[object Object]

← back to Model Arena

auto-save: 2026-07-25T08:04:52 (4 files) — data/challenges.json data/costlog.jsonl data/artifacts/57af693363f2/ data/artifacts/70eea6613a73/

e3d5e37c8550f4fb33e492daf15f78916dcd0760 · 2026-07-25 08:04:58 -0700 · Steve Abrams

Files touched

Diff

commit e3d5e37c8550f4fb33e492daf15f78916dcd0760
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sat Jul 25 08:04:58 2026 -0700

    auto-save: 2026-07-25T08:04:52 (4 files) — data/challenges.json data/costlog.jsonl data/artifacts/57af693363f2/ data/artifacts/70eea6613a73/
---
 data/artifacts/57af693363f2/claude-code.html       |  673 +++++++++++
 data/artifacts/57af693363f2/claude-code.png        |  Bin 0 -> 127461 bytes
 data/artifacts/57af693363f2/gpt.html               | 1194 +++++++++++++++++++
 data/artifacts/57af693363f2/gpt.png                |  Bin 0 -> 176574 bytes
 data/artifacts/57af693363f2/grok.html              | 1233 ++++++++++++++++++++
 data/artifacts/57af693363f2/grok.png               |  Bin 0 -> 82106 bytes
 data/artifacts/57af693363f2/qwen25-7b.html         |  158 +++
 data/artifacts/57af693363f2/qwen25-7b.png          |  Bin 0 -> 21916 bytes
 data/artifacts/57af693363f2/qwen3-14b.html         |  380 ++++++
 data/artifacts/57af693363f2/qwen3-14b.png          |  Bin 0 -> 20062 bytes
 data/artifacts/70eea6613a73/claude-code.html       |  521 +++++++++
 data/artifacts/70eea6613a73/claude-code.png        |  Bin 0 -> 80774 bytes
 data/artifacts/70eea6613a73/gemma3-12b.html        |  274 +++++
 data/artifacts/70eea6613a73/gemma3-12b.png         |  Bin 0 -> 29131 bytes
 data/artifacts/70eea6613a73/gpt.html               | 1104 ++++++++++++++++++
 data/artifacts/70eea6613a73/gpt.png                |  Bin 0 -> 233554 bytes
 data/artifacts/70eea6613a73/grok.html              |  937 +++++++++++++++
 data/artifacts/70eea6613a73/grok.png               |  Bin 0 -> 53121 bytes
 data/artifacts/70eea6613a73/hermes3-8b.html        |  151 +++
 data/artifacts/70eea6613a73/hermes3-8b.png         |  Bin 0 -> 45511 bytes
 data/artifacts/70eea6613a73/hf-qwen-coder-32b.html |  204 ++++
 data/artifacts/70eea6613a73/hf-qwen-coder-32b.png  |  Bin 0 -> 38638 bytes
 data/artifacts/70eea6613a73/kimi.html              | 1041 +++++++++++++++++
 data/artifacts/70eea6613a73/kimi.png               |  Bin 0 -> 27072 bytes
 data/artifacts/70eea6613a73/qwen25-7b.html         |  162 +++
 data/artifacts/70eea6613a73/qwen25-7b.png          |  Bin 0 -> 25646 bytes
 data/artifacts/70eea6613a73/qwen3-14b.html         |  272 +++++
 data/artifacts/70eea6613a73/qwen3-14b.png          |  Bin 0 -> 24762 bytes
 data/challenges.json                               |  232 ++--
 data/costlog.jsonl                                 |    5 +
 30 files changed, 8456 insertions(+), 85 deletions(-)

