[object Object]

← back to Model Arena

Enable 🎨 design-tools belt (opendesign/hyperframes/figma) on all loop battles — models fetch real palettes/type/motion for beautiful UI

e6af3f8af3016c819f0cf4131a531bf508f4e813 · 2026-07-25 00:47:43 -0700 · Steve Abrams

Files touched

Diff

commit e6af3f8af3016c819f0cf4131a531bf508f4e813
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sat Jul 25 00:47:43 2026 -0700

    Enable 🎨 design-tools belt (opendesign/hyperframes/figma) on all loop battles — models fetch real palettes/type/motion for beautiful UI
---
 data/artifacts/53b12394c732/hf-qwen-coder-32b.html |  131 ++
 data/artifacts/53b12394c732/hf-qwen-coder-32b.png  |  Bin 0 -> 14630 bytes
 data/artifacts/b72f0e9e751b/claude-code.html       |  425 ++++++
 data/artifacts/b72f0e9e751b/claude-code.png        |  Bin 0 -> 246668 bytes
 data/artifacts/b72f0e9e751b/gemma3-12b.html        |  214 +++
 data/artifacts/b72f0e9e751b/gemma3-12b.png         |  Bin 0 -> 18532 bytes
 data/artifacts/b72f0e9e751b/gpt.html               | 1453 ++++++++++++++++++++
 data/artifacts/b72f0e9e751b/gpt.png                |  Bin 0 -> 224864 bytes
 data/artifacts/b72f0e9e751b/hermes3-8b.html        |  155 +++
 data/artifacts/b72f0e9e751b/hermes3-8b.png         |  Bin 0 -> 145819 bytes
 data/artifacts/b72f0e9e751b/hf-qwen-coder-32b.html |  154 +++
 data/artifacts/b72f0e9e751b/hf-qwen-coder-32b.png  |  Bin 0 -> 3032 bytes
 data/artifacts/b72f0e9e751b/kimi.html              |  812 +++++++++++
 data/artifacts/b72f0e9e751b/kimi.png               |  Bin 0 -> 101858 bytes
 data/artifacts/b72f0e9e751b/qwen3-14b.html         |  238 ++++
 data/artifacts/b72f0e9e751b/qwen3-14b.png          |  Bin 0 -> 24419 bytes
 data/artifacts/bde366feb227/claude-code.html       |  439 ++++++
 data/artifacts/bde366feb227/claude-code.png        |  Bin 0 -> 181553 bytes
 data/artifacts/bde366feb227/gpt.html               | 1358 ++++++++++++++++++
 data/artifacts/bde366feb227/gpt.png                |  Bin 0 -> 236068 bytes
 data/artifacts/bde366feb227/grok.html              |  629 +++++++++
 data/artifacts/bde366feb227/grok.png               |  Bin 0 -> 88245 bytes
 data/artifacts/d7f4f8ca5f8d/claude-code.html       |  450 ++++++
 data/artifacts/d7f4f8ca5f8d/claude-code.png        |  Bin 0 -> 243189 bytes
 data/artifacts/d7f4f8ca5f8d/gemma3-12b.html        |  284 ++++
 data/artifacts/d7f4f8ca5f8d/gemma3-12b.png         |  Bin 0 -> 17205 bytes
 data/artifacts/d7f4f8ca5f8d/gpt.html               |  613 +++++++++
 data/artifacts/d7f4f8ca5f8d/gpt.png                |  Bin 0 -> 322986 bytes
 data/artifacts/d7f4f8ca5f8d/grok.html              |  298 ++++
 data/artifacts/d7f4f8ca5f8d/grok.png               |  Bin 0 -> 139575 bytes
 data/artifacts/d7f4f8ca5f8d/hermes3-8b.html        |  110 ++
 data/artifacts/d7f4f8ca5f8d/hermes3-8b.png         |  Bin 0 -> 9334 bytes
 data/artifacts/d7f4f8ca5f8d/kimi.html              |  538 ++++++++
 data/artifacts/d7f4f8ca5f8d/kimi.png               |  Bin 0 -> 231943 bytes
 data/artifacts/d7f4f8ca5f8d/qwen3-14b.html         |  210 +++
 data/artifacts/d7f4f8ca5f8d/qwen3-14b.png          |  Bin 0 -> 78492 bytes
 data/challenges.json                               |  256 ++--
 data/costlog.jsonl                                 |    7 +
 idea-run/run-next.sh                               |    2 +-
 39 files changed, 8666 insertions(+), 110 deletions(-)