diff --git a/data/artifacts/57af693363f2/claude-code.html b/data/artifacts/57af693363f2/claude-code.html
new file mode 100644
index 0000000..b7bb5b5
--- /dev/null
+++ b/data/artifacts/57af693363f2/claude-code.html
@@ -0,0 +1,673 @@
+<!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>Designer Wallcoverings — Roller Run</title>
+<style>
+  :root{
+    --bg:#0d0d0f;
+    --surface:#17171c;
+    --surface-2:#1e1e24;
+    --ink:#f5f2ea;
+    --muted:#8a8578;
+    --accent:#c9a961;
+    --accent-2:#7d6a45;
+    --line:rgba(201,169,97,.22);
+    --shadow:0 8px 24px rgba(0,0,0,.45);
+    --glow:0 0 28px rgba(201,169,97,.30);
+    --ease:cubic-bezier(.22,1,.36,1);
+    --serif:'Didot','Bodoni MT','Playfair Display','Cormorant Garamond',Georgia,serif;
+    --sans:-apple-system,'Segoe UI','Helvetica Neue',Arial,sans-serif;
+  }
+  *{box-sizing:border-box;margin:0;padding:0}
+  html,body{height:100%}
+  body{
+    background:
+      radial-gradient(1200px 600px at 50% -10%, #1a1a20 0%, transparent 60%),
+      var(--bg);
+    color:var(--ink);
+    font-family:var(--sans);
+    -webkit-font-smoothing:antialiased;
+    overflow:hidden;
+    display:flex;
+    flex-direction:column;
+    min-height:100vh;
+    user-select:none;
+  }
+
+  /* ---------- Header / Wordmark lockup ---------- */
+  header.topbar{
+    position:fixed;top:0;left:0;right:0;
+    z-index:30;
+    display:flex;align-items:center;justify-content:space-between;
+    gap:24px;
+    padding:18px 32px;
+    background:linear-gradient(180deg, rgba(13,13,15,.92) 0%, rgba(13,13,15,.55) 70%, transparent 100%);
+    backdrop-filter:blur(4px);
+    pointer-events:none;
+  }
+  .wordmark{
+    display:flex;flex-direction:column;line-height:1;
+    max-width:300px;
+  }
+  .wordmark .brand{
+    font-family:var(--serif);
+    color:var(--ink);
+    font-size:44px;
+    font-weight:500;
+    text-transform:uppercase;
+    letter-spacing:.18em;
+    white-space:nowrap;
+  }
+  .wordmark .sub{
+    margin-top:8px;
+    font-family:var(--sans);
+    font-size:11px;
+    letter-spacing:.34em;
+    text-transform:uppercase;
+    color:var(--accent);
+    padding-left:.18em;
+  }
+  .hairline{
+    height:1px;background:var(--line);
+    margin-top:10px;width:100%;
+  }
+  .scoreboard{
+    display:flex;gap:28px;align-items:flex-start;
+    text-align:right;
+  }
+  .stat{display:flex;flex-direction:column;gap:6px}
+  .stat .label{
+    font-family:var(--sans);
+    font-size:11px;letter-spacing:.16em;text-transform:uppercase;
+    color:var(--muted);
+  }
+  .stat .value{
+    font-family:var(--serif);
+    font-size:30px;color:var(--accent);letter-spacing:.02em;
+    font-variant-numeric:tabular-nums;
+  }
+
+  /* ---------- Stage ---------- */
+  .stage{
+    position:relative;flex:1;display:flex;align-items:center;justify-content:center;
+  }
+  #game{
+    display:block;
+    width:100%;height:100%;
+    position:absolute;inset:0;
+  }
+
+  /* ---------- Overlays ---------- */
+  .overlay{
+    position:absolute;inset:0;z-index:20;
+    display:flex;align-items:center;justify-content:center;
+    padding:24px;
+  }
+  .panel{
+    position:relative;
+    background:linear-gradient(180deg,var(--surface) 0%, var(--surface-2) 100%);
+    border:1px solid var(--line);
+    border-radius:14px;
+    box-shadow:var(--shadow),var(--glow);
+    padding:56px 64px;
+    max-width:560px;width:100%;
+    text-align:center;
+    animation:fadeUp .7s var(--ease) both;
+  }
+  .panel::before{
+    content:"";position:absolute;inset:10px;border:1px solid rgba(201,169,97,.12);
+    border-radius:8px;pointer-events:none;
+  }
+  .eyebrow{
+    font-size:12px;letter-spacing:.32em;text-transform:uppercase;color:var(--accent);
+    margin-bottom:22px;
+  }
+  .panel h1{
+    font-family:var(--serif);
+    font-size:52px;font-weight:500;line-height:1.02;letter-spacing:.01em;
+    margin-bottom:18px;color:var(--ink);
+  }
+  .panel h1 .thin{color:var(--muted);font-style:italic;display:block;font-size:34px;margin-top:6px}
+  .panel p.lead{
+    font-size:16px;line-height:1.7;color:var(--muted);
+    max-width:400px;margin:0 auto 34px;
+  }
+  .legend{
+    display:flex;justify-content:center;gap:26px;flex-wrap:wrap;
+    margin:0 auto 34px;
+  }
+  .legend .item{display:flex;flex-direction:column;align-items:center;gap:10px}
+  .swatch{width:46px;height:46px;border-radius:10px;border:1px solid rgba(255,255,255,.08);box-shadow:0 6px 16px rgba(0,0,0,.4)}
+  .legend .name{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
+  .btn{
+    display:inline-flex;align-items:center;gap:12px;
+    font-family:var(--sans);
+    font-size:13px;letter-spacing:.2em;text-transform:uppercase;
+    color:var(--bg);
+    background:linear-gradient(180deg,var(--accent) 0%, var(--accent-2) 130%);
+    border:none;border-radius:40px;
+    padding:16px 40px;cursor:pointer;
+    box-shadow:0 8px 24px rgba(201,169,97,.28);
+    transition:transform .2s var(--ease), box-shadow .2s var(--ease);
+  }
+  .btn:hover{transform:translateY(-2px);box-shadow:0 14px 34px rgba(201,169,97,.4)}
+  .btn:active{transform:translateY(0)}
+  .finalscores{
+    display:flex;justify-content:center;gap:56px;margin:8px auto 34px;
+  }
+  .finalscores .fs{display:flex;flex-direction:column;gap:8px}
+  .finalscores .fs .l{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
+  .finalscores .fs .v{font-family:var(--serif);font-size:48px;color:var(--accent);font-variant-numeric:tabular-nums;line-height:1}
+  .hint{
+    margin-top:26px;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);opacity:.7;
+  }
+  .hide{display:none !important}
+
+  @keyframes fadeUp{from{opacity:0;transform:translateY(28px)}to{opacity:1;transform:none}}
+
+  @media (max-width:640px){
+    .wordmark .brand{font-size:30px;letter-spacing:.14em;white-space:normal}
+    header.topbar{padding:14px 18px}
+    .scoreboard{gap:16px}
+    .stat .value{font-size:22px}
+    .panel{padding:40px 28px}
+    .panel h1{font-size:38px}
+    .finalscores{gap:36px}
+  }
+</style>
+</head>
+<body>
+
+  <header class="topbar">
+    <div class="wordmark">
+      <span class="brand">Designer Wallcoverings</span>
+      <span class="sub">Roller Run · The Atelier Game</span>
+      <span class="hairline"></span>
+    </div>
+    <div class="scoreboard">
+      <div class="stat">
+        <span class="label">Score</span>
+        <span class="value" id="scoreVal">0</span>
+      </div>
+      <div class="stat">
+        <span class="label">Best</span>
+        <span class="value" id="bestVal">0</span>
+      </div>
+    </div>
+  </header>
+
+  <div class="stage">
+    <canvas id="game"></canvas>
+
+    <!-- Start overlay -->
+    <div class="overlay" id="startOverlay">
+      <div class="panel">
+        <div class="eyebrow">An Endless Roll</div>
+        <h1>Roller Run<span class="thin">collect the collection</span></h1>
+        <p class="lead">Guide the paint-roller along the gallery wall. Gather wallpaper rolls by their design style, dodge the pails and ladders, and let the wall reveal itself faster with every pass.</p>
+        <div class="legend" id="legend"></div>
+        <button class="btn" id="startBtn">Begin the Run</button>
+        <div class="hint">Tap · Click · Press Space to Jump</div>
+      </div>
+    </div>
+
+    <!-- Game over overlay -->
+    <div class="overlay hide" id="overOverlay">
+      <div class="panel">
+        <div class="eyebrow">The Wall Rests</div>
+        <h1>Game Over</h1>
+        <div class="finalscores">
+          <div class="fs"><span class="l">Your Score</span><span class="v" id="finalScore">0</span></div>
+          <div class="fs"><span class="l">Best</span><span class="v" id="finalBest">0</span></div>
+        </div>
+        <p class="lead" id="overMsg">A refined effort. Every roll gathered adds to the pattern.</p>
+        <button class="btn" id="restartBtn">Roll Again</button>
+        <div class="hint">Tap · Click · Press Space</div>
+      </div>
+    </div>
+  </div>
+
+<script>
+(function(){
+  "use strict";
+
+  const canvas = document.getElementById('game');
+  const ctx = canvas.getContext('2d');
+
+  const scoreEl = document.getElementById('scoreVal');
+  const bestEl  = document.getElementById('bestVal');
+  const startOverlay = document.getElementById('startOverlay');
+  const overOverlay  = document.getElementById('overOverlay');
+  const startBtn = document.getElementById('startBtn');
+  const restartBtn = document.getElementById('restartBtn');
+  const finalScore = document.getElementById('finalScore');
+  const finalBest  = document.getElementById('finalBest');
+  const overMsg = document.getElementById('overMsg');
+  const legendEl = document.getElementById('legend');
+
+  // ---- Palette tokens (mirrors CSS) ----
+  const C = {
+    bg:'#0d0d0f', surface:'#17171c', surface2:'#1e1e24',
+    ink:'#f5f2ea', muted:'#8a8578', accent:'#c9a961', accent2:'#7d6a45',
+    line:'rgba(201,169,97,0.22)'
+  };
+
+  // Wallpaper roll "styles" — each visually distinct, no letters.
+  const STYLES = [
+    { name:'Damask',    base:'#7d6a45', motif:'#e6cd8f' },
+    { name:'Moiré',     base:'#3a4c5a', motif:'#9fc0d1' },
+    { name:'Botanical', base:'#2f4c39', motif:'#a6cf9d' },
+    { name:'Terracotta',base:'#8a4632', motif:'#e0a458' },
+    { name:'Noir Silk', base:'#232028', motif:'#c9a961' }
+  ];
+
+  // Build legend swatches (bare luxury swatches, no letters)
+  STYLES.forEach(s=>{
+    const item = document.createElement('div');
+    item.className='item';
+    const sw = document.createElement('div');
+    sw.className='swatch';
+    sw.style.background = `linear-gradient(135deg, ${s.base} 0%, ${s.motif} 140%)`;
+    const nm = document.createElement('div');
+    nm.className='name'; nm.textContent = s.name;
+    item.appendChild(sw); item.appendChild(nm);
+    legendEl.appendChild(item);
+  });
+
+  // ---- Device / sizing ----
+  let W=0,H=0,DPR=1, groundY=0;
+  function resize(){
+    DPR = Math.min(window.devicePixelRatio||1, 2);
+    W = canvas.clientWidth = canvas.parentElement.clientWidth;
+    H = canvas.clientHeight = canvas.parentElement.clientHeight;
+    canvas.width = Math.floor(W*DPR);
+    canvas.height= Math.floor(H*DPR);
+    ctx.setTransform(DPR,0,0,DPR,0,0);
+    groundY = H*0.80;
+  }
+  window.addEventListener('resize', resize);
+
+  // ---- Game state ----
+  let state='start'; // start | playing | over
+  let best = parseInt(localStorage.getItem('dw_rollerrun_best')||'0',10) || 0;
+  bestEl.textContent = best;
+
+  const player = { x:0, y:0, r:26, vy:0, onGround:true, rot:0, squash:1 };
+  let gravity, jumpV, baseSpeed, speed, distance, score, spawnTimer, spawnGap;
+  let obstacles=[], collectibles=[], particles=[], sparkles=[];
+  let bgOffset=0, shake=0, lastT=0, comboMsg=null;
+
+  function reset(){
+    player.x = W*0.22;
+    player.y = groundY - player.r;
+    player.vy=0; player.onGround=true; player.rot=0; player.squash=1;
+    gravity = H*0.0028;
+    jumpV   = -H*0.017;
+    baseSpeed = W*0.0052;
+    speed = baseSpeed;
+    distance=0; score=0; spawnTimer=0; spawnGap=95;
+    obstacles=[]; collectibles=[]; particles=[]; sparkles=[];
+    bgOffset=0; shake=0; comboMsg=null;
+    scoreEl.textContent='0';
+  }
+
+  function start(){
+    resize(); reset();
+    state='playing';
+    startOverlay.classList.add('hide');
+    overOverlay.classList.add('hide');
+    lastT = performance.now();
+    requestAnimationFrame(loop);
+  }
+
+  function gameOver(){
+    state='over';
+    shake = 14;
+    if(score>best){ best=score; localStorage.setItem('dw_rollerrun_best', String(best)); }
+    bestEl.textContent = best;
+    finalScore.textContent = score;
+    finalBest.textContent = best;
+    overMsg.textContent = score>=200
+      ? 'A masterwork of a run — the full collection is nearly yours.'
+      : (score>=80 ? 'Beautifully done. The pattern is taking shape.'
+                   : 'A refined effort. Every roll gathered adds to the pattern.');
+    overOverlay.classList.remove('hide');
+  }
+
+  function jump(){
+    if(state!=='playing') return;
+    if(player.onGround){
+      player.vy = jumpV;
+      player.onGround=false;
+      player.squash=0.8;
+      // launch dust
+      for(let i=0;i<8;i++){
+        particles.push({x:player.x, y:groundY, vx:(Math.random()-0.5)*3, vy:-Math.random()*2-0.5, life:1, r:2+Math.random()*2, col:C.muted});
+      }
+    }
+  }
+
+  // ---- Input ----
+  function onPress(e){
+    if(state==='playing'){ jump(); }
+  }
+  window.addEventListener('keydown', e=>{
+    if(e.code==='Space'||e.code==='ArrowUp'){
+      e.preventDefault();
+      if(state==='start') start();
+      else if(state==='over') start();
+      else jump();
+    }
+  });
+  canvas.addEventListener('pointerdown', onPress);
+  startBtn.addEventListener('click', start);
+  restartBtn.addEventListener('click', start);
+
+  // ---- Spawning ----
+  function spawnObstacle(){
+    const kinds=['pail','ladder','pail'];
+    const k = kinds[(Math.random()*kinds.length)|0];
+    if(k==='ladder'){
+      obstacles.push({type:'ladder', x:W+40, w:20, h:64+Math.random()*26});
+    } else {
+      obstacles.push({type:'pail', x:W+40, w:34, h:34+Math.random()*16});
+    }
+  }
+  function spawnCollectible(){
+    const s = STYLES[(Math.random()*STYLES.length)|0];
+    const highJump = Math.random()<0.45;
+    const y = highJump ? groundY - 130 - Math.random()*40 : groundY - 60 - Math.random()*30;
+    collectibles.push({x:W+40, y:y, r:16, style:s, spin:Math.random()*Math.PI, taken:false, float:Math.random()*Math.PI*2});
+  }
+
+  // ---- Update ----
+  function update(dt){
+    speed = baseSpeed + Math.min(distance/2600, baseSpeed*1.9);
+    distance += speed;
+    bgOffset = (bgOffset + speed*0.5) % 240;
+
+    // player physics
+    player.vy += gravity;
+    player.y  += player.vy;
+    const floor = groundY - player.r;
+    if(player.y >= floor){
+      player.y = floor;
+      if(!player.onGround){
+        player.squash=1.25;
+        for(let i=0;i<6;i++){
+          particles.push({x:player.x, y:groundY, vx:(Math.random()-0.5)*2.5, vy:-Math.random()*1.5, life:1, r:2+Math.random()*2, col:C.muted});
+        }
+      }
+      player.vy=0; player.onGround=true;
+    }
+    player.rot += speed*0.06;
+    player.squash += (1-player.squash)*0.18;
+
+    // spawn cadence tightens with speed
+    spawnTimer += 1;
+    const gap = Math.max(46, spawnGap - distance/260);
+    if(spawnTimer >= gap){
+      spawnTimer = 0;
+      spawnObstacle();
+      if(Math.random()<0.75) {
+        // stagger a collectible slightly after
+        setTimeout(()=>{ if(state==='playing') spawnCollectible(); }, 180);
+      }
+    }
+
+    // obstacles
+    for(let o of obstacles){ o.x -= speed; }
+    obstacles = obstacles.filter(o=> o.x + (o.w||40) > -20);
+
+    // collectibles
+    for(let c of collectibles){ c.x -= speed; c.spin += 0.08; c.float += 0.06; }
+    collectibles = collectibles.filter(c=> c.x > -40 && !c.taken);
+
+    // collision + collection
+    const pr = player.r*0.9;
+    for(let o of obstacles){
+      let ox, oy, ow, oh;
+      if(o.type==='pail'){ ow=o.w; oh=o.h; ox=o.x; oy=groundY-oh; }
+      else { ow=o.w; oh=o.h; ox=o.x; oy=groundY-oh; }
+      // circle vs rect
+      const cx = Math.max(ox, Math.min(player.x, ox+ow));
+      const cy = Math.max(oy, Math.min(player.y, oy+oh));
+      const dx = player.x - cx, dy = player.y - cy;
+      if(dx*dx+dy*dy < pr*pr){ gameOver(); return; }
+    }
+    for(let c of collectibles){
+      const dx = player.x - c.x, dy = player.y - c.y;
+      if(dx*dx+dy*dy < (pr+c.r)*(pr+c.r)){
+        c.taken=true;
+        score += 5;
+        scoreEl.textContent = score;
+        // sparkle burst in style color
+        for(let i=0;i<14;i++){
+          const a=Math.random()*Math.PI*2, sp=Math.random()*4+1;
+          sparkles.push({x:c.x, y:c.y, vx:Math.cos(a)*sp, vy:Math.sin(a)*sp, life:1, r:1.5+Math.random()*2.5, col: Math.random()<0.5?c.style.motif:c.style.base});
+        }
+        comboMsg = { text:c.style.name, x:c.x, y:c.y-24, life:1, col:c.style.motif };
+      }
+    }
+
+    // passive distance score
+    if(((distance/ W)|0) !== (((distance-speed)/W)|0)){
+      score += 1;
+      scoreEl.textContent = score;
+    }
+
+    // particles
+    for(let p of particles){ p.x -= speed*0.3; p.x+=p.vx; p.y+=p.vy; p.vy+=0.12; p.life-=0.03; }
+    particles = particles.filter(p=>p.life>0);
+    for(let s of sparkles){ s.x-=speed*0.4; s.x+=s.vx; s.y+=s.vy; s.vy+=0.08; s.vx*=0.96; s.life-=0.028; }
+    sparkles = sparkles.filter(s=>s.life>0);
+    if(comboMsg){ comboMsg.x-=speed; comboMsg.y-=0.6; comboMsg.life-=0.02; if(comboMsg.life<=0) comboMsg=null; }
+
+    if(shake>0) shake*=0.86;
+  }
+
+  // ---- Draw ----
+  function roundRect(x,y,w,h,r){
+    ctx.beginPath();
+    ctx.moveTo(x+r,y);
+    ctx.arcTo(x+w,y,x+w,y+h,r);
+    ctx.arcTo(x+w,y+h,x,y+h,r);
+    ctx.arcTo(x,y+h,x,y,r);
+    ctx.arcTo(x,y,x+w,y,r);
+    ctx.closePath();
+  }
+
+  function drawWall(){
+    // deep vignette wall
+    const g = ctx.createLinearGradient(0,0,0,H);
+    g.addColorStop(0, '#141419');
+    g.addColorStop(0.62,'#101014');
+    g.addColorStop(1, '#0b0b0d');
+    ctx.fillStyle=g; ctx.fillRect(0,0,W,H);
+
+    // faint damask-style repeating motif on the wall (hairline gold)
+    ctx.save();
+    ctx.globalAlpha=0.05;
+    ctx.strokeStyle=C.accent;
+    ctx.lineWidth=1;
+    const step=120;
+    for(let x=-((bgOffset)%step); x<W+step; x+=step){
+      for(let y=60; y<groundY-30; y+=step){
+        ctx.beginPath();
+        ctx.ellipse(x, y, 26, 40, 0, 0, Math.PI*2);
+        ctx.stroke();
+        ctx.beginPath();
+        ctx.ellipse(x, y, 12, 20, 0, 0, Math.PI*2);
+        ctx.stroke();
+      }
+    }
+    ctx.restore();
+
+    // baseboard / floor line
+    ctx.fillStyle = '#08080a';
+    ctx.fillRect(0, groundY, W, H-groundY);
+    // gold hairline where roller runs
+    ctx.strokeStyle = C.line;
+    ctx.lineWidth=1;
+    ctx.beginPath(); ctx.moveTo(0,groundY+0.5); ctx.lineTo(W,groundY+0.5); ctx.stroke();
+    // subtle floor sheen
+    const fg = ctx.createLinearGradient(0,groundY,0,H);
+    fg.addColorStop(0,'rgba(201,169,97,0.06)');
+    fg.addColorStop(1,'rgba(201,169,97,0)');
+    ctx.fillStyle=fg; ctx.fillRect(0,groundY,W,H-groundY);
+  }
+
+  function drawPlayer(){
+    ctx.save();
+    ctx.translate(player.x, player.y);
+    // shadow
+    ctx.save();
+    ctx.globalAlpha=0.4;
+    ctx.fillStyle='#000';
+    const sc = Math.max(0.4, 1 - (groundY-player.r-player.y)/260);
+    ctx.beginPath();
+    ctx.ellipse(0, (groundY-player.y), player.r*1.1*sc, 6*sc, 0,0,Math.PI*2);
+    ctx.fill();
+    ctx.restore();
+
+    ctx.rotate(player.rot);
+    ctx.scale(1/player.squash, player.squash);
+
+    // roller drum (gold cylinder as a circle w/ nap ridges)
+    ctx.fillStyle = C.surface2;
+    ctx.beginPath(); ctx.arc(0,0,player.r,0,Math.PI*2); ctx.fill();
+    // metallic rim
+    const rg = ctx.createRadialGradient(-6,-6,4,0,0,player.r);
+    rg.addColorStop(0,'#e6cd8f');
+    rg.addColorStop(0.6,C.accent);
+    rg.addColorStop(1,C.accent2);
+    ctx.fillStyle=rg;
+    ctx.beginPath(); ctx.arc(0,0,player.r-3,0,Math.PI*2); ctx.fill();
+    // nap ridges
+    ctx.strokeStyle='rgba(13,13,15,0.35)'; ctx.lineWidth=2;
+    for(let i=0;i<6;i++){
+      const a=i*Math.PI/3;
+      ctx.beginPath();
+      ctx.moveTo(Math.cos(a)*8, Math.sin(a)*8);
+      ctx.lineTo(Math.cos(a)*(player.r-5), Math.sin(a)*(player.r-5));
+      ctx.stroke();
+    }
+    // hub
+    ctx.fillStyle=C.surface;
+    ctx.beginPath(); ctx.arc(0,0,6,0,Math.PI*2); ctx.fill();
+    ctx.restore();
+  }
+
+  function drawObstacles(){
+    for(let o of obstacles){
+      if(o.type==='pail'){
+        const x=o.x, w=o.w, h=o.h, y=groundY-h;
+        // paint pail — dark surface w/ gold rim + accent drip
+        ctx.fillStyle=C.surface2;
+        roundRect(x, y, w, h, 4); ctx.fill();
+        ctx.strokeStyle=C.accent; ctx.lineWidth=1.5;
+        roundRect(x, y, w, h, 4); ctx.stroke();
+        // rim
+        ctx.fillStyle=C.accent;
+        roundRect(x-2, y-4, w+4, 6, 3); ctx.fill();
+        // paint surface
+        ctx.fillStyle=C.accent2;
+        roundRect(x+3, y-1, w-6, 5, 2); ctx.fill();
+      } else {
+        // ladder / obstacle post
+        const x=o.x, w=o.w, h=o.h, y=groundY-h;
+        ctx.strokeStyle=C.muted; ctx.lineWidth=3;
+        ctx.beginPath(); ctx.moveTo(x,groundY); ctx.lineTo(x, y); ctx.stroke();
+        ctx.beginPath(); ctx.moveTo(x+w,groundY); ctx.lineTo(x+w, y); ctx.stroke();
+        ctx.lineWidth=2; ctx.strokeStyle='rgba(138,133,120,0.7)';
+        for(let ry=y+6; ry<groundY; ry+=14){
+          ctx.beginPath(); ctx.moveTo(x, ry); ctx.lineTo(x+w, ry); ctx.stroke();
+        }
+      }
+    }
+  }
+
+  function drawCollectibles(){
+    for(let c of collectibles){
+      const fy = c.y + Math.sin(c.float)*3;
+      ctx.save();
+      ctx.translate(c.x, fy);
+      // glow
+      ctx.save();
+      ctx.globalAlpha=0.35;
+      const gg=ctx.createRadialGradient(0,0,2,0,0,c.r*2.2);
+      gg.addColorStop(0,c.style.motif); gg.addColorStop(1,'rgba(0,0,0,0)');
+      ctx.fillStyle=gg;
+      ctx.beginPath(); ctx.arc(0,0,c.r*2.2,0,Math.PI*2); ctx.fill();
+      ctx.restore();
+      // rolled wallpaper — a small cylinder end-on with style gradient
+      ctx.rotate(Math.sin(c.spin)*0.15);
+      const wg=ctx.createLinearGradient(-c.r,-c.r,c.r,c.r);
+      wg.addColorStop(0,c.style.base); wg.addColorStop(1,c.style.motif);
+      ctx.fillStyle=wg;
+      roundRect(-c.r, -c.r, c.r*2, c.r*2, 5); ctx.fill();
+      // rolled edge spiral suggestion
+      ctx.strokeStyle='rgba(13,13,15,0.35)'; ctx.lineWidth=2;
+      ctx.beginPath(); ctx.arc(0,0,c.r-4,0,Math.PI*1.6); ctx.stroke();
+      ctx.strokeStyle=c.style.motif; ctx.lineWidth=1.5;
+      roundRect(-c.r,-c.r,c.r*2,c.r*2,5); ctx.stroke();
+      ctx.restore();
+    }
+  }
+
+  function drawFX(){
+    for(let p of particles){
+      ctx.globalAlpha=Math.max(0,p.life);
+      ctx.fillStyle=p.col;
+      ctx.beginPath(); ctx.arc(p.x,p.y,p.r,0,Math.PI*2); ctx.fill();
+    }
+    for(let s of sparkles){
+      ctx.globalAlpha=Math.max(0,s.life);
+      ctx.fillStyle=s.col;
+      ctx.beginPath(); ctx.arc(s.x,s.y,s.r*s.life,0,Math.PI*2); ctx.fill();
+    }
+    ctx.globalAlpha=1;
+    if(comboMsg){
+      ctx.globalAlpha=Math.max(0,comboMsg.life);
+      ctx.fillStyle=comboMsg.col;
+      ctx.font='600 13px -apple-system,Segoe UI,Arial,sans-serif';
+      ctx.textAlign='center';
+      ctx.fillText('+5  '+comboMsg.text.toUpperCase(), comboMsg.x, comboMsg.y);
+      ctx.globalAlpha=1;
+    }
+  }
+
+  function render(){
+    ctx.save();
+    if(shake>0.4){
+      ctx.translate((Math.random()-0.5)*shake, (Math.random()-0.5)*shake);
+    }
+    drawWall();
+    drawCollectibles();
+    drawObstacles();
+    drawFX();
+    drawPlayer();
+    ctx.restore();
+  }
+
+  // ---- Main loop ----
+  function loop(t){
+    const dt = Math.min(50, t-lastT); lastT=t;
+    if(state==='playing'){
+      update(dt);
+      render();
+      requestAnimationFrame(loop);
+    } else {
+      render();
+    }
+  }
+
+  // idle preview render behind start overlay
+  resize(); reset(); render();
+
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/57af693363f2/claude-code.png b/data/artifacts/57af693363f2/claude-code.png
new file mode 100644
index 0000000..791f504
Binary files /dev/null and b/data/artifacts/57af693363f2/claude-code.png differ
diff --git a/data/artifacts/57af693363f2/gpt.html b/data/artifacts/57af693363f2/gpt.html
new file mode 100644
index 0000000..32c2840
--- /dev/null
+++ b/data/artifacts/57af693363f2/gpt.html
@@ -0,0 +1,1194 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Designer Wallcoverings Runner</title>
+  <style>
+    :root {
+      /* Design tokens */
+      --bg: #0d0d0f;
+      --surface: #17171c;
+      --surface-soft: #1f2026;
+      --ink: #f5f2ea;
+      --ink-muted: #8a8578;
+      --accent: #c9a961; /* metallic gold */
+      --accent-deep: #7d6a45;
+      --line: rgba(245, 242, 234, 0.14);
+      --line-strong: rgba(245, 242, 234, 0.32);
+      --shadow-soft: 0 18px 45px rgba(0, 0, 0, 0.6);
+      --shadow-subtle: 0 1px 3px rgba(0, 0, 0, 0.5);
+      --radius-lg: 18px;
+      --radius-md: 12px;
+      --radius-pill: 999px;
+
+      --font-display: "Playfair Display", "Didot", "Bodoni MT", Georgia, serif;
+      --font-serif: "EB Garamond", "Cormorant Garamond", "Playfair Display", Georgia, serif;
+      --font-sans: "Avenir Next", "Century Gothic", -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
+
+      --fs-logo: 44px;
+      --fs-body: 16px;
+      --fs-label: 11px;
+      --fs-hud: 13px;
+
+      --ease-default: cubic-bezier(.22,.9,.24,1); /* swift-out */
+      --ease-hero: cubic-bezier(.22,1,.36,1);     /* ease-out-quint */
+      --ease-pop: cubic-bezier(.34,1.56,.64,1);   /* overshoot */
+
+      --transition-fast: 160ms var(--ease-default);
+      --transition-med: 260ms var(--ease-default);
+    }
+
+    * {
+      box-sizing: border-box;
+    }
+
+    html, body {
+      margin: 0;
+      padding: 0;
+      height: 100%;
+      background: radial-gradient(circle at top, #15151b 0, var(--bg) 52%, #050508 100%);
+      color: var(--ink);
+      font-family: var(--font-sans);
+      -webkit-font-smoothing: antialiased;
+    }
+
+    body {
+      display: flex;
+      flex-direction: column;
+      align-items: stretch;
+      justify-content: flex-start;
+    }
+
+    header {
+      position: fixed;
+      top: 0;
+      left: 0;
+      right: 0;
+      height: 78px;
+      padding: 18px 32px 14px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      background: linear-gradient(to bottom, rgba(13,13,15,0.96), rgba(13,13,15,0.86));
+      border-bottom: 1px solid var(--line);
+      box-shadow: 0 12px 30px rgba(0,0,0,0.7);
+      z-index: 20;
+      backdrop-filter: blur(18px);
+    }
+
+    .wordmark-lockup {
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      max-width: 320px;
+    }
+
+    .wordmark {
+      font-family: var(--font-serif);
+      font-size: var(--fs-logo);
+      letter-spacing: 0.18em;
+      text-transform: uppercase;
+      color: #1c1a17; /* darkest ink variant to satisfy requirement */
+      color: var(--bg); /* near-black text over luminous accent panel */
+      line-height: 1.05;
+      padding: 10px 16px 9px;
+      border-radius: 999px;
+      border: 1px solid rgba(0,0,0,0.28);
+      background:
+        linear-gradient(135deg, rgba(255,255,255,0.05), rgba(0,0,0,0.40)),
+        radial-gradient(circle at 10% 0%, rgba(255,255,255,0.35), transparent 55%),
+        linear-gradient(135deg, #f7f3e6 0%, #d9c394 45%, #b59654 100%);
+      box-shadow:
+        0 0 0 1px rgba(255,255,255,0.05),
+        0 14px 38px rgba(0,0,0,0.65),
+        inset 0 0 0 0.5px rgba(255,255,255,0.3);
+      white-space: normal;
+    }
+
+    .hud {
+      display: flex;
+      align-items: center;
+      gap: 18px;
+      font-family: var(--font-sans);
+      font-size: var(--fs-hud);
+      letter-spacing: 0.16em;
+      text-transform: uppercase;
+      color: var(--ink-muted);
+    }
+
+    .hud-group {
+      display: flex;
+      align-items: center;
+      gap: 10px;
+      padding: 6px 12px;
+      border-radius: var(--radius-pill);
+      background: rgba(23,23,28,0.9);
+      border: 1px solid var(--line);
+      box-shadow: var(--shadow-subtle);
+    }
+
+    .hud-label {
+      opacity: 0.7;
+    }
+
+    .hud-value {
+      color: var(--ink);
+    }
+
+    .hud-dot {
+      width: 6px;
+      height: 6px;
+      border-radius: 50%;
+      background: radial-gradient(circle at 30% 20%, #fff, #f1e2b0 45%, #b59242 100%);
+      box-shadow: 0 0 0 1px rgba(0,0,0,0.7);
+    }
+
+    main {
+      flex: 1;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      padding: 96px 32px 32px;
+    }
+
+    .shell {
+      width: 100%;
+      max-width: 960px;
+      aspect-ratio: 16 / 9;
+      min-height: 420px;
+      position: relative;
+      border-radius: var(--radius-lg);
+      background: radial-gradient(circle at top left, #262632 0, #14141a 40%, #050507 100%);
+      border: 1px solid var(--line-strong);
+      box-shadow: var(--shadow-soft);
+      overflow: hidden;
+      display: flex;
+      align-items: stretch;
+      justify-content: stretch;
+    }
+
+    .canvas-wrap {
+      position: relative;
+      flex: 1;
+      margin: 18px;
+      border-radius: calc(var(--radius-lg) - 10px);
+      background:
+        radial-gradient(circle at 0% 0%, rgba(255,255,255,0.06), transparent 55%),
+        repeating-linear-gradient(
+          90deg,
+          rgba(255,255,255,0.05) 0,
+          rgba(255,255,255,0.05) 1px,
+          transparent 1px,
+          transparent 32px
+        ),
+        linear-gradient(to bottom, #201f28, #111018 42%, #08070c 100%);
+      border: 1px solid var(--line);
+      overflow: hidden;
+    }
+
+    canvas {
+      width: 100%;
+      height: 100%;
+      display: block;
+    }
+
+    .side-panel {
+      position: absolute;
+      right: 0;
+      top: 0;
+      bottom: 0;
+      width: 220px;
+      padding: 18px 18px 18px 0;
+      pointer-events: none;
+      display: flex;
+      flex-direction: column;
+      gap: 14px;
+    }
+
+    .card {
+      pointer-events: auto;
+      background: radial-gradient(circle at top, rgba(255,255,255,0.05), transparent 55%), rgba(12,12,18,0.92);
+      border-radius: var(--radius-md);
+      border: 1px solid var(--line);
+      box-shadow: var(--shadow-subtle);
+      padding: 14px 16px 13px;
+    }
+
+    .card-label {
+      font-size: var(--fs-label);
+      letter-spacing: 0.16em;
+      text-transform: uppercase;
+      color: var(--ink-muted);
+      margin-bottom: 8px;
+    }
+
+    .card-body {
+      font-size: 13px;
+      line-height: 1.5;
+      color: var(--ink);
+    }
+
+    .pattern-row {
+      display: flex;
+      gap: 6px;
+      margin-top: 6px;
+    }
+
+    .swatch {
+      flex: 1;
+      height: 34px;
+      border-radius: 999px;
+      border: 1px solid rgba(245,242,234,0.3);
+      box-shadow: inset 0 0 0 0.5px rgba(255,255,255,0.25);
+      overflow: hidden;
+    }
+
+    .swatch--marble {
+      background:
+        radial-gradient(circle at 20% 0%, rgba(255,255,255,0.65), transparent 55%),
+        repeating-linear-gradient(
+          135deg,
+          rgba(255,255,255,0.28) 0,
+          rgba(255,255,255,0.16) 5px,
+          rgba(0,0,0,0.18) 10px,
+          rgba(0,0,0,0.4) 16px
+        );
+      filter: saturate(1.1);
+    }
+
+    .swatch--geo {
+      background:
+        radial-gradient(circle at 0 0, rgba(255,255,255,0.55), transparent 60%),
+        repeating-linear-gradient(
+          45deg,
+          transparent 0,
+          transparent 6px,
+          rgba(255,255,255,0.28) 6px,
+          rgba(255,255,255,0.28) 7px
+        ),
+        repeating-linear-gradient(
+          -45deg,
+          transparent 0,
+          transparent 6px,
+          rgba(201,169,97,0.75) 6px,
+          rgba(201,169,97,0.75) 7px
+        );
+    }
+
+    .swatch--silk {
+      background:
+        linear-gradient(135deg, rgba(255,255,255,0.4), transparent 50%),
+        linear-gradient(315deg, rgba(255,255,255,0.45), transparent 55%),
+        linear-gradient(90deg, #22212b 0%, #4a3b2f 40%, #b38a4a 70%, #f3e6c7 100%);
+      background-size: 200% 200%;
+      animation: sheen 10s linear infinite;
+    }
+
+    @keyframes sheen {
+      0% { background-position: 0% 50%; }
+      50% { background-position: 100% 50%; }
+      100% { background-position: 0% 50%; }
+    }
+
+    .controls {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 6px 10px;
+      margin-top: 8px;
+      font-size: 11px;
+      letter-spacing: 0.14em;
+      text-transform: uppercase;
+      color: var(--ink-muted);
+    }
+
+    .key {
+      min-width: 18px;
+      padding: 3px 6px;
+      border-radius: 8px;
+      border: 1px solid var(--line);
+      background: rgba(23,23,28,0.9);
+      color: var(--ink);
+      text-align: center;
+      box-shadow: inset 0 0 0 0.5px rgba(255,255,255,0.08);
+    }
+
+    .button-row {
+      display: flex;
+      gap: 8px;
+      margin-top: 10px;
+    }
+
+    .btn {
+      pointer-events: auto;
+      flex: 1;
+      padding: 7px 10px;
+      border-radius: var(--radius-pill);
+      border: 1px solid var(--line);
+      background: linear-gradient(to bottom, #23222e, #13121a);
+      color: var(--ink);
+      font-family: var(--font-sans);
+      font-size: 11px;
+      letter-spacing: 0.18em;
+      text-transform: uppercase;
+      cursor: pointer;
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+      gap: 6px;
+      transition:
+        background-color var(--transition-med),
+        border-color var(--transition-med),
+        transform var(--transition-fast),
+        box-shadow var(--transition-med);
+    }
+
+    .btn-primary {
+      background:
+        radial-gradient(circle at 0 0, rgba(255,255,255,0.15), transparent 55%),
+        linear-gradient(135deg, #d7bf7c, #b6934b);
+      color: #201d12;
+      border-color: rgba(248,241,221,0.9);
+      box-shadow:
+        0 0 0 1px rgba(0,0,0,0.55),
+        0 10px 24px rgba(0,0,0,0.7);
+    }
+
+    .btn-primary:hover {
+      transform: translateY(-1px);
+      box-shadow:
+        0 0 0 1px rgba(0,0,0,0.7),
+        0 12px 32px rgba(0,0,0,0.8);
+    }
+
+    .btn-ghost:hover {
+      background: linear-gradient(to bottom, #2b2a36, #18171f);
+      border-color: var(--line-strong);
+      transform: translateY(-1px);
+      box-shadow: 0 10px 24px rgba(0,0,0,0.7);
+    }
+
+    .btn-icon {
+      width: 10px;
+      height: 10px;
+      border-radius: 50%;
+      background: radial-gradient(circle at 30% 20%, #fff, #f7e8ba 45%, #b6934b 100%);
+      box-shadow: 0 0 0 1px rgba(0,0,0,0.7);
+    }
+
+    .overlay {
+      position: absolute;
+      inset: 18px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      pointer-events: none;
+      z-index: 10;
+    }
+
+    .overlay-inner {
+      pointer-events: auto;
+      min-width: 260px;
+      max-width: 360px;
+      padding: 20px 22px 18px;
+      border-radius: var(--radius-lg);
+      background:
+        radial-gradient(circle at top, rgba(255,255,255,0.1), transparent 55%),
+        linear-gradient(135deg, rgba(13,13,15,0.98), rgba(13,13,15,0.92));
+      border: 1px solid rgba(245,242,234,0.22);
+      box-shadow: 0 28px 60px rgba(0,0,0,0.85);
+      transform: translateY(12px);
+      opacity: 0;
+      transition:
+        opacity 260ms var(--ease-hero),
+        transform 260ms var(--ease-hero);
+    }
+
+    .overlay--visible .overlay-inner {
+      opacity: 1;
+      transform: translateY(0);
+    }
+
+    .overlay-title {
+      font-family: var(--font-serif);
+      font-size: 28px;
+      letter-spacing: 0.16em;
+      text-transform: uppercase;
+      color: var(--ink);
+      margin-bottom: 6px;
+    }
+
+    .overlay-sub {
+      font-size: 13px;
+      color: var(--ink-muted);
+      margin-bottom: 12px;
+    }
+
+    .overlay-metrics {
+      display: flex;
+      justify-content: space-between;
+      gap: 10px;
+      margin-bottom: 14px;
+      font-size: 13px;
+    }
+
+    .overlay-metric-label {
+      text-transform: uppercase;
+      letter-spacing: 0.16em;
+      font-size: 11px;
+      color: var(--ink-muted);
+      margin-bottom: 2px;
+    }
+
+    .overlay-metric-value {
+      color: var(--ink);
+    }
+
+    .pill {
+      display: inline-flex;
+      align-items: center;
+      gap: 6px;
+      padding: 3px 9px;
+      border-radius: var(--radius-pill);
+      border: 1px solid rgba(245,242,234,0.24);
+      background: rgba(23,23,28,0.9);
+      font-size: 11px;
+      letter-spacing: 0.14em;
+      text-transform: uppercase;
+      color: var(--ink-muted);
+    }
+
+    .pill-dot {
+      width: 8px;
+      height: 8px;
+      border-radius: 50%;
+      background: radial-gradient(circle at 30% 20%, #fff, #f9eec3 45%, #c9a961 100%);
+      box-shadow: 0 0 0 1px rgba(0,0,0,0.7);
+    }
+
+    .overlay-actions {
+      display: flex;
+      gap: 8px;
+      margin-top: 14px;
+    }
+
+    .hidden {
+      display: none;
+    }
+
+    @media (max-width: 900px) {
+      header {
+        padding: 14px 18px 10px;
+        height: auto;
+      }
+      .wordmark {
+        font-size: 40px;
+      }
+      main {
+        padding: 92px 14px 18px;
+      }
+      .shell {
+        aspect-ratio: 3 / 4;
+      }
+      .side-panel {
+        position: static;
+        width: auto;
+        padding: 0;
+        margin: 0 12px 12px;
+        flex-direction: row;
+        flex-wrap: wrap;
+        justify-content: space-between;
+      }
+      .card {
+        flex: 1;
+        min-width: 180px;
+      }
+      .overlay-inner {
+        max-width: 90%;
+      }
+    }
+
+    @media (max-width: 640px) {
+      .hud {
+        display: none;
+      }
+      .shell {
+        min-height: 360px;
+      }
+      .wordmark {
+        font-size: 40px;
+        letter-spacing: 0.16em;
+      }
+    }
+  </style>
+</head>
+<body>
+  <header>
+    <div class="wordmark-lockup">
+      <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+    </div>
+    <div class="hud">
+      <div class="hud-group">
+        <div class="hud-label">Score</div>
+        <div class="hud-value" id="scoreHud">000</div>
+      </div>
+      <div class="hud-group">
+        <div class="hud-label">Best</div>
+        <div class="hud-value" id="bestHud">000</div>
+      </div>
+      <div class="hud-group">
+        <div class="hud-dot"></div>
+        <div class="hud-label">Tap / Space to jump</div>
+      </div>
+    </div>
+  </header>
+  <main>
+    <div class="shell">
+      <div class="canvas-wrap">
+        <canvas id="gameCanvas"></canvas>
+        <div class="overlay overlay--visible" id="startOverlay">
+          <div class="overlay-inner">
+            <div class="overlay-title">Luxe Roller Run</div>
+            <div class="overlay-sub">
+              Glide your paint roller along the gallery wall, collecting curated wallpapers and gliding past architectural trims.
+            </div>
+            <div class="overlay-metrics">
+              <div>
+                <div class="overlay-metric-label">Best Score</div>
+                <div class="overlay-metric-value" id="bestOverlay">000</div>
+              </div>
+              <div>
+                <div class="overlay-metric-label">Difficulty</div>
+                <div class="overlay-metric-value">Rising Tempo</div>
+              </div>
+            </div>
+            <div class="pill">
+              <span class="pill-dot"></span>
+              <span>Tap / Space / Up to jump</span>
+            </div>
+            <div class="overlay-actions">
+              <button class="btn btn-primary" id="startPlay">
+                <span class="btn-icon"></span>
+                <span>Begin Run</span>
+              </button>
+              <button class="btn btn-ghost" id="startPractice">
+                <span>Practice</span>
+              </button>
+            </div>
+          </div>
+        </div>
+
+        <div class="overlay hidden" id="gameOverOverlay">
+          <div class="overlay-inner">
+            <div class="overlay-title">Wall Scuffed</div>
+            <div class="overlay-sub">
+              The roller clipped a molding. Reset the wall and refine your line.
+            </div>
+            <div class="overlay-metrics">
+              <div>
+                <div class="overlay-metric-label">Run Score</div>
+                <div class="overlay-metric-value" id="runScore">000</div>
+              </div>
+              <div>
+                <div class="overlay-metric-label">Best Score</div>
+                <div class="overlay-metric-value" id="runBest">000</div>
+              </div>
+            </div>
+            <div class="overlay-actions">
+              <button class="btn btn-primary" id="restartBtn">
+                <span class="btn-icon"></span>
+                <span>Run Again</span>
+              </button>
+              <button class="btn btn-ghost" id="resumeBtn">
+                <span>Watch Wall</span>
+              </button>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <aside class="side-panel">
+        <section class="card">
+          <div class="card-label">Controls</div>
+          <div class="card-body">
+            <div class="controls">
+              <span class="key">Tap</span>
+              <span class="key">Space</span>
+              <span class="key">↑</span>
+              <span>Jump</span>
+            </div>
+          </div>
+        </section>
+        <section class="card">
+          <div class="card-label">Palette Styles</div>
+          <div class="card-body">
+            <div class="pattern-row">
+              <div class="swatch swatch--marble" title="Marble Vein"></div>
+              <div class="swatch swatch--geo" title="Art Deco Geo"></div>
+              <div class="swatch swatch--silk" title="Silk Panel"></div>
+            </div>
+          </div>
+        </section>
+      </aside>
+    </div>
+  </main>
+
+  <script>
+    (function() {
+      const canvas = document.getElementById('gameCanvas');
+      const ctx = canvas.getContext('2d');
+
+      function resize() {
+        const rect = canvas.parentElement.getBoundingClientRect();
+        const dpr = window.devicePixelRatio || 1;
+        canvas.width = rect.width * dpr;
+        canvas.height = rect.height * dpr;
+        ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
+      }
+      resize();
+      window.addEventListener('resize', resize);
+
+      const state = {
+        running: false,
+        practice: false,
+        gameOver: false,
+        speed: 4.2,
+        maxSpeed: 10,
+        speedIncrease: 0.00045,
+        gravity: 0.5,
+        jumpVel: -9.6,
+        groundY: 0,
+        roller: { x: 110, y: 0, vy: 0, radius: 20 },
+        collectibles: [],
+        obstacles: [],
+        wallpaperTypes: [
+          { name: 'marble', color: '#f3eadd' },
+          { name: 'geo', color: '#c9a961' },
+          { name: 'silk', color: '#c5b8ff' }
+        ],
+        score: 0,
+        best: 0,
+        lastTime: 0,
+        spawnTimerObs: 0,
+        spawnTimerCol: 0
+      };
+
+      const scoreHud = document.getElementById('scoreHud');
+      const bestHud = document.getElementById('bestHud');
+      const bestOverlay = document.getElementById('bestOverlay');
+      const runScore = document.getElementById('runScore');
+      const runBest = document.getElementById('runBest');
+      const startOverlay = document.getElementById('startOverlay');
+      const gameOverOverlay = document.getElementById('gameOverOverlay');
+
+      function loadBest() {
+        try {
+          const v = localStorage.getItem('dw_runner_best');
+          const n = v ? parseInt(v, 10) : 0;
+          if (!isNaN(n)) state.best = n;
+        } catch(e) {}
+        bestHud.textContent = pad(state.best);
+        bestOverlay.textContent = pad(state.best);
+      }
+
+      function saveBest() {
+        try {
+          localStorage.setItem('dw_runner_best', String(state.best));
+        } catch(e) {}
+      }
+
+      function pad(n) {
+        return String(Math.floor(n)).padStart(3, '0');
+      }
+
+      loadBest();
+
+      function resetRun() {
+        const h = canvas.getBoundingClientRect().height;
+        state.groundY = h * 0.72;
+        state.roller.y = state.groundY - state.roller.radius;
+        state.roller.vy = 0;
+        state.collectibles.length = 0;
+        state.obstacles.length = 0;
+        state.score = 0;
+        state.speed = 4.2;
+        state.spawnTimerObs = 0;
+        state.spawnTimerCol = 0;
+        scoreHud.textContent = pad(0);
+      }
+
+      function startGame(practice) {
+        state.practice = practice;
+        state.running = true;
+        state.gameOver = false;
+        hideOverlay(startOverlay);
+        hideOverlay(gameOverOverlay);
+        resetRun();
+      }
+
+      function showOverlay(el) {
+        el.classList.remove('hidden');
+        requestAnimationFrame(() => el.classList.add('overlay--visible'));
+      }
+
+      function hideOverlay(el) {
+        el.classList.remove('overlay--visible');
+        setTimeout(() => {
+          el.classList.add('hidden');
+        }, 260);
+      }
+
+      function endGame() {
+        state.running = false;
+        state.gameOver = true;
+        runScore.textContent = pad(state.score);
+        if (state.score > state.best) {
+          state.best = state.score;
+          saveBest();
+        }
+        bestHud.textContent = pad(state.best);
+        bestOverlay.textContent = pad(state.best);
+        runBest.textContent = pad(state.best);
+        showOverlay(gameOverOverlay);
+      }
+
+      function spawnObstacle() {
+        const h = canvas.getBoundingClientRect().height;
+        const type = Math.random() < 0.5 ? 'low' : 'tall';
+        const width = type === 'low' ? 30 : 26;
+        const height = type === 'low' ? 30 : 60;
+        const y = state.groundY - height;
+        state.obstacles.push({
+          x: canvas.getBoundingClientRect().width + width,
+          y,
+          width,
+          height,
+          type
+        });
+      }
+
+      function spawnCollectible() {
+        const cType = state.wallpaperTypes[Math.floor(Math.random() * state.wallpaperTypes.length)];
+        const lane = Math.random();
+        const baseY = state.groundY - 40;
+        let y = baseY;
+        if (lane < 0.33) y = baseY - 60;
+        else if (lane < 0.66) y = baseY - 30;
+        const width = 18;
+        const height = 32;
+        state.collectibles.push({
+          x: canvas.getBoundingClientRect().width + width,
+          y,
+          width,
+          height,
+          type: cType
+        });
+      }
+
+      function rollerRect() {
+        const r = state.roller;
+        return {
+          x: r.x - r.radius,
+          y: r.y - r.radius,
+          width: r.radius * 2,
+          height: r.radius * 2
+        };
+      }
+
+      function rectsIntersect(a, b) {
+        return a.x < b.x + b.width &&
+               a.x + a.width > b.x &&
+               a.y < b.y + b.height &&
+               a.y + a.height > b.y;
+      }
+
+      function jump() {
+        if (!state.running) return;
+        if (state.roller.y >= state.groundY - state.roller.radius - 0.5) {
+          state.roller.vy = state.jumpVel;
+        }
+      }
+
+      function drawBackground() {
+        const w = canvas.getBoundingClientRect().width;
+        const h = canvas.getBoundingClientRect().height;
+        const panelHeight = h * 0.65;
+        const baseY = state.groundY - panelHeight + 4;
+
+        const grad = ctx.createLinearGradient(0, baseY, 0, baseY + panelHeight);
+        grad.addColorStop(0, '#25222f');
+        grad.addColorStop(0.4, '#191823');
+        grad.addColorStop(1, '#08070c');
+        ctx.fillStyle = grad;
+        ctx.fillRect(0, baseY, w, panelHeight);
+
+        const seamCount = 7;
+        const seamWidth = w / seamCount;
+        ctx.save();
+        ctx.beginPath();
+        ctx.rect(0, baseY, w, panelHeight);
+        ctx.clip();
+
+        const offset = (Date.now() * 0.02 * state.speed) % seamWidth;
+
+        for (let i = -2; i < seamCount + 2; i++) {
+          const x = i * seamWidth - offset;
+          const panelGrad = ctx.createLinearGradient(x, baseY, x + seamWidth, baseY + panelHeight);
+          panelGrad.addColorStop(0, 'rgba(255,255,255,0.04)');
+          panelGrad.addColorStop(0.5, 'rgba(0,0,0,0.4)');
+          panelGrad.addColorStop(1, 'rgba(255,255,255,0.08)');
+          ctx.fillStyle = panelGrad;
+          ctx.fillRect(x, baseY, seamWidth - 1, panelHeight);
+
+          ctx.strokeStyle = 'rgba(0,0,0,0.8)';
+          ctx.lineWidth = 1;
+          ctx.beginPath();
+          ctx.moveTo(x, baseY);
+          ctx.lineTo(x, baseY + panelHeight);
+          ctx.stroke();
+
+          ctx.strokeStyle = 'rgba(255,255,255,0.08)';
+          ctx.beginPath();
+          ctx.moveTo(x + seamWidth - 1, baseY);
+          ctx.lineTo(x + seamWidth - 1, baseY + panelHeight);
+          ctx.stroke();
+        }
+        ctx.restore();
+
+        ctx.strokeStyle = 'rgba(0,0,0,0.85)';
+        ctx.lineWidth = 2;
+        ctx.beginPath();
+        ctx.moveTo(0, state.groundY + 0.5);
+        ctx.lineTo(w, state.groundY + 0.5);
+        ctx.stroke();
+
+        ctx.strokeStyle = 'rgba(255,255,255,0.06)';
+        ctx.beginPath();
+        ctx.moveTo(0, state.groundY - 2);
+        ctx.lineTo(w, state.groundY - 2);
+        ctx.stroke();
+      }
+
+      function drawCollectible(c) {
+        ctx.save();
+        const { x, y, width, height, type } = c;
+        const radius = 6;
+        ctx.beginPath();
+        ctx.moveTo(x + radius, y);
+        ctx.lineTo(x + width - radius, y);
+        ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
+        ctx.lineTo(x + width, y + height - radius);
+        ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
+        ctx.lineTo(x + radius, y + height);
+        ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
+        ctx.lineTo(x, y + radius);
+        ctx.quadraticCurveTo(x, y, x + radius, y);
+        ctx.closePath();
+
+        let fill;
+        if (type.name === 'marble') {
+          fill = ctx.createLinearGradient(x, y, x + width, y + height);
+          fill.addColorStop(0, '#faf3e8');
+          fill.addColorStop(0.5, '#e1d4c4');
+          fill.addColorStop(1, '#b2a08d');
+        } else if (type.name === 'geo') {
+          fill = ctx.createLinearGradient(x, y, x + width, y + height);
+          fill.addColorStop(0, '#f3e6c5');
+          fill.addColorStop(0.4, '#d7bd7a');
+          fill.addColorStop(1, '#a88437');
+        } else {
+          fill = ctx.createLinearGradient(x, y, x, y + height);
+          fill.addColorStop(0, '#f7f4ff');
+          fill.addColorStop(0.4, '#d0c5ff');
+          fill.addColorStop(1, '#8576c8');
+        }
+        ctx.fillStyle = fill;
+        ctx.fill();
+
+        ctx.strokeStyle = 'rgba(0,0,0,0.7)';
+        ctx.lineWidth = 1;
+        ctx.stroke();
+
+        ctx.beginPath();
+        ctx.moveTo(x + 3, y + 4);
+        ctx.lineTo(x + width - 3, y + 4);
+        ctx.strokeStyle = 'rgba(255,255,255,0.45)';
+        ctx.lineWidth = 1;
+        ctx.stroke();
+
+        if (type.name === 'geo') {
+          ctx.strokeStyle = 'rgba(0,0,0,0.3)';
+          ctx.lineWidth = 0.8;
+          ctx.beginPath();
+          ctx.moveTo(x + 3, y + height * 0.5);
+          ctx.lineTo(x + width - 3, y + height * 0.3);
+          ctx.lineTo(x + width - 5, y + height - 4);
+          ctx.closePath();
+          ctx.stroke();
+        } else if (type.name === 'marble') {
+          ctx.strokeStyle = 'rgba(0,0,0,0.3)';
+          ctx.lineWidth = 1.2;
+          ctx.beginPath();
+          ctx.moveTo(x + 4, y + height - 6);
+          ctx.bezierCurveTo(x + 6, y + height - 10, x + 10, y + height - 3, x + 14, y + height - 8);
+          ctx.bezierCurveTo(x + 18, y + height - 13, x + 20, y + height - 5, x + width - 4, y + height - 10);
+          ctx.stroke();
+        } else {
+          ctx.strokeStyle = 'rgba(255,255,255,0.38)';
+          ctx.lineWidth = 0.9;
+          ctx.beginPath();
+          ctx.moveTo(x + 2, y + height * 0.3);
+          ctx.lineTo(x + width - 2, y + height * 0.7);
+          ctx.stroke();
+        }
+
+        ctx.restore();
+      }
+
+      function drawObstacle(o) {
+        ctx.save();
+        const { x, y, width, height, type } = o;
+        const radius = 6;
+        ctx.beginPath();
+        ctx.moveTo(x + radius, y);
+        ctx.lineTo(x + width - radius, y);
+        ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
+        ctx.lineTo(x + width, y + height - radius);
+        ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
+        ctx.lineTo(x + radius, y + height);
+        ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
+        ctx.lineTo(x, y + radius);
+        ctx.quadraticCurveTo(x, y, x + radius, y);
+        ctx.closePath();
+
+        const grad = ctx.createLinearGradient(x, y, x + width, y + height);
+        if (type === 'low') {
+          grad.addColorStop(0, '#2a272c');
+          grad.addColorStop(0.4, '#17141a');
+          grad.addColorStop(1, '#060509');
+        } else {
+          grad.addColorStop(0, '#25222b');
+          grad.addColorStop(1, '#0b0a10');
+        }
+        ctx.fillStyle = grad;
+        ctx.fill();
+
+        ctx.strokeStyle = 'rgba(0,0,0,0.9)';
+        ctx.lineWidth = 1;
+        ctx.stroke();
+
+        const trimGrad = ctx.createLinearGradient(x, y, x, y + 8);
+        trimGrad.addColorStop(0, 'rgba(255,255,255,0.3)');
+        trimGrad.addColorStop(1, 'rgba(255,255,255,0.05)');
+        ctx.fillStyle = trimGrad;
+        ctx.fillRect(x + 2, y + 2, width - 4, 6);
+      }
+
+      function drawRoller() {
+        const r = state.roller;
+        ctx.save();
+
+        const handleX = r.x - 18;
+        const handleY = r.y + 12;
+        ctx.strokeStyle = '#c9a961';
+        ctx.lineWidth = 2;
+        ctx.beginPath();
+        ctx.moveTo(handleX, handleY);
+        ctx.lineTo(handleX - 8, handleY + 14);
+        ctx.stroke();
+        ctx.lineWidth = 4;
+        ctx.strokeStyle = '#ded3b3';
+        ctx.beginPath();
+        ctx.moveTo(handleX - 8, handleY + 14);
+        ctx.lineTo(handleX - 18, handleY + 26);
+        ctx.stroke();
+
+        ctx.fillStyle = '#c9a961';
+        ctx.beginPath();
+        ctx.arc(r.x, r.y, r.radius, 0, Math.PI * 2);
+        ctx.fill();
+
+        const innerGrad = ctx.createRadialGradient(r.x - 6, r.y - 8, 4, r.x, r.y, r.radius);
+        innerGrad.addColorStop(0, '#fff8d8');
+        innerGrad.addColorStop(0.4, '#f2dd9d');
+        innerGrad.addColorStop(1, '#7d6a45');
+        ctx.fillStyle = innerGrad;
+        ctx.beginPath();
+        ctx.arc(r.x, r.y, r.radius - 4, 0, Math.PI * 2);
+        ctx.fill();
+
+        ctx.fillStyle = '#0d0d0f';
+        ctx.beginPath();
+        ctx.arc(r.x, r.y, 4, 0, Math.PI * 2);
+        ctx.fill();
+
+        ctx.strokeStyle = 'rgba(255,255,255,0.5)';
+        ctx.lineWidth = 1;
+        ctx.beginPath();
+        ctx.arc(r.x - 4, r.y - 6, r.radius - 7, -Math.PI * 0.3, -Math.PI * 0.9, true);
+        ctx.stroke();
+
+        const trailLength = 100;
+        const trailHeight = 14;
+        const tx = r.x - r.radius - 4;
+        const ty = r.y - trailHeight / 2;
+        const grad = ctx.createLinearGradient(tx - trailLength, ty, tx, ty);
+        grad.addColorStop(0, 'rgba(201,169,97,0)');
+        grad.addColorStop(0.3, 'rgba(201,169,97,0.2)');
+        grad.addColorStop(1, 'rgba(201,169,97,0.8)');
+        ctx.fillStyle = grad;
+        ctx.beginPath();
+        ctx.moveTo(tx, ty);
+        ctx.lineTo(tx - trailLength, ty);
+        ctx.lineTo(tx - trailLength, ty + trailHeight);
+        ctx.lineTo(tx, ty + trailHeight);
+        ctx.closePath();
+        ctx.fill();
+
+        ctx.restore();
+      }
+
+      function update(dt) {
+        const w = canvas.getBoundingClientRect().width;
+        const speedPx = state.speed * (dt / 16.67);
+
+        state.speed = Math.min(state.maxSpeed, state.speed + state.speedIncrease * dt);
+
+        const r = state.roller;
+        r.vy += state.gravity * (dt / 16.67);
+        r.y += r.vy;
+        if (r.y >= state.groundY - r.radius) {
+          r.y = state.groundY - r.radius;
+          r.vy = 0;
+        }
+
+        state.spawnTimerObs += dt;
+        if (state.spawnTimerObs > 800 + Math.random() * 700) {
+          spawnObstacle();
+          state.spawnTimerObs = 0;
+        }
+        state.spawnTimerCol += dt;
+        if (state.spawnTimerCol > 650 + Math.random() * 650) {
+          spawnCollectible();
+          state.spawnTimerCol = 0;
+        }
+
+        const rr = rollerRect();
+
+        for (let i = state.obstacles.length - 1; i >= 0; i--) {
+          const o = state.obstacles[i];
+          o.x -= speedPx;
+          if (!state.practice && rectsIntersect(rr, o)) {
+            endGame();
+            return;
+          }
+          if (o.x + o.width < -40) {
+            state.obstacles.splice(i, 1);
+          }
+        }
+
+        for (let i = state.collectibles.length - 1; i >= 0; i--) {
+          const c = state.collectibles[i];
+          c.x -= speedPx;
+          if (rectsIntersect(rr, c)) {
+            state.collectibles.splice(i, 1);
+            state.score += 5;
+            scoreHud.textContent = pad(state.score);
+            continue;
+          }
+          if (c.x + c.width < -40) {
+            state.collectibles.splice(i, 1);
+          }
+        }
+
+        if (state.running) {
+          state.score += 0.03 * (dt / 16.67);
+          scoreHud.textContent = pad(state.score);
+        }
+      }
+
+      function render() {
+        const w = canvas.getBoundingClientRect().width;
+        const h = canvas.getBoundingClientRect().height;
+        ctx.clearRect(0, 0, w, h);
+        drawBackground();
+
+        ctx.save();
+        const glowGrad = ctx.createRadialGradient(
+          state.roller.x - 30, state.roller.y - 60, 10,
+          state.roller.x - 30, state.roller.y - 60, 180
+        );
+        glowGrad.addColorStop(0, 'rgba(236,217,155,0.22)');
+        glowGrad.addColorStop(1, 'rgba(236,217,155,0)');
+        ctx.fillStyle = glowGrad;
+        ctx.fillRect(0, 0, w, h);
+        ctx.restore();
+
+        for (const c of state.collectibles) drawCollectible(c);
+        for (const o of state.obstacles) drawObstacle(o);
+        drawRoller();
+      }
+
+      function loop(timestamp) {
+        if (!state.lastTime) state.lastTime = timestamp;
+        const dt = Math.min(40, timestamp - state.lastTime);
+        state.lastTime = timestamp;
+
+        if (state.running) {
+          update(dt);
+        }
+        render();
+
+        requestAnimationFrame(loop);
+      }
+
+      requestAnimationFrame(loop);
+
+      function handleKey(e) {
+        if (e.code === 'Space' || e.code === 'ArrowUp') {
+          e.preventDefault();
+          if (!state.running && !state.gameOver) {
+            startGame(false);
+          } else if (!state.running && state.gameOver) {
+            startGame(false);
+          } else {
+            jump();
+          }
+        }
+      }
+
+      function handlePointer(e) {
+        const rect = canvas.getBoundingClientRect();
+        const x = (e.touches ? e.touches[0].clientX : e.clientX);
+        const y = (e.touches ? e.touches[0].clientY : e.clientY);
+        if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
+          if (!state.running && !state.gameOver) {
+            startGame(false);
+          } else if (!state.running && state.gameOver) {
+            startGame(false);
+          } else {
+            jump();
+          }
+        }
+      }
+
+      window.addEventListener('keydown', handleKey);
+      window.addEventListener('mousedown', handlePointer);
+      window.addEventListener('touchstart', handlePointer, { passive: false });
+
+      document.getElementById('startPlay').addEventListener('click', function() {
+        startGame(false);
+      });
+      document.getElementById('startPractice').addEventListener('click', function() {
+        startGame(true);
+      });
+      document.getElementById('restartBtn').addEventListener('click', function() {
+        startGame(false);
+      });
+      document.getElementById('resumeBtn').addEventListener('click', function() {
+        hideOverlay(gameOverOverlay);
+        state.gameOver = false;
+      });
+    })();
+  </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/57af693363f2/gpt.png b/data/artifacts/57af693363f2/gpt.png
new file mode 100644
index 0000000..562f86c
Binary files /dev/null and b/data/artifacts/57af693363f2/gpt.png differ
diff --git a/data/artifacts/57af693363f2/grok.html b/data/artifacts/57af693363f2/grok.html
new file mode 100644
index 0000000..76eeea3
--- /dev/null
+++ b/data/artifacts/57af693363f2/grok.html
@@ -0,0 +1,1233 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Roll</title>
+<style>
+:root {
+  --bg: #f7f3eb;
+  --bg-deep: #efe8dc;
+  --surface: #fffcf6;
+  --ink: #1c1a17;
+  --ink-soft: #3a3530;
+  --muted: #8a8276;
+  --accent: #b8952c;
+  --accent-deep: #8a6e1f;
+  --accent-soft: rgba(184, 149, 44, 0.14);
+  --line: rgba(28, 26, 23, 0.12);
+  --line-strong: rgba(28, 26, 23, 0.22);
+  --shadow: 0 12px 40px rgba(28, 26, 23, 0.08);
+  --shadow-soft: 0 4px 16px rgba(28, 26, 23, 0.06);
+  --ease: cubic-bezier(.22, .9, .24, 1);
+  --ease-out: cubic-bezier(.22, 1, .36, 1);
+  --ease-pop: cubic-bezier(.34, 1.56, .64, 1);
+  --serif: 'Didot', 'Bodoni MT', 'Playfair Display', 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
+  --sans: 'Avenir Next', 'Century Gothic', 'Helvetica Neue', Futura, sans-serif;
+  --radius: 14px;
+  --radius-sm: 6px;
+  --header-h: 72px;
+}
+
+*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+
+html, body {
+  height: 100%;
+  overflow: hidden;
+  background: var(--bg);
+  color: var(--ink);
+  font-family: var(--sans);
+  font-size: 16px;
+  line-height: 1.5;
+  -webkit-font-smoothing: antialiased;
+}
+
+/* —— Fixed brand header —— */
+.site-header {
+  position: fixed;
+  top: 0; left: 0; right: 0;
+  z-index: 100;
+  height: var(--header-h);
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 28px;
+  background: rgba(247, 243, 235, 0.92);
+  backdrop-filter: blur(12px);
+  border-bottom: 1px solid var(--line);
+}
+
+.wordmark {
+  font-family: var(--serif);
+  font-size: clamp(18px, 2.6vw, 28px);
+  font-weight: 500;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  color: var(--ink);
+  line-height: 1.15;
+  white-space: normal;
+  max-width: min(520px, 58vw);
+}
+
+.header-meta {
+  display: flex;
+  align-items: center;
+  gap: 28px;
+  font-family: var(--sans);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.16em;
+  text-transform: uppercase;
+  color: var(--muted);
+}
+
+.header-meta .stat {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-end;
+  gap: 2px;
+}
+
+.header-meta .stat b {
+  color: var(--ink);
+  font-weight: 600;
+  font-size: 13px;
+  letter-spacing: 0.12em;
+  font-variant-numeric: tabular-nums;
+}
+
+.header-meta .stat b.accent { color: var(--accent-deep); }
+
+/* —— Stage —— */
+.stage {
+  position: fixed;
+  inset: var(--header-h) 0 0 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background:
+    radial-gradient(ellipse 80% 60% at 50% 0%, rgba(184,149,44,0.06), transparent 60%),
+    linear-gradient(180deg, var(--bg) 0%, var(--bg-deep) 100%);
+  padding: 24px;
+}
+
+.canvas-wrap {
+  position: relative;
+  width: min(960px, 100%);
+  aspect-ratio: 16 / 9;
+  max-height: calc(100vh - var(--header-h) - 48px);
+  background: var(--surface);
+  border: 1px solid var(--line);
+  border-radius: var(--radius);
+  box-shadow: var(--shadow);
+  overflow: hidden;
+}
+
+canvas {
+  display: block;
+  width: 100%;
+  height: 100%;
+  cursor: pointer;
+}
+
+/* —— Overlays —— */
+.overlay {
+  position: absolute;
+  inset: 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 40px 32px;
+  background: rgba(247, 243, 235, 0.88);
+  backdrop-filter: blur(10px);
+  opacity: 0;
+  pointer-events: none;
+  transition: opacity 0.45s var(--ease-out);
+  text-align: center;
+  z-index: 10;
+}
+
+.overlay.is-on {
+  opacity: 1;
+  pointer-events: auto;
+}
+
+.overlay-kicker {
+  font-family: var(--sans);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.2em;
+  text-transform: uppercase;
+  color: var(--accent-deep);
+  margin-bottom: 16px;
+}
+
+.overlay h1, .overlay h2 {
+  font-family: var(--serif);
+  font-weight: 500;
+  color: var(--ink);
+  letter-spacing: 0.02em;
+  line-height: 1.1;
+}
+
+.overlay h1 {
+  font-size: clamp(36px, 5vw, 50px);
+  margin-bottom: 12px;
+}
+
+.overlay h2 {
+  font-size: clamp(28px, 4vw, 38px);
+  margin-bottom: 12px;
+}
+
+.overlay p {
+  font-size: 15px;
+  color: var(--ink-soft);
+  max-width: 36ch;
+  margin: 0 auto 28px;
+  line-height: 1.6;
+}
+
+.overlay .score-line {
+  font-family: var(--sans);
+  font-size: 12px;
+  font-weight: 600;
+  letter-spacing: 0.16em;
+  text-transform: uppercase;
+  color: var(--muted);
+  margin-bottom: 32px;
+}
+
+.overlay .score-line strong {
+  color: var(--ink);
+  font-size: 18px;
+  letter-spacing: 0.08em;
+  display: block;
+  margin-top: 6px;
+  font-variant-numeric: tabular-nums;
+}
+
+.btn {
+  appearance: none;
+  border: 1px solid var(--ink);
+  background: var(--ink);
+  color: var(--bg);
+  font-family: var(--sans);
+  font-size: 12px;
+  font-weight: 600;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  padding: 16px 36px;
+  border-radius: 999px;
+  cursor: pointer;
+  transition: transform 0.35s var(--ease-pop), background 0.25s var(--ease), color 0.25s var(--ease), box-shadow 0.25s var(--ease);
+  box-shadow: var(--shadow-soft);
+}
+
+.btn:hover {
+  background: var(--accent);
+  border-color: var(--accent);
+  color: var(--ink);
+  transform: translateY(-2px);
+}
+
+.btn:active { transform: translateY(0) scale(0.98); }
+
+.hint {
+  margin-top: 28px;
+  font-size: 11px;
+  letter-spacing: 0.14em;
+  text-transform: uppercase;
+  color: var(--muted);
+}
+
+.swatch-row {
+  display: flex;
+  gap: 10px;
+  justify-content: center;
+  margin-bottom: 28px;
+}
+
+.swatch {
+  width: 36px;
+  height: 36px;
+  border-radius: 50%;
+  border: 1px solid var(--line-strong);
+  box-shadow: var(--shadow-soft);
+}
+
+/* pattern previews via CSS */
+.swatch.damask {
+  background:
+    radial-gradient(circle at 30% 30%, var(--accent) 2px, transparent 2.5px),
+    radial-gradient(circle at 70% 70%, var(--accent) 2px, transparent 2.5px),
+    #2c3a4a;
+}
+.swatch.chinoiserie {
+  background:
+    linear-gradient(135deg, transparent 45%, #c45c4a 45%, #c45c4a 55%, transparent 55%),
+    linear-gradient(45deg, transparent 45%, #c45c4a 45%, #c45c4a 55%, transparent 55%),
+    #f0e6d4;
+}
+.swatch.art-deco {
+  background:
+    repeating-linear-gradient(90deg, #1c1a17 0 3px, transparent 3px 8px),
+    repeating-linear-gradient(0deg, #1c1a17 0 3px, transparent 3px 8px),
+    var(--accent);
+}
+.swatch.toile {
+  background:
+    radial-gradient(ellipse 40% 50% at 50% 50%, transparent 40%, #4a6b5a 41%, #4a6b5a 48%, transparent 49%),
+    #e8dfd0;
+}
+.swatch.geometric {
+  background:
+    conic-gradient(from 45deg, #5c3d6e 0 25%, #d4c4a8 0 50%, #5c3d6e 0 75%, #d4c4a8 0),
+    #5c3d6e;
+  background-size: 12px 12px;
+}
+
+@media (max-width: 640px) {
+  .site-header { padding: 0 16px; height: 64px; }
+  :root { --header-h: 64px; }
+  .wordmark { font-size: 15px; letter-spacing: 0.14em; max-width: 48vw; }
+  .header-meta { gap: 14px; }
+  .stage { padding: 12px; }
+}
+</style>
+</head>
+<body>
+
+<header class="site-header">
+  <div class="wordmark">Designer<br>Wallcoverings</div>
+  <div class="header-meta">
+    <div class="stat">Score <b id="liveScore">0</b></div>
+    <div class="stat">Best <b class="accent" id="liveBest">0</b></div>
+  </div>
+</header>
+
+<main class="stage">
+  <div class="canvas-wrap">
+    <canvas id="game" width="960" height="540"></canvas>
+
+    <div class="overlay is-on" id="startOverlay">
+      <div class="overlay-kicker">An endless atelier run</div>
+      <h1>Paper the Wall</h1>
+      <p>Guide the paint roller. Collect wallpaper rolls — each style a different jewel — and leap the scaffolding.</p>
+      <div class="swatch-row" aria-hidden="true">
+        <div class="swatch damask"></div>
+        <div class="swatch chinoiserie"></div>
+        <div class="swatch art-deco"></div>
+        <div class="swatch toile"></div>
+        <div class="swatch geometric"></div>
+      </div>
+      <button class="btn" id="startBtn" type="button">Begin</button>
+      <div class="hint">Space / tap to jump</div>
+    </div>
+
+    <div class="overlay" id="overOverlay">
+      <div class="overlay-kicker">Session complete</div>
+      <h2>Wall Interrupted</h2>
+      <div class="score-line">Final score <strong id="finalScore">0</strong></div>
+      <button class="btn" id="restartBtn" type="button">Roll Again</button>
+      <div class="hint">Space / tap to restart</div>
+    </div>
+  </div>
+</main>
+
+<script>
+(function () {
+  'use strict';
+
+  const W = 960, H = 540;
+  const canvas = document.getElementById('game');
+  const ctx = canvas.getContext('2d');
+  const liveScore = document.getElementById('liveScore');
+  const liveBest = document.getElementById('liveBest');
+  const finalScore = document.getElementById('finalScore');
+  const startOverlay = document.getElementById('startOverlay');
+  const overOverlay = document.getElementById('overOverlay');
+  const startBtn = document.getElementById('startBtn');
+  const restartBtn = document.getElementById('restartBtn');
+
+  const BEST_KEY = 'dw_roller_best';
+  let best = parseInt(localStorage.getItem(BEST_KEY) || '0', 10) || 0;
+  liveBest.textContent = String(best);
+
+  // Palette (mirrors CSS tokens)
+  const C = {
+    bg: '#f7f3eb',
+    surface: '#fffcf6',
+    wall: '#ebe4d6',
+    wallDeep: '#e0d6c4',
+    ink: '#1c1a17',
+    inkSoft: '#3a3530',
+    muted: '#8a8276',
+    accent: '#b8952c',
+    accentDeep: '#8a6e1f',
+    cream: '#f5efe3',
+    rollerBody: '#2a2622',
+    rollerMetal: '#c9a961',
+    ground: '#d9cfc0',
+    shadow: 'rgba(28,26,23,0.12)'
+  };
+
+  // Wallpaper style definitions — visually distinct motifs
+  const STYLES = [
+    {
+      name: 'damask',
+      base: '#2c3a4a',
+      ink: '#c9a961',
+      draw(g, s) {
+        g.fillStyle = this.base;
+        g.fillRect(-s, -s, s * 2, s * 2);
+        g.fillStyle = this.ink;
+        // fleur motif
+        for (let i = 0; i < 3; i++) {
+          const a = (i / 3) * Math.PI * 2;
+          g.beginPath();
+          g.ellipse(Math.cos(a) * s * 0.35, Math.sin(a) * s * 0.35, s * 0.18, s * 0.1, a, 0, Math.PI * 2);
+          g.fill();
+        }
+        g.beginPath();
+        g.arc(0, 0, s * 0.12, 0, Math.PI * 2);
+        g.fill();
+      }
+    },
+    {
+      name: 'chinoiserie',
+      base: '#f0e6d4',
+      ink: '#c45c4a',
+      draw(g, s) {
+        g.fillStyle = this.base;
+        g.fillRect(-s, -s, s * 2, s * 2);
+        g.strokeStyle = this.ink;
+        g.lineWidth = 2;
+        // branch + blossom
+        g.beginPath();
+        g.moveTo(-s * 0.6, s * 0.5);
+        g.quadraticCurveTo(-s * 0.1, -s * 0.2, s * 0.5, -s * 0.55);
+        g.stroke();
+        g.fillStyle = this.ink;
+        [[0.1, -0.15], [0.35, -0.4], [-0.2, 0.15]].forEach(([x, y]) => {
+          g.beginPath();
+          g.arc(x * s, y * s, s * 0.14, 0, Math.PI * 2);
+          g.fill();
+          g.fillStyle = this.base;
+          g.beginPath();
+          g.arc(x * s, y * s, s * 0.05, 0, Math.PI * 2);
+          g.fill();
+          g.fillStyle = this.ink;
+        });
+      }
+    },
+    {
+      name: 'artdeco',
+      base: '#1c1a17',
+      ink: '#c9a961',
+      draw(g, s) {
+        g.fillStyle = this.base;
+        g.fillRect(-s, -s, s * 2, s * 2);
+        g.strokeStyle = this.ink;
+        g.lineWidth = 1.5;
+        // sunburst
+        for (let i = 0; i < 8; i++) {
+          const a = (i / 8) * Math.PI - Math.PI / 2;
+          g.beginPath();
+          g.moveTo(0, s * 0.5);
+          g.lineTo(Math.cos(a) * s * 0.85, Math.sin(a) * s * 0.85 + s * 0.15);
+          g.stroke();
+        }
+        g.beginPath();
+        g.arc(0, s * 0.5, s * 0.18, Math.PI, 0);
+        g.stroke();
+        g.strokeRect(-s * 0.7, -s * 0.7, s * 1.4, s * 1.4);
+      }
+    },
+    {
+      name: 'toile',
+      base: '#e8dfd0',
+      ink: '#4a6b5a',
+      draw(g, s) {
+        g.fillStyle = this.base;
+        g.fillRect(-s, -s, s * 2, s * 2);
+        g.strokeStyle = this.ink;
+        g.fillStyle = this.ink;
+        g.lineWidth = 1.5;
+        // pastoral oval scene
+        g.beginPath();
+        g.ellipse(0, 0, s * 0.55, s * 0.7, 0, 0, Math.PI * 2);
+        g.stroke();
+        // little tree
+        g.beginPath();
+        g.moveTo(0, s * 0.35);
+        g.lineTo(0, -s * 0.05);
+        g.stroke();
+        g.beginPath();
+        g.arc(0, -s * 0.2, s * 0.22, 0, Math.PI * 2);
+        g.stroke();
+        // ground line
+        g.beginPath();
+        g.moveTo(-s * 0.4, s * 0.35);
+        g.quadraticCurveTo(0, s * 0.45, s * 0.4, s * 0.35);
+        g.stroke();
+      }
+    },
+    {
+      name: 'geometric',
+      base: '#5c3d6e',
+      ink: '#d4c4a8',
+      draw(g, s) {
+        g.fillStyle = this.base;
+        g.fillRect(-s, -s, s * 2, s * 2);
+        g.fillStyle = this.ink;
+        // tessellated diamonds
+        const drawDia = (x, y, r) => {
+          g.beginPath();
+          g.moveTo(x, y - r);
+          g.lineTo(x + r * 0.7, y);
+          g.lineTo(x, y + r);
+          g.lineTo(x - r * 0.7, y);
+          g.closePath();
+          g.fill();
+        };
+        drawDia(0, 0, s * 0.55);
+        g.fillStyle = this.base;
+        drawDia(0, 0, s * 0.28);
+        g.fillStyle = this.ink;
+        drawDia(-s * 0.55, -s * 0.55, s * 0.22);
+        drawDia(s * 0.55, -s * 0.55, s * 0.22);
+        drawDia(-s * 0.55, s * 0.55, s * 0.22);
+        drawDia(s * 0.55, s * 0.55, s * 0.22);
+      }
+    }
+  ];
+
+  // Game state
+  let running = false;
+  let gameOver = false;
+  let score = 0;
+  let speed = 5.2;
+  const maxSpeed = 14;
+  let distance = 0;
+  let spawnTimer = 0;
+  let decorOffset = 0;
+  let particles = [];
+  let entities = [];
+  let shake = 0;
+  let flash = 0;
+  let wallPaint = []; // painted segments behind roller
+  let raf = 0;
+  let lastT = 0;
+
+  // Player — paint roller
+  const player = {
+    x: 160,
+    y: 0,
+    w: 54,
+    h: 70,
+    vy: 0,
+    onGround: true,
+    rot: 0,
+    jumpCount: 0
+  };
+
+  const GROUND_Y = H - 78;
+  const GRAVITY = 0.72;
+  const JUMP_V = -13.8;
+
+  function resetGame() {
+    score = 0;
+    speed = 5.2;
+    distance = 0;
+    spawnTimer = 40;
+    decorOffset = 0;
+    particles = [];
+    entities = [];
+    shake = 0;
+    flash = 0;
+    wallPaint = [];
+    player.y = GROUND_Y - player.h;
+    player.vy = 0;
+    player.onGround = true;
+    player.rot = 0;
+    player.jumpCount = 0;
+    gameOver = false;
+    liveScore.textContent = '0';
+    // seed a few early collectibles
+    for (let i = 0; i < 3; i++) {
+      spawnCollectible(W + 200 + i * 280);
+    }
+  }
+
+  function spawnCollectible(x) {
+    const style = STYLES[(Math.random() * STYLES.length) | 0];
+    const lane = Math.random() < 0.35 ? 'high' : 'mid';
+    entities.push({
+      type: 'roll',
+      x: x,
+      y: lane === 'high' ? GROUND_Y - 200 : GROUND_Y - 120,
+      r: 22,
+      style,
+      rot: Math.random() * Math.PI * 2,
+      bob: Math.random() * Math.PI * 2,
+      taken: false
+    });
+  }
+
+  function spawnObstacle(x) {
+    const kind = Math.random();
+    if (kind < 0.4) {
+      // low crate / bucket
+      entities.push({
+        type: 'obs',
+        kind: 'crate',
+        x, y: GROUND_Y - 48,
+        w: 44, h: 48
+      });
+    } else if (kind < 0.7) {
+      // tall ladder / scaffolding
+      entities.push({
+        type: 'obs',
+        kind: 'scaffold',
+        x, y: GROUND_Y - 110,
+        w: 36, h: 110
+      });
+    } else {
+      // hanging dropcloth — must duck by timing (it's mid-air low gap... actually it's hanging so jump over low or it's high obstacle)
+      entities.push({
+        type: 'obs',
+        kind: 'hang',
+        x, y: GROUND_Y - 200,
+        w: 50, h: 90
+      });
+    }
+  }
+
+  function jump() {
+    if (!running) return;
+    if (gameOver) return;
+    if (player.jumpCount < 2) {
+      player.vy = JUMP_V * (player.jumpCount === 0 ? 1 : 0.88);
+      player.onGround = false;
+      player.jumpCount++;
+      // dust
+      for (let i = 0; i < 6; i++) {
+        particles.push({
+          x: player.x + player.w * 0.5,
+          y: GROUND_Y - 4,
+          vx: (Math.random() - 0.5) * 3,
+          vy: -Math.random() * 2,
+          life: 1,
+          r: 2 + Math.random() * 3,
+          col: C.muted
+        });
+      }
+    }
+  }
+
+  function endGame() {
+    gameOver = true;
+    running = false;
+    shake = 10;
+    flash = 1;
+    if (score > best) {
+      best = score;
+      localStorage.setItem(BEST_KEY, String(best));
+      liveBest.textContent = String(best);
+    }
+    finalScore.textContent = String(score);
+    overOverlay.classList.add('is-on');
+  }
+
+  function startGame() {
+    startOverlay.classList.remove('is-on');
+    overOverlay.classList.remove('is-on');
+    resetGame();
+    running = true;
+    lastT = performance.now();
+    cancelAnimationFrame(raf);
+    raf = requestAnimationFrame(loop);
+  }
+
+  // Input
+  function onAction(e) {
+    if (e.type === 'keydown' && e.code !== 'Space' && e.key !== ' ') return;
+    if (e.type === 'keydown') e.preventDefault();
+    if (!running && !gameOver && startOverlay.classList.contains('is-on')) {
+      startGame();
+      return;
+    }
+    if (gameOver && overOverlay.classList.contains('is-on')) {
+      startGame();
+      return;
+    }
+    jump();
+  }
+
+  window.addEventListener('keydown', onAction);
+  canvas.addEventListener('pointerdown', onAction);
+  startBtn.addEventListener('click', (e) => { e.stopPropagation(); startGame(); });
+  restartBtn.addEventListener('click', (e) => { e.stopPropagation(); startGame(); });
+
+  // —— Drawing helpers ——
+  function roundRect(x, y, w, h, r) {
+    const rr = Math.min(r, w / 2, h / 2);
+    ctx.beginPath();
+    ctx.moveTo(x + rr, y);
+    ctx.arcTo(x + w, y, x + w, y + h, rr);
+    ctx.arcTo(x + w, y + h, x, y + h, rr);
+    ctx.arcTo(x, y + h, x, y, rr);
+    ctx.arcTo(x, y, x + w, y, rr);
+    ctx.closePath();
+  }
+
+  function drawBackground() {
+    // wall field
+    const g = ctx.createLinearGradient(0, 0, 0, H);
+    g.addColorStop(0, '#f3eee4');
+    g.addColorStop(1, C.wall);
+    ctx.fillStyle = g;
+    ctx.fillRect(0, 0, W, H);
+
+    // subtle vertical paneling lines
+    ctx.strokeStyle = 'rgba(28,26,23,0.04)';
+    ctx.lineWidth = 1;
+    const panelW = 80;
+    const off = -(decorOffset * 0.3) % panelW;
+    for (let x = off; x < W + panelW; x += panelW) {
+      ctx.beginPath();
+      ctx.moveTo(x, 0);
+      ctx.lineTo(x, GROUND_Y);
+      ctx.stroke();
+    }
+
+    // painted trail behind player (collected wallpaper applied)
+    wallPaint.forEach(p => {
+      ctx.save();
+      ctx.globalAlpha = p.a;
+      ctx.translate(p.x, p.y);
+      p.style.draw(ctx, p.s);
+      ctx.restore();
+    });
+
+    // chair rail / dado
+    ctx.fillStyle = C.wallDeep;
+    ctx.fillRect(0, GROUND_Y - 14, W, 6);
+    ctx.fillStyle = 'rgba(28,26,23,0.06)';
+    ctx.fillRect(0, GROUND_Y - 14, W, 1);
+
+    // floor
+    const fg = ctx.createLinearGradient(0, GROUND_Y, 0, H);
+    fg.addColorStop(0, '#d4c9b6');
+    fg.addColorStop(1, '#c4b8a2');
+    ctx.fillStyle = fg;
+    ctx.fillRect(0, GROUND_Y, W, H - GROUND_Y);
+
+    // floor boards
+    ctx.strokeStyle = 'rgba(28,26,23,0.07)';
+    ctx.lineWidth = 1;
+    const board = 48;
+    const bo = -(decorOffset) % board;
+    for (let x = bo; x < W + board; x += board) {
+      ctx.beginPath();
+      ctx.moveTo(x, GROUND_Y);
+      ctx.lineTo(x, H);
+      ctx.stroke();
+    }
+    // floor highlight line
+    ctx.strokeStyle = 'rgba(255,252,246,0.35)';
+    ctx.beginPath();
+    ctx.moveTo(0, GROUND_Y + 1);
+    ctx.lineTo(W, GROUND_Y + 1);
+    ctx.stroke();
+  }
+
+  function drawRoller(p) {
+    const cx = p.x + p.w * 0.5;
+    const cy = p.y + p.h * 0.55;
+    ctx.save();
+    ctx.translate(cx, cy);
+    // soft contact shadow
+    ctx.fillStyle = 'rgba(28,26,23,0.12)';
+    ctx.beginPath();
+    ctx.ellipse(0, p.h * 0.45 + (p.onGround ? 0 : 4), 22, 6, 0, 0, Math.PI * 2);
+    ctx.fill();
+
+    ctx.rotate(p.rot);
+
+    // handle shaft
+    ctx.strokeStyle = C.rollerMetal;
+    ctx.lineWidth = 4;
+    ctx.lineCap = 'round';
+    ctx.beginPath();
+    ctx.moveTo(0, -8);
+    ctx.lineTo(0, -38);
+    ctx.stroke();
+
+    // handle grip
+    ctx.fillStyle = C.ink;
+    roundRect(-5, -52, 10, 18, 3);
+    ctx.fill();
+    // gold ferrule
+    ctx.fillStyle = C.accent;
+    roundRect(-6, -36, 12, 5, 1);
+    ctx.fill();
+
+    // roller frame
+    ctx.strokeStyle = C.rollerMetal;
+    ctx.lineWidth = 3;
+    ctx.beginPath();
+    ctx.moveTo(-22, -8);
+    ctx.lineTo(22, -8);
+    ctx.stroke();
+    ctx.beginPath();
+    ctx.moveTo(-22, -8);
+    ctx.lineTo(-22, 8);
+    ctx.moveTo(22, -8);
+    ctx.lineTo(22, 8);
+    ctx.stroke();
+
+    // nap cylinder
+    const rg = ctx.createLinearGradient(-22, 0, 22, 0);
+    rg.addColorStop(0, '#3d3832');
+    rg.addColorStop(0.5, '#5a534a');
+    rg.addColorStop(1, '#3d3832');
+    ctx.fillStyle = rg;
+    roundRect(-24, 4, 48, 28, 10);
+    ctx.fill();
+    // nap texture lines
+    ctx.strokeStyle = 'rgba(245,242,234,0.08)';
+    ctx.lineWidth = 1;
+    for (let i = -18; i <= 18; i += 6) {
+      ctx.beginPath();
+      ctx.moveTo(i, 8);
+      ctx.lineTo(i, 28);
+      ctx.stroke();
+    }
+    // gold end caps
+    ctx.fillStyle = C.accent;
+    ctx.beginPath();
+    ctx.arc(-24, 18, 7, 0, Math.PI * 2);
+    ctx.arc(24, 18, 7, 0, Math.PI * 2);
+    ctx.fill();
+    ctx.fillStyle = C.accentDeep;
+    ctx.beginPath();
+    ctx.arc(-24, 18, 3, 0, Math.PI * 2);
+    ctx.arc(24, 18, 3, 0, Math.PI * 2);
+    ctx.fill();
+
+    // paint drip accent
+    ctx.fillStyle = C.accent;
+    ctx.globalAlpha = 0.85;
+    ctx.beginPath();
+    ctx.ellipse(8, 34, 4, 6, 0, 0, Math.PI * 2);
+    ctx.fill();
+    ctx.globalAlpha = 1;
+
+    ctx.restore();
+  }
+
+  function drawEntity(e, t) {
+    if (e.type === 'roll') {
+      const bob = Math.sin(t * 0.004 + e.bob) * 5;
+      const x = e.x;
+      const y = e.y + bob;
+      ctx.save();
+      // glow
+      ctx.shadowColor = 'rgba(184,149,44,0.35)';
+      ctx.shadowBlur = 16;
+      ctx.translate(x, y);
+      ctx.rotate(e.rot);
+      // outer ring (tube)
+      ctx.fillStyle = e.style.base;
+      ctx.beginPath();
+      ctx.arc(0, 0, e.r + 4, 0, Math.PI * 2);
+      ctx.fill();
+      // pattern face
+      ctx.save();
+      ctx.beginPath();
+      ctx.arc(0, 0, e.r, 0, Math.PI * 2);
+      ctx.clip();
+      e.style.draw(ctx, e.r);
+      ctx.restore();
+      // cardboard tube hole
+      ctx.fillStyle = '#c4b49a';
+      ctx.beginPath();
+      ctx.arc(0, 0, 5, 0, Math.PI * 2);
+      ctx.fill();
+      ctx.strokeStyle = 'rgba(28,26,23,0.25)';
+      ctx.lineWidth = 1;
+      ctx.beginPath();
+      ctx.arc(0, 0, e.r + 4, 0, Math.PI * 2);
+      ctx.stroke();
+      // rim highlight
+      ctx.strokeStyle = 'rgba(255,252,246,0.35)';
+      ctx.beginPath();
+      ctx.arc(0, 0, e.r + 2, -Math.PI * 0.8, -Math.PI * 0.2);
+      ctx.stroke();
+      ctx.restore();
+    } else if (e.type === 'obs') {
+      ctx.save();
+      if (e.kind === 'crate') {
+        // paint bucket
+        ctx.fillStyle = C.shadow;
+        ctx.beginPath();
+        ctx.ellipse(e.x + e.w / 2, GROUND_Y - 2, e.w * 0.45, 5, 0, 0, Math.PI * 2);
+        ctx.fill();
+        // body
+        const bg = ctx.createLinearGradient(e.x, e.y, e.x + e.w, e.y);
+        bg.addColorStop(0, '#5a534a');
+        bg.addColorStop(0.5, '#7a7268');
+        bg.addColorStop(1, '#4a443c');
+        ctx.fillStyle = bg;
+        roundRect(e.x + 4, e.y + 8, e.w - 8, e.h - 8, 4);
+        ctx.fill();
+        // lid
+        ctx.fillStyle = C.accent;
+        roundRect(e.x, e.y + 4, e.w, 10, 3);
+        ctx.fill();
+        ctx.fillStyle = C.accentDeep;
+        roundRect(e.x + 14, e.y, e.w - 28, 8, 2);
+        ctx.fill();
+        // label band
+        ctx.fillStyle = C.cream;
+        ctx.fillRect(e.x + 8, e.y + 22, e.w - 16, 14);
+        ctx.strokeStyle = C.ink;
+        ctx.lineWidth = 1;
+        ctx.strokeRect(e.x + 8, e.y + 22, e.w - 16, 14);
+      } else if (e.kind === 'scaffold') {
+        ctx.fillStyle = C.shadow;
+        ctx.beginPath();
+        ctx.ellipse(e.x + e.w / 2, GROUND_Y - 2, e.w * 0.55, 5, 0, 0, Math.PI * 2);
+        ctx.fill();
+        ctx.strokeStyle = C.inkSoft;
+        ctx.lineWidth = 4;
+        ctx.lineCap = 'round';
+        // uprights
+        ctx.beginPath();
+        ctx.moveTo(e.x + 6, e.y + e.h);
+        ctx.lineTo(e.x + 6, e.y);
+        ctx.moveTo(e.x + e.w - 6, e.y + e.h);
+        ctx.lineTo(e.x + e.w - 6, e.y);
+        ctx.stroke();
+        // rungs
+        ctx.lineWidth = 3;
+        ctx.strokeStyle = C.muted;
+        for (let ry = e.y + 16; ry < e.y + e.h; ry += 22) {
+          ctx.beginPath();
+          ctx.moveTo(e.x + 6, ry);
+          ctx.lineTo(e.x + e.w - 6, ry);
+          ctx.stroke();
+        }
+        // warning tape top
+        ctx.fillStyle = C.accent;
+        ctx.fillRect(e.x, e.y, e.w, 6);
+        ctx.fillStyle = C.ink;
+        for (let tx = e.x; tx < e.x + e.w; tx += 10) {
+          ctx.fillRect(tx, e.y, 5, 6);
+        }
+      } else if (e.kind === 'hang') {
+        // hanging drop cloth / chandelier obstacle
+        ctx.strokeStyle = C.muted;
+        ctx.lineWidth = 1.5;
+        ctx.setLineDash([3, 4]);
+        ctx.beginPath();
+        ctx.moveTo(e.x + e.w / 2, 0);
+        ctx.lineTo(e.x + e.w / 2, e.y);
+        ctx.stroke();
+        ctx.setLineDash([]);
+        // cloth
+        const cg = ctx.createLinearGradient(e.x, e.y, e.x, e.y + e.h);
+        cg.addColorStop(0, '#f5efe3');
+        cg.addColorStop(1, '#d9cfc0');
+        ctx.fillStyle = cg;
+        ctx.beginPath();
+        ctx.moveTo(e.x, e.y);
+        ctx.lineTo(e.x + e.w, e.y);
+        ctx.quadraticCurveTo(e.x + e.w + 4, e.y + e.h * 0.5, e.x + e.w - 6, e.y + e.h);
+        ctx.lineTo(e.x + 6, e.y + e.h);
+        ctx.quadraticCurveTo(e.x - 4, e.y + e.h * 0.5, e.x, e.y);
+        ctx.fill();
+        ctx.strokeStyle = 'rgba(28,26,23,0.15)';
+        ctx.stroke();
+        // pattern dots on cloth
+        ctx.fillStyle = 'rgba(184,149,44,0.35)';
+        for (let i = 0; i < 5; i++) {
+          ctx.beginPath();
+          ctx.arc(e.x + 12 + (i % 3) * 12, e.y + 20 + Math.floor(i / 3) * 28, 3, 0, Math.PI * 2);
+          ctx.fill();
+        }
+      }
+      ctx.restore();
+    }
+  }
+
+  function drawParticles() {
+    particles.forEach(p => {
+      ctx.globalAlpha = Math.max(0, p.life);
+      ctx.fillStyle = p.col;
+      ctx.beginPath();
+      ctx.arc(p.x, p.y, p.r * p.life, 0, Math.PI * 2);
+      ctx.fill();
+    });
+    ctx.globalAlpha = 1;
+  }
+
+  function drawHUD() {
+    // subtle speed ticks at bottom of canvas
+    ctx.fillStyle = 'rgba(28,26,23,0.05)';
+    ctx.fillRect(0, H - 3, W, 3);
+    ctx.fillStyle = C.accent;
+    const pct = (speed - 5.2) / (maxSpeed - 5.2);
+    ctx.fillRect(0, H - 3, W * Math.min(1, pct), 3);
+  }
+
+  // —— Update ——
+  function update(dt) {
+    if (!running || gameOver) return;
+    const tscale = Math.min(dt, 32) / 16.67; // normalize to ~60fps steps
+
+    distance += speed * tscale;
+    decorOffset += speed * tscale;
+
+    // accelerate gently
+    speed = Math.min(maxSpeed, speed + 0.0018 * tscale);
+
+    // player physics
+    player.vy += GRAVITY * tscale;
+    player.y += player.vy * tscale;
+    if (player.y >= GROUND_Y - player.h) {
+      player.y = GROUND_Y - player.h;
+      player.vy = 0;
+      player.onGround = true;
+      player.jumpCount = 0;
+    }
+    player.rot += (speed * 0.06) * tscale;
+
+    // spawn
+    spawnTimer -= tscale;
+    if (spawnTimer <= 0) {
+      const gap = Math.max(70, 140 - speed * 4);
+      if (Math.random() < 0.62) {
+        spawnCollectible(W + 40);
+      } else {
+        spawnObstacle(W + 40);
+        // sometimes a collectible after obstacle
+        if (Math.random() < 0.5) spawnCollectible(W + 40 + 140);
+      }
+      spawnTimer = gap + Math.random() * 40;
+    }
+
+    // entities
+    const px = player.x + 8;
+    const py = player.y + 10;
+    const pw = player.w - 16;
+    const ph = player.h - 18;
+
+    for (let i = entities.length - 1; i >= 0; i--) {
+      const e = entities[i];
+      e.x -= speed * tscale;
+      if (e.type === 'roll') e.rot += 0.04 * tscale;
+
+      if (e.x < -80) {
+        entities.splice(i, 1);
+        continue;
+      }
+
+      if (e.type === 'roll' && !e.taken) {
+        const dx = e.x - (player.x + player.w * 0.5);
+        const dy = e.y - (player.y + player.h * 0.5);
+        if (dx * dx + dy * dy < (e.r + 28) * (e.r + 28)) {
+          e.taken = true;
+          score += 10;
+          liveScore.textContent = String(score);
+          // paint splash on wall
+          wallPaint.push({
+            x: player.x - 20,
+            y: 80 + Math.random() * (GROUND_Y - 160),
+            s: 28 + Math.random() * 18,
+            style: e.style,
+            a: 0.55,
+            life: 1
+          });
+          if (wallPaint.length > 18) wallPaint.shift();
+          // sparkles
+          for (let k = 0; k < 10; k++) {
+            particles.push({
+              x: e.x, y: e.y,
+              vx: (Math.random() - 0.5) * 6,
+              vy: (Math.random() - 0.5) * 6 - 2,
+              life: 1,
+              r: 2 + Math.random() * 3,
+              col: Math.random() < 0.5 ? C.accent : e.style.ink
+            });
+          }
+          entities.splice(i, 1);
+          // micro score float
+          particles.push({
+            x: e.x, y: e.y - 10,
+            vx: 0, vy: -1.2,
+            life: 1, r: 0,
+            col: C.accent,
+            text: '+10'
+          });
+        }
+      } else if (e.type === 'obs') {
+        // AABB
+        let ox = e.x, oy = e.y, ow = e.w, oh = e.h;
+        if (e.kind === 'crate') { ox += 6; ow -= 12; oy += 8; oh -= 8; }
+        if (e.kind === 'scaffold') { ox += 4; ow -= 8; }
+        if (e.kind === 'hang') { ox += 6; ow -= 12; oy += 4; oh -= 10; }
+        if (px < ox + ow && px + pw > ox && py < oy + oh && py + ph > oy) {
+          endGame();
+        }
+      }
+    }
+
+    // particles
+    for (let i = particles.length - 1; i >= 0; i--) {
+      const p = particles[i];
+      p.x += p.vx * tscale;
+      p.y += p.vy * tscale;
+      p.vy += 0.05 * tscale;
+      p.life -= 0.03 * tscale;
+      if (p.life <= 0) particles.splice(i, 1);
+    }
+
+    // wall paint fade drift
+    wallPaint.forEach(p => {
+      p.x -= speed * 0.35 * tscale;
+      p.a *= 0.999;
+    });
+    wallPaint = wallPaint.filter(p => p.x > -80 && p.a > 0.05);
+
+    // passive score for distance
+    if (Math.floor(distance) % 40 < speed * tscale) {
+      // occasional tick
+    }
+    // score by distance
+    const distScore = Math.floor(distance / 50);
+    const collectPart = score; // already includes collects; keep simple
+    // actually keep score as collect-based + distance
+    // We'll add distance points separately via a base
+  }
+
+  // distance scoring — track last awarded
+  let lastDistAward = 0;
+
+  function updateScoreFromDist() {
+    const award = Math.floor(distance / 80);
+    if (award > lastDistAward) {
+      score += (award - lastDistAward);
+      lastDistAward = award;
+      liveScore.textContent = String(score);
+    }
+  }
+
+  function loop(now) {
+    const dt = now - lastT || 16;
+    lastT = now;
+
+    if (running && !gameOver) {
+      update(dt);
+      updateScoreFromDist();
+    }
+
+    if (shake > 0) shake *= 0.88;
+    if (flash > 0) flash *= 0.9;
+
+    // draw
+    ctx.save();
+    if (shake > 0.4) {
+      ctx.translate((Math.random() - 0.5) * shake, (Math.random() - 0.5) * shake);
+    }
+
+    drawBackground();
+
+    // entities behind player-ish
+    const t = now;
+    entities.forEach(e => drawEntity(e, t));
+    drawRoller(player);
+    drawParticles();
+
+    // floating +10 texts
+    particles.forEach(p => {
+      if (p.text) {
+        ctx.globalAlpha = Math.max(0, p.life);
+        ctx.fillStyle = C.accentDeep;
+        ctx.font = '600 14px "Avenir Next", "Helvetica Neue", sans-serif';
+        ctx.letterSpacing = '0.1em';
+        ctx.fillText(p.text, p.x - 12, p.y);
+        ctx.globalAlpha = 1;
+      }
+    });
+
+    drawHUD();
+
+    if (flash > 0.05) {
+      ctx.fillStyle = `rgba(28,26,23,${flash * 0.25})`;
+      ctx.fillRect(0, 0, W, H);
+    }
+
+    ctx.restore();
+
+    raf = requestAnimationFrame(loop);
+  }
+
+  // Idle preview render
+  function idleDraw() {
+    resetGame();
+    lastDistAward = 0;
+    drawBackground();
+    // decorative rolls on start screen
+    STYLES.forEach((s, i) => {
+      const e = {
+        type: 'roll', x: 220 + i * 130, y: GROUND_Y - 130 - (i % 2) * 30,
+        r: 22, style: s, rot: i * 0.4, bob: i, taken: false
+      };
+      drawEntity(e, performance.now());
+    });
+    player.y = GROUND_Y - player.h;
+    drawRoller(player);
+  }
+
+  idleDraw();
+  // keep a gentle idle animation under the start overlay
+  function idleLoop(now) {
+    if (running) return;
+    lastT = now;
+    decorOffset += 0.6;
+    // drift sample entities
+    ctx.clearRect(0, 0, W, H);
+    drawBackground();
+    STYLES.forEach((s, i) => {
+      const e = {
+        type: 'roll',
+        x: 220 + i * 130,
+        y: GROUND_Y - 130 - (i % 2) * 30,
+        r: 22, style: s,
+        rot: now * 0.001 + i,
+        bob: i * 1.3,
+        taken: false
+      };
+      drawEntity(e, now);
+    });
+    player.rot = now * 0.002;
+    player.y = GROUND_Y - player.h;
+    drawRoller(player);
+    raf = requestAnimationFrame(idleLoop);
+  }
+  raf = requestAnimationFrame(idleLoop);
+
+  // fix reset to also reset distance award
+  const _reset = resetGame;
+  resetGame = function () {
+    _reset();
+    lastDistAward = 0;
+  };
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/57af693363f2/grok.png b/data/artifacts/57af693363f2/grok.png
new file mode 100644
index 0000000..3414cde
Binary files /dev/null and b/data/artifacts/57af693363f2/grok.png differ
diff --git a/data/artifacts/57af693363f2/qwen25-7b.html b/data/artifacts/57af693363f2/qwen25-7b.html
new file mode 100644
index 0000000..991ae3c
--- /dev/null
+++ b/data/artifacts/57af693363f2/qwen25-7b.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Endless Runner</title>
+<style>
+:root {
+    --bg: #0d0d0f;
+    --surface: #17171c;
+    --text: #f5f2ea;
+    --muted: #8a8578;
+    --accent: #c9a961;
+    --line: 1px solid var(--text);
+    --shadow: 0 8px 24px rgba(0,0,0,.12), hover 0 16px 48px rgba(0,0,0,.18);
+    --ease: cubic-bezier(.22,1,.36,1) both;
+}
+
+body {
+    margin: 0;
+    padding: 0;
+    background-color: var(--bg);
+    color: var(--text);
+    font-family: 'Didot', Georgia, serif;
+    overflow-x: hidden;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 100vh;
+}
+
+header {
+    position: fixed;
+    top: 24px;
+    left: 24px;
+    width: calc(100% - 48px);
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 8px 0;
+    background-color: var(--surface);
+    border-bottom: var(--line);
+}
+
+.wordmark {
+    font-size: 52px;
+    letter-spacing: .18em;
+    text-transform: uppercase;
+}
+
+.scoreboard {
+    font-size: 16px;
+    letter-spacing: .15em;
+    text-transform: uppercase;
+    margin-left: 40px;
+}
+
+canvas {
+    position: absolute;
+    top: 120px;
+    left: 50%;
+    transform: translateX(-50%);
+    width: 80vw;
+    height: 60vh;
+    background-color: var(--surface);
+}
+</style>
+</head>
+<body>
+
+<header>
+    <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+    <div class="scoreboard" id="scoreboard">Score: 0 | Best: 0</div>
+</header>
+
+<canvas id="gameCanvas"></canvas>
+
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+    const canvas = document.getElementById('gameCanvas');
+    const ctx = canvas.getContext('2d');
+
+    canvas.width = window.innerWidth;
+    canvas.height = window.innerHeight - 120;
+
+    let score = localStorage.getItem('score') || 0;
+    const scoreboard = document.getElementById('scoreboard');
+    scoreboard.textContent = `Score: ${score} | Best: ${score}`;
+
+    function drawBackground() {
+        ctx.fillStyle = 'var(--surface)';
+        ctx.fillRect(0, 0, canvas.width, canvas.height);
+    }
+
+    function drawWordmark(x, y) {
+        ctx.font = "52px Didot";
+        ctx.textAlign = "left";
+        ctx.fillStyle = 'var(--text)';
+        ctx.fillText("DESIGNER WALLCOVERINGS", x, y);
+    }
+
+    function drawRoller(rollerX, rollerY, rollerW, rollerH) {
+        ctx.fillStyle = 'var(--accent)';
+        ctx.fillRect(rollerX, rollerY, rollerW, rollerH);
+    }
+
+    function drawObstacle(obstacleX, obstacleY, obstacleW, obstacleH) {
+        ctx.fillStyle = 'rgba(255, 69, 134, 0.7)';
+        ctx.fillRect(obstacleX, obstacleY, obstacleW, obstacleH);
+    }
+
+    function drawWallpaper(wallpaperX, wallpaperY, wallpaperW, wallpaperH) {
+        ctx.beginPath();
+        ctx.moveTo(wallpaperX, wallpaperY);
+        ctx.lineTo(wallpaperX + wallpaperW, wallpaperY);
+        ctx.quadraticCurveTo(wallpaperX + wallpaperW / 2, wallpaperY - 10, wallpaperX + wallpaperW, wallpaperY);
+        ctx.closePath();
+        ctx.fillStyle = 'rgba(255, 69, 134, 0.7)';
+        ctx.fill();
+    }
+
+    function gameLoop() {
+        drawBackground();
+        drawWordmark(20, 80);
+
+        // Roller
+        let rollerX = canvas.width / 2 - 50;
+        let rollerY = canvas.height - 100;
+        let rollerW = 100;
+        let rollerH = 50;
+
+        drawRoller(rollerX, rollerY, rollerW, rollerH);
+
+        // Obstacles
+        const obstacleX = Math.random() * (canvas.width - 200) + 100;
+        const obstacleY = canvas.height / 3;
+        const obstacleW = 50;
+        const obstacleH = 50;
+
+        drawObstacle(obstacleX, obstacleY, obstacleW, obstacleH);
+
+        // Wallpaper
+        const wallpaperX = Math.random() * (canvas.width - 200) + 100;
+        const wallpaperY = canvas.height / 3 - 50;
+        const wallpaperW = 200;
+        const wallpaperH = 100;
+
+        drawWallpaper(wallpaperX, wallpaperY, wallpaperW, wallpaperH);
+
+        requestAnimationFrame(gameLoop);
+    }
+
+    gameLoop();
+});
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/57af693363f2/qwen25-7b.png b/data/artifacts/57af693363f2/qwen25-7b.png
new file mode 100644
index 0000000..50f3928
Binary files /dev/null and b/data/artifacts/57af693363f2/qwen25-7b.png differ
diff --git a/data/artifacts/57af693363f2/qwen3-14b.html b/data/artifacts/57af693363f2/qwen3-14b.html
new file mode 100644
index 0000000..42d50fb
--- /dev/null
+++ b/data/artifacts/57af693363f2/qwen3-14b.html
@@ -0,0 +1,380 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Designer Wallcoverings - Endless Runner</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <style>
+    :root {
+      --bg: #faf8f4;
+      --surface: #ffffff;
+      --text: #1c1a17;
+      --muted: #9b948a;
+      --accent: #b0472e;
+      --line: #eaeaea;
+      --shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+      --ease: cubic-bezier(0.22, 1, 0.36, 1);
+    }
+
+    * {
+      box-sizing: border-box;
+      margin: 0;
+      padding: 0;
+    }
+
+    body {
+      background: var(--bg);
+      color: var(--text);
+      font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+      font-size: 16px;
+      line-height: 1.6;
+      display: flex;
+      flex-direction: column;
+      height: 100vh;
+      overflow: hidden;
+    }
+
+    header {
+      font-family: 'Playfair Display', Georgia, serif;
+      font-size: 48px;
+      letter-spacing: 0.18em;
+      line-height: 1;
+      color: var(--text);
+      padding: 16px 24px;
+      background: var(--surface);
+      box-shadow: var(--shadow);
+      position: fixed;
+      top: 0;
+      left: 0;
+      right: 0;
+      z-index: 1000;
+      display: flex;
+      align-items: center;
+      justify-content: flex-start;
+      text-transform: uppercase;
+    }
+
+    main {
+      flex: 1;
+      position: relative;
+      overflow: hidden;
+    }
+
+    canvas {
+      display: block;
+      width: 100%;
+      height: 100%;
+    }
+
+    .overlay {
+      position: fixed;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      background: rgba(0, 0, 0, 0.7);
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      color: var(--text);
+      font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+      font-size: 24px;
+      text-transform: uppercase;
+      letter-spacing: 0.15em;
+      opacity: 0;
+      pointer-events: none;
+      transition: opacity 0.3s var(--ease);
+    }
+
+    .overlay.visible {
+      opacity: 1;
+      pointer-events: auto;
+    }
+
+    .scoreboard {
+      position: fixed;
+      top: 24px;
+      right: 24px;
+      background: var(--surface);
+      padding: 8px 16px;
+      border: 1px solid var(--line);
+      border-radius: 14px;
+      box-shadow: var(--shadow);
+      font-size: 16px;
+      letter-spacing: 0.15em;
+      text-transform: uppercase;
+      display: flex;
+      flex-direction: column;
+      gap: 8px;
+    }
+
+    .scoreboard span {
+      font-size: 14px;
+      font-weight: bold;
+    }
+
+    .restart-button {
+      margin-top: 16px;
+      padding: 8px 16px;
+      background: var(--accent);
+      color: var(--surface);
+      border: none;
+      border-radius: 8px;
+      cursor: pointer;
+      text-transform: uppercase;
+      letter-spacing: 0.15em;
+      font-size: 14px;
+      transition: background 0.2s var(--ease);
+    }
+
+    .restart-button:hover {
+      background: #d03f26;
+    }
+  </style>
+</head>
+<body>
+  <header>DESIGNER WALLCOVERINGS</header>
+  <main>
+    <canvas id="gameCanvas"></canvas>
+  </main>
+  <div class="overlay" id="gameOverOverlay">
+    <div>
+      <div>GAME OVER</div>
+      <div id="finalScore">SCORE: 0</div>
+      <div id="bestScore">BEST: 0</div>
+      <button class="restart-button" onclick="restartGame()">RESTART</button>
+    </div>
+  </div>
+  <div class="scoreboard" id="scoreboard">
+    <span id="score">SCORE: 0</span>
+    <span id="best">BEST: 0</span>
+  </div>
+
+  <script>
+    const canvas = document.getElementById('gameCanvas');
+    const ctx = canvas.getContext('2d');
+    const gameOverOverlay = document.getElementById('gameOverOverlay');
+    const finalScore = document.getElementById('finalScore');
+    const bestScore = document.getElementById('bestScore');
+    const scoreDisplay = document.getElementById('score');
+    const bestDisplay = document.getElementById('best');
+
+    let score = 0;
+    let best = 0;
+    let gameOver = false;
+    let lastTime = 0;
+    let gravity = 0.5;
+    let velocityY = 0;
+    let positionY = 0;
+    let jumpStrength = -12;
+    let isJumping = false;
+    let lastJump = 0;
+    let jumpCooldown = 200;
+    let groundHeight = 100;
+    let speed = 3;
+
+    const obstacles = [];
+    const wallpaperRolls = [];
+
+    function resizeCanvas() {
+      canvas.width = window.innerWidth;
+      canvas.height = window.innerHeight;
+    }
+
+    window.addEventListener('resize', resizeCanvas);
+    resizeCanvas();
+
+    function drawWallpaper(x, y, color) {
+      ctx.fillStyle = color;
+      ctx.beginPath();
+      ctx.moveTo(x, y);
+      ctx.lineTo(x + 40, y);
+      ctx.lineTo(x + 40, y + 40);
+      ctx.lineTo(x, y + 40);
+      ctx.closePath();
+      ctx.fill();
+    }
+
+    function drawObstacle(x, y, color) {
+      ctx.fillStyle = color;
+      ctx.beginPath();
+      ctx.moveTo(x, y);
+      ctx.lineTo(x + 30, y);
+      ctx.lineTo(x + 30, y + 40);
+      ctx.lineTo(x, y + 40);
+      ctx.closePath();
+      ctx.fill();
+    }
+
+    function drawPlayer(x, y) {
+      ctx.fillStyle = '#b0472e';
+      ctx.beginPath();
+      ctx.arc(x, y, 20, 0, Math.PI * 2);
+      ctx.fill();
+    }
+
+    function drawGround() {
+      ctx.fillStyle = '#eaeaea';
+      ctx.fillRect(0, canvas.height - groundHeight, canvas.width, groundHeight);
+    }
+
+    function update(deltaTime) {
+      if (gameOver) return;
+
+      velocityY += gravity * deltaTime;
+      positionY += velocityY * deltaTime;
+
+      if (positionY > canvas.height - groundHeight - 20) {
+        positionY = canvas.height - groundHeight - 20;
+        velocityY = 0;
+        isJumping = false;
+      }
+
+      // Move obstacles
+      for (let i = 0; i < obstacles.length; i++) {
+        obstacles[i].x -= speed * deltaTime;
+        if (obstacles[i].x + 30 < 0) {
+          obstacles.splice(i, 1);
+          i--;
+        }
+      }
+
+      // Move wallpaper rolls
+      for (let i = 0; i < wallpaperRolls.length; i++) {
+        wallpaperRolls[i].x -= speed * deltaTime;
+        if (wallpaperRolls[i].x + 40 < 0) {
+          wallpaperRolls.splice(i, 1);
+          i--;
+        }
+      }
+
+      // Check collision with obstacles
+      for (let obstacle of obstacles) {
+        if (
+          positionY + 20 > obstacle.y &&
+          positionY - 20 < obstacle.y + 40 &&
+          positionX + 20 > obstacle.x &&
+          positionX - 20 < obstacle.x + 30
+        ) {
+          gameOver = true;
+          showGameOver();
+        }
+      }
+
+      // Check collision with wallpaper rolls
+      for (let roll of wallpaperRolls) {
+        if (
+          positionY + 20 > roll.y &&
+          positionY - 20 < roll.y + 40 &&
+          positionX + 20 > roll.x &&
+          positionX - 20 < roll.x + 40
+        ) {
+          score += 10;
+          wallpaperRolls.splice(wallpaperRolls.indexOf(roll), 1);
+          updateScore();
+        }
+      }
+    }
+
+    function draw() {
+      ctx.clearRect(0, 0, canvas.width, canvas.height);
+      drawGround();
+      drawPlayer(canvas.width / 2, positionY);
+      for (let obstacle of obstacles) {
+        drawObstacle(obstacle.x, obstacle.y, '#333');
+      }
+      for (let roll of wallpaperRolls) {
+        drawWallpaper(roll.x, roll.y, roll.color);
+      }
+    }
+
+    function spawnObstacle() {
+      const x = canvas.width + 30;
+      const y = Math.random() * (canvas.height - groundHeight - 40);
+      obstacles.push({ x, y });
+    }
+
+    function spawnWallpaperRoll() {
+      const x = canvas.width + 40;
+      const y = Math.random() * (canvas.height - groundHeight - 40);
+      const color = ['#c65f38', '#e0a458', '#d03f26', '#8a8578', '#7d6a45'][Math.floor(Math.random() * 5)];
+      wallpaperRolls.push({ x, y, color });
+    }
+
+    function gameLoop(timestamp) {
+      if (!lastTime) lastTime = timestamp;
+      const deltaTime = timestamp - lastTime;
+      lastTime = timestamp;
+
+      update(deltaTime);
+      draw();
+
+      if (timestamp % 1000 === 0) {
+        spawnObstacle();
+        spawnWallpaperRoll();
+      }
+
+      if (!gameOver) {
+        requestAnimationFrame(gameLoop);
+      }
+    }
+
+    function showGameOver() {
+      gameOverOverlay.classList.add('visible');
+      finalScore.textContent = `SCORE: ${score}`;
+      bestScore.textContent = `BEST: ${best}`;
+    }
+
+    function updateScore() {
+      scoreDisplay.textContent = `SCORE: ${score}`;
+      if (score > best) {
+        best = score;
+        bestDisplay.textContent = `BEST: ${best}`;
+      }
+      localStorage.setItem('bestScore', best);
+    }
+
+    function restartGame() {
+      gameOver = false;
+      gameOverOverlay.classList.remove('visible');
+      score = 0;
+      updateScore();
+      positionY = canvas.height - groundHeight - 20;
+      velocityY = 0;
+      isJumping = false;
+      obstacles.length = 0;
+      wallpaperRolls.length = 0;
+      lastTime = 0;
+      gameLoop(performance.now());
+    }
+
+    document.addEventListener('keydown', (e) => {
+      if (e.code === 'Space' || e.code === 'ArrowUp') {
+        if (!isJumping && !gameOver) {
+          velocityY = jumpStrength;
+          isJumping = true;
+          lastJump = performance.now();
+        }
+      }
+    });
+
+    document.addEventListener('touchstart', (e) => {
+      if (!isJumping && !gameOver) {
+        velocityY = jumpStrength;
+        isJumping = true;
+        lastJump = performance.now();
+      }
+    });
+
+    // Load best score from localStorage
+    const savedBest = localStorage.getItem('bestScore');
+    if (savedBest) {
+      best = parseInt(savedBest);
+      bestDisplay.textContent = `BEST: ${best}`;
+    }
+
+    // Start game loop
+    gameLoop(performance.now());
+  </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/57af693363f2/qwen3-14b.png b/data/artifacts/57af693363f2/qwen3-14b.png
new file mode 100644
index 0000000..64b8da4
Binary files /dev/null and b/data/artifacts/57af693363f2/qwen3-14b.png differ
diff --git a/data/artifacts/70eea6613a73/claude-code.html b/data/artifacts/70eea6613a73/claude-code.html
new file mode 100644
index 0000000..1045f95
--- /dev/null
+++ b/data/artifacts/70eea6613a73/claude-code.html
@@ -0,0 +1,521 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Style Lookbook</title>
+<style>
+  :root{
+    --bg:#faf8f4;
+    --surface:#ffffff;
+    --ink:#1c1a17;
+    --text:#1c1a17;
+    --muted:#9b948a;
+    --accent:#b0472e;
+    --accent-2:#2f4c39;
+    --line:rgba(28,26,23,.12);
+    --shadow:0 8px 24px rgba(28,26,23,.10);
+    --shadow-hover:0 16px 48px rgba(28,26,23,.16);
+    --ease:cubic-bezier(.22,1,.36,1);
+    --serif:'Didot','Bodoni MT','Playfair Display',Georgia,serif;
+    --sans:-apple-system,'Segoe UI','Helvetica Neue',Arial,sans-serif;
+  }
+  *{box-sizing:border-box;margin:0;padding:0;}
+  html,body{height:100%;}
+  body{
+    background:var(--bg);
+    color:var(--text);
+    font-family:var(--sans);
+    -webkit-font-smoothing:antialiased;
+    display:flex;
+    flex-direction:column;
+    min-height:100vh;
+  }
+
+  /* ---------- HEADER / WORDMARK ---------- */
+  header.topbar{
+    position:sticky;top:0;z-index:40;
+    background:rgba(250,248,244,.92);
+    backdrop-filter:blur(10px);
+    border-bottom:1px solid var(--line);
+    display:flex;align-items:center;justify-content:space-between;
+    padding:18px 28px;
+    gap:20px;
+  }
+  .wordmark{
+    font-family:var(--serif);
+    color:var(--ink);
+    text-transform:uppercase;
+    letter-spacing:.18em;
+    line-height:1.02;
+    font-weight:600;
+    font-size:clamp(20px,3.4vw,30px);
+    white-space:normal;
+    max-width:280px;
+  }
+  .wordmark .l2{display:block;font-size:.9em;letter-spacing:.20em;}
+  .header-tag{
+    font-family:var(--sans);
+    font-size:11px;
+    text-transform:uppercase;
+    letter-spacing:.15em;
+    color:var(--muted);
+    text-align:right;
+    line-height:1.5;
+  }
+
+  /* ---------- STAGE ---------- */
+  .stage-wrap{
+    flex:1;
+    display:flex;
+    flex-direction:column;
+    align-items:center;
+    justify-content:center;
+    padding:32px 16px 12px;
+  }
+  .frame{
+    width:100%;
+    max-width:440px;
+    aspect-ratio:4/5;
+    background:var(--surface);
+    border:1px solid var(--line);
+    border-radius:14px;
+    box-shadow:var(--shadow);
+    overflow:hidden;
+    position:relative;
+  }
+  .track{
+    display:flex;
+    height:100%;
+    width:100%;
+    transition:transform .7s var(--ease);
+  }
+  .slide{
+    min-width:100%;
+    height:100%;
+    position:relative;
+    overflow:hidden;
+    display:flex;
+    flex-direction:column;
+  }
+
+  /* ---------- COVER SLIDE ---------- */
+  .cover{
+    background:
+      radial-gradient(120% 80% at 50% 0%, rgba(176,71,46,.06), transparent 60%),
+      var(--surface);
+    align-items:center;
+    justify-content:center;
+    text-align:center;
+    padding:44px 34px;
+  }
+  .cover .kicker{
+    font-size:11px;letter-spacing:.28em;text-transform:uppercase;
+    color:var(--muted);margin-bottom:22px;
+  }
+  .cover-rule{width:44px;height:1px;background:var(--accent);margin:0 auto 26px;}
+  .cover h1{
+    font-family:var(--serif);
+    font-weight:600;
+    line-height:1.04;
+    font-size:clamp(38px,10vw,54px);
+    letter-spacing:.01em;
+    color:var(--ink);
+  }
+  .cover .edit-name{
+    font-family:var(--serif);
+    font-weight:600;
+    line-height:1.04;
+    font-size:clamp(38px,10vw,54px);
+    letter-spacing:.01em;
+    color:var(--ink);
+    text-align:center;
+    border:none;background:transparent;
+    outline:none;width:100%;
+    caret-color:var(--accent);
+  }
+  .cover .edit-name:focus{
+    box-shadow:0 1px 0 var(--accent);
+  }
+  .cover .sub{
+    margin-top:24px;font-size:14px;letter-spacing:.06em;color:var(--muted);
+    max-width:280px;line-height:1.7;
+  }
+  .cover .palette-row{
+    display:flex;gap:10px;margin-top:30px;
+  }
+  .cover .palette-row .dot{
+    width:26px;height:26px;border-radius:50%;
+    border:1px solid var(--line);
+    box-shadow:inset 0 0 0 2px rgba(255,255,255,.5);
+    cursor:pointer;
+    transition:transform .2s var(--ease);
+  }
+  .cover .palette-row .dot:hover{transform:scale(1.12);}
+
+  /* ---------- PATTERN SLIDES ---------- */
+  .swatch{
+    height:52%;
+    position:relative;
+    border-bottom:1px solid var(--line);
+  }
+  .vignette{
+    height:48%;
+    position:relative;
+    background:var(--surface);
+    padding:22px 26px;
+    display:flex;
+    flex-direction:column;
+    justify-content:center;
+  }
+  .vignette .idx{
+    font-size:11px;letter-spacing:.22em;text-transform:uppercase;
+    color:var(--accent);margin-bottom:10px;
+  }
+  .vignette h3{
+    font-family:var(--serif);font-weight:600;
+    font-size:26px;line-height:1.12;color:var(--ink);margin-bottom:10px;
+  }
+  .vignette p{
+    font-size:13.5px;line-height:1.6;color:var(--muted);letter-spacing:.02em;
+  }
+  .room{
+    position:absolute;inset:0;
+  }
+  /* room vignette overlay elements drawn in CSS */
+  .room .floor{position:absolute;left:0;right:0;bottom:0;height:26%;background:linear-gradient(180deg,rgba(28,26,23,.05),rgba(28,26,23,.14));}
+  .room .furn{position:absolute;border-radius:8px 8px 4px 4px;box-shadow:var(--shadow);}
+  .room .lamp{position:absolute;}
+
+  /* ---------- CTA SLIDE ---------- */
+  .cta{
+    background:
+      radial-gradient(130% 90% at 50% 100%, rgba(47,76,57,.07), transparent 60%),
+      var(--surface);
+    align-items:center;justify-content:center;text-align:center;
+    padding:44px 34px;
+  }
+  .cta .mono{
+    font-size:11px;letter-spacing:.28em;text-transform:uppercase;color:var(--muted);margin-bottom:22px;
+  }
+  .cta h2{
+    font-family:var(--serif);font-weight:600;font-size:clamp(30px,8vw,42px);
+    line-height:1.08;color:var(--ink);margin-bottom:18px;
+  }
+  .cta p{font-size:14px;line-height:1.7;color:var(--muted);max-width:280px;margin:0 auto 30px;letter-spacing:.03em;}
+  .cta .btn{
+    font-family:var(--sans);font-size:12px;letter-spacing:.18em;text-transform:uppercase;
+    color:var(--surface);background:var(--ink);
+    border:none;border-radius:999px;
+    padding:15px 34px;cursor:pointer;
+    transition:background .2s var(--ease),transform .2s var(--ease),box-shadow .2s var(--ease);
+    box-shadow:var(--shadow);
+  }
+  .cta .btn:hover{background:var(--accent);transform:translateY(-2px);box-shadow:var(--shadow-hover);}
+  .cta .handle{margin-top:26px;font-size:12px;letter-spacing:.14em;color:var(--accent);text-transform:uppercase;}
+
+  /* ---------- CONTROLS ---------- */
+  .nav-btn{
+    position:absolute;top:50%;transform:translateY(-50%);
+    width:42px;height:42px;border-radius:50%;
+    background:rgba(255,255,255,.86);border:1px solid var(--line);
+    backdrop-filter:blur(6px);
+    display:flex;align-items:center;justify-content:center;
+    cursor:pointer;z-index:10;color:var(--ink);
+    transition:background .2s var(--ease),transform .2s var(--ease);
+    box-shadow:var(--shadow);
+    font-size:18px;
+  }
+  .nav-btn:hover{background:#fff;}
+  .nav-btn.prev{left:12px;}
+  .nav-btn.next{right:12px;}
+  .nav-btn:disabled{opacity:.28;cursor:default;}
+  .nav-btn.prev:active{transform:translateY(-50%) scale(.94);}
+  .nav-btn.next:active{transform:translateY(-50%) scale(.94);}
+
+  .counter{
+    position:absolute;top:14px;right:16px;z-index:10;
+    font-size:11px;letter-spacing:.16em;color:var(--muted);
+    background:rgba(255,255,255,.75);padding:4px 10px;border-radius:999px;
+    border:1px solid var(--line);
+  }
+
+  .dots{
+    display:flex;gap:9px;justify-content:center;margin-top:22px;
+  }
+  .dots .dot{
+    width:8px;height:8px;border-radius:50%;
+    background:var(--line);border:none;cursor:pointer;padding:0;
+    transition:all .3s var(--ease);
+  }
+  .dots .dot.active{background:var(--accent);width:22px;border-radius:999px;}
+
+  .hint{
+    margin-top:16px;text-align:center;font-size:10.5px;letter-spacing:.16em;
+    text-transform:uppercase;color:var(--muted);
+  }
+  footer.footbar{
+    padding:14px;text-align:center;border-top:1px solid var(--line);
+    font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
+  }
+  .edit-hint{
+    display:inline-block;margin-top:14px;font-size:10px;letter-spacing:.14em;
+    text-transform:uppercase;color:var(--accent);opacity:.8;
+  }
+</style>
+</head>
+<body>
+
+<header class="topbar">
+  <div class="wordmark">Designer<span class="l2">Wallcoverings</span></div>
+  <div class="header-tag">Style Lookbook<br>Carousel</div>
+</header>
+
+<div class="stage-wrap">
+  <div class="frame">
+    <div class="counter" id="counter">01 / 05</div>
+    <button class="nav-btn prev" id="prev" aria-label="Previous">‹</button>
+    <button class="nav-btn next" id="next" aria-label="Next">›</button>
+    <div class="track" id="track">
+
+      <!-- COVER -->
+      <section class="slide cover">
+        <div class="kicker">The Style Edit · No. 01</div>
+        <div class="cover-rule"></div>
+        <input class="edit-name" id="styleName" value="Grandmillennial" spellcheck="false" aria-label="Edit style name">
+        <div class="sub">A curated wallcovering study — pattern, palette &amp; the rooms they belong in.</div>
+        <div class="palette-row" id="paletteRow" title="Click a swatch to shift the accent"></div>
+        <span class="edit-hint">Tap the title to rename · tap a dot to recolor</span>
+      </section>
+
+      <!-- PATTERN 1 -->
+      <section class="slide">
+        <div class="swatch" id="sw1"></div>
+        <div class="vignette">
+          <div class="room" id="room1">
+            <div class="floor"></div>
+          </div>
+        </div>
+      </section>
+
+      <!-- PATTERN 2 -->
+      <section class="slide">
+        <div class="swatch" id="sw2"></div>
+        <div class="vignette">
+          <div class="idx">Pattern Two · Trellis</div>
+          <h3>Garden Lattice</h3>
+          <p>Layer a hand-drawn trellis behind skirted furniture to soften rigid architecture with movement.</p>
+        </div>
+      </section>
+
+      <!-- PATTERN 3 -->
+      <section class="slide">
+        <div class="swatch" id="sw3"></div>
+        <div class="vignette">
+          <div class="idx">Pattern Three · Chinoiserie</div>
+          <h3>Painted Bough</h3>
+          <p>Reserve the scenic for a single feature wall, then echo one motif color in your lampshades.</p>
+        </div>
+      </section>
+
+      <!-- CTA -->
+      <section class="slide cta">
+        <div class="mono">Bring The Look Home</div>
+        <h2>Order Your<br>Swatch Box</h2>
+        <p>Five curated wallcoverings, cut to hand and posted to your studio — styled the way you saw them here.</p>
+        <button class="btn" id="ctaBtn">Request Samples</button>
+        <div class="handle">@designerwallcoverings</div>
+      </section>
+
+    </div>
+  </div>
+
+  <div class="dots" id="dots"></div>
+  <div class="hint">Swipe · Arrow keys · Dots to navigate</div>
+</div>
+
+<footer class="footbar">Designer Wallcoverings — The Style Lookbook</footer>
+
+<!-- CTA overlay (in-page, token-styled) -->
+<div id="overlay" style="position:fixed;inset:0;z-index:100;display:none;align-items:center;justify-content:center;padding:24px;background:rgba(28,26,23,.55);backdrop-filter:blur(4px);">
+  <div style="background:var(--surface);border:1px solid var(--line);border-radius:14px;max-width:360px;width:100%;padding:40px 32px;text-align:center;box-shadow:var(--shadow-hover);">
+    <div style="width:44px;height:1px;background:var(--accent);margin:0 auto 22px;"></div>
+    <h3 style="font-family:var(--serif);font-weight:600;font-size:28px;color:var(--ink);margin-bottom:14px;">Swatch Box Reserved</h3>
+    <p style="font-size:13.5px;line-height:1.7;color:var(--muted);margin-bottom:28px;">Your <span id="ovStyle" style="color:var(--accent);">Grandmillennial</span> edit is on its way. Watch your inbox for a tracking note.</p>
+    <button id="ovClose" style="font-family:var(--sans);font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--surface);background:var(--ink);border:none;border-radius:999px;padding:13px 30px;cursor:pointer;">Close</button>
+  </div>
+</div>
+
+<script>
+(function(){
+  "use strict";
+
+  /* ----- PALETTE (editable accent) ----- */
+  var palette = [
+    {name:'Terracotta', v:'#b0472e'},
+    {name:'Forest',     v:'#2f4c39'},
+    {name:'Ochre',      v:'#c08a2d'},
+    {name:'Ink Blue',   v:'#2c3e57'},
+    {name:'Plum',       v:'#6b3a56'}
+  ];
+  var root = document.documentElement;
+
+  function setAccent(hex){
+    root.style.setProperty('--accent', hex);
+    buildSwatches();
+    document.getElementById('room1Note') && null;
+  }
+
+  /* build palette dots on cover */
+  var paletteRow = document.getElementById('paletteRow');
+  palette.forEach(function(c){
+    var d = document.createElement('button');
+    d.className = 'dot';
+    d.style.background = c.v;
+    d.title = c.name + ' — set as accent';
+    d.setAttribute('aria-label', c.name);
+    d.addEventListener('click', function(){ setAccent(c.v); });
+    paletteRow.appendChild(d);
+  });
+
+  /* ----- CSS PATTERN SWATCHES (each visually distinct) ----- */
+  function accent(){ return getComputedStyle(root).getPropertyValue('--accent').trim() || '#b0472e'; }
+
+  function buildSwatches(){
+    var a = accent();
+    var ivory = '#faf6ef';
+
+    // 1 — Scalloped ogee / medallion (radial + repeating)
+    document.getElementById('sw1').style.background =
+      'radial-gradient(circle at 50% 50%, '+a+'22 0 18%, transparent 19%),'+
+      'radial-gradient(circle at 0% 0%, '+a+'22 0 18%, transparent 19%),'+
+      'radial-gradient(circle at 100% 0%, '+a+'22 0 18%, transparent 19%),'+
+      'radial-gradient(circle at 0% 100%, '+a+'22 0 18%, transparent 19%),'+
+      'radial-gradient(circle at 100% 100%, '+a+'22 0 18%, transparent 19%),'+
+      ivory;
+    document.getElementById('sw1').style.backgroundSize = '52px 52px';
+
+    // 2 — Garden lattice / trellis (crossed diagonal lines)
+    document.getElementById('sw2').style.background =
+      'repeating-linear-gradient(45deg, '+a+'55 0 2px, transparent 2px 26px),'+
+      'repeating-linear-gradient(-45deg, '+a+'55 0 2px, transparent 2px 26px),'+
+      'linear-gradient('+ivory+','+ivory+')';
+
+    // 3 — Chinoiscerie painted bough (organic conic + dots)
+    document.getElementById('sw3').style.background =
+      'radial-gradient(ellipse 14px 26px at 30% 20%, '+a+'40 0 60%, transparent 62%),'+
+      'radial-gradient(ellipse 22px 12px at 70% 55%, '+a+'33 0 60%, transparent 62%),'+
+      'radial-gradient(circle at 50% 85%, '+a+'55 0 8%, transparent 9%),'+
+      'linear-gradient(120deg, '+ivory+', #f3ede2)';
+    document.getElementById('sw3').style.backgroundSize = '90px 120px,90px 120px,40px 40px, cover';
+  }
+  buildSwatches();
+
+  /* Pattern 1 vignette content (built dynamically to include styling note) */
+  (function(){
+    var v = document.querySelector('#room1').parentElement;
+    v.innerHTML =
+      '<div class="idx">Pattern One · Medallion</div>'+
+      '<h3>Scalloped Ogee</h3>'+
+      '<p>Pair a soft medallion repeat with a skirted table and blue-and-white ginger jars for instant heritage warmth.</p>';
+  })();
+
+  /* Build a small styled room vignette (CSS shapes) inside cover-adjacent? 
+     Keep patterns clean — decorative room bars behind swatch tops. */
+  function decorateRoom(swId, sofa){
+    var el = document.getElementById(swId);
+    var r = document.createElement('div');
+    r.className='room';
+    r.innerHTML =
+      '<div class="floor"></div>'+
+      '<div class="furn" style="left:14%;bottom:9%;width:52%;height:22%;background:'+sofa+';"></div>'+
+      '<div class="furn" style="right:12%;bottom:9%;width:16%;height:34%;background:#efe7d8;border:1px solid var(--line);"></div>'+
+      '<div class="lamp" style="right:16%;bottom:40%;width:8%;height:10%;background:radial-gradient(circle,#f7e9c8,#e8d3a4);border-radius:50% 50% 4px 4px;"></div>';
+    el.appendChild(r);
+  }
+  decorateRoom('sw1','#e9dfce');
+  decorateRoom('sw2','#dde4dc');
+  decorateRoom('sw3','#efe1e6');
+
+  /* ----- CAROUSEL LOGIC ----- */
+  var track   = document.getElementById('track');
+  var slides  = track.children;
+  var total   = slides.length;
+  var idx     = 0;
+  var prevBtn = document.getElementById('prev');
+  var nextBtn = document.getElementById('next');
+  var counter = document.getElementById('counter');
+  var dotsWrap= document.getElementById('dots');
+
+  for(var i=0;i<total;i++){
+    (function(n){
+      var b=document.createElement('button');
+      b.className='dot'+(n===0?' active':'');
+      b.setAttribute('aria-label','Slide '+(n+1));
+      b.addEventListener('click',function(){ go(n); });
+      dotsWrap.appendChild(b);
+    })(i);
+  }
+  var dots=dotsWrap.children;
+
+  function pad(n){ return (n<10?'0':'')+n; }
+
+  function render(){
+    track.style.transform = 'translateX(-'+(idx*100)+'%)';
+    counter.textContent = pad(idx+1)+' / '+pad(total);
+    for(var i=0;i<dots.length;i++) dots[i].className='dot'+(i===idx?' active':'');
+    prevBtn.disabled = idx===0;
+    nextBtn.disabled = idx===total-1;
+  }
+  function go(n){ idx=Math.max(0,Math.min(total-1,n)); render(); }
+
+  prevBtn.addEventListener('click',function(){ go(idx-1); });
+  nextBtn.addEventListener('click',function(){ go(idx+1); });
+  document.addEventListener('keydown',function(e){
+    if(e.key==='ArrowLeft') go(idx-1);
+    else if(e.key==='ArrowRight') go(idx+1);
+  });
+
+  /* swipe */
+  var startX=null;
+  track.addEventListener('touchstart',function(e){ startX=e.touches[0].clientX; },{passive:true});
+  track.addEventListener('touchend',function(e){
+    if(startX===null) return;
+    var dx=e.changedTouches[0].clientX-startX;
+    if(Math.abs(dx)>40){ dx<0 ? go(idx+1) : go(idx-1); }
+    startX=null;
+  });
+  /* mouse drag */
+  var mDown=false,mStart=0;
+  track.addEventListener('mousedown',function(e){ mDown=true;mStart=e.clientX; });
+  window.addEventListener('mouseup',function(e){
+    if(!mDown) return; mDown=false;
+    var dx=e.clientX-mStart;
+    if(Math.abs(dx)>50){ dx<0 ? go(idx+1) : go(idx-1); }
+  });
+
+  render();
+
+  /* ----- editable style name syncs to CTA + overlay ----- */
+  var styleName=document.getElementById('styleName');
+  function syncName(){
+    var t=styleName.value.trim()||'Your';
+    document.getElementById('ovStyle').textContent=t;
+  }
+  styleName.addEventListener('input',syncName);
+  styleName.addEventListener('keydown',function(e){ if(e.key==='Enter'){ e.preventDefault(); styleName.blur(); }});
+  syncName();
+
+  /* ----- CTA overlay ----- */
+  var overlay=document.getElementById('overlay');
+  document.getElementById('ctaBtn').addEventListener('click',function(){
+    syncName();
+    overlay.style.display='flex';
+  });
+  document.getElementById('ovClose').addEventListener('click',function(){ overlay.style.display='none'; });
+  overlay.addEventListener('click',function(e){ if(e.target===overlay) overlay.style.display='none'; });
+
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/claude-code.png b/data/artifacts/70eea6613a73/claude-code.png
new file mode 100644
index 0000000..167dc37
Binary files /dev/null and b/data/artifacts/70eea6613a73/claude-code.png differ
diff --git a/data/artifacts/70eea6613a73/gemma3-12b.html b/data/artifacts/70eea6613a73/gemma3-12b.html
new file mode 100644
index 0000000..da1ed7c
--- /dev/null
+++ b/data/artifacts/70eea6613a73/gemma3-12b.html
@@ -0,0 +1,274 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Grandmillennial Lookbook</title>
+  <style>
+    :root {
+      --bg: #faf8f4;
+      --surface: #ffffff;
+      --text: #3a2c22;
+      --muted: #9b948a;
+      --accent: #b0472e;
+      --line: rgba(51, 43, 34, 0.1); /* a subtle line color */
+      --shadow: rgba(0, 0, 0, 0.12);
+      --ease: cubic-bezier(.22,1,.36,1);
+    }
+
+    body {
+      font-family: 'apple-system', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+      background-color: var(--bg);
+      color: var(--text);
+      margin: 0;
+      padding: 0;
+      overflow-x: hidden; /* Prevent horizontal scrolling */
+    }
+
+    header {
+      background-color: transparent;
+      padding: 24px;
+      display: flex;
+      align-items: center;
+      justify-content: left;
+      width: 100%;
+      position: fixed; /* Fix the header to the top */
+      top: 0;
+      left: 0;
+      z-index: 100;
+    }
+
+    .wordmark {
+      font-family: 'Didot', Georgia, serif;
+      font-size: 67px;
+      letter-spacing: .18em;
+      text-transform: uppercase;
+      line-height: 1; /* Adjust line height for better typography */
+    }
+
+    .carousel {
+      position: relative;
+      width: 100%;
+      overflow-x: auto;
+      scroll-snap-type: x mandatory;
+      padding-top: 128px; /* Account for fixed header */
+      padding-bottom: 64px;
+    }
+
+    .carousel-slide {
+      width: 100vw;
+      height: 100vh;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      scroll-snap-align: start;
+      padding: 96px;
+      position: relative;
+    }
+
+    .card {
+      background-color: var(--surface);
+      border-radius: 14px;
+      box-shadow: 0 8px 24px var(--shadow);
+      width: 80%; /* Adjusted width for better layout */
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      text-align: center;
+      margin-bottom: 32px;
+    }
+
+    .card h2 {
+      font-family: 'Didot', Georgia, serif;
+      font-size: 38px;
+      margin-bottom: 16px;
+    }
+
+    .swatch {
+      width: 200px;
+      height: 200px;
+      border: 1px solid var(--line);
+      background-color: var(--accent);
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      margin-bottom: 32px;
+    }
+
+    .vignette {
+      width: 100%; /* Take full width of the card */
+      height: 300px;
+      background-color: #e6dada;  /* Placeholder - replace with SVG/gradient*/
+      border-radius: 8px;
+      margin-top: 32px;
+    }
+
+    .note {
+      font-size: 16px;
+      line-height: 1.5;
+      color: var(--muted);
+    }
+
+    .cta {
+      background-color: var(--accent);
+      color: white;
+      padding: 24px;
+      border-radius: 8px;
+      text-align: center;
+      margin-top: 64px;
+      font-size: 18px;
+      letter-spacing: .15em;
+    }
+
+    .dots {
+      position: fixed;
+      bottom: 32px;
+      left: 50%;
+      transform: translateX(-50%);
+      display: flex;
+      gap: 8px;
+    }
+
+    .dot {
+      width: 16px;
+      height: 16px;
+      border-radius: 50%;
+      background-color: var(--muted);
+      cursor: pointer;
+    }
+
+    .dot.active {
+      background-color: var(--accent);
+    }
+
+    /* Animations */
+    @keyframes fadeUp {
+      from { opacity: 0; transform: translateY(28px) }
+      to { opacity: 1; transform: none }
+    }
+
+  </style>
+</head>
+<body>
+
+  <header>
+    <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+  </header>
+
+
+  <div class="carousel" id="carousel">
+    <div class="carousel-slide">
+      <h1>Grandmillennial Lookbook</h1>
+    </div>
+
+    <div class="carousel-slide">
+      <div class="card">
+        <h2>Pattern 1: Floral Toile</h2>
+        <div class="swatch" style="background-color:#f2e6d9;"></div>
+        <div class="vignette" style="background: linear-gradient(to bottom, #f2e6d9, #edeae0);"></div>
+        <p class="note">Combine traditional toile with antique furniture for a cozy and nostalgic feel.</p>
+      </div>
+    </div>
+
+    <div class="carousel-slide">
+       <div class="card">
+        <h2>Pattern 2: Striped Wallpaper</h2>
+          <div class="swatch" style="background-color:#d9e6ff;"></div>
+        <div class="vignette" style="background: linear-gradient(to bottom, #d9e6ff, #ccebe4);"></div>
+        <p class="note">Vertical stripes add height and a touch of formality to the space.</p>
+      </div>
+    </div>
+
+     <div class="carousel-slide">
+       <div class="card">
+        <h2>Pattern 3: Chintz Fabric</h2>
+          <div class="swatch" style="background-color:#ffffe6;"></div>
+        <div class="vignette" style="background: linear-gradient(to bottom, #ffffe6, #fdfaf0);"></div>
+        <p class="note">Layer chintz with soft textures and warm lighting for a welcoming atmosphere.</p>
+      </div>
+    </div>
+
+    <div class="carousel-slide">
+      <a href="#" class="cta">Explore the Collection</a>
+    </div>
+  </div>
+
+  <div class="dots" id="dots">
+    <!-- Dots will be dynamically generated by JavaScript -->
+  </div>
+
+
+  <script>
+    const carousel = document.getElementById('carousel');
+    const dotsContainer = document.getElementById('dots');
+    let currentSlide = 0;
+    const totalSlides = document.querySelectorAll('.carousel-slide').length;
+
+    // Generate dots dynamically
+    for (let i = 0; i < totalSlides; i++) {
+      const dot = document.createElement('div');
+      dot.classList.add('dot');
+      dotsContainer.appendChild(dot);
+    }
+
+    const dots = document.querySelectorAll('.dot');
+    dots[0].classList.add('active');
+
+
+    function showSlide(n) {
+        currentSlide = n;
+        carousel.scrollTo({left: carousel.offsetWidth * currentSlide, behavior: 'smooth'});
+        dots.forEach((dot, index) => {
+            if (index === currentSlide) {
+                dot.classList.add('active');
+            } else {
+                dot.classList.remove('active');
+            }
+        });
+
+    }
+
+    // Swipe functionality - basic placeholder; needs refinement for real-world use
+    let startX = 0;
+    let isSwiping = false;
+    carousel.addEventListener('touchstart', (e) => {
+        startX = e.touches[0].clientX;
+        isSwiping = true;
+    });
+
+    carousel.addEventListener('touchmove', (e) => {
+      if (!isSwiping) return;
+      const diffX = e.touches[0].clientX - startX;
+      carousel.scrollTo({left: carousel.scrollLeft + diffX, behavior: 'smooth'});
+      startX = e.touches[0].clientX;
+
+    });
+
+
+    carousel.addEventListener('touchend', (e) => {
+        if (!isSwiping) return;
+        isSwiping = false;
+         const threshold = 50;
+            if (currentSlide > 0 && carousel.scrollLeft < carousel.offsetWidth * currentSlide - threshold ) {
+                showSlide(currentSlide -1);
+          } else if (currentSlide < totalSlides-1 && carousel.scrollLeft > carousel.offsetWidth * currentSlide + threshold) {
+               showSlide(currentSlide+1);
+           }
+
+    });
+
+
+
+
+    // Dot click functionality
+    dots.forEach((dot, index) => {
+      dot.addEventListener('click', () => {
+        showSlide(index);
+      });
+    });
+
+
+  </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/gemma3-12b.png b/data/artifacts/70eea6613a73/gemma3-12b.png
new file mode 100644
index 0000000..486b57a
Binary files /dev/null and b/data/artifacts/70eea6613a73/gemma3-12b.png differ
diff --git a/data/artifacts/70eea6613a73/gpt.html b/data/artifacts/70eea6613a73/gpt.html
new file mode 100644
index 0000000..20f6e0c
--- /dev/null
+++ b/data/artifacts/70eea6613a73/gpt.html
@@ -0,0 +1,1104 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<title>DESIGNER WALLCOVERINGS – Art Deco Noir Lookbook</title>
+<style>
+:root {
+  /* Color tokens – luxe-noir palette */
+  --bg: #0d0d0f;
+  --surface: #17171c;
+  --surface-soft: #111117;
+  --text: #f5f2ea;
+  --muted: #8a8578;
+  --accent: #c9a961;   /* warm metallic gold */
+  --accent-deep: #7d6a45;
+  --line: rgba(249, 244, 232, 0.12);
+  --line-strong: rgba(249, 244, 232, 0.28);
+
+  /* Type tokens */
+  --font-display: 'Playfair Display', 'Didot', 'Bodoni MT', Georgia, serif;
+  --font-sans: 'Avenir Next', 'Century Gothic', 'Helvetica Neue', system-ui, sans-serif;
+  --fs-caption: 12px;
+  --fs-body: 16px;
+  --fs-lead: 21px;
+  --fs-h3: 28px;
+  --fs-h2: 38px;
+  --fs-h1: 50px;
+  --fs-display: 67px;
+
+  /* Motion tokens (HyperFrames-inspired) */
+  --ease-swift-out: cubic-bezier(.22,.9,.24,1);  /* swift-out */
+  --ease-hero: cubic-bezier(.22,1,.36,1);        /* ease-out-quint */
+  --ease-power: cubic-bezier(.77,0,.18,1);
+
+  /* Elevation */
+  --shadow-soft: 0 18px 40px rgba(0, 0, 0, 0.45);
+
+  /* Layout */
+  --radius-card: 18px;
+  --radius-pill: 999px;
+  --header-height: 88px;
+}
+
+/* Global reset */
+*,
+*::before,
+*::after {
+  box-sizing: border-box;
+}
+
+html, body {
+  margin: 0;
+  padding: 0;
+  background: radial-gradient(circle at top left, #181821 0, var(--bg) 55%, #050507 100%);
+  color: var(--text);
+  font-family: var(--font-sans);
+  font-size: var(--fs-body);
+  line-height: 1.6;
+  -webkit-font-smoothing: antialiased;
+}
+
+body {
+  min-height: 100vh;
+  display: flex;
+  flex-direction: column;
+}
+
+/* Header / Wordmark */
+.app-shell {
+  min-height: 100vh;
+  display: flex;
+  flex-direction: column;
+}
+
+.app-header {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: var(--header-height);
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 18px 32px 16px;
+  background: linear-gradient(to bottom, rgba(13,13,15,0.96), rgba(13,13,15,0.92), rgba(13,13,15,0.85));
+  border-bottom: 1px solid var(--line);
+  z-index: 10;
+  backdrop-filter: blur(18px);
+}
+
+.wordmark-lockup {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  max-width: 280px;
+}
+
+.wordmark {
+  font-family: var(--font-display);
+  font-size: 42px;
+  line-height: 1.05;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  color: var(--text); /* darkest ink token */
+  white-space: normal;
+}
+
+.wordmark-sub {
+  font-family: var(--font-sans);
+  font-size: 10px;
+  letter-spacing: 0.16em;
+  text-transform: uppercase;
+  color: var(--muted);
+  margin-top: 4px;
+}
+
+.header-meta {
+  display: flex;
+  align-items: center;
+  gap: 16px;
+  font-family: var(--font-sans);
+}
+
+.meta-pill {
+  padding: 6px 12px 5px;
+  border-radius: var(--radius-pill);
+  border: 1px solid var(--line);
+  font-size: 11px;
+  letter-spacing: 0.14em;
+  text-transform: uppercase;
+  color: var(--muted);
+  display: inline-flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.meta-dot {
+  width: 6px;
+  height: 6px;
+  border-radius: 999px;
+  background: radial-gradient(circle at 30% 20%, #f9f3d5 0, var(--accent) 40%, var(--accent-deep) 100%);
+  box-shadow: 0 0 0 1px rgba(249, 244, 232, 0.25), 0 0 10px rgba(201, 169, 97, 0.7);
+}
+
+/* Main */
+.main {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: calc(var(--header-height) + 16px) 20px 32px;
+}
+
+.carousel-shell {
+  width: min(980px, 100%);
+  max-width: 980px;
+}
+
+/* Carousel card */
+.carousel-card {
+  background: radial-gradient(circle at top, #232330 0, var(--surface) 55%, #0d0d10 100%);
+  border-radius: 26px;
+  box-shadow: var(--shadow-soft);
+  border: 1px solid rgba(255, 255, 255, 0.03);
+  padding: 24px 26px 22px;
+  display: flex;
+  flex-direction: column;
+  gap: 18px;
+  position: relative;
+  overflow: hidden;
+}
+
+/* Top row: style label + slide count */
+.carousel-header-row {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 12px;
+}
+
+.style-label-group {
+  display: flex;
+  flex-direction: column;
+  gap: 6px;
+}
+
+.style-chip {
+  display: inline-flex;
+  align-items: center;
+  gap: 8px;
+  padding: 4px 10px 3px;
+  border-radius: var(--radius-pill);
+  border: 1px solid var(--line);
+  background: linear-gradient(to right, rgba(255,255,255,0.04), rgba(255,255,255,0.0));
+  font-family: var(--font-sans);
+  font-size: 11px;
+  letter-spacing: 0.16em;
+  text-transform: uppercase;
+  color: var(--muted);
+}
+
+.style-chip-accent {
+  width: 16px;
+  height: 8px;
+  border-radius: 999px;
+  background: linear-gradient(90deg, var(--accent-deep), var(--accent));
+}
+
+.style-name {
+  font-family: var(--font-display);
+  font-size: 30px;
+  line-height: 1.1;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--text);
+}
+
+.style-subtitle {
+  font-family: var(--font-sans);
+  font-size: 13px;
+  letter-spacing: 0.12em;
+  text-transform: uppercase;
+  color: var(--muted);
+}
+
+.slide-counter {
+  font-family: var(--font-sans);
+  font-size: 12px;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  color: var(--muted);
+  border-radius: var(--radius-pill);
+  border: 1px solid var(--line);
+  padding: 6px 13px 5px;
+}
+
+/* Divider */
+.card-divider {
+  height: 1px;
+  width: 100%;
+  background-image: linear-gradient(to right, rgba(249, 244, 232, 0), rgba(249, 244, 232, 0.5), rgba(249, 244, 232, 0));
+  opacity: 0.6;
+}
+
+/* Carousel content */
+.carousel-inner {
+  display: flex;
+  flex-direction: column;
+  gap: 18px;
+}
+
+.carousel-content-row {
+  display: grid;
+  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr);
+  gap: 22px;
+}
+
+/* Slide image pane */
+.slide-visual {
+  border-radius: 22px;
+  background: radial-gradient(circle at top left, #20202a 0, #101018 45%, #050507 100%);
+  padding: 18px 16px 16px;
+  border: 1px solid var(--line-strong);
+  position: relative;
+  overflow: hidden;
+}
+
+/* Pattern swatch & vignette wrapper */
+.pattern-vignette {
+  display: grid;
+  grid-template-columns: 1.05fr 1.2fr;
+  gap: 14px;
+  align-items: stretch;
+}
+
+/* Swatch */
+.pattern-swatch {
+  border-radius: 18px;
+  overflow: hidden;
+  border: 1px solid rgba(249, 244, 232, 0.24);
+  position: relative;
+  isolation: isolate;
+  min-height: 130px;
+}
+
+/* Vignette */
+.room-vignette {
+  border-radius: 18px;
+  overflow: hidden;
+  border: 1px solid rgba(249, 244, 232, 0.16);
+  position: relative;
+  background: radial-gradient(circle at 0% 0%, #2d2b32 0, #15131a 42%, #020206 100%);
+}
+
+/* Vignette “floor” + “wall” structure */
+.vignette-inner {
+  position: absolute;
+  inset: 0;
+  display: grid;
+  grid-template-rows: 62% 38%;
+}
+
+.vignette-wall {
+  position: relative;
+  overflow: hidden;
+}
+
+.vignette-floor {
+  position: relative;
+  background-image:
+    linear-gradient(175deg, rgba(0,0,0,0.4) 0, rgba(0,0,0,0.7) 45%, rgba(0,0,0,0.95) 100%),
+    repeating-linear-gradient(105deg, rgba(130,110,90,0.2) 0, rgba(130,110,90,0.2) 6px, rgba(40,32,26,0.7) 6px, rgba(40,32,26,0.7) 12px);
+}
+
+/* Shared vignette furniture base */
+.vignette-furniture {
+  position: absolute;
+  inset: 0;
+}
+
+/* Base seat block */
+.v-seat {
+  position: absolute;
+  bottom: 12%;
+  left: 8%;
+  width: 54%;
+  height: 22%;
+  border-radius: 16px;
+  background: linear-gradient(135deg, #26252c, #14131a);
+  box-shadow: 0 14px 24px rgba(0,0,0,0.7);
+  border: 1px solid rgba(255,255,255,0.08);
+}
+
+/* Backrest variations per slide created via modifiers */
+
+/* Side table */
+.v-table {
+  position: absolute;
+  bottom: 14%;
+  right: 10%;
+  width: 16%;
+  height: 26%;
+  background: linear-gradient(to bottom, #2e2c33, #17151c);
+  border-radius: 12px;
+  border: 1px solid rgba(255,255,255,0.1);
+  box-shadow: 0 12px 18px rgba(0,0,0,0.7);
+}
+
+/* Lamp stem */
+.v-lamp-stem {
+  position: absolute;
+  bottom: 40%;
+  right: 17%;
+  width: 2px;
+  height: 20%;
+  background: linear-gradient(to bottom, rgba(249,244,232,0.9), rgba(249,244,232,0.4));
+}
+
+/* Lamp shade */
+.v-lamp-shade {
+  position: absolute;
+  bottom: 62%;
+  right: 12%;
+  width: 22%;
+  height: 18%;
+  border-radius: 50% 50% 45% 45%;
+  background: radial-gradient(circle at 30% 0%, #fffbe1 0, #f3d38a 35%, #7d6a45 100%);
+  box-shadow: 0 0 18px rgba(201,169,97,0.75);
+}
+
+/* Artwork frame */
+.v-frame {
+  position: absolute;
+  top: 14%;
+  left: 14%;
+  width: 38%;
+  height: 40%;
+  border-radius: 12px;
+  border: 1px solid rgba(249,244,232,0.6);
+  box-shadow: 0 8px 18px rgba(0,0,0,0.6);
+  overflow: hidden;
+}
+
+/* Text pane */
+.slide-text {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  gap: 18px;
+}
+
+.slide-kicker {
+  font-family: var(--font-sans);
+  font-size: 11px;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  color: var(--muted);
+}
+
+.slide-title {
+  font-family: var(--font-display);
+  font-size: 32px;
+  line-height: 1.05;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  margin-bottom: 6px;
+}
+
+.slide-note {
+  font-family: var(--font-sans);
+  font-size: 15px;
+  color: rgba(245, 242, 234, 0.9);
+  max-width: 34rem;
+}
+
+.slide-caption {
+  font-family: var(--font-sans);
+  font-size: 12px;
+  color: var(--muted);
+}
+
+/* CTA slide overrides */
+.slide--cta .slide-visual {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 24px 22px;
+}
+
+.cta-emblem {
+  width: 100%;
+  height: 100%;
+  border-radius: 20px;
+  border: 1px solid var(--line-strong);
+  background-image:
+    radial-gradient(circle at top left, rgba(201,169,97,0.16) 0, transparent 48%),
+    radial-gradient(circle at bottom right, rgba(201,169,97,0.2) 0, transparent 50%),
+    repeating-linear-gradient(135deg, rgba(249,244,232,0.08) 0, rgba(249,244,232,0.08) 2px, rgba(0,0,0,0) 2px, rgba(0,0,0,0) 8px);
+  position: relative;
+  overflow: hidden;
+}
+
+/* concentric rings */
+.cta-ring {
+  position: absolute;
+  border-radius: 999px;
+  border: 1px solid rgba(201,169,97,0.35);
+  inset: 14%;
+}
+
+.cta-ring:nth-child(2) { inset: 26%; opacity: 0.6; }
+.cta-ring:nth-child(3) { inset: 38%; opacity: 0.4; }
+
+/* central monogram */
+.cta-monogram {
+  position: absolute;
+  inset: 44%;
+  border-radius: 999px;
+  background: radial-gradient(circle at 30% 10%, #fff9dc 0, var(--accent) 45%, var(--accent-deep) 100%);
+  box-shadow: 0 0 30px rgba(201,169,97,0.7);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.cta-monogram-letter {
+  font-family: var(--font-display);
+  font-size: 24px;
+  letter-spacing: 0.22em;
+  text-transform: uppercase;
+  color: #151313;
+}
+
+/* CTA text */
+.cta-heading {
+  font-family: var(--font-display);
+  font-size: 30px;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  margin-bottom: 6px;
+}
+
+.cta-body {
+  font-size: 15px;
+  color: rgba(245,242,234,0.9);
+  max-width: 30rem;
+  margin-bottom: 12px;
+}
+
+.cta-meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px 14px;
+  font-size: 11px;
+  letter-spacing: 0.16em;
+  text-transform: uppercase;
+  color: var(--muted);
+}
+
+.cta-pill {
+  padding: 5px 10px 4px;
+  border-radius: var(--radius-pill);
+  border: 1px solid var(--line);
+}
+
+/* Bottom controls */
+.carousel-footer-row {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 16px;
+}
+
+.carousel-dots {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.dot {
+  width: 8px;
+  height: 8px;
+  border-radius: 999px;
+  border: 1px solid rgba(249, 244, 232, 0.35);
+  background: transparent;
+  transition: background-color 260ms var(--ease-swift-out), transform 260ms var(--ease-swift-out), border-color 260ms var(--ease-swift-out), box-shadow 260ms var(--ease-swift-out);
+}
+
+.dot.active {
+  background: radial-gradient(circle at 30% 20%, #fff9dc 0, var(--accent) 40%, var(--accent-deep) 100%);
+  box-shadow: 0 0 0 1px rgba(249, 244, 232, 0.35), 0 0 14px rgba(201, 169, 97, 0.7);
+  transform: scale(1.32);
+  border-color: transparent;
+}
+
+/* arrows */
+.carousel-arrows {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.arrow-btn {
+  border-radius: 999px;
+  border: 1px solid var(--line);
+  background: rgba(10,10,12,0.55);
+  color: var(--muted);
+  width: 34px;
+  height: 34px;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+  padding: 0;
+  transition: background-color 220ms var(--ease-swift-out), border-color 220ms var(--ease-swift-out), color 220ms var(--ease-swift-out), transform 220ms var(--ease-swift-out), box-shadow 220ms var(--ease-swift-out);
+}
+
+.arrow-btn svg {
+  width: 16px;
+  height: 16px;
+  fill: none;
+  stroke: currentColor;
+  stroke-width: 1.3;
+}
+
+.arrow-btn:focus-visible {
+  outline: 2px solid var(--accent);
+  outline-offset: 2px;
+}
+
+.arrow-btn:hover {
+  background: radial-gradient(circle at top left, rgba(201,169,97,0.18) 0, rgba(11,11,13,0.9) 55%);
+  border-color: rgba(249, 244, 232, 0.5);
+  color: var(--text);
+  box-shadow: 0 0 0 1px rgba(201,169,97,0.25);
+  transform: translateY(-0.5px);
+}
+
+/* slide index label */
+.carousel-index {
+  font-size: 11px;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  color: var(--muted);
+}
+
+/* Slides */
+.slide {
+  opacity: 0;
+  transform: translateX(16px);
+  pointer-events: none;
+  position: absolute;
+  inset: 0;
+  padding-right: 2px;
+  padding-bottom: 2px;
+  transition:
+    opacity 420ms var(--ease-hero),
+    transform 420ms var(--ease-hero);
+}
+
+.slide.active {
+  opacity: 1;
+  transform: translateX(0);
+  pointer-events: auto;
+  position: relative;
+}
+
+/* Slide-specific pattern swatches & vignette details */
+
+/* Cover slide pattern: stepped deco fan */
+.swatch--cover {
+  background-image:
+    radial-gradient(circle at 0 0, rgba(249,244,232,0.2) 0, transparent 46%),
+    repeating-linear-gradient(135deg, rgba(249,244,232,0.04) 0, rgba(249,244,232,0.04) 1px, rgba(0,0,0,0) 1px, rgba(0,0,0,0) 7px),
+    repeating-linear-gradient(45deg, rgba(201,169,97,0.22) 0, rgba(201,169,97,0.22) 2px, rgba(13,13,15,1) 2px, rgba(13,13,15,1) 10px);
+}
+
+/* Slide 1 swatch: geometric brass inlay grid */
+.swatch--geo-grid {
+  background-image:
+    linear-gradient(135deg, rgba(201,169,97,0.22), rgba(125,106,69,0.05)),
+    repeating-linear-gradient(90deg, transparent 0, transparent 19px, rgba(201,169,97,0.36) 19px, rgba(201,169,97,0.36) 20px),
+    repeating-linear-gradient(180deg, transparent 0, transparent 19px, rgba(201,169,97,0.36) 19px, rgba(201,169,97,0.36) 20px);
+}
+
+/* Slide 2 swatch: fan motif */
+.swatch--fan {
+  background-image:
+    radial-gradient(circle at 50% 0%, rgba(201,169,97,0.45) 0, rgba(201,169,97,0) 55%),
+    repeating-radial-gradient(circle at 50% 120%, rgba(249,244,232,0.18) 0, rgba(249,244,232,0.18) 1px, rgba(13,13,15,1) 1px, rgba(13,13,15,1) 9px);
+}
+
+/* Slide 3 swatch: slender vertical pinstripes */
+.swatch--pinstripe {
+  background-image:
+    linear-gradient(180deg, rgba(0,0,0,0.65), rgba(0,0,0,0.95)),
+    repeating-linear-gradient(90deg, rgba(249,244,232,0.16) 0, rgba(249,244,232,0.16) 1px, rgba(7,7,9,1) 1px, rgba(7,7,9,1) 8px);
+}
+
+/* Cover vignette backrest: low profile */
+.v-seat-back--cover {
+  position: absolute;
+  left: 10%;
+  bottom: 32%;
+  width: 48%;
+  height: 20%;
+  border-radius: 18px 18px 10px 10px;
+  background-image:
+    linear-gradient(120deg, #373642, #1c1a23);
+  border: 1px solid rgba(255,255,255,0.09);
+}
+
+/* Slide 1 vignette: faceted wall paneling */
+.v-wall-geo {
+  position: absolute;
+  inset: 0;
+  background-image:
+    linear-gradient(135deg, rgba(201,169,97,0.2) 0, rgba(201,169,97,0) 55%),
+    repeating-linear-gradient(135deg, rgba(249,244,232,0.06) 0, rgba(249,244,232,0.06) 1px, rgba(5,5,7,0.8) 1px, rgba(5,5,7,0.8) 12px);
+  opacity: 0.9;
+}
+
+/* Slide 2 vignette: scalloped fans on wall */
+.v-wall-fan {
+  position: absolute;
+  inset: 0;
+  background-image:
+    repeating-radial-gradient(circle at 50% 120%, rgba(249,244,232,0.12) 0, rgba(249,244,232,0.12) 1px, rgba(7,7,9,0.9) 1px, rgba(7,7,9,0.9) 10px);
+}
+
+/* Slide 3 vignette: pinstriped wall with spotlight */
+.v-wall-pin {
+  position: absolute;
+  inset: 0;
+  background-image:
+    radial-gradient(circle at 50% 0%, rgba(255,255,255,0.06) 0, rgba(0,0,0,0) 50%),
+    repeating-linear-gradient(90deg, rgba(249,244,232,0.16) 0, rgba(249,244,232,0.16) 1px, rgba(7,7,9,1) 1px, rgba(7,7,9,1) 10px);
+}
+
+/* Slide2 backrest: curved shell */
+.v-seat-back--shell {
+  position: absolute;
+  left: 6%;
+  bottom: 34%;
+  width: 58%;
+  height: 32%;
+  border-radius: 60px 60px 30px 30px;
+  background-image:
+    radial-gradient(circle at 20% 0%, rgba(255,255,255,0.16) 0, rgba(255,255,255,0) 50%),
+    linear-gradient(135deg, #3b3742, #1a1822);
+  border: 1px solid rgba(255,255,255,0.12);
+}
+
+/* Slide3 backrest: tall channel-tufted */
+.v-seat-back--channel {
+  position: absolute;
+  left: 9%;
+  bottom: 35%;
+  width: 54%;
+  height: 40%;
+  border-radius: 18px 18px 12px 12px;
+  background-image:
+    repeating-linear-gradient(90deg, #302d35 0, #302d35 8px, #241f29 8px, #241f29 18px);
+  border: 1px solid rgba(255,255,255,0.09);
+}
+
+/* Art pieces per slide */
+
+/* Cover artwork: simple deco arch */
+.art--arch {
+  background-image:
+    radial-gradient(circle at 50% 120%, rgba(13,13,15,1) 0, rgba(13,13,15,1) 40%, rgba(249,244,232,0.14) 42%, rgba(249,244,232,0.14) 48%, rgba(13,13,15,1) 50%, rgba(13,13,15,1) 100%),
+    linear-gradient(180deg, rgba(201,169,97,0.32), rgba(77,60,32,0.9));
+}
+
+/* Slide1 artwork: intersecting line work */
+.art--lines {
+  background-image:
+    linear-gradient(135deg, rgba(201,169,97,0.35) 0, rgba(201,169,97,0.05) 60%),
+    repeating-linear-gradient(45deg, rgba(13,13,15,1) 0, rgba(13,13,15,1) 8px, rgba(249,244,232,0.16) 8px, rgba(249,244,232,0.16) 9px);
+}
+
+/* Slide2 artwork: stylized fan */
+.art--fan {
+  background-image:
+    radial-gradient(circle at 50% 110%, rgba(201,169,97,0.65) 0, rgba(201,169,97,0.0) 60%),
+    radial-gradient(circle at 0 0, rgba(249,244,232,0.15) 0, rgba(13,13,15,1) 60%);
+}
+
+/* Slide3 artwork: minimal stripe composition */
+.art--stripe {
+  background-image:
+    linear-gradient(90deg,
+      rgba(249,244,232,0.05) 0,
+      rgba(249,244,232,0.05) 26%,
+      rgba(201,169,97,0.6) 26%,
+      rgba(201,169,97,0.6) 32%,
+      rgba(13,13,15,1) 32%,
+      rgba(13,13,15,1) 100%);
+}
+
+/* Responsive adjustments */
+@media (max-width: 900px) {
+  .carousel-card {
+    padding: 18px 16px 18px;
+    border-radius: 22px;
+  }
+  .carousel-content-row {
+    grid-template-columns: 1fr;
+  }
+  .slide-visual {
+    order: -1;
+  }
+}
+
+@media (max-width: 640px) {
+  .app-header {
+    padding: 14px 16px 12px;
+    height: auto;
+  }
+  :root {
+    --header-height: 92px;
+  }
+  .wordmark {
+    font-size: 36px;
+    letter-spacing: 0.16em;
+  }
+  .style-name {
+    font-size: 24px;
+  }
+  .slide-title {
+    font-size: 26px;
+  }
+  .pattern-vignette {
+    grid-template-columns: 1.1fr 1.5fr;
+  }
+  .carousel-footer-row {
+    flex-direction: column;
+    align-items: flex-start;
+  }
+}
+
+/* Reduce motion preference */
+@media (prefers-reduced-motion: reduce) {
+  * {
+    scroll-behavior: auto !important;
+    animation: none !important;
+    transition: none !important;
+  }
+}
+</style>
+</head>
+<body>
+<div class="app-shell">
+  <header class="app-header">
+    <div class="wordmark-lockup">
+      <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+      <div class="wordmark-sub">CURATED WALL PATTERNS FOR INTERIOR PURISTS</div>
+    </div>
+    <div class="header-meta">
+      <div class="meta-pill">
+        <span class="meta-dot" aria-hidden="true"></span>
+        <span>Lookbook · Art Deco Noir</span>
+      </div>
+      <div class="meta-pill">
+        <span>Swipe</span>
+      </div>
+    </div>
+  </header>
+
+  <main class="main">
+    <section class="carousel-shell" aria-label="Art Deco Noir wallcovering carousel">
+      <div class="carousel-card">
+        <div class="carousel-header-row">
+          <div class="style-label-group">
+            <div class="style-chip">
+              <span class="style-chip-accent" aria-hidden="true"></span>
+              <span>Style edit</span>
+            </div>
+            <div class="style-name" contenteditable="true" spellcheck="false">
+              Art&nbsp;Deco&nbsp;Noir
+            </div>
+            <div class="style-subtitle">
+              Wallcoverings for cinematic living rooms
+            </div>
+          </div>
+          <div class="slide-counter" id="slideCounter" aria-live="polite">
+            Slide 1 · 5
+          </div>
+        </div>
+
+        <div class="card-divider" aria-hidden="true"></div>
+
+        <div class="carousel-inner">
+          <!-- Slide 1: Cover -->
+          <article class="slide active" data-index="0" aria-roledescription="slide" aria-label="Cover: Art Deco Noir palette">
+            <div class="carousel-content-row">
+              <div class="slide-visual">
+                <div class="pattern-vignette">
+                  <div class="pattern-swatch swatch--cover" aria-hidden="true"></div>
+                  <div class="room-vignette" aria-hidden="true">
+                    <div class="vignette-inner">
+                      <div class="vignette-wall">
+                        <div class="v-wall-geo"></div>
+                        <div class="v-frame art--arch"></div>
+                      </div>
+                      <div class="vignette-floor"></div>
+                    </div>
+                    <div class="vignette-furniture">
+                      <div class="v-seat"></div>
+                      <div class="v-seat-back--cover"></div>
+                      <div class="v-table"></div>
+                      <div class="v-lamp-stem"></div>
+                      <div class="v-lamp-shade"></div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="slide-text">
+                <div>
+                  <div class="slide-kicker">Lookbook cover</div>
+                  <h2 class="slide-title">Sculpted light over deep nocturnes</h2>
+                  <p class="slide-note">
+                    A restrained palette of ink black, warm ivory, and brushed gold sets the tone for an Art Deco living room that feels like a private cinema.
+                  </p>
+                </div>
+                <p class="slide-caption">
+                  Edit the style name above and tune this palette for your next launch — every swatch below is drawn with pure CSS, ready to adapt.
+                </p>
+              </div>
+            </div>
+          </article>
+
+          <!-- Slide 2: Geometric brass grid -->
+          <article class="slide" data-index="1" aria-roledescription="slide" aria-label="Geometric brass grid wall">
+            <div class="carousel-content-row">
+              <div class="slide-visual">
+                <div class="pattern-vignette">
+                  <div class="pattern-swatch swatch--geo-grid" aria-hidden="true"></div>
+                  <div class="room-vignette" aria-hidden="true">
+                    <div class="vignette-inner">
+                      <div class="vignette-wall">
+                        <div class="v-wall-geo"></div>
+                        <div class="v-frame art--lines"></div>
+                      </div>
+                      <div class="vignette-floor"></div>
+                    </div>
+                    <div class="vignette-furniture">
+                      <div class="v-seat"></div>
+                      <div class="v-seat-back--channel"></div>
+                      <div class="v-table"></div>
+                      <div class="v-lamp-stem"></div>
+                      <div class="v-lamp-shade"></div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="slide-text">
+                <div>
+                  <div class="slide-kicker">Pattern one · Geometric brass grid</div>
+                  <h2 class="slide-title">Frame the room with quiet geometry</h2>
+                  <p class="slide-note">
+                    Use a slim brass inlay grid on the main wall only, then keep furnishings low and monochrome so the pattern reads like built-in architecture.
+                  </p>
+                </div>
+                <p class="slide-caption">
+                  Deep charcoal grounds the grid; echo the metal in table edges and lamp stems for a subtle, continuous line around the room.
+                </p>
+              </div>
+            </div>
+          </article>
+
+          <!-- Slide 3: Fan motif -->
+          <article class="slide" data-index="2" aria-roledescription="slide" aria-label="Scalloped fan wall">
+            <div class="carousel-content-row">
+              <div class="slide-visual">
+                <div class="pattern-vignette">
+                  <div class="pattern-swatch swatch--fan" aria-hidden="true"></div>
+                  <div class="room-vignette" aria-hidden="true">
+                    <div class="vignette-inner">
+                      <div class="vignette-wall">
+                        <div class="v-wall-fan"></div>
+                        <div class="v-frame art--fan"></div>
+                      </div>
+                      <div class="vignette-floor"></div>
+                    </div>
+                    <div class="vignette-furniture">
+                      <div class="v-seat"></div>
+                      <div class="v-seat-back--shell"></div>
+                      <div class="v-table"></div>
+                      <div class="v-lamp-stem"></div>
+                      <div class="v-lamp-shade"></div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="slide-text">
+                <div>
+                  <div class="slide-kicker">Pattern two · Fan motif</div>
+                  <h2 class="slide-title">Let the fans glow, not shout</h2>
+                  <p class="slide-note">
+                    Pair scalloped fans with rounded seating and a single halo lamp so light brushes the arcs and the pattern feels luminous rather than busy.
+                  </p>
+                </div>
+                <p class="slide-caption">
+                  Keep fabrics matte and textured — bouclé, wool, or mohair — to contrast the silky sheen of the fan print.
+                </p>
+              </div>
+            </div>
+          </article>
+
+          <!-- Slide 4: Pinstripe -->
+          <article class="slide" data-index="3" aria-roledescription="slide" aria-label="Vertical pinstripe wall">
+            <div class="carousel-content-row">
+              <div class="slide-visual">
+                <div class="pattern-vignette">
+                  <div class="pattern-swatch swatch--pinstripe" aria-hidden="true"></div>
+                  <div class="room-vignette" aria-hidden="true">
+                    <div class="vignette-inner">
+                      <div class="vignette-wall">
+                        <div class="v-wall-pin"></div>
+                        <div class="v-frame art--stripe"></div>
+                      </div>
+                      <div class="vignette-floor"></div>
+                    </div>
+                    <div class="vignette-furniture">
+                      <div class="v-seat"></div>
+                      <div class="v-seat-back--channel"></div>
+                      <div class="v-table"></div>
+                      <div class="v-lamp-stem"></div>
+                      <div class="v-lamp-shade"></div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="slide-text">
+                <div>
+                  <div class="slide-kicker">Pattern three · Vertical pinstripe</div>
+                  <h2 class="slide-title">Pull the ceiling higher with stripes</h2>
+                  <p class="slide-note">
+                    Run ultra-fine ivory pinstripes floor to ceiling, then choose low-slung seating so the wall reads taller and the room feels quietly grand.
+                  </p>
+                </div>
+                <p class="slide-caption">
+                  Anchor the look with a single dark, glossy table or plinth to mirror the line of the stripes without adding visual noise.
+                </p>
+              </div>
+            </div>
+          </article>
+
+          <!-- Slide 5: CTA -->
+          <article class="slide slide--cta" data-index="4" aria-roledescription="slide" aria-label="Call to action">
+            <div class="carousel-content-row">
+              <div class="slide-visual">
+                <div class="cta-emblem" aria-hidden="true">
+                  <div class="cta-ring"></div>
+                  <div class="cta-ring"></div>
+                  <div class="cta-ring"></div>
+                  <div class="cta-monogram">
+                    <span class="cta-monogram-letter">DW</span>
+                  </div>
+                </div>
+              </div>
+              <div class="slide-text">
+                <div>
+                  <div class="slide-kicker">Final touch</div>
+                  <h2 class="cta-heading">Specify your next statement wall</h2>
+                  <p class="cta-body">
+                    Save this carousel as a palette sketch: edit the style name, tune the gold, and swap patterns to prototype your own couture wallcovering story.
+                  </p>
+                </div>
+                <div class="cta-meta">
+                  <span class="cta-pill">Hold to zoom details</span>
+                  <span class="cta-pill">Share with your client</span>
+                  <span class="cta-pill">Tag @designerwallcoverings</span>
+                </div>
+              </div>
+            </div>
+          </article>
+        </div>
+
+        <div class="carousel-footer-row">
+          <div class="carousel-dots" role="tablist" aria-label="Slide navigation">
+            <button class="dot active" data-index="0" role="tab" aria-selected="true" aria-label="Go to cover slide"></button>
+            <button class="dot" data-index="1" role="tab" aria-selected="false" aria-label="Go to geometric brass grid slide"></button>
+            <button class="dot" data-index="2" role="tab" aria-selected="false" aria-label="Go to fan motif slide"></button>
+            <button class="dot" data-index="3" role="tab" aria-selected="false" aria-label="Go to vertical pinstripe slide"></button>
+            <button class="dot" data-index="4" role="tab" aria-selected="false" aria-label="Go to call to action slide"></button>
+          </div>
+          <div class="carousel-arrows">
+            <div class="carousel-index" id="slideIndexText">01 · 05</div>
+            <button class="arrow-btn" id="prevBtn" type="button" aria-label="Previous slide">
+              <svg viewBox="0 0 24 24" aria-hidden="true">
+                <path d="M14.5 6.5L9 12l5.5 5.5" />
+              </svg>
+            </button>
+            <button class="arrow-btn" id="nextBtn" type="button" aria-label="Next slide">
+              <svg viewBox="0 0 24 24" aria-hidden="true">
+                <path d="M9.5 6.5L15 12l-5.5 5.5" />
+              </svg>
+            </button>
+          </div>
+        </div>
+      </div>
+    </section>
+  </main>
+</div>
+
+<script>
+(function () {
+  const slides = Array.from(document.querySelectorAll('.slide'));
+  const dots = Array.from(document.querySelectorAll('.dot'));
+  const counter = document.getElementById('slideCounter');
+  const indexText = document.getElementById('slideIndexText');
+  const prev = document.getElementById('prevBtn');
+  const next = document.getElementById('nextBtn');
+  const total = slides.length;
+  let current = 0;
+
+  function setSlide(index) {
+    if (index === current || index < 0 || index >= total) return;
+    slides[current].classList.remove('active');
+    dots[current].classList.remove('active');
+    slides[index].classList.add('active');
+    dots[index].classList.add('active');
+    current = index;
+    const displayIndex = (current + 1).toString().padStart(2, '0');
+    const displayTotal = total.toString().padStart(2, '0');
+    counter.textContent = 'Slide ' + (current + 1) + ' · ' + total;
+    indexText.textContent = displayIndex + ' · ' + displayTotal;
+    dots.forEach((dot, i) => {
+      dot.setAttribute('aria-selected', i === current ? 'true' : 'false');
+    });
+  }
+
+  prev.addEventListener('click', function () {
+    const target = current === 0 ? total - 1 : current - 1;
+    setSlide(target);
+  });
+
+  next.addEventListener('click', function () {
+    const target = current === total - 1 ? 0 : current + 1;
+    setSlide(target);
+  });
+
+  dots.forEach(dot => {
+    dot.addEventListener('click', () => {
+      const index = parseInt(dot.getAttribute('data-index'), 10);
+      setSlide(index);
+    });
+  });
+
+  // Keyboard navigation
+  document.addEventListener('keydown', function (e) {
+    if (e.key === 'ArrowRight') {
+      next.click();
+    } else if (e.key === 'ArrowLeft') {
+      prev.click();
+    }
+  });
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/gpt.png b/data/artifacts/70eea6613a73/gpt.png
new file mode 100644
index 0000000..d77da36
Binary files /dev/null and b/data/artifacts/70eea6613a73/gpt.png differ
diff --git a/data/artifacts/70eea6613a73/grok.html b/data/artifacts/70eea6613a73/grok.html
new file mode 100644
index 0000000..c1f8a02
--- /dev/null
+++ b/data/artifacts/70eea6613a73/grok.html
@@ -0,0 +1,937 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Grandmillennial — Designer Wallcoverings Lookbook</title>
+<style>
+:root {
+  --bg: #f7f3eb;
+  --surface: #fffdf8;
+  --ink: #1c1a17;
+  --muted: #6e675c;
+  --accent: #9a3b4a;
+  --accent-soft: #c4a dig;
+  --gold: #b8956c;
+  --line: rgba(28, 26, 23, 0.12);
+  --shadow: 0 18px 48px rgba(28, 26, 23, 0.08);
+  --shadow-soft: 0 6px 20px rgba(28, 26, 23, 0.06);
+  --ease: cubic-bezier(.22, .9, .24, 1);
+  --ease-scene: cubic-bezier(.77, 0, .18, 1);
+  --ease-out: cubic-bezier(.22, 1, .36, 1);
+  --serif: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, 'Times New Roman', serif;
+  --sans: 'Avenir Next', 'Century Gothic', Futura, 'Segoe UI', sans-serif;
+  --bar-h: 72px;
+  --radius: 2px;
+}
+
+*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+
+html, body {
+  height: 100%;
+  background: var(--bg);
+  color: var(--ink);
+  font-family: var(--sans);
+  font-size: 16px;
+  line-height: 1.55;
+  -webkit-font-smoothing: antialiased;
+  overflow: hidden;
+}
+
+/* —— Fixed brand bar —— */
+.brand-bar {
+  position: fixed;
+  top: 0; left: 0; right: 0;
+  height: var(--bar-h);
+  z-index: 100;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 28px;
+  background: var(--bg);
+  border-bottom: 1px solid var(--line);
+}
+
+.wordmark {
+  font-family: var(--serif);
+  font-size: 42px;
+  font-weight: 400;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  color: var(--ink);
+  line-height: 1.05;
+  white-space: nowrap;
+}
+
+.bar-meta {
+  font-family: var(--sans);
+  font-size: 10px;
+  letter-spacing: 0.2em;
+  text-transform: uppercase;
+  color: var(--muted);
+}
+
+/* —— Stage —— */
+.stage {
+  position: fixed;
+  inset: var(--bar-h) 0 0 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 28px 20px 36px;
+}
+
+.phone {
+  width: min(400px, 100%);
+  height: min(720px, calc(100vh - var(--bar-h) - 64px));
+  background: var(--surface);
+  border: 1px solid var(--line);
+  box-shadow: var(--shadow);
+  border-radius: 4px;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+  position: relative;
+}
+
+/* —— Carousel —— */
+.carousel {
+  flex: 1;
+  position: relative;
+  overflow: hidden;
+  touch-action: pan-y;
+}
+
+.track {
+  display: flex;
+  height: 100%;
+  transition: transform 0.7s var(--ease-scene);
+  will-change: transform;
+}
+
+.slide {
+  flex: 0 0 100%;
+  width: 100%;
+  height: 100%;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  padding: 28px 28px 20px;
+  opacity: 0.35;
+  transition: opacity 0.55s var(--ease);
+}
+
+.slide.is-active { opacity: 1; }
+
+/* Cover */
+.slide-cover {
+  justify-content: flex-end;
+  padding-bottom: 48px;
+  background:
+    linear-gradient(180deg, transparent 30%, rgba(247,243,235,0.92) 70%, var(--bg) 100%),
+    repeating-linear-gradient(
+      0deg,
+      transparent,
+      transparent 11px,
+      rgba(154, 59, 74, 0.045) 11px,
+      rgba(154, 59, 74, 0.045) 12px
+    ),
+    repeating-linear-gradient(
+      90deg,
+      transparent,
+      transparent 11px,
+      rgba(184, 149, 108, 0.05) 11px,
+      rgba(184, 149, 108, 0.05) 12px
+    );
+}
+
+.cover-ornament {
+  position: absolute;
+  inset: 36px 28px auto;
+  height: 52%;
+  border: 1px solid var(--line);
+  display: grid;
+  place-items: center;
+  overflow: hidden;
+}
+
+.cover-ornament svg { width: 78%; height: 78%; }
+
+.eyebrow {
+  font-size: 11px;
+  letter-spacing: 0.22em;
+  text-transform: uppercase;
+  color: var(--muted);
+  margin-bottom: 14px;
+}
+
+.style-name {
+  font-family: var(--serif);
+  font-size: 50px;
+  font-weight: 400;
+  line-height: 1.05;
+  letter-spacing: -0.02em;
+  color: var(--ink);
+  margin-bottom: 10px;
+}
+
+.style-name[contenteditable="true"] {
+  outline: none;
+  border-bottom: 1px solid transparent;
+  transition: border-color 0.3s var(--ease);
+  cursor: text;
+}
+.style-name[contenteditable="true"]:hover,
+.style-name[contenteditable="true"]:focus {
+  border-bottom-color: var(--gold);
+}
+
+.cover-line {
+  width: 48px;
+  height: 1px;
+  background: var(--accent);
+  margin: 16px 0;
+}
+
+.cover-dek {
+  font-size: 14px;
+  color: var(--muted);
+  max-width: 28ch;
+  line-height: 1.6;
+}
+
+/* Pair slides */
+.slide-pair {
+  gap: 18px;
+}
+
+.pair-top {
+  display: grid;
+  grid-template-columns: 1fr 1.15fr;
+  gap: 14px;
+  flex: 1;
+  min-height: 0;
+}
+
+.swatch {
+  border: 1px solid var(--line);
+  border-radius: var(--radius);
+  position: relative;
+  overflow: hidden;
+  box-shadow: var(--shadow-soft);
+  min-height: 180px;
+}
+
+.vignette {
+  border: 1px solid var(--line);
+  border-radius: var(--radius);
+  position: relative;
+  overflow: hidden;
+  background: #e8e0d4;
+  box-shadow: var(--shadow-soft);
+  min-height: 180px;
+}
+
+.pair-note {
+  border-top: 1px solid var(--line);
+  padding-top: 16px;
+  display: flex;
+  gap: 14px;
+  align-items: flex-start;
+}
+
+.note-index {
+  font-family: var(--serif);
+  font-size: 28px;
+  color: var(--accent);
+  line-height: 1;
+  min-width: 28px;
+}
+
+.note-text {
+  font-size: 14px;
+  color: var(--ink);
+  line-height: 1.55;
+  max-width: 34ch;
+}
+
+.note-label {
+  display: block;
+  font-size: 10px;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  color: var(--muted);
+  margin-bottom: 6px;
+}
+
+/* CTA */
+.slide-cta {
+  justify-content: center;
+  align-items: center;
+  text-align: center;
+  gap: 18px;
+  background:
+    radial-gradient(ellipse at 50% 0%, rgba(154,59,74,0.06), transparent 55%);
+}
+
+.cta-mark {
+  width: 56px;
+  height: 1px;
+  background: var(--gold);
+}
+
+.cta-title {
+  font-family: var(--serif);
+  font-size: 38px;
+  line-height: 1.1;
+  letter-spacing: -0.02em;
+}
+
+.cta-body {
+  font-size: 14px;
+  color: var(--muted);
+  max-width: 28ch;
+  line-height: 1.65;
+}
+
+.palette-row {
+  display: flex;
+  gap: 10px;
+  margin-top: 8px;
+  flex-wrap: wrap;
+  justify-content: center;
+}
+
+.swatch-dot {
+  width: 28px;
+  height: 28px;
+  border-radius: 50%;
+  border: 1px solid var(--line);
+  cursor: pointer;
+  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
+  position: relative;
+}
+.swatch-dot:hover { transform: scale(1.12); }
+.swatch-dot.is-active {
+  box-shadow: 0 0 0 2px var(--surface), 0 0 0 3px var(--ink);
+}
+
+.cta-btn {
+  margin-top: 10px;
+  appearance: none;
+  border: 1px solid var(--ink);
+  background: var(--ink);
+  color: var(--bg);
+  font-family: var(--sans);
+  font-size: 11px;
+  letter-spacing: 0.2em;
+  text-transform: uppercase;
+  padding: 14px 28px;
+  cursor: pointer;
+  transition: background 0.35s var(--ease), color 0.35s var(--ease), transform 0.35s var(--ease);
+}
+.cta-btn:hover {
+  background: transparent;
+  color: var(--ink);
+}
+.cta-btn:active { transform: scale(0.98); }
+
+/* —— Dots + controls —— */
+.chrome {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 14px 22px 18px;
+  border-top: 1px solid var(--line);
+  background: var(--surface);
+}
+
+.dots {
+  display: flex;
+  gap: 8px;
+  align-items: center;
+}
+
+.dot {
+  width: 6px;
+  height: 6px;
+  border-radius: 50%;
+  background: var(--line);
+  border: none;
+  padding: 0;
+  cursor: pointer;
+  transition: background 0.35s var(--ease), transform 0.35s var(--ease);
+}
+.dot[aria-current="true"] {
+  background: var(--ink);
+  transform: scale(1.25);
+}
+
+.nav-btns {
+  display: flex;
+  gap: 6px;
+}
+
+.nav-btn {
+  appearance: none;
+  background: transparent;
+  border: 1px solid var(--line);
+  color: var(--ink);
+  font-family: var(--sans);
+  font-size: 10px;
+  letter-spacing: 0.16em;
+  text-transform: uppercase;
+  padding: 8px 12px;
+  cursor: pointer;
+  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
+}
+.nav-btn:hover {
+  border-color: var(--ink);
+  background: rgba(28,26,23,0.03);
+}
+.nav-btn:disabled {
+  opacity: 0.35;
+  cursor: default;
+}
+
+/* —— Room vignettes (pure CSS) —— */
+.room {
+  position: absolute;
+  inset: 0;
+}
+
+/* shared furniture pieces */
+.wall {
+  position: absolute;
+  inset: 0 0 38% 0;
+}
+.floor {
+  position: absolute;
+  left: 0; right: 0; bottom: 0;
+  height: 38%;
+  background:
+    linear-gradient(180deg, rgba(28,26,23,0.06), transparent 40%),
+    repeating-linear-gradient(
+      90deg,
+      #d9cfc0 0 28px,
+      #d2c6b4 28px 29px
+    );
+}
+.baseboard {
+  position: absolute;
+  left: 0; right: 0;
+  bottom: 38%;
+  height: 4px;
+  background: #f3ebe0;
+  border-top: 1px solid rgba(28,26,23,0.08);
+  border-bottom: 1px solid rgba(28,26,23,0.1);
+}
+.sofa {
+  position: absolute;
+  left: 12%;
+  right: 12%;
+  bottom: 22%;
+  height: 22%;
+  background: #6b4f55;
+  border-radius: 6px 6px 2px 2px;
+  box-shadow: 0 4px 12px rgba(28,26,23,0.12);
+}
+.sofa::before {
+  content: '';
+  position: absolute;
+  left: 6%; right: 6%;
+  top: -28%;
+  height: 38%;
+  background: #7a5a60;
+  border-radius: 4px 4px 0 0;
+}
+.sofa::after {
+  content: '';
+  position: absolute;
+  left: 10%;
+  top: 18%;
+  width: 22%;
+  height: 42%;
+  background: #c4a dig;
+  background: #c9b29a;
+  border-radius: 3px;
+  box-shadow: 26px 0 0 #b8956c, 52px 4px 0 #9a3b4a;
+}
+.table {
+  position: absolute;
+  left: 32%;
+  right: 32%;
+  bottom: 16%;
+  height: 8%;
+  background: #3a322c;
+  border-radius: 1px;
+}
+.table::before {
+  content: '';
+  position: absolute;
+  left: 8%; right: 8%;
+  top: -55%;
+  height: 55%;
+  background: radial-gradient(ellipse at 50% 80%, #efe6d8, #e0d4c2);
+  border: 1px solid rgba(28,26,23,0.08);
+  border-radius: 50%;
+}
+.lamp {
+  position: absolute;
+  width: 10%;
+  right: 14%;
+  bottom: 38%;
+  height: 28%;
+}
+.lamp-shade {
+  position: absolute;
+  top: 0; left: 0; right: 0;
+  height: 38%;
+  background: #f0e6d4;
+  clip-path: polygon(8% 100%, 92% 100%, 100% 0, 0 0);
+  box-shadow: 0 0 24px rgba(240, 230, 212, 0.55);
+}
+.lamp-stem {
+  position: absolute;
+  left: 46%;
+  width: 8%;
+  top: 38%;
+  bottom: 0;
+  background: var(--gold);
+}
+.frame {
+  position: absolute;
+  border: 3px solid var(--gold);
+  background: #f7f1e6;
+  box-shadow: inset 0 0 0 1px rgba(28,26,23,0.06);
+}
+.plant {
+  position: absolute;
+  left: 10%;
+  bottom: 38%;
+  width: 12%;
+  height: 18%;
+}
+.plant-pot {
+  position: absolute;
+  bottom: 0; left: 20%; right: 20%;
+  height: 35%;
+  background: #8a6a4a;
+  clip-path: polygon(10% 0, 90% 0, 100% 100%, 0 100%);
+}
+.plant-leaf {
+  position: absolute;
+  background: #4a6b52;
+  border-radius: 50% 50% 50% 0;
+}
+
+/* Room 1 — parlor */
+.room-1 .wall {
+  background:
+    repeating-linear-gradient(
+      45deg,
+      #e9dfd0 0 10px,
+      #e4d8c6 10px 20px
+    );
+}
+.room-1 .frame { top: 14%; left: 18%; width: 28%; height: 32%; }
+.room-1 .frame-b { top: 18%; left: 52%; width: 22%; height: 26%; border-color: #8a6a4a; }
+
+/* Room 2 — library nook */
+.room-2 .wall {
+  background:
+    repeating-linear-gradient(
+      0deg,
+      #d9cfc3 0 14px,
+      #cfc3b4 14px 15px
+    );
+}
+.room-2 .sofa { background: #3d4a56; }
+.room-2 .sofa::before { background: #4a5866; }
+.room-2 .bookshelf {
+  position: absolute;
+  left: 8%; top: 10%;
+  width: 36%; height: 48%;
+  background:
+    repeating-linear-gradient(
+      90deg,
+      #5c3d2e 0 8px,
+      #6b4a38 8px 10px,
+      #2c241e 10px 18px,
+      #8b3a3a 18px 22px,
+      #1c1a17 22px 26px,
+      #b8956c 26px 30px
+    ),
+    linear-gradient(#3a2a22, #3a2a22);
+  border: 2px solid #2a201a;
+  box-shadow: inset 0 0 0 3px #4a3428;
+}
+.room-2 .sofa { left: 48%; right: 8%; }
+
+/* Room 3 — breakfast bay */
+.room-3 .wall {
+  background:
+    radial-gradient(circle at 20% 30%, rgba(154,59,74,0.15) 0 6%, transparent 6.5%),
+    radial-gradient(circle at 50% 60%, rgba(154,59,74,0.12) 0 5%, transparent 5.5%),
+    radial-gradient(circle at 75% 25%, rgba(154,59,74,0.14) 0 7%, transparent 7.5%),
+    radial-gradient(circle at 40% 80%, rgba(184,149,108,0.18) 0 5%, transparent 5.5%),
+    #efe6d6;
+}
+.room-3 .window {
+  position: absolute;
+  top: 12%; left: 22%; right: 22%;
+  height: 42%;
+  background: linear-gradient(180deg, #c5d4c8, #a8bfb0);
+  border: 4px solid #f5efe4;
+  box-shadow: 0 0 0 1px rgba(28,26,23,0.1), inset 0 0 0 2px #e8dfd0;
+}
+.room-3 .window::before {
+  content: '';
+  position: absolute;
+  inset: 0;
+  background:
+    linear-gradient(var(--gold), var(--gold)) center/100% 2px no-repeat,
+    linear-gradient(var(--gold), var(--gold)) center/2px 100% no-repeat;
+}
+.room-3 .sofa {
+  left: 18%; right: 18%;
+  bottom: 18%;
+  height: 16%;
+  background: #d8c8a8;
+  border-radius: 2px;
+}
+.room-3 .sofa::before { display: none; }
+.room-3 .sofa::after { display: none; }
+.room-3 .chair-l, .room-3 .chair-r {
+  position: absolute;
+  bottom: 20%;
+  width: 14%;
+  height: 18%;
+  background: #6b4f55;
+  border-radius: 3px 3px 0 0;
+}
+.room-3 .chair-l { left: 10%; }
+.room-3 .chair-r { right: 10%; }
+
+/* —— Pattern swatches (distinct motifs) —— */
+/* 1. Chinoiserie vine */
+.pat-chinoiserie {
+  background-color: #f3ebe0;
+  background-image:
+    radial-gradient(ellipse 18px 28px at 30% 35%, transparent 60%, rgba(154,59,74,0.55) 61% 68%, transparent 69%),
+    radial-gradient(ellipse 14px 22px at 68% 62%, transparent 60%, rgba(74,107,82,0.5) 61% 70%, transparent 71%),
+    radial-gradient(circle at 50% 48%, rgba(184,149,108,0.45) 0 3px, transparent 3.5px),
+    radial-gradient(circle at 22% 70%, rgba(154,59,74,0.35) 0 2px, transparent 2.5px),
+    radial-gradient(circle at 78% 28%, rgba(74,107,82,0.4) 0 2.5px, transparent 3px),
+    linear-gradient(125deg, transparent 48%, rgba(74,107,82,0.25) 49% 51%, transparent 52%),
+    linear-gradient(55deg, transparent 46%, rgba(154,59,74,0.2) 47% 49%, transparent 50%);
+}
+
+/* 2. Damask diamond */
+.pat-damask {
+  background-color: #2c333c;
+  background-image:
+    radial-gradient(ellipse 40% 30% at 50% 50%, rgba(184,149,108,0.55) 0 8%, transparent 9%),
+    radial-gradient(ellipse 18% 40% at 50% 50%, rgba(184,149,108,0.4) 0 10%, transparent 11%),
+    linear-gradient(45deg, transparent 46%, rgba(184,149,108,0.22) 47% 53%, transparent 54%),
+    linear-gradient(-45deg, transparent 46%, rgba(184,149,108,0.22) 47% 53%, transparent 54%);
+  background-size: 48px 48px, 48px 48px, 48px 48px, 48px 48px;
+}
+
+/* 3. Botanical stripe */
+.pat-botanical {
+  background-color: #f6f0e6;
+  background-image:
+    radial-gradient(circle at 50% 20%, #9a3b4a 0 2px, transparent 2.5px),
+    radial-gradient(circle at 50% 50%, #4a6b52 0 3px, transparent 3.5px),
+    radial-gradient(circle at 50% 80%, #b8956c 0 2px, transparent 2.5px),
+    linear-gradient(90deg,
+      transparent 0 18%,
+      rgba(154,59,74,0.15) 18% 20%,
+      transparent 20% 48%,
+      rgba(74,107,82,0.18) 48% 52%,
+      transparent 52% 80%,
+      rgba(184,149,108,0.2) 80% 82%,
+      transparent 82%
+    );
+  background-size: 36px 60px, 36px 60px, 36px 60px, 36px 100%;
+}
+
+/* overlay toast */
+.toast {
+  position: absolute;
+  left: 50%;
+  bottom: 88px;
+  transform: translateX(-50%) translateY(12px);
+  background: var(--ink);
+  color: var(--bg);
+  font-size: 11px;
+  letter-spacing: 0.16em;
+  text-transform: uppercase;
+  padding: 12px 20px;
+  opacity: 0;
+  pointer-events: none;
+  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
+  z-index: 20;
+  white-space: nowrap;
+}
+.toast.show {
+  opacity: 1;
+  transform: translateX(-50%) translateY(0);
+}
+
+/* editable palette hint */
+.edit-hint {
+  font-size: 10px;
+  letter-spacing: 0.14em;
+  text-transform: uppercase;
+  color: var(--muted);
+  margin-top: 4px;
+}
+
+@media (max-width: 480px) {
+  .wordmark { font-size: 28px; letter-spacing: 0.14em; }
+  .brand-bar { padding: 0 16px; height: 60px; }
+  :root { --bar-h: 60px; }
+  .style-name { font-size: 40px; }
+  .pair-top { grid-template-columns: 1fr; }
+}
+</style>
+</head>
+<body>
+
+<header class="brand-bar">
+  <div class="wordmark">Designer Wallcoverings</div>
+  <div class="bar-meta">Lookbook · 01</div>
+</header>
+
+<main class="stage">
+  <div class="phone" id="phone">
+    <div class="carousel" id="carousel">
+      <div class="track" id="track">
+
+        <!-- COVER -->
+        <section class="slide slide-cover is-active" data-i="0">
+          <div class="cover-ornament" aria-hidden="true">
+            <svg viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
+              <rect x="20" y="20" width="160" height="160" stroke="#1c1a17" stroke-opacity="0.15" stroke-width="0.75"/>
+              <path d="M100 36 C78 60, 58 78, 58 104 C58 128, 76 146, 100 146 C124 146, 142 128, 142 104 C142 78, 122 60, 100 36Z" stroke="#9a3b4a" stroke-width="1.25" fill="none"/>
+              <path d="M100 52 C86 70, 72 84, 72 104 C72 120, 84 132, 100 132 C116 132, 128 120, 128 104 C128 84, 114 70, 100 52Z" stroke="#b8956c" stroke-width="0.75" fill="none"/>
+              <circle cx="100" cy="104" r="4" fill="#9a3b4a"/>
+              <path d="M100 146 V168 M88 156 H112" stroke="#1c1a17" stroke-opacity="0.35" stroke-width="1"/>
+              <path d="M40 100 H62 M138 100 H160" stroke="#b8956c" stroke-width="0.75" stroke-opacity="0.7"/>
+              <path d="M48 80 Q58 100 48 120 M152 80 Q142 100 152 120" stroke="#4a6b52" stroke-width="1" fill="none" opacity="0.7"/>
+            </svg>
+          </div>
+          <p class="eyebrow">Style Study · Vol. IV</p>
+          <h1 class="style-name" id="styleName" contenteditable="true" spellcheck="false">Grandmillennial</h1>
+          <div class="cover-line"></div>
+          <p class="cover-dek">Heirloom patterns, collected color, and rooms that feel inherited — not staged.</p>
+        </section>
+
+        <!-- SLIDE 1 -->
+        <section class="slide slide-pair" data-i="1">
+          <div class="pair-top">
+            <div class="swatch pat-chinoiserie" title="Chinoiserie vine"></div>
+            <div class="vignette">
+              <div class="room room-1">
+                <div class="wall"></div>
+                <div class="frame"></div>
+                <div class="frame frame-b"></div>
+                <div class="baseboard"></div>
+                <div class="floor"></div>
+                <div class="lamp"><div class="lamp-shade"></div><div class="lamp-stem"></div></div>
+                <div class="sofa"></div>
+                <div class="table"></div>
+              </div>
+            </div>
+          </div>
+          <div class="pair-note">
+            <span class="note-index">01</span>
+            <div>
+              <span class="note-label">Chinoiserie vine</span>
+              <p class="note-text">Paper one accent wall in trailing florals; ground it with oxblood velvet and a gilt frame pair.</p>
+            </div>
+          </div>
+        </section>
+
+        <!-- SLIDE 2 -->
+        <section class="slide slide-pair" data-i="2">
+          <div class="pair-top">
+            <div class="swatch pat-damask" title="Midnight damask"></div>
+            <div class="vignette">
+              <div class="room room-2">
+                <div class="wall"></div>
+                <div class="bookshelf"></div>
+                <div class="baseboard"></div>
+                <div class="floor"></div>
+                <div class="sofa"></div>
+                <div class="table"></div>
+              </div>
+            </div>
+          </div>
+          <div class="pair-note">
+            <span class="note-index">02</span>
+            <div>
+              <span class="note-label">Midnight damask</span>
+              <p class="note-text">Wrap a library nook in ink-dark damask; let brass hardware and leather spines catch the light.</p>
+            </div>
+          </div>
+        </section>
+
+        <!-- SLIDE 3 -->
+        <section class="slide slide-pair" data-i="3">
+          <div class="pair-top">
+            <div class="swatch pat-botanical" title="Botanical stripe"></div>
+            <div class="vignette">
+              <div class="room room-3">
+                <div class="wall"></div>
+                <div class="window"></div>
+                <div class="baseboard"></div>
+                <div class="floor"></div>
+                <div class="chair-l"></div>
+                <div class="chair-r"></div>
+                <div class="sofa"></div>
+              </div>
+            </div>
+          </div>
+          <div class="pair-note">
+            <span class="note-index">03</span>
+            <div>
+              <span class="note-label">Botanical stripe</span>
+              <p class="note-text">Soft vertical rhythm for a breakfast bay — pair with cane chairs and a single rose-madder runner.</p>
+            </div>
+          </div>
+        </section>
+
+        <!-- CTA -->
+        <section class="slide slide-cta" data-i="4">
+          <div class="cta-mark"></div>
+          <h2 class="cta-title">Bring it home</h2>
+          <p class="cta-body">Request sample cuttings in your edited palette. Style name is live — click the cover title to rename.</p>
+          <p class="edit-hint">Tap a chip to recolor accent</p>
+          <div class="palette-row" id="paletteRow" aria-label="Accent palette">
+            <button class="swatch-dot is-active" data-accent="#9a3b4a" data-gold="#b8956c" style="background:#9a3b4a" title="Rose madder"></button>
+            <button class="swatch-dot" data-accent="#2f4a3c" data-gold="#c4a574" style="background:#2f4a3c" title="Deep sage"></button>
+            <button class="swatch-dot" data-accent="#3d4a56" data-gold="#c9a961" style="background:#3d4a56" title="Slate"></button>
+            <button class="swatch-dot" data-accent="#6b3f2a" data-gold="#d4b896" style="background:#6b3f2a" title="Cognac"></button>
+            <button class="swatch-dot" data-accent="#1c1a17" data-gold="#b8956c" style="background:#1c1a17" title="Near black"></button>
+          </div>
+          <button class="cta-btn" id="ctaBtn" type="button">Request samples</button>
+        </section>
+
+      </div>
+    </div>
+
+    <div class="toast" id="toast" role="status">Samples noted — we'll be in touch</div>
+
+    <div class="chrome">
+      <div class="dots" id="dots" role="tablist" aria-label="Slides"></div>
+      <div class="nav-btns">
+        <button class="nav-btn" id="prev" type="button">Prev</button>
+        <button class="nav-btn" id="next" type="button">Next</button>
+      </div>
+    </div>
+  </div>
+</main>
+
+<script>
+(function () {
+  const track = document.getElementById('track');
+  const slides = Array.from(document.querySelectorAll('.slide'));
+  const dotsWrap = document.getElementById('dots');
+  const prev = document.getElementById('prev');
+  const next = document.getElementById('next');
+  const carousel = document.getElementById('carousel');
+  const toast = document.getElementById('toast');
+  const ctaBtn = document.getElementById('ctaBtn');
+  const root = document.documentElement;
+  let i = 0;
+  const n = slides.length;
+
+  // dots
+  slides.forEach((_, idx) => {
+    const b = document.createElement('button');
+    b.className = 'dot';
+    b.type = 'button';
+    b.setAttribute('role', 'tab');
+    b.setAttribute('aria-label', 'Slide ' + (idx + 1));
+    b.addEventListener('click', () => go(idx));
+    dotsWrap.appendChild(b);
+  });
+  const dots = Array.from(dotsWrap.children);
+
+  function go(to) {
+    i = Math.max(0, Math.min(n - 1, to));
+    track.style.transform = 'translateX(' + (-i * 100) + '%)';
+    slides.forEach((s, k) => s.classList.toggle('is-active', k === i));
+    dots.forEach((d, k) => d.setAttribute('aria-current', k === i ? 'true' : 'false'));
+    prev.disabled = i === 0;
+    next.disabled = i === n - 1;
+  }
+
+  prev.addEventListener('click', () => go(i - 1));
+  next.addEventListener('click', () => go(i + 1));
+
+  // swipe
+  let x0 = null, dx = 0, dragging = false;
+  const threshold = 48;
+
+  function onStart(x) {
+    x0 = x;
+    dragging = true;
+    track.style.transition = 'none';
+  }
+  function onMove(x) {
+    if (!dragging || x0 === null) return;
+    dx = x - x0;
+    const pct = (dx / carousel.offsetWidth) * 100;
+    track.style.transform = 'translateX(calc(' + (-i * 100) + '% + ' + pct + '%))';
+  }
+  function onEnd() {
+    if (!dragging) return;
+    track.style.transition = '';
+    if (dx > threshold) go(i - 1);
+    else if (dx < -threshold) go(i + 1);
+    else go(i);
+    x0 = null; dx = 0; dragging = false;
+  }
+
+  carousel.addEventListener('touchstart', e => onStart(e.touches[0].clientX), { passive: true });
+  carousel.addEventListener('touchmove', e => onMove(e.touches[0].clientX), { passive: true });
+  carousel.addEventListener('touchend', onEnd);
+  carousel.addEventListener('mousedown', e => { e.preventDefault(); onStart(e.clientX); });
+  window.addEventListener('mousemove', e => onMove(e.clientX));
+  window.addEventListener('mouseup', onEnd);
+
+  // keyboard
+  window.addEventListener('keydown', e => {
+    if (e.key === 'ArrowRight') go(i + 1);
+    if (e.key === 'ArrowLeft') go(i - 1);
+  });
+
+  // palette chips
+  document.getElementById('paletteRow').addEventListener('click', e => {
+    const btn = e.target.closest('.swatch-dot');
+    if (!btn) return;
+    document.querySelectorAll('.swatch-dot').forEach(d => d.classList.remove('is-active'));
+    btn.classList.add('is-active');
+    root.style.setProperty('--accent', btn.dataset.accent);
+    root.style.setProperty('--gold', btn.dataset.gold);
+  });
+
+  // CTA toast
+  let toastTimer;
+  ctaBtn.addEventListener('click', () => {
+    const name = (document.getElementById('styleName').textContent || 'Grandmillennial').trim();
+    toast.textContent = name + ' · samples requested';
+    toast.classList.add('show');
+    clearTimeout(toastTimer);
+    toastTimer = setTimeout(() => toast.classList.remove('show'), 2600);
+  });
+
+  go(0);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/grok.png b/data/artifacts/70eea6613a73/grok.png
new file mode 100644
index 0000000..e527fdb
Binary files /dev/null and b/data/artifacts/70eea6613a73/grok.png differ
diff --git a/data/artifacts/70eea6613a73/hermes3-8b.html b/data/artifacts/70eea6613a73/hermes3-8b.html
new file mode 100644
index 0000000..ecf68a3
--- /dev/null
+++ b/data/artifacts/70eea6613a73/hermes3-8b.html
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Grandmillennial Lookbook</title>
+<style>
+:root {
+  --bg: #faf8f4;
+  --surface: #ffffff;
+  --text: #1c1a17;
+  --muted: #9b948a;
+  --accent-base: #7d6a45;
+  --accent-hover: #c9a961;
+  --line: rgba(0, 0, 0, .12);
+  --shadow-light: rgba(255, 255, 255, .15);
+  --ease-in-out-quart: cubic-bezier(.165, .84, .44, 1);
+  font-family: -apple-system, "Segoe UI", Helvetica Neue, Arial, sans-serif;
+}
+body {
+  background-color: var(--bg);
+  color: var(--text);
+  margin: 0;
+  padding: 64px;
+  font-size: 16px;
+}
+h1 {
+  display: block;
+  font-family: 'Didot', "Bodoni MT", "Playfair Display", Georgia, serif;
+  color: var(--bg);
+  background-color: var(--text);
+  text-align: center;
+  letter-spacing: .15em;
+  padding: 32px 0;
+}
+header {
+  display: flex;
+  align-items: center;
+  font-family: 'Didot', "Bodoni MT", "Playfair Display", Georgia, serif;
+  color: var(--bg);
+  background-color: var(--text);
+  letter-spacing: .18em;
+  padding: 0 32px;
+}
+.wordmark {
+  font-size: 50px;
+  flex-grow: 1;
+}
+nav {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-left: 24px;
+  color: var(--surface);
+  background-color: var(--muted);
+}
+a, button {
+  font-family: -apple-system, "Segoe UI", Helvetica Neue, Arial, sans-serif;
+  text-transform: uppercase;
+  letter-spacing: .15em;
+  padding: 8px 16px;
+  border-radius: 14px;
+  margin-left: 12px;
+  background-color: var(--surface);
+  color: var(--muted);
+  transition: background-color .3s, color .3s;
+}
+a:hover, button:hover {
+  background-color: var(--accent-hover);
+  color: var(--bg);
+}
+section {
+  display: flex;
+  flex-wrap: wrap;
+  padding: 96px 0;
+}
+.card {
+  flex-basis: calc(33% - 24px);
+  margin-right: 24px;
+  border-radius: 14px;
+  overflow: hidden;
+  box-shadow: 0 8px 24px var(--line), 0 16px 48px rgba(var(--text), .18);
+  transition: transform .7s var(--ease-in-out-quart), box-shadow .3s, opacity .6s;
+}
+.card img {
+  width: 100%;
+  display: block;
+  transition: opacity .4s;
+}
+.card:hover {
+  transform: translateY(-8px);
+  box-shadow: 0 16px 48px rgba(var(--text), .18);
+  opacity: .9;
+}
+.note {
+  position: relative;
+  z-index: 1;
+  background-color: var(--surface);
+  color: var(--muted);
+  padding: 24px;
+  box-shadow: 0 0 24px var(--accent-base) var(--shadow-light);
+}
+.note::before {
+  content: '';
+  position: absolute;
+  top: -8px; left: 0;
+  width: 100%;
+  height: 14px;
+  background-color: var(--muted);
+  box-shadow: 0 8px 24px var(--line);
+}
+.cta {
+  text-align: center;
+  margin-top: 64px;
+}
+.cta a {
+  font-size: 38px;
+  display: block;
+  width: 100%;
+  background-color: var(--accent-base);
+  color: var(--surface);
+  padding: 24px 0;
+  border-radius: 14px;
+}
+@media (max-width: 768px) {
+  h1, header, .card, .cta a {
+    font-size: calc(12px + (20 - 12) * ((100vw - 320px) / 384))
+  }
+}
+</style>
+<body>
+<header class="wordmark">DESIGNER WALLCOVERINGS</header>
+<nav><a href="#">Home</a> | <button>Shop</button></nav>
+<h1>Grandmillennial Lookbook</h1>
+<section>
+  <div class="card">
+    <img src="#grandmillennial" alt="">
+    <div class="note">CLASSIC PATTERNS<br>FOR TIMELESS SPACES</div>
+  </div>
+  <div class="card">
+    <img src="#vibrant-vignette" alt="">
+    <div class="note">ELEGANT COLORS<br>MIXED WITH MODERN FUNK</div>
+  </div>
+  <div class="card">
+    <img src="#cozy-combo" alt="">
+    <div class="note">COMFORTING TEXTURES<br>AND DELICATE DETAILS</div>
+  </div>
+</section>
+<div class="cta"><a href="#">EXPLORE MORE LOOKBOOKS</a></div>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/hermes3-8b.png b/data/artifacts/70eea6613a73/hermes3-8b.png
new file mode 100644
index 0000000..50f019b
Binary files /dev/null and b/data/artifacts/70eea6613a73/hermes3-8b.png differ
diff --git a/data/artifacts/70eea6613a73/hf-qwen-coder-32b.html b/data/artifacts/70eea6613a73/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..3e3f457
--- /dev/null
+++ b/data/artifacts/70eea6613a73/hf-qwen-coder-32b.html
@@ -0,0 +1,204 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Grandmillennial Lookbook</title>
+    <style>
+        :root {
+            --bg: #faf8f4;
+            --surface: #ffffff;
+            --text: #1c1a17;
+            --muted: #9b948a;
+            --accent: #b0472e;
+            --line: #dcdcdc;
+            --shadow: rgba(0, 0, 0, .12);
+            --hover-shadow: rgba(0, 0, 0, .18);
+            --glow: rgba(176, 71, 46, .35);
+            --ease: cubic-bezier(.22, 1, .36, 1);
+        }
+        body {
+            font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+            background-color: var(--bg);
+            color: var(--text);
+            margin: 0;
+            padding: 0;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            height: 100vh;
+        }
+        header {
+            position: fixed;
+            top: 0;
+            left: 0;
+            width: 100%;
+            background-color: var(--bg);
+            padding: 24px;
+            box-shadow: 0 4px 8px rgba(0, 0, 0, .06);
+            z-index: 10;
+        }
+        header h1 {
+            font-family: 'Playfair Display', Georgia, serif;
+            font-size: 50px;
+            letter-spacing: .18em;
+            text-transform: uppercase;
+            margin: 0;
+            color: var(--text);
+        }
+        .carousel {
+            position: relative;
+            width: 90%;
+            max-width: 1200px;
+            overflow: hidden;
+            border-radius: 14px;
+            box-shadow: var(--shadow);
+        }
+        .carousel-inner {
+            display: flex;
+            transition: transform .7s var(--ease);
+        }
+        .slide {
+            min-width: 100%;
+            padding: 96px 24px;
+            box-sizing: border-box;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            background-color: var(--surface);
+            text-align: center;
+        }
+        .slide h2 {
+            font-family: 'Playfair Display', Georgia, serif;
+            font-size: 38px;
+            margin-bottom: 48px;
+        }
+        .slide p {
+            font-size: 16px;
+            color: var(--muted);
+            margin-bottom: 48px;
+        }
+        .pattern-swatch {
+            width: 200px;
+            height: 200px;
+            background-image: linear-gradient(45deg, #b0472e, #2f4c39);
+            border-radius: 14px;
+            box-shadow: var(--shadow);
+            margin-bottom: 48px;
+        }
+        .room-vignette {
+            width: 100%;
+            max-width: 600px;
+            height: 400px;
+            background-color: var(--muted);
+            border-radius: 14px;
+            box-shadow: var(--shadow);
+            margin-bottom: 24px;
+        }
+        .room-vignette::before {
+            content: '';
+            position: absolute;
+            width: 100%;
+            height: 100%;
+            background-image: linear-gradient(90deg, rgba(255, 255, 255, .1), rgba(255, 255, 255, .3));
+        }
+        .dots {
+            display: flex;
+            justify-content: center;
+            margin-top: 48px;
+        }
+        .dot {
+            width: 10px;
+            height: 10px;
+            border-radius: 50%;
+            background-color: var(--muted);
+            margin: 0 8px;
+            cursor: pointer;
+            transition: background-color .3s ease-in-out;
+        }
+        .dot.active {
+            background-color: var(--accent);
+        }
+    </style>
+</head>
+<body>
+    <header>
+        <h1>DESIGNER WALLCOVERINGS</h1>
+    </header>
+    <div class="carousel">
+        <div class="carousel-inner" id="carouselInner">
+            <div class="slide">
+                <h2>GRANDMILLENNIAL</h2>
+                <p>A design style that blends timeless elegance with modern sophistication, perfect for those who appreciate the charm of classic aesthetics.</p>
+            </div>
+            <div class="slide">
+                <div class="pattern-swatch"></div>
+                <div class="room-vignette" style="background-image: linear-gradient(135deg, #f7efe6, #fff9f1);"></div>
+                <p>Subtle textures and warm hues create a cozy yet chic ambiance.</p>
+            </div>
+            <div class="slide">
+                <div class="pattern-swatch" style="background-image: linear-gradient(45deg, #c65f38, #e0a458);"></div>
+                <div class="room-vignette" style="background-image: linear-gradient(90deg, #fff9f1, #f7efe6);"></div>
+                <p>Vivid colors and rich patterns add a touch of opulence to your space.</p>
+            </div>
+            <div class="slide">
+                <div class="pattern-swatch" style="background-image: linear-gradient(135deg, #b0472e, #2f4c39);"></div>
+                <div class="room-vignette" style="background-image: linear-gradient(45deg, #fff9f1, #f7efe6);"></div>
+                <p>Neutral tones and earthy elements bring a sense of calm and balance.</p>
+            </div>
+            <div class="slide">
+                <h2>ELEVATE YOUR SPACE</h2>
+                <p>Discover more luxurious wallcoverings that reflect your personal style.</p>
+            </div>
+        </div>
+        <div class="dots" id="dotsContainer"></div>
+    </div>
+    <script>
+        const slides = document.querySelectorAll('.slide');
+        const dotsContainer = document.getElementById('dotsContainer');
+        let currentSlideIndex = 0;
+
+        function createDots() {
+            slides.forEach((_, index) => {
+                const dot = document.createElement('div');
+                dot.classList.add('dot');
+                dot.addEventListener('click', () => goToSlide(index));
+                dotsContainer.appendChild(dot);
+            });
+            updateActiveDot();
+        }
+
+        function updateActiveDot() {
+            const dots = document.querySelectorAll('.dot');
+            dots.forEach((dot, index) => {
+                if (index === currentSlideIndex) {
+                    dot.classList.add('active');
+                } else {
+                    dot.classList.remove('active');
+                }
+            });
+        }
+
+        function goToSlide(index) {
+            currentSlideIndex = index;
+            const offset = -currentSlideIndex * 100 + '%';
+            document.querySelector('.carousel-inner').style.transform = `translateX(${offset})`;
+            updateActiveDot();
+        }
+
+        function nextSlide() {
+            if (currentSlideIndex < slides.length - 1) {
+                currentSlideIndex++;
+            } else {
+                currentSlideIndex = 0;
+            }
+            goToSlide(currentSlideIndex);
+        }
+
+        createDots();
+
+        setInterval(nextSlide, 5000);
+    </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/hf-qwen-coder-32b.png b/data/artifacts/70eea6613a73/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..bcfc686
Binary files /dev/null and b/data/artifacts/70eea6613a73/hf-qwen-coder-32b.png differ
diff --git a/data/artifacts/70eea6613a73/kimi.html b/data/artifacts/70eea6613a73/kimi.html
new file mode 100644
index 0000000..902456f
--- /dev/null
+++ b/data/artifacts/70eea6613a73/kimi.html
@@ -0,0 +1,1041 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Grandmillennial Lookbook | Designer Wallcoverings</title>
+<style>
+/* DESIGN TOKENS */
+:root {
+  /* Grandmillennial Luxury Palette */
+  --bg: #f7f5f0;
+  --surface: #ffffff;
+  --ink: #1c1a17;
+  --muted: #8b8178;
+  --accent: #2d5a4a; /* Botanical green */
+  --accent-warm: #c9a86c; /* Antique gold */
+  --line: #d4cfc4;
+  --shadow: rgba(28, 26, 23, 0.08);
+  --shadow-deep: rgba(28, 26, 23, 0.15);
+  
+  /* Typography */
+  --font-display: "Didot", "Bodoni MT", "Playfair Display", Georgia, serif;
+  --font-body: -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
+  
+  /* Motion */
+  --ease-swift: cubic-bezier(.22,.9,.24,1);
+  --ease-power: cubic-bezier(.77,0,.18,1);
+  --ease-quint: cubic-bezier(.22,1,.36,1);
+  
+  /* Spacing */
+  --space-xs: 8px;
+  --space-sm: 16px;
+  --space-md: 24px;
+  --space-lg: 40px;
+  --space-xl: 64px;
+}
+
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+}
+
+html {
+  font-size: 16px;
+}
+
+body {
+  font-family: var(--font-body);
+  background: var(--bg);
+  color: var(--ink);
+  line-height: 1.6;
+  overflow-x: hidden;
+}
+
+/* HEADER / WORDMARK */
+header {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 100;
+  background: var(--surface);
+  border-bottom: 1px solid var(--line);
+  padding: var(--space-sm) var(--space-md);
+  display: flex;
+  align-items: center;
+  height: 72px;
+}
+
+.wordmark {
+  font-family: var(--font-display);
+  font-size: 42px;
+  font-weight: 400;
+  letter-spacing: 0.18em;
+  text-transform: uppercase;
+  color: var(--ink);
+  line-height: 1.1;
+}
+
+/* CAROUSEL CONTAINER */
+.carousel-container {
+  position: relative;
+  width: 100%;
+  max-width: 480px;
+  margin: 0 auto;
+  padding-top: 72px;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  background: var(--bg);
+}
+
+.carousel-track {
+  position: relative;
+  flex: 1;
+  overflow: hidden;
+}
+
+.carousel-slides {
+  display: flex;
+  height: 100%;
+  transition: transform 500ms var(--ease-swift);
+}
+
+.slide {
+  min-width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  padding: var(--space-md);
+  gap: var(--space-md);
+}
+
+/* DOTS NAVIGATION */
+.carousel-dots {
+  display: flex;
+  justify-content: center;
+  gap: var(--space-sm);
+  padding: var(--space-md);
+  background: var(--surface);
+  border-top: 1px solid var(--line);
+}
+
+.dot {
+  width: 8px;
+  height: 8px;
+  border-radius: 50%;
+  background: var(--line);
+  border: none;
+  cursor: pointer;
+  transition: all 300ms var(--ease-swift);
+}
+
+.dot.active {
+  background: var(--accent);
+  transform: scale(1.2);
+}
+
+/* SWIPE HINT */
+.swipe-hint {
+  position: absolute;
+  bottom: 80px;
+  left: 50%;
+  transform: translateX(-50%);
+  font-family: var(--font-body);
+  font-size: 11px;
+  letter-spacing: 0.15em;
+  text-transform: uppercase;
+  color: var(--muted);
+  opacity: 0.6;
+  pointer-events: none;
+}
+
+/* COVER SLIDE */
+.slide-cover {
+  justify-content: center;
+  align-items: center;
+  text-align: center;
+  background: var(--surface);
+  position: relative;
+}
+
+.slide-cover::before {
+  content: '';
+  position: absolute;
+  inset: var(--space-md);
+  border: 1px solid var(--line);
+  pointer-events: none;
+}
+
+.cover-content h1 {
+  font-family: var(--font-display);
+  font-size: 50px;
+  font-weight: 400;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ink);
+  margin-bottom: var(--space-sm);
+  line-height: 1.1;
+}
+
+.cover-content .subtitle {
+  font-family: var(--font-body);
+  font-size: 14px;
+  letter-spacing: 0.15em;
+  text-transform: uppercase;
+  color: var(--muted);
+  margin-bottom: var(--space-lg);
+}
+
+.cover-accent {
+  width: 60px;
+  height: 2px;
+  background: var(--accent);
+  margin: 0 auto var(--space-lg);
+}
+
+.cover-year {
+  font-family: var(--font-display);
+  font-size: 14px;
+  letter-spacing: 0.2em;
+  color: var(--muted);
+  font-style: italic;
+}
+
+/* PATTERN SWATCH + VIGNETTE PAIR */
+.pattern-vignette-pair {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  gap: var(--space-md);
+}
+
+.pattern-swatch {
+  height: 35%;
+  border-radius: 4px;
+  position: relative;
+  overflow: hidden;
+  box-shadow: 0 4px 20px var(--shadow);
+}
+
+.room-vignette {
+  flex: 1;
+  border-radius: 4px;
+  position: relative;
+  overflow: hidden;
+  box-shadow: 0 4px 20px var(--shadow);
+  background: linear-gradient(135deg, #f0ebe3 0%, #e8e2d8 100%);
+}
+
+.styling-note {
+  font-family: var(--font-body);
+  font-size: 13px;
+  letter-spacing: 0.05em;
+  color: var(--muted);
+  text-align: center;
+  font-style: italic;
+  padding: var(--space-sm) 0;
+  border-top: 1px solid var(--line);
+}
+
+/* GRANDMILLENNIAL PATTERNS */
+
+/* Pattern 1: Chintz Floral */
+.pattern-chintz {
+  background: 
+    radial-gradient(circle at 30% 30%, rgba(194, 140, 140, 0.4) 0%, transparent 50%),
+    radial-gradient(circle at 70% 60%, rgba(140, 170, 130, 0.3) 0%, transparent 45%),
+    radial-gradient(circle at 40% 80%, rgba(200, 160, 120, 0.35) 0%, transparent 40%),
+    radial-gradient(circle at 80% 20%, rgba(180, 140, 160, 0.3) 0%, transparent 50%),
+    radial-gradient(circle at 20% 70%, rgba(140, 160, 140, 0.35) 0%, transparent 45%),
+    radial-gradient(circle at 60% 40%, rgba(190, 150, 140, 0.25) 0%, transparent 40%),
+    linear-gradient(45deg, #f5f0e8 0%, #ebe4d8 100%);
+  position: relative;
+}
+
+.pattern-chintz::before {
+  content: '';
+  position: absolute;
+  inset: 0;
+  background-image: 
+    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cg fill='none' stroke='%232d5a4a' stroke-width='0.5' opacity='0.3'%3E%3Cpath d='M20 60c0-20 20-35 40-35s40 15 40 35-20 35-40 35-40-15-40-35z'/%3E%3Cpath d='M60 20c20 0 35 20 35 40s-15 40-35 40-35-15-35-40 15-40 35-40z'/%3E%3Ccircle cx='60' cy='60' r='8' fill='%23c9a86c' opacity='0.4'/%3E%3C/g%3E%3C/svg%3E");
+  opacity: 0.6;
+}
+
+/* Pattern 2: Chinese Chippendale Lattice */
+.pattern-lattice {
+  background: 
+    repeating-linear-gradient(
+      45deg,
+      transparent,
+      transparent 10px,
+      rgba(45, 90, 74, 0.1) 10px,
+      rgba(45, 90, 74, 0.1) 11px
+    ),
+    repeating-linear-gradient(
+      -45deg,
+      transparent,
+      transparent 10px,
+      rgba(45, 90, 74, 0.1) 10px,
+      rgba(45, 90, 74, 0.1) 11px
+    ),
+    #f7f5f0;
+  position: relative;
+}
+
+.pattern-lattice::before {
+  content: '';
+  position: absolute;
+  inset: 0;
+  background-image: 
+    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 80 80'%3E%3Cpath d='M0 0h80v80H0z' fill='none'/%3E%3Cpath d='M0 40 L40 0 L80 40 L40 80 Z' fill='none' stroke='%232d5a4a' stroke-width='1.5' opacity='0.25'/%3E%3Ccircle cx='40' cy='40' r='12' fill='none' stroke='%23c9a86c' stroke-width='1' opacity='0.4'/%3E%3C/svg%3E");
+  opacity: 0.8;
+}
+
+/* Pattern 3: Ticking Stripe */
+.pattern-ticking {
+  background: 
+    repeating-linear-gradient(
+      90deg,
+      #f7f5f0,
+      #f7f5f0 8px,
+      #2d5a4a 8px,
+      #2d5a4a 10px,
+      #f7f5f0 10px,
+      #f7f5f0 18px,
+      #1c1a17 18px,
+      #1c1a17 19px,
+      #f7f5f0 19px,
+      #f7f5f0 40px
+    );
+  position: relative;
+}
+
+/* ROOM VIGNETTES (CSS-DRAWN) */
+
+/* Vignette 1: Chintz Living Room */
+.vignette-chintz {
+  position: relative;
+  background: linear-gradient(180deg, #e8e2d8 0%, #d8d0c4 100%);
+}
+
+.vignette-chintz .wall {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 65%;
+  background: 
+    radial-gradient(circle at 20% 40%, rgba(194, 140, 140, 0.2) 0%, transparent 30%),
+    radial-gradient(circle at 80% 30%, rgba(140, 170, 130, 0.15) 0%, transparent 25%),
+    radial-gradient(circle at 50% 60%, rgba(200, 160, 120, 0.2) 0%, transparent 35%),
+    #f0ebe3;
+}
+
+.vignette-chintz .floor {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 35%;
+  background: 
+    repeating-linear-gradient(
+      0deg,
+      #c4b8a8,
+      #c4b8a8 2px,
+      #b8aa98 2px,
+      #b8aa98 20px
+    );
+}
+
+.vignette-chintz .sofa {
+  position: absolute;
+  bottom: 25%;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 140px;
+  height: 80px;
+  background: #8b4513;
+  border-radius: 8px 8px 0 0;
+  box-shadow: 0 -4px 0 rgba(0,0,0,0.1) inset;
+}
+
+.vignette-chintz .sofa::before {
+  content: '';
+  position: absolute;
+  top: -20px;
+  left: 10px;
+  right: 10px;
+  height: 30px;
+  background: #a0522d;
+  border-radius: 10px 10px 0 0;
+}
+
+.vignette-chintz .lamp {
+  position: absolute;
+  bottom: 30%;
+  right: 15%;
+  width: 40px;
+  height: 100px;
+}
+
+.vignette-chintz .lamp-shade {
+  position: absolute;
+  top: 0;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 50px;
+  height: 35px;
+  background: #f5f2ea;
+  border-radius: 50% 50% 10% 10%;
+  box-shadow: 0 2px 8px var(--shadow);
+}
+
+.vignette-chintz .lamp-base {
+  position: absolute;
+  bottom: 0;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 8px;
+  height: 65px;
+  background: var(--accent-warm);
+}
+
+.vignette-chintz .plant {
+  position: absolute;
+  bottom: 30%;
+  left: 10%;
+  width: 50px;
+  height: 80px;
+}
+
+.vignette-chintz .plant-pot {
+  position: absolute;
+  bottom: 0;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 30px;
+  height: 25px;
+  background: #8b7355;
+  border-radius: 0 0 5px 5px;
+}
+
+.vignette-chintz .plant-leaves {
+  position: absolute;
+  top: 0;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 40px;
+  height: 55px;
+  background: 
+    radial-gradient(ellipse at 30% 20%, #4a7c59 0%, transparent 50%),
+    radial-gradient(ellipse at 70% 40%, #5a8c69 0%, transparent 50%),
+    radial-gradient(ellipse at 50% 80%, #3a6c49 0%, transparent 50%);
+  border-radius: 50%;
+}
+
+/* Vignette 2: Lattice Dining Room */
+.vignette-lattice {
+  position: relative;
+  background: linear-gradient(180deg, #e8e2d8 0%, #d8d0c4 100%);
+}
+
+.vignette-lattice .wall {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 70%;
+  background: 
+    repeating-linear-gradient(
+      45deg,
+      transparent,
+      transparent 15px,
+      rgba(45, 90, 74, 0.08) 15px,
+      rgba(45, 90, 74, 0.08) 16px
+    ),
+    repeating-linear-gradient(
+      -45deg,
+      transparent,
+      transparent 15px,
+      rgba(45, 90, 74, 0.08) 15px,
+      rgba(45, 90, 74, 0.08) 16px
+    ),
+    #f5f0e8;
+}
+
+.vignette-lattice .floor {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 30%;
+  background: #b8a898;
+}
+
+.vignette-lattice .table {
+  position: absolute;
+  bottom: 25%;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 120px;
+  height: 70px;
+  background: #6b4423;
+  border-radius: 60px 60px 0 0;
+  box-shadow: 0 8px 20px var(--shadow-deep);
+}
+
+.vignette-lattice .table::before {
+  content: '';
+  position: absolute;
+  top: -10px;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 100px;
+  height: 20px;
+  background: #7d5432;
+  border-radius: 50%;
+}
+
+.vignette-lattice .chair {
+  position: absolute;
+  bottom: 28%;
+  width: 35px;
+  height: 60px;
+  background: #8b4513;
+  border-radius: 5px 5px 0 0;
+}
+
+.vignette-lattice .chair:nth-child(3) { left: 15%; }
+.vignette-lattice .chair:nth-child(4) { right: 15%; }
+
+.vignette-lattice .chair::before {
+  content: '';
+  position: absolute;
+  top: -15px;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 30px;
+  height: 20px;
+  background: #a0522d;
+  border-radius: 5px 5px 0 0;
+}
+
+.vignette-lattice .chandelier {
+  position: absolute;
+  top: 10%;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 60px;
+  height: 80px;
+}
+
+.vignette-lattice .chandelier-chain {
+  position: absolute;
+  top: 0;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 2px;
+  height: 30px;
+  background: var(--accent-warm);
+}
+
+.vignette-lattice .chandelier-body {
+  position: absolute;
+  top: 30px;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 40px;
+  height: 40px;
+  background: 
+    radial-gradient(circle at 30% 30%, var(--accent-warm) 0%, transparent 30%),
+    radial-gradient(circle at 70% 30%, var(--accent-warm) 0%, transparent 30%),
+    radial-gradient(circle at 50% 70%, var(--accent-warm) 0%, transparent 30%);
+  opacity: 0.8;
+}
+
+/* Vignette 3: Stripe Bedroom */
+.vignette-stripe {
+  position: relative;
+  background: linear-gradient(180deg, #e8e2d8 0%, #d8d0c4 100%);
+}
+
+.vignette-stripe .wall {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 60%;
+  background: 
+    repeating-linear-gradient(
+      90deg,
+      #f7f5f0,
+      #f7f5f0 15px,
+      #2d5a4a 15px,
+      #2d5a4a 17px,
+      #f7f5f0 17px,
+      #f7f5f0 35px,
+      #1c1a17 35px,
+      #1c1a17 36px,
+      #f7f5f0 36px,
+      #f7f5f0 70px
+    ),
+    #f5f0e8;
+  opacity: 0.9;
+}
+
+.vignette-stripe .floor {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 40%;
+  background: 
+    linear-gradient(180deg, #c4b8a8 0%, #b8aa98 100%);
+}
+
+.vignette-stripe .bed {
+  position: absolute;
+  bottom: 30%;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 160px;
+  height: 90px;
+  background: #fff;
+  border-radius: 5px;
+  box-shadow: 0 4px 15px var(--shadow-deep);
+}
+
+.vignette-stripe .bed-headboard {
+  position: absolute;
+  top: -40px;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 140px;
+  height: 50px;
+  background: 
+    linear-gradient(90deg, 
+      #8b4513 0%, 
+      #a0522d 20%, 
+      #8b4513 40%, 
+      #a0522d 60%, 
+      #8b4513 80%, 
+      #a0522d 100%
+    );
+  border-radius: 10px 10px 0 0;
+}
+
+.vignette-stripe .pillow {
+  position: absolute;
+  top: 10px;
+  width: 45px;
+  height: 30px;
+  background: #f5f2ea;
+  border-radius: 8px;
+  box-shadow: 0 2px 5px var(--shadow);
+}
+
+.vignette-stripe .pillow:nth-child(2) { left: 20px; }
+.vignette-stripe .pillow:nth-child(3) { right: 20px; }
+
+.vignette-stripe .blanket {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 50px;
+  background: 
+    repeating-linear-gradient(
+      0deg,
+      #2d5a4a,
+      #2d5a4a 8px,
+      #f7f5f0 8px,
+      #f7f5f0 16px
+    );
+  border-radius: 0 0 5px 5px;
+}
+
+.vignette-stripe .side-table {
+  position: absolute;
+  bottom: 32%;
+  right: 8%;
+  width: 35px;
+  height: 45px;
+  background: #6b4423;
+  border-radius: 3px;
+}
+
+.vignette-stripe .lamp-small {
+  position: absolute;
+  bottom: 55%;
+  right: 10%;
+  width: 25px;
+  height: 50px;
+}
+
+.vignette-stripe .lamp-small-shade {
+  position: absolute;
+  top: 0;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 30px;
+  height: 20px;
+  background: #f5f2ea;
+  border-radius: 40% 40% 10% 10%;
+}
+
+.vignette-stripe .lamp-small-base {
+  position: absolute;
+  bottom: 0;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 4px;
+  height: 30px;
+  background: var(--accent-warm);
+}
+
+/* CTA SLIDE */
+.slide-cta {
+  justify-content: center;
+  align-items: center;
+  text-align: center;
+  background: var(--surface);
+  position: relative;
+}
+
+.slide-cta::before {
+  content: '';
+  position: absolute;
+  inset: var(--space-md);
+  border: 1px solid var(--line);
+  pointer-events: none;
+}
+
+.cta-content {
+  padding: var(--space-xl);
+}
+
+.cta-content h2 {
+  font-family: var(--font-display);
+  font-size: 38px;
+  font-weight: 400;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ink);
+  margin-bottom: var(--space-sm);
+  line-height: 1.1;
+}
+
+.cta-content p {
+  font-family: var(--font-body);
+  font-size: 14px;
+  color: var(--muted);
+  margin-bottom: var(--space-lg);
+  letter-spacing: 0.02em;
+}
+
+.cta-button {
+  display: inline-block;
+  padding: var(--space-sm) var(--space-lg);
+  background: var(--ink);
+  color: var(--surface);
+  font-family: var(--font-body);
+  font-size: 11px;
+  letter-spacing: 0.15em;
+  text-transform: uppercase;
+  text-decoration: none;
+  border-radius: 2px;
+  transition: all 300ms var(--ease-swift);
+  border: 1px solid var(--ink);
+}
+
+.cta-button:hover {
+  background: transparent;
+  color: var(--ink);
+}
+
+.cta-accent {
+  width: 40px;
+  height: 1px;
+  background: var(--accent);
+  margin: var(--space-lg) auto;
+}
+
+/* EDITABLE STYLE NAME */
+.editable-title {
+  cursor: text;
+  border-bottom: 1px solid transparent;
+  transition: border-color 200ms;
+}
+
+.editable-title:hover {
+  border-bottom-color: var(--line);
+}
+
+.editable-title:focus {
+  outline: none;
+  border-bottom-color: var(--accent);
+}
+
+/* SLIDE TRANSITION ANIMATIONS */
+.slide-enter {
+  opacity: 0;
+  transform: translateX(30px);
+}
+
+.slide-enter-active {
+  opacity: 1;
+  transform: translateX(0);
+  transition: all 600ms var(--ease-quint);
+}
+
+/* PATTERN LABELS (Minimal, elegant) */
+.pattern-label {
+  position: absolute;
+  bottom: var(--space-sm);
+  left: var(--space-sm);
+  font-family: var(--font-body);
+  font-size: 10px;
+  letter-spacing: 0.15em;
+  text-transform: uppercase;
+  color: var(--ink);
+  background: rgba(247, 245, 240, 0.9);
+  padding: 4px 8px;
+  border-radius: 2px;
+}
+
+/* RESPONSIVE */
+@media (max-width: 480px) {
+  .wordmark {
+    font-size: 36px;
+  }
+  
+  .cover-content h1 {
+    font-size: 42px;
+  }
+  
+  .cta-content h2 {
+    font-size: 32px;
+  }
+}
+
+@media (max-width: 380px) {
+  .wordmark {
+    font-size: 32px;
+  }
+  
+  .cover-content h1 {
+    font-size: 36px;
+  }
+}
+</style>
+</head>
+<body>
+
+<header>
+  <div class="wordmark">Designer Wallcoverings</div>
+</header>
+
+<div class="carousel-container">
+  <div class="carousel-track">
+    <div class="carousel-slides" id="track">
+      
+      <!-- Slide 1: Cover -->
+      <div class="slide slide-cover">
+        <div class="cover-content">
+          <div class="cover-accent"></div>
+          <h1 class="editable-title" contenteditable="true">Grandmillennial</h1>
+          <p class="subtitle">The New Traditional</p>
+          <p class="cover-year">Est. MMXXV</p>
+        </div>
+      </div>
+      
+      <!-- Slide 2: Chintz -->
+      <div class="slide">
+        <div class="pattern-vignette-pair">
+          <div class="pattern-swatch pattern-chintz">
+            <span class="pattern-label">English Chintz</span>
+          </div>
+          <div class="room-vignette vignette-chintz">
+            <div class="wall"></div>
+            <div class="floor"></div>
+            <div class="plant">
+              <div class="plant-leaves"></div>
+              <div class="plant-pot"></div>
+            </div>
+            <div class="sofa"></div>
+            <div class="lamp">
+              <div class="lamp-base"></div>
+              <div class="lamp-shade"></div>
+            </div>
+          </div>
+        </div>
+        <p class="styling-note">"Layer florals on cream grounds with honey-toned woods"</p>
+      </div>
+      
+      <!-- Slide 3: Lattice -->
+      <div class="slide">
+        <div class="pattern-vignette-pair">
+          <div class="pattern-swatch pattern-lattice">
+            <span class="pattern-label">Chippendale Lattice</span>
+          </div>
+          <div class="room-vignette vignette-lattice">
+            <div class="wall"></div>
+            <div class="floor"></div>
+            <div class="chair"></div>
+            <div class="table"></div>
+            <div class="chair"></div>
+            <div class="chandelier">
+              <div class="chandelier-chain"></div>
+              <div class="chandelier-body"></div>
+            </div>
+          </div>
+        </div>
+        <p class="styling-note">"Fretwork patterns bring architectural elegance to dining spaces"</p>
+      </div>
+      
+      <!-- Slide 4: Ticking -->
+      <div class="slide">
+        <div class="pattern-vignette-pair">
+          <div class="pattern-swatch pattern-ticking">
+            <span class="pattern-label">Botanical Ticking</span>
+          </div>
+          <div class="room-vignette vignette-stripe">
+            <div class="wall"></div>
+            <div class="floor"></div>
+            <div class="bed">
+              <div class="bed-headboard"></div>
+              <div class="pillow"></div>
+              <div class="pillow"></div>
+              <div class="blanket"></div>
+            </div>
+            <div class="side-table"></div>
+            <div class="lamp-small">
+              <div class="lamp-small-base"></div>
+              <div class="lamp-small-shade"></div>
+            </div>
+          </div>
+        </div>
+        <p class="styling-note">"Classic stripes in forest green feel fresh, not farmhouse"</p>
+      </div>
+      
+      <!-- Slide 5: CTA -->
+      <div class="slide slide-cta">
+        <div class="cta-content">
+          <h2>Curate Your<br>Collection</h2>
+          <div class="cta-accent"></div>
+          <p>Discover 200+ heritage patterns<br>reimagined for today</p>
+          <a href="#" class="cta-button" onclick="event.preventDefault(); alert('Visit designerwallcoverings.com');">Explore Lookbook</a>
+        </div>
+      </div>
+      
+    </div>
+  </div>
+  
+  <div class="swipe-hint">Swipe to explore</div>
+  
+  <div class="carousel-dots" id="dots">
+    <button class="dot active" data-index="0"></button>
+    <button class="dot" data-index="1"></button>
+    <button class="dot" data-index="2"></button>
+    <button class="dot" data-index="3"></button>
+    <button class="dot" data-index="4"></button>
+  </div>
+</div>
+
+<script>
+(function() {
+  const track = document.getElementById('track');
+  const dots = document.querySelectorAll('.dot');
+  const slides = document.querySelectorAll('.slide');
+  let currentIndex = 0;
+  let startX = 0;
+  let isDragging = false;
+  
+  function goToSlide(index) {
+    if (index < 0) index = 0;
+    if (index >= slides.length) index = slides.length - 1;
+    currentIndex = index;
+    
+    track.style.transform = `translateX(-${currentIndex * 100}%)`;
+    
+    dots.forEach((dot, i) => {
+      dot.classList.toggle('active', i === currentIndex);
+    });
+  }
+  
+  // Dot navigation
+  dots.forEach((dot, i) => {
+    dot.addEventListener('click', () => goToSlide(i));
+  });
+  
+  // Touch swipe
+  const container = document.querySelector('.carousel-track');
+  
+  container.addEventListener('touchstart', (e) => {
+    startX = e.touches[0].clientX;
+    isDragging = true;
+  });
+  
+  container.addEventListener('touchmove', (e) => {
+    if (!isDragging) return;
+  });
+  
+  container.addEventListener('touchend', (e) => {
+    if (!isDragging) return;
+    isDragging = false;
+    
+    const endX = e.changedTouches[0].clientX;
+    const diff = startX - endX;
+    
+    if (Math.abs(diff) > 50) {
+      if (diff > 0) {
+        goToSlide(currentIndex + 1);
+      } else {
+        goToSlide(currentIndex - 1);
+      }
+    }
+  });
+  
+  // Mouse drag for desktop
+  container.addEventListener('mousedown', (e) => {
+    startX = e.clientX;
+    isDragging = true;
+  });
+  
+  container.addEventListener('mousemove', (e) => {
+    if (!isDragging) return;
+  });
+  
+  container.addEventListener('mouseup', (e) => {
+    if (!isDragging) return;
+    isDragging = false;
+    
+    const endX = e.clientX;
+    const diff = startX - endX;
+    
+    if (Math.abs(diff) > 50) {
+      if (diff > 0) {
+        goToSlide(currentIndex + 1);
+      } else {
+        goToSlide(currentIndex - 1);
+      }
+    }
+  });
+  
+  container.addEventListener('mouseleave', () => {
+    isDragging = false;
+  });
+  
+  // Keyboard navigation
+  document.addEventListener('keydown', (e) => {
+    if (e.key === 'ArrowRight') goToSlide(currentIndex + 1);
+    if (e.key === 'ArrowLeft') goToSlide(currentIndex - 1);
+  });
+})();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/kimi.png b/data/artifacts/70eea6613a73/kimi.png
new file mode 100644
index 0000000..51f7eba
Binary files /dev/null and b/data/artifacts/70eea6613a73/kimi.png differ
diff --git a/data/artifacts/70eea6613a73/qwen25-7b.html b/data/artifacts/70eea6613a73/qwen25-7b.html
new file mode 100644
index 0000000..6a57d82
--- /dev/null
+++ b/data/artifacts/70eea6613a73/qwen25-7b.html
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Grandmillennial Lookbook</title>
+    <style>
+        :root {
+            --bg: #f7efe6;
+            --surface: #fff9f1;
+            --text: #3a2c22;
+            --muted: #a08c7a;
+            --accent: #c65f38;
+            --line: 1px solid var(--text);
+            --shadow: 0 8px 24px rgba(0, 0, 0, .12), hover 0 16px 48px rgba(0, 0, 0, .18);
+            --ease: cubic-bezier(.22,1,.36,1) both;
+        }
+
+        body {
+            margin: 0;
+            padding: 0;
+            background-color: var(--bg);
+            color: var(--text);
+            font-family: 'Didot', 'Bodoni MT', Georgia, serif;
+            overflow-x: hidden;
+            height: 100vh;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+        }
+
+        header {
+            position: fixed;
+            top: 0;
+            left: 0;
+            width: 100%;
+            background-color: var(--surface);
+            padding: 24px;
+            color: var(--text);
+            font-size: 48px;
+            text-transform: uppercase;
+            letter-spacing: .15em;
+        }
+
+        .carousel {
+            display: flex;
+            overflow-x: auto;
+            gap: 32px;
+            justify-content: center;
+            align-items: center;
+        }
+
+        .slide {
+            width: 300px;
+            max-height: 480px;
+            background-color: var(--surface);
+            border-radius: 14px;
+            overflow: hidden;
+            flex-shrink: 0;
+        }
+
+        .swatch, .vignette {
+            display: inline-block;
+            width: 150px;
+            height: 300px;
+            margin: auto;
+            background-size: cover;
+        }
+
+        .swatch {
+            box-shadow: var(--shadow);
+            transition: transform .7s var(--ease), box-shadow .7s var(--ease);
+        }
+
+        .vignette {
+            opacity: 1;
+            filter: drop-shadow(0px 8px 24px rgba(0, 0, 0, 0.3));
+        }
+
+        .swatch:hover {
+            transform: translateY(-16px);
+        }
+
+        .title {
+            text-align: center;
+            font-size: 24px;
+            margin-top: 24px;
+        }
+
+        footer {
+            position: fixed;
+            bottom: 0;
+            left: 0;
+            width: 100%;
+            background-color: var(--surface);
+            padding: 24px;
+            text-align: center;
+            font-family: 'Didot', 'Bodoni MT', Georgia, serif;
+        }
+
+        .cta {
+            display: inline-block;
+            padding: 16px 32px;
+            margin-top: 24px;
+            background-color: var(--accent);
+            color: #fff;
+            text-decoration: none;
+            font-size: 18px;
+            letter-spacing: .15em;
+        }
+
+        @keyframes fadeUp {
+            from { opacity: 0; transform: translateY(28px); }
+            to { opacity: 1; transform: translateY(0); }
+        }
+
+        section {
+            animation: ambient-bg 18s linear infinite alternate;
+        }
+
+        .fade-up {
+            animation-name: fadeUp;
+        }
+
+        @keyframes ambient-bg {
+            from { background-position: 0%; }
+            to { background-position: -1200%; }
+        }
+    </style>
+</head>
+<body>
+
+<header class="header">
+    <span>DESIGNER WALLCOVERINGS</span>
+</header>
+
+<div class="carousel">
+    <div class="slide fade-up">
+        <div class="swatch" style="background: linear-gradient(to bottom, var(--accent) 0%, rgba(255, 86, 56, 0.7) 100%);"></div>
+        <div class="vignette" style="background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="150" height="300"><rect width="150" height="300" fill="#fff9f1"/></svg>');"></div>
+        <div class="title">Warm Living</div>
+    </div>
+
+    <div class="slide fade-up">
+        <div class="swatch" style="background: linear-gradient(to bottom, var(--accent) 0%, rgba(255, 86, 56, 0.7) 100%);"></div>
+        <div class="vignette" style="background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="150" height="300"><rect width="150" height="300" fill="#fff9f1"/></svg>');"></div>
+        <div class="title">Cozy Corner</div>
+    </div>
+
+    <div class="slide fade-up">
+        <div class="swatch" style="background: linear-gradient(to bottom, var(--accent) 0%, rgba(255, 86, 56, 0.7) 100%);"></div>
+        <div class="vignette" style="background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="150" height="300"><rect width="150" height="300" fill="#fff9f1"/></svg>');"></div>
+        <div class="title">Rustic Retreat</div>
+    </div>
+
+    <footer class="cta">
+        Explore More
+    </footer>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/qwen25-7b.png b/data/artifacts/70eea6613a73/qwen25-7b.png
new file mode 100644
index 0000000..5ee874b
Binary files /dev/null and b/data/artifacts/70eea6613a73/qwen25-7b.png differ
diff --git a/data/artifacts/70eea6613a73/qwen3-14b.html b/data/artifacts/70eea6613a73/qwen3-14b.html
new file mode 100644
index 0000000..c5a3c41
--- /dev/null
+++ b/data/artifacts/70eea6613a73/qwen3-14b.html
@@ -0,0 +1,272 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <title>Design Lookbook</title>
+  <style>
+    :root {
+      --bg: #faf8f4;
+      --surface: #ffffff;
+      --text: #1c1a17;
+      --muted: #9b948a;
+      --accent: #b0472e;
+      --line: #e8e5e0;
+      --shadow: 0 0 24px rgba(0, 0, 0, 0.1);
+      --ease: cubic-bezier(0.22, 1, 0.36, 1);
+    }
+
+    * {
+      box-sizing: border-box;
+      margin: 0;
+      padding: 0;
+    }
+
+    body {
+      background: var(--bg);
+      color: var(--text);
+      font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+      line-height: 1.6;
+      overflow-x: hidden;
+    }
+
+    header {
+      position: fixed;
+      top: 0;
+      left: 0;
+      width: 100%;
+      background: var(--surface);
+      padding: 16px 32px;
+      font-family: 'Playfair Display', Georgia, serif;
+      font-size: 40px;
+      letter-spacing: 0.18em;
+      text-transform: uppercase;
+      color: var(--text);
+      z-index: 1000;
+    }
+
+    .carousel {
+      position: relative;
+      width: 100%;
+      height: 100vh;
+      overflow: hidden;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: var(--bg);
+      padding-top: 96px;
+    }
+
+    .slide {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      opacity: 0;
+      transform: translateY(28px);
+      transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
+      pointer-events: none;
+      background: var(--surface);
+      box-shadow: var(--shadow);
+      border-radius: 14px;
+      padding: 32px;
+      font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+      text-align: center;
+    }
+
+    .slide.active {
+      opacity: 1;
+      transform: translateY(0);
+      pointer-events: auto;
+    }
+
+    .slide h1 {
+      font-size: 48px;
+      margin-bottom: 24px;
+      font-family: 'Playfair Display', Georgia, serif;
+      color: var(--text);
+    }
+
+    .slide .pattern {
+      width: 200px;
+      height: 200px;
+      margin-bottom: 24px;
+      background: repeating-conic-gradient(
+        var(--accent) 0% 25%,
+        var(--muted) 25% 50%,
+        var(--surface) 50% 75%,
+        var(--text) 75% 100%
+      );
+      border: 1px solid var(--line);
+      border-radius: 14px;
+      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);
+    }
+
+    .slide .room {
+      width: 300px;
+      height: 200px;
+      background: linear-gradient(135deg, var(--surface), var(--bg));
+      border: 1px solid var(--line);
+      border-radius: 14px;
+      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);
+      margin-bottom: 24px;
+    }
+
+    .slide .note {
+      font-size: 16px;
+      color: var(--muted);
+      margin-bottom: 48px;
+    }
+
+    .slide .cta {
+      font-size: 24px;
+      font-weight: bold;
+      color: var(--accent);
+      cursor: pointer;
+    }
+
+    .dots {
+      position: absolute;
+      bottom: 48px;
+      left: 50%;
+      transform: translateX(-50%);
+      display: flex;
+      gap: 16px;
+    }
+
+    .dot {
+      width: 12px;
+      height: 12px;
+      background: var(--muted);
+      border-radius: 50%;
+      transition: background 0.3s var(--ease);
+    }
+
+    .dot.active {
+      background: var(--accent);
+    }
+
+    @keyframes fadeUp {
+      from {
+        opacity: 0;
+        transform: translateY(28px);
+      }
+      to {
+        opacity: 1;
+        transform: translateY(0);
+      }
+    }
+
+    @keyframes drift {
+      0% { background-position: 0% 50%; }
+      100% { background-position: 100% 50%; }
+    }
+
+    body {
+      background: linear-gradient(135deg, var(--bg), var(--surface)) fixed;
+      animation: drift 18s linear infinite;
+    }
+  </style>
+</head>
+<body>
+  <header>DESIGNER WALLCOVERINGS</header>
+  <div class="carousel" id="carousel">
+    <div class="slide active" data-index="0">
+      <h1>GRANDMILL ennEIAL</h1>
+    </div>
+    <div class="slide" data-index="1">
+      <h1>Pattern Swatch</h1>
+      <div class="pattern"></div>
+      <div class="room"></div>
+      <div class="note">Soft textures meet refined geometry.</div>
+    </div>
+    <div class="slide" data-index="2">
+      <h1>Pattern Swatch</h1>
+      <div class="pattern" style="background: repeating-linear-gradient(45deg, var(--accent) 0%, var(--muted) 50%, var(--accent) 100%);"></div>
+      <div class="room" style="background: linear-gradient(135deg, var(--surface), var(--bg));"></div>
+      <div class="note">Subtle floral accents in rich tones.</div>
+    </div>
+    <div class="slide" data-index="3">
+      <h1>Pattern Swatch</h1>
+      <div class="pattern" style="background: repeating-radial-gradient(circle at 30% 30%, var(--accent) 0%, var(--muted) 40%, var(--surface) 60%);"></div>
+      <div class="room" style="background: linear-gradient(135deg, var(--bg), var(--surface));"></div>
+      <div class="note">Opulent damask meets traditional craftsmanship.</div>
+    </div>
+    <div class="slide" data-index="4">
+      <h1>Explore More</h1>
+      <div class="cta">Discover the Collection</div>
+    </div>
+  </div>
+  <div class="dots" id="dots">
+    <div class="dot active"></div>
+    <div class="dot"></div>
+    <div class="dot"></div>
+    <div class="dot"></div>
+    <div class="dot"></div>
+  </div>
+  <script>
+    const carousel = document.getElementById('carousel');
+    const slides = document.querySelectorAll('.slide');
+    const dots = document.querySelectorAll('.dot');
+    let currentIndex = 0;
+
+    function showSlide(index) {
+      slides.forEach((slide, i) => {
+        slide.classList.remove('active');
+        if (i === index) {
+          slide.classList.add('active');
+        }
+      });
+      dots.forEach((dot, i) => {
+        dot.classList.toggle('active', i === index);
+      });
+    }
+
+    function nextSlide() {
+      currentIndex = (currentIndex + 1) % slides.length;
+      showSlide(currentIndex);
+    }
+
+    function prevSlide() {
+      currentIndex = (currentIndex - 1 + slides.length) % slides.length;
+      showSlide(currentIndex);
+    }
+
+    // Auto-advance every 6 seconds
+    setInterval(nextSlide, 6000);
+
+    // Swipe detection
+    let startX = 0;
+    let endX = 0;
+
+    carousel.addEventListener('touchstart', e => {
+      startX = e.touches[0].clientX;
+    });
+
+    carousel.addEventListener('touchmove', e => {
+      endX = e.touches[0].clientX;
+    });
+
+    carousel.addEventListener('touchend', () => {
+      if (startX - endX > 50) {
+        nextSlide();
+      } else if (startX - endX < -50) {
+        prevSlide();
+      }
+    });
+
+    // Dot click
+    dots.forEach((dot, index) => {
+      dot.addEventListener('click', () => {
+        currentIndex = index;
+        showSlide(index);
+      });
+    });
+  </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/70eea6613a73/qwen3-14b.png b/data/artifacts/70eea6613a73/qwen3-14b.png
new file mode 100644
index 0000000..9adccae
Binary files /dev/null and b/data/artifacts/70eea6613a73/qwen3-14b.png differ
diff --git a/data/challenges.json b/data/challenges.json
index a384238..265dcf4 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -2080,7 +2080,14 @@
         "started_at": "2026-07-23T13:54:49.362Z",
         "finished_at": "2026-07-23T13:55:44.602Z",
         "bytes": 3531,
-        "thumb": true
+        "thumb": true,
+        "aiScore": 6.8,
+        "aiReason": "The game fulfills the challenge but lacks some visual polish and detail.",
+        "aiScores": {
+          "qwen2.5vl:7b": 7,
+          "minicpm-v:latest": 6.5
+        },
+        "aiSpread": 0.5
       },
       {
         "model": "gemma3-12b",
@@ -29124,95 +29131,129 @@
     "runs": [
       {
         "model": "qwen3-14b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.710Z"
+        "seconds": 52,
+        "cost": 0,
+        "started_at": "2026-07-25T14:59:57.530Z",
+        "finished_at": "2026-07-25T15:00:49.611Z",
+        "queued_at": "2026-07-25T14:59:53.710Z",
+        "bytes": 6880,
+        "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-25T14:59:53.722Z"
+        "seconds": 58,
+        "cost": 0,
+        "started_at": "2026-07-25T15:00:49.621Z",
+        "finished_at": "2026-07-25T15:01:47.970Z",
+        "queued_at": "2026-07-25T14:59:53.722Z",
+        "bytes": 7179,
+        "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-25T14:59:53.730Z"
+        "seconds": 18,
+        "cost": 0,
+        "started_at": "2026-07-25T15:01:47.984Z",
+        "finished_at": "2026-07-25T15:02:05.935Z",
+        "queued_at": "2026-07-25T14:59:53.730Z",
+        "bytes": 3593,
+        "thumb": true
       },
       {
         "model": "qwen25-7b",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 35,
+        "cost": 0,
         "started_at": "2026-07-25T14:59:53.761Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.735Z"
+        "finished_at": "2026-07-25T15:00:28.547Z",
+        "queued_at": "2026-07-25T14:59:53.735Z",
+        "bytes": 4850,
+        "thumb": true
       },
       {
         "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-25T14:59:53.739Z"
+        "seconds": 84,
+        "cost": 0,
+        "started_at": "2026-07-25T15:02:05.950Z",
+        "finished_at": "2026-07-25T15:03:30.087Z",
+        "queued_at": "2026-07-25T14:59:53.739Z",
+        "bytes": 6937,
+        "thumb": true
       },
       {
         "model": "claude-code",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 95,
+        "cost": 0,
         "started_at": "2026-07-25T14:59:53.767Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.743Z"
+        "finished_at": "2026-07-25T15:01:29.157Z",
+        "queued_at": "2026-07-25T14:59:53.743Z",
+        "bytes": 18609,
+        "thumb": true
       },
       {
         "model": "kimi",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 161,
+        "cost": 0.0231,
         "started_at": "2026-07-25T14:59:53.772Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.747Z"
+        "finished_at": "2026-07-25T15:02:35.084Z",
+        "queued_at": "2026-07-25T14:59:53.747Z",
+        "toolCalls": [
+          "opendesign",
+          "opendesign",
+          "hyperframes"
+        ],
+        "bytes": 23067,
+        "thumb": true
       },
       {
         "model": "gpt",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 74,
+        "cost": 0.1439,
         "started_at": "2026-07-25T14:59:53.778Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.752Z"
+        "finished_at": "2026-07-25T15:01:08.049Z",
+        "queued_at": "2026-07-25T14:59:53.752Z",
+        "toolCalls": [
+          "opendesign",
+          "opendesign",
+          "hyperframes"
+        ],
+        "bytes": 32557,
+        "thumb": true
       },
       {
         "model": "grok",
-        "status": "running",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
+        "seconds": 120,
+        "cost": 0.1476,
         "started_at": "2026-07-25T14:59:53.783Z",
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.757Z"
+        "finished_at": "2026-07-25T15:01:53.328Z",
+        "queued_at": "2026-07-25T14:59:53.757Z",
+        "toolCalls": [
+          "opendesign",
+          "opendesign",
+          "hyperframes"
+        ],
+        "bytes": 25347,
+        "thumb": true
       }
-    ]
+    ],
+    "judging": true
   },
   {
     "id": "57af693363f2",
@@ -29225,21 +29266,23 @@
     "runs": [
       {
         "model": "qwen3-14b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.816Z"
+        "seconds": 66,
+        "cost": 0,
+        "started_at": "2026-07-25T15:03:30.102Z",
+        "finished_at": "2026-07-25T15:04:36.402Z",
+        "queued_at": "2026-07-25T14:59:53.816Z",
+        "bytes": 9561,
+        "thumb": true
       },
       {
         "model": "gemma3-12b",
-        "status": "queued",
+        "status": "running",
         "error": null,
         "seconds": null,
         "cost": null,
-        "started_at": null,
+        "started_at": "2026-07-25T15:04:36.413Z",
         "finished_at": null,
         "queued_at": "2026-07-25T14:59:53.821Z"
       },
@@ -29255,13 +29298,15 @@
       },
       {
         "model": "qwen25-7b",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.829Z"
+        "seconds": 30,
+        "cost": 0,
+        "started_at": "2026-07-25T15:00:28.551Z",
+        "finished_at": "2026-07-25T15:00:58.475Z",
+        "queued_at": "2026-07-25T14:59:53.829Z",
+        "bytes": 4043,
+        "thumb": true
       },
       {
         "model": "hf-qwen-coder-32b",
@@ -29275,43 +29320,60 @@
       },
       {
         "model": "claude-code",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.837Z"
+        "seconds": 118,
+        "cost": 0,
+        "started_at": "2026-07-25T15:01:29.165Z",
+        "finished_at": "2026-07-25T15:03:26.781Z",
+        "queued_at": "2026-07-25T14:59:53.837Z",
+        "bytes": 22630,
+        "thumb": true
       },
       {
         "model": "kimi",
-        "status": "queued",
+        "status": "running",
         "error": null,
         "seconds": null,
         "cost": null,
-        "started_at": null,
+        "started_at": "2026-07-25T15:02:35.105Z",
         "finished_at": null,
         "queued_at": "2026-07-25T14:59:53.841Z"
       },
       {
         "model": "gpt",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.846Z"
+        "seconds": 80,
+        "cost": 0.1477,
+        "started_at": "2026-07-25T15:01:08.060Z",
+        "finished_at": "2026-07-25T15:02:27.660Z",
+        "queued_at": "2026-07-25T14:59:53.846Z",
+        "toolCalls": [
+          "opendesign",
+          "opendesign",
+          "hyperframes"
+        ],
+        "bytes": 35327,
+        "thumb": true
       },
       {
         "model": "grok",
-        "status": "queued",
+        "status": "done",
         "error": null,
-        "seconds": null,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null,
-        "queued_at": "2026-07-25T14:59:53.850Z"
+        "seconds": 156,
+        "cost": 0.1919,
+        "started_at": "2026-07-25T15:01:53.333Z",
+        "finished_at": "2026-07-25T15:04:28.932Z",
+        "queued_at": "2026-07-25T14:59:53.850Z",
+        "toolCalls": [
+          "opendesign",
+          "opendesign",
+          "opendesign",
+          "hyperframes"
+        ],
+        "bytes": 32876,
+        "thumb": true
       }
     ]
   }
diff --git a/data/costlog.jsonl b/data/costlog.jsonl
index 715a2ea..5ff4453 100644
--- a/data/costlog.jsonl
+++ b/data/costlog.jsonl
@@ -402,3 +402,8 @@
 {"ts":"2026-07-25T14:49:57.395Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3486,"output_tokens":11052,"cost_usd":0.160829}
 {"ts":"2026-07-25T14:50:21.494Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":3638,"output_tokens":7749,"cost_usd":0.021555}
 {"ts":"2026-07-25T14:50:46.352Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4256,"output_tokens":11214,"cost_usd":0.180978}
+{"ts":"2026-07-25T15:01:08.046Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3301,"output_tokens":9868,"cost_usd":0.143929}
+{"ts":"2026-07-25T15:01:53.327Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4057,"output_tokens":9030,"cost_usd":0.147621}
+{"ts":"2026-07-25T15:02:27.658Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3289,"output_tokens":10136,"cost_usd":0.14766}
+{"ts":"2026-07-25T15:02:35.080Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":3623,"output_tokens":8358,"cost_usd":0.023069}
+{"ts":"2026-07-25T15:04:28.927Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4257,"output_tokens":11941,"cost_usd":0.191886}

← 2a4b2e1 night-loop: cycle 07:59 — judged=d7636ea87ec3 · fired 2 →; F  ·  back to Model Arena  ·  night-loop: cycle 08:12 — judged=93a51ee67f87 · fired 1 →; F 844afc1 →