diff --git a/data/artifacts/53b12394c732/hf-qwen-coder-32b.html b/data/artifacts/53b12394c732/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..93127b6
--- /dev/null
+++ b/data/artifacts/53b12394c732/hf-qwen-coder-32b.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Luxury Wallcovering Carousel</title>
+    <style>
+        body {
+            font-family: 'Arial', sans-serif;
+            margin: 0;
+            padding: 0;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            height: 100vh;
+            background-color: #f5f5f5;
+        }
+        .carousel-container {
+            position: relative;
+            width: 1080px;
+            height: 1080px;
+            overflow: hidden;
+            border-radius: 20px;
+            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
+        }
+        .carousel-slide {
+            position: absolute;
+            width: 100%;
+            height: 100%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            transition: transform 0.5s ease-in-out;
+        }
+        .slide-1 { background-color: #f8e9d3; }
+        .slide-2, .slide-3, .slide-4 { background-color: #ffffff; }
+        .slide-5 { background-color: #f8e9d3; }
+        .carousel-slide h1 {
+            font-size: 40px;
+            color: #333;
+            text-align: center;
+        }
+        .carousel-slide p {
+            font-size: 24px;
+            color: #666;
+            text-align: center;
+            margin-top: 20px;
+        }
+        .pattern { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 80%; height: 80%; background-image: repeating-linear-gradient(45deg, #d3e6fa, #d3e6fa 10px, transparent 10px, transparent 20px); }
+        .wordmark { position: absolute; top: 20px; left: 20px; font-size: 32px; color: #333; text-transform: uppercase; }
+        .controls {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-top: 10px;
+        }
+        .dot { width: 10px; height: 10px; background-color: #ccc; border-radius: 50%; margin: 0 5px; cursor: pointer; transition: background-color 0.3s ease-in-out; }
+        .dot.active { background-color: #333; }
+        .arrow {
+            width: 0;
+            height: 0;
+            border-style: solid;
+            border-width: 12px 8px 0 8px;
+            border-color: #333 transparent transparent transparent;
+            cursor: pointer;
+            margin: 0 10px;
+        }
+        .arrow.right { transform: rotate(180deg); }
+    </style>
+</head>
+<body>
+    <div class="carousel-container">
+        <div class="carousel-slide slide-1" style="transform: translateX(0);">
+            <div class="pattern"></div>
+            <div class="wordmark">Luxury Wallcoverings</div>
+        </div>
+        <div class="carousel-slide slide-2" style="transform: translateX(1080px);">
+            <h1>Pattern 1</h1>
+            <p>Elegant and sophisticated, this pattern adds a touch of luxury to any space.</p>
+        </div>
+        <div class="carousel-slide slide-3" style="transform: translateX(2160px);">
+            <h1>Pattern 2</h1>
+            <p>A modern twist on tradition, perfect for contemporary interiors.</p>
+        </div>
+        <div class="carousel-slide slide-4" style="transform: translateX(3240px);">
+            <h1>Pattern 3</h1>
+            <p>Vibrant and eye-catching, ideal for making a statement in any room.</p>
+        </div>
+        <div class="carousel-slide slide-5" style="transform: translateX(4320px);">
+            <h1>Contact Us</h1>
+            <p>Discover how our wallcoverings can transform your space. Get in touch today!</p>
+        </div>
+    </div>
+    <div class="controls">
+        <div class="arrow left" onclick="moveSlide(-1)"></div>
+        <div class="dot active" onclick="changeSlide(0)"></div>
+        <div class="dot" onclick="changeSlide(1)"></div>
+        <div class="dot" onclick="changeSlide(2)"></div>
+        <div class="dot" onclick="changeSlide(3)"></div>
+        <div class="dot" onclick="changeSlide(4)"></div>
+        <div class="arrow right" onclick="moveSlide(1)"></div>
+    </div>
+    <script>
+        let currentSlide = 0;
+        const slides = document.querySelectorAll('.carousel-slide');
+        const dots = document.querySelectorAll('.dot');
+
+        function changeSlide(index) {
+            if (index >= slides.length || index < 0) return;
+            currentSlide = index;
+            updateSlides();
+        }
+
+        function moveSlide(direction) {
+            changeSlide(currentSlide + direction);
+        }
+
+        function updateSlides() {
+            slides.forEach((slide, index) => {
+                slide.style.transform = `translateX(${(index - currentSlide) * 1080}px)`;
+            });
+            dots.forEach(dot => dot.classList.remove('active'));
+            dots[currentSlide].classList.add('active');
+        }
+
+        document.addEventListener('DOMContentLoaded', () => {
+            updateSlides();
+        });
+    </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/53b12394c732/hf-qwen-coder-32b.png b/data/artifacts/53b12394c732/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..6edc38e
Binary files /dev/null and b/data/artifacts/53b12394c732/hf-qwen-coder-32b.png differ
diff --git a/data/artifacts/b72f0e9e751b/claude-code.html b/data/artifacts/b72f0e9e751b/claude-code.html
new file mode 100644
index 0000000..3a75215
--- /dev/null
+++ b/data/artifacts/b72f0e9e751b/claude-code.html
@@ -0,0 +1,425 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Reel Storyboard · Maison Wallcoverings</title>
+<style>
+  :root{
+    --bg:#0a0a0c;
+    --panel:#121216;
+    --panel-2:#17171d;
+    --line:#26262f;
+    --gold:#c9a24b;
+    --gold-2:#e7cf8f;
+    --ink:#f4f1e9;
+    --muted:#8a8a97;
+    --accent:#b98a5e;
+    --radius:18px;
+    --sans:'Helvetica Neue',Helvetica,Arial,sans-serif;
+    --serif:Georgia,'Times New Roman',serif;
+  }
+  *{box-sizing:border-box;margin:0;padding:0}
+  html,body{height:100%}
+  body{
+    background:
+      radial-gradient(1200px 700px at 80% -10%, #1a1712 0%, transparent 60%),
+      radial-gradient(900px 600px at -10% 110%, #14100c 0%, transparent 55%),
+      var(--bg);
+    color:var(--ink);
+    font-family:var(--sans);
+    min-height:100%;
+    -webkit-font-smoothing:antialiased;
+    display:flex;
+    justify-content:center;
+    padding:34px 20px 60px;
+  }
+  .wrap{
+    width:100%;
+    max-width:1100px;
+    display:grid;
+    grid-template-columns:minmax(300px,360px) 1fr;
+    gap:38px;
+    align-items:start;
+  }
+  header.brand{
+    grid-column:1 / -1;
+    display:flex;
+    align-items:flex-end;
+    justify-content:space-between;
+    border-bottom:1px solid var(--line);
+    padding-bottom:20px;
+    flex-wrap:wrap;
+    gap:14px;
+  }
+  .brand h1{
+    font-family:var(--serif);
+    font-weight:400;
+    font-size:26px;
+    letter-spacing:.14em;
+    text-transform:uppercase;
+  }
+  .brand h1 span{color:var(--gold)}
+  .brand .sub{
+    color:var(--muted);
+    font-size:11px;
+    letter-spacing:.32em;
+    text-transform:uppercase;
+    margin-top:6px;
+  }
+  .badge{
+    font-size:10px;letter-spacing:.28em;text-transform:uppercase;
+    color:var(--gold-2);
+    border:1px solid var(--line);
+    padding:8px 14px;border-radius:40px;
+    background:linear-gradient(180deg,rgba(201,162,75,.08),rgba(201,162,75,0));
+  }
+
+  /* ---------- PHONE ---------- */
+  .stage{display:flex;flex-direction:column;align-items:center;gap:22px;position:sticky;top:24px}
+  .phone{
+    position:relative;
+    width:300px;
+    aspect-ratio:9/16;
+    border-radius:44px;
+    padding:12px;
+    background:linear-gradient(150deg,#2a2a31,#0c0c0f 55%);
+    box-shadow:0 40px 90px -30px rgba(0,0,0,.9),0 0 0 1px #000, inset 0 0 0 2px #303038;
+  }
+  .notch{
+    position:absolute;top:20px;left:50%;transform:translateX(-50%);
+    width:96px;height:22px;background:#000;border-radius:14px;z-index:20;
+  }
+  .screen{
+    position:relative;
+    width:100%;height:100%;
+    border-radius:34px;
+    overflow:hidden;
+    background:#000;
+  }
+  .scene{
+    position:absolute;inset:0;
+    opacity:0;
+    transition:opacity .7s ease;
+    display:flex;align-items:flex-end;
+    background-size:cover;background-position:center;
+  }
+  .scene.active{opacity:1}
+  .scene::before{
+    content:"";position:absolute;inset:0;
+    background:linear-gradient(180deg,rgba(0,0,0,.15) 0%,rgba(0,0,0,0) 35%,rgba(0,0,0,.75) 100%);
+  }
+  .scene .grain{position:absolute;inset:0;opacity:.05;mix-blend-mode:overlay;
+    background-image:radial-gradient(#fff 1px,transparent 1px);background-size:3px 3px}
+
+  .scene .kicker{
+    position:absolute;top:56px;left:22px;
+    font-size:10px;letter-spacing:.34em;text-transform:uppercase;
+    color:rgba(255,255,255,.85);
+    padding:6px 12px;border:1px solid rgba(255,255,255,.35);border-radius:30px;
+    backdrop-filter:blur(4px);
+  }
+  .scene .cap{
+    position:relative;z-index:2;
+    padding:26px 24px 40px;
+    width:100%;
+  }
+  .scene .cap .line{
+    font-family:var(--serif);
+    font-size:27px;line-height:1.15;
+    text-shadow:0 2px 18px rgba(0,0,0,.6);
+    transform:translateY(18px);opacity:0;
+  }
+  .scene .cap .sub{
+    margin-top:10px;
+    font-size:12px;letter-spacing:.06em;
+    color:rgba(255,255,255,.82);
+    transform:translateY(18px);opacity:0;
+  }
+  .scene.active .cap .line{animation:rise .8s .15s forwards cubic-bezier(.2,.8,.2,1)}
+  .scene.active .cap .sub{animation:rise .8s .32s forwards cubic-bezier(.2,.8,.2,1)}
+  @keyframes rise{to{transform:translateY(0);opacity:1}}
+
+  /* swatch grid scene */
+  .swgrid{position:absolute;top:0;left:0;right:0;bottom:0;
+    display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);gap:5px;padding:5px}
+  .swgrid div{border-radius:5px;transform:scale(.4);opacity:0}
+  .scene.active .swgrid div{animation:pop .5s forwards cubic-bezier(.2,.9,.3,1.3)}
+  @keyframes pop{to{transform:scale(1);opacity:1}}
+
+  /* CTA scene */
+  .cta-btn{
+    display:inline-block;margin-top:16px;
+    font-size:12px;letter-spacing:.2em;text-transform:uppercase;
+    color:#0a0a0c;background:var(--gold-2);
+    padding:12px 22px;border-radius:40px;font-weight:600;
+    transform:translateY(18px);opacity:0;
+  }
+  .scene.active .cta-btn{animation:rise .8s .5s forwards cubic-bezier(.2,.8,.2,1)}
+
+  /* progress + segments */
+  .segbar{
+    position:absolute;top:20px;left:16px;right:16px;z-index:30;
+    display:flex;gap:5px;height:3px;
+  }
+  .segbar .seg{flex:1;background:rgba(255,255,255,.25);border-radius:3px;overflow:hidden}
+  .segbar .seg i{display:block;height:100%;width:0;background:#fff;border-radius:3px}
+
+  .ui-icons{position:absolute;right:16px;bottom:120px;z-index:25;display:flex;flex-direction:column;gap:20px;align-items:center}
+  .ui-icons div{width:30px;height:30px;border-radius:50%;
+    border:1px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;
+    color:#fff;font-size:14px;background:rgba(0,0,0,.2)}
+
+  .transport{display:flex;align-items:center;gap:16px}
+  .btn{
+    cursor:pointer;border:1px solid var(--line);background:var(--panel-2);
+    color:var(--ink);border-radius:50px;font-size:13px;
+    padding:12px 20px;letter-spacing:.04em;transition:.2s;
+    display:flex;align-items:center;gap:8px;
+  }
+  .btn:hover{border-color:var(--gold);color:var(--gold-2)}
+  .btn.primary{background:linear-gradient(180deg,var(--gold-2),var(--gold));color:#111;border:none;font-weight:600;padding:14px 28px}
+  .btn.primary:hover{filter:brightness(1.08);color:#111}
+  .timecode{font-variant-numeric:tabular-nums;color:var(--muted);font-size:12px;letter-spacing:.1em}
+
+  /* ---------- EDITOR ---------- */
+  .editor h2{
+    font-family:var(--serif);font-weight:400;font-size:19px;letter-spacing:.05em;
+    margin-bottom:4px;
+  }
+  .editor .hint{color:var(--muted);font-size:12px;margin-bottom:20px}
+  .cards{display:flex;flex-direction:column;gap:14px}
+  .card{
+    background:linear-gradient(180deg,var(--panel),var(--panel-2));
+    border:1px solid var(--line);border-radius:var(--radius);
+    padding:16px 18px;transition:.25s;position:relative;overflow:hidden;
+  }
+  .card::after{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:transparent;transition:.25s}
+  .card.on{border-color:rgba(201,162,75,.5)}
+  .card.on::after{background:linear-gradient(var(--gold-2),var(--gold))}
+  .card-top{display:flex;align-items:center;gap:12px;margin-bottom:12px}
+  .idx{
+    width:30px;height:30px;flex:none;border-radius:9px;
+    background:#000;border:1px solid var(--line);
+    display:flex;align-items:center;justify-content:center;
+    font-family:var(--serif);color:var(--gold-2);font-size:14px;
+  }
+  .card.on .idx{border-color:var(--gold)}
+  .card-top .meta{flex:1;min-width:0}
+  .card-top .name{font-size:12px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink)}
+  .card-top .role{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);margin-top:3px}
+  .dur{color:var(--muted);font-size:11px;font-variant-numeric:tabular-nums;letter-spacing:.08em}
+  .card textarea{
+    width:100%;background:#0c0c0f;border:1px solid var(--line);
+    color:var(--ink);border-radius:10px;padding:10px 12px;
+    font-family:var(--serif);font-size:15px;line-height:1.4;resize:vertical;min-height:52px;
+    transition:.2s;
+  }
+  .card textarea:focus{outline:none;border-color:var(--gold);box-shadow:0 0 0 3px rgba(201,162,75,.12)}
+  .card .sublbl{display:block;margin:10px 0 6px;font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
+  .card input.subedit{
+    width:100%;background:#0c0c0f;border:1px solid var(--line);
+    color:var(--muted);border-radius:10px;padding:8px 12px;font-size:12px;font-family:var(--sans);
+  }
+  .card input.subedit:focus{outline:none;border-color:var(--accent);color:var(--ink)}
+  .goto{cursor:pointer;font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
+    border:1px solid var(--line);padding:6px 10px;border-radius:30px}
+  .goto:hover{color:var(--gold-2);border-color:var(--gold)}
+
+  .foot{grid-column:1/-1;text-align:center;color:#4c4c57;font-size:11px;letter-spacing:.24em;text-transform:uppercase;margin-top:14px}
+
+  @media(max-width:820px){
+    .wrap{grid-template-columns:1fr;gap:30px}
+    .stage{position:static}
+  }
+</style>
+</head>
+<body>
+<div class="wrap">
+  <header class="brand">
+    <div>
+      <h1>Maison <span>Wallcoverings</span></h1>
+      <div class="sub">Reel Storyboard · 9:16 · 15 sec</div>
+    </div>
+    <div class="badge">Instagram Reel Maker</div>
+  </header>
+
+  <!-- PREVIEW -->
+  <section class="stage">
+    <div class="phone">
+      <div class="notch"></div>
+      <div class="screen">
+        <div class="segbar" id="segbar"></div>
+        <div id="scenes"></div>
+        <div class="ui-icons">
+          <div>♡</div><div>❝</div><div>➤</div>
+        </div>
+      </div>
+    </div>
+    <div class="transport">
+      <button class="btn primary" id="play">▶ Play</button>
+      <button class="btn" id="restart">↺ Restart</button>
+      <span class="timecode" id="tc">0.0 / 15.0s</span>
+    </div>
+  </section>
+
+  <!-- EDITOR -->
+  <section class="editor">
+    <h2>Scene Captions</h2>
+    <p class="hint">Edit the on-screen text for each of the five scenes. Changes appear live in the preview.</p>
+    <div class="cards" id="cards"></div>
+  </section>
+
+  <div class="foot">Maison Wallcoverings — Craft in Every Wall</div>
+</div>
+
+<script>
+const scenes = [
+  { role:"Hook", name:"The Hook", dur:2.6, kicker:"New Collection",
+    bg:"linear-gradient(135deg,#3a2c22,#6d4b32 45%,#1c130d)",
+    line:"Walls that whisper luxury.", sub:"Introducing the Atelier Series ✦" },
+  { role:"Room Reveal", name:"Room Reveal", dur:3.2, kicker:"The Reveal",
+    bg:"linear-gradient(160deg,#1f2b2b,#2e4a48 40%,#0d1615)",
+    line:"One wall changes everything.", sub:"Emerald damask · living room" },
+  { role:"Close-up Texture", name:"Close-Up", dur:2.8, kicker:"Feel It",
+    bg:"linear-gradient(135deg,#4a3a2a,#8a6b3f 50%,#241a10)",
+    line:"Hand-woven. Gold-threaded.", sub:"Grasscloth with real metallic weave" },
+  { role:"Swatch Grid", name:"Swatch Grid", dur:3.0, kicker:"14 Colorways",
+    bg:"#101014", swatches:true,
+    line:"Find your shade.", sub:"Swipe through the full palette" },
+  { role:"CTA", name:"Call to Action", dur:3.4, kicker:"Order Samples",
+    bg:"linear-gradient(150deg,#2a2118,#0a0a0c)", cta:true,
+    line:"Order your free swatch.", sub:"Tap the link in bio →" }
+];
+const swColors = ["#6d4b32","#2e4a48","#8a6b3f","#3a2c3a","#4a5568","#7a3b3b","#3b5a3b","#8a7f5f","#463a5a"];
+
+const scenesEl = document.getElementById('scenes');
+const segbar   = document.getElementById('segbar');
+const cardsEl  = document.getElementById('cards');
+const tcEl     = document.getElementById('tc');
+const playBtn  = document.getElementById('play');
+const total    = scenes.reduce((a,s)=>a+s.dur,0);
+
+// build scenes
+scenes.forEach((s,i)=>{
+  const d=document.createElement('div');
+  d.className='scene'; d.dataset.i=i;
+  d.style.background=s.bg; d.style.backgroundSize='cover';
+  let inner=`<div class="grain"></div>`;
+  if(s.swatches){
+    inner+=`<div class="swgrid">`+swColors.map((c,k)=>`<div style="background:${c};animation-delay:${k*0.06}s"></div>`).join('')+`</div>`;
+  }
+  inner+=`<div class="kicker">${s.kicker}</div>
+    <div class="cap">
+      <div class="line" data-line>${s.line}</div>
+      <div class="sub" data-sub>${s.sub}</div>
+      ${s.cta?'<span class="cta-btn">Shop Now</span>':''}
+    </div>`;
+  d.innerHTML=inner;
+  scenesEl.appendChild(d);
+
+  const seg=document.createElement('div');
+  seg.className='seg'; seg.innerHTML='<i></i>';
+  segbar.appendChild(seg);
+});
+
+// build editor cards
+scenes.forEach((s,i)=>{
+  const c=document.createElement('div');
+  c.className='card'; c.dataset.i=i;
+  c.innerHTML=`
+    <div class="card-top">
+      <div class="idx">${i+1}</div>
+      <div class="meta">
+        <div class="name">${s.name}</div>
+        <div class="role">${s.role}</div>
+      </div>
+      <span class="dur">${s.dur.toFixed(1)}s</span>
+      <span class="goto" data-goto="${i}">View</span>
+    </div>
+    <textarea data-edit="line" data-i="${i}" maxlength="70">${s.line}</textarea>
+    <span class="sublbl">Sub-caption</span>
+    <input class="subedit" data-edit="sub" data-i="${i}" maxlength="60" value="${s.sub.replace(/"/g,'&quot;')}">
+  `;
+  cardsEl.appendChild(c);
+});
+
+const sceneNodes=[...scenesEl.children];
+const segNodes=[...segbar.querySelectorAll('.seg i')];
+const cardNodes=[...cardsEl.children];
+
+// live editing
+cardsEl.addEventListener('input',e=>{
+  const t=e.target; if(!t.dataset.edit) return;
+  const i=+t.dataset.i;
+  const node=sceneNodes[i].querySelector(t.dataset.edit==='line'?'[data-line]':'[data-sub]');
+  node.textContent=t.value;
+});
+cardsEl.addEventListener('click',e=>{
+  if(e.target.dataset.goto!=null){ jumpTo(+e.target.dataset.goto); }
+});
+
+// playback engine
+let current=0, elapsedInScene=0, playing=false, last=0, raf=null;
+
+function setActive(i){
+  sceneNodes.forEach((n,k)=>n.classList.toggle('active',k===i));
+  cardNodes.forEach((n,k)=>n.classList.toggle('on',k===i));
+  segNodes.forEach((n,k)=>{ n.style.transition='none'; n.style.width=(k<i?'100%':'0%'); });
+}
+setActive(0);
+
+function jumpTo(i){
+  current=i; elapsedInScene=0;
+  setActive(i);
+  updateTC();
+  if(!playing){ // restart the entry animation by re-toggling
+    const n=sceneNodes[i]; n.classList.remove('active'); void n.offsetWidth; n.classList.add('active');
+  }
+}
+
+function updateTC(){
+  let before=0; for(let k=0;k<current;k++) before+=scenes[k].dur;
+  const t=Math.min(before+elapsedInScene,total);
+  tcEl.textContent=t.toFixed(1)+' / '+total.toFixed(1)+'s';
+}
+
+function tick(now){
+  if(!playing) return;
+  const dt=(now-last)/1000; last=now;
+  elapsedInScene+=dt;
+  const dur=scenes[current].dur;
+  const seg=segNodes[current];
+  seg.style.transition='none';
+  seg.style.width=Math.min(elapsedInScene/dur*100,100)+'%';
+  updateTC();
+  if(elapsedInScene>=dur){
+    seg.style.width='100%';
+    current=(current+1)%scenes.length;
+    elapsedInScene=0;
+    if(current===0){ segNodes.forEach(s=>s.style.width='0%'); }
+    setActive(current);
+  }
+  raf=requestAnimationFrame(tick);
+}
+
+function play(){
+  playing=true; playBtn.textContent='❚❚ Pause';
+  last=performance.now();
+  raf=requestAnimationFrame(tick);
+}
+function pause(){
+  playing=false; playBtn.textContent='▶ Play';
+  cancelAnimationFrame(raf);
+}
+playBtn.addEventListener('click',()=>{ playing?pause():play(); });
+document.getElementById('restart').addEventListener('click',()=>{
+  pause(); current=0; elapsedInScene=0;
+  segNodes.forEach(s=>{s.style.transition='none';s.style.width='0%';});
+  setActive(0); updateTC();
+  const n=sceneNodes[0]; n.classList.remove('active'); void n.offsetWidth; n.classList.add('active');
+});
+updateTC();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/b72f0e9e751b/claude-code.png b/data/artifacts/b72f0e9e751b/claude-code.png
new file mode 100644
index 0000000..47e5dd6
Binary files /dev/null and b/data/artifacts/b72f0e9e751b/claude-code.png differ
diff --git a/data/artifacts/b72f0e9e751b/gemma3-12b.html b/data/artifacts/b72f0e9e751b/gemma3-12b.html
new file mode 100644
index 0000000..aba6df8
--- /dev/null
+++ b/data/artifacts/b72f0e9e751b/gemma3-12b.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Wallcovering Reel Storyboard</title>
+    <style>
+        body {
+            font-family: sans-serif;
+            margin: 0;
+            background-color: #121212; /* Luxe dark background */
+            color: #fff;
+            overflow: hidden; /* Prevent scrollbars */
+        }
+
+        .container {
+            display: flex;
+            flex-direction: column;
+            height: 100vh;
+            width: 100%;
+        }
+
+        #phone-frame {
+            background-color: #282828; /* Darker phone frame */
+            border: 1px solid rgba(255, 255, 255, 0.1);
+            padding: 20px;
+            margin: 20px auto;
+            width: calc(100% - 40px); /* Responsive width */
+            max-width: 400px; /* Limit maximum width */
+            height: 568px;  /* Standard phone height (9:16) */
+            overflow: hidden;
+        }
+
+        .scene {
+            display: none;
+            height: 100%;
+            position: relative;
+        }
+
+        #reel-preview {
+            width: 100%;
+            height: 100%;
+            object-fit: cover; /* Fill the frame */
+        }
+
+        .caption {
+            position: absolute;
+            bottom: 20px;
+            left: 50%;
+            transform: translateX(-50%);
+            background-color: rgba(0, 0, 0, 0.7);
+            padding: 10px;
+            border-radius: 5px;
+            font-size: 14px;
+            text-align: center;
+            animation: slideIn 0.5s ease-in-out forwards; /* Animate the caption */
+        }
+
+        @keyframes slideIn {
+            from { opacity: 0; }
+            to { opacity: 1; }
+        }
+
+        #progress-bar-container {
+            width: 100%;
+            height: 10px;
+            background-color: #333;
+            margin: 20px auto;
+        }
+
+        #progress-bar {
+            width: 0%;
+            height: 100%;
+            background-color: #f05446; /* Accent color */
+        }
+
+        .controls {
+            text-align: center;
+            margin-top: 20px;
+        }
+
+        button {
+            background-color: transparent;
+            border: 1px solid #fff;
+            padding: 8px 16px;
+            color: #fff;
+            cursor: pointer;
+            margin: 0 10px;
+            font-size: 14px;
+        }
+
+        button:hover {
+            background-color: rgba(255, 255, 255, 0.1);
+        }
+
+
+    </style>
+</head>
+<body>
+
+<div class="container">
+    <h1>Wallcovering Reel Storyboard</h1>
+
+    <div id="phone-frame">
+        <img id="reel-preview" src="" alt="Reel Preview">
+        <div class="scene" data-duration="3" id="scene1"><div class="caption">✨Captivating Walls Await! ✨</div></div>
+        <div class="scene" data-duration="4" id="scene2"><div class="caption">Transform Your Space 🏡</div></div>
+        <div class="scene" data-duration="3" id="scene3"><div class="caption">Textural Details That Elevate. ✨</div></div>
+        <div class="scene" data-duration="5" id="scene4"><div class="caption">Endless Possibilities 🎨</div></div>
+        <div class="scene" data-duration="4" id="scene5"><div class="caption">Shop the Look! Link in Bio 🔗</div></div>
+
+
+    </div>
+
+    <div id="progress-bar-container">
+        <div id="progress-bar"></div>
+    </div>
+
+    <div class="controls">
+        <button id="playPauseBtn">Play</button>
+        <button id="resetBtn">Reset</button>
+    </div>
+</div>
+
+<script>
+    const phoneFrame = document.getElementById('phone-frame');
+    const reelPreview = document.getElementById('reel-preview');
+    const scenes = document.querySelectorAll('.scene');
+    const progressBar = document.getElementById('progress-bar');
+    const playPauseBtn = document.getElementById('playPauseBtn');
+    const resetBtn = document.getElementById('resetBtn');
+
+    let currentSceneIndex = 0;
+    let timer;
+    let isPlaying = false;
+
+
+    // Sample Images (Replace with actual image URLs)
+    const images = [
+        "https://via.placeholder.com/400x568?text=Hook",
+        "https://via.placeholder.com/400x568?text=Room+Reveal",
+        "https://via.placeholder.com/400x568?text=Texture",
+        "https://via.placeholder.com/400x568?text=Swatch+Grid",
+        "https://via.placeholder.com/400x568?text=CTA"
+    ];
+
+
+    function showScene(index) {
+      scenes.forEach(scene => scene.style.display = 'none'); // Hide all scenes
+
+        const scene = document.getElementById(`scene${index + 1}`);
+        reelPreview.src = images[index];
+        scene.style.display = 'block';
+
+    }
+
+    function startTimer() {
+      let totalDuration = 0;
+       scenes.forEach(scene => {
+            totalDuration += parseInt(scene.dataset.duration);
+        });
+
+
+        if (isPlaying) {
+           timer = setTimeout(() => {
+                currentSceneIndex++;
+                if (currentSceneIndex < scenes.length) {
+                    showScene(currentSceneIndex);
+                    startTimer(); // Restart timer for the next scene
+                } else {
+                    currentSceneIndex = 0;
+                    showScene(currentSceneIndex);
+                    startTimer();  // Loop back to the beginning
+                }
+
+            }, (scenes[currentSceneIndex].dataset.duration *1000));
+        }
+
+
+    }
+
+
+    function playPause() {
+      isPlaying = !isPlaying;
+      if (isPlaying) {
+          playPauseBtn.textContent = 'Pause';
+          startTimer();
+      } else {
+          playPauseBtn.textContent = 'Play';
+          clearTimeout(timer);
+      }
+    }
+
+    function resetStoryboard() {
+        currentSceneIndex = 0;
+        isPlaying = false;
+        playPauseBtn.textContent = "Play";
+        showScene(currentSceneIndex);
+        progressBar.style.width = '0%';
+        clearTimeout(timer)
+
+    }
+
+
+    // Event Listeners
+    playPauseBtn.addEventListener('click', playPause);
+    resetBtn.addEventListener('click', resetStoryboard);
+
+    // Initial Setup
+    showScene(currentSceneIndex);
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/b72f0e9e751b/gemma3-12b.png b/data/artifacts/b72f0e9e751b/gemma3-12b.png
new file mode 100644
index 0000000..f920d73
Binary files /dev/null and b/data/artifacts/b72f0e9e751b/gemma3-12b.png differ
diff --git a/data/artifacts/b72f0e9e751b/gpt.html b/data/artifacts/b72f0e9e751b/gpt.html
new file mode 100644
index 0000000..5797f46
--- /dev/null
+++ b/data/artifacts/b72f0e9e751b/gpt.html
@@ -0,0 +1,1453 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<title>Reel Storyboard Tool – Wallcovering Brand</title>
+<style>
+  :root {
+    --bg: #050509;
+    --bg-elevated: #111119;
+    --bg-soft: #171721;
+    --accent: #d2b57e;
+    --accent-soft: rgba(210,181,126,0.28);
+    --accent-strong: #f3d9a2;
+    --text-main: #f5f5f7;
+    --text-muted: #a3a3b3;
+    --border-subtle: #272738;
+    --danger: #f87c7c;
+    --phone-radius: 36px;
+    --transition-fast: 160ms ease-out;
+    --shadow-soft: 0 22px 70px rgba(0,0,0,0.7);
+    --font-body: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text",
+      "Segoe UI", sans-serif;
+  }
+
+  * {
+    box-sizing: border-box;
+  }
+
+  html, body {
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    background: radial-gradient(circle at top, #1a1a26 0, #050509 52%, #000 100%);
+    color: var(--text-main);
+    font-family: var(--font-body);
+    -webkit-font-smoothing: antialiased;
+  }
+
+  body {
+    display: flex;
+    align-items: stretch;
+    justify-content: center;
+  }
+
+  .app {
+    display: flex;
+    gap: 28px;
+    max-width: 1120px;
+    width: 100%;
+    padding: 22px 26px;
+  }
+
+  @media (max-width: 920px) {
+    .app {
+      flex-direction: column;
+      align-items: center;
+      padding: 18px;
+      gap: 20px;
+    }
+  }
+
+  /* LEFT: PHONE PREVIEW */
+
+  .preview-column {
+    flex: 0 0 auto;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 16px;
+  }
+
+  .branding {
+    text-align: center;
+  }
+
+  .branding-title {
+    letter-spacing: 0.12em;
+    text-transform: uppercase;
+    font-size: 11px;
+    color: var(--accent-strong);
+  }
+
+  .branding-main {
+    margin-top: 4px;
+    font-size: 18px;
+    letter-spacing: 0.06em;
+    text-transform: uppercase;
+  }
+
+  .branding-sub {
+    margin-top: 3px;
+    font-size: 11px;
+    color: var(--text-muted);
+    letter-spacing: 0.11em;
+    text-transform: uppercase;
+  }
+
+  .phone-frame-wrapper {
+    position: relative;
+    padding: 8px;
+    border-radius: calc(var(--phone-radius) + 6px);
+    background: radial-gradient(circle at 20% 0, rgba(210,181,126,0.28), transparent 55%),
+                radial-gradient(circle at 80% 120%, rgba(117,104,84,0.35), transparent 60%),
+                linear-gradient(145deg, #050509, #12121b);
+    box-shadow: var(--shadow-soft);
+  }
+
+  .phone-outline {
+    position: relative;
+    width: 280px;
+    height: calc(280px * 16 / 9);
+    border-radius: var(--phone-radius);
+    background: radial-gradient(circle at 10% 0, #282834, #090910 55%);
+    padding: 10px 6px;
+    box-shadow:
+      inset 0 0 0 1px rgba(255,255,255,0.02),
+      inset 0 0 0 2px rgba(0,0,0,0.8),
+      0 20px 45px rgba(0,0,0,0.9);
+    overflow: hidden;
+  }
+
+  /* Notch & hardware hints */
+
+  .notch {
+    position: absolute;
+    top: 6px;
+    left: 50%;
+    transform: translateX(-50%);
+    width: 96px;
+    height: 14px;
+    border-radius: 0 0 12px 12px;
+    background: radial-gradient(circle at 50% 0, #2f2f3c, #12121b 70%);
+    box-shadow: 0 1px 3px rgba(0,0,0,0.7);
+    z-index: 3;
+  }
+
+  .notch::before,
+  .notch::after {
+    content: "";
+    position: absolute;
+    top: 4px;
+    border-radius: 999px;
+  }
+  .notch::before {
+    left: 18px;
+    width: 18px;
+    height: 4px;
+    background: radial-gradient(circle, #666674, #11111a);
+  }
+  .notch::after {
+    right: 16px;
+    width: 10px;
+    height: 10px;
+    background: radial-gradient(circle, #44445b, #11111a);
+  }
+
+  .phone-bezel-inner {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    border-radius: calc(var(--phone-radius) - 6px);
+    overflow: hidden;
+    background: #000;
+  }
+
+  /* Reel content */
+
+  .reel-screen {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    background: radial-gradient(circle at 20% -10%, #303046, #050509 55%);
+    color: #f8f8fb;
+    display: flex;
+    flex-direction: column;
+    padding: 14px 11px 12px;
+  }
+
+  /* Faux Instagram UI chrome */
+
+  .reel-status-bar {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: 9px;
+    color: #d9d9e6;
+    opacity: 0.92;
+    margin-bottom: 6px;
+  }
+  .reel-status-bar span {
+    opacity: 0.9;
+  }
+
+  .reel-progress-bar {
+    width: 100%;
+    height: 3px;
+    border-radius: 999px;
+    background: rgba(255,255,255,0.1);
+    overflow: hidden;
+    margin-bottom: 5px;
+    display: flex;
+    gap: 2px;
+  }
+
+  .reel-progress-segment {
+    flex: 1;
+    background: rgba(255,255,255,0.08);
+    position: relative;
+    overflow: hidden;
+    border-radius: 999px;
+  }
+
+  .reel-progress-segment-fill {
+    position: absolute;
+    top: 0; left: 0; bottom: 0;
+    width: 0%;
+    background: linear-gradient(90deg, #f5f5ff, #e3c893);
+    border-radius: inherit;
+    transition: width 120ms linear;
+  }
+
+  .reel-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 9px;
+    margin-bottom: 6px;
+  }
+
+  .reel-profile {
+    display: flex;
+    align-items: center;
+    gap: 6px;
+  }
+
+  .reel-avatar {
+    width: 17px;
+    height: 17px;
+    border-radius: 999px;
+    background: radial-gradient(circle at 30% 20%, #f5e7d1, #987a48 40%, #41363f 70%, #0c0b11 100%);
+    border: 1px solid rgba(255,255,255,0.35);
+    box-shadow: 0 0 0 1px rgba(0,0,0,0.7);
+  }
+
+  .reel-handle {
+    display: flex;
+    flex-direction: column;
+    gap: 1px;
+  }
+
+  .reel-handle-main {
+    letter-spacing: 0.08em;
+    text-transform: uppercase;
+    font-size: 8px;
+  }
+
+  .reel-handle-sub {
+    font-size: 8px;
+    color: rgba(230,230,240,0.7);
+  }
+
+  .reel-header-icons {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    opacity: 0.95;
+  }
+
+  .reel-header-dot-menu {
+    width: 12px;
+    height: 3px;
+    border-radius: 999px;
+    background: radial-gradient(circle, rgba(255,255,255,0.95) 0, rgba(255,255,255,0.6) 55%, transparent 100%);
+  }
+
+  /* Scene visual */
+
+  .scene-visual {
+    flex: 1;
+    border-radius: 18px;
+    overflow: hidden;
+    position: relative;
+    background: radial-gradient(circle at 10% 0, #3b3b4c, #050509 65%);
+    box-shadow: 0 18px 38px rgba(0,0,0,0.65);
+    border: 1px solid rgba(255,255,255,0.06);
+  }
+
+  .scene-gradient-overlay {
+    position: absolute;
+    inset: 0;
+    background:
+      linear-gradient(135deg, rgba(210,181,126,0.14), transparent 40%),
+      radial-gradient(circle at 80% 120%, rgba(0,0,0,0.85), transparent 60%);
+    mix-blend-mode: screen;
+    opacity: 0.9;
+    pointer-events: none;
+  }
+
+  .scene-panes {
+    position: absolute;
+    inset: 0;
+    display: grid;
+    grid-template-columns: 1.2fr 0.9fr;
+    overflow: hidden;
+  }
+
+  .pane-left,
+  .pane-right {
+    position: relative;
+  }
+
+  .pane-left::before {
+    content: "";
+    position: absolute;
+    inset: 8% 10% 6% 10%;
+    border-radius: 20px;
+    background:
+      linear-gradient(145deg, #1c1c27, #050509 65%),
+      radial-gradient(circle at 10% 0, rgba(210,181,126,0.18), transparent 55%);
+    box-shadow:
+      inset 0 0 0 1px rgba(255,255,255,0.05),
+      0 16px 34px rgba(0,0,0,0.8);
+  }
+
+  .pane-right::before {
+    content: "";
+    position: absolute;
+    inset: 10% 14% 10% 0;
+    border-radius: 18px;
+    background:
+      linear-gradient(165deg, #13131e, #08060a 55%),
+      radial-gradient(circle at 40% 0, rgba(210,181,126,0.18), transparent 45%);
+    box-shadow:
+      inset 0 0 0 1px rgba(255,255,255,0.03),
+      0 16px 34px rgba(0,0,0,0.9);
+  }
+
+  .pane-wall-stripes {
+    position: absolute;
+    inset: 14% 10% 16% 14%;
+    background-image:
+      repeating-linear-gradient(
+        100deg,
+        rgba(255,255,255,0.14) 0,
+        rgba(255,255,255,0.1) 4px,
+        rgba(0,0,0,0.5) 4px,
+        rgba(0,0,0,0.5) 8px
+      );
+    opacity: 0.32;
+    mix-blend-mode: screen;
+    border-radius: 22px;
+  }
+
+  .pane-right-grid {
+    position: absolute;
+    inset: 16% 16% 18% 4%;
+    display: grid;
+    grid-template-columns: 1fr;
+    grid-auto-rows: 1fr;
+    gap: 6px;
+  }
+
+  .pane-swatch {
+    border-radius: 11px;
+    background: conic-gradient(from 210deg, #f7e6d1, #c8a16a, #7e6545, #241e26, #f7e6d1);
+    position: relative;
+    overflow: hidden;
+  }
+
+  .pane-swatch::before {
+    content: "";
+    position: absolute;
+    inset: 12%;
+    border-radius: 9px;
+    background:
+      linear-gradient(145deg, #f2e4cf, #c7a36d 50%, #7a6648 80%);
+    mix-blend-mode: normal;
+  }
+
+  .pane-detail {
+    border-radius: 11px;
+    position: relative;
+    overflow: hidden;
+    background:
+      radial-gradient(circle at 0 0, #f5e5cc, #947a53 40%, #30272f 75%),
+      repeating-linear-gradient(
+        45deg,
+        rgba(255,255,255,0.32) 0,
+        rgba(255,255,255,0.25) 1px,
+        rgba(140,126,103,0.6) 2px,
+        rgba(140,126,103,0.6) 4px
+      );
+    opacity: 0.95;
+  }
+
+  .pane-detail::before {
+    content: "";
+    position: absolute;
+    inset: 10%;
+    border-radius: 10px;
+    border: 1px dashed rgba(0,0,0,0.35);
+    opacity: 0.32;
+  }
+
+  .pane-glow-orb {
+    position: absolute;
+    width: 80px;
+    height: 80px;
+    border-radius: 50%;
+    right: 10%;
+    bottom: 9%;
+    background: radial-gradient(circle, rgba(255,255,255,0.9), rgba(210,181,126,0.9), transparent 70%);
+    opacity: 0.22;
+    filter: blur(1px);
+    pointer-events: none;
+  }
+
+  .scene-label {
+    position: absolute;
+    top: 10px;
+    left: 12px;
+    padding: 3px 7px 3px 6px;
+    border-radius: 999px;
+    font-size: 8px;
+    text-transform: uppercase;
+    letter-spacing: 0.16em;
+    background: rgba(6,6,10,0.86);
+    color: rgba(245,245,255,0.9);
+    border: 1px solid rgba(255,255,255,0.12);
+    display: inline-flex;
+    align-items: center;
+    gap: 5px;
+  }
+
+  .scene-label-dot {
+    width: 7px;
+    height: 7px;
+    border-radius: 999px;
+    background: radial-gradient(circle, #fce5b8, #c08f43 60%, #433629 100%);
+    box-shadow: 0 0 0 1px rgba(0,0,0,0.6);
+  }
+
+  .scene-timer {
+    position: absolute;
+    top: 10px;
+    right: 10px;
+    padding: 3px 7px;
+    border-radius: 999px;
+    font-size: 8px;
+    text-transform: uppercase;
+    letter-spacing: 0.16em;
+    color: rgba(245,245,255,0.8);
+    background: rgba(7,7,11,0.9);
+    border: 1px solid rgba(255,255,255,0.12);
+  }
+
+  /* Captions overlay */
+
+  .caption-container {
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    padding: 10px 10px 9px;
+    pointer-events: none;
+  }
+
+  .caption-backdrop {
+    border-radius: 16px;
+    padding: 7px 7px 6px;
+    background: linear-gradient(to top, rgba(0,0,0,0.92), rgba(0,0,0,0.68), transparent);
+    border: 1px solid rgba(255,255,255,0.08);
+    box-shadow: 0 16px 26px rgba(0,0,0,0.9);
+    pointer-events: auto;
+  }
+
+  .caption-text {
+    font-size: 11px;
+    line-height: 1.4;
+    color: #f5f5ff;
+    max-height: 52px;
+    overflow: hidden;
+    position: relative;
+  }
+
+  .caption-text.fade-in {
+    animation: captionFade 380ms ease-out forwards;
+  }
+
+  @keyframes captionFade {
+    from {
+      opacity: 0;
+      transform: translateY(8px);
+      filter: blur(2px);
+    }
+    to {
+      opacity: 1;
+      transform: translateY(0);
+      filter: blur(0);
+    }
+  }
+
+  .caption-text span.key {
+    color: var(--accent-strong);
+    font-weight: 500;
+  }
+
+  .caption-meta {
+    margin-top: 4px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 9px;
+    color: rgba(210,210,230,0.8);
+  }
+
+  .caption-meta-left {
+    display: flex;
+    gap: 7px;
+    align-items: center;
+  }
+
+  .caption-pill {
+    padding: 2px 6px 3px;
+    border-radius: 999px;
+    border: 1px solid rgba(255,255,255,0.16);
+    background: rgba(20,20,35,0.72);
+    font-size: 8px;
+    text-transform: uppercase;
+    letter-spacing: 0.14em;
+  }
+
+  .caption-meta-tag {
+    opacity: 0.7;
+  }
+
+  .caption-meta-ticks {
+    font-size: 8px;
+    letter-spacing: 0.08em;
+    opacity: 0.85;
+  }
+
+  /* Right controls */
+
+  .controls-column {
+    flex: 1;
+    background: radial-gradient(circle at top left, rgba(210,181,126,0.08), transparent 50%),
+                linear-gradient(145deg, #050509, #12121b);
+    border-radius: 22px;
+    border: 1px solid rgba(255,255,255,0.05);
+    padding: 16px 16px 14px;
+    display: flex;
+    flex-direction: column;
+    box-shadow:
+      0 26px 60px rgba(0,0,0,0.9),
+      inset 0 0 0 1px rgba(255,255,255,0.02);
+  }
+
+  @media (max-width: 920px) {
+    .phone-outline {
+      width: 240px;
+      height: calc(240px * 16 / 9);
+    }
+    .controls-column {
+      width: 100%;
+      max-width: 640px;
+    }
+  }
+
+  .panel-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: baseline;
+    margin-bottom: 10px;
+  }
+
+  .panel-title {
+    font-size: 13px;
+    letter-spacing: 0.18em;
+    text-transform: uppercase;
+    color: var(--text-main);
+  }
+
+  .panel-subtitle {
+    font-size: 11px;
+    color: var(--text-muted);
+  }
+
+  .tagline {
+    font-size: 11px;
+    color: var(--accent-strong);
+    letter-spacing: 0.14em;
+    text-transform: uppercase;
+    margin-bottom: 10px;
+  }
+
+  .scene-timeline {
+    display: flex;
+    gap: 6px;
+    margin-bottom: 10px;
+  }
+
+  .timeline-chip {
+    flex: 1;
+    border-radius: 999px;
+    padding: 6px 7px;
+    border: 1px solid var(--border-subtle);
+    background: rgba(9,9,16,0.9);
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 10px;
+    color: var(--text-muted);
+    cursor: pointer;
+    transition: border-color var(--transition-fast),
+                background var(--transition-fast),
+                transform 120ms ease-out,
+                box-shadow 120ms ease-out;
+  }
+
+  .timeline-chip-label {
+    display: flex;
+    flex-direction: column;
+    gap: 2px;
+  }
+
+  .timeline-chip-title {
+    text-transform: uppercase;
+    letter-spacing: 0.14em;
+    font-size: 9px;
+  }
+
+  .timeline-chip-desc {
+    font-size: 9px;
+    opacity: 0.8;
+  }
+
+  .timeline-chip-duration {
+    padding: 2px 5px;
+    border-radius: 999px;
+    background: rgba(32,32,48,0.9);
+    font-size: 9px;
+  }
+
+  .timeline-chip.active {
+    border-color: var(--accent-soft);
+    background: radial-gradient(circle at top left, rgba(210,181,126,0.16), rgba(12,12,20,0.98));
+    color: var(--text-main);
+    box-shadow: 0 0 0 1px rgba(210,181,126,0.2);
+    transform: translateY(-1px);
+  }
+
+  .timeline-chip.active .timeline-chip-duration {
+    background: rgba(210,181,126,0.16);
+  }
+
+  .transport-row {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 10px;
+    gap: 10px;
+  }
+
+  .transport-left {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+  }
+
+  .btn-ghost {
+    border-radius: 999px;
+    border: 1px solid var(--border-subtle);
+    padding: 6px 10px;
+    background: radial-gradient(circle at 0 0, rgba(255,255,255,0.05), transparent 60%);
+    color: var(--text-main);
+    font-size: 11px;
+    display: inline-flex;
+    align-items: center;
+    gap: 6px;
+    cursor: pointer;
+    letter-spacing: 0.12em;
+    text-transform: uppercase;
+    transition: border-color var(--transition-fast),
+                background var(--transition-fast),
+                transform 80ms ease-out,
+                box-shadow 80ms ease-out;
+  }
+
+  .btn-ghost span.icon {
+    width: 9px;
+    height: 9px;
+    border-radius: 999px;
+    background: radial-gradient(circle, #f4e0b9, #ba8b45 55%, #36251b 100%);
+    box-shadow: 0 0 0 1px rgba(0,0,0,0.6);
+  }
+
+  .btn-ghost:hover {
+    border-color: rgba(210,181,126,0.5);
+    background: radial-gradient(circle at 0 0, rgba(210,181,126,0.14), rgba(10,10,18,0.96));
+    box-shadow: 0 0 0 1px rgba(210,181,126,0.25);
+  }
+
+  .btn-ghost:active {
+    transform: translateY(1px);
+    box-shadow: none;
+  }
+
+  .transport-right {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    font-size: 10px;
+    color: var(--text-muted);
+  }
+
+  .play-toggle {
+    width: 26px;
+    height: 26px;
+    border-radius: 999px;
+    background: radial-gradient(circle at 30% 20%, #f9e6c4, #c39a5b 55%, #3c3022 100%);
+    border: 1px solid rgba(255,255,255,0.4);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #050509;
+    font-size: 11px;
+    cursor: pointer;
+    box-shadow:
+      0 0 0 1px rgba(0,0,0,0.8),
+      0 10px 18px rgba(0,0,0,0.8);
+    transition: transform 60ms ease-out, box-shadow 60ms ease-out, filter 120ms ease-out;
+  }
+
+  .play-toggle.paused {
+    filter: grayscale(0.1) brightness(0.95);
+    opacity: 0.9;
+  }
+
+  .play-toggle:active {
+    transform: translateY(1px) scale(0.97);
+    box-shadow: 0 3px 8px rgba(0,0,0,0.9);
+  }
+
+  .scene-indicator {
+    padding: 2px 7px;
+    border-radius: 999px;
+    border: 1px solid var(--border-subtle);
+    background: rgba(16,16,26,0.9);
+    font-size: 9px;
+    letter-spacing: 0.16em;
+    text-transform: uppercase;
+  }
+
+  .scene-indicator span {
+    color: var(--accent-strong);
+  }
+
+  .duration-label {
+    font-variant-numeric: tabular-nums;
+  }
+
+  .editor {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    gap: 8px;
+    margin-top: 4px;
+  }
+
+  .field-group {
+    background: rgba(10,10,16,0.9);
+    border-radius: 16px;
+    border: 1px solid var(--border-subtle);
+    padding: 9px 10px;
+    display: flex;
+    flex-direction: column;
+    gap: 6px;
+  }
+
+  .field-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: baseline;
+  }
+
+  .field-title {
+    font-size: 10px;
+    text-transform: uppercase;
+    letter-spacing: 0.18em;
+    color: var(--text-main);
+  }
+
+  .field-badge {
+    font-size: 9px;
+    color: var(--accent-strong);
+    letter-spacing: 0.16em;
+    text-transform: uppercase;
+    padding: 2px 7px;
+    border-radius: 999px;
+    border: 1px solid rgba(210,181,126,0.4);
+    background: rgba(210,181,126,0.14);
+  }
+
+  .field-subtitle {
+    font-size: 10px;
+    color: var(--text-muted);
+  }
+
+  textarea {
+    margin-top: 4px;
+    width: 100%;
+    min-height: 68px;
+    resize: vertical;
+    border-radius: 12px;
+    border: 1px solid rgba(60,60,84,0.9);
+    background: radial-gradient(circle at top, rgba(210,181,126,0.08), rgba(8,8,12,0.98));
+    color: var(--text-main);
+    font-family: inherit;
+    font-size: 11px;
+    padding: 7px 8px;
+    outline: none;
+    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.7);
+    transition: border-color var(--transition-fast),
+                box-shadow var(--transition-fast),
+                background var(--transition-fast);
+  }
+
+  textarea:focus {
+    border-color: rgba(210,181,126,0.7);
+    box-shadow:
+      0 0 0 1px rgba(210,181,126,0.35),
+      0 0 0 1px rgba(0,0,0,0.9);
+    background: radial-gradient(circle at top, rgba(210,181,126,0.14), rgba(8,8,12,0.98));
+  }
+
+  .helper-row {
+    display: flex;
+    justify-content: space-between;
+    font-size: 9px;
+    color: var(--text-muted);
+  }
+
+  .helper-row span strong {
+    color: var(--accent-strong);
+  }
+
+  .scene-meta-grid {
+    display: grid;
+    grid-template-columns: 1.2fr 1fr;
+    gap: 8px;
+  }
+
+  @media (max-width: 680px) {
+    .scene-meta-grid {
+      grid-template-columns: 1fr;
+    }
+  }
+
+  .pill-row {
+    display: flex;
+    gap: 6px;
+    flex-wrap: wrap;
+    margin-top: 3px;
+  }
+
+  .mini-pill {
+    font-size: 9px;
+    padding: 3px 6px;
+    border-radius: 999px;
+    border: 1px solid rgba(60,60,84,0.9);
+    color: var(--text-muted);
+    background: rgba(10,10,18,0.96);
+  }
+
+  .mini-pill.highlight {
+    border-color: rgba(210,181,126,0.7);
+    color: var(--accent-strong);
+    background: rgba(210,181,126,0.08);
+  }
+
+  .cta-note {
+    font-size: 10px;
+    color: var(--text-muted);
+  }
+
+  .cta-note span {
+    color: var(--accent-strong);
+  }
+
+  .footer-hint {
+    margin-top: 6px;
+    font-size: 9px;
+    color: var(--text-muted);
+    display: flex;
+    justify-content: space-between;
+    gap: 8px;
+    flex-wrap: wrap;
+  }
+
+  .footer-hint span {
+    opacity: 0.8;
+  }
+
+  .footer-hint span.code {
+    font-family: "SF Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
+    font-size: 9px;
+    background: rgba(12,12,18,0.9);
+    padding: 2px 4px;
+    border-radius: 5px;
+    border: 1px solid rgba(40,40,62,0.8);
+  }
+</style>
+</head>
+<body>
+<div class="app">
+  <section class="preview-column">
+    <header class="branding">
+      <div class="branding-title">Storyboard</div>
+      <div class="branding-main">Reels for Walls</div>
+      <div class="branding-sub">Vertical 9:16 | Wallcovering launch</div>
+    </header>
+
+    <div class="phone-frame-wrapper">
+      <div class="phone-outline">
+        <div class="notch"></div>
+        <div class="phone-bezel-inner">
+          <div class="reel-screen">
+            <div class="reel-status-bar">
+              <span>9:16 • Preview</span>
+              <span id="clock">00:00</span>
+            </div>
+            <div class="reel-progress-bar" id="progressBar">
+              <div class="reel-progress-segment"><div class="reel-progress-segment-fill"></div></div>
+              <div class="reel-progress-segment"><div class="reel-progress-segment-fill"></div></div>
+              <div class="reel-progress-segment"><div class="reel-progress-segment-fill"></div></div>
+              <div class="reel-progress-segment"><div class="reel-progress-segment-fill"></div></div>
+              <div class="reel-progress-segment"><div class="reel-progress-segment-fill"></div></div>
+            </div>
+            <div class="reel-header">
+              <div class="reel-profile">
+                <div class="reel-avatar"></div>
+                <div class="reel-handle">
+                  <div class="reel-handle-main">@atelier.wall</div>
+                  <div class="reel-handle-sub">New Collection • Storyboard</div>
+                </div>
+              </div>
+              <div class="reel-header-icons">
+                <div class="reel-header-dot-menu"></div>
+              </div>
+            </div>
+
+            <div class="scene-visual">
+              <div class="scene-gradient-overlay"></div>
+              <div class="scene-panes">
+                <div class="pane-left">
+                  <div class="pane-wall-stripes"></div>
+                </div>
+                <div class="pane-right">
+                  <div class="pane-right-grid">
+                    <div class="pane-swatch"></div>
+                    <div class="pane-detail"></div>
+                  </div>
+                </div>
+              </div>
+              <div class="pane-glow-orb"></div>
+              <div class="scene-label">
+                <span class="scene-label-dot"></span>
+                <span id="sceneLabelText">Hook • Scene 1</span>
+              </div>
+              <div class="scene-timer" id="sceneTimer">00:00 – 00:02</div>
+
+              <div class="caption-container">
+                <div class="caption-backdrop">
+                  <div class="caption-text" id="captionDisplay"></div>
+                  <div class="caption-meta">
+                    <div class="caption-meta-left">
+                      <span class="caption-pill" id="captionScenePill">Hook</span>
+                      <span class="caption-meta-tag">Animated captions • 9:16</span>
+                    </div>
+                    <div class="caption-meta-ticks" id="captionTicks">⏱ • 0.0s</div>
+                  </div>
+                </div>
+              </div>
+            </div> <!-- scene-visual -->
+          </div> <!-- reel-screen -->
+        </div>
+      </div>
+    </div>
+  </section>
+
+  <section class="controls-column">
+    <header class="panel-header">
+      <div>
+        <div class="panel-title">Reel Storyboard</div>
+        <div class="panel-subtitle">Plan 5 scenes for your wallcovering launch reel.</div>
+      </div>
+      <div class="tagline">Luxe wall stories, frame by frame</div>
+    </header>
+
+    <div class="scene-timeline" id="sceneTimeline">
+      <!-- Scene chips injected by JS -->
+    </div>
+
+    <div class="transport-row">
+      <div class="transport-left">
+        <button class="btn-ghost" id="resetBtn">
+          <span class="icon"></span>
+          Reset order
+        </button>
+        <span class="scene-indicator" id="sceneIndicator">
+          Scene <span>1</span> / 5
+        </span>
+      </div>
+      <div class="transport-right">
+        <button class="play-toggle paused" id="playToggle" aria-label="Play or pause preview">
+          ▷
+        </button>
+        <span class="duration-label" id="durationLabel">00.0 / 10.0s</span>
+      </div>
+    </div>
+
+    <div class="editor">
+      <div class="field-group">
+        <div class="field-header">
+          <div>
+            <div class="field-title" id="fieldTitle">Hook caption</div>
+            <div class="field-subtitle" id="fieldSubtitle">Stop the scroll in the first second. Lead with transformation.</div>
+          </div>
+          <div class="field-badge" id="fieldBadge">Scene 1 • Hook</div>
+        </div>
+        <textarea id="captionInput"></textarea>
+        <div class="helper-row">
+          <span>Use <strong>*asterisks*</strong> to highlight hero phrases.</span>
+          <span id="charCount">0 / 120</span>
+        </div>
+      </div>
+
+      <div class="scene-meta-grid">
+        <div class="field-group">
+          <div class="field-header">
+            <div class="field-title">Scene timing</div>
+          </div>
+          <div class="field-subtitle">Scenes auto-loop based on durations below (seconds).</div>
+          <div class="pill-row" id="durationPills">
+            <!-- Duration pills injected -->
+          </div>
+        </div>
+
+        <div class="field-group">
+          <div class="field-title">CTA & mood</div>
+          <div class="cta-note">
+            Final frame should invite action:
+            <span>"Save for your renovation", "Tap to order swatches"</span>, or a showroom visit.
+          </div>
+          <div class="pill-row">
+            <div class="mini-pill highlight">Muted glamour</div>
+            <div class="mini-pill">Warm metallics</div>
+            <div class="mini-pill">Textured close-ups</div>
+          </div>
+        </div>
+      </div>
+
+      <div class="footer-hint">
+        <span>Tip: Match each scene to a beat in your audio for seamless transitions.</span>
+        <span>Hook → Reveal → Texture → Swatches → <span class="code">CTA: "Your walls, reimagined."</span></span>
+      </div>
+    </div>
+  </section>
+</div>
+
+<script>
+(function () {
+  const scenes = [
+    {
+      id: 1,
+      key: "Hook",
+      name: "Hook",
+      title: "Hook caption",
+      subtitle: "Stop the scroll in the first second. Lead with transformation.",
+      duration: 2.0,
+      defaultCaption:
+        "*Bare wall* today. Boutique hotel tomorrow. Meet the wallcovering that changes everything."
+    },
+    {
+      id: 2,
+      key: "Reveal",
+      name: "Room reveal",
+      title: "Room reveal",
+      subtitle: "Pull back to show the full space dressed in your hero pattern.",
+      duration: 2.5,
+      defaultCaption:
+        "From *blank* to breathtaking. A single wall, washed in tailored texture and quiet shine."
+    },
+    {
+      id: 3,
+      key: "Texture",
+      name: "Texture detail",
+      title: "Texture close-up",
+      subtitle: "Let them feel the surface through the screen.",
+      duration: 2.0,
+      defaultCaption:
+        "Hand-drawn lines, layered inks, and a soft brushed shimmer you can almost *touch*."
+    },
+    {
+      id: 4,
+      key: "Swatches",
+      name: "Swatch grid",
+      title: "Swatch grid",
+      subtitle: "Show options: tones, scales, or material stories.",
+      duration: 1.8,
+      defaultCaption:
+        "Four curated colorways, designed to shift with sunrise, candlelight, and everything between."
+    },
+    {
+      id: 5,
+      key: "CTA",
+      name: "Call to action",
+      title: "CTA",
+      subtitle: "End with a clear, simple next step.",
+      duration: 1.7,
+      defaultCaption:
+        "*Save this wall* for your renovation board and tap for samples delivered to your studio."
+    }
+  ];
+
+  const sceneTimelineEl = document.getElementById("sceneTimeline");
+  const durationPillsEl = document.getElementById("durationPills");
+  const captionDisplayEl = document.getElementById("captionDisplay");
+  const captionInputEl = document.getElementById("captionInput");
+  const sceneLabelTextEl = document.getElementById("sceneLabelText");
+  const sceneTimerEl = document.getElementById("sceneTimer");
+  const captionScenePillEl = document.getElementById("captionScenePill");
+  const captionTicksEl = document.getElementById("captionTicks");
+  const sceneIndicatorEl = document.getElementById("sceneIndicator");
+  const durationLabelEl = document.getElementById("durationLabel");
+  const playToggleEl = document.getElementById("playToggle");
+  const resetBtnEl = document.getElementById("resetBtn");
+  const fieldTitleEl = document.getElementById("fieldTitle");
+  const fieldSubtitleEl = document.getElementById("fieldSubtitle");
+  const fieldBadgeEl = document.getElementById("fieldBadge");
+  const charCountEl = document.getElementById("charCount");
+  const clockEl = document.getElementById("clock");
+  const progressSegments = Array.from(
+    document.querySelectorAll(".reel-progress-segment-fill")
+  );
+
+  let currentSceneIndex = 0;
+  let isPlaying = false;
+  let startTime = null;
+  let currentSceneStart = 0;
+  let frameReq = null;
+  const maxChars = 120;
+
+  const captionValues = {};
+  scenes.forEach(scene => {
+    captionValues[scene.id] = scene.defaultCaption;
+  });
+
+  function totalDuration() {
+    return scenes.reduce((sum, s) => sum + s.duration, 0);
+  }
+
+  function formatTime(ms) {
+    const sec = ms / 1000;
+    const m = Math.floor(sec / 60);
+    const s = Math.floor(sec % 60);
+    return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
+  }
+
+  function formatSeconds(sec) {
+    return sec.toFixed(1).padStart(4, "0");
+  }
+
+  function formatSceneRange(sceneIndex, offsetSec, sceneStartGlobal) {
+    let offset = 0;
+    for (let i = 0; i < sceneIndex; i++) offset += scenes[i].duration;
+    const start = offset;
+    const end = start + scenes[sceneIndex].duration;
+    return `${start.toFixed(1).padStart(4, "0")} – ${end
+      .toFixed(1)
+      .padStart(4, "0")}s`;
+  }
+
+  function renderCaption(scene) {
+    const raw = captionValues[scene.id] || "";
+    const escaped = raw
+      .replace(/&/g, "&amp;")
+      .replace(/</g, "&lt;")
+      .replace(/>/g, "&gt;");
+    const withHighlights = escaped.replace(
+      /\*(.+?)\*/g,
+      '<span class="key">$1</span>'
+    );
+    captionDisplayEl.innerHTML = withHighlights;
+    captionDisplayEl.classList.remove("fade-in");
+    void captionDisplayEl.offsetWidth;
+    captionDisplayEl.classList.add("fade-in");
+  }
+
+  function updateSceneMeta() {
+    const scene = scenes[currentSceneIndex];
+    const sceneNumber = currentSceneIndex + 1;
+    sceneLabelTextEl.textContent = `${scene.key} • Scene ${sceneNumber}`;
+    captionScenePillEl.textContent = scene.key;
+    sceneIndicatorEl.innerHTML = `Scene <span>${sceneNumber}</span> / ${scenes.length}`;
+    fieldTitleEl.textContent = scene.title;
+    fieldSubtitleEl.textContent = scene.subtitle;
+    fieldBadgeEl.textContent = `Scene ${sceneNumber} • ${scene.name}`;
+    captionInputEl.value = captionValues[scene.id] || "";
+    updateCharCount();
+    captionTicksEl.textContent = `⏱ • 0.0s`;
+    updateSceneTimer(0);
+    renderCaption(scene);
+  }
+
+  function updateSceneTimer(offsetSec) {
+    const scene = scenes[currentSceneIndex];
+    sceneTimerEl.textContent = formatSceneRange(
+      currentSceneIndex,
+      offsetSec,
+      0
+    );
+  }
+
+  function updateTimelineUI() {
+    const chips = Array.from(
+      sceneTimelineEl.querySelectorAll(".timeline-chip")
+    );
+    chips.forEach((chip, idx) => {
+      chip.classList.toggle("active", idx === currentSceneIndex);
+    });
+
+    const total = totalDuration();
+    durationLabelEl.textContent = `${formatSeconds(
+      elapsedMs() / 1000
+    )} / ${total.toFixed(1)}s`;
+  }
+
+  function updateDurationPills() {
+    durationPillsEl.innerHTML = "";
+    scenes.forEach((scene, idx) => {
+      const pill = document.createElement("button");
+      pill.type = "button";
+      pill.className =
+        "mini-pill" + (idx === currentSceneIndex ? " highlight" : "");
+      pill.textContent = `${scene.key} • ${scene.duration.toFixed(1)}s`;
+      durationPillsEl.appendChild(pill);
+    });
+  }
+
+  function buildSceneTimeline() {
+    sceneTimelineEl.innerHTML = "";
+    scenes.forEach((scene, idx) => {
+      const chip = document.createElement("button");
+      chip.type = "button";
+      chip.className =
+        "timeline-chip" + (idx === currentSceneIndex ? " active" : "");
+      chip.dataset.index = idx;
+
+      chip.innerHTML = `
+        <div class="timeline-chip-label">
+          <span class="timeline-chip-title">${scene.key}</span>
+          <span class="timeline-chip-desc">${scene.name}</span>
+        </div>
+        <span class="timeline-chip-duration">${scene.duration.toFixed(
+          1
+        )}s</span>
+      `;
+      chip.addEventListener("click", () => {
+        jumpToScene(idx);
+      });
+      sceneTimelineEl.appendChild(chip);
+    });
+  }
+
+  function buildDurationPills() {
+    updateDurationPills();
+  }
+
+  function jumpToScene(idx) {
+    currentSceneIndex = idx;
+    currentSceneStart = sceneStartOffset(idx);
+    if (isPlaying) {
+      startTime = performance.now() - currentSceneStart * 1000;
+    }
+    updateSceneMeta();
+    updateTimelineUI();
+    updateProgress(0);
+  }
+
+  function sceneStartOffset(index) {
+    let offset = 0;
+    for (let i = 0; i < index; i++) offset += scenes[i].duration;
+    return offset;
+  }
+
+  function updateProgress(nowMs) {
+    const total = totalDuration();
+    const globalElapsedSec = isPlaying
+      ? (nowMs - startTime) / 1000
+      : currentSceneStart;
+    const loopedElapsed =
+      ((globalElapsedSec % total) + total) % total;
+
+    // determine current scene based on loopedElapsed
+    let acc = 0;
+    let newIndex = 0;
+    for (let i = 0; i < scenes.length; i++) {
+      const sDur = scenes[i].duration;
+      if (loopedElapsed < acc + sDur) {
+        newIndex = i;
+        break;
+      }
+      acc += sDur;
+    }
+
+    if (newIndex !== currentSceneIndex) {
+      currentSceneIndex = newIndex;
+      currentSceneStart = acc;
+      updateSceneMeta();
+      updateDurationPills();
+    }
+
+    const sceneElapsed = loopedElapsed - currentSceneStart;
+    captionTicksEl.textContent = `⏱ • ${sceneElapsed.toFixed(1)}s`;
+    updateSceneTimer(sceneElapsed);
+
+    // update progress bar
+    let running = 0;
+    scenes.forEach((scene, idx) => {
+      const segFill = progressSegments[idx];
+      const segDur = scene.duration;
+      let widthPercent = 0;
+      if (loopedElapsed >= running + segDur) {
+        widthPercent = 100;
+      } else if (loopedElapsed <= running) {
+        widthPercent = 0;
+      } else {
+        const local = loopedElapsed - running;
+        widthPercent = (local / segDur) * 100;
+      }
+      segFill.style.width = `${widthPercent}%`;
+      running += segDur;
+    });
+
+    // status bar clock
+    clockEl.textContent = formatTime(loopedElapsed * 1000);
+
+    durationLabelEl.textContent = `${formatSeconds(
+      loopedElapsed
+    )} / ${total.toFixed(1)}s`;
+    updateTimelineUI();
+  }
+
+  function elapsedMs() {
+    if (!isPlaying) {
+      return currentSceneStart * 1000;
+    }
+    const now = performance.now();
+    return now - startTime;
+  }
+
+  function loop(now) {
+    if (!isPlaying) return;
+    updateProgress(now);
+    frameReq = requestAnimationFrame(loop);
+  }
+
+  function play() {
+    if (isPlaying) return;
+    isPlaying = true;
+    playToggleEl.textContent = "❚❚";
+    playToggleEl.classList.remove("paused");
+    const total = totalDuration();
+    const initialSec =
+      currentSceneStart % total;
+    startTime = performance.now() - initialSec * 1000;
+    frameReq = requestAnimationFrame(loop);
+  }
+
+  function pause() {
+    if (!isPlaying) return;
+    isPlaying = false;
+    playToggleEl.textContent = "▷";
+    playToggleEl.classList.add("paused");
+    cancelAnimationFrame(frameReq);
+    const total = totalDuration();
+    const elapsedSec = (performance.now() - startTime) / 1000;
+    const looped = ((elapsedSec % total) + total) % total;
+    currentSceneStart = looped;
+    updateProgress(performance.now());
+  }
+
+  function togglePlay() {
+    if (isPlaying) pause();
+    else play();
+  }
+
+  function resetOrder() {
+    pause();
+    currentSceneIndex = 0;
+    currentSceneStart = 0;
+    scenes.slice().sort((a, b) => a.id - b.id);
+    buildSceneTimeline();
+    updateSceneMeta();
+    updateDurationPills();
+    progressSegments.forEach(seg => (seg.style.width = "0%"));
+    updateProgress(performance.now());
+  }
+
+  function updateCharCount() {
+    const len = captionInputEl.value.length;
+    charCountEl.textContent = `${len} / ${maxChars}`;
+    charCountEl.style.color =
+      len > maxChars ? "var(--danger)" : "var(--text-muted)";
+  }
+
+  captionInputEl.addEventListener("input", () => {
+    captionValues[scenes[currentSceneIndex].id] = captionInputEl.value;
+    updateCharCount();
+    renderCaption(scenes[currentSceneIndex]);
+  });
+
+  playToggleEl.addEventListener("click", togglePlay);
+  resetBtnEl.addEventListener("click", resetOrder);
+
+  captionInputEl.addEventListener("keydown", e => {
+    if (e.key === "Tab") {
+      e.preventDefault();
+      const nextIndex =
+        (currentSceneIndex + 1) % scenes.length;
+      jumpToScene(nextIndex);
+      captionInputEl.focus();
+      captionInputEl.select();
+    }
+  });
+
+  document.addEventListener("visibilitychange", () => {
+    if (document.hidden) {
+      pause();
+    }
+  });
+
+  // Initialize UI
+  buildSceneTimeline();
+  buildDurationPills();
+  updateSceneMeta();
+  updateProgress(performance.now());
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/b72f0e9e751b/gpt.png b/data/artifacts/b72f0e9e751b/gpt.png
new file mode 100644
index 0000000..0fe27c4
Binary files /dev/null and b/data/artifacts/b72f0e9e751b/gpt.png differ
diff --git a/data/artifacts/b72f0e9e751b/hermes3-8b.html b/data/artifacts/b72f0e9e751b/hermes3-8b.html
new file mode 100644
index 0000000..893da25
--- /dev/null
+++ b/data/artifacts/b72f0e9e751b/hermes3-8b.html
@@ -0,0 +1,155 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Wallcovering Brand Storyboard Tool</title>
+    <style>
+        body {
+            margin: 0;
+            padding: 0;
+            font-family: Arial, sans-serif;
+            color: white;
+            background-color: #000;
+        }
+        
+        .container {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            height: 100vh;
+        }
+        
+        .phone-frame {
+            position: relative;
+            width: 135px;
+            height: 270px;
+            background-color: #333;
+            border-radius: 10px;
+            overflow: hidden;
+        }
+        
+        .phone-frame::after {
+            content: '';
+            display: block;
+            position: absolute;
+            top: 20px; 
+            right: -15px;
+            width: 0;
+            height: 0;
+            border-top: 135px solid transparent;
+            border-bottom: 135px solid #333;
+            border-right: 15px solid white;
+        }
+        
+        .scene {
+            position: absolute;
+            top: 20px;
+            left: 20px;
+            width: 90%;
+            height: 80%;
+            background-position: center;
+            background-repeat: no-repeat;
+            background-size: cover;
+        }
+        
+        .scene-text {
+            position: absolute;
+            bottom: 10px; 
+            left: 10px;
+            color: white;
+            font-size: 12px;
+            text-shadow: 1px 1px 0 #000;
+        }
+        
+        .progress-bar {
+            position: absolute;
+            top: 20px;
+            right: 20px;
+            width: 90%;
+            height: 5px;
+            background-color: #444;
+            border-radius: 5px;
+            box-shadow: 0 2px 6px rgba(255, 255, 255, 0.3);
+        }
+        
+        .progress-bar-fill {
+            position: absolute;
+            top: 0;
+            left: 0; 
+            height: 100%;
+            background-color: #ff5f58;
+            width: 20%;
+            border-radius: 5px 5px 0 0;
+        }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <div class="phone-frame">
+            <div class="scene" style="background-image:url('https://picsum.photos/135/270?image=1');"></div>
+            <div class="scene-text">Welcome to Our Brand!</div>
+        </div>
+        
+        <div class="phone-frame">
+            <div class="scene" style="background-image:url('https://picsum.photos/135/270?image=10');"></div>
+            <div class="scene-text">Transform Your Space</div>
+        </div>
+        
+        <div class="phone-frame">
+            <div class="scene" style="background-image:url('https://picsum.photos/135/270?image=100');"></div>
+            <div class="scene-text">Discover the Texture</div>
+        </div>
+        
+        <div class="phone-frame">
+            <div class="scene" style="background-image:url('https://picsum.photos/135/270?image=1010');"></div>
+            <div class="scene-text">Choose Your Swatch</div>
+        </div>
+        
+        <div class="phone-frame">
+            <div class="scene" style="background-image:url('https://picsum.photos/135/270?image=10000');"></div>
+            <div class="scene-text">Shop Now!</div>
+        </div>
+        
+        <div class="progress-bar">
+            <div class="progress-bar-fill"></div>
+        </div>
+    </div>
+    
+    <script>
+        let timer = null;
+        let currentIndex = 0;
+
+        function startTimer() {
+            const frames = document.querySelectorAll('.phone-frame');
+            const duration = 5; // seconds
+            
+            timer = setInterval(() => {
+                if (currentIndex >= frames.length) {
+                    currentIndex = 0;
+                }
+                
+                frames[currentIndex].style.zIndex = '1';
+                frames[currentIndex].querySelector('.scene').style.opacity = '1';
+                frames[currentIndex].querySelector('.scene-text').style.opacity = '1';
+
+                const progressFill = document.querySelector('.progress-bar-fill');
+                const progressWidth = (currentIndex / frames.length) * 100;
+                progressFill.style.width = `${progressWidth}%`;
+                
+                currentIndex++;
+                
+            }, duration * 1000);
+        }
+
+        startTimer();
+
+        function pausePlay() {
+            clearInterval(timer);
+            startTimer();
+        }
+        
+        document.querySelector('.phone-frame').addEventListener('click', pausePlay);
+    </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/b72f0e9e751b/hermes3-8b.png b/data/artifacts/b72f0e9e751b/hermes3-8b.png
new file mode 100644
index 0000000..7308b12
Binary files /dev/null and b/data/artifacts/b72f0e9e751b/hermes3-8b.png differ
diff --git a/data/artifacts/b72f0e9e751b/hf-qwen-coder-32b.html b/data/artifacts/b72f0e9e751b/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..d29440f
--- /dev/null
+++ b/data/artifacts/b72f0e9e751b/hf-qwen-coder-32b.html
@@ -0,0 +1,154 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Instagram Reel Storyboard</title>
+    <style>
+        body, html {
+            margin: 0;
+            padding: 0;
+            height: 100%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            background-color: #121212;
+            color: white;
+            font-family: Arial, sans-serif;
+        }
+        .phone-frame {
+            width: 375px;
+            height: 667px;
+            border-radius: 40px;
+            overflow: hidden;
+            position: relative;
+            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.8);
+        }
+        .screen {
+            width: 100%;
+            height: 100%;
+            position: absolute;
+            top: 0;
+            left: 0;
+            background-size: cover;
+            background-position: center;
+        }
+        .scene {
+            display: none;
+            position: relative;
+        }
+        .scene.active {
+            display: block;
+        }
+        .caption {
+            position: absolute;
+            bottom: 20px;
+            left: 20px;
+            right: 20px;
+            font-size: 18px;
+            opacity: 0;
+            transition: opacity 0.5s ease-in-out;
+        }
+        .scene.active .caption {
+            opacity: 1;
+        }
+        .controls {
+            position: absolute;
+            bottom: 10px;
+            left: 20px;
+            right: 20px;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+        }
+        .progress-bar {
+            width: 100%;
+            height: 5px;
+            background-color: rgba(255, 255, 255, 0.3);
+            position: absolute;
+            bottom: 0;
+            left: 0;
+        }
+        .fill {
+            width: 0;
+            height: 100%;
+            background-color: white;
+            transition: width 6s linear;
+        }
+    </style>
+</head>
+<body>
+    <div class="phone-frame">
+        <div id="screen" class="screen"></div>
+        <div id="controls" class="controls">
+            <button onclick="togglePlay()">Play/Pause</button>
+            <div class="progress-bar">
+                <div id="fill" class="fill"></div>
+            </div>
+        </div>
+        <div id="scene1" class="scene active">
+            <div class="caption">Discover the luxury of elegance.</div>
+        </div>
+        <div id="scene2" class="scene">
+            <div class="caption">Transform your space with our textures.</div>
+        </div>
+        <div id="scene3" class="scene">
+            <div class="caption">Feel the smoothness of each touch.</div>
+        </div>
+        <div id="scene4" class="scene">
+            <div class="caption">Choose your perfect color palette.</div>
+        </div>
+        <div id="scene5" class="scene">
+            <div class="caption">Contact us for a custom design today!</div>
+        </div>
+    </div>
+
+    <script>
+        const scenes = [
+            { image: 'https://via.placeholder.com/375x667?text=Hook', duration: 6 },
+            { image: 'https://via.placeholder.com/375x667?text=Room+Reveal', duration: 6 },
+            { image: 'https://via.placeholder.com/375x667?text=Close-up+Texture', duration: 6 },
+            { image: 'https://via.placeholder.com/375x667?text=Swatch+Grid', duration: 6 },
+            { image: 'https://via.placeholder.com/375x667?text=CTA', duration: 6 }
+        ];
+        let currentScene = 0;
+        let timer;
+        let fillWidth = 0;
+        const screen = document.getElementById('screen');
+        const fill = document.getElementById('fill');
+
+        function updateScene() {
+            scenes.forEach((scene, index) => {
+                document.getElementById(`scene${index + 1}`).classList.toggle('active', index === currentScene);
+            });
+            screen.style.backgroundImage = `url(${scenes[currentScene].image})`;
+            fillWidth = 0;
+            fill.style.width = `${fillWidth}%`;
+        }
+
+        function startTimer() {
+            timer = setInterval(() => {
+                fillWidth += 1 / (6 * 100);
+                fill.style.width = `${fillWidth * 100}%`;
+
+                if (fillWidth >= 1) {
+                    currentScene = (currentScene + 1) % scenes.length;
+                    updateScene();
+                }
+            }, 10);
+        }
+
+        function togglePlay() {
+            if (timer) {
+                clearInterval(timer);
+                timer = null;
+            } else {
+                startTimer();
+            }
+        }
+
+        updateScene();
+        startTimer();
+    </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/b72f0e9e751b/hf-qwen-coder-32b.png b/data/artifacts/b72f0e9e751b/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..311886c
Binary files /dev/null and b/data/artifacts/b72f0e9e751b/hf-qwen-coder-32b.png differ
diff --git a/data/artifacts/b72f0e9e751b/kimi.html b/data/artifacts/b72f0e9e751b/kimi.html
new file mode 100644
index 0000000..1812e7a
--- /dev/null
+++ b/data/artifacts/b72f0e9e751b/kimi.html
@@ -0,0 +1,812 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Luxe Wallcovering Storyboard</title>
+<style>
+:root {
+  --gold: #d4af37;
+  --gold-light: #f4e5c2;
+  --dark: #0a0a0a;
+  --dark-grey: #1a1a1a;
+  --grey: #2a2a2a;
+  --text: #e8e8e8;
+  --transition: cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+}
+
+body {
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+  background: var(--dark);
+  color: var(--text);
+  min-height: 100vh;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 20px;
+  overflow-x: hidden;
+}
+
+header {
+  text-align: center;
+  margin-bottom: 30px;
+  letter-spacing: 2px;
+}
+
+h1 {
+  font-weight: 300;
+  font-size: 1.5rem;
+  color: var(--gold);
+  text-transform: uppercase;
+  margin-bottom: 8px;
+}
+
+.subtitle {
+  font-size: 0.75rem;
+  color: #666;
+  letter-spacing: 3px;
+}
+
+.workspace {
+  display: flex;
+  gap: 40px;
+  align-items: flex-start;
+  justify-content: center;
+  flex-wrap: wrap;
+  width: 100%;
+  max-width: 1200px;
+}
+
+.phone-container {
+  position: relative;
+  filter: drop-shadow(0 20px 40px rgba(0,0,0,0.8));
+}
+
+.phone-frame {
+  width: 375px;
+  height: 667px;
+  background: var(--dark-grey);
+  border-radius: 40px;
+  padding: 12px;
+  position: relative;
+  box-shadow: 
+    0 0 0 2px #333,
+    inset 0 0 20px rgba(0,0,0,0.5);
+}
+
+.phone-notch {
+  position: absolute;
+  top: 12px;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 120px;
+  height: 25px;
+  background: var(--dark);
+  border-radius: 0 0 20px 20px;
+  z-index: 10;
+}
+
+.screen {
+  width: 100%;
+  height: 100%;
+  background: var(--dark);
+  border-radius: 30px;
+  overflow: hidden;
+  position: relative;
+}
+
+.progress-container {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 3px;
+  background: rgba(255,255,255,0.1);
+  z-index: 100;
+}
+
+.progress-bar {
+  height: 100%;
+  background: var(--gold);
+  width: 0%;
+  transition: width 0.1s linear;
+  box-shadow: 0 0 10px var(--gold);
+}
+
+.scene {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  transition: opacity 0.8s var(--transition);
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  padding: 40px 30px;
+}
+
+.scene.active {
+  opacity: 1;
+}
+
+/* Scene 1: Hook */
+.scene-hook {
+  background: radial-gradient(circle at 30% 30%, #1a1a2e 0%, #0a0a0a 100%);
+  position: relative;
+  overflow: hidden;
+}
+
+.scene-hook::before {
+  content: '';
+  position: absolute;
+  width: 200%;
+  height: 200%;
+  background: repeating-linear-gradient(
+    45deg,
+    transparent,
+    transparent 10px,
+    rgba(212, 175, 55, 0.03) 10px,
+    rgba(212, 175, 55, 0.03) 20px
+  );
+  animation: drift 20s linear infinite;
+}
+
+@keyframes drift {
+  0% { transform: translate(0, 0); }
+  100% { transform: translate(-50px, -50px); }
+}
+
+.luxury-text {
+  font-size: 2.2rem;
+  font-weight: 300;
+  text-align: center;
+  line-height: 1.2;
+  background: linear-gradient(135deg, var(--gold-light) 0%, var(--gold) 50%, var(--gold-light) 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-transform: uppercase;
+  letter-spacing: 3px;
+  opacity: 0;
+  transform: translateY(30px);
+  transition: all 1s var(--transition);
+}
+
+.scene.active .luxury-text {
+  opacity: 1;
+  transform: translateY(0);
+}
+
+/* Scene 2: Room */
+.scene-room {
+  background: linear-gradient(135deg, #1e1e1e 0%, #2d2d2d 100%);
+  position: relative;
+}
+
+.wall-left {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 50%;
+  height: 100%;
+  background: linear-gradient(90deg, #2a2520 0%, #3e3630 100%);
+  transform: skewY(-5deg);
+  transform-origin: top left;
+}
+
+.wall-right {
+  position: absolute;
+  right: 0;
+  top: 0;
+  width: 50%;
+  height: 100%;
+  background: linear-gradient(-90deg, #2a2520 0%, #3e3630 100%);
+  transform: skewY(5deg);
+  transform-origin: top right;
+}
+
+.wall-pattern {
+  position: absolute;
+  inset: 0;
+  background-image: repeating-linear-gradient(
+    0deg,
+    transparent,
+    transparent 50px,
+    rgba(212, 175, 55, 0.05) 50px,
+    rgba(212, 175, 55, 0.05) 51px
+  );
+}
+
+.light-beam {
+  position: absolute;
+  top: -20%;
+  left: 20%;
+  width: 60%;
+  height: 80%;
+  background: linear-gradient(180deg, rgba(255,255,255,0.1) 0%, transparent 100%);
+  filter: blur(40px);
+  transform: rotate(-15deg);
+}
+
+/* Scene 3: Texture */
+.scene-texture {
+  background: var(--dark-grey);
+  position: relative;
+}
+
+.texture-pattern {
+  position: absolute;
+  inset: 0;
+  background-color: #1a1a1a;
+  background-image: 
+    repeating-linear-gradient(90deg, transparent, transparent 2px, rgba(212,175,55,0.1) 2px, rgba(212,175,55,0.1) 4px),
+    repeating-linear-gradient(0deg, transparent, transparent 20px, rgba(255,255,255,0.02) 20px, rgba(255,255,255,0.02) 21px);
+  background-size: 100% 100%, 100% 100%;
+}
+
+.texture-shine {
+  position: absolute;
+  inset: 0;
+  background: radial-gradient(circle at 50% 50%, rgba(212,175,55,0.2) 0%, transparent 70%);
+  animation: pulse 4s ease-in-out infinite;
+}
+
+@keyframes pulse {
+  0%, 100% { opacity: 0.3; }
+  50% { opacity: 0.6; }
+}
+
+/* Scene 4: Swatches */
+.scene-swatches {
+  background: var(--dark);
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 15px;
+  padding: 60px 30px;
+}
+
+.swatch {
+  border-radius: 12px;
+  position: relative;
+  overflow: hidden;
+  box-shadow: 0 4px 15px rgba(0,0,0,0.5);
+  border: 1px solid rgba(255,255,255,0.1);
+  transform: scale(0.9);
+  opacity: 0;
+  transition: all 0.6s var(--transition);
+}
+
+.scene.active .swatch {
+  transform: scale(1);
+  opacity: 1;
+}
+
+.scene.active .swatch:nth-child(1) { transition-delay: 0.1s; }
+.scene.active .swatch:nth-child(2) { transition-delay: 0.2s; }
+.scene.active .swatch:nth-child(3) { transition-delay: 0.3s; }
+.scene.active .swatch:nth-child(4) { transition-delay: 0.4s; }
+
+.swatch-gold { background: linear-gradient(135deg, #d4af37 0%, #f4e5c2 50%, #d4af37 100%); }
+.swatch-bronze { background: linear-gradient(135deg, #8b7355 0%, #d4af37 100%); }
+.swatch-slate { background: linear-gradient(135deg, #2c3e50 0%, #4a5f7f 100%); }
+.swatch-cream { background: linear-gradient(135deg, #f5f5dc 0%, #e8dcc0 100%); }
+
+/* Scene 5: CTA */
+.scene-cta {
+  background: radial-gradient(circle at center, #1a1a2e 0%, #000 100%);
+  text-align: center;
+}
+
+.cta-button {
+  margin-top: 30px;
+  padding: 18px 40px;
+  background: transparent;
+  border: 1px solid var(--gold);
+  color: var(--gold);
+  font-size: 0.9rem;
+  letter-spacing: 3px;
+  text-transform: uppercase;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: all 0.3s;
+  opacity: 0;
+  transform: translateY(20px);
+}
+
+.scene.active .cta-button {
+  opacity: 1;
+  transform: translateY(0);
+  transition-delay: 0.5s;
+}
+
+.cta-button::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: -100%;
+  width: 100%;
+  height: 100%;
+  background: var(--gold);
+  transition: left 0.3s;
+  z-index: -1;
+}
+
+.cta-button:hover {
+  color: var(--dark);
+}
+
+.cta-button:hover::before {
+  left: 0;
+}
+
+.caption-overlay {
+  position: absolute;
+  bottom: 80px;
+  left: 30px;
+  right: 30px;
+  text-align: center;
+  z-index: 50;
+  pointer-events: none;
+}
+
+.caption-text {
+  font-size: 1.3rem;
+  font-weight: 400;
+  color: white;
+  text-shadow: 0 2px 10px rgba(0,0,0,0.8);
+  letter-spacing: 1px;
+  line-height: 1.4;
+  opacity: 0;
+  transform: translateY(20px);
+  transition: all 0.8s var(--transition);
+}
+
+.scene.active .caption-text {
+  opacity: 1;
+  transform: translateY(0);
+  transition-delay: 0.3s;
+}
+
+.controls-overlay {
+  position: absolute;
+  bottom: 30px;
+  left: 50%;
+  transform: translateX(-50%);
+  z-index: 100;
+  display: flex;
+  gap: 20px;
+  align-items: center;
+}
+
+.play-pause-btn {
+  width: 50px;
+  height: 50px;
+  border-radius: 50%;
+  background: rgba(255,255,255,0.1);
+  backdrop-filter: blur(10px);
+  border: 1px solid rgba(255,255,255,0.2);
+  color: white;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+  transition: all 0.3s;
+  font-size: 1.2rem;
+}
+
+.play-pause-btn:hover {
+  background: var(--gold);
+  color: var(--dark);
+  transform: scale(1.1);
+}
+
+.editor-panel {
+  background: var(--dark-grey);
+  padding: 30px;
+  border-radius: 20px;
+  width: 350px;
+  border: 1px solid var(--grey);
+}
+
+.editor-header {
+  font-size: 0.8rem;
+  text-transform: uppercase;
+  letter-spacing: 2px;
+  color: var(--gold);
+  margin-bottom: 20px;
+  border-bottom: 1px solid var(--grey);
+  padding-bottom: 10px;
+}
+
+.scene-editor {
+  margin-bottom: 20px;
+  padding: 15px;
+  background: rgba(0,0,0,0.3);
+  border-radius: 10px;
+  border: 1px solid transparent;
+  transition: all 0.3s;
+}
+
+.scene-editor.active {
+  border-color: var(--gold);
+  background: rgba(212,175,55,0.05);
+}
+
+.scene-label {
+  font-size: 0.7rem;
+  color: #666;
+  text-transform: uppercase;
+  letter-spacing: 1px;
+  margin-bottom: 8px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.scene-number {
+  color: var(--gold);
+  font-weight: bold;
+}
+
+.caption-input {
+  width: 100%;
+  background: transparent;
+  border: none;
+  border-bottom: 1px solid var(--grey);
+  color: var(--text);
+  font-size: 0.95rem;
+  padding: 8px 0;
+  font-family: inherit;
+  transition: border-color 0.3s;
+}
+
+.caption-input:focus {
+  outline: none;
+  border-color: var(--gold);
+}
+
+.transport-controls {
+  display: flex;
+  gap: 10px;
+  margin-top: 20px;
+  padding-top: 20px;
+  border-top: 1px solid var(--grey);
+}
+
+.transport-btn {
+  flex: 1;
+  padding: 12px;
+  background: var(--grey);
+  border: none;
+  color: var(--text);
+  border-radius: 8px;
+  cursor: pointer;
+  font-size: 0.8rem;
+  letter-spacing: 1px;
+  text-transform: uppercase;
+  transition: all 0.3s;
+}
+
+.transport-btn:hover {
+  background: var(--gold);
+  color: var(--dark);
+}
+
+.timeline-indicator {
+  display: flex;
+  gap: 5px;
+  margin-bottom: 20px;
+  justify-content: center;
+}
+
+.timeline-dot {
+  width: 8px;
+  height: 8px;
+  border-radius: 50%;
+  background: var(--grey);
+  transition: all 0.3s;
+}
+
+.timeline-dot.active {
+  background: var(--gold);
+  transform: scale(1.2);
+  box-shadow: 0 0 10px var(--gold);
+}
+
+@media (max-width: 800px) {
+  .workspace {
+    flex-direction: column;
+    align-items: center;
+  }
+  
+  .phone-frame {
+    width: 320px;
+    height: 569px;
+  }
+  
+  .editor-panel {
+    width: 100%;
+    max-width: 400px;
+  }
+}
+</style>
+</head>
+<body>
+
+<header>
+  <h1>Atelier Storyboard</h1>
+  <div class="subtitle">Vertical Content Studio</div>
+</header>
+
+<div class="workspace">
+  <div class="phone-container">
+    <div class="phone-frame">
+      <div class="phone-notch"></div>
+      <div class="screen" id="screen">
+        <div class="progress-container">
+          <div class="progress-bar" id="progressBar"></div>
+        </div>
+        
+        <!-- Scene 1: Hook -->
+        <div class="scene scene-hook active" data-index="0">
+          <div class="luxury-text" id="caption-0">Transform<br>Your Space</div>
+        </div>
+        
+        <!-- Scene 2: Room -->
+        <div class="scene scene-room" data-index="1">
+          <div class="wall-left">
+            <div class="wall-pattern"></div>
+          </div>
+          <div class="wall-right">
+            <div class="wall-pattern"></div>
+          </div>
+          <div class="light-beam"></div>
+          <div class="caption-overlay">
+            <div class="caption-text" id="caption-1">Elegance in Every Roll</div>
+          </div>
+        </div>
+        
+        <!-- Scene 3: Texture -->
+        <div class="scene scene-texture" data-index="2">
+          <div class="texture-pattern"></div>
+          <div class="texture-shine"></div>
+          <div class="caption-overlay">
+            <div class="caption-text" id="caption-2">Tactile Luxury</div>
+          </div>
+        </div>
+        
+        <!-- Scene 4: Swatches -->
+        <div class="scene scene-swatches" data-index="3">
+          <div class="swatch swatch-gold"></div>
+          <div class="swatch swatch-bronze"></div>
+          <div class="swatch swatch-slate"></div>
+          <div class="swatch swatch-cream"></div>
+          <div class="caption-overlay" style="bottom: 40px;">
+            <div class="caption-text" id="caption-3">Curated Palettes</div>
+          </div>
+        </div>
+        
+        <!-- Scene 5: CTA -->
+        <div class="scene scene-cta" data-index="4">
+          <div class="luxury-text" style="font-size: 1.8rem; margin-bottom: 20px;" id="caption-4">Define Your<br>Sanctuary</div>
+          <button class="cta-button">Shop Collection</button>
+        </div>
+        
+        <div class="controls-overlay">
+          <button class="play-pause-btn" id="playPauseBtn">❚❚</button>
+        </div>
+      </div>
+    </div>
+  </div>
+  
+  <div class="editor-panel">
+    <div class="editor-header">Scene Editor</div>
+    
+    <div class="timeline-indicator" id="timelineIndicator">
+      <div class="timeline-dot active"></div>
+      <div class="timeline-dot"></div>
+      <div class="timeline-dot"></div>
+      <div class="timeline-dot"></div>
+      <div class="timeline-dot"></div>
+    </div>
+    
+    <div class="scene-editor active" data-scene="0">
+      <div class="scene-label">
+        <span>Hook</span>
+        <span class="scene-number">01</span>
+      </div>
+      <input type="text" class="caption-input" value="Transform Your Space" data-scene="0">
+    </div>
+    
+    <div class="scene-editor" data-scene="1">
+      <div class="scene-label">
+        <span>Room Reveal</span>
+        <span class="scene-number">02</span>
+      </div>
+      <input type="text" class="caption-input" value="Elegance in Every Roll" data-scene="1">
+    </div>
+    
+    <div class="scene-editor" data-scene="2">
+      <div class="scene-label">
+        <span>Texture Close-up</span>
+        <span class="scene-number">03</span>
+      </div>
+      <input type="text" class="caption-input" value="Tactile Luxury" data-scene="2">
+    </div>
+    
+    <div class="scene-editor" data-scene="3">
+      <div class="scene-label">
+        <span>Swatch Grid</span>
+        <span class="scene-number">04</span>
+      </div>
+      <input type="text" class="caption-input" value="Curated Palettes" data-scene="3">
+    </div>
+    
+    <div class="scene-editor" data-scene="4">
+      <div class="scene-label">
+        <span>Call to Action</span>
+        <span class="scene-number">05</span>
+      </div>
+      <input type="text" class="caption-input" value="Define Your Sanctuary" data-scene="4">
+    </div>
+    
+    <div class="transport-controls">
+      <button class="transport-btn" id="resetBtn">Reset</button>
+      <button class="transport-btn" id="prevBtn">Prev</button>
+      <button class="transport-btn" id="nextBtn">Next</button>
+    </div>
+  </div>
+</div>
+
+<script>
+const scenes = [
+  { duration: 4000, type: 'hook' },
+  { duration: 4000, type: 'room' },
+  { duration: 4000, type: 'texture' },
+  { duration: 4000, type: 'swatches' },
+  { duration: 4000, type: 'cta' }
+];
+
+let currentScene = 0;
+let isPlaying = true;
+let startTime = Date.now();
+let sceneStartTime = Date.now();
+let pausedTime = 0;
+let animationFrame;
+
+const screen = document.getElementById('screen');
+const progressBar = document.getElementById('progressBar');
+const playPauseBtn = document.getElementById('playPauseBtn');
+const sceneElements = document.querySelectorAll('.scene');
+const captionInputs = document.querySelectorAll('.caption-input');
+const sceneEditors = document.querySelectorAll('.scene-editor');
+const timelineDots = document.querySelectorAll('.timeline-dot');
+
+function updateScene(index) {
+  sceneElements.forEach((el, i) => {
+    if (i === index) {
+      el.classList.add('active');
+    } else {
+      el.classList.remove('active');
+    }
+  });
+  
+  sceneEditors.forEach((el, i) => {
+    if (i === index) {
+      el.classList.add('active');
+    } else {
+      el.classList.remove('active');
+    }
+  });
+  
+  timelineDots.forEach((el, i) => {
+    if (i === index) {
+      el.classList.add('active');
+    } else {
+      el.classList.remove('active');
+    }
+  });
+  
+  currentScene = index;
+  sceneStartTime = Date.now() - pausedTime;
+  pausedTime = 0;
+}
+
+function nextScene() {
+  const next = (currentScene + 1) % scenes.length;
+  updateScene(next);
+}
+
+function prevScene() {
+  const prev = (currentScene - 1 + scenes.length) % scenes.length;
+  updateScene(prev);
+}
+
+function animate() {
+  if (!isPlaying) {
+    animationFrame = requestAnimationFrame(animate);
+    return;
+  }
+  
+  const now = Date.now();
+  const elapsed = now - sceneStartTime;
+  const duration = scenes[currentScene].duration;
+  const progress = Math.min((elapsed / duration) * 100, 100);
+  
+  progressBar.style.width = progress + '%';
+  
+  if (elapsed >= duration) {
+    nextScene();
+  }
+  
+  animationFrame = requestAnimationFrame(animate);
+}
+
+playPauseBtn.addEventListener('click', () => {
+  isPlaying = !isPlaying;
+  playPauseBtn.textContent = isPlaying ? '❚❚' : '▶';
+  
+  if (isPlaying) {
+    sceneStartTime = Date.now() - pausedTime;
+    pausedTime = 0;
+  } else {
+    pausedTime = Date.now() - sceneStartTime;
+  }
+});
+
+document.getElementById('resetBtn').addEventListener('click', () => {
+  updateScene(0);
+  sceneStartTime = Date.now();
+  pausedTime = 0;
+  isPlaying = true;
+  playPauseBtn.textContent = '❚❚';
+});
+
+document.getElementById('nextBtn').addEventListener('click', () => {
+  nextScene();
+  sceneStartTime = Date.now();
+  pausedTime = 0;
+});
+
+document.getElementById('prevBtn').addEventListener('click', () => {
+  prevScene();
+  sceneStartTime = Date.now();
+  pausedTime = 0;
+});
+
+captionInputs.forEach(input => {
+  input.addEventListener('input', (e) => {
+    const sceneIndex = parseInt(e.target.dataset.scene);
+    const captionEl = document.getElementById(`caption-${sceneIndex}`);
+    if (captionEl) {
+      if (sceneIndex === 0 || sceneIndex === 4) {
+        captionEl.innerHTML = e.target.value.replace(/\n/g, '<br>');
+      } else {
+        captionEl.textContent = e.target.value;
+      }
+    }
+  });
+});
+
+sceneEditors.forEach((editor, index) => {
+  editor.addEventListener('click', () => {
+    updateScene(index);
+    sceneStartTime = Date.now();
+    pausedTime = 0;
+  });
+});
+
+animate();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/b72f0e9e751b/kimi.png b/data/artifacts/b72f0e9e751b/kimi.png
new file mode 100644
index 0000000..e64a544
Binary files /dev/null and b/data/artifacts/b72f0e9e751b/kimi.png differ
diff --git a/data/artifacts/b72f0e9e751b/qwen3-14b.html b/data/artifacts/b72f0e9e751b/qwen3-14b.html
new file mode 100644
index 0000000..57a08e3
--- /dev/null
+++ b/data/artifacts/b72f0e9e751b/qwen3-14b.html
@@ -0,0 +1,238 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <title>Instagram Reel Storyboard</title>
+  <style>
+    * {
+      box-sizing: border-box;
+      margin: 0;
+      padding: 0;
+    }
+    html, body {
+      width: 100%;
+      height: 100%;
+      background: #0f0f0f;
+      color: #fff;
+      font-family: 'Helvetica Neue', sans-serif;
+      overflow: hidden;
+    }
+    .container {
+      position: relative;
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .phone-frame {
+      width: 80vw;
+      max-width: 360px;
+      height: 55vw;
+      max-height: 810px;
+      background: #1a1a1a;
+      border: 4px solid #2a2a2a;
+      border-radius: 40px;
+      box-shadow: 0 0 20px rgba(0,0,0,0.5);
+      position: relative;
+      overflow: hidden;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .phone-frame::before {
+      content: '';
+      position: absolute;
+      top: 0; left: 0;
+      width: 100%;
+      height: 100%;
+      background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 640"><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/><path d="M0 0h360v640H0z" fill="none"/></svg>') no-repeat center;
+      background-size: contain;
+    }
+    .scene {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      background: #1e1e1e;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      transition: opacity 0.5s ease-in-out;
+      opacity: 0;
+      pointer-events: none;
+    }
+    .scene.active {
+      opacity: 1;
+      pointer-events: auto;
+    }
+    .caption {
+      font-size: 24px;
+      font-weight: bold;
+      text-align: center;
+      padding: 10px;
+      background: rgba(0,0,0,0.3);
+      border-radius: 10px;
+      max-width: 80%;
+      animation: fadeIn 1s ease-in-out forwards;
+    }
+    @keyframes fadeIn {
+      from { opacity: 0; transform: translateY(20px); }
+      to { opacity: 1; transform: translateY(0); }
+    }
+    .progress-bar {
+      position: absolute;
+      bottom: 20px;
+      left: 0;
+      width: 90%;
+      height: 8px;
+      background: #333;
+      border-radius: 4px;
+      overflow: hidden;
+      margin: 0 auto;
+    }
+    .progress-fill {
+      height: 100%;
+      width: 0%;
+      background: #6f42c1;
+      transition: width 0.5s ease-in-out;
+    }
+    .controls {
+      position: absolute;
+      top: 20px;
+      left: 50%;
+      transform: translateX(-50%);
+      display: flex;
+      gap: 15px;
+    }
+    .controls button {
+      background: #333;
+      color: #fff;
+      border: none;
+      padding: 10px 15px;
+      border-radius: 50px;
+      font-size: 16px;
+      cursor: pointer;
+      transition: background 0.3s ease;
+    }
+    .controls button:hover {
+      background: #444;
+    }
+    .scene-editor {
+      position: absolute;
+      bottom: 10px;
+      left: 50%;
+      transform: translateX(-50%);
+      background: #1a1a1a;
+      padding: 10px 20px;
+      border-radius: 10px;
+      display: flex;
+      gap: 10px;
+      flex-wrap: wrap;
+      max-width: 90%;
+    }
+    .scene-editor input {
+      flex: 1;
+      min-width: 150px;
+      padding: 6px;
+      background: #2a2a2a;
+      color: #fff;
+      border: none;
+      border-radius: 5px;
+    }
+  </style>
+</head>
+<body>
+  <div class="container">
+    <div class="phone-frame">
+      <div class="scene active" data-index="0">
+        <div class="caption">Hook: Luxe living starts here</div>
+      </div>
+      <div class="scene" data-index="1">
+        <div class="caption">Room reveal: Timeless elegance in every corner</div>
+      </div>
+      <div class="scene" data-index="2">
+        <div class="caption">Texture close-up: Feel the artistry</div>
+      </div>
+      <div class="scene" data-index="3">
+        <div class="caption">Swatch grid: Choose your perfect match</div>
+      </div>
+      <div class="scene" data-index="4">
+        <div class="caption">CTA: Discover the collection now</div>
+      </div>
+      <div class="progress-bar">
+        <div class="progress-fill" style="width: 0%;"></div>
+      </div>
+      <div class="controls">
+        <button id="playPauseBtn">▶️ Play</button>
+      </div>
+    </div>
+    <div class="scene-editor">
+      <input type="text" data-index="0" value="Hook: Luxe living starts here" />
+      <input type="text" data-index="1" value="Room reveal: Timeless elegance in every corner" />
+      <input type="text" data-index="2" value="Texture close-up: Feel the artistry" />
+      <input type="text" data-index="3" value="Swatch grid: Choose your perfect match" />
+      <input type="text" data-index="4" value="CTA: Discover the collection now" />
+    </div>
+  </div>
+  <script>
+    const scenes = document.querySelectorAll('.scene');
+    const inputs = document.querySelectorAll('.scene-editor input');
+    const progressBar = document.querySelector('.progress-fill');
+    const playPauseBtn = document.getElementById('playPauseBtn');
+    let isPlaying = false;
+    let currentSceneIndex = 0;
+    let interval;
+
+    function updateSceneCaptions() {
+      scenes.forEach((scene, index) => {
+        const caption = scene.querySelector('.caption');
+        if (caption) {
+          caption.textContent = inputs[index].value;
+        }
+      });
+    }
+
+    inputs.forEach((input, index) => {
+      input.addEventListener('input', updateSceneCaptions);
+    });
+
+    function showScene(index) {
+      scenes.forEach((scene, i) => {
+        scene.classList.toggle('active', i === index);
+      });
+      currentSceneIndex = index;
+      progressBar.style.width = `${(index / (scenes.length - 1)) * 100}%`;
+    }
+
+    function play() {
+      if (isPlaying) return;
+      isPlaying = true;
+      playPauseBtn.textContent = '⏸️ Pause';
+      interval = setInterval(() => {
+        currentSceneIndex = (currentSceneIndex + 1) % scenes.length;
+        showScene(currentSceneIndex);
+      }, 2000);
+    }
+
+    function pause() {
+      isPlaying = false;
+      playPauseBtn.textContent = '▶️ Play';
+      clearInterval(interval);
+    }
+
+    playPauseBtn.addEventListener('click', () => {
+      if (isPlaying) {
+        pause();
+      } else {
+        play();
+      }
+    });
+
+    // Initialize
+    showScene(currentSceneIndex);
+    updateSceneCaptions();
+  </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/b72f0e9e751b/qwen3-14b.png b/data/artifacts/b72f0e9e751b/qwen3-14b.png
new file mode 100644
index 0000000..ea349ea
Binary files /dev/null and b/data/artifacts/b72f0e9e751b/qwen3-14b.png differ
diff --git a/data/artifacts/bde366feb227/claude-code.html b/data/artifacts/bde366feb227/claude-code.html
new file mode 100644
index 0000000..3946704
--- /dev/null
+++ b/data/artifacts/bde366feb227/claude-code.html
@@ -0,0 +1,439 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Atelier Verdant — Shoppable Post</title>
+<style>
+  :root{
+    --ink:#1a1a1a; --sub:#8a8a8a; --line:#efefef; --accent:#2f4638;
+    --card:#ffffff; --bg:#fafafa;
+  }
+  *{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
+  html,body{height:100%}
+  body{
+    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
+    background:linear-gradient(160deg,#ece9e4,#dfe4de);
+    display:flex;align-items:center;justify-content:center;
+    min-height:100vh;padding:24px 12px;color:var(--ink);
+  }
+  .phone{
+    width:100%;max-width:430px;background:var(--card);
+    border-radius:22px;overflow:hidden;
+    box-shadow:0 20px 60px rgba(40,50,45,.22),0 2px 8px rgba(0,0,0,.06);
+  }
+
+  /* ---------- Post header ---------- */
+  .post-head{display:flex;align-items:center;gap:11px;padding:12px 14px}
+  .avatar{
+    width:38px;height:38px;border-radius:50%;flex-shrink:0;
+    padding:2px;background:conic-gradient(from 210deg,#c9a86a,#7c9a7e,#3a5245,#c9a86a);
+  }
+  .avatar span{
+    display:flex;align-items:center;justify-content:center;
+    width:100%;height:100%;border-radius:50%;
+    background:#2f4638;color:#f4efe6;font-weight:600;font-size:13px;
+    letter-spacing:.5px;border:2px solid #fff;
+  }
+  .who{display:flex;flex-direction:column;line-height:1.25;flex:1;min-width:0}
+  .who b{font-size:13.5px;font-weight:600;display:flex;align-items:center;gap:4px}
+  .who b svg{width:13px;height:13px;color:#3897f0;flex-shrink:0}
+  .who small{font-size:11.5px;color:var(--sub)}
+  .dots{font-size:20px;color:var(--ink);letter-spacing:1px;padding:0 4px;cursor:pointer}
+
+  /* ---------- Room scene (CSS illustrated) ---------- */
+  .scene{
+    position:relative;width:100%;aspect-ratio:1/1;overflow:hidden;
+    background:#d8cfc0;user-select:none;
+  }
+  /* wallpaper wall */
+  .wall{
+    position:absolute;inset:0;
+    background-color:#3a5346;
+    background-image:
+      radial-gradient(circle at 20% 25%, rgba(201,168,106,.35) 0 3px, transparent 4px),
+      radial-gradient(circle at 20% 25%, transparent 13px, rgba(201,168,106,.22) 13px 15px, transparent 16px),
+      radial-gradient(circle at 60% 65%, rgba(201,168,106,.35) 0 3px, transparent 4px),
+      radial-gradient(circle at 60% 65%, transparent 13px, rgba(201,168,106,.22) 13px 15px, transparent 16px),
+      linear-gradient(140deg, rgba(255,255,255,.06), rgba(0,0,0,.14));
+    background-size:120px 120px,120px 120px,120px 120px,120px 120px,100% 100%;
+    background-position:0 0,0 0,60px 60px,60px 60px,0 0;
+  }
+  /* botanical leaf accents */
+  .wall::before{
+    content:"";position:absolute;inset:0;
+    background-image:
+      radial-gradient(ellipse 8px 20px at 35% 15%, rgba(233,222,200,.28) 40%, transparent 60%),
+      radial-gradient(ellipse 8px 20px at 78% 40%, rgba(233,222,200,.24) 40%, transparent 60%),
+      radial-gradient(ellipse 8px 20px at 12% 70%, rgba(233,222,200,.24) 40%, transparent 60%),
+      radial-gradient(ellipse 8px 20px at 88% 85%, rgba(233,222,200,.22) 40%, transparent 60%);
+    transform:rotate(8deg);
+  }
+  /* soft window light */
+  .light{
+    position:absolute;top:-8%;left:-10%;width:70%;height:80%;
+    background:radial-gradient(ellipse at 30% 30%, rgba(255,248,225,.35), transparent 65%);
+    pointer-events:none;
+  }
+  /* floor */
+  .floor{
+    position:absolute;left:0;right:0;bottom:0;height:26%;
+    background:linear-gradient(#c9b59a,#b39c7d);
+    box-shadow:0 -1px 0 rgba(0,0,0,.12) inset;
+  }
+  .baseboard{
+    position:absolute;left:0;right:0;bottom:26%;height:3.5%;
+    background:linear-gradient(#f3ece0,#e2d8c7);
+  }
+  /* console/sideboard */
+  .console{
+    position:absolute;bottom:22%;left:50%;transform:translateX(-50%);
+    width:62%;height:20%;background:linear-gradient(#3c2c22,#2c2018);
+    border-radius:4px 4px 2px 2px;
+    box-shadow:0 12px 22px rgba(0,0,0,.3);
+  }
+  .console::before,.console::after{
+    content:"";position:absolute;bottom:-14px;width:6px;height:16px;
+    background:#241a13;
+  }
+  .console::before{left:11%}.console::after{right:11%}
+  .console .drw{
+    position:absolute;top:38%;left:8%;right:8%;height:2px;background:rgba(255,255,255,.12);
+  }
+  .knob{position:absolute;top:52%;width:5px;height:5px;border-radius:50%;background:#c9a86a}
+  .knob.l{left:32%}.knob.r{right:32%}
+  /* framed art on wall */
+  .frame{
+    position:absolute;top:16%;left:50%;transform:translateX(-50%);
+    width:26%;height:26%;background:#f6f1e7;
+    border:5px solid #d9c9a3;border-radius:2px;
+    box-shadow:0 8px 16px rgba(0,0,0,.25);
+  }
+  .frame::after{
+    content:"";position:absolute;inset:6px;
+    background:linear-gradient(135deg,#7c9a7e,#3a5245 70%);
+    border-radius:1px;
+  }
+  /* vase + lamp on console */
+  .vase{
+    position:absolute;bottom:42%;left:34%;width:9%;height:16%;
+    background:linear-gradient(#b9491f,#8f3213);border-radius:40% 40% 45% 45%/60% 60% 40% 40%;
+    box-shadow:0 6px 10px rgba(0,0,0,.28);
+  }
+  .vase::before{
+    content:"";position:absolute;bottom:70%;left:50%;transform:translateX(-50%);
+    width:120%;height:90%;
+    background:
+      radial-gradient(ellipse 4px 14px at 30% 60%, #6f8f6b 50%, transparent 60%),
+      radial-gradient(ellipse 4px 16px at 55% 40%, #567a52 50%, transparent 60%),
+      radial-gradient(ellipse 4px 13px at 72% 62%, #6f8f6b 50%, transparent 60%);
+  }
+  .lamp{
+    position:absolute;bottom:42%;right:31%;width:12%;height:20%;
+  }
+  .lamp .shade{
+    position:absolute;top:0;left:50%;transform:translateX(-50%);
+    width:100%;height:52%;background:linear-gradient(#f6ead0,#e6d3ad);
+    border-radius:6px 6px 3px 3px;box-shadow:0 4px 10px rgba(0,0,0,.2);
+  }
+  .lamp .stem{position:absolute;bottom:0;left:50%;transform:translateX(-50%);width:8%;height:52%;background:#28201a}
+
+  /* ---------- Product tags ---------- */
+  .tag{
+    position:absolute;width:26px;height:26px;border-radius:50%;
+    background:rgba(255,255,255,.92);border:none;cursor:pointer;
+    display:flex;align-items:center;justify-content:center;
+    box-shadow:0 2px 10px rgba(0,0,0,.35);
+    transform:translate(-50%,-50%);z-index:5;
+    animation:pulse 2.4s ease-out infinite;
+  }
+  .tag::before{
+    content:"";width:8px;height:8px;border-radius:50%;background:#1a1a1a;
+    transition:transform .2s;
+  }
+  .tag:hover::before{transform:scale(1.25)}
+  .tag.active{background:#2f4638;animation:none}
+  .tag.active::before{background:#fff}
+  @keyframes pulse{
+    0%{box-shadow:0 2px 10px rgba(0,0,0,.35),0 0 0 0 rgba(255,255,255,.6)}
+    70%{box-shadow:0 2px 10px rgba(0,0,0,.35),0 0 0 12px rgba(255,255,255,0)}
+    100%{box-shadow:0 2px 10px rgba(0,0,0,.35),0 0 0 0 rgba(255,255,255,0)}
+  }
+  .tag1{top:30%;left:26%}
+  .tag2{top:60%;left:50%}
+  .tag3{top:26%;left:63%}
+
+  /* ---------- Product card popover ---------- */
+  .card{
+    position:absolute;z-index:8;width:220px;
+    background:var(--card);border-radius:14px;overflow:hidden;
+    box-shadow:0 14px 40px rgba(0,0,0,.32);
+    opacity:0;pointer-events:none;transform:translate(-50%,-6px) scale(.94);
+    transition:opacity .22s ease,transform .22s ease;
+  }
+  .card.show{opacity:1;pointer-events:auto;transform:translate(-50%,0) scale(1)}
+  .card .top{display:flex;gap:11px;padding:12px}
+  .swatch{
+    width:52px;height:52px;border-radius:9px;flex-shrink:0;
+    box-shadow:inset 0 0 0 1px rgba(0,0,0,.08);
+  }
+  .sw1{background:
+      radial-gradient(circle at 30% 30%, #c9a86a 0 2px, transparent 3px),
+      radial-gradient(circle at 70% 70%, #c9a86a 0 2px, transparent 3px),
+      #3a5346;background-size:20px 20px}
+  .sw2{background:
+      repeating-linear-gradient(45deg,#8f3213 0 4px,#a8451f 4px 8px)}
+  .sw3{background:
+      linear-gradient(#e6d3ad,#d9c9a3),
+      repeating-linear-gradient(90deg, rgba(120,90,50,.25) 0 1px, transparent 1px 6px);
+      background-blend-mode:multiply}
+  .card .info{min-width:0;display:flex;flex-direction:column;justify-content:center}
+  .card .brand{font-size:9.5px;letter-spacing:1.2px;text-transform:uppercase;color:var(--sub)}
+  .card .name{font-size:13.5px;font-weight:600;margin:2px 0 3px;line-height:1.2}
+  .card .price{font-size:12.5px;color:var(--accent);font-weight:600}
+  .card .price small{color:var(--sub);font-weight:400}
+  .card .view{
+    display:block;width:100%;border:none;border-top:1px solid var(--line);
+    background:#fff;color:var(--accent);font-weight:600;font-size:12.5px;
+    padding:11px;cursor:pointer;letter-spacing:.4px;transition:background .15s;
+  }
+  .card .view:hover{background:#f4f6f4}
+  .card .arrow{
+    position:absolute;width:12px;height:12px;background:#fff;
+    transform:rotate(45deg);top:-6px;left:50%;margin-left:-6px;
+  }
+  .card.below .arrow{top:auto;bottom:-6px}
+
+  /* ---------- Action bar ---------- */
+  .actions{display:flex;align-items:center;gap:16px;padding:11px 14px 6px}
+  .actions svg{width:24px;height:24px;cursor:pointer;stroke:var(--ink);fill:none;stroke-width:1.7}
+  .actions .heart.liked{fill:#ed4956;stroke:#ed4956}
+  .actions .spacer{flex:1}
+  .meta{padding:0 14px}
+  .likes{font-size:13.5px;font-weight:600}
+  .caption{font-size:13.5px;line-height:1.45;margin-top:5px}
+  .caption b{font-weight:600}
+  .caption .tagword{color:#3a5a86}
+  .comments{margin-top:7px;display:flex;flex-direction:column;gap:4px}
+  .comments .c{font-size:13px;line-height:1.4}
+  .comments .c b{font-weight:600}
+  .viewall{font-size:13px;color:var(--sub);margin-top:6px;cursor:pointer}
+  .time{font-size:10.5px;letter-spacing:.4px;color:var(--sub);text-transform:uppercase;margin:9px 0 2px}
+
+  /* add comment row */
+  .addrow{display:flex;align-items:center;gap:10px;padding:11px 14px;border-top:1px solid var(--line);margin-top:10px}
+  .addrow .em{width:24px;height:24px;border-radius:50%;background:#eee;display:flex;align-items:center;justify-content:center;font-size:13px}
+  .addrow input{border:none;flex:1;font-size:13px;outline:none;background:transparent}
+  .addrow .post{color:#b9d0f0;font-weight:600;font-size:13px}
+
+  .toast{
+    position:fixed;left:50%;bottom:34px;transform:translateX(-50%) translateY(20px);
+    background:#1a1a1a;color:#fff;padding:11px 20px;border-radius:30px;
+    font-size:13px;opacity:0;pointer-events:none;transition:.3s;z-index:20;
+    box-shadow:0 8px 24px rgba(0,0,0,.3);
+  }
+  .toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
+</style>
+</head>
+<body>
+  <div class="phone">
+    <!-- header -->
+    <div class="post-head">
+      <div class="avatar"><span>AV</span></div>
+      <div class="who">
+        <b>atelierverdant
+          <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.4 1.8 3 .1 1 2.8 2.4 1.7-.9 2.9.9 2.9-2.4 1.7-1 2.8-3 .1L12 22l-2.4-1.8-3-.1-1-2.8L3.2 15l.9-2.9-.9-2.9 2.4-1.7 1-2.8 3-.1z"/><path d="M10.4 13.7l-1.9-1.9-1.2 1.2 3.1 3.1 5.6-5.6-1.2-1.2z" fill="#fff"/></svg>
+        </b>
+        <small>Designer Wallcoverings · Sponsored</small>
+      </div>
+      <div class="dots">⋯</div>
+    </div>
+
+    <!-- room scene -->
+    <div class="scene" id="scene">
+      <div class="wall"></div>
+      <div class="light"></div>
+      <div class="frame"></div>
+      <div class="baseboard"></div>
+      <div class="floor"></div>
+      <div class="console">
+        <div class="drw"></div><div class="knob l"></div><div class="knob r"></div>
+      </div>
+      <div class="vase"></div>
+      <div class="lamp"><div class="shade"></div><div class="stem"></div></div>
+
+      <!-- tappable tags -->
+      <button class="tag tag1" data-i="0" aria-label="Tagged product"></button>
+      <button class="tag tag2" data-i="1" aria-label="Tagged product"></button>
+      <button class="tag tag3" data-i="2" aria-label="Tagged product"></button>
+
+      <!-- product cards -->
+      <div class="card" id="card0">
+        <div class="arrow"></div>
+        <div class="top">
+          <div class="swatch sw1"></div>
+          <div class="info">
+            <div class="brand">Atelier Verdant</div>
+            <div class="name">Fernwood Emerald</div>
+            <div class="price">$168 <small>/ roll</small></div>
+          </div>
+        </div>
+        <button class="view" data-name="Fernwood Emerald">View Product →</button>
+      </div>
+
+      <div class="card" id="card1">
+        <div class="arrow"></div>
+        <div class="top">
+          <div class="swatch sw2"></div>
+          <div class="info">
+            <div class="brand">Atelier Verdant</div>
+            <div class="name">Terracotta Vessel</div>
+            <div class="price">$92 <small>/ each</small></div>
+          </div>
+        </div>
+        <button class="view" data-name="Terracotta Vessel">View Product →</button>
+      </div>
+
+      <div class="card" id="card2">
+        <div class="arrow"></div>
+        <div class="top">
+          <div class="swatch sw3"></div>
+          <div class="info">
+            <div class="brand">Atelier Verdant</div>
+            <div class="name">Grasscloth Alabaster</div>
+            <div class="price">$144 <small>/ roll</small></div>
+          </div>
+        </div>
+        <button class="view" data-name="Grasscloth Alabaster">View Product →</button>
+      </div>
+    </div>
+
+    <!-- actions -->
+    <div class="actions">
+      <svg class="heart" id="heart" viewBox="0 0 24 24"><path d="M12 21s-7.5-4.6-10-9.3C.4 8.4 2 5 5.3 5c2 0 3.3 1.1 4.2 2.3l.6.9.6-.9C11.6 6.1 13 5 15 5c3.3 0 4.9 3.4 3.3 6.7C19.5 16.4 12 21 12 21z"/></svg>
+      <svg viewBox="0 0 24 24"><path d="M21 11.5a8.4 8.4 0 01-9 8.3 9 9 0 01-3.9-.9L3 20l1.1-4a8.3 8.3 0 01-1-4A8.4 8.4 0 1121 11.5z"/></svg>
+      <svg viewBox="0 0 24 24"><path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/></svg>
+      <div class="spacer"></div>
+      <svg viewBox="0 0 24 24"><path d="M6 3h12v18l-6-4-6 4V3z"/></svg>
+    </div>
+
+    <!-- meta -->
+    <div class="meta">
+      <div class="likes" id="likes">2,847 likes</div>
+      <div class="caption">
+        <b>atelierverdant</b> Slow mornings against our <span class="tagword">Fernwood Emerald</span> grasscloth 🌿 A hand-woven botanical that turns any wall into a garden. Tap the dots to shop the room. <span class="tagword">#wallcoverings #interiordesign #botanicalhome</span>
+      </div>
+      <div class="comments">
+        <div class="c"><b>studio.olive</b> The depth on that green is unreal 😍</div>
+        <div class="c"><b>maison_clara</b> Need the Fernwood in my hallway immediately</div>
+      </div>
+      <div class="viewall">View all 134 comments</div>
+      <div class="time">2 hours ago</div>
+    </div>
+
+    <div class="addrow">
+      <div class="em">🙂</div>
+      <input id="cinput" placeholder="Add a comment…" aria-label="Add a comment">
+      <span class="post" id="cpost">Post</span>
+    </div>
+  </div>
+
+  <div class="toast" id="toast"></div>
+
+<script>
+(function(){
+  const scene = document.getElementById('scene');
+  const tags = Array.from(document.querySelectorAll('.tag'));
+  const cards = [0,1,2].map(i=>document.getElementById('card'+i));
+  let open = -1;
+
+  function positionCard(i){
+    const tag = tags[i], card = cards[i];
+    const st = tag.style;
+    // read tag % position from its class-defined left/top via computed
+    const rect = tag.getBoundingClientRect();
+    const srect = scene.getBoundingClientRect();
+    const cx = rect.left - srect.left + rect.width/2;
+    const cy = rect.top - srect.top + rect.height/2;
+    // decide above or below based on vertical space
+    const below = cy < srect.height*0.42;
+    card.classList.toggle('below', below);
+    let left = cx;
+    left = Math.max(115, Math.min(srect.width-115, left));
+    card.style.left = left+'px';
+    if(below){
+      card.style.top = (cy+22)+'px';
+      card.style.bottom = 'auto';
+    }else{
+      card.style.top = 'auto';
+      card.style.bottom = (srect.height-cy+22)+'px';
+    }
+    // point arrow toward the tag
+    const arrow = card.querySelector('.arrow');
+    arrow.style.left = (cx-left+card.offsetWidth/2)+'px';
+  }
+
+  function closeAll(){
+    cards.forEach(c=>c.classList.remove('show'));
+    tags.forEach(t=>t.classList.remove('active'));
+    open = -1;
+  }
+
+  tags.forEach((tag,i)=>{
+    tag.addEventListener('click',e=>{
+      e.stopPropagation();
+      if(open===i){closeAll();return;}
+      closeAll();
+      positionCard(i);
+      // recompute after layout for accurate arrow
+      requestAnimationFrame(()=>positionCard(i));
+      cards[i].classList.add('show');
+      tag.classList.add('active');
+      open=i;
+    });
+  });
+
+  scene.addEventListener('click',e=>{
+    if(!e.target.closest('.card') && !e.target.closest('.tag')) closeAll();
+  });
+
+  const toast = document.getElementById('toast');
+  let tt;
+  function showToast(msg){
+    toast.textContent=msg;toast.classList.add('show');
+    clearTimeout(tt);tt=setTimeout(()=>toast.classList.remove('show'),2000);
+  }
+
+  document.querySelectorAll('.view').forEach(b=>{
+    b.addEventListener('click',e=>{
+      e.stopPropagation();
+      showToast('Opening “'+b.dataset.name+'” →');
+    });
+  });
+
+  // like interactions
+  const heart=document.getElementById('heart');
+  const likes=document.getElementById('likes');
+  let liked=false, base=2847;
+  heart.addEventListener('click',()=>{
+    liked=!liked;heart.classList.toggle('liked',liked);
+    likes.textContent=(base+(liked?1:0)).toLocaleString()+' likes';
+    if(liked) showToast('Liked ❤');
+  });
+
+  // comment
+  const ci=document.getElementById('cinput'), cp=document.getElementById('cpost');
+  function postComment(){
+    const v=ci.value.trim();if(!v)return;
+    const wrap=document.querySelector('.comments');
+    const d=document.createElement('div');d.className='c';
+    d.innerHTML='<b>you</b> '+v.replace(/</g,'&lt;');
+    wrap.appendChild(d);ci.value='';showToast('Comment posted');
+  }
+  cp.addEventListener('click',postComment);
+  ci.addEventListener('keydown',e=>{if(e.key==='Enter')postComment();});
+
+  window.addEventListener('resize',()=>{if(open>=0)positionCard(open);});
+})();
+</script>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/bde366feb227/claude-code.png b/data/artifacts/bde366feb227/claude-code.png
new file mode 100644
index 0000000..011cd74
Binary files /dev/null and b/data/artifacts/bde366feb227/claude-code.png differ
diff --git a/data/artifacts/bde366feb227/gpt.html b/data/artifacts/bde366feb227/gpt.html
new file mode 100644
index 0000000..804d6f4
--- /dev/null
+++ b/data/artifacts/bde366feb227/gpt.html
@@ -0,0 +1,1358 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<title>Instagram Shoppable Post Mockup - Wallcovering</title>
+<style>
+  :root {
+    --bg: #101015;
+    --card-bg: #111119;
+    --accent: #f2b679;
+    --accent-soft: rgba(242, 182, 121, 0.12);
+    --text-main: #f5f5f7;
+    --text-muted: #a4a4b0;
+    --text-soft: #7b7b88;
+    --border-subtle: #272734;
+    --like-red: #f05a7e;
+    --blue-link: #3897f0;
+    --shadow-soft: 0 24px 60px rgba(0,0,0,0.65);
+    --radius-lg: 18px;
+    --radius-md: 12px;
+    --radius-pill: 999px;
+    --transition-fast: 0.22s ease-out;
+    --transition-med: 0.3s cubic-bezier(.19,1,.22,1);
+  }
+
+  * {
+    box-sizing: border-box;
+    -webkit-tap-highlight-color: transparent;
+  }
+
+  html, body {
+    margin: 0;
+    padding: 0;
+    background: radial-gradient(circle at top, #181828 0, #05050a 52%);
+    font-family: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text",
+      "Segoe UI", sans-serif;
+    color: var(--text-main);
+  }
+
+  body {
+    min-height: 100vh;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .frame {
+    width: 370px;
+    max-width: 100vw;
+    background: radial-gradient(circle at top left, #202030, #080813 70%);
+    border-radius: 28px;
+    padding: 18px 14px;
+    box-shadow:
+      0 35px 80px rgba(0,0,0,0.85),
+      0 0 0 1px rgba(255,255,255,0.02);
+    border: 1px solid rgba(255,255,255,0.03);
+  }
+
+  .ig-shell {
+    background: linear-gradient(145deg, #151521, #0b0b14);
+    border-radius: 24px;
+    overflow: hidden;
+    border: 1px solid rgba(255,255,255,0.06);
+  }
+
+  /* HEADER */
+  .ig-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 10px 14px 8px;
+  }
+  .ig-header-left {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+  }
+  .avatar-wrap {
+    width: 32px;
+    height: 32px;
+    padding: 2px;
+    border-radius: 50%;
+    background: conic-gradient(from 180deg, #f9ce6a, #f58c75, #d948a6, #6a5af9, #f9ce6a);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .avatar-inner {
+    width: 100%;
+    height: 100%;
+    border-radius: 50%;
+    background: radial-gradient(circle at 30% 20%, #fefefe 0, #dedfe9 32%, #c4c6d2 70%);
+    border: 2px solid #151521;
+    position: relative;
+    overflow: hidden;
+  }
+  .avatar-inner::before {
+    content: "";
+    position: absolute;
+    inset: 16% 8% 22% 22%;
+    border-radius: 40% 60% 60% 40%;
+    background: radial-gradient(circle at 35% 25%, #f6e5df 0, #e4c5b4 32%, #c89b86 65%);
+  }
+  .avatar-inner::after {
+    content: "";
+    position: absolute;
+    inset: 40% 28% 20% 18%;
+    border-radius: 50%;
+    background: radial-gradient(circle at 50% 30%, #2f2c3a 0, #151521 65%);
+  }
+
+  .ig-identity {
+    display: flex;
+    flex-direction: column;
+    gap: 2px;
+  }
+  .ig-handle {
+    font-size: 13px;
+    font-weight: 600;
+    letter-spacing: 0.01em;
+  }
+  .ig-meta {
+    font-size: 11px;
+    color: var(--text-soft);
+  }
+  .ig-meta-dot::before {
+    content: "•";
+    margin: 0 4px;
+  }
+
+  .ig-header-right {
+    display: flex;
+    align-items: center;
+    gap: 14px;
+    color: #efefef;
+  }
+  .ig-icon {
+    width: 18px;
+    height: 18px;
+    position: relative;
+  }
+  .ig-icon.more::before,
+  .ig-icon.more::after {
+    content: "";
+    position: absolute;
+    width: 3px;
+    height: 3px;
+    border-radius: 50%;
+    background: #fafafa;
+    left: 50%;
+    transform: translateX(-50%);
+  }
+  .ig-icon.more::before {
+    top: 4px;
+    box-shadow: 0 4px 0 #fafafa, 0 8px 0 #fafafa;
+  }
+
+  .ig-icon.shop {
+    border-radius: 6px;
+    border: 1px solid rgba(255,255,255,0.16);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .ig-icon.shop::before {
+    content: "";
+    width: 11px;
+    height: 8px;
+    border: 1.4px solid #fafafa;
+    border-radius: 3px 3px 5px 5px;
+    box-sizing: border-box;
+    position: relative;
+    top: 0.5px;
+  }
+  .ig-icon.shop::after {
+    content: "";
+    position: absolute;
+    top: 2px;
+    left: 4px;
+    right: 4px;
+    height: 3px;
+    border-top: 1.4px solid #fafafa;
+    border-radius: 2px;
+  }
+
+  /* IMAGE AREA - ROOM ILLUSTRATION */
+  .ig-media-wrap {
+    position: relative;
+    background: radial-gradient(circle at top, #202031 0, #060612 72%);
+    border-radius: 18px;
+    margin: 0 10px;
+    overflow: hidden;
+    border: 1px solid rgba(255,255,255,0.06);
+  }
+  .ig-media {
+    position: relative;
+    width: 100%;
+    padding-top: 100%;
+    overflow: hidden;
+    cursor: pointer;
+  }
+
+  /* Room base */
+  .room {
+    position: absolute;
+    inset: 0;
+    padding: 16px 14px 12px;
+    display: flex;
+    flex-direction: column;
+    justify-content: flex-end;
+    background:
+      radial-gradient(circle at top left, rgba(255,255,255,0.12) 0, transparent 55%),
+      radial-gradient(circle at top right, rgba(111, 92, 255,0.16) 0, transparent 55%),
+      linear-gradient(160deg, #151524 0, #070713 70%);
+  }
+
+  .room-wall {
+    position: absolute;
+    inset: 14px 14px 34%;
+    border-radius: 14px;
+    overflow: hidden;
+    background-color: #222132;
+  }
+
+  /* Wallpaper patterns layer */
+  .wallpattern-base {
+    position: absolute;
+    inset: 0;
+    background:
+      radial-gradient(circle at 0% 0%, rgba(255,255,255,0.12) 0, transparent 55%),
+      radial-gradient(circle at 100% 0%, rgba(241,182,121,0.10) 0, transparent 60%),
+      radial-gradient(circle at 100% 100%, rgba(141,188,159,0.25) 0, transparent 70%),
+      radial-gradient(circle at 0% 100%, rgba(19,187,187,0.16) 0, transparent 65%),
+      #232332;
+    opacity: 0.98;
+  }
+
+  .wallpattern-arches {
+    position: absolute;
+    inset: 0;
+    background-image:
+      radial-gradient(circle at 10% 110%, rgba(0,0,0,0.24) 0, transparent 55%),
+      radial-gradient(circle at 50% -30%, rgba(255,255,255,0.12) 0, transparent 60%);
+    mix-blend-mode: soft-light;
+  }
+
+  .wallpattern-lines {
+    position: absolute;
+    inset: 0;
+    background-image:
+      repeating-linear-gradient(
+        135deg,
+        rgba(255,255,255,0.04) 0,
+        rgba(255,255,255,0.04) 1px,
+        transparent 1px,
+        transparent 7px
+      ),
+      repeating-linear-gradient(
+        -135deg,
+        rgba(13,13,25,0.7) 0,
+        rgba(13,13,25,0.7) 1px,
+        transparent 1px,
+        transparent 8px
+      );
+    opacity: 0.8;
+  }
+
+  .room-floor {
+    position: absolute;
+    left: 6px;
+    right: 6px;
+    bottom: 6px;
+    height: 27%;
+    border-radius: 16px;
+    background:
+      linear-gradient(to top, rgba(0,0,0,0.45), transparent 55%),
+      linear-gradient(180deg, #111019, #07050b 65%);
+    box-shadow: 0 -8px 25px rgba(0,0,0,0.85);
+  }
+
+  .floor-planks {
+    position: absolute;
+    inset: 6px 10px 6px;
+    background-image:
+      linear-gradient(
+        90deg,
+        rgba(255,255,255,0.04) 0,
+        rgba(255,255,255,0.04) 1px,
+        transparent 1px,
+        transparent 30px
+      );
+    opacity: 0.6;
+  }
+
+  /* Sofa */
+  .sofa {
+    position: absolute;
+    left: 14%;
+    right: 10%;
+    bottom: 13%;
+    height: 26%;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .sofa-base {
+    flex: 1;
+    border-radius: 16px 16px 14px 14px;
+    background:
+      linear-gradient(145deg, #272941 0, #141423 60%, #0c0c18 100%);
+    box-shadow:
+      0 18px 30px rgba(0,0,0,0.9),
+      0 -4px 12px rgba(255,255,255,0.02) inset;
+    position: relative;
+    overflow: hidden;
+  }
+
+  .sofa-base::before {
+    content: "";
+    position: absolute;
+    inset: 2px 2px auto 2px;
+    height: 32%;
+    border-radius: 12px 12px 10px 10px;
+    background:
+      linear-gradient(120deg, rgba(255,255,255,0.08), transparent 40%),
+      linear-gradient(145deg, #313454, #19192b 60%);
+  }
+
+  .sofa-arm {
+    position: absolute;
+    right: -4%;
+    top: 10%;
+    bottom: 14%;
+    width: 22%;
+    border-radius: 22px 18px 16px 10px;
+    background: linear-gradient(145deg, #24253d, #11111e);
+    box-shadow:
+      -4px 0 14px rgba(0,0,0,0.8),
+      0 0 0 1px rgba(255,255,255,0.04) inset;
+  }
+
+  .sofa-cushion-main {
+    position: absolute;
+    left: 18%;
+    right: 22%;
+    top: 16%;
+    bottom: 40%;
+    border-radius: 16px;
+    background:
+      linear-gradient(160deg, #3a3e6a, #20223f 60%, #151524);
+    box-shadow:
+      0 14px 22px rgba(0,0,0,0.85),
+      0 0 0 1px rgba(255,255,255,0.04) inset;
+  }
+
+  .sofa-cushion-alt {
+    position: absolute;
+    left: 5%;
+    width: 20%;
+    top: 16%;
+    bottom: 45%;
+    border-radius: 13px;
+    background:
+      linear-gradient(145deg, #f3d9b8, #d9a271);
+    box-shadow: 0 14px 18px rgba(0,0,0,0.75);
+  }
+
+  .throw {
+    position: absolute;
+    right: 20%;
+    bottom: 34%;
+    width: 18%;
+    height: 24%;
+    border-radius: 6px;
+    background:
+      linear-gradient(135deg, #8fe1d9, #4ab7a6);
+    box-shadow: 0 10px 16px rgba(0,0,0,0.7);
+    transform: skewX(-10deg) rotate(-2deg);
+  }
+
+  .throw::after {
+    content: "";
+    position: absolute;
+    inset: 0 0 -18% 0;
+    background:
+      repeating-linear-gradient(
+        180deg,
+        rgba(255,255,255,0.45) 0,
+        rgba(255,255,255,0.45) 2px,
+        transparent 2px,
+        transparent 4px
+      );
+    opacity: 0.85;
+    border-radius: 0 0 6px 6px;
+  }
+
+  .sofa-shadow {
+    position: absolute;
+    left: 8%;
+    right: 16%;
+    bottom: 8%;
+    height: 24%;
+    background: radial-gradient(circle at 50% 0, rgba(0,0,0,0.9) 0, transparent 70%);
+    opacity: 0.95;
+  }
+
+  /* Coffee table */
+  .table {
+    position: absolute;
+    left: 20%;
+    right: 32%;
+    bottom: 8%;
+    height: 14%;
+  }
+
+  .table-top {
+    position: absolute;
+    left: 10%;
+    right: 10%;
+    top: 0;
+    height: 35%;
+    border-radius: 14px;
+    background:
+      linear-gradient(145deg, #f5f0eb, #e2d1c1);
+    box-shadow: 0 10px 18px rgba(0,0,0,0.6);
+  }
+  .table-legs {
+    position: absolute;
+    left: 16%;
+    right: 16%;
+    bottom: 0;
+    top: 30%;
+  }
+  .table-leg {
+    position: absolute;
+    bottom: 0;
+    width: 3px;
+    border-radius: 999px;
+    background: linear-gradient(180deg, #d0b29c, #8b6245);
+    box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
+  }
+  .table-leg:nth-child(1) { left: 22%; }
+  .table-leg:nth-child(2) { left: 50%; transform: translateX(-50%); }
+  .table-leg:nth-child(3) { right: 22%; }
+
+  .table-decor {
+    position: absolute;
+    left: 18%;
+    right: 18%;
+    top: 10%;
+    height: 60%;
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-end;
+  }
+  .decor-vase {
+    width: 16px;
+    height: 22px;
+    border-radius: 50% 50% 40% 40%;
+    background: radial-gradient(circle at 30% 10%, #ffffff 0, #dfd7ff 30%, #9c91f6 75%);
+    box-shadow: 0 7px 10px rgba(0,0,0,0.5);
+    position: relative;
+  }
+  .decor-vase::after {
+    content: "";
+    position: absolute;
+    left: 50%;
+    top: -10px;
+    width: 1px;
+    height: 12px;
+    background: linear-gradient(180deg, #6bbb7a, #29643a);
+  }
+  .decor-book {
+    width: 18px;
+    height: 8px;
+    border-radius: 3px;
+    background: linear-gradient(145deg, #1f2135, #10111e);
+    box-shadow: 0 5px 7px rgba(0,0,0,0.6);
+    position: relative;
+  }
+  .decor-book::before {
+    content: "";
+    position: absolute;
+    inset: 1px;
+    border-radius: 2px;
+    border-top: 2px solid rgba(255,255,255,0.24);
+  }
+
+  /* Wall art */
+  .wall-art {
+    position: absolute;
+    left: 26%;
+    right: 22%;
+    top: 20%;
+    height: 24%;
+    border-radius: 14px;
+    background:
+      linear-gradient(145deg, #f7f4f1, #e1d9ce);
+    box-shadow:
+      0 18px 24px rgba(0,0,0,0.7),
+      0 0 0 1px rgba(0,0,0,0.45);
+    overflow: hidden;
+  }
+  .wall-art-inner {
+    position: absolute;
+    inset: 8% 10%;
+    border-radius: 10px;
+    background:
+      radial-gradient(circle at 15% 20%, #f8d6b0 0, transparent 55%),
+      radial-gradient(circle at 70% 80%, #a3d2f9 0, transparent 55%),
+      radial-gradient(circle at 95% 10%, #f8a0b1 0, transparent 50%),
+      linear-gradient(145deg, #151622, #1e2235);
+  }
+  .wall-art-inner::before {
+    content: "";
+    position: absolute;
+    inset: 12% 30% 18% 6%;
+    border-radius: 999px;
+    border: 2px solid rgba(255,255,255,0.4);
+  }
+  .wall-art-inner::after {
+    content: "";
+    position: absolute;
+    inset: 22% 6% 8% 34%;
+    border-radius: 10px;
+    border: 2px solid rgba(255,255,255,0.4);
+  }
+
+  /* Product tags */
+  .tag {
+    position: absolute;
+    z-index: 4;
+    width: 22px;
+    height: 22px;
+    border-radius: 999px;
+    background: rgba(15,15,25,0.8);
+    border: 1px solid rgba(255,255,255,0.18);
+    box-shadow:
+      0 0 0 1px rgba(0,0,0,0.5),
+      0 8px 15px rgba(0,0,0,0.65);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    transition: transform var(--transition-fast), box-shadow var(--transition-fast), background 0.18s ease-out;
+    backdrop-filter: blur(10px);
+  }
+
+  .tag::before,
+  .tag::after {
+    content: "";
+    position: absolute;
+    border-radius: inherit;
+    inset: 2px;
+  }
+  .tag::before {
+    border: 1px solid rgba(255,255,255,0.35);
+    opacity: 0.85;
+  }
+  .tag::after {
+    background: radial-gradient(circle at 30% 20%, rgba(255,255,255,0.7) 0, rgba(255,255,255,0) 55%);
+    mix-blend-mode: screen;
+  }
+
+  .tag-dot {
+    position: relative;
+    width: 6px;
+    height: 6px;
+    border-radius: 999px;
+    background: #ffffff;
+    box-shadow: 0 0 0 3px rgba(21,21,33,0.85);
+  }
+
+  .tag:hover {
+    transform: translateY(-1px) scale(1.03);
+    box-shadow:
+      0 0 0 1px rgba(255,255,255,0.25),
+      0 10px 20px rgba(0,0,0,0.85);
+    background: rgba(18,18,32,0.98);
+  }
+
+  .tag[data-target="tag1"] { top: 22%; left: 22%; }
+  .tag[data-target="tag2"] { top: 66%; left: 56%; }
+  .tag[data-target="tag3"] { top: 44%; right: 18%; }
+
+  .tag.active {
+    background: rgba(242,182,121,0.95);
+    border-color: rgba(255,255,255,0.85);
+  }
+  .tag.active .tag-dot {
+    background: #151521;
+    box-shadow: 0 0 0 4px rgba(21,21,33,0.8);
+  }
+
+  /* Swatch pattern (reusable) */
+  .swatch {
+    position: relative;
+    border-radius: 8px;
+    overflow: hidden;
+    background-color: #25253a;
+  }
+  .swatch-main {
+    position: absolute;
+    inset: 0;
+  }
+
+  .swatch.pattern-aurora {
+    background:
+      radial-gradient(circle at 0% 0%, #f7d5aa 0, #f5c495 16%, transparent 55%),
+      radial-gradient(circle at 80% 100%, #89d9bb 0, transparent 50%),
+      #101323;
+  }
+  .swatch.pattern-aurora .swatch-main {
+    background-image:
+      radial-gradient(circle at 0% 120%, rgba(0,0,0,0.42) 0, transparent 60%),
+      repeating-linear-gradient(
+        135deg,
+        rgba(255,255,255,0.2) 0,
+        rgba(255,255,255,0.2) 1px,
+        transparent 1px,
+        transparent 8px
+      );
+    mix-blend-mode: soft-light;
+    opacity: 0.8;
+  }
+
+  .swatch.pattern-linen {
+    background:
+      linear-gradient(120deg, #f7f1e5, #e2d5c3);
+  }
+  .swatch.pattern-linen .swatch-main {
+    background-image:
+      repeating-linear-gradient(
+        0deg,
+        rgba(182,160,132,0.45) 0,
+        rgba(182,160,132,0.45) 1px,
+        transparent 1px,
+        transparent 4px
+      ),
+      repeating-linear-gradient(
+        90deg,
+        rgba(182,160,132,0.45) 0,
+        rgba(182,160,132,0.45) 1px,
+        transparent 1px,
+        transparent 6px
+      );
+    opacity: 0.45;
+    mix-blend-mode: multiply;
+  }
+
+  .swatch.pattern-ink {
+    background:
+      radial-gradient(circle at 50% 0%, #fce4d4 0, transparent 55%),
+      radial-gradient(circle at 0% 100%, #c2f0ff 0, transparent 58%),
+      #111322;
+  }
+  .swatch.pattern-ink .swatch-main {
+    background-image:
+      radial-gradient(circle at 20% 40%, rgba(0,0,0,0.9) 0, transparent 32%),
+      radial-gradient(circle at 70% 70%, rgba(0,0,0,0.8) 0, transparent 30%);
+    mix-blend-mode: normal;
+    opacity: 0.85;
+  }
+
+  /* Product cards */
+  .product-card {
+    position: absolute;
+    min-width: 200px;
+    max-width: 230px;
+    border-radius: 14px;
+    padding: 10px 10px 10px;
+    background: linear-gradient(145deg, rgba(15,15,25,0.97), rgba(17,17,31,0.95));
+    border: 1px solid rgba(255,255,255,0.18);
+    box-shadow:
+      0 18px 40px rgba(0,0,0,0.9),
+      0 0 0 1px rgba(0,0,0,0.7);
+    backdrop-filter: blur(14px);
+    display: none;
+    z-index: 5;
+  }
+
+  .product-card.visible {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    animation: popIn var(--transition-med);
+    transform-origin: top left;
+  }
+
+  @keyframes popIn {
+    from {
+      opacity: 0;
+      transform: translateY(4px) scale(0.96);
+    }
+    to {
+      opacity: 1;
+      transform: translateY(0) scale(1);
+    }
+  }
+
+  .product-card-main {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+  }
+
+  .product-info {
+    display: flex;
+    flex-direction: column;
+    gap: 3px;
+  }
+  .product-name {
+    font-size: 12px;
+    font-weight: 600;
+    letter-spacing: 0.01em;
+  }
+  .product-detail-line {
+    font-size: 11px;
+    color: var(--text-soft);
+  }
+  .product-meta {
+    display: flex;
+    align-items: center;
+    gap: 6px;
+    margin-top: 2px;
+  }
+  .price {
+    font-size: 12px;
+    font-weight: 600;
+    color: var(--accent);
+  }
+  .pill {
+    font-size: 10px;
+    padding: 2px 6px;
+    border-radius: 999px;
+    background: rgba(242,182,121,0.08);
+    border: 1px solid rgba(242,182,121,0.25);
+    color: var(--accent);
+  }
+
+  .btn-view {
+    margin-left: auto;
+    font-size: 11px;
+    padding: 4px 10px;
+    border-radius: 999px;
+    border: none;
+    cursor: pointer;
+    background: linear-gradient(145deg, #f2b679, #f59562);
+    color: #141320;
+    font-weight: 600;
+    letter-spacing: 0.03em;
+    text-transform: uppercase;
+    box-shadow:
+      0 7px 14px rgba(0,0,0,0.7),
+      0 0 0 1px rgba(0,0,0,0.5);
+    transition: transform 0.15s ease-out, box-shadow 0.15s ease-out, filter 0.15s ease-out;
+  }
+  .btn-view:hover {
+    transform: translateY(-1px);
+    box-shadow:
+      0 10px 20px rgba(0,0,0,0.85),
+      0 0 0 1px rgba(0,0,0,0.6);
+    filter: brightness(1.03);
+  }
+  .btn-view:active {
+    transform: translateY(0);
+    box-shadow:
+      0 5px 10px rgba(0,0,0,0.8),
+      0 0 0 1px rgba(0,0,0,0.6);
+  }
+
+  .card-topline {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 6px;
+  }
+  .tag-label {
+    font-size: 10px;
+    text-transform: uppercase;
+    letter-spacing: 0.14em;
+    color: var(--text-soft);
+  }
+
+  .close-hit {
+    width: 16px;
+    height: 16px;
+    border-radius: 999px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    margin-left: 4px;
+    opacity: 0.7;
+    transition: opacity 0.18s ease-out, background 0.18s ease-out;
+  }
+  .close-hit:hover {
+    opacity: 1;
+    background: rgba(255,255,255,0.02);
+  }
+  .close-x {
+    width: 9px;
+    height: 9px;
+    position: relative;
+  }
+  .close-x::before,
+  .close-x::after {
+    content: "";
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    width: 100%;
+    height: 1px;
+    background: rgba(255,255,255,0.7);
+    transform-origin: center;
+  }
+  .close-x::before {
+    transform: translate(-50%, -50%) rotate(45deg);
+  }
+  .close-x::after {
+    transform: translate(-50%, -50%) rotate(-45deg);
+  }
+
+  .card-layout {
+    display: flex;
+    flex-direction: column;
+    gap: 6px;
+  }
+  .card-body {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+  }
+
+  .card-swatch-wrap {
+    width: 54px;
+    height: 54px;
+    flex: 0 0 auto;
+    border-radius: 13px;
+    padding: 3px;
+    background: radial-gradient(circle at 10% 0, rgba(255,255,255,0.4), transparent 40%);
+    box-shadow:
+      0 10px 20px rgba(0,0,0,0.7),
+      0 0 0 1px rgba(255,255,255,0.08);
+  }
+  .card-swatch-inner {
+    width: 100%;
+    height: 100%;
+    border-radius: 10px;
+    overflow: hidden;
+    position: relative;
+  }
+
+  /* Card placements relative to tags */
+  #card1 { top: 24%; left: 22%; transform: translate(-2px, 20px); }
+  #card2 { bottom: 14%; left: 36%; transform: translate(-6px, 0); }
+  #card3 { top: 26%; right: 18%; transform: translate(-40%, 16px); }
+
+  /* IG Controls */
+  .ig-controls {
+    padding: 8px 14px 0;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+  .ig-actions-left {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+  }
+  .control-icon {
+    width: 22px;
+    height: 22px;
+    position: relative;
+    cursor: pointer;
+  }
+  .control-icon.heart::before {
+    content: "";
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    width: 11px;
+    height: 10px;
+    transform: translate(-50%, -50%) rotate(-45deg);
+    border-radius: 6px 6px 0 0;
+    background: #fefefe;
+  }
+  .control-icon.heart::after {
+    content: "";
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    width: 11px;
+    height: 10px;
+    transform: translate(-50%, -50%) rotate(45deg);
+    border-radius: 6px 6px 0 0;
+    background: #fefefe;
+  }
+  .control-icon.comment::before {
+    content: "";
+    position: absolute;
+    inset: 4px 4px 7px 4px;
+    border-radius: 50% 50% 45% 45%;
+    border: 1.6px solid #fefefe;
+  }
+  .control-icon.comment::after {
+    content: "";
+    position: absolute;
+    left: 40%;
+    bottom: 4px;
+    width: 6px;
+    height: 6px;
+    border-radius: 0 0 6px 0;
+    border-right: 1.6px solid #fefefe;
+    border-bottom: 1.6px solid #fefefe;
+  }
+  .control-icon.share::before {
+    content: "";
+    position: absolute;
+    inset: 5px 7px;
+    border-radius: 4px;
+    border: 1.5px solid #fefefe;
+  }
+  .control-icon.share::after {
+    content: "";
+    position: absolute;
+    left: 50%;
+    top: 3px;
+    width: 10px;
+    height: 8px;
+    border-radius: 10px 10px 0 0;
+    border: 1.5px solid #fefefe;
+    border-bottom: none;
+    transform: translateX(-50%);
+  }
+  .control-icon.save::before {
+    content: "";
+    position: absolute;
+    inset: 4px 5px;
+    border-radius: 3px 3px 2px 2px;
+    border: 1.5px solid #fefefe;
+  }
+  .control-icon.save::after {
+    content: "";
+    position: absolute;
+    left: 10px;
+    bottom: 5px;
+    width: 5px;
+    height: 5px;
+    background: #fefefe;
+    clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 70%, 0 100%);
+  }
+
+  .ig-indicator {
+    font-size: 11px;
+    color: var(--text-soft);
+  }
+  .dots {
+    display: inline-flex;
+    gap: 3px;
+    margin-left: 6px;
+  }
+  .dot {
+    width: 4px;
+    height: 4px;
+    border-radius: 999px;
+    background: rgba(255,255,255,0.28);
+  }
+  .dot.active {
+    width: 9px;
+    background: #fefefe;
+  }
+
+  /* IG Meta section */
+  .ig-meta-section {
+    padding: 4px 14px 10px;
+  }
+  .likes-row {
+    font-size: 12px;
+    font-weight: 600;
+    margin-bottom: 4px;
+    display: flex;
+    align-items: center;
+    gap: 6px;
+  }
+  .likes-avatars {
+    display: flex;
+  }
+  .likes-avatar {
+    width: 16px;
+    height: 16px;
+    border-radius: 50%;
+    border: 1px solid #12121c;
+    background: radial-gradient(circle at 30% 20%, #ffffff 0, #d8daf0 45%, #9a9fcb);
+    box-shadow: 0 0 0 1px rgba(0,0,0,0.4);
+  }
+  .likes-avatar + .likes-avatar {
+    margin-left: -6px;
+  }
+
+  .caption {
+    font-size: 12px;
+    line-height: 1.5;
+  }
+  .caption b {
+    font-weight: 600;
+  }
+  .caption .tag-accent {
+    color: var(--accent);
+    font-weight: 500;
+  }
+  .caption .more {
+    color: var(--text-soft);
+  }
+
+  .view-comments {
+    margin-top: 4px;
+    font-size: 12px;
+    color: var(--text-soft);
+  }
+  .comment {
+    margin-top: 2px;
+    font-size: 12px;
+  }
+  .comment b {
+    font-weight: 600;
+  }
+  .timestamp {
+    margin-top: 6px;
+    font-size: 10px;
+    letter-spacing: 0.16em;
+    text-transform: uppercase;
+    color: var(--text-soft);
+  }
+  .shop-link {
+    color: var(--blue-link);
+    font-weight: 500;
+    cursor: pointer;
+  }
+
+  /* Tap hint */
+  .hint {
+    position: absolute;
+    inset: 12px 10px auto auto;
+    background: rgba(0,0,0,0.55);
+    border-radius: 999px;
+    padding: 4px 8px;
+    font-size: 10px;
+    display: inline-flex;
+    align-items: center;
+    gap: 5px;
+    color: var(--text-muted);
+    border: 1px solid rgba(255,255,255,0.16);
+    backdrop-filter: blur(12px);
+    z-index: 6;
+  }
+  .hint-dot {
+    width: 8px;
+    height: 8px;
+    border-radius: 999px;
+    border: 1px solid rgba(255,255,255,0.5);
+    position: relative;
+  }
+  .hint-dot::before {
+    content: "";
+    position: absolute;
+    inset: 2px;
+    border-radius: inherit;
+    background: #ffffff;
+  }
+
+  @media (max-width: 400px) {
+    .frame {
+      border-radius: 0;
+      box-shadow: none;
+      border: none;
+    }
+  }
+</style>
+</head>
+<body>
+<div class="frame">
+  <div class="ig-shell">
+    <!-- Header -->
+    <div class="ig-header">
+      <div class="ig-header-left">
+        <div class="avatar-wrap">
+          <div class="avatar-inner"></div>
+        </div>
+        <div class="ig-identity">
+          <div class="ig-handle">LumenWall Studio</div>
+          <div class="ig-meta">
+            Tokyo, Japan
+            <span class="ig-meta-dot"></span>
+            <span>Sponsored</span>
+          </div>
+        </div>
+      </div>
+      <div class="ig-header-right">
+        <div class="ig-icon shop" aria-hidden="true"></div>
+        <div class="ig-icon more" aria-hidden="true"></div>
+      </div>
+    </div>
+
+    <!-- Media -->
+    <div class="ig-media-wrap">
+      <div class="ig-media" id="media">
+        <div class="room">
+          <div class="room-wall">
+            <div class="wallpattern-base"></div>
+            <div class="wallpattern-arches"></div>
+            <div class="wallpattern-lines"></div>
+          </div>
+          <div class="room-floor">
+            <div class="floor-planks"></div>
+          </div>
+
+          <div class="sofa">
+            <div class="sofa-base">
+              <div class="sofa-arm"></div>
+              <div class="sofa-cushion-main"></div>
+              <div class="sofa-cushion-alt"></div>
+              <div class="throw"></div>
+            </div>
+            <div class="sofa-shadow"></div>
+          </div>
+
+          <div class="table">
+            <div class="table-top"></div>
+            <div class="table-decor">
+              <div class="decor-vase"></div>
+              <div class="decor-book"></div>
+            </div>
+            <div class="table-legs">
+              <div class="table-leg"></div>
+              <div class="table-leg"></div>
+              <div class="table-leg"></div>
+            </div>
+          </div>
+
+          <div class="wall-art">
+            <div class="wall-art-inner"></div>
+          </div>
+
+          <!-- Tap hint -->
+          <div class="hint" id="tapHint">
+            <span class="hint-dot"></span>
+            <span>Tap to view pieces</span>
+          </div>
+
+          <!-- Product tags -->
+          <button class="tag" type="button" data-target="card1" aria-label="View wallcovering">
+            <span class="tag-dot"></span>
+          </button>
+          <button class="tag" type="button" data-target="card2" aria-label="View sofa upholstery">
+            <span class="tag-dot"></span>
+          </button>
+          <button class="tag" type="button" data-target="card3" aria-label="View art wallcovering panel">
+            <span class="tag-dot"></span>
+          </button>
+
+          <!-- Product Cards -->
+          <div class="product-card" id="card1">
+            <div class="card-layout">
+              <div class="card-topline">
+                <span class="tag-label">Signature Wallcovering</span>
+                <div class="close-hit" data-close="card1" aria-label="Close wallcovering details">
+                  <div class="close-x"></div>
+                </div>
+              </div>
+              <div class="card-body">
+                <div class="card-swatch-wrap">
+                  <div class="card-swatch-inner swatch pattern-aurora">
+                    <div class="swatch-main"></div>
+                  </div>
+                </div>
+                <div class="product-info">
+                  <div class="product-name">Aurora Gradient Mural</div>
+                  <div class="product-detail-line">Peel + paste vinyl · 27 in repeat</div>
+                  <div class="product-meta">
+                    <span class="price">$168 / roll</span>
+                    <span class="pill">Limited edition</span>
+                  </div>
+                </div>
+                <button class="btn-view" type="button">View</button>
+              </div>
+            </div>
+          </div>
+
+          <div class="product-card" id="card2">
+            <div class="card-layout">
+              <div class="card-topline">
+                <span class="tag-label">Texture Companion</span>
+                <div class="close-hit" data-close="card2" aria-label="Close upholstery details">
+                  <div class="close-x"></div>
+                </div>
+              </div>
+              <div class="card-body">
+                <div class="card-swatch-wrap">
+                  <div class="card-swatch-inner swatch pattern-linen">
+                    <div class="swatch-main"></div>
+                  </div>
+                </div>
+                <div class="product-info">
+                  <div class="product-name">Cloudline Linen Weave</div>
+                  <div class="product-detail-line">Grasscloth-style wallcovering</div>
+                  <div class="product-meta">
+                    <span class="price">$132 / roll</span>
+                    <span class="pill">Matte texture</span>
+                  </div>
+                </div>
+                <button class="btn-view" type="button">View</button>
+              </div>
+            </div>
+          </div>
+
+          <div class="product-card" id="card3">
+            <div class="card-layout">
+              <div class="card-topline">
+                <span class="tag-label">Art Panel</span>
+                <div class="close-hit" data-close="card3" aria-label="Close wall panel details">
+                  <div class="close-x"></div>
+                </div>
+              </div>
+              <div class="card-body">
+                <div class="card-swatch-wrap">
+                  <div class="card-swatch-inner swatch pattern-ink">
+                    <div class="swatch-main"></div>
+                  </div>
+                </div>
+                <div class="product-info">
+                  <div class="product-name">Ink Bloom Panel Set</div>
+                  <div class="product-detail-line">Triptych wallcovering panels</div>
+                  <div class="product-meta">
+                    <span class="price">$420 / set</span>
+                    <span class="pill">Made to measure</span>
+                  </div>
+                </div>
+                <button class="btn-view" type="button">View</button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- Controls -->
+    <div class="ig-controls">
+      <div class="ig-actions-left">
+        <div class="control-icon heart" aria-hidden="true"></div>
+        <div class="control-icon comment" aria-hidden="true"></div>
+        <div class="control-icon share" aria-hidden="true"></div>
+      </div>
+      <div class="control-icon save" aria-hidden="true"></div>
+    </div>
+
+    <!-- Meta -->
+    <div class="ig-meta-section">
+      <div class="likes-row">
+        <div class="likes-avatars">
+          <div class="likes-avatar"></div>
+          <div class="likes-avatar"></div>
+          <div class="likes-avatar"></div>
+        </div>
+        <span>1,284 likes</span>
+      </div>
+      <div class="caption">
+        <b>lumenwall.studio</b>
+        Evening light on our
+        <span class="tag-accent">Aurora Gradient</span>
+        mural, paired with soft linen texture and a custom inked panel set.
+        <span class="more">More</span>
+      </div>
+      <div class="view-comments">View all 32 comments</div>
+      <div class="comment"><b>case.form</b> That gradient is unreal. Does it come in cool tones?</div>
+      <div class="comment"><b>lumenwall.studio</b> Yes – tap the tags to explore the full palette.</div>
+      <div class="timestamp">2 hours ago · <span class="shop-link" id="shopLink">Shop collection</span></div>
+    </div>
+  </div>
+</div>
+
+<script>
+(function() {
+  const tags = Array.from(document.querySelectorAll('.tag'));
+  const cards = Array.from(document.querySelectorAll('.product-card'));
+  const hint = document.getElementById('tapHint');
+  const media = document.getElementById('media');
+  const shopLink = document.getElementById('shopLink');
+
+  function hideAllCards() {
+    cards.forEach(c => c.classList.remove('visible'));
+    tags.forEach(t => t.classList.remove('active'));
+  }
+
+  function showCard(id) {
+    const card = document.getElementById(id);
+    if (!card) return;
+    const tag = tags.find(t => t.dataset.target === id);
+    hideAllCards();
+    card.classList.add('visible');
+    if (tag) tag.classList.add('active');
+    if (hint) hint.style.display = 'none';
+  }
+
+  tags.forEach(tag => {
+    tag.addEventListener('click', function(e) {
+      e.stopPropagation();
+      const targetId = this.dataset.target;
+      const card = document.getElementById(targetId);
+      const isVisible = card && card.classList.contains('visible');
+      if (isVisible) {
+        hideAllCards();
+      } else {
+        showCard(targetId);
+      }
+    });
+  });
+
+  cards.forEach(card => {
+    card.addEventListener('click', e => e.stopPropagation());
+  });
+
+  document.addEventListener('click', function(e) {
+    if (!media.contains(e.target)) {
+      hideAllCards();
+    }
+  });
+
+  document.querySelectorAll('.close-hit').forEach(btn => {
+    btn.addEventListener('click', function(e) {
+      e.stopPropagation();
+      const id = this.getAttribute('data-close');
+      const card = document.getElementById(id);
+      if (card) card.classList.remove('visible');
+      const tag = tags.find(t => t.dataset.target === id);
+      if (tag) tag.classList.remove('active');
+    });
+  });
+
+  if (shopLink) {
+    shopLink.addEventListener('click', function(e) {
+      e.preventDefault();
+      showCard('card1');
+    });
+  }
+
+  let hintTimeout = setTimeout(() => {
+    if (hint) hint.style.opacity = '0.9';
+  }, 800);
+
+  media.addEventListener('click', function() {
+    if (hint) hint.style.display = 'none';
+    clearTimeout(hintTimeout);
+  });
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/bde366feb227/gpt.png b/data/artifacts/bde366feb227/gpt.png
new file mode 100644
index 0000000..8b12bab
Binary files /dev/null and b/data/artifacts/bde366feb227/gpt.png differ
diff --git a/data/artifacts/bde366feb227/grok.html b/data/artifacts/bde366feb227/grok.html
new file mode 100644
index 0000000..c5073cf
--- /dev/null
+++ b/data/artifacts/bde366feb227/grok.html
@@ -0,0 +1,629 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Maison Murale — Shoppable Post</title>
+<style>
+  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+  body {
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+    background: #0a0a0a;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    min-height: 100vh;
+    padding: 24px 12px;
+    color: #262626;
+  }
+  .phone {
+    width: 390px;
+    max-width: 100%;
+    background: #fff;
+    border-radius: 28px;
+    overflow: hidden;
+    box-shadow: 0 25px 80px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.06);
+  }
+  /* IG header */
+  .ig-header {
+    display: flex;
+    align-items: center;
+    padding: 12px 14px;
+    gap: 10px;
+    border-bottom: 1px solid #efefef;
+  }
+  .avatar {
+    width: 34px; height: 34px;
+    border-radius: 50%;
+    background: conic-gradient(from 210deg, #c9a87c, #8b6f4e, #e8d5b5, #a68b5b, #c9a87c);
+    display: grid; place-items: center;
+    flex-shrink: 0;
+    position: relative;
+  }
+  .avatar::after {
+    content: "";
+    width: 28px; height: 28px;
+    border-radius: 50%;
+    background: linear-gradient(145deg, #2c2420, #4a3f35);
+    display: block;
+  }
+  .avatar-initial {
+    position: absolute;
+    font-size: 11px; font-weight: 600; color: #e8d5b5;
+    letter-spacing: .5px;
+  }
+  .user-meta { flex: 1; min-width: 0; }
+  .username { font-size: 13.5px; font-weight: 600; line-height: 1.2; }
+  .sponsored { font-size: 11px; color: #8e8e8e; }
+  .more-btn {
+    background: none; border: none; cursor: pointer;
+    padding: 6px; font-size: 18px; letter-spacing: 2px; color: #262626;
+  }
+  /* Media / room */
+  .media {
+    position: relative;
+    width: 100%;
+    aspect-ratio: 1 / 1;
+    overflow: hidden;
+    background: #d4c4a8;
+    cursor: default;
+  }
+  /* CSS room illustration */
+  .room {
+    position: absolute; inset: 0;
+    background:
+      linear-gradient(180deg, #e8dfd0 0%, #ddd2c0 40%, #cbbba3 100%);
+  }
+  /* Wallpaper pattern on back wall */
+  .wall {
+    position: absolute;
+    left: 0; right: 0; top: 0; bottom: 28%;
+    background-color: #f3ebe0;
+    background-image:
+      radial-gradient(ellipse 18px 28px at 30px 40px, transparent 40%, rgba(139,111,78,.18) 41%, rgba(139,111,78,.18) 55%, transparent 56%),
+      radial-gradient(ellipse 14px 22px at 70px 90px, transparent 40%, rgba(166,139,91,.14) 41%, rgba(166,139,91,.14) 52%, transparent 53%),
+      radial-gradient(ellipse 16px 24px at 110px 35px, transparent 40%, rgba(139,111,78,.16) 41%, rgba(139,111,78,.16) 54%, transparent 55%),
+      radial-gradient(ellipse 12px 20px at 50px 140px, transparent 40%, rgba(120,95,60,.12) 41%, rgba(120,95,60,.12) 50%, transparent 51%),
+      repeating-linear-gradient(
+        0deg,
+        transparent,
+        transparent 47px,
+        rgba(139,111,78,.07) 47px,
+        rgba(139,111,78,.07) 48px
+      ),
+      repeating-linear-gradient(
+        90deg,
+        transparent,
+        transparent 55px,
+        rgba(139,111,78,.05) 55px,
+        rgba(139,111,78,.05) 56px
+      );
+    background-size: 120px 160px, 100px 140px, 130px 150px, 90px 120px, 48px 48px, 56px 56px;
+  }
+  /* Soft botanical vine motif overlay */
+  .wall::before {
+    content: "";
+    position: absolute; inset: 0;
+    opacity: .45;
+    background-image:
+      radial-gradient(circle at 20% 30%, rgba(90,110,70,.2) 0 3px, transparent 4px),
+      radial-gradient(circle at 22% 34%, rgba(90,110,70,.15) 0 5px, transparent 6px),
+      radial-gradient(circle at 55% 55%, rgba(90,110,70,.18) 0 3px, transparent 4px),
+      radial-gradient(circle at 58% 50%, rgba(90,110,70,.12) 0 7px, transparent 8px),
+      radial-gradient(circle at 78% 22%, rgba(90,110,70,.2) 0 2px, transparent 3px),
+      radial-gradient(circle at 80% 26%, rgba(90,110,70,.14) 0 6px, transparent 7px),
+      radial-gradient(circle at 35% 70%, rgba(90,110,70,.16) 0 4px, transparent 5px),
+      radial-gradient(circle at 88% 68%, rgba(90,110,70,.15) 0 3px, transparent 4px);
+    background-size: 100% 100%;
+  }
+  /* Floor */
+  .floor {
+    position: absolute;
+    left: 0; right: 0; bottom: 0; height: 30%;
+    background: linear-gradient(180deg, #b8956a 0%, #a07d55 30%, #8c6c48 100%);
+    transform: perspective(400px) rotateX(8deg);
+    transform-origin: top center;
+  }
+  .floor::before {
+    content: "";
+    position: absolute; inset: 0;
+    background: repeating-linear-gradient(
+      90deg,
+      transparent 0 48px,
+      rgba(0,0,0,.08) 48px 49px
+    );
+  }
+  /* Baseboard */
+  .baseboard {
+    position: absolute;
+    left: 0; right: 0; bottom: 28%;
+    height: 10px;
+    background: linear-gradient(180deg, #f5f0e8, #e0d6c8);
+    box-shadow: 0 2px 4px rgba(0,0,0,.1);
+    z-index: 2;
+  }
+  /* Window light */
+  .window-light {
+    position: absolute;
+    top: 8%; right: 6%;
+    width: 28%; height: 38%;
+    background: linear-gradient(135deg, rgba(255,252,245,.55), rgba(255,248,230,.15));
+    border: 3px solid rgba(245,240,230,.7);
+    border-radius: 2px;
+    box-shadow: inset 0 0 40px rgba(255,250,240,.4), 0 8px 30px rgba(200,180,140,.15);
+    z-index: 2;
+  }
+  .window-light::before {
+    content: "";
+    position: absolute; inset: 0;
+    background:
+      linear-gradient(90deg, transparent 48%, rgba(245,240,230,.6) 48% 52%, transparent 52%),
+      linear-gradient(0deg, transparent 48%, rgba(245,240,230,.6) 48% 52%, transparent 52%);
+  }
+  /* Light rays on floor */
+  .sun-rays {
+    position: absolute;
+    bottom: 0; right: 5%;
+    width: 40%; height: 32%;
+    background: linear-gradient(160deg, rgba(255,248,220,.35), transparent 70%);
+    clip-path: polygon(40% 0, 100% 0, 85% 100%, 0% 100%);
+    z-index: 1;
+    pointer-events: none;
+  }
+  /* Console table */
+  .console {
+    position: absolute;
+    bottom: 22%; left: 50%;
+    transform: translateX(-50%);
+    width: 52%; height: 14%;
+    z-index: 3;
+  }
+  .console-top {
+    position: absolute; top: 0; left: 0; right: 0;
+    height: 12px;
+    background: linear-gradient(180deg, #5c4030, #3d2a1f);
+    border-radius: 2px 2px 0 0;
+    box-shadow: 0 2px 6px rgba(0,0,0,.25);
+  }
+  .console-leg {
+    position: absolute; top: 12px;
+    width: 6px; height: calc(100% - 12px);
+    background: linear-gradient(90deg, #4a3224, #2e1e14);
+  }
+  .console-leg.l { left: 8%; }
+  .console-leg.r { right: 8%; }
+  /* Vase on console */
+  .vase {
+    position: absolute;
+    bottom: 34%; left: 42%;
+    width: 28px; height: 48px;
+    background: linear-gradient(90deg, #c4b8a4, #e8e0d4 40%, #b8ac98);
+    border-radius: 40% 40% 30% 30% / 20% 20% 60% 60%;
+    z-index: 4;
+    box-shadow: 2px 4px 8px rgba(0,0,0,.15);
+  }
+  .vase::before {
+    content: "";
+    position: absolute;
+    top: -18px; left: 50%; transform: translateX(-50%);
+    width: 4px; height: 22px;
+    background: #5a6e48;
+    border-radius: 2px;
+    box-shadow: 6px 4px 0 -1px #6a7e55, -5px 8px 0 -1px #4a5e3a, 3px -2px 0 -1px #7a8e60;
+  }
+  .vase::after {
+    content: "";
+    position: absolute;
+    top: -28px; left: 50%; transform: translateX(-30%);
+    width: 22px; height: 16px;
+    background: radial-gradient(ellipse, #7a9a5a 0%, #5a7a40 60%, transparent 70%);
+    border-radius: 50%;
+  }
+  /* Framed art / second wall moment */
+  .frame {
+    position: absolute;
+    top: 18%; left: 10%;
+    width: 22%; height: 28%;
+    background: #faf6f0;
+    border: 5px solid #3d2a1f;
+    box-shadow: 3px 4px 12px rgba(0,0,0,.18);
+    z-index: 3;
+  }
+  .frame::before {
+    content: "";
+    position: absolute; inset: 8px;
+    background:
+      linear-gradient(160deg, #d4c8b0, #e8dfd0),
+      radial-gradient(circle at 40% 40%, rgba(90,110,70,.25) 0 20%, transparent 50%);
+    background-blend-mode: multiply;
+  }
+  /* Armchair suggestion */
+  .chair {
+    position: absolute;
+    bottom: 18%; right: 8%;
+    width: 26%; height: 22%;
+    z-index: 3;
+  }
+  .chair-back {
+    position: absolute; top: 0; left: 10%; right: 10%;
+    height: 55%;
+    background: linear-gradient(180deg, #6b4f3a, #5a3f2c);
+    border-radius: 40% 40% 8% 8% / 30% 30% 10% 10%;
+    box-shadow: inset 0 4px 8px rgba(255,255,255,.08);
+  }
+  .chair-seat {
+    position: absolute; bottom: 15%; left: 0; right: 0;
+    height: 35%;
+    background: linear-gradient(180deg, #7a5a42, #5c4030);
+    border-radius: 8px 8px 4px 4px;
+  }
+  .chair-leg {
+    position: absolute; bottom: 0;
+    width: 5px; height: 18%;
+    background: #2e1e14;
+  }
+  .chair-leg.l { left: 15%; }
+  .chair-leg.r { right: 15%; }
+  /* Product tags */
+  .tag {
+    position: absolute;
+    z-index: 10;
+    width: 28px; height: 28px;
+    border-radius: 50%;
+    background: rgba(255,255,255,.92);
+    border: none;
+    cursor: pointer;
+    box-shadow: 0 2px 10px rgba(0,0,0,.28);
+    display: grid; place-items: center;
+    transition: transform .2s ease, box-shadow .2s ease;
+    padding: 0;
+  }
+  .tag::after {
+    content: "";
+    width: 9px; height: 9px;
+    border-radius: 50%;
+    background: #262626;
+    transition: transform .2s ease;
+  }
+  .tag:hover, .tag.active {
+    transform: scale(1.12);
+    box-shadow: 0 3px 16px rgba(0,0,0,.35);
+  }
+  .tag.active::after {
+    background: #c9a87c;
+  }
+  .tag .pulse {
+    position: absolute; inset: -4px;
+    border-radius: 50%;
+    border: 2px solid rgba(255,255,255,.7);
+    animation: pulse 2.2s ease-out infinite;
+    pointer-events: none;
+  }
+  @keyframes pulse {
+    0% { transform: scale(.85); opacity: .8; }
+    100% { transform: scale(1.55); opacity: 0; }
+  }
+  .tag-1 { top: 32%; left: 48%; }
+  .tag-2 { top: 55%; left: 18%; }
+  .tag-3 { top: 42%; right: 22%; left: auto; }
+  /* Product card popup */
+  .product-card {
+    position: absolute;
+    z-index: 20;
+    width: 220px;
+    background: #fff;
+    border-radius: 12px;
+    box-shadow: 0 12px 40px rgba(0,0,0,.28), 0 0 0 1px rgba(0,0,0,.04);
+    padding: 12px;
+    display: none;
+    animation: cardIn .22s ease;
+    bottom: 16px; left: 50%;
+    transform: translateX(-50%);
+  }
+  .product-card.show { display: block; }
+  @keyframes cardIn {
+    from { opacity: 0; transform: translateX(-50%) translateY(8px); }
+    to { opacity: 1; transform: translateX(-50%) translateY(0); }
+  }
+  .pc-inner { display: flex; gap: 12px; align-items: center; }
+  .swatch {
+    width: 56px; height: 56px;
+    border-radius: 8px;
+    flex-shrink: 0;
+    box-shadow: inset 0 0 0 1px rgba(0,0,0,.06);
+    position: relative;
+    overflow: hidden;
+  }
+  .swatch-a {
+    background-color: #f3ebe0;
+    background-image:
+      radial-gradient(ellipse 8px 12px at 14px 18px, transparent 40%, rgba(139,111,78,.35) 41%, rgba(139,111,78,.35) 55%, transparent 56%),
+      radial-gradient(ellipse 6px 10px at 36px 38px, transparent 40%, rgba(90,110,70,.3) 41%, rgba(90,110,70,.3) 52%, transparent 53%);
+    background-size: 40px 50px;
+  }
+  .swatch-b {
+    background-color: #e8e4dc;
+    background-image:
+      repeating-linear-gradient(45deg, transparent, transparent 4px, rgba(100,90,70,.12) 4px 5px),
+      radial-gradient(circle at 30% 40%, rgba(70,90,60,.25) 0 3px, transparent 4px),
+      radial-gradient(circle at 70% 60%, rgba(70,90,60,.2) 0 2px, transparent 3px);
+  }
+  .swatch-c {
+    background:
+      linear-gradient(135deg, #2c2420 25%, transparent 25%) -10px 0,
+      linear-gradient(225deg, #2c2420 25%, transparent 25%) -10px 0,
+      linear-gradient(315deg, #2c2420 25%, transparent 25%),
+      linear-gradient(45deg, #2c2420 25%, transparent 25%);
+    background-size: 12px 12px;
+    background-color: #c9a87c;
+  }
+  .pc-info { flex: 1; min-width: 0; }
+  .pc-brand { font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: #8e8e8e; margin-bottom: 2px; }
+  .pc-name { font-size: 13px; font-weight: 600; line-height: 1.25; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+  .pc-price { font-size: 13px; color: #262626; font-weight: 500; }
+  .pc-view {
+    display: block;
+    width: 100%;
+    margin-top: 10px;
+    padding: 9px;
+    background: #262626;
+    color: #fff;
+    border: none;
+    border-radius: 8px;
+    font-size: 12.5px;
+    font-weight: 600;
+    cursor: pointer;
+    letter-spacing: .3px;
+    transition: background .15s;
+  }
+  .pc-view:hover { background: #000; }
+  .pc-close {
+    position: absolute; top: 6px; right: 8px;
+    background: none; border: none;
+    font-size: 16px; color: #8e8e8e;
+    cursor: pointer; line-height: 1; padding: 4px;
+  }
+  /* Actions row */
+  .actions {
+    display: flex;
+    align-items: center;
+    padding: 10px 14px 6px;
+    gap: 14px;
+  }
+  .actions button {
+    background: none; border: none; cursor: pointer;
+    padding: 0; display: flex; align-items: center;
+  }
+  .actions svg { width: 24px; height: 24px; }
+  .actions .spacer { flex: 1; }
+  .liked svg path { fill: #ed4956; stroke: #ed4956; }
+  /* Likes & caption */
+  .likes {
+    padding: 0 14px;
+    font-size: 13.5px; font-weight: 600;
+  }
+  .caption {
+    padding: 6px 14px 2px;
+    font-size: 13.5px; line-height: 1.4;
+  }
+  .caption .un { font-weight: 600; margin-right: 4px; }
+  .caption .more { color: #8e8e8e; cursor: pointer; }
+  .comments-preview {
+    padding: 4px 14px;
+    font-size: 13.5px; color: #8e8e8e;
+    cursor: pointer;
+  }
+  .comment {
+    padding: 2px 14px;
+    font-size: 13.5px; line-height: 1.35;
+  }
+  .comment .un { font-weight: 600; margin-right: 4px; }
+  .timestamp {
+    padding: 8px 14px 4px;
+    font-size: 10px; color: #8e8e8e;
+    text-transform: uppercase; letter-spacing: .2px;
+  }
+  /* Add comment bar */
+  .add-comment {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    padding: 12px 14px;
+    border-top: 1px solid #efefef;
+    margin-top: 4px;
+  }
+  .add-comment .sm-avatar {
+    width: 28px; height: 28px;
+    border-radius: 50%;
+    background: linear-gradient(135deg, #ddd, #bbb);
+    flex-shrink: 0;
+  }
+  .add-comment span {
+    flex: 1; font-size: 13.5px; color: #8e8e8e;
+  }
+  .shop-badge {
+    display: inline-flex;
+    align-items: center;
+    gap: 4px;
+    font-size: 11px;
+    font-weight: 600;
+    color: #262626;
+    background: rgba(255,255,255,.92);
+    padding: 5px 10px;
+    border-radius: 6px;
+    position: absolute;
+    bottom: 14px; left: 12px;
+    z-index: 5;
+    box-shadow: 0 2px 8px rgba(0,0,0,.15);
+    pointer-events: none;
+  }
+  .shop-badge svg { width: 12px; height: 12px; }
+</style>
+</head>
+<body>
+<div class="phone">
+  <header class="ig-header">
+    <div class="avatar"><span class="avatar-initial">M</span></div>
+    <div class="user-meta">
+      <div class="username">maisonmurale</div>
+      <div class="sponsored">Sponsored</div>
+    </div>
+    <button class="more-btn" aria-label="More">•••</button>
+  </header>
+
+  <div class="media" id="media">
+    <div class="room">
+      <div class="wall"></div>
+      <div class="window-light"></div>
+      <div class="sun-rays"></div>
+      <div class="frame"></div>
+      <div class="baseboard"></div>
+      <div class="floor"></div>
+      <div class="console">
+        <div class="console-top"></div>
+        <div class="console-leg l"></div>
+        <div class="console-leg r"></div>
+      </div>
+      <div class="vase"></div>
+      <div class="chair">
+        <div class="chair-back"></div>
+        <div class="chair-seat"></div>
+        <div class="chair-leg l"></div>
+        <div class="chair-leg r"></div>
+      </div>
+    </div>
+
+    <div class="shop-badge">
+      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 6h15l-1.5 9h-12z"/><circle cx="9" cy="20" r="1"/><circle cx="18" cy="20" r="1"/><path d="M6 6L5 3H2"/></svg>
+      Shop
+    </div>
+
+    <button class="tag tag-1" data-product="0" aria-label="View product"><span class="pulse"></span></button>
+    <button class="tag tag-2" data-product="1" aria-label="View product"><span class="pulse"></span></button>
+    <button class="tag tag-3" data-product="2" aria-label="View product"><span class="pulse"></span></button>
+
+    <div class="product-card" id="productCard">
+      <button class="pc-close" id="pcClose" aria-label="Close">×</button>
+      <div class="pc-inner">
+        <div class="swatch" id="pcSwatch"></div>
+        <div class="pc-info">
+          <div class="pc-brand">Maison Murale</div>
+          <div class="pc-name" id="pcName"></div>
+          <div class="pc-price" id="pcPrice"></div>
+        </div>
+      </div>
+      <button class="pc-view">View</button>
+    </div>
+  </div>
+
+  <div class="actions" id="actions">
+    <button class="like-btn" id="likeBtn" aria-label="Like">
+      <svg viewBox="0 0 24 24" fill="none" stroke="#262626" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
+    </button>
+    <button aria-label="Comment">
+      <svg viewBox="0 0 24 24" fill="none" stroke="#262626" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
+    </button>
+    <button aria-label="Share">
+      <svg viewBox="0 0 24 24" fill="none" stroke="#262626" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
+    </button>
+    <div class="spacer"></div>
+    <button aria-label="Save">
+      <svg viewBox="0 0 24 24" fill="none" stroke="#262626" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
+    </button>
+  </div>
+
+  <div class="likes" id="likeCount">12,847 likes</div>
+  <div class="caption">
+    <span class="un">maisonmurale</span>Soft morning light, quiet botanicals. Our <strong>Hearth &amp; Vine</strong> collection turns bare walls into a lived-in sanctuary. Tap the tags to explore each pattern. <span class="more">more</span>
+  </div>
+  <div class="comments-preview">View all 234 comments</div>
+  <div class="comment"><span class="un">atelier.lena</span>The scale of that vine print is perfection 🤍</div>
+  <div class="comment"><span class="un">design.by.cole</span>Need this for the reading nook project</div>
+  <div class="timestamp">2 hours ago</div>
+
+  <div class="add-comment">
+    <div class="sm-avatar"></div>
+    <span>Add a comment…</span>
+  </div>
+</div>
+
+<script>
+(function () {
+  var products = [
+    {
+      name: "Hearth Vine — Cream",
+      price: "from $148 / roll",
+      swatch: "swatch-a"
+    },
+    {
+      name: "Olive Branch Damask",
+      price: "from $162 / roll",
+      swatch: "swatch-b"
+    },
+    {
+      name: "Gilded Lattice Noir",
+      price: "from $178 / roll",
+      swatch: "swatch-c"
+    }
+  ];
+
+  var card = document.getElementById("productCard");
+  var pcName = document.getElementById("pcName");
+  var pcPrice = document.getElementById("pcPrice");
+  var pcSwatch = document.getElementById("pcSwatch");
+  var tags = document.querySelectorAll(".tag");
+  var activeIdx = null;
+
+  function openCard(idx) {
+    var p = products[idx];
+    pcName.textContent = p.name;
+    pcPrice.textContent = p.price;
+    pcSwatch.className = "swatch " + p.swatch;
+    card.classList.add("show");
+    tags.forEach(function (t, i) {
+      t.classList.toggle("active", i === idx);
+    });
+    activeIdx = idx;
+  }
+
+  function closeCard() {
+    card.classList.remove("show");
+    tags.forEach(function (t) { t.classList.remove("active"); });
+    activeIdx = null;
+  }
+
+  tags.forEach(function (tag) {
+    tag.addEventListener("click", function (e) {
+      e.stopPropagation();
+      var idx = parseInt(tag.getAttribute("data-product"), 10);
+      if (activeIdx === idx) {
+        closeCard();
+      } else {
+        openCard(idx);
+      }
+    });
+  });
+
+  document.getElementById("pcClose").addEventListener("click", function (e) {
+    e.stopPropagation();
+    closeCard();
+  });
+
+  document.getElementById("media").addEventListener("click", function (e) {
+    if (!e.target.closest(".tag") && !e.target.closest(".product-card")) {
+      closeCard();
+    }
+  });
+
+  var liked = false;
+  var baseLikes = 12847;
+  document.getElementById("likeBtn").addEventListener("click", function () {
+    liked = !liked;
+    this.classList.toggle("liked", liked);
+    document.getElementById("likeCount").textContent =
+      (baseLikes + (liked ? 1 : 0)).toLocaleString() + " likes";
+  });
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/bde366feb227/grok.png b/data/artifacts/bde366feb227/grok.png
new file mode 100644
index 0000000..26e7206
Binary files /dev/null and b/data/artifacts/bde366feb227/grok.png differ
diff --git a/data/artifacts/d7f4f8ca5f8d/claude-code.html b/data/artifacts/d7f4f8ca5f8d/claude-code.html
new file mode 100644
index 0000000..8918f9e
--- /dev/null
+++ b/data/artifacts/d7f4f8ca5f8d/claude-code.html
@@ -0,0 +1,450 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<title>Atelier — Wallpaper Swatch Match</title>
+<style>
+  :root{
+    --bg1:#1c1b1a; --bg2:#26221f; --ink:#e9e2d4; --muted:#9c9385;
+    --gold:#c9a24b; --gold-soft:#b8955a; --frame:#3a332b;
+    --cell:60px;
+  }
+  *{box-sizing:border-box; -webkit-tap-highlight-color:transparent;}
+  html,body{height:100%;}
+  body{
+    margin:0; min-height:100%;
+    font-family:"Georgia","Times New Roman",serif;
+    color:var(--ink);
+    background:
+      radial-gradient(1200px 700px at 50% -10%, #2f2a25 0%, transparent 60%),
+      linear-gradient(160deg, var(--bg1), var(--bg2));
+    display:flex; flex-direction:column; align-items:center;
+    justify-content:flex-start; gap:14px; padding:20px 14px 40px;
+  }
+  header{ text-align:center; margin-top:6px; }
+  h1{
+    margin:0; font-weight:400; letter-spacing:.32em;
+    font-size:clamp(18px,5.5vw,30px); text-transform:uppercase;
+    color:var(--ink);
+  }
+  h1 .amp{ color:var(--gold); }
+  .subtitle{
+    margin:6px 0 0; font-size:11px; letter-spacing:.42em;
+    text-transform:uppercase; color:var(--muted);
+  }
+  .hud{
+    display:flex; gap:10px; align-items:stretch; width:min(94vw,460px);
+    justify-content:center;
+  }
+  .stat{
+    flex:1; background:linear-gradient(180deg,#2b2620,#211d18);
+    border:1px solid var(--frame); border-radius:12px;
+    padding:9px 6px; text-align:center;
+    box-shadow: inset 0 1px 0 rgba(255,255,255,.04);
+  }
+  .stat .label{
+    font-size:9.5px; letter-spacing:.28em; text-transform:uppercase; color:var(--muted);
+  }
+  .stat .value{
+    font-size:clamp(18px,5vw,24px); color:var(--gold); margin-top:3px; letter-spacing:.04em;
+    font-variant-numeric:tabular-nums;
+  }
+  .btn{
+    flex:1; background:linear-gradient(180deg,#332b21,#241d16);
+    border:1px solid var(--gold-soft); border-radius:12px;
+    color:var(--gold); cursor:pointer; font-family:inherit;
+    letter-spacing:.2em; text-transform:uppercase; font-size:12px;
+    transition:transform .12s ease, background .2s ease;
+    display:flex; align-items:center; justify-content:center;
+  }
+  .btn:hover{ background:linear-gradient(180deg,#3d3325,#2a2118); }
+  .btn:active{ transform:scale(.96); }
+
+  .frame{
+    padding:12px; border-radius:18px;
+    background:linear-gradient(180deg,#322b22,#231e18);
+    border:1px solid var(--frame);
+    box-shadow:
+      0 18px 40px rgba(0,0,0,.55),
+      inset 0 0 0 1px rgba(201,162,75,.18),
+      inset 0 2px 0 rgba(255,255,255,.04);
+  }
+  .board{
+    position:relative;
+    width:min(88vw,432px); aspect-ratio:1/1;
+    border-radius:10px;
+    background:
+      repeating-linear-gradient(45deg, rgba(255,255,255,.015) 0 8px, transparent 8px 16px),
+      #17140f;
+    box-shadow: inset 0 0 26px rgba(0,0,0,.6);
+    touch-action:none; overflow:hidden;
+  }
+
+  .tile{
+    position:absolute; border-radius:8px;
+    background-repeat:no-repeat; background-position:center; background-size:100% 100%;
+    box-shadow:
+      inset 0 0 0 1px rgba(0,0,0,.32),
+      inset 0 0 0 3px rgba(255,255,255,.05),
+      0 2px 5px rgba(0,0,0,.35);
+    cursor:pointer;
+    transition:top .34s cubic-bezier(.2,.85,.3,1), left .34s cubic-bezier(.2,.85,.3,1),
+               transform .16s ease, box-shadow .18s ease;
+    will-change:top,left,transform;
+  }
+  .tile.sel{
+    z-index:6; transform:scale(.88);
+    box-shadow:
+      0 0 0 3px var(--gold),
+      0 0 18px rgba(201,162,75,.7),
+      inset 0 0 0 3px rgba(255,255,255,.12);
+  }
+  .tile.clearing{
+    z-index:5; animation:shimmer .44s ease forwards;
+  }
+  @keyframes shimmer{
+    0%{ transform:scale(1); filter:brightness(1); }
+    35%{ transform:scale(1.14); filter:brightness(1.9) saturate(1.5);
+         box-shadow:0 0 26px rgba(255,240,205,.95), inset 0 0 0 3px rgba(255,255,255,.5); }
+    100%{ transform:scale(.1) rotate(12deg); filter:brightness(2.4); opacity:0; }
+  }
+
+  /* ——— luxe wallpaper swatches (CSS-drawn) ——— */
+  /* 0 · Damask — deep forest */
+  .t0{ background-color:#3a4a3f;
+    background-image:
+      radial-gradient(ellipse 42% 26% at 50% 20%, #93a795 0 44%, transparent 47%),
+      radial-gradient(ellipse 20% 34% at 50% 55%, #b4c4b0 0 46%, transparent 49%),
+      radial-gradient(ellipse 30% 16% at 25% 62%, #93a795 0 46%, transparent 49%),
+      radial-gradient(ellipse 30% 16% at 75% 62%, #93a795 0 46%, transparent 49%),
+      radial-gradient(circle at 50% 87%, #b4c4b0 0 11%, transparent 13%);
+  }
+  /* 1 · Floral — dusty rose */
+  .t1{ background-color:#b0868a;
+    background-image:
+      radial-gradient(circle at 50% 27%, #e4cdcf 0 15%, transparent 17%),
+      radial-gradient(circle at 27% 55%, #e4cdcf 0 15%, transparent 17%),
+      radial-gradient(circle at 73% 55%, #e4cdcf 0 15%, transparent 17%),
+      radial-gradient(circle at 50% 78%, #e4cdcf 0 15%, transparent 17%),
+      radial-gradient(circle at 50% 52%, #f2e4dd 0 12%, transparent 14%);
+  }
+  /* 2 · Geometric weave — antique gold */
+  .t2{ background-color:#b7994f;
+    background-image:
+      repeating-linear-gradient(45deg, rgba(255,248,220,.55) 0 4px, transparent 4px 11px),
+      repeating-linear-gradient(-45deg, rgba(90,68,26,.6) 0 4px, transparent 4px 11px);
+  }
+  /* 3 · Trellis lattice — slate blue */
+  .t3{ background-color:#5d7083;
+    background-image:
+      repeating-linear-gradient(45deg, transparent 0 11px, rgba(190,205,216,.9) 11px 13px),
+      repeating-linear-gradient(-45deg, transparent 0 11px, rgba(190,205,216,.9) 11px 13px);
+  }
+  /* 4 · Pearl medallion — mauve/plum */
+  .t4{ background-color:#856576;
+    background-image:
+      radial-gradient(circle at 50% 50%, #decad3 0 23%, transparent 25%),
+      radial-gradient(circle at 50% 50%, #a9899a 0 34%, transparent 36%),
+      radial-gradient(circle at 12% 12%, #c2a6b3 0 12%, transparent 14%),
+      radial-gradient(circle at 88% 88%, #c2a6b3 0 12%, transparent 14%),
+      radial-gradient(circle at 88% 12%, #c2a6b3 0 12%, transparent 14%),
+      radial-gradient(circle at 12% 88%, #c2a6b3 0 12%, transparent 14%);
+  }
+  /* 5 · Quatrefoil — warm caramel taupe */
+  .t5{ background-color:#9c7c58;
+    background-image:
+      radial-gradient(circle at 30% 30%, #cdb18b 0 21%, transparent 23%),
+      radial-gradient(circle at 70% 30%, #cdb18b 0 21%, transparent 23%),
+      radial-gradient(circle at 30% 70%, #cdb18b 0 21%, transparent 23%),
+      radial-gradient(circle at 70% 70%, #cdb18b 0 21%, transparent 23%),
+      radial-gradient(circle at 50% 50%, #e0cbaa 0 12%, transparent 14%);
+  }
+
+  footer{ font-size:10.5px; letter-spacing:.26em; text-transform:uppercase; color:var(--muted); }
+</style>
+</head>
+<body>
+  <header>
+    <h1>Atelier <span class="amp">&middot;</span> Swatch Match</h1>
+    <p class="subtitle">Line up three fine wallpapers</p>
+  </header>
+
+  <div class="hud">
+    <div class="stat"><div class="label">Score</div><div class="value" id="score">0</div></div>
+    <div class="stat"><div class="label">Moves</div><div class="value" id="moves">0</div></div>
+    <button class="btn" id="restart">Restart</button>
+  </div>
+
+  <div class="frame">
+    <div class="board" id="board"></div>
+  </div>
+
+  <footer>Swap adjacent swatches to make a match</footer>
+
+<script>
+(function(){
+  const N = 6, TYPES = 6, GAP = 4;
+  const TR = "top .34s cubic-bezier(.2,.85,.3,1), left .34s cubic-bezier(.2,.85,.3,1), transform .16s ease, box-shadow .18s ease";
+  const board = document.getElementById('board');
+  const scoreEl = document.getElementById('score');
+  const movesEl = document.getElementById('moves');
+
+  let grid = [];            // grid[r][c] = tileId | null
+  let tiles = {};           // id -> {type, el, r, c}
+  let nextId = 1;
+  let selected = null;      // tileId
+  let score = 0, moves = 0;
+  let busy = false;
+
+  const sleep = ms => new Promise(res => setTimeout(res, ms));
+  const randType = () => Math.floor(Math.random() * TYPES);
+  const cell = () => board.clientWidth / N;
+
+  function createTile(type){
+    const id = nextId++;
+    const el = document.createElement('div');
+    el.className = 'tile t' + type;
+    el.dataset.id = id;
+    board.appendChild(el);
+    tiles[id] = { type, el, r:null, c:null };
+    return id;
+  }
+
+  function placeNow(id, r, c){
+    // instant placement (used for spawning above the board)
+    const cs = cell();
+    const t = tiles[id];
+    t.el.style.transition = 'none';
+    t.el.style.width  = (cs - GAP) + 'px';
+    t.el.style.height = (cs - GAP) + 'px';
+    t.el.style.left   = (c * cs + GAP/2) + 'px';
+    t.el.style.top    = (r * cs + GAP/2) + 'px';
+    t.r = r; t.c = c;
+    void t.el.offsetWidth; // commit reflow so the next move animates
+  }
+
+  function layout(instant){
+    const cs = cell();
+    for(let r=0;r<N;r++){
+      for(let c=0;c<N;c++){
+        const id = grid[r][c];
+        if(id == null) continue;
+        const t = tiles[id];
+        t.el.style.transition = instant ? 'none' : TR;
+        t.el.style.width  = (cs - GAP) + 'px';
+        t.el.style.height = (cs - GAP) + 'px';
+        t.el.style.left   = (c * cs + GAP/2) + 'px';
+        t.el.style.top    = (r * cs + GAP/2) + 'px';
+        t.r = r; t.c = c;
+      }
+    }
+    if(instant){
+      void board.offsetWidth;
+      for(const id in tiles) tiles[id].el.style.transition = TR;
+    }
+  }
+
+  // ——— match detection ———
+  function typeGridFromGrid(){
+    const g = [];
+    for(let r=0;r<N;r++){ g[r]=[]; for(let c=0;c<N;c++){ const id=grid[r][c]; g[r][c]= id==null?-1:tiles[id].type; } }
+    return g;
+  }
+  function findMatchesIn(g){
+    const set = new Set();
+    // rows
+    for(let r=0;r<N;r++){
+      let run=1;
+      for(let c=1;c<=N;c++){
+        if(c<N && g[r][c]!==-1 && g[r][c]===g[r][c-1]) run++;
+        else { if(run>=3) for(let k=c-run;k<c;k++) set.add(r+','+k); run=1; }
+      }
+    }
+    // cols
+    for(let c=0;c<N;c++){
+      let run=1;
+      for(let r=1;r<=N;r++){
+        if(r<N && g[r][c]!==-1 && g[r][c]===g[r-1][c]) run++;
+        else { if(run>=3) for(let k=r-run;k<r;k++) set.add(k+','+c); run=1; }
+      }
+    }
+    return set;
+  }
+  function findMatches(){ return findMatchesIn(typeGridFromGrid()); }
+
+  function collapse(){
+    for(let c=0;c<N;c++){
+      const kept = [];
+      for(let r=N-1;r>=0;r--){ if(grid[r][c]!=null) kept.push(grid[r][c]); }
+      let i = 0, above = 1;
+      for(let r=N-1;r>=0;r--){
+        if(i < kept.length){ grid[r][c] = kept[i++]; }
+        else {
+          const id = createTile(randType());
+          placeNow(id, -(above++), c);   // spawn above, will fall on next layout()
+          grid[r][c] = id;
+        }
+      }
+    }
+  }
+
+  async function resolve(){
+    busy = true;
+    let combo = 0;
+    let matched = findMatches();
+    while(matched.size){
+      combo++;
+      score += matched.size * 10 * combo;
+      matched.forEach(k=>{
+        const [r,c] = k.split(',').map(Number);
+        const id = grid[r][c];
+        if(id!=null) tiles[id].el.classList.add('clearing');
+      });
+      updateHUD();
+      await sleep(440);
+      matched.forEach(k=>{
+        const [r,c] = k.split(',').map(Number);
+        const id = grid[r][c];
+        if(id!=null){ tiles[id].el.remove(); delete tiles[id]; grid[r][c]=null; }
+      });
+      collapse();
+      layout(false);
+      await sleep(360);
+      matched = findMatches();
+    }
+    ensurePlayable();
+    busy = false;
+  }
+
+  // ——— interaction ———
+  function tileIdFromEvent(e){
+    const el = e.target.closest('.tile');
+    if(!el) return null;
+    return parseInt(el.dataset.id, 10);
+  }
+
+  function select(id){
+    if(busy || id==null || !tiles[id]) return;
+    if(selected == null){
+      selected = id; tiles[id].el.classList.add('sel'); return;
+    }
+    if(selected === id){
+      tiles[id].el.classList.remove('sel'); selected = null; return;
+    }
+    const a = tiles[selected], b = tiles[id];
+    const adjacent = Math.abs(a.r-b.r) + Math.abs(a.c-b.c) === 1;
+    if(adjacent){
+      const prev = selected;
+      tiles[prev].el.classList.remove('sel');
+      selected = null;
+      attemptSwap(prev, id);
+    } else {
+      tiles[selected].el.classList.remove('sel');
+      selected = id; tiles[id].el.classList.add('sel');
+    }
+  }
+
+  async function attemptSwap(a, b){
+    busy = true;
+    const ta = tiles[a], tb = tiles[b];
+    const ar=ta.r, ac=ta.c, br=tb.r, bc=tb.c;
+    grid[ar][ac] = b; grid[br][bc] = a;
+    ta.r=br; ta.c=bc; tb.r=ar; tb.c=ac;
+    layout(false);
+    await sleep(340);
+
+    if(findMatches().size === 0){
+      // no match — revert
+      grid[ar][ac] = a; grid[br][bc] = b;
+      ta.r=ar; ta.c=ac; tb.r=br; tb.c=bc;
+      layout(false);
+      await sleep(340);
+      busy = false;
+    } else {
+      moves++; updateHUD();
+      await resolve();
+    }
+  }
+
+  board.addEventListener('click', e=>{
+    const id = tileIdFromEvent(e);
+    if(id!=null) select(id);
+  });
+
+  // ——— setup / helpers ———
+  function updateHUD(){ scoreEl.textContent = score; movesEl.textContent = moves; }
+
+  function buildBoard(){
+    // clear
+    board.innerHTML = '';
+    tiles = {}; grid = [];
+    selected = null; nextId = 1;
+    for(let r=0;r<N;r++){
+      grid[r]=[];
+      for(let c=0;c<N;c++){
+        let type;
+        do { type = randType(); }
+        while(
+          (c>=2 && tiles[grid[r][c-1]].type===type && tiles[grid[r][c-2]].type===type) ||
+          (r>=2 && tiles[grid[r-1][c]].type===type && tiles[grid[r-2][c]].type===type)
+        );
+        const id = createTile(type);
+        grid[r][c] = id;
+      }
+    }
+    layout(true);
+    ensurePlayable();
+  }
+
+  function hasMoves(){
+    const g = typeGridFromGrid();
+    const trySwap = (r1,c1,r2,c2)=>{
+      const t=g[r1][c1]; g[r1][c1]=g[r2][c2]; g[r2][c2]=t;
+      const ok = findMatchesIn(g).size>0;
+      const t2=g[r1][c1]; g[r1][c1]=g[r2][c2]; g[r2][c2]=t2;
+      return ok;
+    };
+    for(let r=0;r<N;r++) for(let c=0;c<N;c++){
+      if(c<N-1 && trySwap(r,c,r,c+1)) return true;
+      if(r<N-1 && trySwap(r,c,r+1,c)) return true;
+    }
+    return false;
+  }
+
+  function ensurePlayable(){
+    let guard = 0;
+    while(!hasMoves() && guard++ < 20){
+      // reshuffle types among existing tiles until a move exists & no instant matches
+      const ids = [];
+      for(let r=0;r<N;r++) for(let c=0;c<N;c++) ids.push(grid[r][c]);
+      const types = ids.map(id=>tiles[id].type);
+      for(let i=types.length-1;i>0;i--){ const j=Math.floor(Math.random()*(i+1)); [types[i],types[j]]=[types[j],types[i]]; }
+      let k=0;
+      for(let r=0;r<N;r++) for(let c=0;c<N;c++){
+        const id=grid[r][c]; const t=types[k++];
+        tiles[id].type=t; tiles[id].el.className='tile t'+t;
+      }
+      if(findMatches().size>0) continue; // avoid pre-made matches, loop again
+    }
+  }
+
+  document.getElementById('restart').addEventListener('click', ()=>{
+    if(busy) return;
+    score = 0; moves = 0; updateHUD();
+    buildBoard();
+  });
+
+  let resizeTimer;
+  window.addEventListener('resize', ()=>{
+    clearTimeout(resizeTimer);
+    resizeTimer = setTimeout(()=>layout(true), 80);
+  });
+
+  // start
+  buildBoard();
+  updateHUD();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7f4f8ca5f8d/claude-code.png b/data/artifacts/d7f4f8ca5f8d/claude-code.png
new file mode 100644
index 0000000..21e27e3
Binary files /dev/null and b/data/artifacts/d7f4f8ca5f8d/claude-code.png differ
diff --git a/data/artifacts/d7f4f8ca5f8d/gemma3-12b.html b/data/artifacts/d7f4f8ca5f8d/gemma3-12b.html
new file mode 100644
index 0000000..02d9011
--- /dev/null
+++ b/data/artifacts/d7f4f8ca5f8d/gemma3-12b.html
@@ -0,0 +1,284 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Luxe Match</title>
+    <style>
+        body {
+            font-family: sans-serif;
+            background-color: #f2e9d8; /* Muted beige */
+            margin: 0;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            height: 100vh;
+        }
+
+        .game-container {
+            width: 360px;
+            border: 2px solid #c8b7a0; /* Soft gray */
+            padding: 20px;
+            background-color: white;
+            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+        }
+
+        .grid {
+            display: grid;
+            grid-template-columns: repeat(6, 50px);
+            grid-gap: 5px;
+        }
+
+        .tile {
+            width: 50px;
+            height: 50px;
+            background-color: #e7d2c1; /* Light tan */
+            border: 1px solid #ddd;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            font-size: 24px;
+            cursor: pointer;
+        }
+
+        .tile.matched {
+            animation: shimmer 0.5s forwards;
+            background-color: #ffeadc; /* Lighter tan */
+        }
+
+
+        @keyframes shimmer {
+            0% { transform: scale(1); }
+            25% { transform: scale(1.1); }
+            75% { transform: scale(1.1); }
+            100% { transform: scale(1); }
+        }
+
+        #controls {
+            margin-top: 20px;
+            text-align: center;
+        }
+
+        button {
+            padding: 8px 16px;
+            background-color: #d4a97f; /* Warm brown */
+            color: white;
+            border: none;
+            cursor: pointer;
+            font-size: 14px;
+        }
+
+         /* Wallpaper patterns (CSS drawn) - Example, can be expanded greatly*/
+        .tile.pattern-damask { background-image: url("data:image/svg+xml,%3Csvg width='50' height='50' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23c8b7a0' stroke='%23ddd' stroke-width='1'%3E%3Crect x='5' y='5' width='40' height='40'/%3E%3Crect x='15' y='15' width='20' height='20'/%3E%3Crect x='25' y='25' width='20' height='20'/%3E%3C/g%3E%3C/svg%3E"); }
+        .tile.pattern-floral { background-image: url("data:image/svg+xml,%3Csvg width='50' height='50' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23c8b7a0' stroke='%23ddd' stroke-width='1'%3E%3Ccircle cx='25' cy='25' r='15'/%3E%3C/g%3E%3C/svg%3E"); }
+        .tile.pattern-geometric { background-image: url("data:image/svg+xml,%3Csvg width='50' height='50' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23c8b7a0' stroke='%23ddd' stroke-width='1'%3E%3Crect x='10' y='10' width='30' height='30'/%3E%3Crect x='20' y='20' width='10' height='10'/%3E%3C/g%3E%3C/svg%3E"); }
+
+    </style>
+</head>
+<body>
+
+    <div class="game-container">
+        <h2>Luxe Match</h2>
+        <div id="grid" class="grid"></div>
+        <div id="controls">
+            <p>Moves: <span id="move-count">0</span></p>
+            <button id="restart-button">Restart</button>
+        </div>
+    </div>
+
+    <script>
+        const gridElement = document.getElementById('grid');
+        const moveCountSpan = document.getElementById('move-count');
+        const restartButton = document.getElementById('restart-button');
+
+        const gridSize = 6;
+        let grid = [];
+        let moves = 0;
+
+        const patterns = ["pattern-damask", "pattern-floral", "pattern-geometric"];
+
+
+        function createGrid() {
+            grid = [];
+            for (let i = 0; i < gridSize; i++) {
+                grid[i] = [];
+                for (let j = 0; j < gridSize; j++) {
+                    const patternIndex = Math.floor(Math.random() * patterns.length);
+                    grid[i][j] = patternIndex;
+                }
+            }
+        }
+
+        function renderGrid() {
+            gridElement.innerHTML = '';
+            for (let i = 0; i < gridSize; i++) {
+                for (let j = 0; j < gridSize; j++) {
+                    const tile = document.createElement('div');
+                    tile.classList.add('tile', patterns[grid[i][j]]); // Add pattern class
+                    tile.dataset.row = i;
+                    tile.dataset.col = j;
+                    tile.addEventListener('click', tileClickHandler);
+                    gridElement.appendChild(tile);
+                }
+            }
+        }
+
+        function tileClickHandler(event) {
+            const row = parseInt(event.target.dataset.row);
+            const col = parseInt(event.target.dataset.col);
+            swapTiles(row, col, null); // Initially, no second tile selected
+        }
+
+
+        let firstTileClicked = null;
+
+        function swapTiles(row1, col1, row2, col2) {
+            if (firstTileClicked === null) {
+                firstTileClicked = { row: row1, col: col1 };
+                return;
+            }
+
+            const secondTile = { row: row1, col: col1 };
+
+             // Check if adjacent to the first tile. Not Diagonal
+            if (Math.abs(firstTileClicked.row - secondTile.row) + Math.abs(firstTileClicked.col - secondTile.col) !== 1) {
+                return;
+            }
+
+
+            moves++;
+            moveCountSpan.textContent = moves;
+
+            // Swap the tiles in the grid array
+            const temp = grid[firstTileClicked.row][firstTileClicked.col];
+            grid[firstTileClicked.row][firstTileClicked.col] = grid[secondTile.row][secondTile.col];
+            grid[secondTile.row][secondTile.col] = temp;
+
+            renderGrid();  // Re-render the entire grid after swapping
+
+
+             if (checkForMatches()) {
+                clearMatchedTiles();
+            } else {
+                // Swap back if no match found
+                 const temp2 = grid[firstTileClicked.row][firstTileClicked.col];
+                 grid[firstTileClicked.row][firstTileClicked.col] = grid[secondTile.row][secondTile.col];
+                 grid[secondTile.row][secondTile.col] = temp2;
+                 renderGrid();
+
+             }
+
+
+            firstTileClicked = null; // Reset for next click
+        }
+
+        function checkForMatches() {
+           let hasMatch = false;
+
+            // Check horizontal matches
+            for (let i = 0; i < gridSize; i++) {
+                for (let j = 0; j < gridSize - 2; j++) {
+                    if (grid[i][j] === grid[i][j + 1] && grid[i][j] === grid[i][j + 2]) {
+                        hasMatch = true;
+                        break;
+                    }
+                }
+                if(hasMatch) break;
+            }
+
+            // Check vertical matches
+            if(!hasMatch){
+               for (let j = 0; j < gridSize; j++) {
+                   for (let i = 0; i < gridSize - 2; i++) {
+                       if (grid[i][j] === grid[i + 1][j] && grid[i][j] === grid[i + 2][j]) {
+                           hasMatch = true;
+                           break;
+                       }
+                   }
+                   if(hasMatch) break;
+               }
+            }
+
+           return hasMatch;
+
+        }
+
+        function clearMatchedTiles() {
+            let matchedTiles = [];
+
+            // Find horizontal matches
+            for (let i = 0; i < gridSize; i++) {
+                for (let j = 0; j < gridSize - 2; j++) {
+                    if (grid[i][j] === grid[i][j + 1] && grid[i][j] === grid[i][j + 2]) {
+                        matchedTiles.push({ row: i, col: j });
+                        matchedTiles.push({ row: i, col: j + 1 });
+                        matchedTiles.push({ row: i, col: j + 2 });
+                    }
+                }
+            }
+
+            // Find vertical matches
+            for (let j = 0; j < gridSize; j++) {
+                for (let i = 0; i < gridSize - 2; i++) {
+                    if (grid[i][j] === grid[i + 1][j] && grid[i][j] === grid[i + 2][j]) {
+                        matchedTiles.push({ row: i, col: j });
+                        matchedTiles.push({ row: i + 1, col: j });
+                        matchedTiles.push({ row: i + 2, col: j });
+                    }
+                }
+            }
+
+           // Remove duplicates from matched tiles (important for correct clearing)
+           matchedTiles = [...new Set(matchedTiles)];
+
+
+            for (const tile of matchedTiles) {
+                grid[tile.row][tile.col] = -1; // Mark as cleared
+
+                const gridTileElement = document.querySelector(`.tile[data-row="${tile.row}"][data-col="${tile.col}"]`);
+                 if(gridTileElement){
+                    gridTileElement.classList.add('matched');
+                 }
+            }
+
+            setTimeout(() => {
+               // Shift Tiles Down or Left
+                for (let i = 0; i < gridSize; i++) {
+                    for (let j = 0; j < gridSize; j++) {
+                        if(grid[i][j] === -1){
+                            // Shift down
+                           let k = i;
+                           while(k > 0 && grid[k-1][j] !== -1 ){
+                               grid[k][j] = grid[k-1][j];
+                               k--;
+                           }
+
+                           if(k === 0){
+                              const patternIndex = Math.floor(Math.random() * patterns.length);
+                              grid[k][j] = patternIndex;
+                           }
+
+
+                        }
+                    }
+                }
+
+                 renderGrid();  // Re-render the entire grid after clearing and shifting
+            }, 500); // Delay to allow shimmer animation to complete before shifting
+        }
+
+
+
+        restartButton.addEventListener('click', () => {
+            createGrid();
+            moves = 0;
+            moveCountSpan.textContent = moves;
+            renderGrid();
+        });
+
+        createGrid();
+        renderGrid();
+    </script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7f4f8ca5f8d/gemma3-12b.png b/data/artifacts/d7f4f8ca5f8d/gemma3-12b.png
new file mode 100644
index 0000000..7e8a036
Binary files /dev/null and b/data/artifacts/d7f4f8ca5f8d/gemma3-12b.png differ
diff --git a/data/artifacts/d7f4f8ca5f8d/gpt.html b/data/artifacts/d7f4f8ca5f8d/gpt.html
new file mode 100644
index 0000000..ea50b54
--- /dev/null
+++ b/data/artifacts/d7f4f8ca5f8d/gpt.html
@@ -0,0 +1,613 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<title>Luxury Wallpaper Match</title>
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<style>
+:root{
+  --bg:#151519;
+  --panel:#202028;
+  --panel-soft:#252632;
+  --accent:#d7c6a1;
+  --accent-soft:#bfae8b;
+  --text:#f3f0ea;
+  --text-soft:#ccc6ba;
+  --grid-gap:6px;
+  --tile-size:64px;
+  --border-radius:10px;
+  --shadow-soft:0 18px 40px rgba(0,0,0,0.55);
+}
+*{box-sizing:border-box;margin:0;padding:0;}
+html,body{
+  height:100%;
+  background:radial-gradient(circle at top, #262635 0%, #121019 55%, #05040a 100%);
+  color:var(--text);
+  font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
+}
+body{
+  display:flex;
+  align-items:center;
+  justify-content:center;
+}
+.app-wrap{
+  background:radial-gradient(circle at top left, #303045 0, #1a1a24 45%, #111016 100%);
+  padding:20px 22px 22px;
+  border-radius:18px;
+  box-shadow:var(--shadow-soft);
+  border:1px solid rgba(255,255,255,0.06);
+  max-width:460px;
+  width:100%;
+}
+.header{
+  display:flex;
+  justify-content:space-between;
+  align-items:center;
+  margin-bottom:12px;
+}
+.title-block{
+  display:flex;
+  flex-direction:column;
+  gap:2px;
+}
+.title{
+  font-size:20px;
+  letter-spacing:.06em;
+  text-transform:uppercase;
+}
+.subtitle{
+  font-size:11px;
+  letter-spacing:.16em;
+  text-transform:uppercase;
+  color:var(--text-soft);
+}
+.controls{
+  display:flex;
+  align-items:center;
+  gap:10px;
+}
+.info-pill{
+  background:linear-gradient(135deg,#29293a,#202029);
+  border-radius:999px;
+  padding:6px 10px;
+  font-size:11px;
+  display:flex;
+  align-items:center;
+  gap:6px;
+  border:1px solid rgba(255,255,255,0.08);
+}
+.info-label{
+  text-transform:uppercase;
+  letter-spacing:.12em;
+  color:var(--text-soft);
+  font-size:10px;
+}
+.info-val{
+  font-variant-numeric:tabular-nums;
+  color:var(--accent);
+}
+button{
+  border:none;
+  cursor:pointer;
+  background:linear-gradient(135deg,#d7c6a1,#b49b6c);
+  color:#1d1408;
+  font-size:11px;
+  padding:6px 12px;
+  border-radius:999px;
+  text-transform:uppercase;
+  letter-spacing:.16em;
+  font-weight:600;
+  box-shadow:0 0 0 1px rgba(0,0,0,.4),0 7px 18px rgba(0,0,0,.55);
+  transition:transform .1s ease, box-shadow .1s ease, filter .15s ease;
+}
+button:active{
+  transform:translateY(1px) scale(.98);
+  box-shadow:0 4px 10px rgba(0,0,0,.6);
+  filter:brightness(.96);
+}
+.status-row{
+  display:flex;
+  justify-content:space-between;
+  margin-bottom:10px;
+  font-size:11px;
+  color:var(--text-soft);
+}
+.status-row span strong{color:var(--accent-soft);}
+.board-wrap{
+  background:radial-gradient(circle at top, #2b2b3c 0, #171720 40%, #0e0d13 100%);
+  border-radius:16px;
+  padding:14px;
+  border:1px solid rgba(255,255,255,0.08);
+  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.5);
+  position:relative;
+}
+.grid{
+  display:grid;
+  grid-template-columns:repeat(6,var(--tile-size));
+  grid-template-rows:repeat(6,var(--tile-size));
+  gap:var(--grid-gap);
+  touch-action:none;
+}
+.tile{
+  position:relative;
+  width:var(--tile-size);
+  height:var(--tile-size);
+  border-radius:12px;
+  overflow:hidden;
+  cursor:pointer;
+  transform-origin:center;
+  box-shadow:0 5px 15px rgba(0,0,0,0.7);
+  transition:transform .15s ease, box-shadow .15s ease, filter .15s ease;
+}
+.tile::before,
+.tile::after{
+  content:"";
+  position:absolute;
+  inset:0;
+}
+.tile-base{
+  position:absolute;
+  inset:0;
+  border-radius:inherit;
+}
+.tile.selected{
+  transform:translateY(-2px) scale(1.03);
+  box-shadow:0 10px 22px rgba(0,0,0,0.8);
+}
+.tile.hint{
+  animation:hintPulse 1.1s ease-in-out 0s 2;
+}
+@keyframes hintPulse{
+  0%,100%{transform:scale(1);}
+  50%{transform:scale(1.05);}
+}
+.tile.matched{
+  animation:shimmer .6s ease-out forwards;
+  pointer-events:none;
+}
+@keyframes shimmer{
+  0%{
+    transform:scale(1);
+    box-shadow:0 6px 16px rgba(0,0,0,0.8);
+  }
+  40%{
+    filter:brightness(1.8);
+    box-shadow:0 0 26px rgba(255,255,255,0.6);
+  }
+  100%{
+    opacity:0;
+    transform:scale(0.5);
+    filter:brightness(.7);
+    box-shadow:none;
+  }
+}
+.overlay-shine{
+  position:absolute;
+  inset:-20%;
+  background:conic-gradient(from 220deg,rgba(255,255,255,0.35),transparent 20%,transparent 60%,rgba(0,0,0,0.35));
+  mix-blend-mode:soft-light;
+  opacity:.35;
+  pointer-events:none;
+}
+.tile.gentle-glow{
+  animation:gentleGlow 4s ease-in-out infinite;
+}
+@keyframes gentleGlow{
+  0%,100%{box-shadow:0 5px 15px rgba(0,0,0,0.7);}
+  50%{box-shadow:0 7px 22px rgba(0,0,0,0.85);}
+}
+/* Palette & wallpaper patterns */
+.tile[data-type="0"] .tile-base{
+  background:
+    radial-gradient(circle at 12% 18%,rgba(255,255,255,0.22) 0,transparent 40%),
+    repeating-radial-gradient(circle at 50% 40%,rgba(255,255,255,0.13) 0,rgba(255,255,255,0.13) 2px,transparent 2px,transparent 6px),
+    linear-gradient(135deg,#4d4254,#31253a);
+}
+.tile[data-type="1"] .tile-base{
+  background:
+    radial-gradient(circle at 20% 15%,rgba(255,255,255,0.24) 0,transparent 36%),
+    repeating-linear-gradient(45deg,rgba(255,255,255,0.10) 0,rgba(255,255,255,0.10) 2px,transparent 2px,transparent 8px),
+    linear-gradient(135deg,#465458,#27333a);
+}
+.tile[data-type="2"] .tile-base{
+  background:
+    radial-gradient(circle at 78% 20%,rgba(255,255,255,0.22) 0,transparent 36%),
+    repeating-linear-gradient(135deg,rgba(255,255,255,0.14) 0,rgba(255,255,255,0.14) 1px,transparent 1px,transparent 7px),
+    linear-gradient(135deg,#59513f,#3a3225);
+}
+.tile[data-type="3"] .tile-base{
+  background:
+    radial-gradient(circle at 20% 80%,rgba(255,255,255,0.18) 0,transparent 40%),
+    repeating-radial-gradient(circle at 20% 25%,rgba(255,255,255,0.16) 0,rgba(255,255,255,0.16) 1.5px,transparent 1.5px,transparent 6px),
+    linear-gradient(135deg,#455662,#293540);
+}
+.tile[data-type="4"] .tile-base{
+  background:
+    radial-gradient(circle at 10% 10%,rgba(255,255,255,0.29) 0,transparent 36%),
+    repeating-linear-gradient(90deg,rgba(255,255,255,0.12) 0,rgba(255,255,255,0.12) 1px,transparent 1px,transparent 6px),
+    linear-gradient(135deg,#584952,#362633);
+}
+.tile[data-type="5"] .tile-base{
+  background:
+    radial-gradient(circle at 80% 82%,rgba(255,255,255,0.2) 0,transparent 40%),
+    repeating-linear-gradient(45deg,rgba(255,255,255,0.11) 0,rgba(255,255,255,0.11) 1px,transparent 1px,transparent 5px),
+    linear-gradient(135deg,#535049,#302f2b);
+}
+/* Damask / floral / geometric overlay patterns */
+.tile[data-type="0"]::before{
+  background-image:
+    radial-gradient(circle at 50% 25%,rgba(255,255,255,0.25) 0,transparent 55%),
+    radial-gradient(circle at 25% 70%,rgba(255,255,255,0.18) 0,transparent 55%),
+    radial-gradient(circle at 75% 70%,rgba(255,255,255,0.18) 0,transparent 55%);
+  background-size:40px 40px;
+  mix-blend-mode:soft-light;
+  opacity:.4;
+}
+.tile[data-type="1"]::before{
+  background-image:
+    radial-gradient(circle,rgba(255,255,255,0.16) 2px,transparent 2px),
+    radial-gradient(circle,rgba(255,255,255,0.10) 2px,transparent 2px);
+  background-position:0 0, 10px 10px;
+  background-size:20px 20px;
+  mix-blend-mode:soft-light;
+  opacity:.55;
+}
+.tile[data-type="2"]::before{
+  background-image:
+    linear-gradient(135deg,rgba(255,255,255,0.26) 1px,transparent 1px),
+    linear-gradient(225deg,rgba(255,255,255,0.18) 1px,transparent 1px);
+  background-size:10px 10px;
+  mix-blend-mode:soft-light;
+  opacity:.6;
+}
+.tile[data-type="3"]::before{
+  background-image:
+    radial-gradient(circle at 50% 30%,rgba(255,255,255,0.22) 0,transparent 55%),
+    radial-gradient(circle at 30% 70%,rgba(255,255,255,0.17) 0,transparent 45%),
+    radial-gradient(circle at 70% 70%,rgba(255,255,255,0.17) 0,transparent 45%);
+  background-size:44px 44px;
+  mix-blend-mode:soft-light;
+  opacity:.42;
+}
+.tile[data-type="4"]::before{
+  background-image:
+    radial-gradient(circle,rgba(255,255,255,0.26) 0,rgba(255,255,255,0.26) 1px,transparent 1px),
+    radial-gradient(circle,rgba(255,255,255,0.18) 0,rgba(255,255,255,0.18) 1px,transparent 1px);
+  background-size:14px 14px;
+  background-position:0 0,7px 7px;
+  mix-blend-mode:soft-light;
+  opacity:.5;
+}
+.tile[data-type="5"]::before{
+  background-image:
+    linear-gradient(135deg,rgba(255,255,255,0.2) 0,rgba(255,255,255,0.2) 1px,transparent 1px),
+    linear-gradient(225deg,rgba(255,255,255,0.12) 0,rgba(255,255,255,0.12) 1px,transparent 1px);
+  background-size:12px 12px;
+  mix-blend-mode:soft-light;
+  opacity:.5;
+}
+/* Highlight edge / inner glow */
+.tile::after{
+  background:
+    radial-gradient(circle at 10% 0,rgba(255,255,255,0.45) 0,transparent 55%),
+    radial-gradient(circle at 90% 100%,rgba(0,0,0,0.6) 0,transparent 60%);
+  mix-blend-mode:soft-light;
+  opacity:.55;
+  pointer-events:none;
+}
+.footer-note{
+  margin-top:10px;
+  font-size:10px;
+  letter-spacing:.12em;
+  text-transform:uppercase;
+  color:var(--text-soft);
+  text-align:right;
+  opacity:.8;
+}
+.footer-note span{
+  color:var(--accent-soft);
+}
+@media (max-width:480px){
+  :root{--tile-size:52px;--grid-gap:5px;}
+  .app-wrap{max-width:92vw;padding:16px;}
+  .title{font-size:18px;}
+  .subtitle{font-size:10px;}
+  .status-row{font-size:10px;}
+}
+</style>
+</head>
+<body>
+<div class="app-wrap">
+  <div class="header">
+    <div class="title-block">
+      <div class="title">Maison Match</div>
+      <div class="subtitle">Swap luxe wallpapers into gentle harmony</div>
+    </div>
+    <div class="controls">
+      <div class="info-pill">
+        <span class="info-label">Score</span>
+        <span class="info-val" id="score">0</span>
+      </div>
+      <div class="info-pill">
+        <span class="info-label">Moves</span>
+        <span class="info-val" id="moves">0</span>
+      </div>
+      <button id="restartBtn">Restart</button>
+    </div>
+  </div>
+  <div class="status-row">
+    <span>Line up <strong>3 or more</strong> matching swatches.</span>
+    <span>Swap <strong>adjacent</strong> tiles only.</span>
+  </div>
+  <div class="board-wrap">
+    <div id="grid" class="grid" aria-label="Wallpaper matching board"></div>
+    <div class="overlay-shine"></div>
+  </div>
+  <div class="footer-note">
+    <span>Tip</span> — Pause, breathe, and move with intention.
+  </div>
+</div>
+<script>
+(function(){
+  const size = 6;
+  const types = 6;
+  const gridEl = document.getElementById('grid');
+  const scoreEl = document.getElementById('score');
+  const movesEl = document.getElementById('moves');
+  const restartBtn = document.getElementById('restartBtn');
+
+  let board = [];
+  let selected = null;
+  let animating = false;
+  let score = 0;
+  let moves = 0;
+
+  function idx(r,c){return r*size+c;}
+
+  function randomType(){
+    return Math.floor(Math.random()*types);
+  }
+
+  function createEmptyBoard(){
+    board = new Array(size*size).fill(0);
+  }
+
+  function hasMatchAt(r,c,arr){
+    const t = arr[idx(r,c)];
+    if(t==null) return false;
+    let count=1;
+    for(let x=c-1;x>=0 && arr[idx(r,x)]===t;x--) count++;
+    for(let x=c+1;x<size && arr[idx(r,x)]===t;x++) count++;
+    if(count>=3) return true;
+    count=1;
+    for(let y=r-1;y>=0 && arr[idx(y,c)]===t;y--) count++;
+    for(let y=r+1;y<size && arr[idx(y,c)]===t;y++) count++;
+    return count>=3;
+  }
+
+  function generateBoard(){
+    createEmptyBoard();
+    for(let r=0;r<size;r++){
+      for(let c=0;c<size;c++){
+        let t;
+        do{
+          t=randomType();
+          board[idx(r,c)]=t;
+        }while(hasMatchAt(r,c,board));
+      }
+    }
+  }
+
+  function renderBoard(){
+    gridEl.innerHTML='';
+    for(let i=0;i<board.length;i++){
+      const tile=document.createElement('div');
+      tile.className='tile gentle-glow';
+      tile.dataset.index=i;
+      tile.dataset.type=board[i];
+      gridEl.appendChild(tile);
+    }
+  }
+
+  function updateScore(delta){
+    score+=delta;
+    scoreEl.textContent=score;
+  }
+  function updateMoves(){
+    moves++;
+    movesEl.textContent=moves;
+  }
+
+  function getRC(index){
+    return {r:Math.floor(index/size), c:index%size};
+  }
+
+  function areAdjacent(a,b){
+    const A=getRC(a), B=getRC(b);
+    return (Math.abs(A.r-B.r)+Math.abs(A.c-B.c))===1;
+  }
+
+  function findMatches(arr){
+    const matches = new Set();
+    // rows
+    for(let r=0;r<size;r++){
+      let run=[0];
+      for(let c=1;c<=size;c++){
+        const prevIdx=idx(r,c-1);
+        const curIdx=c<size?idx(r,c):-1;
+        if(c<size && arr[prevIdx]!=null && arr[prevIdx]===arr[curIdx]){
+          run.push(c);
+        }else{
+          if(run.length>=3){
+            for(const col of run) matches.add(idx(r,col));
+          }
+          run=[c];
+        }
+      }
+    }
+    // cols
+    for(let c=0;c<size;c++){
+      let run=[0];
+      for(let r=1;r<=size;r++){
+        const prevIdx=idx(r-1,c);
+        const curIdx=r<size?idx(r,c):-1;
+        if(r<size && arr[prevIdx]!=null && arr[prevIdx]===arr[curIdx]){
+          run.push(r);
+        }else{
+          if(run.length>=3){
+            for(const row of run) matches.add(idx(row,c));
+          }
+          run=[r];
+        }
+      }
+    }
+    return matches;
+  }
+
+  function applyGravity(){
+    for(let c=0;c<size;c++){
+      let writeRow=size-1;
+      for(let r=size-1;r>=0;r--){
+        const i=idx(r,c);
+        if(board[i]!=null){
+          board[idx(writeRow,c)]=board[i];
+          if(writeRow!==r) board[i]=null;
+          writeRow--;
+        }
+      }
+      for(let r=writeRow;r>=0;r--){
+        board[idx(r,c)]=randomType();
+      }
+    }
+  }
+
+  function refreshTiles(){
+    const tiles = gridEl.children;
+    for(let i=0;i<board.length;i++){
+      const t = tiles[i];
+      t.dataset.type = board[i];
+      t.classList.remove('matched');
+    }
+  }
+
+  function resolveMatches(){
+    const tiles = gridEl.children;
+    const matches = findMatches(board);
+    if(matches.size===0){
+      animating=false;
+      return;
+    }
+    matches.forEach(i=>{
+      tiles[i].classList.add('matched');
+      board[i]=null;
+    });
+    updateScore(matches.size*10);
+    setTimeout(()=>{
+      applyGravity();
+      refreshTiles();
+      setTimeout(()=>{
+        resolveMatches();
+      },160);
+    },420);
+  }
+
+  function deselect(){
+    if(selected==null) return;
+    const t = gridEl.querySelector('.tile.selected');
+    if(t) t.classList.remove('selected');
+    selected=null;
+  }
+
+  function attemptSwap(i1,i2){
+    if(animating) return;
+    if(!areAdjacent(i1,i2)){ deselect(); return; }
+
+    const tiles = gridEl.children;
+    animating=true;
+
+    [board[i1],board[i2]] = [board[i2],board[i1]];
+    tiles[i1].dataset.type=board[i1];
+    tiles[i2].dataset.type=board[i2];
+
+    updateMoves();
+
+    const matches = findMatches(board);
+    if(matches.size===0){
+      // revert if no match
+      setTimeout(()=>{
+        [board[i1],board[i2]] = [board[i2],board[i1]];
+        tiles[i1].dataset.type=board[i1];
+        tiles[i2].dataset.type=board[i2];
+        animating=false;
+      },160);
+    }else{
+      setTimeout(()=>resolveMatches(),80);
+    }
+    deselect();
+  }
+
+  function onTileSelect(index){
+    if(animating) return;
+    const tile = gridEl.children[index];
+    if(!selected){
+      selected=index;
+      tile.classList.add('selected');
+    }else if(selected===index){
+      deselect();
+    }else{
+      const prev=selected;
+      deselect();
+      attemptSwap(prev,index);
+    }
+  }
+
+  // Mouse & touch
+  let touchStartIndex=null;
+  function eventIndexFromTarget(t){
+    const el=t.closest('.tile');
+    return el?parseInt(el.dataset.index,10):null;
+  }
+
+  gridEl.addEventListener('mousedown',e=>{
+    const idx = eventIndexFromTarget(e.target);
+    if(idx==null) return;
+    onTileSelect(idx);
+  });
+
+  gridEl.addEventListener('touchstart',e=>{
+    const t=e.changedTouches[0];
+    const target=document.elementFromPoint(t.clientX,t.clientY);
+    const i=eventIndexFromTarget(target);
+    if(i==null) return;
+    e.preventDefault();
+    touchStartIndex=i;
+    onTileSelect(i);
+  },{passive:false});
+
+  gridEl.addEventListener('touchend',e=>{
+    const t=e.changedTouches[0];
+    const endTarget=document.elementFromPoint(t.clientX,t.clientY);
+    const endIdx=eventIndexFromTarget(endTarget);
+    if(endIdx==null || touchStartIndex==null) {touchStartIndex=null;return;}
+    if(endIdx!==touchStartIndex){
+      attemptSwap(touchStartIndex,endIdx);
+    }
+    touchStartIndex=null;
+  });
+
+  restartBtn.addEventListener('click',()=>{
+    animating=false;
+    selected=null;
+    score=0;moves=0;
+    scoreEl.textContent='0';
+    movesEl.textContent='0';
+    generateBoard();
+    renderBoard();
+  });
+
+  generateBoard();
+  renderBoard();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7f4f8ca5f8d/gpt.png b/data/artifacts/d7f4f8ca5f8d/gpt.png
new file mode 100644
index 0000000..32a78f2
Binary files /dev/null and b/data/artifacts/d7f4f8ca5f8d/gpt.png differ
diff --git a/data/artifacts/d7f4f8ca5f8d/grok.html b/data/artifacts/d7f4f8ca5f8d/grok.html
new file mode 100644
index 0000000..0e37795
--- /dev/null
+++ b/data/artifacts/d7f4f8ca5f8d/grok.html
@@ -0,0 +1,298 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
+<title>Luxe Match</title>
+<style>
+*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
+:root{
+--bg:#1a1816;--panel:#242120;--cream:#e8e0d4;--champagne:#c4a882;
+--rose:#a67c7c;--sage:#7a8a72;--slate:#6a7a8a;--taupe:#8a7a6a;
+--gold:#b8a078;--text:#d4cdc2;--muted:#8a8278;--shimmer:#f5efe6
+}
+html,body{height:100%;overflow:hidden;font-family:Georgia,"Times New Roman",serif;background:var(--bg);color:var(--text)}
+body{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100%}
+.wrap{display:flex;flex-direction:column;align-items:center;gap:14px;padding:16px;max-width:100%}
+h1{font-weight:400;font-size:1.35rem;letter-spacing:.28em;text-transform:uppercase;color:var(--gold);text-shadow:0 1px 0 #000}
+.bar{display:flex;gap:20px;align-items:center;font-size:.85rem;letter-spacing:.12em;color:var(--muted)}
+.bar span b{color:var(--cream);font-weight:400;font-size:1.05rem}
+button{background:transparent;border:1px solid var(--gold);color:var(--gold);padding:8px 20px;font-family:inherit;font-size:.75rem;letter-spacing:.2em;text-transform:uppercase;cursor:pointer;border-radius:2px;transition:background .25s,color .25s}
+button:hover{background:var(--gold);color:var(--bg)}
+.board-wrap{position:relative;padding:10px;background:var(--panel);border:1px solid #3a3530;border-radius:4px;box-shadow:0 12px 40px rgba(0,0,0,.45),inset 0 1px 0 #3a3530}
+.board{display:grid;grid-template-columns:repeat(6,1fr);gap:5px;width:min(78vw,420px);height:min(78vw,420px);touch-action:none}
+.tile{position:relative;border-radius:3px;cursor:pointer;overflow:hidden;transition:transform .15s,box-shadow .2s;border:1px solid rgba(0,0,0,.25)}
+.tile::after{content:"";position:absolute;inset:0;background:linear-gradient(135deg,rgba(255,255,255,.12) 0%,transparent 45%,rgba(0,0,0,.08) 100%);pointer-events:none}
+.tile.selected{transform:scale(.92);box-shadow:0 0 0 2px var(--gold),0 0 16px rgba(184,160,120,.5);z-index:2}
+.tile.swap-a,.tile.swap-b{transition:transform .28s ease}
+.tile.clearing{animation:shimmer .55s ease forwards;pointer-events:none;z-index:3}
+@keyframes shimmer{
+0%{filter:brightness(1);transform:scale(1);opacity:1}
+40%{filter:brightness(1.8);box-shadow:0 0 24px var(--shimmer);transform:scale(1.06)}
+100%{filter:brightness(2.2);transform:scale(.3);opacity:0}
+}
+.tile.drop{transition:transform .32s cubic-bezier(.2,.8,.3,1)}
+/* Pattern bases */
+.p0{background-color:#2c2824}
+.p1{background-color:#3a3028}
+.p2{background-color:#2a322c}
+.p3{background-color:#2a2e36}
+.p4{background-color:#362a2a}
+.p5{background-color:#322e28}
+/* Damask — ornate cross */
+.p0{background-image:
+radial-gradient(ellipse 30% 30% at 50% 50%,var(--champagne) 0%,transparent 70%),
+radial-gradient(ellipse 12% 40% at 50% 20%,var(--gold) 0%,transparent 70%),
+radial-gradient(ellipse 12% 40% at 50% 80%,var(--gold) 0%,transparent 70%),
+radial-gradient(ellipse 40% 12% at 20% 50%,var(--gold) 0%,transparent 70%),
+radial-gradient(ellipse 40% 12% at 80% 50%,var(--gold) 0%,transparent 70%),
+radial-gradient(circle at 50% 50%,transparent 28%,rgba(196,168,130,.25) 30%,transparent 32%)}
+/* Floral — soft blooms */
+.p1{background-image:
+radial-gradient(circle at 50% 50%,var(--rose) 0 8%,transparent 9%),
+radial-gradient(circle at 50% 28%,var(--rose) 0 6%,transparent 7%),
+radial-gradient(circle at 50% 72%,var(--rose) 0 6%,transparent 7%),
+radial-gradient(circle at 28% 50%,var(--rose) 0 6%,transparent 7%),
+radial-gradient(circle at 72% 50%,var(--rose) 0 6%,transparent 7%),
+radial-gradient(circle at 35% 35%,rgba(166,124,124,.5) 0 5%,transparent 6%),
+radial-gradient(circle at 65% 35%,rgba(166,124,124,.5) 0 5%,transparent 6%),
+radial-gradient(circle at 35% 65%,rgba(166,124,124,.5) 0 5%,transparent 6%),
+radial-gradient(circle at 65% 65%,rgba(166,124,124,.5) 0 5%,transparent 6%)}
+/* Geometric diamonds */
+.p2{background-image:
+linear-gradient(45deg,transparent 42%,var(--sage) 43%,var(--sage) 57%,transparent 58%),
+linear-gradient(-45deg,transparent 42%,var(--sage) 43%,var(--sage) 57%,transparent 58%),
+linear-gradient(45deg,transparent 46%,rgba(122,138,114,.4) 47%,rgba(122,138,114,.4) 53%,transparent 54%),
+linear-gradient(-45deg,transparent 46%,rgba(122,138,114,.4) 47%,rgba(122,138,114,.4) 53%,transparent 54%)}
+/* Art deco arcs */
+.p3{background-image:
+repeating-radial-gradient(ellipse at 50% 100%,transparent 0,transparent 8%,var(--slate) 8.5%,var(--slate) 10%,transparent 10.5%),
+repeating-radial-gradient(ellipse at 50% 0%,transparent 0,transparent 8%,rgba(106,122,138,.6) 8.5%,rgba(106,122,138,.6) 10%,transparent 10.5%),
+linear-gradient(180deg,transparent 48%,var(--slate) 49%,var(--slate) 51%,transparent 52%)}
+/* Herringbone / chevron */
+.p4{background-image:
+linear-gradient(135deg,var(--taupe) 25%,transparent 25.5%),
+linear-gradient(225deg,var(--taupe) 25%,transparent 25.5%),
+linear-gradient(315deg,var(--taupe) 25%,transparent 25.5%),
+linear-gradient(45deg,var(--taupe) 25%,transparent 25.5%);
+background-size:14px 14px;background-position:0 0,7px 0,7px -7px,0 7px}
+/* Fleur lattice */
+.p5{background-image:
+radial-gradient(circle at 0 0,var(--gold) 0 2px,transparent 2.5px),
+radial-gradient(circle at 100% 0,var(--gold) 0 2px,transparent 2.5px),
+radial-gradient(circle at 0 100%,var(--gold) 0 2px,transparent 2.5px),
+radial-gradient(circle at 100% 100%,var(--gold) 0 2px,transparent 2.5px),
+radial-gradient(circle at 50% 50%,var(--champagne) 0 3px,transparent 3.5px),
+linear-gradient(0deg,transparent 49%,rgba(184,160,120,.35) 50%,transparent 51%),
+linear-gradient(90deg,transparent 49%,rgba(184,160,120,.35) 50%,transparent 51%)}
+.hint{font-size:.7rem;letter-spacing:.1em;color:var(--muted);opacity:.7;margin-top:2px}
+</style>
+</head>
+<body>
+<div class="wrap">
+<h1>Luxe Match</h1>
+<div class="bar">
+<span>Score <b id="score">0</b></span>
+<span>Moves <b id="moves">0</b></span>
+<button id="restart" type="button">Restart</button>
+</div>
+<div class="board-wrap"><div class="board" id="board"></div></div>
+<p class="hint">Tap adjacent swatches to swap · match 3+</p>
+</div>
+<script>
+(function(){
+const N=6, TYPES=6;
+const boardEl=document.getElementById('board');
+const scoreEl=document.getElementById('score');
+const movesEl=document.getElementById('moves');
+let grid=[], selected=null, locked=false, score=0, moves=0;
+
+function rnd(){return Math.floor(Math.random()*TYPES)}
+function idx(r,c){return r*N+c}
+function rc(i){return [Math.floor(i/N),i%N]}
+
+function createTile(type,i){
+  const d=document.createElement('div');
+  d.className='tile p'+type;
+  d.dataset.i=i;
+  d.dataset.type=type;
+  return d;
+}
+
+function noMatchAt(r,c,type,g){
+  if(c>=2&&g[r][c-1]===type&&g[r][c-2]===type)return false;
+  if(r>=2&&g[r-1][c]===type&&g[r-2][c]===type)return false;
+  return true;
+}
+
+function fillInitial(){
+  grid=[];
+  for(let r=0;r<N;r++){
+    grid[r]=[];
+    for(let c=0;c<N;c++){
+      let t,guard=0;
+      do{t=rnd();guard++}while(!noMatchAt(r,c,t,grid)&&guard<40);
+      grid[r][c]=t;
+    }
+  }
+}
+
+function render(){
+  boardEl.innerHTML='';
+  for(let r=0;r<N;r++)for(let c=0;c<N;c++){
+    boardEl.appendChild(createTile(grid[r][c],idx(r,c)));
+  }
+}
+
+function tileAt(i){return boardEl.children[i]}
+
+function findMatches(){
+  const m=new Set();
+  for(let r=0;r<N;r++){
+    let run=1;
+    for(let c=1;c<=N;c++){
+      if(c<N&&grid[r][c]===grid[r][c-1])run++;
+      else{if(run>=3)for(let k=c-run;k<c;k++)m.add(idx(r,k));run=1}
+    }
+  }
+  for(let c=0;c<N;c++){
+    let run=1;
+    for(let r=1;r<=N;r++){
+      if(r<N&&grid[r][c]===grid[r-1][c])run++;
+      else{if(run>=3)for(let k=r-run;k<r;k++)m.add(idx(k,c));run=1}
+    }
+  }
+  return m;
+}
+
+function adjacent(a,b){
+  const [r1,c1]=rc(a),[r2,c2]=rc(b);
+  return Math.abs(r1-r2)+Math.abs(c1-c2)===1;
+}
+
+function swapData(a,b){
+  const [r1,c1]=rc(a),[r2,c2]=rc(b);
+  const t=grid[r1][c1];grid[r1][c1]=grid[r2][c2];grid[r2][c2]=t;
+}
+
+function syncTile(i){
+  const [r,c]=rc(i);
+  const el=tileAt(i);
+  el.className='tile p'+grid[r][c];
+  el.dataset.type=grid[r][c];
+  el.dataset.i=i;
+}
+
+async function animateSwap(a,b){
+  const ea=tileAt(a),eb=tileAt(b);
+  const ra=ea.getBoundingClientRect(),rb=eb.getBoundingClientRect();
+  const dx=rb.left-ra.left,dy=rb.top-ra.top;
+  ea.style.transform=`translate(${dx}px,${dy}px)`;
+  eb.style.transform=`translate(${-dx}px,${-dy}px)`;
+  ea.classList.add('swap-a');eb.classList.add('swap-b');
+  await wait(280);
+  ea.style.transform='';eb.style.transform='';
+  ea.classList.remove('swap-a');eb.classList.remove('swap-b');
+  syncTile(a);syncTile(b);
+}
+
+function wait(ms){return new Promise(r=>setTimeout(r,ms))}
+
+async function clearAndCascade(matches){
+  const arr=[...matches];
+  score+=arr.length*10+(arr.length>3?(arr.length-3)*15:0);
+  scoreEl.textContent=score;
+  arr.forEach(i=>tileAt(i).classList.add('clearing'));
+  await wait(550);
+  arr.forEach(i=>{const[r,c]=rc(i);grid[r][c]=-1});
+
+  for(let c=0;c<N;c++){
+    let write=N-1;
+    for(let r=N-1;r>=0;r--){
+      if(grid[r][c]!==-1){
+        if(r!==write){grid[write][c]=grid[r][c];grid[r][c]=-1}
+        write--;
+      }
+    }
+    for(let r=write;r>=0;r--)grid[r][c]=rnd();
+  }
+  render();
+  await wait(40);
+  const more=findMatches();
+  if(more.size)await clearAndCascade(more);
+}
+
+async function trySwap(a,b){
+  if(locked||!adjacent(a,b))return;
+  locked=true;
+  clearSelect();
+  swapData(a,b);
+  await animateSwap(a,b);
+  const matches=findMatches();
+  if(matches.size===0){
+    swapData(a,b);
+    await animateSwap(a,b);
+    locked=false;
+    return;
+  }
+  moves++;movesEl.textContent=moves;
+  await clearAndCascade(matches);
+  locked=false;
+}
+
+function clearSelect(){
+  if(selected!==null){const el=tileAt(selected);if(el)el.classList.remove('selected')}
+  selected=null;
+}
+
+function onPick(i){
+  if(locked)return;
+  if(selected===null){
+    selected=i;tileAt(i).classList.add('selected');
+  }else if(selected===i){
+    clearSelect();
+  }else if(adjacent(selected,i)){
+    trySwap(selected,i);
+  }else{
+    clearSelect();
+    selected=i;tileAt(i).classList.add('selected');
+  }
+}
+
+boardEl.addEventListener('click',e=>{
+  const t=e.target.closest('.tile');
+  if(!t)return;
+  onPick(+t.dataset.i);
+});
+
+let touchStart=null;
+boardEl.addEventListener('touchstart',e=>{
+  const t=e.target.closest('.tile');
+  if(!t)return;
+  touchStart=+t.dataset.i;
+},{passive:true});
+boardEl.addEventListener('touchend',e=>{
+  if(touchStart===null)return;
+  const touch=e.changedTouches[0];
+  const el=document.elementFromPoint(touch.clientX,touch.clientY);
+  const t=el&&el.closest?el.closest('.tile'):null;
+  if(t){
+    const end=+t.dataset.i;
+    if(end===touchStart)onPick(end);
+    else if(adjacent(touchStart,end)){clearSelect();trySwap(touchStart,end)}
+    else onPick(end);
+  }
+  touchStart=null;
+},{passive:true});
+
+function restart(){
+  locked=false;selected=null;score=0;moves=0;
+  scoreEl.textContent='0';movesEl.textContent='0';
+  fillInitial();render();
+}
+document.getElementById('restart').addEventListener('click',restart);
+restart();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7f4f8ca5f8d/grok.png b/data/artifacts/d7f4f8ca5f8d/grok.png
new file mode 100644
index 0000000..4dc5dec
Binary files /dev/null and b/data/artifacts/d7f4f8ca5f8d/grok.png differ
diff --git a/data/artifacts/d7f4f8ca5f8d/hermes3-8b.html b/data/artifacts/d7f4f8ca5f8d/hermes3-8b.html
new file mode 100644
index 0000000..7aee35b
--- /dev/null
+++ b/data/artifacts/d7f4f8ca5f8d/hermes3-8b.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Luxury Tile Puzzle</title>
+    <style>
+        * {
+            margin: 0;
+            padding: 0;
+            box-sizing: border-box;
+        }
+        
+        body {
+            background-color: #f5f5f5;
+            font-family: Arial, sans-serif;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            height: 100vh;
+        }
+        
+        .container {
+            text-align: center;
+        }
+        
+        h1 {
+            color: #8b0000;
+            margin-bottom: 20px;
+        }
+        
+        canvas {
+            border: 2px solid #8b0000;
+            display: inline-block;
+            cursor: pointer;
+        }
+        
+        .info {
+            margin-top: 10px;
+        }
+        
+        .score {
+            color: #8b0000;
+            font-weight: bold;
+        }
+        
+        button {
+            background-color: #8b0000;
+            color: white;
+            border: none;
+            padding: 5px 15px;
+            margin-right: 10px;
+            cursor: pointer;
+            outline: none;
+        }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <h1>Luxury Tile Puzzle</h1>
+        <canvas id="gameCanvas" width="300" height="300"></canvas>
+        <div class="info">
+            <span class="score">Score: </span><span id="scoreDisplay">0</span>
+        </div>
+        <button id="restartButton">Restart</button>
+    </div>
+    
+    <script>
+        const canvas = document.getElementById('gameCanvas');
+        const ctx = canvas.getContext('2d');
+
+        let tiles = generateTiles();
+        let gameBoard = createGameBoard(tiles);
+        let score = 0;
+
+        drawCanvas(gameBoard, ctx);
+
+        function generateTiles() {
+            // Generate luxury wallpaper swatches
+            return [];
+        }
+
+        function createGameBoard(tiles) {
+            // Create the initial 6x6 game board 
+            return [];
+        }
+        
+        function drawCanvas(board, context) {
+            // Draw the current state of the game board
+        }
+
+        canvas.addEventListener('click', (event) => {
+            // Handle mouse click events to move tiles around
+        });
+
+        document.getElementById('restartButton').addEventListener('click', () => {
+            // Restart the game
+        });
+
+        function findMatches() {
+            // Find and remove matching rows
+            return score;
+        }
+
+        setInterval(() => {
+            // Update game state periodically (e.g., for matches found)
+        }, 1000);
+    </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7f4f8ca5f8d/hermes3-8b.png b/data/artifacts/d7f4f8ca5f8d/hermes3-8b.png
new file mode 100644
index 0000000..5724d72
Binary files /dev/null and b/data/artifacts/d7f4f8ca5f8d/hermes3-8b.png differ
diff --git a/data/artifacts/d7f4f8ca5f8d/kimi.html b/data/artifacts/d7f4f8ca5f8d/kimi.html
new file mode 100644
index 0000000..2b196f4
--- /dev/null
+++ b/data/artifacts/d7f4f8ca5f8d/kimi.html
@@ -0,0 +1,538 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Luxe Wallpaper Match</title>
+<style>
+* {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+  user-select: none;
+  -webkit-user-select: none;
+}
+
+body {
+  font-family: 'Georgia', 'Times New Roman', serif;
+  background: linear-gradient(135deg, #f5f2ed 0%, #e8e4dc 100%);
+  min-height: 100vh;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: #4a4a4a;
+  overflow: hidden;
+  touch-action: none;
+}
+
+.game-container {
+  background: rgba(255, 255, 255, 0.6);
+  backdrop-filter: blur(10px);
+  border-radius: 16px;
+  padding: 24px;
+  box-shadow: 
+    0 10px 40px rgba(0,0,0,0.08),
+    0 2px 8px rgba(0,0,0,0.04),
+    inset 0 0 0 1px rgba(255,255,255,0.8);
+  max-width: 500px;
+  width: 90vw;
+}
+
+header {
+  text-align: center;
+  margin-bottom: 20px;
+}
+
+h1 {
+  font-size: 24px;
+  font-weight: 400;
+  letter-spacing: 3px;
+  color: #5c4a3a;
+  margin-bottom: 16px;
+  text-transform: uppercase;
+}
+
+.stats {
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  gap: 20px;
+}
+
+.stat {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 4px;
+}
+
+.stat span:first-child {
+  font-size: 11px;
+  text-transform: uppercase;
+  letter-spacing: 2px;
+  color: #8a7a6a;
+}
+
+.stat span:last-child {
+  font-size: 20px;
+  color: #5c4a3a;
+  font-weight: 600;
+}
+
+button {
+  background: #5c4a3a;
+  color: #f5f2ed;
+  border: none;
+  padding: 8px 20px;
+  border-radius: 20px;
+  font-family: inherit;
+  font-size: 11px;
+  letter-spacing: 1px;
+  text-transform: uppercase;
+  cursor: pointer;
+  transition: all 0.3s ease;
+  box-shadow: 0 2px 8px rgba(92,74,58,0.2);
+}
+
+button:hover {
+  background: #4a3a2a;
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(92,74,58,0.3);
+}
+
+.grid {
+  display: grid;
+  grid-template-columns: repeat(6, 1fr);
+  grid-template-rows: repeat(6, 1fr);
+  gap: 8px;
+  aspect-ratio: 1;
+  background: rgba(255,255,255,0.4);
+  padding: 12px;
+  border-radius: 12px;
+  box-shadow: inset 0 2px 8px rgba(0,0,0,0.05);
+}
+
+.tile {
+  position: relative;
+  border-radius: 6px;
+  cursor: pointer;
+  transition: transform 0.2s ease, box-shadow 0.2s ease;
+  box-shadow: 
+    inset 0 0 12px rgba(0,0,0,0.08),
+    0 2px 4px rgba(0,0,0,0.1);
+  overflow: hidden;
+}
+
+.tile::after {
+  content: '';
+  position: absolute;
+  inset: 0;
+  background: linear-gradient(135deg, rgba(255,255,255,0.4) 0%, transparent 50%, rgba(0,0,0,0.05) 100%);
+  pointer-events: none;
+}
+
+.tile:hover {
+  transform: translateY(-2px);
+  box-shadow: 
+    inset 0 0 12px rgba(0,0,0,0.08),
+    0 4px 8px rgba(0,0,0,0.15);
+}
+
+.tile.selected {
+  box-shadow: 
+    inset 0 0 12px rgba(0,0,0,0.08),
+    0 0 0 3px #d4af37,
+    0 4px 12px rgba(0,0,0,0.2);
+  z-index: 10;
+  transform: scale(1.05);
+}
+
+/* Pattern 0: Damask Gold */
+.pattern-0 {
+  background-color: #f4e8d0;
+  background-image: 
+    radial-gradient(circle at 50% 50%, rgba(184, 134, 11, 0.25) 0%, transparent 50%),
+    radial-gradient(circle at 0% 0%, rgba(184, 134, 11, 0.2) 0%, transparent 40%),
+    radial-gradient(circle at 100% 0%, rgba(184, 134, 11, 0.2) 0%, transparent 40%),
+    radial-gradient(circle at 0% 100%, rgba(184, 134, 11, 0.2) 0%, transparent 40%),
+    radial-gradient(circle at 100% 100%, rgba(184, 134, 11, 0.2) 0%, transparent 40%);
+  border: 1px solid #e6d5b8;
+}
+
+/* Pattern 1: Floral Rose */
+.pattern-1 {
+  background-color: #e8d5d5;
+  background-image:
+    radial-gradient(circle at 30% 30%, rgba(188, 143, 143, 0.7) 0%, transparent 35%),
+    radial-gradient(circle at 70% 30%, rgba(188, 143, 143, 0.7) 0%, transparent 35%),
+    radial-gradient(circle at 50% 70%, rgba(180, 130, 130, 0.6) 0%, transparent 45%),
+    radial-gradient(circle at 50% 50%, rgba(160, 110, 110, 0.3) 0%, transparent 70%);
+  border: 1px solid #d4b8b8;
+}
+
+/* Pattern 2: Geometric Navy */
+.pattern-2 {
+  background-color: #3d4550;
+  background-image:
+    linear-gradient(45deg, transparent 45%, rgba(255,255,255,0.15) 45%, rgba(255,255,255,0.15) 55%, transparent 55%),
+    linear-gradient(-45deg, transparent 45%, rgba(255,255,255,0.15) 45%, rgba(255,255,255,0.15) 55%, transparent 55%);
+  background-size: 14px 14px;
+  border: 1px solid #2d3748;
+}
+
+/* Pattern 3: Lattice Sage */
+.pattern-3 {
+  background-color: #c5d5c0;
+  background-image:
+    linear-gradient(90deg, transparent 46%, rgba(255,255,255,0.5) 46%, rgba(255,255,255,0.5) 54%, transparent 54%),
+    linear-gradient(0deg, transparent 46%, rgba(255,255,255,0.5) 46%, rgba(255,255,255,0.5) 54%, transparent 54%),
+    linear-gradient(90deg, transparent 20%, rgba(154, 170, 144, 0.3) 20%, rgba(154, 170, 144, 0.3) 25%, transparent 25%),
+    linear-gradient(0deg, transparent 20%, rgba(154, 170, 144, 0.3) 20%, rgba(154, 170, 144, 0.3) 25%, transparent 25%);
+  border: 1px solid #b0c4a8;
+}
+
+/* Pattern 4: Pinstripe Burgundy */
+.pattern-4 {
+  background-color: #722f37;
+  background-image:
+    repeating-linear-gradient(90deg, transparent, transparent 6px, rgba(255,255,255,0.12) 6px, rgba(255,255,255,0.12) 12px),
+    radial-gradient(ellipse at 50% 50%, rgba(255,255,255,0.1) 0%, transparent 70%);
+  border: 1px solid #5c2028;
+}
+
+/* Pattern 5: Medallion Teal */
+.pattern-5 {
+  background-color: #4a7c7e;
+  background-image:
+    radial-gradient(circle at 50% 50%, rgba(255,255,255,0.25) 0%, transparent 25%),
+    radial-gradient(circle at 50% 50%, rgba(255,255,255,0.15) 30%, transparent 60%),
+    conic-gradient(from 0deg, transparent 0deg, rgba(255,255,255,0.15) 30deg, transparent 60deg, transparent 120deg, rgba(255,255,255,0.15) 150deg, transparent 180deg, transparent 240deg, rgba(255,255,255,0.15) 270deg, transparent 300deg, transparent 360deg);
+  border: 1px solid #3a6364;
+}
+
+@keyframes shimmer {
+  0% {
+    filter: brightness(1) opacity(1);
+    transform: scale(1) rotate(0deg);
+  }
+  25% {
+    filter: brightness(2) opacity(0.9);
+    background-color: #ffd700;
+    transform: scale(1.1) rotate(2deg);
+  }
+  50% {
+    filter: brightness(2.5) opacity(0.8);
+    background-color: #ffed4e;
+    transform: scale(1.2) rotate(-2deg);
+  }
+  75% {
+    filter: brightness(2) opacity(0.9);
+    background-color: #ffd700;
+    transform: scale(1.1) rotate(1deg);
+  }
+  100% {
+    filter: brightness(1) opacity(0);
+    transform: scale(0) rotate(0deg);
+  }
+}
+
+.clearing {
+  animation: shimmer 0.6s ease-in-out forwards;
+  z-index: 20;
+  pointer-events: none;
+}
+
+@media (max-width: 500px) {
+  .game-container {
+    padding: 16px;
+  }
+  h1 {
+    font-size: 20px;
+  }
+  .grid {
+    gap: 6px;
+    padding: 8px;
+  }
+}
+</style>
+</head>
+<body>
+<div class="game-container">
+  <header>
+    <h1>Luxe Match</h1>
+    <div class="stats">
+      <div class="stat">
+        <span>Score</span>
+        <span id="score">0</span>
+      </div>
+      <button onclick="game.restart()">Restart</button>
+      <div class="stat">
+        <span>Moves</span>
+        <span id="moves">0</span>
+      </div>
+    </div>
+  </header>
+  <div class="grid" id="grid"></div>
+</div>
+
+<script>
+class Game {
+  constructor() {
+    this.size = 6;
+    this.types = 6;
+    this.grid = [];
+    this.score = 0;
+    this.moves = 0;
+    this.selected = null;
+    this.busy = false;
+    this.touchStartX = 0;
+    this.touchStartY = 0;
+    this.init();
+    this.setupTouch();
+  }
+
+  init() {
+    this.grid = [];
+    for (let r = 0; r < this.size; r++) {
+      this.grid[r] = [];
+      for (let c = 0; c < this.size; c++) {
+        this.grid[r][c] = this.randomType();
+      }
+    }
+    
+    while (this.findMatches().length > 0) {
+      const matches = this.findMatches();
+      matches.forEach(m => {
+        this.grid[m.r][m.c] = this.randomType();
+      });
+    }
+    
+    this.render();
+    this.updateStats();
+  }
+
+  randomType() {
+    return Math.floor(Math.random() * this.types);
+  }
+
+  findMatches() {
+    const matches = [];
+    const seen = new Set();
+
+    for (let r = 0; r < this.size; r++) {
+      for (let c = 0; c < this.size - 2; c++) {
+        const type = this.grid[r][c];
+        if (type === -1) continue;
+        let count = 1;
+        while (c + count < this.size && this.grid[r][c + count] === type) {
+          count++;
+        }
+        if (count >= 3) {
+          for (let i = 0; i < count; i++) {
+            const key = `${r},${c + i}`;
+            if (!seen.has(key)) {
+              seen.add(key);
+              matches.push({r, c: c + i});
+            }
+          }
+        }
+        c += count - 1;
+      }
+    }
+
+    for (let c = 0; c < this.size; c++) {
+      for (let r = 0; r < this.size - 2; r++) {
+        const type = this.grid[r][c];
+        if (type === -1) continue;
+        let count = 1;
+        while (r + count < this.size && this.grid[r + count][c] === type) {
+          count++;
+        }
+        if (count >= 3) {
+          for (let i = 0; i < count; i++) {
+            const key = `${r + i},${c}`;
+            if (!seen.has(key)) {
+              seen.add(key);
+              matches.push({r: r + i, c});
+            }
+          }
+        }
+        r += count - 1;
+      }
+    }
+
+    return matches;
+  }
+
+  async handleMatches() {
+    if (this.busy) return;
+    const matches = this.findMatches();
+    if (matches.length === 0) {
+      this.busy = false;
+      return;
+    }
+
+    this.busy = true;
+    this.score += matches.length * 10;
+    this.updateStats();
+
+    const cells = document.querySelectorAll('.tile');
+    matches.forEach(m => {
+      const index = m.r * this.size + m.c;
+      if (cells[index]) {
+        cells[index].classList.add('clearing');
+      }
+    });
+
+    await new Promise(resolve => setTimeout(resolve, 600));
+
+    matches.forEach(m => {
+      this.grid[m.r][m.c] = -1;
+    });
+
+    this.applyGravity();
+    this.fillEmpty();
+    this.render();
+
+    setTimeout(() => this.handleMatches(), 100);
+  }
+
+  applyGravity() {
+    for (let c = 0; c < this.size; c++) {
+      let writeRow = this.size - 1;
+      for (let r = this.size - 1; r >= 0; r--) {
+        if (this.grid[r][c] !== -1) {
+          this.grid[writeRow][c] = this.grid[r][c];
+          if (writeRow !== r) {
+            this.grid[r][c] = -1;
+          }
+          writeRow--;
+        }
+      }
+    }
+  }
+
+  fillEmpty() {
+    for (let r = 0; r < this.size; r++) {
+      for (let c = 0; c < this.size; c++) {
+        if (this.grid[r][c] === -1) {
+          this.grid[r][c] = this.randomType();
+        }
+      }
+    }
+  }
+
+  swap(r1, c1, r2, c2) {
+    if (this.busy) return;
+    
+    const temp = this.grid[r1][c1];
+    this.grid[r1][c1] = this.grid[r2][c2];
+    this.grid[r2][c2] = temp;
+
+    this.moves++;
+    this.updateStats();
+    this.render();
+
+    const hasMatches = this.findMatches().length > 0;
+    
+    if (!hasMatches) {
+      setTimeout(() => {
+        const temp = this.grid[r1][c1];
+        this.grid[r1][c1] = this.grid[r2][c2];
+        this.grid[r2][c2] = temp;
+        this.render();
+        this.busy = false;
+      }, 300);
+    } else {
+      this.handleMatches();
+    }
+  }
+
+  handleClick(r, c) {
+    if (this.busy) return;
+
+    if (!this.selected) {
+      this.selected = {r, c};
+      this.render();
+    } else {
+      const {r: r1, c: c1} = this.selected;
+      const dist = Math.abs(r - r1) + Math.abs(c - c1);
+      
+      if (dist === 1) {
+        this.selected = null;
+        this.swap(r1, c1, r, c);
+      } else if (dist === 0) {
+        this.selected = null;
+        this.render();
+      } else {
+        this.selected = {r, c};
+        this.render();
+      }
+    }
+  }
+
+  render() {
+    const grid = document.getElementById('grid');
+    grid.innerHTML = '';
+    
+    for (let r = 0; r < this.size; r++) {
+      for (let c = 0; c < this.size; c++) {
+        const tile = document.createElement('div');
+        tile.className = `tile pattern-${this.grid[r][c]}`;
+        tile.dataset.r = r;
+        tile.dataset.c = c;
+        
+        if (this.selected && this.selected.r === r && this.selected.c === c) {
+          tile.classList.add('selected');
+        }
+        
+        tile.addEventListener('click', () => this.handleClick(r, c));
+        grid.appendChild(tile);
+      }
+    }
+  }
+
+  setupTouch() {
+    const grid = document.getElementById('grid');
+    
+    grid.addEventListener('touchstart', (e) => {
+      this.touchStartX = e.touches[0].clientX;
+      this.touchStartY = e.touches[0].clientY;
+    }, {passive: false});
+    
+    grid.addEventListener('touchend', (e) => {
+      e.preventDefault();
+      const touchEndX = e.changedTouches[0].clientX;
+      const touchEndY = e.changedTouches[0].clientY;
+      const dx = touchEndX - this.touchStartX;
+      const dy = touchEndY - this.touchStartY;
+      
+      if (Math.abs(dx) < 10 && Math.abs(dy) < 10) {
+        const element = document.elementFromPoint(touchEndX, touchEndY);
+        if (element && element.classList.contains('tile')) {
+          const r = parseInt(element.dataset.r);
+          const c = parseInt(element.dataset.c);
+          this.handleClick(r, c);
+        }
+      }
+    }, {passive: false});
+  }
+
+  updateStats() {
+    document.getElementById('score').textContent = this.score;
+    document.getElementById('moves').textContent = this.moves;
+  }
+
+  restart() {
+    this.score = 0;
+    this.moves = 0;
+    this.selected = null;
+    this.busy = false;
+    this.init();
+  }
+}
+
+const game = new Game();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7f4f8ca5f8d/kimi.png b/data/artifacts/d7f4f8ca5f8d/kimi.png
new file mode 100644
index 0000000..67d3e10
Binary files /dev/null and b/data/artifacts/d7f4f8ca5f8d/kimi.png differ
diff --git a/data/artifacts/d7f4f8ca5f8d/qwen3-14b.html b/data/artifacts/d7f4f8ca5f8d/qwen3-14b.html
new file mode 100644
index 0000000..d51079f
--- /dev/null
+++ b/data/artifacts/d7f4f8ca5f8d/qwen3-14b.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <title>Luxury Tile Match</title>
+  <style>
+    * {
+      box-sizing: border-box;
+      margin: 0;
+      padding: 0;
+    }
+    body {
+      background: #f8f4f0;
+      font-family: 'Georgia', serif;
+      color: #3a2d28;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      height: 100vh;
+      overflow: hidden;
+    }
+    h1 {
+      margin-bottom: 10px;
+    }
+    #game {
+      display: grid;
+      grid-template-columns: repeat(6, 80px);
+      grid-template-rows: repeat(6, 80px);
+      gap: 4px;
+      margin-bottom: 10px;
+    }
+    .tile {
+      background-size: 200% 200%;
+      background-position: 0% 0%;
+      width: 80px;
+      height: 80px;
+      cursor: pointer;
+      user-select: none;
+      transition: transform 0.2s, opacity 0.3s;
+    }
+    .tile[data-type="damask"] {
+      background-image: linear-gradient(45deg, #e6d8d1 25%, #d6cfc1 25%, #d6cfc1 50%, #e6d8d1 50%, #e6d8d1 75%, #d6cfc1 75%, #d6cfc1 100%);
+    }
+    .tile[data-type="floral"] {
+      background-image: radial-gradient(circle at 30% 30%, #f2e6e2 0%, #e0d4d0 100%);
+      background-image: radial-gradient(circle at 70% 70%, #f8f4f0 0%, #e6d8d1 100%), linear-gradient(135deg, #e0d4d0 25%, #f2e6e2 75%);
+    }
+    .tile[data-type="geometric"] {
+      background-image: repeating-linear-gradient(45deg, #e6d8d1 0%, #d6cfc1 25%, #e6d8d1 50%);
+    }
+    .tile.selected {
+      transform: scale(1.1);
+      z-index: 1;
+    }
+    .tile.matching {
+      opacity: 0.5;
+    }
+    #info {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      gap: 5px;
+    }
+    #score, #moves {
+      font-size: 18px;
+      font-weight: bold;
+    }
+    button {
+      padding: 10px 20px;
+      font-size: 16px;
+      background-color: #d6cfc1;
+      border: none;
+      border-radius: 8px;
+      cursor: pointer;
+      transition: background-color 0.2s;
+    }
+    button:hover {
+      background-color: #e6d8d1;
+    }
+  </style>
+</head>
+<body>
+  <h1>Luxury Tile Match</h1>
+  <div id="game"></div>
+  <div id="info">
+    <div id="score">Score: 0</div>
+    <div id="moves">Moves: 0</div>
+    <button onclick="restartGame()">Restart</button>
+  </div>
+  <script>
+    const game = document.getElementById('game');
+    const scoreEl = document.getElementById('score');
+    const movesEl = document.getElementById('moves');
+    let score = 0;
+    let moves = 0;
+    let selected = null;
+    let tiles = [];
+
+    const tileTypes = ['damask', 'floral', 'geometric'];
+
+    function createTile(type) {
+      const tile = document.createElement('div');
+      tile.className = 'tile';
+      tile.dataset.type = type;
+      return tile;
+    }
+
+    function initGame() {
+      game.innerHTML = '';
+      tiles = [];
+      score = 0;
+      moves = 0;
+      scoreEl.textContent = 'Score: 0';
+      movesEl.textContent = 'Moves: 0';
+
+      for (let i = 0; i < 36; i++) {
+        const type = tileTypes[Math.floor(Math.random() * tileTypes.length)];
+        const tile = createTile(type);
+        game.appendChild(tile);
+        tiles.push(tile);
+      }
+
+      checkMatches();
+    }
+
+    function getTilePos(el) {
+      const rect = el.getBoundingClientRect();
+      const x = Math.floor((rect.left + window.scrollX) / 84);
+      const y = Math.floor((rect.top + window.scrollY) / 84);
+      return { x, y };
+    }
+
+    function findAdjacentTiles(tile) {
+      const { x, y } = getTilePos(tile);
+      const neighbors = [];
+      if (x > 0) neighbors.push(tiles[x - 1 + y * 6]);
+      if (x < 5) neighbors.push(tiles[x + 1 + y * 6]);
+      if (y > 0) neighbors.push(tiles[x + (y - 1) * 6]);
+      if (y < 5) neighbors.push(tiles[x + (y + 1) * 6]);
+      return neighbors;
+    }
+
+    function checkMatches() {
+      const matches = {};
+      tiles.forEach((tile, index) => {
+        const type = tile.dataset.type;
+        const { x, y } = getTilePos(tile);
+        const key = `${x},${y}`;
+        if (!matches[key]) matches[key] = [];
+        matches[key].push(index);
+      });
+
+      Object.values(matches).forEach(group => {
+        if (group.length >= 3) {
+          group.forEach(i => {
+            tiles[i].classList.add('matching');
+          });
+        }
+      });
+
+      setTimeout(() => {
+        Object.values(matches).forEach(group => {
+          if (group.length >= 3) {
+            group.forEach(i => {
+              tiles[i].remove();
+            });
+          }
+        });
+        score += group.length * 10;
+        scoreEl.textContent = 'Score: ' + score;
+        initGame();
+      }, 500);
+    }
+
+    function restartGame() {
+      initGame();
+    }
+
+    game.addEventListener('click', e => {
+      const tile = e.target;
+      if (!tile.classList.contains('tile')) return;
+
+      if (selected === null) {
+        selected = tile;
+        tile.classList.add('selected');
+      } else if (selected === tile) {
+        selected.classList.remove('selected');
+        selected = null;
+      } else {
+        const neighbors = findAdjacentTiles(selected);
+        if (neighbors.includes(tile)) {
+          moves++;
+          movesEl.textContent = 'Moves: ' + moves;
+          selected.classList.remove('selected');
+          selected = null;
+          checkMatches();
+        } else {
+          selected.classList.remove('selected');
+          selected = tile;
+          tile.classList.add('selected');
+        }
+      }
+    });
+
+    initGame();
+  </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7f4f8ca5f8d/qwen3-14b.png b/data/artifacts/d7f4f8ca5f8d/qwen3-14b.png
new file mode 100644
index 0000000..bfb08aa
Binary files /dev/null and b/data/artifacts/d7f4f8ca5f8d/qwen3-14b.png differ
diff --git a/data/challenges.json b/data/challenges.json
index 184b10f..efc96b3 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -14428,13 +14428,15 @@
       },
       {
         "model": "hf-qwen-coder-32b",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 66,
+        "cost": 0,
         "started_at": "2026-07-25T07:41:41.794Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.077Z"
+        "finished_at": "2026-07-25T07:42:48.069Z",
+        "queued_at": "2026-07-25T07:39:01.077Z",
+        "bytes": 4989,
+        "thumb": true
       },
       {
         "model": "claude-code",
@@ -14484,7 +14486,8 @@
         "bytes": 25399,
         "thumb": true
       }
-    ]
+    ],
+    "judging": true
   },
   {
     "id": "b72f0e9e751b",
@@ -14497,33 +14500,39 @@
     "runs": [
       {
         "model": "qwen3-14b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.151Z"
+        "seconds": 43,
+        "cost": 0,
+        "started_at": "2026-07-25T07:42:48.072Z",
+        "finished_at": "2026-07-25T07:43:30.739Z",
+        "queued_at": "2026-07-25T07:39:01.151Z",
+        "bytes": 6764,
+        "thumb": true
       },
       {
         "model": "gemma3-12b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.153Z"
+        "seconds": 42,
+        "cost": 0,
+        "started_at": "2026-07-25T07:43:30.747Z",
+        "finished_at": "2026-07-25T07:44:12.710Z",
+        "queued_at": "2026-07-25T07:39:01.153Z",
+        "bytes": 6093,
+        "thumb": true
       },
       {
         "model": "hermes3-8b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.155Z"
+        "seconds": 18,
+        "cost": 0,
+        "started_at": "2026-07-25T07:44:12.719Z",
+        "finished_at": "2026-07-25T07:44:30.975Z",
+        "queued_at": "2026-07-25T07:39:01.155Z",
+        "bytes": 4718,
+        "thumb": true
       },
       {
         "model": "qwen25-7b",
@@ -14539,43 +14548,51 @@
       },
       {
         "model": "hf-qwen-coder-32b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.160Z"
+        "seconds": 54,
+        "cost": 0,
+        "started_at": "2026-07-25T07:44:30.980Z",
+        "finished_at": "2026-07-25T07:45:25.158Z",
+        "queued_at": "2026-07-25T07:39:01.160Z",
+        "bytes": 4751,
+        "thumb": true
       },
       {
         "model": "claude-code",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 82,
+        "cost": 0,
         "started_at": "2026-07-25T07:41:05.454Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.163Z"
+        "finished_at": "2026-07-25T07:42:27.546Z",
+        "queued_at": "2026-07-25T07:39:01.163Z",
+        "bytes": 15442,
+        "thumb": true
       },
       {
         "model": "kimi",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 116,
+        "cost": 0.0182,
         "started_at": "2026-07-25T07:40:59.590Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.166Z"
+        "finished_at": "2026-07-25T07:42:55.117Z",
+        "queued_at": "2026-07-25T07:39:01.166Z",
+        "bytes": 18220,
+        "thumb": true
       },
       {
         "model": "gpt",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 99,
+        "cost": 0.156,
         "started_at": "2026-07-25T07:40:56.989Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.168Z"
+        "finished_at": "2026-07-25T07:42:36.451Z",
+        "queued_at": "2026-07-25T07:39:01.168Z",
+        "bytes": 37564,
+        "thumb": true
       },
       {
         "model": "grok",
@@ -14589,7 +14606,8 @@
         "bytes": 18401,
         "thumb": true
       }
-    ]
+    ],
+    "judging": true
   },
   {
     "id": "d7f4f8ca5f8d",
@@ -14602,33 +14620,39 @@
     "runs": [
       {
         "model": "qwen3-14b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.227Z"
+        "seconds": 38,
+        "cost": 0,
+        "started_at": "2026-07-25T07:45:25.166Z",
+        "finished_at": "2026-07-25T07:46:02.946Z",
+        "queued_at": "2026-07-25T07:39:01.227Z",
+        "bytes": 5563,
+        "thumb": true
       },
       {
         "model": "gemma3-12b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.229Z"
+        "seconds": 67,
+        "cost": 0,
+        "started_at": "2026-07-25T07:46:02.951Z",
+        "finished_at": "2026-07-25T07:47:09.777Z",
+        "queued_at": "2026-07-25T07:39:01.229Z",
+        "bytes": 9937,
+        "thumb": true
       },
       {
         "model": "hermes3-8b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.232Z"
+        "seconds": 11,
+        "cost": 0,
+        "started_at": "2026-07-25T07:47:09.782Z",
+        "finished_at": "2026-07-25T07:47:21.017Z",
+        "queued_at": "2026-07-25T07:39:01.232Z",
+        "bytes": 2748,
+        "thumb": true
       },
       {
         "model": "qwen25-7b",
@@ -14644,53 +14668,61 @@
       },
       {
         "model": "hf-qwen-coder-32b",
-        "status": "queued",
+        "status": "running",
         "error": null,
         "seconds": null,
         "cost": null,
-        "started_at": null,
+        "started_at": "2026-07-25T07:47:21.024Z",
         "finished_at": null,
         "queued_at": "2026-07-25T07:39:01.237Z"
       },
       {
         "model": "claude-code",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.239Z"
+        "seconds": 204,
+        "cost": 0,
+        "started_at": "2026-07-25T07:42:27.550Z",
+        "finished_at": "2026-07-25T07:45:51.943Z",
+        "queued_at": "2026-07-25T07:39:01.239Z",
+        "bytes": 15116,
+        "thumb": true
       },
       {
         "model": "kimi",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.241Z"
+        "seconds": 181,
+        "cost": 0.028,
+        "started_at": "2026-07-25T07:42:55.123Z",
+        "finished_at": "2026-07-25T07:45:55.841Z",
+        "queued_at": "2026-07-25T07:39:01.241Z",
+        "bytes": 13289,
+        "thumb": true
       },
       {
         "model": "gpt",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.244Z"
+        "seconds": 60,
+        "cost": 0.0723,
+        "started_at": "2026-07-25T07:42:36.461Z",
+        "finished_at": "2026-07-25T07:43:36.080Z",
+        "queued_at": "2026-07-25T07:39:01.244Z",
+        "bytes": 16356,
+        "thumb": true
       },
       {
         "model": "grok",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 60,
+        "cost": 0.0641,
         "started_at": "2026-07-25T07:41:46.420Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.246Z"
+        "finished_at": "2026-07-25T07:42:46.921Z",
+        "queued_at": "2026-07-25T07:39:01.246Z",
+        "bytes": 11117,
+        "thumb": true
       }
     ]
   },
@@ -14757,43 +14789,49 @@
       },
       {
         "model": "claude-code",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.315Z"
+        "seconds": 98,
+        "cost": 0,
+        "started_at": "2026-07-25T07:45:51.946Z",
+        "finished_at": "2026-07-25T07:47:29.655Z",
+        "queued_at": "2026-07-25T07:39:01.315Z",
+        "bytes": 17961,
+        "thumb": true
       },
       {
         "model": "kimi",
-        "status": "queued",
+        "status": "running",
         "error": null,
         "seconds": null,
         "cost": null,
-        "started_at": null,
+        "started_at": "2026-07-25T07:45:55.845Z",
         "finished_at": null,
         "queued_at": "2026-07-25T07:39:01.318Z"
       },
       {
         "model": "gpt",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.320Z"
+        "seconds": 121,
+        "cost": 0.1515,
+        "started_at": "2026-07-25T07:43:36.087Z",
+        "finished_at": "2026-07-25T07:45:36.644Z",
+        "queued_at": "2026-07-25T07:39:01.320Z",
+        "bytes": 34064,
+        "thumb": true
       },
       {
         "model": "grok",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T07:39:01.322Z"
+        "seconds": 102,
+        "cost": 0.1137,
+        "started_at": "2026-07-25T07:42:46.938Z",
+        "finished_at": "2026-07-25T07:44:29.131Z",
+        "queued_at": "2026-07-25T07:39:01.322Z",
+        "bytes": 20418,
+        "thumb": true
       }
     ]
   }
diff --git a/data/costlog.jsonl b/data/costlog.jsonl
index 96163d1..377c2a2 100644
--- a/data/costlog.jsonl
+++ b/data/costlog.jsonl
@@ -200,3 +200,10 @@
 {"ts":"2026-07-25T07:40:56.981Z","provider":"openai","model":"gpt-5.1","task":"model-arena","input_tokens":176,"output_tokens":10508,"cost_usd":0.14742}
 {"ts":"2026-07-25T07:40:59.586Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena","input_tokens":178,"output_tokens":7263,"cost_usd":0.018264}
 {"ts":"2026-07-25T07:41:46.410Z","provider":"xai","model":"grok-4.5","task":"model-arena","input_tokens":374,"output_tokens":6050,"cost_usd":0.091872}
+{"ts":"2026-07-25T07:42:36.447Z","provider":"openai","model":"gpt-5.1","task":"model-arena","input_tokens":166,"output_tokens":11124,"cost_usd":0.156027}
+{"ts":"2026-07-25T07:42:46.917Z","provider":"xai","model":"grok-4.5","task":"model-arena","input_tokens":360,"output_tokens":4202,"cost_usd":0.06411}
+{"ts":"2026-07-25T07:42:55.113Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena","input_tokens":171,"output_tokens":7248,"cost_usd":0.018223}
+{"ts":"2026-07-25T07:43:36.075Z","provider":"openai","model":"gpt-5.1","task":"model-arena","input_tokens":154,"output_tokens":5144,"cost_usd":0.072286}
+{"ts":"2026-07-25T07:44:29.126Z","provider":"xai","model":"grok-4.5","task":"model-arena","input_tokens":364,"output_tokens":7510,"cost_usd":0.113742}
+{"ts":"2026-07-25T07:45:36.642Z","provider":"openai","model":"gpt-5.1","task":"model-arena","input_tokens":161,"output_tokens":10798,"cost_usd":0.151454}
+{"ts":"2026-07-25T07:45:55.839Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena","input_tokens":156,"output_tokens":11151,"cost_usd":0.027971}
diff --git a/idea-run/run-next.sh b/idea-run/run-next.sh
index 0830e7c..49979a8 100755
--- a/idea-run/run-next.sh
+++ b/idea-run/run-next.sh
@@ -16,7 +16,7 @@ TITLE="${LINE%%|*}"; PROMPT="${LINE#*|}"
 python3 - "$TITLE" "$PROMPT" > /tmp/dwaa-payload.json <<'PY'
 import json,sys
 json.dump({"title":sys.argv[1],"prompt":sys.argv[2],
-           "models":["qwen3-14b","gemma3-12b","hermes3-8b","qwen25-7b","hf-qwen-coder-32b","claude-code","kimi","gpt","grok"]},
+           "models":["qwen3-14b","gemma3-12b","hermes3-8b","qwen25-7b","hf-qwen-coder-32b","claude-code","kimi","gpt","grok"],"designTools":true},
           sys.stdout)
 PY
 

← 8ebb3f7 Refocus loop to DW games+social by BRAND/STYLE/COLOR (16 ide  ·  back to Model Arena  ·  Beauty gate: auto-remix winners scoring <7 (make it more bea 3e64ec7 →