← back to Model Arena
auto-save: 2026-07-25T07:04:29 (4 files) — data/challenges.json data/costlog.jsonl data/artifacts/d67ca64a7bfc/ data/artifacts/e1961bf42e98/
eac99fb0d0c23064389d5b319e166a1cbde5e3d7 · 2026-07-25 07:04:38 -0700 · Steve Abrams
Files touched
A data/artifacts/d67ca64a7bfc/claude-code.htmlA data/artifacts/d67ca64a7bfc/claude-code.pngA data/artifacts/d67ca64a7bfc/gemma3-12b.htmlA data/artifacts/d67ca64a7bfc/gemma3-12b.pngA data/artifacts/d67ca64a7bfc/gpt.htmlA data/artifacts/d67ca64a7bfc/gpt.pngA data/artifacts/d67ca64a7bfc/grok.htmlA data/artifacts/d67ca64a7bfc/grok.pngA data/artifacts/d67ca64a7bfc/hermes3-8b.htmlA data/artifacts/d67ca64a7bfc/hermes3-8b.pngA data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.htmlA data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.pngA data/artifacts/d67ca64a7bfc/kimi.htmlA data/artifacts/d67ca64a7bfc/kimi.pngA data/artifacts/d67ca64a7bfc/qwen25-7b.htmlA data/artifacts/d67ca64a7bfc/qwen25-7b.pngA data/artifacts/d67ca64a7bfc/qwen3-14b.htmlA data/artifacts/d67ca64a7bfc/qwen3-14b.pngA data/artifacts/e1961bf42e98/claude-code.htmlA data/artifacts/e1961bf42e98/claude-code.pngA data/artifacts/e1961bf42e98/gpt.htmlA data/artifacts/e1961bf42e98/gpt.pngA data/artifacts/e1961bf42e98/grok.htmlA data/artifacts/e1961bf42e98/grok.pngA data/artifacts/e1961bf42e98/kimi.htmlA data/artifacts/e1961bf42e98/kimi.pngA data/artifacts/e1961bf42e98/qwen25-7b.htmlA data/artifacts/e1961bf42e98/qwen25-7b.pngA data/artifacts/e1961bf42e98/qwen3-14b.htmlA data/artifacts/e1961bf42e98/qwen3-14b.pngM data/challenges.jsonM data/costlog.jsonl
Diff
commit eac99fb0d0c23064389d5b319e166a1cbde5e3d7
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Jul 25 07:04:38 2026 -0700
auto-save: 2026-07-25T07:04:29 (4 files) — data/challenges.json data/costlog.jsonl data/artifacts/d67ca64a7bfc/ data/artifacts/e1961bf42e98/
---
data/artifacts/d67ca64a7bfc/claude-code.html | 391 +++++++
data/artifacts/d67ca64a7bfc/claude-code.png | Bin 0 -> 83541 bytes
data/artifacts/d67ca64a7bfc/gemma3-12b.html | 287 +++++
data/artifacts/d67ca64a7bfc/gemma3-12b.png | Bin 0 -> 43683 bytes
data/artifacts/d67ca64a7bfc/gpt.html | 1096 ++++++++++++++++++
data/artifacts/d67ca64a7bfc/gpt.png | Bin 0 -> 315425 bytes
data/artifacts/d67ca64a7bfc/grok.html | 709 ++++++++++++
data/artifacts/d67ca64a7bfc/grok.png | Bin 0 -> 57059 bytes
data/artifacts/d67ca64a7bfc/hermes3-8b.html | 141 +++
data/artifacts/d67ca64a7bfc/hermes3-8b.png | Bin 0 -> 37373 bytes
data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.html | 198 ++++
data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.png | Bin 0 -> 28073 bytes
data/artifacts/d67ca64a7bfc/kimi.html | 675 +++++++++++
data/artifacts/d67ca64a7bfc/kimi.png | Bin 0 -> 176924 bytes
data/artifacts/d67ca64a7bfc/qwen25-7b.html | 150 +++
data/artifacts/d67ca64a7bfc/qwen25-7b.png | Bin 0 -> 18964 bytes
data/artifacts/d67ca64a7bfc/qwen3-14b.html | 255 +++++
data/artifacts/d67ca64a7bfc/qwen3-14b.png | Bin 0 -> 32386 bytes
data/artifacts/e1961bf42e98/claude-code.html | 619 ++++++++++
data/artifacts/e1961bf42e98/claude-code.png | Bin 0 -> 61951 bytes
data/artifacts/e1961bf42e98/gpt.html | 1180 ++++++++++++++++++++
data/artifacts/e1961bf42e98/gpt.png | Bin 0 -> 144392 bytes
data/artifacts/e1961bf42e98/grok.html | 1139 +++++++++++++++++++
data/artifacts/e1961bf42e98/grok.png | Bin 0 -> 37521 bytes
data/artifacts/e1961bf42e98/kimi.html | 729 ++++++++++++
data/artifacts/e1961bf42e98/kimi.png | Bin 0 -> 27373 bytes
data/artifacts/e1961bf42e98/qwen25-7b.html | 158 +++
data/artifacts/e1961bf42e98/qwen25-7b.png | Bin 0 -> 18538 bytes
data/artifacts/e1961bf42e98/qwen3-14b.html | 298 +++++
data/artifacts/e1961bf42e98/qwen3-14b.png | Bin 0 -> 32815 bytes
data/challenges.json | 256 +++--
data/costlog.jsonl | 6 +
32 files changed, 8197 insertions(+), 90 deletions(-)
diff --git a/data/artifacts/d67ca64a7bfc/claude-code.html b/data/artifacts/d67ca64a7bfc/claude-code.html
new file mode 100644
index 0000000..cb2e802
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/claude-code.html
@@ -0,0 +1,391 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Color Story</title>
+<style>
+ :root{
+ --bg:#faf8f4;
+ --surface:#ffffff;
+ --text:#1c1a17;
+ --muted:#9b948a;
+ --accent:#2f4c39;
+ --accent-2:#b0472e;
+ --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;
+ /* editable palette hues */
+ --hue-1:#e7ddca; /* Oatmeal */
+ --hue-2:#a9bfa3; /* Celadon */
+ --hue-3:#c06848; /* Terracotta */
+ }
+
+ *{box-sizing:border-box;margin:0;padding:0;}
+ html,body{background:#e9e5dd;font-family:var(--sans);color:var(--text);
+ -webkit-font-smoothing:antialiased;min-height:100%;}
+ body{display:flex;align-items:center;justify-content:center;padding:32px;}
+
+ /* ===== FRAME 1080x1080 ===== */
+ .frame{
+ position:relative;width:1080px;height:1080px;max-width:96vw;max-height:96vw;
+ aspect-ratio:1/1;background:var(--bg);overflow:hidden;
+ box-shadow:0 30px 80px rgba(28,26,23,.28);
+ display:flex;flex-direction:column;
+ }
+
+ /* ===== TOP BAR / WORDMARK ===== */
+ header.topbar{
+ position:relative;z-index:20;flex:0 0 auto;
+ display:flex;align-items:center;justify-content:space-between;
+ padding:34px 48px 26px;border-bottom:1px solid var(--line);
+ background:linear-gradient(180deg,rgba(250,248,244,.96),rgba(250,248,244,.72));
+ backdrop-filter:blur(4px);
+ }
+ .wordmark{
+ font-family:var(--serif);
+ color:var(--text);
+ font-size:44px;line-height:.98;font-weight:400;
+ text-transform:uppercase;letter-spacing:.18em;
+ white-space:nowrap;
+ }
+ .wordmark small{display:block;font-size:44px;letter-spacing:.18em;}
+ .topbar .meta{
+ font-family:var(--sans);font-size:12px;letter-spacing:.15em;
+ text-transform:uppercase;color:var(--muted);text-align:right;line-height:1.6;
+ }
+ .topbar .meta .accent{color:var(--accent);}
+
+ /* ===== CAROUSEL VIEWPORT ===== */
+ .viewport{position:relative;flex:1 1 auto;overflow:hidden;}
+ .track{
+ display:flex;height:100%;width:100%;
+ transition:transform .8s var(--ease);
+ will-change:transform;
+ }
+ .slide{
+ flex:0 0 100%;height:100%;position:relative;
+ padding:56px 60px 40px;display:flex;flex-direction:column;
+ }
+
+ /* shared caption labels */
+ .kicker{
+ font-family:var(--sans);font-size:12px;letter-spacing:.22em;
+ text-transform:uppercase;color:var(--muted);
+ }
+ .kicker .dot{color:var(--accent-2);}
+
+ /* ===== SLIDE 1 : COVER ===== */
+ .cover{justify-content:center;align-items:center;text-align:center;
+ background:radial-gradient(120% 90% at 50% 12%,#fffdf9 0%,var(--bg) 62%);}
+ .cover .season{margin-bottom:26px;}
+ .cover .palette-name{
+ font-family:var(--serif);font-size:78px;line-height:1.02;font-weight:400;
+ letter-spacing:.005em;color:var(--text);margin:8px 0 6px;
+ }
+ .cover .palette-name em{font-style:italic;color:var(--accent);}
+ .cover .amp{display:inline-block;color:var(--accent-2);font-style:italic;padding:0 .12em;}
+ .cover .sub{
+ font-family:var(--sans);font-size:16px;letter-spacing:.05em;color:var(--muted);
+ max-width:560px;margin:22px auto 0;line-height:1.7;
+ }
+ .cover .rule{width:64px;height:1px;background:var(--accent);margin:34px auto 30px;}
+ .swatch-row{display:flex;gap:0;justify-content:center;
+ box-shadow:var(--shadow);border-radius:2px;overflow:hidden;}
+ .swatch-row .chip{width:120px;height:120px;position:relative;}
+ .swatch-row .chip span{
+ position:absolute;left:0;right:0;bottom:10px;text-align:center;
+ font-family:var(--sans);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
+ color:rgba(28,26,23,.55);
+ }
+
+ /* ===== SLIDES 2-4 : HUE FEATURE ===== */
+ .hue{gap:0;}
+ .hue .top{display:flex;justify-content:space-between;align-items:flex-start;}
+ .hue .idx{font-family:var(--serif);font-size:30px;color:var(--muted);font-style:italic;}
+ .hue .swatch-wrap{flex:1 1 auto;display:flex;align-items:center;justify-content:center;
+ padding:30px 0 18px;}
+ .big-swatch{
+ width:520px;max-width:78%;aspect-ratio:1.35/1;border-radius:14px;
+ box-shadow:var(--shadow);position:relative;overflow:hidden;
+ border:1px solid var(--line);
+ }
+ /* distinct CSS motifs per hue via gradients */
+ .sw-oatmeal{background:
+ repeating-linear-gradient(135deg,rgba(255,255,255,.35) 0 2px,transparent 2px 11px),
+ linear-gradient(160deg,#efe7d5,var(--hue-1));}
+ .sw-celadon{background:
+ radial-gradient(circle at 30% 30%,rgba(255,255,255,.4) 0 12%,transparent 13%),
+ radial-gradient(circle at 72% 66%,rgba(255,255,255,.28) 0 10%,transparent 11%),
+ linear-gradient(160deg,#bcd0b6,var(--hue-2));}
+ .sw-terracotta{background:
+ repeating-linear-gradient(90deg,rgba(255,255,255,.14) 0 1px,transparent 1px 26px),
+ repeating-linear-gradient(0deg,rgba(28,26,23,.06) 0 1px,transparent 1px 26px),
+ linear-gradient(160deg,#cf7856,var(--hue-3));}
+ .big-swatch .gloss{position:absolute;inset:0;
+ background:linear-gradient(120deg,rgba(255,255,255,.14),transparent 45%);}
+
+ .hue .name-block{display:flex;justify-content:space-between;align-items:flex-end;
+ border-top:1px solid var(--line);padding-top:24px;margin-top:6px;}
+ .hue .designer-name{font-family:var(--serif);font-size:56px;line-height:1;font-weight:400;
+ color:var(--text);}
+ .hue .designer-name em{font-style:italic;color:var(--accent);}
+ .hue .hex{font-family:var(--sans);font-size:12px;letter-spacing:.18em;
+ text-transform:uppercase;color:var(--muted);text-align:right;}
+ .hue .tip{
+ margin-top:22px;display:flex;gap:16px;align-items:flex-start;
+ }
+ .hue .tip .tag{
+ flex:0 0 auto;font-family:var(--sans);font-size:11px;letter-spacing:.2em;
+ text-transform:uppercase;color:var(--accent-2);padding-top:3px;
+ }
+ .hue .tip p{font-family:var(--sans);font-size:17px;line-height:1.66;color:#4a463f;
+ max-width:640px;}
+
+ /* ===== SLIDE 5 : CTA ===== */
+ .cta{justify-content:center;align-items:center;text-align:center;
+ background:linear-gradient(165deg,#20342a 0%,#1a2c22 100%);color:#f3efe6;}
+ .cta .kicker{color:rgba(243,239,230,.6);}
+ .cta .kicker .dot{color:#d98b5f;}
+ .cta h2{font-family:var(--serif);font-size:64px;line-height:1.05;font-weight:400;
+ margin:22px 0 4px;color:#fdfaf3;}
+ .cta h2 em{font-style:italic;color:#d9b48a;}
+ .cta .rule{width:64px;height:1px;background:rgba(243,239,230,.4);margin:30px auto;}
+ .cta p{font-family:var(--sans);font-size:17px;line-height:1.7;color:rgba(243,239,230,.72);
+ max-width:520px;margin:0 auto;}
+ .cta .btn{
+ display:inline-block;margin-top:38px;font-family:var(--sans);
+ font-size:13px;letter-spacing:.22em;text-transform:uppercase;
+ color:#20342a;background:#e7d3b8;padding:18px 44px;border-radius:2px;
+ box-shadow:var(--shadow);transition:transform .2s var(--ease),box-shadow .2s var(--ease);
+ cursor:pointer;
+ }
+ .cta .btn:hover{transform:translateY(-2px);box-shadow:var(--shadow-hover);}
+ .cta .mini-swatches{display:flex;gap:10px;justify-content:center;margin-top:44px;}
+ .cta .mini-swatches i{width:38px;height:38px;border-radius:50%;
+ box-shadow:0 4px 14px rgba(0,0,0,.3);border:1px solid rgba(255,255,255,.18);}
+ .cta .handle{margin-top:34px;font-family:var(--sans);font-size:12px;letter-spacing:.2em;
+ text-transform:uppercase;color:rgba(243,239,230,.55);}
+
+ /* entrance animation */
+ .slide.active .anim{animation:fadeUp .7s var(--ease) both;}
+ .slide.active .anim:nth-child(2){animation-delay:.09s;}
+ .slide.active .anim:nth-child(3){animation-delay:.18s;}
+ .slide.active .anim:nth-child(4){animation-delay:.27s;}
+ .slide.active .anim:nth-child(5){animation-delay:.36s;}
+ @keyframes fadeUp{from{opacity:0;transform:translateY(28px);}to{opacity:1;transform:none;}}
+
+ /* ===== CONTROLS ===== */
+ .controls{
+ position:absolute;left:0;right:0;bottom:0;z-index:30;flex:0 0 auto;
+ display:flex;align-items:center;justify-content:center;gap:22px;
+ padding:22px 0 28px;
+ background:linear-gradient(0deg,rgba(250,248,244,.9),transparent);
+ }
+ .slide.showdark ~ .controls{}
+ .dots{display:flex;gap:12px;}
+ .dots button{
+ width:9px;height:9px;border-radius:50%;border:1px solid var(--muted);
+ background:transparent;padding:0;cursor:pointer;transition:all .3s var(--ease);
+ }
+ .dots button.on{background:var(--accent);border-color:var(--accent);transform:scale(1.25);}
+ .arrow{
+ position:absolute;top:50%;transform:translateY(-50%);z-index:25;
+ width:48px;height:48px;border-radius:50%;border:1px solid var(--line);
+ background:rgba(255,255,255,.82);color:var(--text);cursor:pointer;
+ font-family:var(--serif);font-size:22px;line-height:1;display:flex;
+ align-items:center;justify-content:center;
+ box-shadow:var(--shadow);transition:all .2s var(--ease);
+ backdrop-filter:blur(4px);
+ }
+ .arrow:hover{background:#fff;box-shadow:var(--shadow-hover);}
+ .arrow.prev{left:26px;}
+ .arrow.next{right:26px;}
+ .arrow[disabled]{opacity:0;pointer-events:none;}
+
+ @media (max-width:1120px){
+ .wordmark,.wordmark small{font-size:34px;}
+ .cover .palette-name{font-size:58px;}
+ .hue .designer-name{font-size:44px;}
+ .cta h2{font-size:48px;}
+ .big-swatch{width:60%;}
+ }
+</style>
+</head>
+<body>
+ <div class="frame" id="frame">
+ <header class="topbar">
+ <div class="wordmark" aria-label="Designer Wallcoverings">
+ DESIGNER<small>WALLCOVERINGS</small>
+ </div>
+ <div class="meta">
+ <div class="accent">Color Story</div>
+ <div>Autumn 2026</div>
+ </div>
+ </header>
+
+ <div class="viewport">
+ <div class="track" id="track">
+
+ <!-- SLIDE 1 : COVER -->
+ <section class="slide cover active" data-i="0">
+ <div class="season kicker anim">Seasonal Palette <span class="dot">·</span> Nº 07</div>
+ <h1 class="palette-name anim" id="paletteName">Terracotta <span class="amp">&</span> <em>Sage</em></h1>
+ <div class="rule anim"></div>
+ <p class="sub anim">A grounded autumn story — sun-warmed clay, quiet sage, and a whisper of oat. Three tones to layer across a considered room.</p>
+ <div class="swatch-row anim" id="coverChips"></div>
+ </section>
+
+ <!-- SLIDES 2-4 injected by JS -->
+ <div id="hueSlides" style="display:contents"></div>
+
+ <!-- SLIDE 5 : CTA -->
+ <section class="slide cta" data-i="4">
+ <div class="kicker anim">The Collection <span class="dot">·</span> Made to Order</div>
+ <h2 class="anim">Dress your walls<br>in the <em>season</em>.</h2>
+ <div class="rule anim"></div>
+ <p class="anim">Order hand-trimmed swatches of every hue in the Terracotta & Sage story, or book a consultation with our design studio.</p>
+ <span class="btn anim" id="ctaBtn">Request Swatches</span>
+ <div class="mini-swatches anim" id="ctaSwatches"></div>
+ <div class="handle anim">@designerwallcoverings · designerwallcoverings.com</div>
+ </section>
+
+ </div>
+
+ <button class="arrow prev" id="prev" aria-label="Previous">‹</button>
+ <button class="arrow next" id="next" aria-label="Next">›</button>
+ </div>
+
+ <div class="controls">
+ <div class="dots" id="dots"></div>
+ </div>
+
+ <!-- in-page toast overlay (no alert/confirm) -->
+ <div id="toast" style="position:absolute;inset:0;z-index:40;display:none;
+ align-items:center;justify-content:center;background:rgba(28,26,23,.55);backdrop-filter:blur(3px);">
+ <div style="background:var(--surface);padding:48px 52px;border-radius:14px;max-width:70%;
+ text-align:center;box-shadow:var(--shadow-hover);border:1px solid var(--line);">
+ <div style="font-family:var(--sans);font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--accent-2);">Thank You</div>
+ <div style="font-family:var(--serif);font-size:34px;margin:14px 0 10px;color:var(--text);">Swatches on the way</div>
+ <p style="font-family:var(--sans);font-size:15px;color:var(--muted);line-height:1.6;">Our studio will be in touch to confirm your Terracotta & Sage sample set.</p>
+ <span id="toastClose" style="display:inline-block;margin-top:26px;font-family:var(--sans);font-size:12px;
+ letter-spacing:.2em;text-transform:uppercase;color:#fff;background:var(--accent);
+ padding:14px 34px;border-radius:2px;cursor:pointer;">Close</span>
+ </div>
+ </div>
+ </div>
+
+<script>
+/* ===== EDITABLE PALETTE ===== */
+const PALETTE = {
+ name: ["Terracotta", "&", "Sage"], // cover title parts (middle rendered as amp)
+ season: "Autumn 2026",
+ hues: [
+ { name:"Oatmeal", designerName:["Oat","meal"], hex:"#E7DDCA", swClass:"sw-oatmeal",
+ tip:"Ground the scheme — run Oatmeal across the largest wall as a soft, textural backdrop that lets accent tones breathe." },
+ { name:"Celadon", designerName:["Cela","don"], hex:"#A9BFA3", swClass:"sw-celadon",
+ tip:"A restorative mid-tone for a study or powder room — Celadon reads calm in north light and flatters brass and warm oak." },
+ { name:"Terracotta", designerName:["Terra","cotta"], hex:"#C06848", swClass:"sw-terracotta",
+ tip:"Reserve Terracotta for an intimate space — a dining nook or entry — where its clay warmth turns candlelight golden." }
+ ]
+};
+
+/* apply CSS custom hue vars from palette */
+const root = document.documentElement.style;
+root.setProperty('--hue-1', PALETTE.hues[0].hex);
+root.setProperty('--hue-2', PALETTE.hues[1].hex);
+root.setProperty('--hue-3', PALETTE.hues[2].hex);
+
+/* cover title */
+document.getElementById('paletteName').innerHTML =
+ `${PALETTE.name[0]} <span class="amp">&</span> <em>${PALETTE.name[2]}</em>`;
+document.querySelector('.topbar .meta div:last-child').textContent = PALETTE.season;
+
+/* cover chips */
+document.getElementById('coverChips').innerHTML = PALETTE.hues.map(h =>
+ `<div class="chip" style="background:${h.hex}"><span>${h.name}</span></div>`).join('');
+
+/* cta mini swatches */
+document.getElementById('ctaSwatches').innerHTML = PALETTE.hues.map(h =>
+ `<i style="background:${h.hex}"></i>`).join('');
+
+/* build hue slides 2-4 */
+const hueHTML = PALETTE.hues.map((h,i)=>`
+ <section class="slide hue" data-i="${i+1}">
+ <div class="top anim">
+ <div class="kicker">Hue Nº 0${i+1} <span class="dot">·</span> Color Story</div>
+ <div class="idx">0${i+1}</div>
+ </div>
+ <div class="swatch-wrap anim">
+ <div class="big-swatch ${h.swClass}"><div class="gloss"></div></div>
+ </div>
+ <div class="name-block anim">
+ <div class="designer-name"><em>${h.designerName[0]}</em>${h.designerName[1]}</div>
+ <div class="hex">${h.hex}<br>Designer Colorway</div>
+ </div>
+ <div class="tip anim">
+ <div class="tag">Room Use</div>
+ <p>${h.tip}</p>
+ </div>
+ </section>`).join('');
+
+/* insert hue slides before the CTA slide */
+const track = document.getElementById('track');
+const cta = track.querySelector('.cta');
+cta.insertAdjacentHTML('beforebegin', hueHTML);
+document.getElementById('hueSlides').remove();
+
+/* ===== CAROUSEL ENGINE ===== */
+const slides = Array.from(track.querySelectorAll('.slide'));
+const N = slides.length;
+let cur = 0;
+const dotsWrap = document.getElementById('dots');
+dotsWrap.innerHTML = slides.map((_,i)=>`<button aria-label="Slide ${i+1}"></button>`).join('');
+const dots = Array.from(dotsWrap.children);
+const prev = document.getElementById('prev');
+const next = document.getElementById('next');
+
+function go(i){
+ cur = Math.max(0, Math.min(N-1, i));
+ track.style.transform = `translateX(${-cur*100}%)`;
+ slides.forEach((s,k)=>s.classList.toggle('active', k===cur));
+ dots.forEach((d,k)=>d.classList.toggle('on', k===cur));
+ prev.disabled = cur===0;
+ next.disabled = cur===N-1;
+}
+dots.forEach((d,i)=>d.addEventListener('click',()=>go(i)));
+prev.addEventListener('click',()=>go(cur-1));
+next.addEventListener('click',()=>go(cur+1));
+document.addEventListener('keydown',e=>{
+ if(e.key==='ArrowRight')go(cur+1);
+ if(e.key==='ArrowLeft')go(cur-1);
+});
+
+/* swipe */
+let sx=0, dragging=false;
+const vp = document.querySelector('.viewport');
+vp.addEventListener('touchstart',e=>{sx=e.touches[0].clientX;dragging=true;},{passive:true});
+vp.addEventListener('touchend',e=>{
+ if(!dragging)return;dragging=false;
+ const dx = e.changedTouches[0].clientX - sx;
+ if(dx<-40)go(cur+1); else if(dx>40)go(cur-1);
+});
+vp.addEventListener('mousedown',e=>{sx=e.clientX;dragging=true;});
+window.addEventListener('mouseup',e=>{
+ if(!dragging)return;dragging=false;
+ const dx = e.clientX - sx;
+ if(dx<-60)go(cur+1); else if(dx>60)go(cur-1);
+});
+
+/* CTA toast (no alert) */
+const toast = document.getElementById('toast');
+document.getElementById('ctaBtn').addEventListener('click',()=>{toast.style.display='flex';});
+document.getElementById('toastClose').addEventListener('click',()=>{toast.style.display='none';});
+
+go(0);
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/claude-code.png b/data/artifacts/d67ca64a7bfc/claude-code.png
new file mode 100644
index 0000000..befb9f3
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/claude-code.png differ
diff --git a/data/artifacts/d67ca64a7bfc/gemma3-12b.html b/data/artifacts/d67ca64a7bfc/gemma3-12b.html
new file mode 100644
index 0000000..1933d9d
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/gemma3-12b.html
@@ -0,0 +1,287 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Designer Wallcoverings - Terracotta & Sage</title>
+ <style>
+ :root {
+ --bg: #f7efe6;
+ --surface: #fff9f1;
+ --text: #3a2c22;
+ --muted: #a08c7a;
+ --accent: #c65f38;
+ --line: rgba(58, 44, 34, 0.1);
+ --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 scroll */
+ }
+
+ header {
+ background-color: var(--surface);
+ padding: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: left;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ }
+
+ header p {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 67px; /* Increased font size */
+ letter-spacing: .18em;
+ margin: 0;
+ line-height: 1.2; /* Improves readability */
+ }
+
+ .carousel-container {
+ position: relative;
+ width: 100%;
+ max-width: 1080px;
+ margin: 48px auto;
+ overflow: hidden;
+ }
+
+ .carousel {
+ display: flex;
+ transition: transform 0.5s ease-in-out;
+ }
+
+ .slide {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ padding: 48px;
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: 0 8px 24px var(--shadow);
+ }
+
+ .slide h1 {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 38px;
+ margin-bottom: 24px;
+ }
+
+ .slide p {
+ font-size: 16px;
+ line-height: 1.6;
+ margin-top: 24px;
+ }
+
+ .swatch {
+ width: 200px;
+ height: 200px;
+ border: 1px solid var(--line);
+ border-radius: 8px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
+ margin-bottom: 24px;
+ }
+
+ /* CSS Gradient Swatch - Terracotta */
+ .swatch-terracotta {
+ background: linear-gradient(to bottom, var(--accent), #e0a458) ;
+ }
+
+ /* CSS Gradient Swatch - Sage */
+ .swatch-sage {
+ background: linear-gradient(to bottom, #c65f38, #2f4c39); /*Example only*/
+
+ }
+
+ .dots {
+ position: absolute;
+ bottom: 24px;
+ left: 50%;
+ transform: translateX(-50%);
+ display: flex;
+ gap: 8px;
+ }
+
+ .dot {
+ width: 16px;
+ height: 16px;
+ background-color: var(--muted);
+ border-radius: 8px;
+ cursor: pointer;
+ }
+
+ .dot.active {
+ background-color: var(--accent);
+ }
+
+ /* CTA Slide */
+ .cta-slide {
+ background-color: var(--surface) ;
+ align-items: center;
+ justify-content: flex-start;
+ padding: 48px;
+ }
+
+ .cta-button {
+ font-family: 'Arial', sans-serif;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ background-color: var(--accent);
+ color: #fff;
+ padding: 12px 24px;
+ border: none;
+ border-radius: 8px;
+ cursor: pointer;
+ }
+
+ /* Design Tokens for Motion */
+ body {
+ animation: ambientGradient 18s linear infinite;
+ }
+
+ @keyframes ambientGradient {
+ from { background-position: 0% 50%; }
+ to { background-position: 100% 50%; }
+ }
+
+
+ </style>
+</head>
+<body>
+
+ <header>
+ <p>DESIGNER WALLCOVERINGS</p>
+ </header>
+
+ <div class="carousel-container">
+ <div class="carousel">
+ <!-- Slide 1: Cover -->
+ <div class="slide" id="slide1" data-index="0">
+ <h1>Terracotta & Sage</h1>
+ </div>
+
+ <!-- Slide 2: Terracotta -->
+ <div class="slide" id="slide2" data-index="1">
+ <h1>Terracotta</h1>
+ <div class="swatch swatch-terracotta"></div>
+ <p>Designer: Amelia Stone. Perfect for cozy living rooms and sunlit kitchens.</p>
+ </div>
+
+ <!-- Slide 3: Sage -->
+ <div class="slide" id="slide3" data-index="2">
+ <h1>Sage</h1>
+ <div class="swatch swatch-sage"></div>
+ <p>Designer: Jasper Reed. Ideal for bedrooms and tranquil dining spaces.</p>
+ </div>
+
+ <!-- Slide 4: Oatmeal -->
+ <div class="slide" id="slide4" data-index="3">
+ <h1>Oatmeal</h1>
+ <div class="swatch swatch-terracotta"></div>
+ <p>Designer: Iris Blackwood. Adds warmth and sophistication to hallways and offices.</p>
+ </div>
+
+ <!-- Slide 5: Celadon -->
+ <div class="slide" id="slide5" data-index="4">
+ <h1>Celadon</h1>
+ <div class="swatch swatch-sage"></div>
+ <p>Designer: Rhys Davies. Creates a serene atmosphere in bathrooms and spas.</p>
+ </div>
+
+ <!-- Slide 6: CTA -->
+ <div class="slide cta-slide" id="slide6" data-index="5">
+ <h1>Explore the Collection</h1>
+ <button class="cta-button">Shop Now</button>
+ </div>
+ </div>
+ </div>
+
+ <script>
+ const carousel = document.querySelector('.carousel');
+ const slides = document.querySelectorAll('.slide');
+ const dotsContainer = document.createElement('div');
+ dotsContainer.classList.add('dots');
+ document.querySelector('.carousel-container').appendChild(dotsContainer);
+
+ let currentSlide = 0;
+ const numSlides = slides.length;
+
+
+ // Create Dots
+ for (let i = 0; i < numSlides; i++) {
+ const dot = document.createElement('div');
+ dot.classList.add('dot');
+ dotsContainer.appendChild(dot);
+ }
+
+ const dots = document.querySelectorAll('.dot');
+ dots[currentSlide].classList.add('active');
+
+
+ // Function to show the current slide
+ function showSlide() {
+ slides.forEach((slide, index) => {
+ if (index === currentSlide) {
+ slide.style.transform = 'translateX(0)';
+ } else {
+ slide.style.transform = `translateX(-${currentSlide * 100}% )`;
+ }
+
+ });
+
+ dots.forEach((dot, index) => {
+ if (index === currentSlide) {
+ dot.classList.add('active');
+ } else {
+ dot.classList.remove('active');
+ }
+ });
+
+ }
+
+
+ // Event listeners for dots click
+ dots.forEach(dot => {
+ dot.addEventListener('click', () => {
+ currentSlide = parseInt(dot.dataset.index);
+ showSlide();
+ });
+ });
+
+ // Swipe functionality (Basic)
+ let touchStart;
+ carousel.addEventListener('touchstart', (e) => {
+ touchStart = e.touches[0].clientX;
+ });
+
+ carousel.addEventListener('touchmove', (e) => {
+ const touchEnd = e.touches[0].clientX;
+ const diffX = touchEnd - touchStart;
+
+ if (diffX > 50) { // Swipe right
+ currentSlide--;
+ } else if (diffX < -50) { // Swipe left
+ currentSlide++;
+ }
+
+ if (currentSlide < 0) currentSlide = numSlides -1;
+ if (currentSlide >= numSlides) currentSlide = 0;
+
+ showSlide();
+ touchStart = touchEnd;
+ });
+
+
+ // Initial slide display
+ showSlide();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/gemma3-12b.png b/data/artifacts/d67ca64a7bfc/gemma3-12b.png
new file mode 100644
index 0000000..a2a99c4
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/gemma3-12b.png differ
diff --git a/data/artifacts/d67ca64a7bfc/gpt.html b/data/artifacts/d67ca64a7bfc/gpt.html
new file mode 100644
index 0000000..0d1d2a2
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/gpt.html
@@ -0,0 +1,1096 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Designer Wallcoverings – Seasonal Color Story Carousel</title>
+ <style>
+ :root {
+ /* Design tokens */
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-soft: #1f2026;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961; /* metallic brass-gold */
+ --accent-secondary: #7d6a45;
+ --line: rgba(245, 242, 234, 0.16);
+ --shadow-soft: 0 18px 45px rgba(0, 0, 0, 0.6);
+ --shadow-subtle: 0 1px 0 rgba(255, 255, 255, 0.03);
+
+ --ease-swift: cubic-bezier(.22,.9,.24,1);
+
+ --radius-card: 24px;
+ --radius-swatch: 22px;
+ --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", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", sans-serif;
+
+ --fs-caption: 12px;
+ --fs-body: 16px;
+ --fs-lead: 21px;
+ --fs-h3: 28px;
+ --fs-h2: 38px;
+ --fs-h1: 50px;
+
+ --carousel-size: 1080px;
+
+ /* Palette-specific tokens (easily editable) */
+ --palette-name: "Terracotta & Sage";
+ --hue-1-name: "Oatmeal";
+ --hue-1-ink: #f3ede0;
+ --hue-1-base: #e3d7c3;
+ --hue-1-deep: #c6b397;
+
+ --hue-2-name: "Celadon";
+ --hue-2-ink: #e9f4eb;
+ --hue-2-base: #c8dfd0;
+ --hue-2-deep: #8aa794;
+
+ --hue-3-name: "Terracotta";
+ --hue-3-ink: #f8ece6;
+ --hue-3-base: #c66a3b;
+ --hue-3-deep: #7b3d23;
+
+ /* CTA slide highlight */
+ --cta-glow: rgba(201, 169, 97, 0.4);
+ }
+
+ * {
+ box-sizing: border-box;
+ }
+
+ html,
+ body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ background: radial-gradient(circle at top left, #14151a 0%, var(--bg) 55%, #050507 100%);
+ color: var(--text);
+ font-family: var(--font-sans);
+ -webkit-font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
+ }
+
+ body {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .frame {
+ position: relative;
+ width: var(--carousel-size);
+ height: var(--carousel-size);
+ background: radial-gradient(circle at 10% 0%, #262732 0%, var(--surface) 40%, #101116 85%);
+ border-radius: 32px;
+ box-shadow: var(--shadow-soft);
+ overflow: hidden;
+ border: 1px solid rgba(255, 255, 255, 0.05);
+ }
+
+ /* Header / wordmark */
+ header.app-header {
+ position: absolute;
+ inset: 0 auto auto 0;
+ height: 96px;
+ padding: 22px 40px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ pointer-events: none;
+ z-index: 10;
+ }
+
+ .wordmark-lockup {
+ pointer-events: auto;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ }
+
+ .wordmark {
+ font-family: var(--font-serif);
+ font-size: 40px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text);
+ line-height: 1.08;
+ white-space: normal;
+ max-width: 280px;
+ }
+
+ .wordmark-sub {
+ font-family: var(--font-sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ }
+
+ .header-meta {
+ pointer-events: auto;
+ display: flex;
+ align-items: center;
+ gap: 18px;
+ font-family: var(--font-sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ }
+
+ .header-pill {
+ padding: 6px 14px;
+ border-radius: var(--radius-pill);
+ border: 1px solid rgba(201, 169, 97, 0.4);
+ background: radial-gradient(circle at 0 0, rgba(201, 169, 97, 0.16), rgba(0, 0, 0, 0.2));
+ box-shadow: var(--shadow-subtle);
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .header-pill-dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 999px;
+ background: var(--accent);
+ box-shadow: 0 0 0 4px rgba(201, 169, 97, 0.25);
+ }
+
+ .header-pill-label {
+ color: var(--text);
+ }
+
+ /* Carousel shell */
+ .carousel-shell {
+ position: absolute;
+ inset: 88px 32px 36px 32px;
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+ }
+
+ .viewport {
+ position: relative;
+ flex: 1;
+ overflow: hidden;
+ border-radius: 26px;
+ border: 1px solid var(--line);
+ background: radial-gradient(circle at top right, rgba(201, 169, 97, 0.18), rgba(10, 10, 14, 0.9) 55%, #050507 100%);
+ }
+
+ .track {
+ display: flex;
+ height: 100%;
+ transition: transform 580ms var(--ease-swift);
+ }
+
+ .slide {
+ flex: 0 0 100%;
+ height: 100%;
+ padding: 80px 88px 76px 88px;
+ display: grid;
+ grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.1fr);
+ gap: 72px;
+ align-items: center;
+ color: var(--text);
+ }
+
+ .slide:nth-child(odd) {
+ background: radial-gradient(circle at 0% 0%, rgba(255, 255, 255, 0.02), rgba(0, 0, 0, 0.85));
+ }
+
+ .slide:nth-child(even) {
+ background: radial-gradient(circle at 100% 0%, rgba(201, 169, 97, 0.14), rgba(5, 5, 8, 0.95));
+ }
+
+ .slide-hero {
+ grid-template-columns: 1.2fr 0.9fr;
+ gap: 80px;
+ }
+
+ .slide-cta {
+ grid-template-columns: 1.1fr 1.1fr;
+ gap: 64px;
+ }
+
+ .slide-body {
+ max-width: 520px;
+ }
+
+ .slide-kicker {
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 18px;
+ }
+
+ h1,
+ h2 {
+ margin: 0;
+ font-family: var(--font-serif);
+ font-weight: 500;
+ letter-spacing: -0.02em;
+ line-height: 1.08;
+ }
+
+ h1 {
+ font-size: var(--fs-h1);
+ margin-bottom: 12px;
+ }
+
+ h2 {
+ font-size: var(--fs-h2);
+ margin-bottom: 10px;
+ }
+
+ .palette-name {
+ font-size: var(--fs-h3);
+ font-family: var(--font-serif);
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-top: 10px;
+ }
+
+ .slide-copy {
+ margin-top: 22px;
+ font-size: var(--fs-body);
+ line-height: 1.7;
+ color: rgba(245, 242, 234, 0.9);
+ max-width: 40rem;
+ }
+
+ .slide-tip-label {
+ margin-top: 26px;
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ }
+
+ .slide-tip {
+ margin-top: 8px;
+ font-size: var(--fs-lead);
+ line-height: 1.5;
+ }
+
+ .micro-note {
+ margin-top: 18px;
+ font-size: 13px;
+ color: rgba(245, 242, 234, 0.7);
+ }
+
+ /* Swatch motifs */
+ .swatch-column {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .swatch-card {
+ position: relative;
+ width: 360px;
+ height: 360px;
+ border-radius: var(--radius-card);
+ background: radial-gradient(circle at 12% 0%, rgba(255, 255, 255, 0.12), rgba(0, 0, 0, 0.88));
+ border: 1px solid rgba(255, 255, 255, 0.05);
+ box-shadow: var(--shadow-soft);
+ overflow: hidden;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .swatch-frame {
+ width: 300px;
+ height: 300px;
+ border-radius: var(--radius-swatch);
+ border: 1px solid rgba(255, 255, 255, 0.16);
+ background: #111;
+ overflow: hidden;
+ position: relative;
+ }
+
+ .swatch-caption {
+ position: absolute;
+ inset: auto 18px 16px 18px;
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: rgba(10, 10, 12, 0.88);
+ mix-blend-mode: soft-light;
+ }
+
+ .swatch-caption span:last-child {
+ font-size: 10px;
+ letter-spacing: 0.22em;
+ }
+
+ /* Motif 1 – Oatmeal: woven herringbone */
+ .pattern-oatmeal {
+ width: 100%;
+ height: 100%;
+ background:
+ linear-gradient(135deg, rgba(255, 255, 255, 0.27) 1px, transparent 1px),
+ linear-gradient(225deg, rgba(0, 0, 0, 0.13) 1px, transparent 1px),
+ repeating-linear-gradient(
+ 135deg,
+ rgba(255, 255, 255, 0.04) 0,
+ rgba(255, 255, 255, 0.04) 8px,
+ transparent 8px,
+ transparent 16px
+ );
+ background-size: 16px 16px, 16px 16px, 32px 32px;
+ background-color: var(--hue-1-base);
+ position: relative;
+ }
+
+ .pattern-oatmeal::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(circle at top left, rgba(255, 255, 255, 0.3), transparent 55%);
+ mix-blend-mode: soft-light;
+ }
+
+ .pattern-oatmeal::after {
+ content: "";
+ position: absolute;
+ inset: 18% 22%;
+ border-radius: 18px;
+ border: 1px solid rgba(255, 255, 255, 0.4);
+ box-shadow:
+ 0 20px 45px rgba(0, 0, 0, 0.35),
+ inset 0 0 0 1px rgba(255, 255, 255, 0.18);
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 255, 255, 0.4),
+ rgba(227, 215, 195, 0.4),
+ rgba(198, 179, 151, 0.7)
+ );
+ opacity: 0.58;
+ }
+
+ /* Motif 2 – Celadon: tranquil paneled panels */
+ .pattern-celadon {
+ width: 100%;
+ height: 100%;
+ background:
+ linear-gradient(90deg, rgba(233, 244, 235, 0.08) 1px, transparent 1px),
+ linear-gradient(180deg, rgba(233, 244, 235, 0.06) 1px, transparent 1px),
+ radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.24), transparent 55%);
+ background-size: 90px 100%, 100% 90px, 100% 100%;
+ background-color: var(--hue-2-base);
+ position: relative;
+ }
+
+ .pattern-celadon::before {
+ content: "";
+ position: absolute;
+ inset: 16% 12%;
+ border-radius: 24px;
+ border: 1px solid rgba(255, 255, 255, 0.7);
+ background:
+ linear-gradient(135deg, rgba(233, 244, 235, 0.85), rgba(200, 223, 208, 0.5)),
+ radial-gradient(circle at 0 0, rgba(255, 255, 255, 1), transparent 55%);
+ opacity: 0.7;
+ box-shadow: 0 20px 45px rgba(0, 0, 0, 0.35);
+ mix-blend-mode: screen;
+ }
+
+ .pattern-celadon::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(circle at 100% 100%, rgba(0, 0, 0, 0.25), transparent 52%);
+ mix-blend-mode: soft-light;
+ }
+
+ /* Motif 3 – Terracotta: architectural arches */
+ .pattern-terracotta {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ background:
+ radial-gradient(circle at top left, rgba(255, 255, 255, 0.18), transparent 55%),
+ linear-gradient(180deg, rgba(0, 0, 0, 0.45), transparent 32%);
+ background-color: var(--hue-3-base);
+ }
+
+ .pattern-terracotta::before,
+ .pattern-terracotta::after {
+ content: "";
+ position: absolute;
+ inset: 14% 6% 12% 6%;
+ background-image:
+ radial-gradient(circle at 12.5% 0, transparent 58%, var(--hue-3-deep) 59%, transparent 62%),
+ radial-gradient(circle at 37.5% 0, transparent 58%, var(--hue-3-deep) 59%, transparent 62%),
+ radial-gradient(circle at 62.5% 0, transparent 58%, var(--hue-3-deep) 59%, transparent 62%),
+ radial-gradient(circle at 87.5% 0, transparent 58%, var(--hue-3-deep) 59%, transparent 62%),
+ linear-gradient(to top, var(--hue-3-deep) 0, var(--hue-3-deep) 34%, transparent 35%);
+ background-size: 25% 100%, 25% 100%, 25% 100%, 25% 100%, 100% 100%;
+ background-repeat: no-repeat;
+ background-position: 0 0, 25% 0, 50% 0, 75% 0, 0 100%;
+ border-radius: 32px;
+ overflow: hidden;
+ }
+
+ .pattern-terracotta::after {
+ inset: 24% 18% 0 18%;
+ background:
+ linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent 40%),
+ radial-gradient(circle at 50% -10%, rgba(248, 236, 230, 0.65), transparent 65%);
+ mix-blend-mode: soft-light;
+ }
+
+ /* CTA swatch mosaic: all three hues + metallic */
+ .cta-mosaic {
+ display: grid;
+ grid-template-columns: 1.2fr 1fr;
+ grid-template-rows: 1fr 1.1fr;
+ gap: 10px;
+ width: 360px;
+ height: 360px;
+ border-radius: var(--radius-card);
+ overflow: hidden;
+ border: 1px solid rgba(255, 255, 255, 0.12);
+ box-shadow: var(--shadow-soft);
+ background: radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.06), rgba(0, 0, 0, 0.9));
+ }
+
+ .cta-tile {
+ position: relative;
+ overflow: hidden;
+ }
+
+ .cta-tile::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.3), transparent 55%);
+ mix-blend-mode: soft-light;
+ opacity: 0.7;
+ }
+
+ .cta-tile.oatmeal {
+ background: var(--hue-1-base);
+ background-image:
+ linear-gradient(135deg, rgba(255, 255, 255, 0.3) 1px, transparent 1px),
+ linear-gradient(225deg, rgba(0, 0, 0, 0.16) 1px, transparent 1px);
+ background-size: 12px 12px;
+ }
+
+ .cta-tile.celadon {
+ background: var(--hue-2-base);
+ background-image:
+ linear-gradient(90deg, rgba(233, 244, 235, 0.1) 1px, transparent 1px),
+ linear-gradient(180deg, rgba(233, 244, 235, 0.06) 1px, transparent 1px);
+ background-size: 40px 100%, 100% 40px;
+ }
+
+ .cta-tile.terracotta {
+ background: var(--hue-3-base);
+ background-image:
+ radial-gradient(circle at 50% -30%, rgba(248, 236, 230, 0.6), transparent 65%);
+ }
+
+ .cta-tile.metallic {
+ background:
+ linear-gradient(135deg, #f7f1e4, #c9a961 45%, #7d6a45 70%, #f0dcc0 100%);
+ box-shadow:
+ inset 0 0 0 1px rgba(255, 255, 255, 0.4),
+ 0 20px 45px rgba(0, 0, 0, 0.5);
+ }
+
+ .cta-tile-label {
+ position: absolute;
+ inset: auto 12px 10px 12px;
+ font-size: 10px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: rgba(0, 0, 0, 0.65);
+ mix-blend-mode: soft-light;
+ }
+
+ /* CTA content */
+ .cta-tagline {
+ font-family: var(--font-serif);
+ font-size: var(--fs-h2);
+ letter-spacing: -0.02em;
+ line-height: 1.1;
+ margin: 0 0 18px 0;
+ }
+
+ .cta-kicker {
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 16px;
+ }
+
+ .cta-body {
+ font-size: var(--fs-body);
+ line-height: 1.7;
+ color: rgba(245, 242, 234, 0.9);
+ max-width: 32rem;
+ }
+
+ .cta-actions {
+ margin-top: 30px;
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ }
+
+ .btn-primary {
+ padding: 13px 28px 12px;
+ border-radius: var(--radius-pill);
+ border: 1px solid rgba(0, 0, 0, 0.85);
+ background:
+ radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.18), transparent 55%),
+ linear-gradient(135deg, #f9f1df, #c9a961, #7d6a45);
+ color: #261e12;
+ font-family: var(--font-sans);
+ font-size: 12px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ cursor: pointer;
+ box-shadow:
+ 0 12px 30px rgba(0, 0, 0, 0.8),
+ inset 0 1px 0 rgba(255, 255, 255, 0.6);
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ transition:
+ transform 180ms var(--ease-swift),
+ box-shadow 200ms var(--ease-swift),
+ background 260ms var(--ease-swift);
+ }
+
+ .btn-primary:hover {
+ transform: translateY(-1px);
+ box-shadow:
+ 0 18px 40px rgba(0, 0, 0, 0.9),
+ inset 0 1px 0 rgba(255, 255, 255, 0.7);
+ background:
+ radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.25), transparent 55%),
+ linear-gradient(135deg, #fff7e4, #d4b976, #8c7243);
+ }
+
+ .btn-primary:active {
+ transform: translateY(0);
+ box-shadow:
+ 0 8px 18px rgba(0, 0, 0, 0.7),
+ inset 0 1px 0 rgba(255, 255, 255, 0.5);
+ }
+
+ .btn-ghost {
+ padding: 10px 18px 9px;
+ border-radius: var(--radius-pill);
+ border: 1px solid rgba(245, 242, 234, 0.2);
+ background: rgba(5, 5, 8, 0.7);
+ color: var(--text);
+ font-family: var(--font-sans);
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ cursor: pointer;
+ box-shadow: 0 12px 30px rgba(0, 0, 0, 0.7);
+ transition:
+ background 200ms var(--ease-swift),
+ transform 160ms var(--ease-swift);
+ }
+
+ .btn-ghost:hover {
+ background: rgba(15, 16, 21, 0.96);
+ transform: translateY(-1px);
+ }
+
+ .btn-ghost:active {
+ transform: translateY(0);
+ }
+
+ .btn-icon-chevron {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ border-right: 1px solid rgba(7, 5, 4, 0.8);
+ border-top: 1px solid rgba(7, 5, 4, 0.8);
+ transform: rotate(45deg);
+ margin-left: -4px;
+ }
+
+ .btn-ghost .btn-icon-chevron {
+ border-color: rgba(245, 242, 234, 0.8);
+ margin-left: 0;
+ }
+
+ /* Carousel controls */
+ .controls {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 6px;
+ color: var(--muted);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ font-family: var(--font-sans);
+ }
+
+ .dots {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 999px;
+ border: 1px solid rgba(245, 242, 234, 0.45);
+ background: transparent;
+ cursor: pointer;
+ transition:
+ background 220ms var(--ease-swift),
+ transform 220ms var(--ease-swift),
+ border-color 220ms var(--ease-swift),
+ box-shadow 220ms var(--ease-swift);
+ }
+
+ .dot.active {
+ background: var(--accent);
+ border-color: rgba(0, 0, 0, 0.9);
+ box-shadow: 0 0 0 4px rgba(201, 169, 97, 0.36);
+ transform: scale(1.15);
+ }
+
+ .arrows {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ }
+
+ .arrow-btn {
+ width: 30px;
+ height: 30px;
+ border-radius: 999px;
+ border: 1px solid rgba(245, 242, 234, 0.22);
+ background: radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.14), rgba(10, 10, 14, 0.8));
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ box-shadow: 0 8px 18px rgba(0, 0, 0, 0.7);
+ transition:
+ transform 160ms var(--ease-swift),
+ box-shadow 160ms var(--ease-swift),
+ background 180ms var(--ease-swift);
+ }
+
+ .arrow-btn svg {
+ width: 12px;
+ height: 12px;
+ fill: none;
+ stroke: rgba(245, 242, 234, 0.9);
+ stroke-width: 1.2;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ }
+
+ .arrow-btn:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 12px 26px rgba(0, 0, 0, 0.9);
+ background: radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.22), rgba(10, 10, 14, 0.95));
+ }
+
+ .arrow-btn:active {
+ transform: translateY(0);
+ box-shadow: 0 8px 18px rgba(0, 0, 0, 0.7);
+ }
+
+ .counter {
+ color: rgba(245, 242, 234, 0.7);
+ }
+
+ .counter-strong {
+ color: var(--accent);
+ }
+
+ /* Overlay for CTA */
+ .overlay {
+ position: absolute;
+ inset: 0;
+ display: none;
+ align-items: center;
+ justify-content: center;
+ background: radial-gradient(circle at top, rgba(201, 169, 97, 0.14), rgba(5, 5, 8, 0.95));
+ backdrop-filter: blur(10px);
+ z-index: 20;
+ }
+
+ .overlay.visible {
+ display: flex;
+ }
+
+ .overlay-card {
+ width: 460px;
+ border-radius: 26px;
+ border: 1px solid rgba(245, 242, 234, 0.16);
+ background: radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.12), rgba(10, 10, 14, 0.98));
+ box-shadow: 0 24px 70px rgba(0, 0, 0, 0.9);
+ padding: 28px 32px 26px;
+ }
+
+ .overlay-kicker {
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 12px;
+ }
+
+ .overlay-title {
+ font-family: var(--font-serif);
+ font-size: 30px;
+ letter-spacing: -0.02em;
+ margin: 0 0 14px 0;
+ }
+
+ .overlay-body {
+ font-size: var(--fs-body);
+ line-height: 1.6;
+ color: rgba(245, 242, 234, 0.9);
+ margin-bottom: 18px;
+ }
+
+ .overlay-meta {
+ font-size: 13px;
+ color: rgba(245, 242, 234, 0.7);
+ margin-bottom: 22px;
+ }
+
+ .overlay-actions {
+ display: flex;
+ justify-content: flex-end;
+ gap: 12px;
+ }
+
+ @media (max-width: 1140px) {
+ body {
+ align-items: flex-start;
+ }
+ .frame {
+ transform: scale(0.9);
+ transform-origin: top center;
+ }
+ }
+ </style>
+</head>
+<body>
+ <div class="frame">
+ <header class="app-header">
+ <div class="wordmark-lockup">
+ <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+ <div class="wordmark-sub">SEASONAL COLOR STORY</div>
+ </div>
+ <div class="header-meta">
+ <div>CAROUSEL · 1080 × 1080</div>
+ <div class="header-pill">
+ <div class="header-pill-dot"></div>
+ <div class="header-pill-label">Muted Luxe Palette</div>
+ </div>
+ </div>
+ </header>
+
+ <div class="carousel-shell" aria-label="Seasonal wallcovering color story carousel">
+ <div class="viewport">
+ <div class="track" id="carousel-track">
+ <!-- Slide 1: Cover -->
+ <section class="slide slide-hero" aria-label="Palette overview">
+ <div class="slide-body">
+ <div class="slide-kicker">Seasonal Color Story</div>
+ <h1><span>Terracotta & Sage</span></h1>
+ <div class="palette-name">A Softly Lit Atelier Palette</div>
+ <p class="slide-copy">
+ A quiet trilogy of hues for rooms that glow after dark: tactile <strong>Oatmeal</strong>,
+ ethereal <strong>Celadon</strong>, and sculpted <strong>Terracotta</strong>. Designed for wallcoverings
+ that read like bespoke finishes rather than flat paint.
+ </p>
+ <p class="micro-note">
+ Swipe to explore each hue with a suggested room application and material pairing.
+ </p>
+ </div>
+ <div class="swatch-column" aria-hidden="true">
+ <div class="swatch-card">
+ <div class="swatch-frame">
+ <div class="pattern-oatmeal"></div>
+ <div class="swatch-caption">
+ <span>OATMEAL · CELADON · TERRACOTTA</span>
+ <span>DW / ATELIER 24</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <!-- Slide 2: Oatmeal -->
+ <section class="slide" aria-label="Oatmeal wallcovering hue">
+ <div class="slide-body">
+ <div class="slide-kicker">Hue One</div>
+ <h2>Oatmeal</h2>
+ <p class="slide-copy">
+ A sun-softened neutral that behaves like linen on the wall. Oatmeal wraps a space in warmth
+ without stealing attention from art, stone, or heirloom furniture.
+ </p>
+ <div class="slide-tip-label">Room Use Tip</div>
+ <div class="slide-tip">
+ Use Oatmeal in <strong>north-facing living rooms</strong> to counter cool daylight.
+ Pair with chalky white trim, wide-plank oak, and burnished brass hardware for quietly luminous walls.
+ </div>
+ </div>
+ <div class="swatch-column" aria-hidden="true">
+ <div class="swatch-card">
+ <div class="swatch-frame">
+ <div class="pattern-oatmeal"></div>
+ <div class="swatch-caption">
+ <span>OATMEAL</span>
+ <span>TEXTURED WEAVE</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <!-- Slide 3: Celadon -->
+ <section class="slide" aria-label="Celadon wallcovering hue">
+ <div class="slide-body">
+ <div class="slide-kicker">Hue Two</div>
+ <h2>Celadon</h2>
+ <p class="slide-copy">
+ A misted green with porcelain clarity. Celadon calms busy sightlines and blurs the edge between
+ indoor planting and architectural envelope.
+ </p>
+ <div class="slide-tip-label">Room Use Tip</div>
+ <div class="slide-tip">
+ Wrap a <strong>primary ensuite</strong> in Celadon paneling to soften stone and chrome.
+ Layer fluted glass, brushed nickel, and crisp white linens for a spa-like, gallery-bright retreat.
+ </div>
+ </div>
+ <div class="swatch-column" aria-hidden="true">
+ <div class="swatch-card">
+ <div class="swatch-frame">
+ <div class="pattern-celadon"></div>
+ <div class="swatch-caption">
+ <span>CELADON</span>
+ <span>PANELED SHEEN</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <!-- Slide 4: Terracotta -->
+ <section class="slide" aria-label="Terracotta wallcovering hue">
+ <div class="slide-body">
+ <div class="slide-kicker">Hue Three</div>
+ <h2>Terracotta</h2>
+ <p class="slide-copy">
+ A sculptural clay tone that recalls sun-baked plaster and atelier brick. Terracotta anchors
+ a palette without feeling heavy, especially under candlelight.
+ </p>
+ <div class="slide-tip-label">Room Use Tip</div>
+ <div class="slide-tip">
+ Reserve Terracotta for a <strong>dining room or entry gallery</strong>. Echo the arching motif in
+ millwork or art niches, and contrast with smoked mirror, blackened steel, and woven rush seating.
+ </div>
+ </div>
+ <div class="swatch-column" aria-hidden="true">
+ <div class="swatch-card">
+ <div class="swatch-frame">
+ <div class="pattern-terracotta"></div>
+ <div class="swatch-caption">
+ <span>TERRACOTTA</span>
+ <span>ARCHED RELIEF</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <!-- Slide 5: CTA -->
+ <section class="slide slide-cta" aria-label="Call to action">
+ <div class="slide-body">
+ <div class="cta-kicker">Design With This Story</div>
+ <h2 class="cta-tagline">Bring Terracotta & Sage Into Your Next Room</h2>
+ <p class="cta-body">
+ Save this carousel as a starting point for your next moodboard. Oatmeal grounds upholstery and ceilings,
+ Celadon cools cabinetry and baths, while Terracotta draws the eye along key sightlines.
+ </p>
+ <p class="micro-note">
+ Within our studio library you’ll find coordinating patterns, trims, and companion paints curated around
+ this capsule palette.
+ </p>
+ <div class="cta-actions">
+ <button class="btn-primary" id="cta-primary">
+ Schedule Palette Review
+ <span class="btn-icon-chevron"></span>
+ </button>
+ <button class="btn-ghost" id="cta-secondary">
+ Save Color Story
+ <span class="btn-icon-chevron"></span>
+ </button>
+ </div>
+ </div>
+ <div class="swatch-column" aria-hidden="true">
+ <div class="cta-mosaic">
+ <div class="cta-tile oatmeal">
+ <div class="cta-tile-label">Oatmeal</div>
+ </div>
+ <div class="cta-tile celadon">
+ <div class="cta-tile-label">Celadon</div>
+ </div>
+ <div class="cta-tile terracotta">
+ <div class="cta-tile-label">Terracotta</div>
+ </div>
+ <div class="cta-tile metallic">
+ <div class="cta-tile-label">Brass Accent</div>
+ </div>
+ </div>
+ </div>
+ </section>
+ </div>
+
+ <!-- Overlay -->
+ <div class="overlay" id="overlay" aria-hidden="true">
+ <div class="overlay-card" role="dialog" aria-modal="true" aria-labelledby="overlay-title">
+ <div class="overlay-kicker">Palette Saved</div>
+ <h3 class="overlay-title" id="overlay-title">Terracotta & Sage is now in your studio</h3>
+ <p class="overlay-body">
+ We’ve pinned this color story to your inspiration wall. Use it as a base layer when building
+ room schemes, then swap wallcovering patterns while keeping the same hue proportions.
+ </p>
+ <div class="overlay-meta">
+ Tip: Lead with Oatmeal for longevity, keep Celadon to 25–30% of the envelope, and reserve Terracotta
+ for no more than one feature wall per room.
+ </div>
+ <div class="overlay-actions">
+ <button class="btn-ghost" id="overlay-close">
+ Dismiss
+ </button>
+ <button class="btn-primary" id="overlay-cta">
+ Start New Scheme
+ <span class="btn-icon-chevron"></span>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Controls -->
+ <div class="controls" aria-hidden="false">
+ <div class="dots" id="dots" aria-label="Carousel navigation">
+ <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 class="counter">
+ <span class="counter-strong" id="counter-current">01</span>
+ /
+ <span id="counter-total">05</span>
+ </div>
+ <div class="arrows">
+ <button class="arrow-btn" id="prev" aria-label="Previous slide">
+ <svg viewBox="0 0 24 24">
+ <path d="M15 5l-7 7 7 7" />
+ </svg>
+ </button>
+ <button class="arrow-btn" id="next" aria-label="Next slide">
+ <svg viewBox="0 0 24 24">
+ <path d="M9 5l7 7-7 7" />
+ </svg>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <script>
+ (function () {
+ const track = document.getElementById("carousel-track");
+ const dots = Array.from(document.querySelectorAll(".dot"));
+ const counterCurrent = document.getElementById("counter-current");
+ const totalSlides = dots.length;
+ const prevBtn = document.getElementById("prev");
+ const nextBtn = document.getElementById("next");
+ const overlay = document.getElementById("overlay");
+ const overlayClose = document.getElementById("overlay-close");
+ const overlayCta = document.getElementById("overlay-cta");
+ const ctaPrimary = document.getElementById("cta-primary");
+ const ctaSecondary = document.getElementById("cta-secondary");
+
+ let currentIndex = 0;
+
+ function formatIndex(i) {
+ return (i + 1).toString().padStart(2, "0");
+ }
+
+ function goToSlide(index) {
+ currentIndex = (index + totalSlides) % totalSlides;
+ const offset = -currentIndex * 100;
+ track.style.transform = "translateX(" + offset + "%)";
+ dots.forEach((dot, i) => {
+ dot.classList.toggle("active", i === currentIndex);
+ });
+ counterCurrent.textContent = formatIndex(currentIndex);
+ }
+
+ dots.forEach((dot) => {
+ dot.addEventListener("click", () => {
+ const index = parseInt(dot.getAttribute("data-index"), 10) || 0;
+ goToSlide(index);
+ });
+ });
+
+ prevBtn.addEventListener("click", () => {
+ goToSlide(currentIndex - 1);
+ });
+
+ nextBtn.addEventListener("click", () => {
+ goToSlide(currentIndex + 1);
+ });
+
+ function openOverlay() {
+ overlay.classList.add("visible");
+ overlay.setAttribute("aria-hidden", "false");
+ }
+
+ function closeOverlay() {
+ overlay.classList.remove("visible");
+ overlay.setAttribute("aria-hidden", "true");
+ }
+
+ overlayClose.addEventListener("click", closeOverlay);
+ overlayCta.addEventListener("click", closeOverlay);
+
+ ctaPrimary.addEventListener("click", openOverlay);
+ ctaSecondary.addEventListener("click", openOverlay);
+ })();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/gpt.png b/data/artifacts/d67ca64a7bfc/gpt.png
new file mode 100644
index 0000000..02c16c0
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/gpt.png differ
diff --git a/data/artifacts/d67ca64a7bfc/grok.html b/data/artifacts/d67ca64a7bfc/grok.html
new file mode 100644
index 0000000..9528f58
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/grok.html
@@ -0,0 +1,709 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Terracotta & Sage — Designer Wallcoverings</title>
+<style>
+:root {
+ --bg: #f3efe6;
+ --surface: #ebe4d6;
+ --ink: #1c1a17;
+ --muted: #7a7368;
+ --accent: #b08d57;
+ --accent-soft: rgba(176, 141, 87, 0.18);
+ --line: rgba(28, 26, 23, 0.12);
+ --shadow: 0 18px 48px rgba(28, 26, 23, 0.10);
+ --ease: cubic-bezier(.22, .9, .24, 1);
+ --ease-hero: cubic-bezier(.22, 1, .36, 1);
+
+ /* Seasonal story hues — editable */
+ --hue-oatmeal: #d9cbb6;
+ --hue-oatmeal-deep: #c4b29a;
+ --hue-celadon: #8fa892;
+ --hue-celadon-deep: #6f8a74;
+ --hue-terracotta: #c dig4a3a;
+ --hue-terracotta: #c dig4a3a;
+ --hue-terracotta: #c47a5a;
+ --hue-terracotta-deep: #a85f42;
+
+ --serif: 'Didot', 'Bodoni MT', 'Playfair Display', 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
+ --sans: 'Avenir Next', 'Century Gothic', 'Helvetica Neue', Futura, 'Segoe UI', sans-serif;
+
+ --frame: min(100vw, 100vh, 720px);
+ --header-h: 72px;
+}
+
+*, *::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 wordmark bar —— */
+header.brand-bar {
+ position: fixed;
+ top: 0; left: 0; right: 0;
+ z-index: 100;
+ height: var(--header-h);
+ display: flex;
+ align-items: center;
+ padding: 0 28px;
+ background: rgba(243, 239, 230, 0.92);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--line);
+}
+
+.wordmark {
+ font-family: var(--serif);
+ font-size: clamp(18px, 2.6vw, 22px);
+ font-weight: 400;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--ink);
+ line-height: 1.25;
+ white-space: normal;
+ max-width: min(280px, 70vw);
+}
+
+/* —— Stage —— */
+.stage {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: calc(var(--header-h) + 24px) 20px 28px;
+ gap: 20px;
+}
+
+.carousel-shell {
+ width: var(--frame);
+ max-width: 100%;
+ aspect-ratio: 1 / 1;
+ position: relative;
+ background: var(--surface);
+ box-shadow: var(--shadow);
+ border: 1px solid var(--line);
+ overflow: hidden;
+}
+
+.track {
+ display: flex;
+ height: 100%;
+ width: 100%;
+ transition: transform 0.7s var(--ease-hero);
+ will-change: transform;
+ touch-action: pan-y;
+ cursor: grab;
+}
+.track.dragging { cursor: grabbing; transition: none; }
+
+.slide {
+ flex: 0 0 100%;
+ width: 100%;
+ height: 100%;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 8%;
+ overflow: hidden;
+}
+
+/* —— Slide 1: Cover —— */
+.slide-cover {
+ background:
+ radial-gradient(ellipse 80% 60% at 70% 20%, rgba(196, 122, 90, 0.18), transparent 55%),
+ radial-gradient(ellipse 70% 50% at 20% 80%, rgba(143, 168, 146, 0.22), transparent 50%),
+ linear-gradient(165deg, #efe8da 0%, var(--surface) 45%, #e2d8c6 100%);
+}
+
+.cover-ornament {
+ position: absolute;
+ inset: 7%;
+ border: 1px solid var(--line);
+ pointer-events: none;
+}
+.cover-ornament::before,
+.cover-ornament::after {
+ content: '';
+ position: absolute;
+ width: 12px; height: 12px;
+ border: 1px solid var(--accent);
+}
+.cover-ornament::before { top: -1px; left: -1px; border-right: 0; border-bottom: 0; }
+.cover-ornament::after { bottom: -1px; right: -1px; border-left: 0; border-top: 0; }
+
+.season-label {
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 28px;
+}
+
+.palette-name {
+ font-family: var(--serif);
+ font-size: clamp(36px, 7.2vw, 54px);
+ font-weight: 400;
+ letter-spacing: -0.02em;
+ line-height: 1.08;
+ text-align: center;
+ color: var(--ink);
+ max-width: 12ch;
+}
+
+.palette-rule {
+ width: 48px;
+ height: 1px;
+ background: var(--accent);
+ margin: 28px auto 22px;
+}
+
+.palette-chips {
+ display: flex;
+ gap: 10px;
+ margin-top: 8px;
+}
+.chip {
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ border: 1px solid var(--line);
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,0.25);
+}
+.chip-o { background: var(--hue-oatmeal); }
+.chip-c { background: var(--hue-celadon); }
+.chip-t { background: var(--hue-terracotta); }
+
+.cover-foot {
+ position: absolute;
+ bottom: 8%;
+ left: 0; right: 0;
+ text-align: center;
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* —— Hue slides —— */
+.slide-hue {
+ background: var(--bg);
+ justify-content: flex-start;
+ padding-top: 10%;
+}
+
+.swatch-frame {
+ width: min(72%, 340px);
+ aspect-ratio: 1 / 1.05;
+ position: relative;
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow);
+ overflow: hidden;
+ flex-shrink: 0;
+}
+
+/* CSS-drawn pattern swatches — visually distinct */
+.swatch-oatmeal {
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ var(--hue-oatmeal) 0 14px,
+ var(--hue-oatmeal-deep) 14px 15px
+ ),
+ var(--hue-oatmeal);
+ background-blend-mode: multiply;
+}
+.swatch-oatmeal::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(circle at 30% 40%, rgba(255,255,255,0.18) 0 1px, transparent 2px),
+ radial-gradient(circle at 70% 65%, rgba(255,255,255,0.12) 0 1px, transparent 2px);
+ background-size: 18px 22px, 24px 28px;
+ opacity: 0.7;
+}
+
+.swatch-celadon {
+ background:
+ linear-gradient(135deg, var(--hue-celadon) 0%, var(--hue-celadon-deep) 100%);
+}
+.swatch-celadon::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ repeating-linear-gradient(
+ 0deg,
+ transparent 0 22px,
+ rgba(255,255,255,0.07) 22px 23px
+ ),
+ repeating-linear-gradient(
+ 90deg,
+ transparent 0 22px,
+ rgba(28,26,23,0.06) 22px 23px
+ );
+}
+.swatch-celadon::after {
+ content: '';
+ position: absolute;
+ inset: 12%;
+ border: 1px solid rgba(255,255,255,0.22);
+ border-radius: 50% 50% 48% 52% / 52% 48% 52% 48%;
+ box-shadow: inset 0 0 40px rgba(28,26,23,0.08);
+}
+
+.swatch-terracotta {
+ background:
+ radial-gradient(ellipse 120% 80% at 50% 100%, var(--hue-terracotta-deep) 0%, transparent 55%),
+ linear-gradient(180deg, #d49272 0%, var(--hue-terracotta) 48%, var(--hue-terracotta-deep) 100%);
+}
+.swatch-terracotta::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ opacity: 0.35;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60' viewBox='0 0 60 60'%3E%3Cpath d='M0 30 Q15 10 30 30 T60 30' fill='none' stroke='%23ffffff' stroke-width='0.6' opacity='0.5'/%3E%3Cpath d='M0 45 Q15 25 30 45 T60 45' fill='none' stroke='%231c1a17' stroke-width='0.5' opacity='0.25'/%3E%3C/svg%3E");
+ background-size: 60px 60px;
+}
+
+.hue-meta {
+ margin-top: 7%;
+ text-align: center;
+ width: 100%;
+ max-width: 28ch;
+}
+
+.hue-kicker {
+ font-size: 10px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-bottom: 10px;
+}
+
+.hue-name {
+ font-family: var(--serif);
+ font-size: clamp(28px, 5.5vw, 38px);
+ font-weight: 400;
+ letter-spacing: -0.015em;
+ line-height: 1.1;
+ color: var(--ink);
+}
+
+.hue-tip {
+ margin-top: 14px;
+ font-size: 14px;
+ line-height: 1.6;
+ color: var(--muted);
+ max-width: 32ch;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+/* —— CTA slide —— */
+.slide-cta {
+ background:
+ linear-gradient(160deg, #1c1a17 0%, #2a2620 55%, #1f1c18 100%);
+ color: #f5f2ea;
+ text-align: center;
+ gap: 0;
+}
+
+.cta-eyebrow {
+ font-size: 11px;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-bottom: 24px;
+}
+
+.cta-title {
+ font-family: var(--serif);
+ font-size: clamp(32px, 6vw, 46px);
+ font-weight: 400;
+ letter-spacing: -0.02em;
+ line-height: 1.12;
+ max-width: 14ch;
+ color: #f5f2ea;
+}
+
+.cta-rule {
+ width: 40px;
+ height: 1px;
+ background: var(--accent);
+ margin: 26px auto;
+}
+
+.cta-copy {
+ font-size: 14px;
+ line-height: 1.65;
+ color: rgba(245, 242, 234, 0.62);
+ max-width: 28ch;
+ margin: 0 auto 32px;
+}
+
+.cta-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14px 28px;
+ border: 1px solid var(--accent);
+ background: transparent;
+ color: #f5f2ea;
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ cursor: pointer;
+ transition: background 0.35s var(--ease), color 0.35s var(--ease);
+}
+.cta-btn:hover,
+.cta-btn:focus-visible {
+ background: var(--accent);
+ color: var(--ink);
+ outline: none;
+}
+
+.cta-swatch-row {
+ position: absolute;
+ bottom: 10%;
+ left: 0; right: 0;
+ display: flex;
+ justify-content: center;
+ gap: 8px;
+}
+.cta-swatch-row span {
+ width: 28px;
+ height: 4px;
+ border-radius: 2px;
+}
+.cta-swatch-row span:nth-child(1) { background: var(--hue-oatmeal); }
+.cta-swatch-row span:nth-child(2) { background: var(--hue-celadon); }
+.cta-swatch-row span:nth-child(3) { background: var(--hue-terracotta); }
+
+/* —— Controls —— */
+.controls {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 22px;
+ min-height: 36px;
+}
+
+.nav-btn {
+ appearance: none;
+ border: 1px solid var(--line);
+ background: transparent;
+ color: var(--ink);
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ display: grid;
+ place-items: center;
+ cursor: pointer;
+ transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
+}
+.nav-btn:hover { border-color: var(--accent); background: var(--accent-soft); }
+.nav-btn:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
+.nav-btn svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.5; }
+
+.dots {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+}
+.dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ border: 1px solid var(--muted);
+ background: transparent;
+ padding: 0;
+ cursor: pointer;
+ transition: background 0.35s var(--ease), border-color 0.35s var(--ease), transform 0.35s var(--ease);
+}
+.dot[aria-current="true"] {
+ background: var(--ink);
+ border-color: var(--ink);
+ transform: scale(1.15);
+}
+
+.palette-edit {
+ position: fixed;
+ bottom: 16px;
+ right: 16px;
+ z-index: 90;
+ display: flex;
+ gap: 6px;
+ align-items: center;
+ padding: 8px 10px;
+ background: rgba(243, 239, 230, 0.94);
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow);
+}
+.palette-edit label {
+ font-size: 9px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-right: 4px;
+}
+.palette-edit input[type="color"] {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 22px;
+ height: 22px;
+ border: 1px solid var(--line);
+ border-radius: 50%;
+ padding: 0;
+ background: none;
+ cursor: pointer;
+ overflow: hidden;
+}
+.palette-edit input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
+.palette-edit input[type="color"]::-webkit-color-swatch {
+ border: none;
+ border-radius: 50%;
+}
+
+/* Entrance */
+@keyframes rise {
+ from { opacity: 0; transform: translateY(14px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+.slide.is-active .anim {
+ animation: rise 0.7s var(--ease-hero) both;
+}
+.slide.is-active .anim-d1 { animation-delay: 0.08s; }
+.slide.is-active .anim-d2 { animation-delay: 0.16s; }
+.slide.is-active .anim-d3 { animation-delay: 0.26s; }
+.slide.is-active .anim-d4 { animation-delay: 0.36s; }
+
+@media (max-width: 480px) {
+ :root { --header-h: 64px; }
+ .wordmark { font-size: 16px; letter-spacing: 0.14em; max-width: 200px; }
+ .slide { padding: 7%; }
+ .palette-edit { display: none; }
+}
+</style>
+</head>
+<body>
+
+<header class="brand-bar">
+ <div class="wordmark">Designer Wallcoverings</div>
+</header>
+
+<main class="stage">
+ <div class="carousel-shell" aria-roledescription="carousel" aria-label="Terracotta and Sage color story">
+ <div class="track" id="track">
+
+ <!-- 1 Cover -->
+ <section class="slide slide-cover is-active" data-i="0" aria-label="Cover">
+ <div class="cover-ornament"></div>
+ <p class="season-label anim anim-d1">Autumn Color Story</p>
+ <h1 class="palette-name anim anim-d2">Terracotta & Sage</h1>
+ <div class="palette-rule anim anim-d3"></div>
+ <div class="palette-chips anim anim-d3" aria-hidden="true">
+ <span class="chip chip-o"></span>
+ <span class="chip chip-c"></span>
+ <span class="chip chip-t"></span>
+ </div>
+ <p class="cover-foot anim anim-d4">Three hues · Quiet luxury</p>
+ </section>
+
+ <!-- 2 Oatmeal -->
+ <section class="slide slide-hue" data-i="1" aria-label="Oatmeal">
+ <div class="swatch-frame swatch-oatmeal anim anim-d1" role="img" aria-label="Oatmeal wallcovering swatch"></div>
+ <div class="hue-meta">
+ <p class="hue-kicker anim anim-d2">01 — Ground</p>
+ <h2 class="hue-name anim anim-d2">Oatmeal</h2>
+ <p class="hue-tip anim anim-d3">Wrap the primary suite in this warm linen ground — it softens north light and lets timber and stone read richer.</p>
+ </div>
+ </section>
+
+ <!-- 3 Celadon -->
+ <section class="slide slide-hue" data-i="2" aria-label="Celadon">
+ <div class="swatch-frame swatch-celadon anim anim-d1" role="img" aria-label="Celadon wallcovering swatch"></div>
+ <div class="hue-meta">
+ <p class="hue-kicker anim anim-d2">02 — Breath</p>
+ <h2 class="hue-name anim anim-d2">Celadon</h2>
+ <p class="hue-tip anim anim-d3">Use on a powder room or study alcove. The botanical quiet of celadon steadies the palette without cooling the room.</p>
+ </div>
+ </section>
+
+ <!-- 4 Terracotta -->
+ <section class="slide slide-hue" data-i="3" aria-label="Terracotta">
+ <div class="swatch-frame swatch-terracotta anim anim-d1" role="img" aria-label="Terracotta wallcovering swatch"></div>
+ <div class="hue-meta">
+ <p class="hue-kicker anim anim-d2">03 — Embers</p>
+ <h2 class="hue-name anim anim-d2">Terracotta</h2>
+ <p class="hue-tip anim anim-d3">Anchor a dining niche or chimney breast. Pair with unlacquered brass — the clay warmth deepens after dusk.</p>
+ </div>
+ </section>
+
+ <!-- 5 CTA -->
+ <section class="slide slide-cta" data-i="4" aria-label="Request samples">
+ <p class="cta-eyebrow anim anim-d1">Complimentary sampling</p>
+ <h2 class="cta-title anim anim-d2">Bring the story home</h2>
+ <div class="cta-rule anim anim-d3"></div>
+ <p class="cta-copy anim anim-d3">Request hand-cut cuttings of Oatmeal, Celadon & Terracotta — delivered in a linen folio.</p>
+ <button type="button" class="cta-btn anim anim-d4" id="ctaBtn">Request the folio</button>
+ <div class="cta-swatch-row" aria-hidden="true">
+ <span></span><span></span><span></span>
+ </div>
+ </section>
+
+ </div>
+ </div>
+
+ <div class="controls">
+ <button type="button" class="nav-btn" id="prev" aria-label="Previous slide">
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 5l-7 7 7 7"/></svg>
+ </button>
+ <div class="dots" id="dots" role="tablist" aria-label="Slides"></div>
+ <button type="button" class="nav-btn" id="next" aria-label="Next slide">
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 5l7 7-7 7"/></svg>
+ </button>
+ </div>
+</main>
+
+<div class="palette-edit" aria-label="Edit story hues">
+ <label>Edit</label>
+ <input type="color" id="cOat" value="#d9cbb6" title="Oatmeal" aria-label="Oatmeal hue">
+ <input type="color" id="cCel" value="#8fa892" title="Celadon" aria-label="Celadon hue">
+ <input type="color" id="cTer" value="#c47a5a" title="Terracotta" aria-label="Terracotta hue">
+</div>
+
+<!-- In-page confirmation overlay (no alert) -->
+<div id="overlay" hidden style="
+ position:fixed;inset:0;z-index:200;display:grid;place-items:center;
+ background:rgba(28,26,23,0.45);backdrop-filter:blur(6px);
+">
+ <div style="
+ background:var(--bg);color:var(--ink);border:1px solid var(--line);
+ box-shadow:var(--shadow);padding:40px 44px;max-width:360px;text-align:center;
+ ">
+ <p style="font-family:var(--serif);font-size:28px;letter-spacing:-0.02em;margin-bottom:12px;">Folio reserved</p>
+ <p style="font-size:14px;color:var(--muted);line-height:1.6;margin-bottom:24px;">Your Terracotta & Sage cuttings will be prepared. A concierge will confirm shortly.</p>
+ <button type="button" id="overlayClose" class="cta-btn" style="border-color:var(--ink);color:var(--ink);">Close</button>
+ </div>
+</div>
+
+<script>
+(function () {
+ const track = document.getElementById('track');
+ const slides = Array.from(track.querySelectorAll('.slide'));
+ const prev = document.getElementById('prev');
+ const next = document.getElementById('next');
+ const dotsWrap = document.getElementById('dots');
+ const total = slides.length;
+ let index = 0;
+ let dragX = 0;
+ let startX = 0;
+ let dragging = false;
+
+ // Dots
+ slides.forEach((_, i) => {
+ const b = document.createElement('button');
+ b.type = 'button';
+ b.className = 'dot';
+ b.setAttribute('role', 'tab');
+ b.setAttribute('aria-label', 'Go to slide ' + (i + 1));
+ b.addEventListener('click', () => go(i));
+ dotsWrap.appendChild(b);
+ });
+ const dots = Array.from(dotsWrap.children);
+
+ function go(i) {
+ index = (i + total) % total;
+ track.style.transform = 'translateX(' + (-index * 100) + '%)';
+ slides.forEach((s, n) => s.classList.toggle('is-active', n === index));
+ dots.forEach((d, n) => d.setAttribute('aria-current', n === index ? 'true' : 'false'));
+ }
+ go(0);
+
+ prev.addEventListener('click', () => go(index - 1));
+ next.addEventListener('click', () => go(index + 1));
+
+ // Keyboard
+ document.addEventListener('keydown', (e) => {
+ if (e.key === 'ArrowRight') go(index + 1);
+ if (e.key === 'ArrowLeft') go(index - 1);
+ });
+
+ // Pointer swipe
+ track.addEventListener('pointerdown', (e) => {
+ dragging = true;
+ startX = e.clientX;
+ dragX = 0;
+ track.classList.add('dragging');
+ track.setPointerCapture(e.pointerId);
+ });
+ track.addEventListener('pointermove', (e) => {
+ if (!dragging) return;
+ dragX = e.clientX - startX;
+ const pct = (dragX / track.offsetWidth) * 100;
+ track.style.transform = 'translateX(calc(' + (-index * 100) + '% + ' + pct + '%))';
+ });
+ function endDrag() {
+ if (!dragging) return;
+ dragging = false;
+ track.classList.remove('dragging');
+ if (Math.abs(dragX) > track.offsetWidth * 0.18) {
+ go(index + (dragX < 0 ? 1 : -1));
+ } else {
+ go(index);
+ }
+ dragX = 0;
+ }
+ track.addEventListener('pointerup', endDrag);
+ track.addEventListener('pointercancel', endDrag);
+
+ // Editable palette
+ const root = document.documentElement;
+ function shade(hex, f) {
+ const n = hex.replace('#', '');
+ const r = Math.min(255, Math.max(0, Math.round(parseInt(n.slice(0,2),16) * f)));
+ const g = Math.min(255, Math.max(0, Math.round(parseInt(n.slice(2,4),16) * f)));
+ const b = Math.min(255, Math.max(0, Math.round(parseInt(n.slice(4,6),16) * f)));
+ return '#' + [r,g,b].map(v => v.toString(16).padStart(2,'0')).join('');
+ }
+ function bind(id, base, deep) {
+ const el = document.getElementById(id);
+ el.addEventListener('input', () => {
+ root.style.setProperty(base, el.value);
+ root.style.setProperty(deep, shade(el.value, 0.82));
+ });
+ }
+ bind('cOat', '--hue-oatmeal', '--hue-oatmeal-deep');
+ bind('cCel', '--hue-celadon', '--hue-celadon-deep');
+ bind('cTer', '--hue-terracotta', '--hue-terracotta-deep');
+
+ // CTA overlay
+ const overlay = document.getElementById('overlay');
+ document.getElementById('ctaBtn').addEventListener('click', () => {
+ overlay.hidden = false;
+ overlay.style.display = 'grid';
+ });
+ document.getElementById('overlayClose').addEventListener('click', () => {
+ overlay.hidden = true;
+ overlay.style.display = 'none';
+ });
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/grok.png b/data/artifacts/d67ca64a7bfc/grok.png
new file mode 100644
index 0000000..9dd3bc0
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/grok.png differ
diff --git a/data/artifacts/d67ca64a7bfc/hermes3-8b.html b/data/artifacts/d67ca64a7bfc/hermes3-8b.html
new file mode 100644
index 0000000..cac123e
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/hermes3-8b.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Design Wallcoverings Color Story</title>
+<style>
+:root {
+ --bg: #f7efe6;
+ --surface: #fff9f1;
+ --text: #3a2c22;
+ --muted: #a08c7a;
+ --accent: #c65f38 / #e0a458;
+ --line: 1px solid #3a2c22;
+ --shadow: 0 8px 24px rgba(0,0,0,.12);
+ --ease: cubic-bezier(.22,1,.36,1);
+}
+body, html { margin: 0; padding: 0; font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; color: var(--text); background: var(--bg); }
+header {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ padding: 40px;
+ gap: 16px;
+}
+.wordmark {
+ font-family: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ color: var(--text);
+ letter-spacing: .15em;
+ font-size: calc(1rem + 2vw);
+ flex-grow: 1;
+}
+nav a {
+ display: block;
+ padding: 8px;
+ background: var(--surface);
+ color: var(--text);
+ text-decoration: none;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-weight: bold;
+}
+section {
+ padding: 96px;
+ gap: 32px;
+}
+.card {
+ display: flex;
+ gap: 24px;
+ background: var(--surface);
+}
+.card img {
+ opacity: .8;
+ filter: grayscale(100%);
+}
+.card:hover img { opacity: 1; filter: none; }
+.card-info {
+ flex-grow: 1;
+}
+.card-name {
+ font-size: calc(1rem + 2vw + 4.5vmin);
+ margin-bottom: 16px;
+}
+.card-swatch {
+ background: var(--accent);
+ color: var(--surface);
+}
+button {
+ padding: 12px 24px;
+ border: none;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-weight: bold;
+ text-decoration: none;
+ background: linear-gradient(45deg, var(--accent), var(--surface));
+ color: var(--text);
+ box-shadow: var(--shadow);
+ border-radius: 14px;
+ transition: .3s var(--ease);
+}
+button:hover {
+ filter: brightness(110%);
+ transform: translateY(-2px);
+}
+@media (min-width: 900px) {
+ header, section { display: flex; justify-content: space-between; }
+ section { gap: 64px; }
+ .card { gap: 48px; }
+ .card-name { font-size: calc(1rem + 2vw); }
+}
+@media (min-width: 1500px) {
+ header, section { align-items: center; }
+ section { padding: 128px; gap: 96px; }
+ .card { gap: 64px; }
+}/* End of Styles */
+</style>
+<body>
+<header class="wordmark">
+ <div class="nav">
+ <a href="#">Home</a> | <a href="#">About</a> | <a href="#">Products</a> | <a href="#">Contact</a>
+ </div>
+ <div class="logo">DESIGNER WALLCOVERINGS</div>
+</header>
+<section class="hero">
+ <h1>Terracotta & Sage</h1>
+ <p>A story of warm organic hues for the luxury home.</p>
+ <button>Shop the Story</button>
+</section>
+<section class="palette">
+ <h2>Palette</h2>
+ <div class="cards">
+ <div class="card">
+ <img src="#" alt="">
+ <div class="card-info">
+ <h3>Oatmeal</h3>
+ <div class="card-swatch" style="--color:#f7efe6;">#f7efe6</div>
+ <p>Blending seamlessly into luxury spaces.</p>
+ </div>
+ </div>
+ <div class="card">
+ <img src="#" alt="">
+ <div class="card-info">
+ <h3>Celadon</h3>
+ <div class="card-swatch" style="--color:#b1d0a6;">#b1d0a6</div>
+ <p>Inviting warmth and nature indoors.</p>
+ </div>
+ </div>
+ <div class="card">
+ <img src="#" alt="">
+ <div class="card-info">
+ <h3>Terracotta</h3>
+ <div class="card-swatch" style="--color:#c65f38;">#c65f38</div>
+ <p>Elevate your interiors with terracotta.</p>
+ </div>
+ </div>
+ </div>
+</section>
+<section class="cta">
+ <h2>Discover More Luxury Palettes</h2>
+ <button>Explore Our Collections</button>
+</section>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/hermes3-8b.png b/data/artifacts/d67ca64a7bfc/hermes3-8b.png
new file mode 100644
index 0000000..7c73227
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/hermes3-8b.png differ
diff --git a/data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.html b/data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..a3faab4
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.html
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Seasonal Wallcovering Color Story</title>
+<style>
+:root {
+ --bg: #f7efe6;
+ --surface: #fff9f1;
+ --text: #3a2c22;
+ --muted: #a08c7a;
+ --accent: #c65f38;
+ --line: #e0a458;
+ --shadow: 0 8px 24px rgba(0,0,0,.12);
+ --hover-shadow: 0 16px 48px rgba(0,0,0,.18);
+ --glow: 0 0 24px rgba(198, 95, 56, .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;
+ overflow: hidden;
+}
+
+header {
+ position: fixed;
+ top: 24px;
+ left: 32px;
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 40px;
+ letter-spacing: .18em;
+ color: var(--text);
+ z-index: 100;
+}
+
+.carousel {
+ width: 1080px;
+ height: 1080px;
+ position: relative;
+ perspective: 1000px;
+ overflow: hidden;
+}
+
+.slide {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: var(--surface);
+ box-shadow: var(--shadow);
+ transform-style: preserve-3d;
+ transition: transform .7s var(--ease);
+}
+
+.slide:nth-child(2) { transform: translateX(-1080px); }
+.slide:nth-child(3) { transform: translateX(-2160px); }
+.slide:nth-child(4) { transform: translateX(-3240px); }
+.slide:nth-child(5) { transform: translateX(-4320px); }
+
+.slide h2 {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 67px;
+ margin-bottom: 16px;
+}
+
+.swatch {
+ width: 80%;
+ aspect-ratio: 1 / 1;
+ background-color: #fff;
+ box-shadow: var(--glow);
+ border-radius: 14px;
+ position: relative;
+ overflow: hidden;
+}
+
+.swatch::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: var(--accent);
+ clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
+}
+
+.swatch::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: var(--muted);
+ clip-path: polygon(50% 25%, 75% 50%, 50% 75%, 25% 50%);
+}
+
+.tip {
+ font-size: 21px;
+ margin-top: 16px;
+ text-align: center;
+}
+
+.cta {
+ font-size: 38px;
+ color: var(--accent);
+ text-align: center;
+ cursor: pointer;
+}
+
+.indicators {
+ position: absolute;
+ bottom: 32px;
+ left: 50%;
+ transform: translateX(-50%);
+ display: flex;
+ gap: 16px;
+}
+
+.dot {
+ width: 16px;
+ height: 16px;
+ background-color: var(--muted);
+ border-radius: 8px;
+ transition: background-color .3s ease-in-out;
+}
+
+.dot.active {
+ background-color: var(--accent);
+}
+</style>
+</head>
+<body>
+<header>DESIGNER WALLCOVERINGS</header>
+<div class="carousel" id="carousel">
+ <div class="slide"><h2>Terracotta & Sage</h2></div>
+ <div class="slide">
+ <div class="swatch"></div>
+ <p class="tip">Perfect for living rooms, adding warmth and comfort.</p>
+ </div>
+ <div class="slide">
+ <div class="swatch" style="--accent:#7d6a45;"></div>
+ <p class="tip>Great for bedrooms, promoting relaxation and calmness.</p>
+ </div>
+ <div class="slide">
+ <div class="swatch" style="--accent:#e0a458;"></div>
+ <p class="tip">Ideal for kitchens, enhancing the modern aesthetic.</p>
+ </div>
+ <div class="slide"><p class="cta">Explore More</p></div>
+</div>
+<div class="indicators">
+ <div class="dot active"></div>
+ <div class="dot"></div>
+ <div class="dot"></div>
+ <div class="dot"></div>
+ <div class="dot"></div>
+</div>
+<script>
+const slides = document.querySelectorAll('.slide');
+const dots = document.querySelectorAll('.dot');
+let currentIndex = 0;
+
+function showSlide(index) {
+ slides.forEach((slide, i) => {
+ slide.style.transform = `translateX(${(i - index) * 1080}px)`;
+ });
+ dots.forEach(dot => dot.classList.remove('active'));
+ dots[index].classList.add('active');
+}
+
+dots.forEach((dot, index) => {
+ dot.addEventListener('click', () => {
+ currentIndex = index;
+ showSlide(currentIndex);
+ });
+});
+
+document.querySelector('.cta').addEventListener('click', () => {
+ currentIndex++;
+ if (currentIndex >= slides.length) currentIndex = 0;
+ showSlide(currentIndex);
+});
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.png b/data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..2f8bf3b
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/hf-qwen-coder-32b.png differ
diff --git a/data/artifacts/d67ca64a7bfc/kimi.html b/data/artifacts/d67ca64a7bfc/kimi.html
new file mode 100644
index 0000000..06f8318
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/kimi.html
@@ -0,0 +1,675 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings - Terracotta & Sage Collection</title>
+<style>
+/* ============================================
+ DESIGN TOKENS - LUXURY PALETTE SYSTEM
+ ============================================ */
+:root {
+ /* Core Palette - Luxe Noir Warm */
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-elevated: #1f1f26;
+ --ink: #1c1a17;
+ --text: #f5f2ea;
+ --text-muted: #8a8578;
+ --accent: #c9a961;
+ --accent-hover: #d4b978;
+ --line: rgba(245, 242, 234, 0.12);
+ --shadow: rgba(0, 0, 0, 0.4);
+
+ /* Carousel Specific - Terracotta & Sage Story */
+ --swatch-oatmeal: #e8e0d5;
+ --swatch-celadon: #b8c4b8;
+ --swatch-terracotta: #c17a5c;
+
+ /* Typography */
+ --font-display: Georgia, 'Times New Roman', 'Playfair Display', serif;
+ --font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+
+ /* Scale */
+ --text-caption: 12px;
+ --text-body: 16px;
+ --text-lead: 21px;
+ --text-h3: 28px;
+ --text-h2: 38px;
+ --text-h1: 50px;
+ --text-display: 67px;
+
+ /* Motion */
+ --ease-swift: cubic-bezier(.22,.9,.24,1);
+ --ease-power: cubic-bezier(.77,0,.18,1);
+ --ease-out: cubic-bezier(.22,1,.36,1);
+ --duration: 0.6s;
+}
+
+/* ============================================
+ BASE RESET
+ ============================================ */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+html, body {
+ height: 100%;
+ font-family: var(--font-body);
+ background: var(--bg);
+ color: var(--text);
+ overflow: hidden;
+}
+
+/* ============================================
+ FIXED HEADER - WORDMARK LOCKUP
+ ============================================ */
+header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1000;
+ padding: 24px 32px;
+ background: linear-gradient(to bottom, var(--bg) 0%, transparent 100%);
+ pointer-events: none;
+}
+
+.wordmark {
+ font-family: var(--font-display);
+ font-size: 42px;
+ font-weight: 400;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text);
+ line-height: 1.1;
+ display: block;
+}
+
+/* ============================================
+ CAROUSEL CONTAINER - 1080x1080 SQUARE
+ ============================================ */
+.carousel-container {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--bg);
+ position: relative;
+}
+
+.carousel-frame {
+ width: min(100vw, 100vh);
+ height: min(100vw, 100vh);
+ max-width: 1080px;
+ max-height: 1080px;
+ position: relative;
+ overflow: hidden;
+ background: var(--surface);
+}
+
+.carousel-track {
+ display: flex;
+ height: 100%;
+ transition: transform var(--duration) var(--ease-power);
+ will-change: transform;
+}
+
+.slide {
+ width: 100%;
+ height: 100%;
+ flex-shrink: 0;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ padding: 80px 48px 48px;
+}
+
+/* ============================================
+ DOTS NAVIGATION
+ ============================================ */
+.dots-container {
+ position: absolute;
+ bottom: 32px;
+ left: 50%;
+ transform: translateX(-50%);
+ display: flex;
+ gap: 12px;
+ z-index: 100;
+}
+
+.dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: var(--line);
+ border: none;
+ cursor: pointer;
+ transition: all var(--duration) var(--ease-swift);
+}
+
+.dot.active {
+ background: var(--accent);
+ transform: scale(1.3);
+}
+
+/* ============================================
+ SLIDE 1 - COVER
+ ============================================ */
+.slide-cover {
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ background:
+ radial-gradient(ellipse at 30% 20%, rgba(201, 169, 97, 0.08) 0%, transparent 50%),
+ radial-gradient(ellipse at 70% 80%, rgba(193, 122, 92, 0.06) 0%, transparent 50%),
+ var(--surface);
+}
+
+.season-label {
+ font-family: var(--font-body);
+ font-size: var(--text-caption);
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-bottom: 24px;
+}
+
+.cover-title {
+ font-family: var(--font-display);
+ font-size: clamp(36px, 8vw, var(--text-display));
+ font-weight: 400;
+ letter-spacing: -0.02em;
+ line-height: 1.05;
+ color: var(--text);
+ margin-bottom: 16px;
+}
+
+.cover-subtitle {
+ font-family: var(--font-body);
+ font-size: var(--text-lead);
+ color: var(--text-muted);
+ font-weight: 300;
+}
+
+.divider-line {
+ width: 60px;
+ height: 1px;
+ background: var(--accent);
+ margin: 40px auto;
+}
+
+/* ============================================
+ SLIDES 2-4 - COLOR SWATCHES
+ ============================================ */
+.slide-swatch {
+ justify-content: space-between;
+}
+
+.swatch-header {
+ margin-top: 20px;
+}
+
+.color-category {
+ font-family: var(--font-body);
+ font-size: var(--text-caption);
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ margin-bottom: 12px;
+}
+
+.color-name {
+ font-family: var(--font-display);
+ font-size: clamp(32px, 6vw, var(--text-h1));
+ font-weight: 400;
+ letter-spacing: -0.02em;
+ color: var(--text);
+ margin-bottom: 8px;
+}
+
+.color-designer {
+ font-family: var(--font-body);
+ font-size: var(--text-body);
+ color: var(--text-muted);
+ font-style: italic;
+}
+
+.swatch-display {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin: 32px 0;
+}
+
+/* Distinct CSS Pattern Swatches */
+.swatch-oatmeal-pattern {
+ width: 280px;
+ height: 280px;
+ background:
+ repeating-linear-gradient(
+ 45deg,
+ transparent,
+ transparent 2px,
+ rgba(232, 224, 213, 0.1) 2px,
+ rgba(232, 224, 213, 0.1) 4px
+ ),
+ linear-gradient(135deg, #f0ebe3 0%, #ddd5ca 50%, #e8e0d5 100%);
+ border-radius: 2px;
+ box-shadow:
+ 0 24px 48px var(--shadow),
+ inset 0 1px 0 rgba(255,255,255,0.2);
+ position: relative;
+}
+
+.swatch-oatmeal-pattern::after {
+ content: '';
+ position: absolute;
+ inset: 12px;
+ border: 1px solid rgba(140, 130, 115, 0.3);
+ border-radius: 1px;
+}
+
+.swatch-celadon-pattern {
+ width: 280px;
+ height: 280px;
+ background:
+ radial-gradient(circle at 30% 30%, rgba(255,255,255,0.2) 0%, transparent 40%),
+ repeating-conic-gradient(
+ from 0deg at 50% 50%,
+ #b8c4b8 0deg 10deg,
+ #a8b4a8 10deg 20deg
+ );
+ border-radius: 50%;
+ box-shadow:
+ 0 24px 48px var(--shadow),
+ inset 0 -4px 20px rgba(0,0,0,0.1);
+ position: relative;
+}
+
+.swatch-celadon-pattern::before {
+ content: '';
+ position: absolute;
+ inset: 20%;
+ border: 1px solid rgba(255,255,255,0.3);
+ border-radius: 50%;
+}
+
+.swatch-terracotta-pattern {
+ width: 280px;
+ height: 280px;
+ background:
+ linear-gradient(135deg, #c17a5c 0%, #a85d3f 100%);
+ border-radius: 4px;
+ box-shadow:
+ 0 24px 48px var(--shadow),
+ inset 0 0 60px rgba(0,0,0,0.2);
+ position: relative;
+ overflow: hidden;
+}
+
+.swatch-terracotta-pattern::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ transparent,
+ transparent 20px,
+ rgba(0,0,0,0.05) 20px,
+ rgba(0,0,0,0.05) 21px
+ );
+}
+
+.swatch-terracotta-pattern::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 200px;
+ height: 200px;
+ border: 1px solid rgba(255,255,255,0.2);
+ border-radius: 50%;
+}
+
+.room-tip {
+ border-top: 1px solid var(--line);
+ padding-top: 24px;
+}
+
+.tip-label {
+ font-family: var(--font-body);
+ font-size: var(--text-caption);
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-bottom: 8px;
+}
+
+.tip-text {
+ font-family: var(--font-body);
+ font-size: var(--text-body);
+ line-height: 1.6;
+ color: var(--text-muted);
+ max-width: 400px;
+}
+
+/* ============================================
+ SLIDE 5 - CTA
+ ============================================ */
+.slide-cta {
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ background:
+ radial-gradient(ellipse at 50% 50%, var(--surface-elevated) 0%, var(--surface) 70%);
+}
+
+.cta-title {
+ font-family: var(--font-display);
+ font-size: clamp(28px, 5vw, var(--text-h2));
+ font-weight: 400;
+ letter-spacing: -0.01em;
+ color: var(--text);
+ margin-bottom: 16px;
+}
+
+.cta-text {
+ font-family: var(--font-body);
+ font-size: var(--text-lead);
+ color: var(--text-muted);
+ margin-bottom: 40px;
+ max-width: 400px;
+ line-height: 1.5;
+}
+
+.cta-button {
+ font-family: var(--font-body);
+ font-size: var(--text-caption);
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--bg);
+ background: var(--accent);
+ border: none;
+ padding: 18px 40px;
+ cursor: pointer;
+ transition: all 0.3s var(--ease-swift);
+ position: relative;
+ overflow: hidden;
+}
+
+.cta-button:hover {
+ background: var(--accent-hover);
+ transform: translateY(-2px);
+ box-shadow: 0 8px 24px rgba(201, 169, 97, 0.3);
+}
+
+.cta-contact {
+ margin-top: 48px;
+ font-family: var(--font-body);
+ font-size: var(--text-caption);
+ letter-spacing: 0.1em;
+ color: var(--text-muted);
+}
+
+/* ============================================
+ SWIPE HINT
+ ============================================ */
+.swipe-hint {
+ position: absolute;
+ bottom: 80px;
+ left: 50%;
+ transform: translateX(-50%);
+ font-family: var(--font-body);
+ font-size: 10px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ opacity: 0.6;
+ animation: pulse 2s infinite;
+}
+
+@keyframes pulse {
+ 0%, 100% { opacity: 0.4; }
+ 50% { opacity: 0.8; }
+}
+
+/* ============================================
+ RESPONSIVE ADJUSTMENTS
+ ============================================ */
+@media (max-width: 600px) {
+ header {
+ padding: 16px 20px;
+ }
+
+ .wordmark {
+ font-size: 28px;
+ letter-spacing: 0.15em;
+ }
+
+ .slide {
+ padding: 70px 24px 32px;
+ }
+
+ .swatch-oatmeal-pattern,
+ .swatch-celadon-pattern,
+ .swatch-terracotta-pattern {
+ width: 200px;
+ height: 200px;
+ }
+}
+
+/* Hide scrollbar */
+::-webkit-scrollbar {
+ display: none;
+}
+</style>
+</head>
+<body>
+
+<!-- Fixed Header with Wordmark -->
+<header>
+ <span class="wordmark">Designer Wallcoverings</span>
+</header>
+
+<!-- Carousel Container -->
+<div class="carousel-container">
+ <div class="carousel-frame">
+ <div class="carousel-track" id="track">
+
+ <!-- Slide 1: Cover -->
+ <div class="slide slide-cover">
+ <div class="season-label">Autumn/Winter Collection</div>
+ <h1 class="cover-title">Terracotta<br>& Sage</h1>
+ <div class="divider-line"></div>
+ <p class="cover-subtitle">A Study in Warm Earth Tones</p>
+ </div>
+
+ <!-- Slide 2: Oatmeal -->
+ <div class="slide slide-swatch">
+ <div class="swatch-header">
+ <div class="color-category">Neutral Foundation</div>
+ <h2 class="color-name">Oatmeal</h2>
+ <p class="color-designer">Atelier Linen Series</p>
+ </div>
+ <div class="swatch-display">
+ <div class="swatch-oatmeal-pattern"></div>
+ </div>
+ <div class="room-tip">
+ <div class="tip-label">Room Tip</div>
+ <p class="tip-text">Perfect for north-facing rooms. The warm undertone counteracts cool natural light, creating an inviting, sun-kissed atmosphere throughout the day.</p>
+ </div>
+ </div>
+
+ <!-- Slide 3: Celadon -->
+ <div class="slide slide-swatch">
+ <div class="swatch-header">
+ <div class="color-category">Accent Hue</div>
+ <h2 class="color-name">Celadon</h2>
+ <p class="color-designer">Studio Glaze Collection</p>
+ </div>
+ <div class="swatch-display">
+ <div class="swatch-celadon-pattern"></div>
+ </div>
+ <div class="room-tip">
+ <div class="tip-label">Room Tip</div>
+ <p class="tip-text">Ideal for bedrooms and reading nooks. This muted sage promotes tranquility while maintaining sophisticated color presence.</p>
+ </div>
+ </div>
+
+ <!-- Slide 4: Terracotta -->
+ <div class="slide slide-swatch">
+ <div class="swatch-header">
+ <div class="color-category">Statement Shade</div>
+ <h2 class="color-name">Terracotta</h2>
+ <p class="color-designer">Earthworks Artisan Line</p>
+ </div>
+ <div class="swatch-display">
+ <div class="swatch-terracotta-pattern"></div>
+ </div>
+ <div class="room-tip">
+ <div class="tip-label">Room Tip</div>
+ <p class="tip-text">Use on a single feature wall to anchor open-plan spaces. Pairs beautifully with aged brass fixtures and natural oak.</p>
+ </div>
+ </div>
+
+ <!-- Slide 5: CTA -->
+ <div class="slide slide-cta">
+ <h2 class="cta-title">Begin Your Project</h2>
+ <p class="cta-text">Request a sample portfolio or schedule a consultation with our design team.</p>
+ <button class="cta-button">Request Samples</button>
+ <p class="cta-contact">hello@designerwallcoverings.com</p>
+ </div>
+
+ </div>
+
+ <!-- Dots Navigation -->
+ <div class="dots-container" id="dots">
+ <button class="dot active" data-slide="0" aria-label="Slide 1"></button>
+ <button class="dot" data-slide="1" aria-label="Slide 2"></button>
+ <button class="dot" data-slide="2" aria-label="Slide 3"></button>
+ <button class="dot" data-slide="3" aria-label="Slide 4"></button>
+ <button class="dot" data-slide="4" aria-label="Slide 5"></button>
+ </div>
+
+ <div class="swipe-hint">Swipe to explore</div>
+ </div>
+</div>
+
+<script>
+/* ============================================
+ CAROUSEL LOGIC
+ ============================================ */
+const track = document.getElementById('track');
+const dots = document.querySelectorAll('.dot');
+const totalSlides = 5;
+let currentSlide = 0;
+let startX = 0;
+let isDragging = false;
+
+function goToSlide(index) {
+ if (index < 0) index = 0;
+ if (index >= totalSlides) index = totalSlides - 1;
+
+ currentSlide = index;
+ track.style.transform = `translateX(-${currentSlide * 100}%)`;
+
+ dots.forEach((dot, i) => {
+ dot.classList.toggle('active', i === currentSlide);
+ });
+}
+
+// Dot navigation
+dots.forEach((dot, index) => {
+ dot.addEventListener('click', () => goToSlide(index));
+});
+
+// Touch/Swipe support
+const frame = document.querySelector('.carousel-frame');
+
+frame.addEventListener('touchstart', (e) => {
+ startX = e.touches[0].clientX;
+ isDragging = true;
+}, { passive: true });
+
+frame.addEventListener('touchmove', (e) => {
+ if (!isDragging) return;
+}, { passive: true });
+
+frame.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(currentSlide + 1);
+ } else {
+ goToSlide(currentSlide - 1);
+ }
+ }
+});
+
+// Mouse drag support
+frame.addEventListener('mousedown', (e) => {
+ startX = e.clientX;
+ isDragging = true;
+ frame.style.cursor = 'grabbing';
+});
+
+frame.addEventListener('mousemove', (e) => {
+ if (!isDragging) return;
+});
+
+frame.addEventListener('mouseup', (e) => {
+ if (!isDragging) return;
+ isDragging = false;
+ frame.style.cursor = 'default';
+
+ const endX = e.clientX;
+ const diff = startX - endX;
+
+ if (Math.abs(diff) > 50) {
+ if (diff > 0) {
+ goToSlide(currentSlide + 1);
+ } else {
+ goToSlide(currentSlide - 1);
+ }
+ }
+});
+
+frame.addEventListener('mouseleave', () => {
+ isDragging = false;
+ frame.style.cursor = 'default';
+});
+
+// Keyboard navigation
+document.addEventListener('keydown', (e) => {
+ if (e.key === 'ArrowRight') goToSlide(currentSlide + 1);
+ if (e.key === 'ArrowLeft') goToSlide(currentSlide - 1);
+});
+
+// Button interaction
+document.querySelector('.cta-button').addEventListener('click', () => {
+ const btn = document.querySelector('.cta-button');
+ btn.textContent = 'Request Sent';
+ btn.style.background = 'var(--text)';
+ btn.style.color = 'var(--bg)';
+ setTimeout(() => {
+ btn.textContent = 'Request Samples';
+ btn.style.background = '';
+ btn.style.color = '';
+ }, 2000);
+});
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/kimi.png b/data/artifacts/d67ca64a7bfc/kimi.png
new file mode 100644
index 0000000..842c938
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/kimi.png differ
diff --git a/data/artifacts/d67ca64a7bfc/qwen25-7b.html b/data/artifacts/d67ca64a7bfc/qwen25-7b.html
new file mode 100644
index 0000000..fe232da
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/qwen25-7b.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>DESIGNER WALLCOVERINGS COLOR STORY</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);
+ }
+
+ body {
+ margin: 0;
+ padding: 0;
+ font-family: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ background-color: var(--bg);
+ color: var(--text);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ }
+
+ header {
+ font-size: 50px;
+ letter-spacing: .18em;
+ text-transform: uppercase;
+ color: var(--text);
+ }
+
+ .carousel-container {
+ width: 90%;
+ max-width: 720px;
+ overflow-x: auto;
+ scroll-snap-type: x mandatory;
+ -webkit-overflow-scrolling: touch;
+ padding-bottom: 1rem;
+ }
+
+ .slide {
+ scroll-snap-align: start;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 1080px;
+ width: 100%;
+ background-color: var(--surface);
+ position: relative;
+ z-index: 1;
+ }
+
+ .slide::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-image: linear-gradient(45deg, transparent 24px, var(--bg) 24px),
+ linear-gradient(-45deg, transparent 24px, var(--bg) 24px);
+ pointer-events: none;
+ }
+
+ .slide1 {
+ background-color: var(--bg);
+ }
+
+ .slide2, .slide3, .slide4 {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+ }
+
+ .swatch {
+ width: 150px;
+ height: 150px;
+ background-color: var(--accent);
+ border-radius: 14px;
+ box-shadow: inset 0 8px 24px rgba(0,0,0,.12),
+ 0 16px 48px rgba(0,0,0,.18);
+ }
+
+ .swatch::before {
+ content: '';
+ position: absolute;
+ top: -3px;
+ left: -3px;
+ right: -3px;
+ bottom: -3px;
+ background-color: var(--surface);
+ border-radius: 14px;
+ z-index: -1;
+ }
+
+ .room-tip {
+ font-size: 20px;
+ line-height: 1.5;
+ margin-top: 1rem;
+ }
+
+ .cta-button {
+ padding: 1rem 2rem;
+ background-color: var(--accent);
+ color: var(--surface);
+ border-radius: 4px;
+ font-size: 18px;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ box-shadow: inset 0 16px 32px rgba(0,0,0,.18);
+ transition: all .7s var(--ease);
+ }
+
+ .cta-button:hover {
+ background-color: var(--accent) calc(1 - 35%);
+ transform: scale(1.05);
+ }
+ </style>
+</head>
+<body>
+ <header class="wordmark">DESIGNER WALLCOVERINGS</header>
+ <div class="carousel-container">
+ <div class="slide slide1">
+ <h1 class="palette-name">TERRACOTTA & SAGE</h1>
+ </div>
+ <div class="slide slide2">
+ <div class="swatch" style="background-color: var(--accent);"></div>
+ <p class="room-tip">Perfect for a cozy living room.</p>
+ </div>
+ <div class="slide slide3">
+ <div class="swatch" style="background-color: #c65f38;"></div>
+ <p class="room-tip">Enhance your dining area with warmth.</p>
+ </div>
+ <div class="slide slide4">
+ <div class="swatch" style="background-color: #e0a458;"></div>
+ <p class="room-tip">Add a touch of elegance to any space.</p>
+ </div>
+ <div class="slide slide5">
+ <button class="cta-button">SHOP NOW</button>
+ </div>
+ </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/qwen25-7b.png b/data/artifacts/d67ca64a7bfc/qwen25-7b.png
new file mode 100644
index 0000000..b9cb4ad
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/qwen25-7b.png differ
diff --git a/data/artifacts/d67ca64a7bfc/qwen3-14b.html b/data/artifacts/d67ca64a7bfc/qwen3-14b.html
new file mode 100644
index 0000000..4c35965
--- /dev/null
+++ b/data/artifacts/d67ca64a7bfc/qwen3-14b.html
@@ -0,0 +1,255 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Designer Wallcoverings</title>
+ <style>
+ :root {
+ --bg: #f7efe6;
+ --surface: #fff9f1;
+ --text: #3a2c22;
+ --muted: #a08c7a;
+ --accent: #c65f38;
+ --line: #dcd9d3;
+ --shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+ --ease: cubic-bezier(0.22, 1, 0.36, 1);
+ --glow: 0 0 24px var(--accent)35%;
+ --font-display: 'Playfair Display', Georgia, serif;
+ --font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ }
+
+ * {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ font-family: var(--font-body);
+ }
+
+ html, body {
+ height: 100%;
+ background: var(--bg);
+ color: var(--text);
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ }
+
+ header {
+ font-family: var(--font-display);
+ font-size: 48px;
+ letter-spacing: 0.18em;
+ color: var(--text);
+ background: var(--surface);
+ padding: 16px 32px;
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1000;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ }
+
+ .carousel-container {
+ position: relative;
+ width: 100%;
+ height: 100vh;
+ overflow: hidden;
+ }
+
+ .carousel {
+ display: flex;
+ width: 400%;
+ height: 100%;
+ transition: transform 0.7s var(--ease);
+ }
+
+ .slide {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--surface);
+ position: relative;
+ padding: 48px;
+ box-shadow: var(--shadow);
+ }
+
+ .slide:nth-child(1) {
+ background: var(--accent);
+ color: var(--text);
+ }
+
+ .slide:nth-child(1) h1 {
+ font-size: 40px;
+ font-family: var(--font-display);
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ }
+
+ .slide:nth-child(2), .slide:nth-child(3), .slide:nth-child(4) {
+ background: var(--surface);
+ color: var(--text);
+ }
+
+ .slide:nth-child(2) .swatch {
+ background: #f5f2ea;
+ }
+
+ .slide:nth-child(3) .swatch {
+ background: #c9a961;
+ }
+
+ .slide:nth-child(4) .swatch {
+ background: #8a8578;
+ }
+
+ .swatch {
+ width: 120px;
+ height: 120px;
+ border: 1px solid var(--line);
+ border-radius: 14px;
+ box-shadow: 0 0 12px rgba(0,0,0,0.1);
+ margin-bottom: 24px;
+ }
+
+ .slide h2 {
+ font-size: 32px;
+ font-family: var(--font-display);
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+ margin-bottom: 16px;
+ }
+
+ .slide p {
+ font-size: 16px;
+ line-height: 1.6;
+ color: var(--muted);
+ max-width: 600px;
+ }
+
+ .slide:nth-child(5) {
+ background: var(--accent);
+ color: var(--text);
+ }
+
+ .slide:nth-child(5) button {
+ font-family: var(--font-body);
+ font-size: 16px;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ background: var(--surface);
+ color: var(--text);
+ border: 1px solid var(--line);
+ padding: 16px 32px;
+ border-radius: 14px;
+ box-shadow: 0 4px 16px rgba(0,0,0,0.1);
+ cursor: pointer;
+ margin-top: 48px;
+ }
+
+ .dots {
+ position: absolute;
+ bottom: 32px;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ gap: 12px;
+ }
+
+ .dot {
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ background: var(--muted);
+ transition: background 0.3s var(--ease);
+ }
+
+ .dot.active {
+ background: var(--text);
+ }
+
+ @keyframes fadeUp {
+ from { opacity: 0; transform: translateY(28px); }
+ to { opacity: 1; transform: translateY(0); }
+ }
+
+ .slide {
+ animation: fadeUp 0.7s var(--ease) forwards;
+ }
+ </style>
+</head>
+<body>
+ <header>DESIGNER WALLCOVERINGS</header>
+ <div class="carousel-container">
+ <div class="carousel" id="carousel">
+ <div class="slide">
+ <h1>TERRACOTTA & SAGE</h1>
+ </div>
+ <div class="slide">
+ <div class="swatch"></div>
+ <h2>OATMEAL</h2>
+ <p>Soft and neutral, Oatmeal works well in modern and traditional interiors. Ideal for living rooms and dining areas.</p>
+ </div>
+ <div class="slide">
+ <div class="swatch"></div>
+ <h2>CELADON</h2>
+ <p>A cool, greenish grey that adds depth and serenity. Perfect for bathrooms and bedrooms.</p>
+ </div>
+ <div class="slide">
+ <div class="swatch"></div>
+ <h2>TERRACOTTA</h2>
+ <p>Warm and rich, Terracotta brings warmth to any space. Great for kitchens and entryways.</p>
+ </div>
+ <div class="slide">
+ <p>Explore our full collection of designer wallcoverings and discover your perfect match.</p>
+ <button>VIEW COLLECTION</button>
+ </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>
+ </div>
+
+ <script>
+ const carousel = document.getElementById('carousel');
+ const dots = document.getElementById('dots');
+ let currentIndex = 0;
+
+ function updateDots() {
+ const dotsList = dots.children;
+ for (let i = 0; i < dotsList.length; i++) {
+ dotsList[i].classList.remove('active');
+ }
+ dotsList[currentIndex].classList.add('active');
+ }
+
+ function goToSlide(index) {
+ currentIndex = index;
+ carousel.style.transform = `translateX(-${currentIndex * 100}%)`;
+ updateDots();
+ }
+
+ function nextSlide() {
+ currentIndex = (currentIndex + 1) % 5;
+ carousel.style.transform = `translateX(-${currentIndex * 100}%)`;
+ updateDots();
+ }
+
+ setInterval(nextSlide, 5000);
+
+ dots.addEventListener('click', (e) => {
+ if (e.target.classList.contains('dot')) {
+ goToSlide(Array.from(dots.children).indexOf(e.target));
+ }
+ });
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d67ca64a7bfc/qwen3-14b.png b/data/artifacts/d67ca64a7bfc/qwen3-14b.png
new file mode 100644
index 0000000..9765947
Binary files /dev/null and b/data/artifacts/d67ca64a7bfc/qwen3-14b.png differ
diff --git a/data/artifacts/e1961bf42e98/claude-code.html b/data/artifacts/e1961bf42e98/claude-code.html
new file mode 100644
index 0000000..46bf533
--- /dev/null
+++ b/data/artifacts/e1961bf42e98/claude-code.html
@@ -0,0 +1,619 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Guess the Style</title>
+<style>
+ :root{
+ /* ——— design tokens ——— */
+ --bg:#faf8f4;
+ --surface:#ffffff;
+ --surface-2:#f3efe7;
+ --ink:#1c1a17; /* darkest ink — wordmark, headings */
+ --ink-soft:#3c372f;
+ --muted:#9b948a;
+ --line:#e3ddd1;
+ --accent:#2f4c39; /* single jewel accent — deep emerald */
+ --accent-warm:#b08a3e; /* metallic brass highlight */
+ --success:#2f6b45;
+ --error:#a23b2b;
+ --shadow:0 8px 30px rgba(28,26,23,.10);
+ --shadow-lg:0 20px 60px rgba(28,26,23,.20);
+ --ease:cubic-bezier(.22,1,.36,1);
+ --serif:'Cormorant Garamond','Playfair Display','EB Garamond',Didot,'Bodoni MT',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 700px at 80% -10%, #fffdf8 0%, transparent 60%),
+ var(--bg);
+ color:var(--ink);
+ font-family:var(--sans);
+ -webkit-font-smoothing:antialiased;
+ min-height:100%;
+ display:flex;
+ flex-direction:column;
+ }
+
+ /* ——— top bar / wordmark lockup ——— */
+ header.brand{
+ position:sticky;top:0;z-index:20;
+ background:rgba(250,248,244,.86);
+ backdrop-filter:blur(12px);
+ border-bottom:1px solid var(--line);
+ padding:18px 28px;
+ display:flex;align-items:center;justify-content:space-between;gap:20px;
+ }
+ .wordmark{
+ font-family:var(--serif);
+ color:var(--ink);
+ font-weight:600;
+ font-size:clamp(20px,3.4vw,28px);
+ line-height:1.02;
+ letter-spacing:.18em;
+ text-transform:uppercase;
+ max-width:280px;
+ }
+ .wordmark small{
+ display:block;
+ font-size:.42em;
+ letter-spacing:.42em;
+ color:var(--accent);
+ font-weight:600;
+ margin-top:4px;
+ padding-left:.12em;
+ }
+ .brand-tag{
+ font-family:var(--sans);
+ font-size:11px;letter-spacing:.22em;text-transform:uppercase;
+ color:var(--muted);
+ text-align:right;
+ display:none;
+ }
+ @media(min-width:620px){.brand-tag{display:block}}
+
+ /* ——— layout ——— */
+ main{
+ flex:1;
+ width:100%;
+ max-width:900px;
+ margin:0 auto;
+ padding:32px 24px 64px;
+ display:flex;flex-direction:column;gap:28px;
+ }
+
+ .scorebar{
+ display:flex;flex-wrap:wrap;gap:12px;justify-content:center;
+ }
+ .stat{
+ background:var(--surface);
+ border:1px solid var(--line);
+ border-radius:12px;
+ padding:12px 20px;
+ min-width:96px;
+ text-align:center;
+ box-shadow:var(--shadow);
+ }
+ .stat .label{
+ font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
+ }
+ .stat .value{
+ font-family:var(--serif);
+ font-size:30px;font-weight:600;color:var(--ink);line-height:1.1;margin-top:2px;
+ font-variant-numeric:tabular-nums;
+ }
+ .stat.streak .value{color:var(--accent-warm)}
+
+ /* ——— stage / swatch ——— */
+ .stage{
+ display:flex;flex-direction:column;align-items:center;gap:22px;
+ }
+ .prompt{
+ text-align:center;
+ }
+ .prompt h2{
+ font-family:var(--serif);
+ font-weight:600;
+ font-size:clamp(24px,4vw,34px);
+ color:var(--ink);
+ letter-spacing:.01em;
+ }
+ .prompt p{
+ color:var(--muted);
+ font-size:13px;letter-spacing:.14em;text-transform:uppercase;margin-top:8px;
+ }
+
+ .swatch-wrap{position:relative;width:min(420px,86vw)}
+ .swatch{
+ width:100%;
+ aspect-ratio:4/5;
+ border-radius:16px;
+ overflow:hidden;
+ border:1px solid var(--line);
+ box-shadow:var(--shadow-lg);
+ background:var(--surface-2);
+ position:relative;
+ animation:reveal .7s var(--ease) both;
+ }
+ .swatch svg{display:block;width:100%;height:100%}
+ .swatch::after{
+ content:"";position:absolute;inset:0;border-radius:16px;pointer-events:none;
+ box-shadow:inset 0 0 0 1px rgba(255,255,255,.14), inset 0 -60px 80px rgba(28,26,23,.16);
+ }
+ @keyframes reveal{from{opacity:0;transform:translateY(22px) scale(.985)}to{opacity:1;transform:none}}
+
+ /* timer ring */
+ .timer{
+ position:absolute;top:-14px;right:-14px;width:56px;height:56px;
+ filter:drop-shadow(0 6px 14px rgba(28,26,23,.22));
+ }
+ .timer circle{fill:none;stroke-width:5}
+ .timer .track{stroke:var(--line)}
+ .timer .prog{stroke:var(--accent);stroke-linecap:round;transition:stroke-dashoffset .12s linear,stroke .3s}
+ .timer .t-num{
+ font-family:var(--serif);font-size:22px;fill:var(--ink);text-anchor:middle;
+ dominant-baseline:central;font-variant-numeric:tabular-nums;
+ }
+ .swatch.correct{animation:pop .5s var(--ease)}
+ .swatch.wrong{animation:shake .5s var(--ease)}
+ @keyframes pop{0%{transform:scale(1)}40%{transform:scale(1.03)}100%{transform:scale(1)}}
+ @keyframes shake{0%,100%{transform:translateX(0)}20%{transform:translateX(-9px)}40%{transform:translateX(8px)}60%{transform:translateX(-5px)}80%{transform:translateX(4px)}}
+
+ /* ——— answer buttons ——— */
+ .answers{
+ display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;
+ width:min(420px,86vw);
+ }
+ .answer{
+ font-family:var(--sans);
+ font-size:13px;letter-spacing:.14em;text-transform:uppercase;font-weight:600;
+ color:var(--ink);
+ background:var(--surface);
+ border:1px solid var(--line);
+ border-radius:12px;
+ padding:16px 12px;
+ cursor:pointer;
+ box-shadow:var(--shadow);
+ transition:transform .18s var(--ease),border-color .18s,background .18s,color .18s;
+ }
+ .answer:hover:not(:disabled){transform:translateY(-2px);border-color:var(--accent)}
+ .answer:disabled{cursor:default}
+ .answer.correct{background:var(--success);color:#fff;border-color:var(--success)}
+ .answer.wrong{background:var(--error);color:#fff;border-color:var(--error)}
+ .answer.dim{opacity:.42}
+
+ .feedback{
+ height:20px;text-align:center;font-size:12px;letter-spacing:.18em;text-transform:uppercase;
+ color:var(--muted);transition:color .2s;
+ }
+ .feedback.ok{color:var(--success)}
+ .feedback.no{color:var(--error)}
+
+ /* ——— overlays ——— */
+ .overlay{
+ position:fixed;inset:0;z-index:40;
+ display:none;align-items:center;justify-content:center;padding:24px;
+ background:rgba(28,26,23,.42);
+ backdrop-filter:blur(6px);
+ }
+ .overlay.show{display:flex;animation:fade .35s var(--ease)}
+ @keyframes fade{from{opacity:0}to{opacity:1}}
+ .modal{
+ background:var(--surface);
+ border:1px solid var(--line);
+ border-radius:20px;
+ box-shadow:var(--shadow-lg);
+ max-width:440px;width:100%;
+ padding:44px 36px;
+ text-align:center;
+ animation:rise .5s var(--ease) both;
+ }
+ @keyframes rise{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:none}}
+ .modal .eyebrow{font-size:11px;letter-spacing:.28em;text-transform:uppercase;color:var(--accent);}
+ .modal h1{
+ font-family:var(--serif);font-weight:600;color:var(--ink);
+ font-size:clamp(32px,7vw,46px);line-height:1.05;margin:12px 0 6px;
+ }
+ .modal p{color:var(--ink-soft);font-size:15px;line-height:1.6;margin-bottom:8px}
+ .modal .score-line{
+ display:flex;gap:14px;justify-content:center;margin:24px 0 28px;
+ }
+ .modal .score-line .box{
+ flex:1;background:var(--surface-2);border:1px solid var(--line);border-radius:12px;padding:14px 8px;
+ }
+ .modal .score-line .box .n{font-family:var(--serif);font-size:28px;font-weight:600;color:var(--ink)}
+ .modal .score-line .box .k{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin-top:2px}
+ .modal .best-flag{
+ font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-warm);
+ margin-bottom:18px;height:16px;
+ }
+ .btn{
+ font-family:var(--sans);font-weight:600;font-size:13px;letter-spacing:.16em;text-transform:uppercase;
+ color:#fff;background:var(--accent);border:none;border-radius:999px;
+ padding:16px 40px;cursor:pointer;box-shadow:var(--shadow);
+ transition:transform .18s var(--ease),background .2s;
+ }
+ .btn:hover{transform:translateY(-2px);background:#264030}
+ .btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line);box-shadow:none}
+ .btn.ghost:hover{background:var(--surface-2)}
+ .modal .rules{font-size:12.5px;color:var(--muted);line-height:1.7;margin-bottom:26px;letter-spacing:.02em}
+
+ footer{
+ text-align:center;padding:20px;color:var(--muted);
+ font-size:11px;letter-spacing:.2em;text-transform:uppercase;border-top:1px solid var(--line);
+ }
+</style>
+</head>
+<body>
+
+ <header class="brand">
+ <div class="wordmark">Designer Wallcoverings<small>The Style Game</small></div>
+ <div class="brand-tag">Guess the Design Style</div>
+ </header>
+
+ <main>
+ <div class="scorebar">
+ <div class="stat"><div class="label">Round</div><div class="value" id="roundVal">1<span style="font-size:16px;color:var(--muted)">/10</span></div></div>
+ <div class="stat"><div class="label">Score</div><div class="value" id="scoreVal">0</div></div>
+ <div class="stat streak"><div class="label">Streak</div><div class="value" id="streakVal">0</div></div>
+ <div class="stat"><div class="label">Best</div><div class="value" id="bestVal">0</div></div>
+ </div>
+
+ <section class="stage">
+ <div class="prompt">
+ <h2>Which style is this?</h2>
+ <p>Study the motif · choose before the ring runs out</p>
+ </div>
+
+ <div class="swatch-wrap">
+ <div class="swatch" id="swatch"></div>
+ <svg class="timer" id="timer" viewBox="0 0 60 60">
+ <circle class="track" cx="30" cy="30" r="25"></circle>
+ <circle class="prog" id="timerProg" cx="30" cy="30" r="25" transform="rotate(-90 30 30)"></circle>
+ <text class="t-num" id="timerNum" x="30" y="31">8</text>
+ </svg>
+ </div>
+
+ <div class="answers" id="answers"></div>
+ <div class="feedback" id="feedback"> </div>
+ </section>
+ </main>
+
+ <footer>Designer Wallcoverings · Est. Craft & Pattern</footer>
+
+ <!-- Start overlay -->
+ <div class="overlay show" id="startOverlay">
+ <div class="modal">
+ <div class="eyebrow">Designer Wallcoverings</div>
+ <h1>Guess the Style</h1>
+ <p class="rules">Ten rounds. A hand-drawn wallpaper motif appears — name its design tradition before the timer empties. Speed and streaks earn bonus points.</p>
+ <button class="btn" id="startBtn">Begin</button>
+ </div>
+ </div>
+
+ <!-- Game over overlay -->
+ <div class="overlay" id="overOverlay">
+ <div class="modal">
+ <div class="eyebrow" id="overEyebrow">Result</div>
+ <h1 id="overTitle">Well Curated</h1>
+ <div class="best-flag" id="bestFlag"> </div>
+ <div class="score-line">
+ <div class="box"><div class="n" id="finalScore">0</div><div class="k">Final Score</div></div>
+ <div class="box"><div class="n" id="finalCorrect">0/10</div><div class="k">Correct</div></div>
+ <div class="box"><div class="n" id="finalBest">0</div><div class="k">Best</div></div>
+ </div>
+ <button class="btn" id="restartBtn">Play Again</button>
+ </div>
+ </div>
+
+<script>
+(function(){
+ "use strict";
+
+ /* ————— Motif library: distinct CSS/SVG wallpaper patterns ————— */
+ // Each returns an <svg> string that tiles across the swatch.
+ const MOTIFS = {
+ Damask: function(){
+ const g="#2f4c39", ink="#c9a961", lo="#a87f38";
+ return `<svg viewBox="0 0 200 250" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <pattern id="dm" width="100" height="125" patternUnits="userSpaceOnUse">
+ <rect width="100" height="125" fill="${g}"/>
+ <g fill="none" stroke="${ink}" stroke-width="2.2" stroke-linecap="round">
+ <path d="M50 8 C 40 26 22 30 22 52 C 22 72 42 74 50 90 C 58 74 78 72 78 52 C 78 30 60 26 50 8 Z"/>
+ <path d="M50 30 C 46 42 38 44 38 55 C 38 66 46 66 50 76 C 54 66 62 66 62 55 C 62 44 54 42 50 30 Z" fill="${lo}" fill-opacity=".9" stroke="none"/>
+ <path d="M50 92 C 40 104 34 112 34 120 M50 92 C 60 104 66 112 66 120"/>
+ <circle cx="50" cy="55" r="4" fill="${ink}" stroke="none"/>
+ </g>
+ <g fill="none" stroke="${ink}" stroke-width="2.2" stroke-linecap="round" opacity=".85">
+ <path d="M0 62 C 10 55 14 46 8 40 M100 62 C 90 55 86 46 92 40"/>
+ <path d="M0 120 C 12 116 20 108 22 100 M100 120 C 88 116 80 108 78 100"/>
+ </g>
+ </pattern>
+ </defs>
+ <rect width="200" height="250" fill="url(#dm)"/>
+ </svg>`;
+ },
+ Toile: function(){
+ const g="#f5f1e8", ink="#2b3a55";
+ return `<svg viewBox="0 0 200 250" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <pattern id="to" width="100" height="115" patternUnits="userSpaceOnUse">
+ <rect width="100" height="115" fill="${g}"/>
+ <g fill="none" stroke="${ink}" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round">
+ <!-- tree -->
+ <path d="M28 96 L28 70"/>
+ <path d="M28 72 C 14 66 12 52 24 48 C 16 40 26 28 36 34 C 42 24 58 30 54 42 C 66 44 64 60 50 62 C 52 74 38 78 28 72 Z"/>
+ <path d="M28 96 C 20 96 14 98 10 102 L46 102 C 42 98 36 96 28 96 Z"/>
+ <!-- little figure / urn -->
+ <path d="M74 100 C 70 92 70 84 76 80 C 82 84 82 92 78 100 Z"/>
+ <path d="M70 100 L86 100"/>
+ <circle cx="76" cy="74" r="3"/>
+ <!-- ground line + birds -->
+ <path d="M2 106 C 30 100 70 100 98 106"/>
+ <path d="M52 20 q4 -4 8 0 M60 20 q4 -4 8 0"/>
+ <path d="M6 30 q4 -4 8 0 M14 30 q4 -4 8 0"/>
+ </g>
+ </pattern>
+ </defs>
+ <rect width="200" height="250" fill="url(#to)"/>
+ </svg>`;
+ },
+ Ikat: function(){
+ const g="#f2ece1", a="#b0472e", b="#7d3220", c="#d98c6a";
+ return `<svg viewBox="0 0 200 250" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <pattern id="ik" width="80" height="100" patternUnits="userSpaceOnUse">
+ <rect width="80" height="100" fill="${g}"/>
+ <g stroke="${a}" stroke-width="3" fill="none" stroke-linejoin="miter">
+ <path d="M40 8 L58 30 L50 30 L66 50 L54 50 L40 66 L26 50 L14 50 L30 30 L22 30 Z" fill="${a}" stroke="${b}" stroke-width="2"/>
+ <path d="M40 22 L50 34 L44 34 L52 46 L40 56 L28 46 L36 34 L30 34 Z" fill="${c}" stroke="none"/>
+ </g>
+ <g stroke="${b}" stroke-width="2.4" stroke-linecap="round" opacity=".8">
+ <path d="M40 68 L40 96 M32 74 L32 92 M48 74 L48 92"/>
+ <path d="M2 50 L14 50 M66 50 L78 50"/>
+ <path d="M6 88 q6 -6 12 0 M62 88 q6 -6 12 0"/>
+ </g>
+ </pattern>
+ </defs>
+ <rect width="200" height="250" fill="url(#ik)"/>
+ </svg>`;
+ },
+ Chinoiserie: function(){
+ const g="#dbe6dd", branch="#3a5a44", leaf="#5c8467", bloom="#d98aa0", ctr="#c9a961";
+ return `<svg viewBox="0 0 200 250" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <pattern id="ch" width="120" height="150" patternUnits="userSpaceOnUse">
+ <rect width="120" height="150" fill="${g}"/>
+ <g fill="none" stroke="${branch}" stroke-width="2.4" stroke-linecap="round">
+ <path d="M6 148 C 30 120 34 92 60 78 C 84 66 92 40 118 24"/>
+ <path d="M40 100 C 52 96 60 88 62 78 M78 60 C 88 60 96 52 98 42"/>
+ </g>
+ <g fill="${leaf}" opacity=".92">
+ <path d="M40 100 C 34 92 34 84 42 82 C 46 90 46 98 40 100 Z"/>
+ <path d="M78 60 C 74 51 76 44 84 44 C 86 52 84 59 78 60 Z"/>
+ </g>
+ <g>
+ <g transform="translate(60,78)">
+ <circle r="8" fill="${bloom}"/>
+ <circle r="8" cx="12" cy="-2" fill="${bloom}" opacity=".9"/>
+ <circle r="8" cx="6" cy="10" fill="${bloom}" opacity=".9"/>
+ <circle r="4" cx="6" cy="3" fill="${ctr}"/>
+ </g>
+ <g transform="translate(100,26)">
+ <circle r="6.5" fill="${bloom}"/>
+ <circle r="6.5" cx="9" cy="3" fill="${bloom}" opacity=".85"/>
+ <circle r="3" cx="4" cy="2" fill="${ctr}"/>
+ </g>
+ </g>
+ <!-- small bird -->
+ <g transform="translate(24,120)" fill="none" stroke="${branch}" stroke-width="2" stroke-linecap="round">
+ <path d="M0 0 C 6 -8 16 -8 20 0 C 14 2 6 2 0 0 Z" fill="${ctr}" stroke="none" opacity=".85"/>
+ <path d="M20 0 C 26 -2 30 2 30 6"/>
+ <circle cx="4" cy="-2" r="1.4" fill="${branch}"/>
+ </g>
+ </pattern>
+ </defs>
+ <rect width="200" height="250" fill="url(#ch)"/>
+ </svg>`;
+ },
+ Geometric: function(){
+ const g="#1c1a17", ink="#c9a961", lo="#7d6a45";
+ return `<svg viewBox="0 0 200 250" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <pattern id="ge" width="60" height="52" patternUnits="userSpaceOnUse" patternTransform="translate(0,0)">
+ <rect width="60" height="52" fill="${g}"/>
+ <g fill="none" stroke="${ink}" stroke-width="2">
+ <polygon points="30,4 56,18 56,42 30,56 4,42 4,18"/>
+ <polygon points="30,16 45,24 45,40 30,48 15,40 15,24" stroke="${lo}"/>
+ <circle cx="30" cy="32" r="4" fill="${ink}" stroke="none"/>
+ </g>
+ <g fill="none" stroke="${lo}" stroke-width="2">
+ <polygon points="0,-8 13,0 13,16 0,24 -13,16 -13,0" transform="translate(0,4)"/>
+ <polygon points="60,-8 73,0 73,16 60,24 47,16 47,0" transform="translate(0,4)"/>
+ <polygon points="0,44 13,52 13,68 0,76 -13,68 -13,52"/>
+ <polygon points="60,44 73,52 73,68 60,76 47,68 47,52"/>
+ </g>
+ </pattern>
+ </defs>
+ <rect width="200" height="250" fill="url(#ge)"/>
+ </svg>`;
+ },
+ Grasscloth: function(){
+ const g="#c8b79a", ink="#9c8763", dk="#84714e", hl="#dccfb4";
+ let strands="";
+ for(let y=0;y<250;y+=7){
+ const w = 3 + (y%14===0?1.4:0);
+ strands += `<line x1="0" y1="${y}" x2="200" y2="${y+ (y%2? -1.5:1.5)}" stroke="${y%14===0?dk:ink}" stroke-width="${w}" />`;
+ }
+ // subtle vertical warp
+ let warp="";
+ for(let x=0;x<200;x+=26){
+ warp += `<line x1="${x}" y1="0" x2="${x}" y2="250" stroke="${hl}" stroke-width="1" opacity=".35"/>`;
+ }
+ return `<svg viewBox="0 0 200 250" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
+ <rect width="200" height="250" fill="${g}"/>
+ <g opacity=".9">${strands}</g>
+ <g>${warp}</g>
+ <rect width="200" height="250" fill="url(#gv)"/>
+ </svg>`;
+ }
+ };
+
+ const STYLES = Object.keys(MOTIFS); // 6 styles
+ const TOTAL_ROUNDS = 10;
+ const ROUND_SECONDS = 8;
+
+ /* ————— State ————— */
+ let round, score, streak, correctCount, currentStyle;
+ let timeLeft, rafId, roundStart, answered;
+ const BEST_KEY = "dw_style_game_best";
+
+ /* ————— DOM ————— */
+ const el = id => document.getElementById(id);
+ const swatch = el('swatch');
+ const answersEl = el('answers');
+ const feedbackEl = el('feedback');
+ const timerProg = el('timerProg');
+ const timerNum = el('timerNum');
+ const R = 25, CIRC = 2*Math.PI*R;
+ timerProg.style.strokeDasharray = CIRC.toFixed(2);
+
+ function getBest(){ const v = parseInt(localStorage.getItem(BEST_KEY)||"0",10); return isNaN(v)?0:v; }
+ function setBest(v){ try{ localStorage.setItem(BEST_KEY, String(v)); }catch(e){} }
+
+ function shuffle(a){ a=a.slice(); for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]];} return a; }
+
+ function updateHUD(){
+ el('roundVal').innerHTML = round + '<span style="font-size:16px;color:var(--muted)">/'+TOTAL_ROUNDS+'</span>';
+ el('scoreVal').textContent = score;
+ el('streakVal').textContent = streak;
+ el('bestVal').textContent = getBest();
+ }
+
+ /* ————— Timer ————— */
+ function tick(){
+ const elapsed = (performance.now() - roundStart)/1000;
+ timeLeft = Math.max(0, ROUND_SECONDS - elapsed);
+ const frac = timeLeft/ROUND_SECONDS;
+ timerProg.style.strokeDashoffset = (CIRC*(1-frac)).toFixed(2);
+ timerNum.textContent = Math.ceil(timeLeft);
+ if(timeLeft <= 3) timerProg.style.stroke = 'var(--error)';
+ else if(timeLeft <= 5) timerProg.style.stroke = 'var(--accent-warm)';
+ else timerProg.style.stroke = 'var(--accent)';
+ if(timeLeft <= 0){ if(!answered) resolve(null); return; }
+ rafId = requestAnimationFrame(tick);
+ }
+
+ /* ————— Round flow ————— */
+ function startRound(){
+ answered = false;
+ timerProg.style.stroke = 'var(--accent)';
+ // pick style (avoid immediate repeat)
+ let s;
+ do { s = STYLES[Math.floor(Math.random()*STYLES.length)]; } while(s===currentStyle && STYLES.length>1);
+ currentStyle = s;
+
+ swatch.className = 'swatch';
+ // force reflow to restart reveal animation
+ void swatch.offsetWidth;
+ swatch.innerHTML = MOTIFS[s]();
+
+ // build options: correct + 3 distractors
+ const distractors = shuffle(STYLES.filter(x=>x!==s)).slice(0,3);
+ const opts = shuffle([s, ...distractors]);
+ answersEl.innerHTML = '';
+ opts.forEach(name=>{
+ const b = document.createElement('button');
+ b.className = 'answer';
+ b.textContent = name;
+ b.dataset.style = name;
+ b.addEventListener('click', ()=>resolve(name, b));
+ answersEl.appendChild(b);
+ });
+ feedbackEl.textContent = '\u00A0';
+ feedbackEl.className = 'feedback';
+
+ updateHUD();
+ roundStart = performance.now();
+ cancelAnimationFrame(rafId);
+ tick();
+ }
+
+ function resolve(pick, btn){
+ if(answered) return;
+ answered = true;
+ cancelAnimationFrame(rafId);
+ const isCorrect = pick === currentStyle;
+ const remaining = Math.ceil(timeLeft);
+
+ // lock + mark buttons
+ [...answersEl.children].forEach(b=>{
+ b.disabled = true;
+ if(b.dataset.style === currentStyle) b.classList.add('correct');
+ else if(b === btn) b.classList.add('wrong');
+ else b.classList.add('dim');
+ });
+
+ if(isCorrect){
+ const gained = 100 + remaining*15 + streak*20;
+ score += gained;
+ streak += 1;
+ correctCount += 1;
+ swatch.classList.add('correct');
+ feedbackEl.textContent = '\u2713 ' + currentStyle + ' +' + gained;
+ feedbackEl.className = 'feedback ok';
+ } else {
+ streak = 0;
+ swatch.classList.add('wrong');
+ feedbackEl.textContent = pick ? '\u2717 It was ' + currentStyle : 'Time\u2019s up \u2014 ' + currentStyle;
+ feedbackEl.className = 'feedback no';
+ }
+ updateHUD();
+
+ setTimeout(()=>{
+ if(round >= TOTAL_ROUNDS){ endGame(); }
+ else { round += 1; startRound(); }
+ }, 1150);
+ }
+
+ function endGame(){
+ const best = getBest();
+ const isBest = score > best;
+ if(isBest) setBest(score);
+ el('finalScore').textContent = score;
+ el('finalCorrect').textContent = correctCount + '/' + TOTAL_ROUNDS;
+ el('finalBest').textContent = getBest();
+
+ let title, eyebrow;
+ if(correctCount>=9){ title='Master Curator'; eyebrow='Exceptional Eye'; }
+ else if(correctCount>=7){ title='Well Curated'; eyebrow='Refined Taste'; }
+ else if(correctCount>=4){ title='Coming Along'; eyebrow='Developing Eye'; }
+ else { title='Keep Studying'; eyebrow='The Swatches Await'; }
+ el('overTitle').textContent = title;
+ el('overEyebrow').textContent = eyebrow;
+ el('bestFlag').textContent = isBest ? '\u2726 New Best Score \u2726' : '\u00A0';
+ el('overOverlay').classList.add('show');
+ updateHUD();
+ }
+
+ function newGame(){
+ round=1; score=0; streak=0; correctCount=0; currentStyle=null;
+ el('overOverlay').classList.remove('show');
+ el('startOverlay').classList.remove('show');
+ updateHUD();
+ startRound();
+ }
+
+ /* ————— Wire up ————— */
+ el('startBtn').addEventListener('click', newGame);
+ el('restartBtn').addEventListener('click', newGame);
+ el('bestVal').textContent = getBest();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/e1961bf42e98/claude-code.png b/data/artifacts/e1961bf42e98/claude-code.png
new file mode 100644
index 0000000..7fbb3a3
Binary files /dev/null and b/data/artifacts/e1961bf42e98/claude-code.png differ
diff --git a/data/artifacts/e1961bf42e98/gpt.html b/data/artifacts/e1961bf42e98/gpt.html
new file mode 100644
index 0000000..8a58b91
--- /dev/null
+++ b/data/artifacts/e1961bf42e98/gpt.html
@@ -0,0 +1,1180 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<title>Guess the Design Style – Designer Wallcoverings</title>
+<style>
+:root {
+ /* Design tokens */
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-soft: #1f1f25;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961; /* metallic gold */
+ --accent-soft: #7d6a45;
+ --line: rgba(201, 169, 97, 0.22);
+ --line-subtle: rgba(245, 242, 234, 0.08);
+ --danger: #d96161;
+ --success: #6fbf8b;
+
+ --shadow-soft: 0 20px 40px rgba(0, 0, 0, 0.48);
+ --shadow-subtle: 0 12px 30px rgba(0, 0, 0, 0.4);
+ --radius-card: 18px;
+ --radius-pill: 999px;
+
+ --font-display: "Playfair Display", "Didot", "Bodoni MT", Georgia, serif;
+ --font-sans: "Avenir Next", "Century Gothic", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+
+ --fs-display: 67px;
+ --fs-h1: 50px;
+ --fs-h2: 38px;
+ --fs-h3: 28px;
+ --fs-lead: 21px;
+ --fs-body: 16px;
+ --fs-caption: 12px;
+ --fs-label: 12px;
+
+ --ease: cubic-bezier(.22,.9,.24,1);
+ --ease-hero: cubic-bezier(.22,1,.36,1);
+ --transition-fast: 150ms var(--ease);
+ --transition-med: 220ms var(--ease);
+
+ --pattern-radius: 18px;
+ --pattern-border: 1px solid var(--line);
+
+ --timer-duration: 20;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ background: radial-gradient(circle at top, #181821 0, #050509 55%, #020203 100%);
+ color: var(--text);
+ font-family: var(--font-sans);
+ -webkit-font-smoothing: antialiased;
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+}
+
+/* Motion keyframes (from HyperFrames) */
+@keyframes fadeUp {
+ from { opacity: 0; transform: translateY(28px); }
+ to { opacity: 1; transform: none; }
+}
+@keyframes scaleIn {
+ from { opacity: 0; transform: scale(.92); }
+ to { opacity: 1; transform: none; }
+}
+@keyframes blurIn {
+ from { opacity: 0; filter: blur(12px); }
+ to { opacity: 1; filter: blur(0); }
+}
+
+/* Layout */
+.app-shell {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.app-main {
+ flex: 1;
+ padding: 96px 32px 32px;
+ display: flex;
+ justify-content: center;
+ align-items: stretch;
+}
+
+@media (max-width: 768px) {
+ .app-main {
+ padding: 96px 16px 24px;
+ }
+}
+
+/* Header / wordmark */
+.app-header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 80px;
+ display: flex;
+ align-items: center;
+ padding: 16px 32px 12px;
+ background: linear-gradient(to bottom, rgba(5,5,9,0.96), rgba(5,5,9,0.9), rgba(5,5,9,0.75));
+ backdrop-filter: blur(18px);
+ border-bottom: 1px solid var(--line-subtle);
+ z-index: 20;
+}
+
+.header-lockup {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.wordmark {
+ font-family: var(--font-display);
+ font-size: 42px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: #1c1a17; /* darkest ink within palette spirit */
+ color: var(--text); /* ensure visible near-black text on dark header */
+ text-shadow: 0 0 0 rgba(0,0,0,0.1);
+ line-height: 1.05;
+ white-space: nowrap;
+}
+
+@media (max-width: 880px) {
+ .wordmark {
+ font-size: 40px;
+ white-space: normal;
+ }
+}
+
+.wordmark-sub {
+ margin-top: 2px;
+ font-size: var(--fs-caption);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* Header meta */
+.header-meta {
+ margin-left: auto;
+ display: flex;
+ align-items: center;
+ gap: 18px;
+ font-size: var(--fs-label);
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.header-meta .pill {
+ border-radius: var(--radius-pill);
+ border: 1px solid var(--line-subtle);
+ padding: 6px 12px;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.header-meta .pill-label {
+ opacity: 0.8;
+}
+
+.header-meta .pill-value {
+ color: var(--accent);
+}
+
+/* Game panel */
+.game-shell {
+ width: 100%;
+ max-width: 1080px;
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
+ gap: 28px;
+ align-items: stretch;
+ animation: fadeUp .7s var(--ease-hero) both;
+}
+
+@media (max-width: 900px) {
+ .game-shell {
+ grid-template-columns: minmax(0, 1fr);
+ }
+}
+
+/* Pattern card */
+.pattern-card {
+ background: radial-gradient(circle at top, #252530 0, #14141b 40%, #101017 100%);
+ border-radius: var(--radius-card);
+ box-shadow: var(--shadow-soft);
+ border: 1px solid var(--line);
+ padding: 22px 22px 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+ position: relative;
+ overflow: hidden;
+}
+
+.pattern-label-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+}
+
+.pattern-label-row .eyebrow {
+ font-size: var(--fs-label);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.round-indicator {
+ font-size: var(--fs-label);
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: var(--accent);
+}
+
+.pattern-viewport {
+ position: relative;
+ flex: 1;
+ min-height: 260px;
+ max-height: 420px;
+ border-radius: calc(var(--radius-card) - 6px);
+ border: 1px solid var(--line-subtle);
+ overflow: hidden;
+ background: #111116;
+ display: flex;
+ align-items: stretch;
+ justify-content: stretch;
+}
+
+.pattern-frame {
+ position: relative;
+ flex: 1;
+}
+
+/* Subtle inner vignette frame */
+.pattern-frame::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ background:
+ radial-gradient(circle at top, rgba(255,255,255,0.14), transparent 55%) ,
+ linear-gradient(to bottom, rgba(0,0,0,0.55), transparent 40%, rgba(0,0,0,0.8));
+ mix-blend-mode: soft-light;
+ opacity: 0.9;
+}
+
+/* Base wallpaper layer */
+.pattern-base {
+ position: absolute;
+ inset: 0;
+}
+
+/* Motif layer */
+.pattern-motif {
+ position: absolute;
+ inset: 0;
+ mix-blend-mode: normal;
+}
+
+/* Edge highlight */
+.pattern-edge {
+ position: absolute;
+ inset: 0;
+ border-radius: calc(var(--radius-card) - 6px);
+ border: 1px solid rgba(255,255,255,0.04);
+ mix-blend-mode: screen;
+ pointer-events: none;
+}
+
+/* Info bar under pattern */
+.pattern-info {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+ font-size: var(--fs-caption);
+ color: var(--muted);
+}
+
+.timer-shell {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.timer-label {
+ font-size: var(--fs-caption);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+}
+
+.timer-bar-outer {
+ position: relative;
+ height: 4px;
+ border-radius: 999px;
+ overflow: hidden;
+ background: rgba(245,242,234,0.08);
+}
+
+.timer-bar-inner {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(90deg, var(--accent), #f0e0a3);
+ transform-origin: left center;
+ transform: scaleX(1);
+ transition: transform linear;
+}
+
+.timer-value {
+ min-width: 56px;
+ text-align: right;
+ font-variant-numeric: tabular-nums;
+}
+
+/* Right-side panel */
+.side-panel {
+ display: flex;
+ flex-direction: column;
+ gap: 18px;
+}
+
+.game-title {
+ font-family: var(--font-display);
+ font-size: var(--fs-h2);
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ color: var(--text);
+}
+
+.game-subtitle {
+ font-size: var(--fs-body);
+ color: var(--muted);
+ max-width: 30rem;
+ line-height: 1.6;
+}
+
+.pills-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.badge {
+ border-radius: var(--radius-pill);
+ border: 1px solid var(--line-subtle);
+ padding: 4px 10px;
+ font-size: var(--fs-caption);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* Score and streak */
+.score-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ font-size: var(--fs-label);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.score-row strong {
+ color: var(--accent);
+}
+
+.score-pill {
+ border-radius: var(--radius-pill);
+ border: 1px solid var(--line-subtle);
+ padding: 6px 12px;
+}
+
+.streak-dot-row {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.streak-dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ border: 1px solid rgba(201,169,97,0.5);
+ background: transparent;
+ opacity: 0.4;
+}
+
+.streak-dot.active {
+ background: var(--accent);
+ box-shadow: 0 0 0 1px rgba(201,169,97,0.3);
+ opacity: 1;
+}
+
+/* Options/buttons */
+.options-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px;
+}
+
+@media (max-width: 480px) {
+ .options-grid {
+ grid-template-columns: minmax(0, 1fr);
+ }
+}
+
+.option-btn {
+ position: relative;
+ border-radius: 999px;
+ border: 1px solid var(--line-subtle);
+ background: rgba(23,23,28,0.85);
+ color: var(--text);
+ padding: 12px 18px;
+ font-size: var(--fs-body);
+ font-family: var(--font-sans);
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ text-align: center;
+ cursor: pointer;
+ overflow: hidden;
+ transition:
+ background var(--transition-med),
+ color var(--transition-med),
+ border-color var(--transition-med),
+ box-shadow var(--transition-med),
+ transform 140ms var(--ease);
+}
+
+.option-btn::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(circle at top, rgba(255,255,255,0.16), transparent 60%);
+ opacity: 0;
+ transition: opacity var(--transition-med);
+ pointer-events: none;
+}
+
+.option-btn:hover {
+ border-color: var(--accent);
+ background: radial-gradient(circle at top left, rgba(201,169,97,0.16), rgba(9,9,13,0.95));
+ box-shadow: var(--shadow-subtle);
+ transform: translateY(-1px);
+}
+
+.option-btn:hover::before {
+ opacity: 1;
+}
+
+.option-btn:active {
+ transform: translateY(0);
+ box-shadow: 0 0 0 rgba(0,0,0,0);
+}
+
+.option-btn.correct {
+ border-color: var(--success);
+ background: linear-gradient(135deg, rgba(111,191,139,0.16), rgba(9,9,13,0.95));
+ box-shadow: 0 0 0 1px rgba(111,191,139,0.5);
+}
+
+.option-btn.wrong {
+ border-color: var(--danger);
+ background: linear-gradient(135deg, rgba(217,97,97,0.12), rgba(9,9,13,0.95));
+ box-shadow: 0 0 0 1px rgba(217,97,97,0.5);
+}
+
+/* Utility button */
+.ghost-btn {
+ border-radius: var(--radius-pill);
+ border: 1px solid var(--line-subtle);
+ background: transparent;
+ color: var(--muted);
+ padding: 8px 14px;
+ font-size: var(--fs-label);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ cursor: pointer;
+ transition:
+ color var(--transition-fast),
+ border-color var(--transition-fast),
+ background var(--transition-fast);
+}
+
+.ghost-btn:hover {
+ color: var(--accent);
+ border-color: var(--accent);
+ background: rgba(201,169,97,0.06);
+}
+
+/* Feedback strip */
+.feedback-strip {
+ min-height: 26px;
+ font-size: var(--fs-caption);
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: var(--muted);
+ display: flex;
+ align-items: center;
+}
+
+.feedback-strip span {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.feedback-strip .dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ border: 1px solid var(--line-subtle);
+ background: rgba(245,242,234,0.08);
+}
+
+.feedback-strip.correct span {
+ color: var(--success);
+}
+
+.feedback-strip.correct .dot {
+ background: var(--success);
+ border-color: rgba(111,191,139,0.6);
+}
+
+.feedback-strip.wrong span {
+ color: var(--danger);
+}
+
+.feedback-strip.wrong .dot {
+ background: var(--danger);
+ border-color: rgba(217,97,97,0.7);
+}
+
+/* Overlay */
+.overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(3,3,5,0.84);
+ display: none;
+ align-items: center;
+ justify-content: center;
+ z-index: 40;
+}
+
+.overlay.visible {
+ display: flex;
+ animation: blurIn .5s var(--ease-hero) both;
+}
+
+.overlay-card {
+ background: radial-gradient(circle at top, #26252f 0, #15141b 45%, #100f16 100%);
+ border-radius: 22px;
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow-soft);
+ padding: 28px 24px 22px;
+ max-width: 420px;
+ width: 90%;
+ text-align: left;
+ animation: scaleIn .5s var(--ease-hero) both;
+}
+
+.overlay-title {
+ font-family: var(--font-display);
+ font-size: var(--fs-h2);
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ margin-bottom: 10px;
+}
+
+.overlay-body {
+ font-size: var(--fs-body);
+ color: var(--muted);
+ margin-bottom: 18px;
+}
+
+.overlay-metrics {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 16px;
+ margin-bottom: 20px;
+ font-size: var(--fs-caption);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.overlay-metrics span strong {
+ display: block;
+ font-size: var(--fs-lead);
+ letter-spacing: 0.04em;
+ color: var(--accent);
+}
+
+.overlay-actions {
+ display: flex;
+ justify-content: flex-end;
+ gap: 10px;
+}
+
+/* Pattern styles */
+
+/* Common bases for variety */
+.pattern-base.damask {
+ background:
+ radial-gradient(circle at 20% 0, rgba(245,242,234,0.12), transparent 60%),
+ repeating-linear-gradient(
+ 90deg,
+ #15151b 0,
+ #15151b 40px,
+ #111118 40px,
+ #111118 80px
+ );
+}
+
+.pattern-motif.damask {
+ background-image:
+ radial-gradient(circle at 25% 20%, rgba(201,169,97,0.3) 0, transparent 25%),
+ radial-gradient(circle at 75% 20%, rgba(201,169,97,0.3) 0, transparent 25%),
+ radial-gradient(circle at 50% 55%, rgba(201,169,97,0.34) 0, transparent 30%),
+ radial-gradient(circle at 10% 65%, rgba(201,169,97,0.16) 0, transparent 22%),
+ radial-gradient(circle at 90% 65%, rgba(201,169,97,0.16) 0, transparent 22%);
+ background-size: 220px 260px;
+ background-position: 0 0, 110px 0, 55px 130px, -20px 90px, 130px 90px;
+ opacity: 0.88;
+}
+
+/* Toile: scenic line art using gradients */
+.pattern-base.toile {
+ background:
+ linear-gradient(to bottom, #16161d 0, #101018 80%),
+ radial-gradient(circle at top, rgba(245,242,234,0.14), transparent 55%);
+}
+
+.pattern-motif.toile {
+ background-image:
+ repeating-linear-gradient(
+ 135deg,
+ transparent 0,
+ transparent 12px,
+ rgba(245,242,234,0.06) 12px,
+ rgba(245,242,234,0.06) 13px
+ ),
+ repeating-linear-gradient(
+ -135deg,
+ transparent 0,
+ transparent 18px,
+ rgba(245,242,234,0.05) 18px,
+ rgba(245,242,234,0.05) 19px
+ ),
+ radial-gradient(circle at 20% 60%, rgba(245,242,234,0.12) 0, transparent 26%),
+ radial-gradient(circle at 70% 35%, rgba(245,242,234,0.13) 0, transparent 24%);
+ mix-blend-mode: screen;
+ opacity: 0.7;
+}
+
+/* Ikat: blurred diamonds */
+.pattern-base.ikat {
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ #14141b 0,
+ #14141b 36px,
+ #0f0f16 36px,
+ #0f0f16 72px
+ );
+}
+
+.pattern-motif.ikat {
+ background-image:
+ radial-gradient(circle at 10% 20%, rgba(201,169,97,0.35) 0, transparent 45%),
+ radial-gradient(circle at 40% 60%, rgba(245,242,234,0.5) 0, transparent 55%),
+ radial-gradient(circle at 70% 30%, rgba(201,169,97,0.35) 0, transparent 45%),
+ radial-gradient(circle at 90% 70%, rgba(245,242,234,0.5) 0, transparent 55%);
+ filter: blur(3px);
+ mix-blend-mode: screen;
+ opacity: 0.85;
+}
+
+/* Chinoiserie: vertical panels with organic motifs */
+.pattern-base.chinoiserie {
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ #15151d 0,
+ #15151d 70px,
+ #101018 70px,
+ #101018 72px
+ );
+}
+
+.pattern-motif.chinoiserie {
+ background-image:
+ radial-gradient(circle at 20% 70%, rgba(201,169,97,0.3) 0, transparent 30%),
+ radial-gradient(circle at 50% 40%, rgba(245,242,234,0.38) 0, transparent 32%),
+ radial-gradient(circle at 80% 65%, rgba(201,169,97,0.3) 0, transparent 30%),
+ radial-gradient(circle at 35% 10%, rgba(245,242,234,0.2) 0, transparent 26%);
+ background-size: 200px 260px;
+ mix-blend-mode: screen;
+ opacity: 0.8;
+}
+
+/* Geometric: crisp tessellated pattern */
+.pattern-base.geometric {
+ background:
+ radial-gradient(circle at top, rgba(245,242,234,0.16), transparent 55%),
+ #101018;
+}
+
+.pattern-motif.geometric {
+ background-image:
+ linear-gradient(135deg, rgba(201,169,97,0.4) 1px, transparent 1px),
+ linear-gradient(-135deg, rgba(201,169,97,0.4) 1px, transparent 1px),
+ linear-gradient(0deg, rgba(245,242,234,0.12) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(245,242,234,0.12) 1px, transparent 1px);
+ background-size: 32px 32px, 32px 32px, 8px 8px, 8px 8px;
+ mix-blend-mode: screen;
+ opacity: 0.9;
+}
+
+/* Grasscloth: fibrous vertical texture */
+.pattern-base.grasscloth {
+ background:
+ linear-gradient(to bottom, #181820 0, #101018 70%, #0b0b11 100%);
+}
+
+.pattern-motif.grasscloth {
+ background-image:
+ repeating-linear-gradient(
+ 90deg,
+ rgba(245,242,234,0.1) 0,
+ rgba(245,242,234,0.1) 2px,
+ rgba(0,0,0,0.15) 3px,
+ rgba(0,0,0,0.15) 6px
+ ),
+ repeating-linear-gradient(
+ 0deg,
+ rgba(245,242,234,0.03) 0,
+ rgba(245,242,234,0.03) 1px,
+ transparent 2px,
+ transparent 3px
+ );
+ opacity: 0.85;
+ mix-blend-mode: soft-light;
+}
+
+/* Accessibility */
+.sr-only {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ width: 1px;
+ margin: -1px;
+ padding: 0;
+ overflow: hidden;
+ position: absolute;
+}
+
+/* Focus outline */
+button:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: 2px;
+}
+
+/* Fine-tune scrollbar for pattern */
+.pattern-viewport::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+}
+</style>
+</head>
+<body>
+<div class="app-shell">
+ <header class="app-header">
+ <div class="header-lockup">
+ <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+ <div class="wordmark-sub">Guess the design style</div>
+ </div>
+ <div class="header-meta">
+ <div class="pill">
+ <span class="pill-label">Best</span>
+ <span class="pill-value" id="bestScoreLabel">0</span>
+ </div>
+ <div class="pill">
+ <span class="pill-label">Rounds</span>
+ <span class="pill-value">10</span>
+ </div>
+ </div>
+ </header>
+
+ <main class="app-main">
+ <section class="game-shell" aria-label="Guess the design style game">
+ <section class="pattern-card">
+ <div class="pattern-label-row">
+ <div class="eyebrow">Wallpaper motif</div>
+ <div class="round-indicator" id="roundLabel">Round 1 / 10</div>
+ </div>
+ <div class="pattern-viewport" aria-hidden="true">
+ <div class="pattern-frame">
+ <div id="patternBase" class="pattern-base geometric"></div>
+ <div id="patternMotif" class="pattern-motif geometric"></div>
+ <div class="pattern-edge"></div>
+ </div>
+ </div>
+ <div class="pattern-info">
+ <div class="timer-shell">
+ <div class="timer-label">Time remaining</div>
+ <div class="timer-bar-outer" aria-hidden="true">
+ <div id="timerBar" class="timer-bar-inner"></div>
+ </div>
+ </div>
+ <div id="timerValue" class="timer-value">20s</div>
+ </div>
+ </section>
+
+ <section class="side-panel">
+ <header>
+ <h1 class="game-title">Guess the Design Style</h1>
+ <p class="game-subtitle">
+ Read the pattern, then choose the style you think inspired it.
+ Ten swift rounds to train your design intuition.
+ </p>
+ </header>
+
+ <div class="pills-row">
+ <span class="badge">Damask</span>
+ <span class="badge">Toile</span>
+ <span class="badge">Ikat</span>
+ <span class="badge">Chinoiserie</span>
+ <span class="badge">Geometric</span>
+ <span class="badge">Grasscloth</span>
+ </div>
+
+ <div>
+ <div class="score-row">
+ <div class="score-pill">
+ Score <strong id="scoreLabel">0</strong>
+ </div>
+ <div class="score-pill">
+ Streak <strong id="streakLabel">0</strong>
+ </div>
+ </div>
+ <div class="streak-dot-row" aria-hidden="true">
+ <div class="streak-dot" id="streakDot1"></div>
+ <div class="streak-dot" id="streakDot2"></div>
+ <div class="streak-dot" id="streakDot3"></div>
+ <div class="streak-dot" id="streakDot4"></div>
+ <div class="streak-dot" id="streakDot5"></div>
+ </div>
+ </div>
+
+ <div class="options-grid" id="optionsContainer">
+ <!-- buttons injected by JS -->
+ </div>
+
+ <div style="display:flex;justify-content:space-between;align-items:center;margin-top:4px;">
+ <div id="feedbackStrip" class="feedback-strip" aria-live="polite">
+ <span><span class="dot"></span><span>Tap a style to begin</span></span>
+ </div>
+ <button type="button" class="ghost-btn" id="restartBtn">Restart</button>
+ </div>
+ </section>
+ </section>
+ </main>
+
+ <div class="overlay" id="overlay" role="dialog" aria-modal="true" aria-labelledby="overlayTitle" aria-hidden="true">
+ <div class="overlay-card">
+ <h2 class="overlay-title" id="overlayTitle">Game over</h2>
+ <p class="overlay-body" id="overlayBody">
+ Your eye for pattern is taking shape. Ready to refine it further?
+ </p>
+ <div class="overlay-metrics">
+ <span>Score<br><strong id="overlayScore">0</strong></span>
+ <span>Best<br><strong id="overlayBest">0</strong></span>
+ <span>Longest streak<br><strong id="overlayStreak">0</strong></span>
+ </div>
+ <div class="overlay-actions">
+ <button type="button" class="ghost-btn" id="overlayCloseBtn">Close</button>
+ <button type="button" class="ghost-btn" id="overlayRestartBtn" style="color:var(--accent);border-color:var(--accent);">
+ Play again
+ </button>
+ </div>
+ </div>
+ </div>
+
+</div>
+
+<script>
+(function() {
+ const STYLES = ["Damask", "Toile", "Ikat", "Chinoiserie", "Geometric", "Grasscloth"];
+ const TOTAL_ROUNDS = 10;
+ const ROUND_TIME = 20; // seconds
+
+ const patternBase = document.getElementById("patternBase");
+ const patternMotif = document.getElementById("patternMotif");
+ const roundLabel = document.getElementById("roundLabel");
+ const scoreLabel = document.getElementById("scoreLabel");
+ const streakLabel = document.getElementById("streakLabel");
+ const bestScoreLabel = document.getElementById("bestScoreLabel");
+ const timerBar = document.getElementById("timerBar");
+ const timerValue = document.getElementById("timerValue");
+ const optionsContainer = document.getElementById("optionsContainer");
+ const feedbackStrip = document.getElementById("feedbackStrip");
+ const restartBtn = document.getElementById("restartBtn");
+
+ const streakDots = [
+ document.getElementById("streakDot1"),
+ document.getElementById("streakDot2"),
+ document.getElementById("streakDot3"),
+ document.getElementById("streakDot4"),
+ document.getElementById("streakDot5")
+ ];
+
+ const overlay = document.getElementById("overlay");
+ const overlayScore = document.getElementById("overlayScore");
+ const overlayBest = document.getElementById("overlayBest");
+ const overlayStreak = document.getElementById("overlayStreak");
+ const overlayTitle = document.getElementById("overlayTitle");
+ const overlayBody = document.getElementById("overlayBody");
+ const overlayCloseBtn = document.getElementById("overlayCloseBtn");
+ const overlayRestartBtn = document.getElementById("overlayRestartBtn");
+
+ let currentRound = 1;
+ let currentAnswer = null;
+ let isLocked = false;
+ let score = 0;
+ let streak = 0;
+ let bestScore = 0;
+ let longestStreak = 0;
+ let timerId = null;
+ let timerRemaining = ROUND_TIME;
+
+ function loadBestScore() {
+ try {
+ const stored = localStorage.getItem("dw_guess_style_best");
+ if (stored !== null) bestScore = parseInt(stored, 10) || 0;
+ } catch (e) {
+ bestScore = 0;
+ }
+ bestScoreLabel.textContent = bestScore;
+ }
+
+ function saveBestScore() {
+ try {
+ localStorage.setItem("dw_guess_style_best", String(bestScore));
+ } catch (e) {}
+ }
+
+ function shuffle(arr) {
+ const a = arr.slice();
+ for (let i = a.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [a[i], a[j]] = [a[j], a[i]];
+ }
+ return a;
+ }
+
+ function applyPattern(style) {
+ const cls = style.toLowerCase();
+ patternBase.className = "pattern-base " + cls;
+ patternMotif.className = "pattern-motif " + cls;
+ }
+
+ function updateScoreDisplays() {
+ scoreLabel.textContent = score;
+ streakLabel.textContent = streak;
+ streakDots.forEach((dot, idx) => {
+ if (idx < Math.min(streak, streakDots.length)) {
+ dot.classList.add("active");
+ } else {
+ dot.classList.remove("active");
+ }
+ });
+ }
+
+ function setFeedback(state, message) {
+ feedbackStrip.classList.remove("correct", "wrong");
+ if (state === "correct") feedbackStrip.classList.add("correct");
+ if (state === "wrong") feedbackStrip.classList.add("wrong");
+ feedbackStrip.innerHTML = '<span><span class="dot"></span><span>' +
+ message +
+ "</span></span>";
+ }
+
+ function buildOptions() {
+ optionsContainer.innerHTML = "";
+ const correct = currentAnswer;
+ const stylesShuffled = shuffle(STYLES);
+ const options = [correct];
+ for (let i = 0; i < stylesShuffled.length && options.length < 4; i++) {
+ const s = stylesShuffled[i];
+ if (s !== correct && !options.includes(s)) options.push(s);
+ }
+ const finalList = shuffle(options);
+ finalList.forEach(label => {
+ const btn = document.createElement("button");
+ btn.type = "button";
+ btn.className = "option-btn";
+ btn.textContent = label;
+ btn.addEventListener("click", () => onGuess(label, btn));
+ optionsContainer.appendChild(btn);
+ });
+ }
+
+ function startTimer() {
+ clearInterval(timerId);
+ timerRemaining = ROUND_TIME;
+ timerValue.textContent = timerRemaining + "s";
+ timerBar.style.transition = "none";
+ timerBar.style.transform = "scaleX(1)";
+ // force reflow
+ void timerBar.offsetWidth;
+ timerBar.style.transition = "transform " + ROUND_TIME + "s linear";
+ timerBar.style.transform = "scaleX(0)";
+ timerId = setInterval(() => {
+ timerRemaining -= 1;
+ if (timerRemaining < 0) timerRemaining = 0;
+ timerValue.textContent = timerRemaining + "s";
+ if (timerRemaining <= 0) {
+ clearInterval(timerId);
+ timerId = null;
+ if (!isLocked) {
+ isLocked = true;
+ handleTimeout();
+ }
+ }
+ }, 1000);
+ }
+
+ function nextRound() {
+ if (currentRound > TOTAL_ROUNDS) {
+ endGame();
+ return;
+ }
+ isLocked = false;
+ currentAnswer = STYLES[Math.floor(Math.random() * STYLES.length)];
+ applyPattern(currentAnswer);
+ roundLabel.textContent = "Round " + currentRound + " / " + TOTAL_ROUNDS;
+ buildOptions();
+ startTimer();
+ if (currentRound === 1) {
+ setFeedback(null, "Tap a style to begin");
+ } else {
+ setFeedback(null, "Tune your eye to the next motif");
+ }
+ }
+
+ function lockButtons(correctLabel, clickedBtn) {
+ const buttons = optionsContainer.querySelectorAll("button");
+ buttons.forEach(btn => {
+ btn.disabled = true;
+ const label = btn.textContent;
+ if (label === correctLabel) {
+ btn.classList.add("correct");
+ }
+ if (clickedBtn && btn === clickedBtn && label !== correctLabel) {
+ btn.classList.add("wrong");
+ }
+ });
+ }
+
+ function onGuess(label, btn) {
+ if (isLocked) return;
+ isLocked = true;
+ clearInterval(timerId);
+ timerId = null;
+
+ const correct = label === currentAnswer;
+ lockButtons(currentAnswer, btn);
+
+ if (correct) {
+ const bonus = timerRemaining >= ROUND_TIME * 0.6 ? 2 : timerRemaining >= ROUND_TIME * 0.3 ? 1 : 0;
+ const base = 10;
+ const gained = base + bonus;
+ score += gained;
+ streak += 1;
+ if (streak > longestStreak) longestStreak = streak;
+ setFeedback("correct", "Correct – +" + gained + " pts");
+ } else {
+ streak = 0;
+ setFeedback("wrong", "That was " + currentAnswer);
+ }
+ updateScoreDisplays();
+
+ setTimeout(() => {
+ currentRound += 1;
+ nextRound();
+ }, 900);
+ }
+
+ function handleTimeout() {
+ lockButtons(currentAnswer, null);
+ streak = 0;
+ updateScoreDisplays();
+ setFeedback("wrong", "Time – it was " + currentAnswer);
+ setTimeout(() => {
+ currentRound += 1;
+ nextRound();
+ }, 900);
+ }
+
+ function endGame() {
+ clearInterval(timerId);
+ timerId = null;
+ if (score > bestScore) {
+ bestScore = score;
+ saveBestScore();
+ }
+ bestScoreLabel.textContent = bestScore;
+ overlayScore.textContent = score;
+ overlayBest.textContent = bestScore;
+ overlayStreak.textContent = longestStreak;
+
+ if (score === 0) {
+ overlayTitle.textContent = "Every eye starts somewhere";
+ overlayBody.textContent = "You’ve laid the first strip. Play again and see how quickly your pattern literacy sharpens.";
+ } else if (score < 60) {
+ overlayTitle.textContent = "Nicely observed";
+ overlayBody.textContent = "You’re catching the cues. Another pass and those motifs will feel second nature.";
+ } else if (score < 110) {
+ overlayTitle.textContent = "Considered eye";
+ overlayBody.textContent = "You’re reading styles with confidence. A few more runs and you’ll think like a studio librarian.";
+ } else {
+ overlayTitle.textContent = "Curator level";
+ overlayBody.textContent = "Your instincts are pure gallery. The next collection needs your signature.";
+ }
+
+ overlay.setAttribute("aria-hidden", "false");
+ overlay.classList.add("visible");
+ }
+
+ function restart() {
+ clearInterval(timerId);
+ timerId = null;
+ currentRound = 1;
+ score = 0;
+ streak = 0;
+ longestStreak = 0;
+ updateScoreDisplays();
+ setFeedback(null, "Tap a style to begin");
+ overlay.classList.remove("visible");
+ overlay.setAttribute("aria-hidden", "true");
+ nextRound();
+ }
+
+ restartBtn.addEventListener("click", restart);
+ overlayRestartBtn.addEventListener("click", restart);
+ overlayCloseBtn.addEventListener("click", function() {
+ overlay.classList.remove("visible");
+ overlay.setAttribute("aria-hidden", "true");
+ });
+
+ // Init
+ loadBestScore();
+ nextRound();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/e1961bf42e98/gpt.png b/data/artifacts/e1961bf42e98/gpt.png
new file mode 100644
index 0000000..0fc5a98
Binary files /dev/null and b/data/artifacts/e1961bf42e98/gpt.png differ
diff --git a/data/artifacts/e1961bf42e98/grok.html b/data/artifacts/e1961bf42e98/grok.html
new file mode 100644
index 0000000..7654310
--- /dev/null
+++ b/data/artifacts/e1961bf42e98/grok.html
@@ -0,0 +1,1139 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Guess the Design Style — Designer Wallcoverings</title>
+<style>
+:root {
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-2: #1e1e24;
+ --ink: #1c1a17;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --accent-dim: #7d6a45;
+ --line: rgba(201, 169, 97, 0.28);
+ --line-soft: rgba(245, 242, 234, 0.08);
+ --shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
+ --shadow-soft: 0 4px 16px rgba(0, 0, 0, 0.3);
+ --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', Futura, 'Helvetica Neue', sans-serif;
+ --radius: 2px;
+ --header-h: 72px;
+}
+
+*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+
+html, body {
+ height: 100%;
+ background: var(--bg);
+ color: var(--text);
+ font-family: var(--sans);
+ font-size: 16px;
+ line-height: 1.55;
+ -webkit-font-smoothing: antialiased;
+ overflow-x: hidden;
+}
+
+/* ── Header / Wordmark ── */
+header.brand-bar {
+ 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(13, 13, 15, 0.92);
+ backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--line);
+}
+
+.wordmark {
+ font-family: var(--serif);
+ font-size: clamp(18px, 2.4vw, 42px);
+ font-weight: 400;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text);
+ line-height: 1.15;
+ white-space: normal;
+ max-width: min(520px, 58vw);
+}
+
+.header-meta {
+ display: flex;
+ gap: 22px;
+ align-items: center;
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.header-meta b {
+ color: var(--accent);
+ font-weight: 500;
+}
+
+/* ── Layout ── */
+main {
+ min-height: 100%;
+ padding: calc(var(--header-h) + 36px) 24px 48px;
+ max-width: 920px;
+ margin: 0 auto;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.game-title {
+ font-family: var(--serif);
+ font-size: 28px;
+ font-weight: 400;
+ letter-spacing: 0.04em;
+ color: var(--text);
+ text-align: center;
+ margin-bottom: 6px;
+}
+
+.game-sub {
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 32px;
+ text-align: center;
+}
+
+/* ── Progress / HUD ── */
+.hud {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20px;
+ gap: 16px;
+ flex-wrap: wrap;
+}
+
+.hud-item {
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.hud-item span {
+ color: var(--text);
+ font-weight: 500;
+}
+
+.progress-track {
+ flex: 1;
+ min-width: 120px;
+ height: 2px;
+ background: var(--line-soft);
+ position: relative;
+ overflow: hidden;
+}
+
+.progress-fill {
+ position: absolute;
+ left: 0; top: 0; bottom: 0;
+ width: 0%;
+ background: var(--accent);
+ transition: width 0.5s var(--ease);
+}
+
+.timer-bar {
+ width: 100%;
+ height: 3px;
+ background: var(--line-soft);
+ margin-bottom: 28px;
+ overflow: hidden;
+ border-radius: 1px;
+}
+
+.timer-fill {
+ height: 100%;
+ width: 100%;
+ background: linear-gradient(90deg, var(--accent-dim), var(--accent));
+ transform-origin: left center;
+ transition: none;
+}
+
+.timer-fill.running {
+ animation: timerDrain linear forwards;
+}
+
+@keyframes timerDrain {
+ from { transform: scaleX(1); }
+ to { transform: scaleX(0); }
+}
+
+/* ── Pattern Stage ── */
+.stage {
+ width: 100%;
+ aspect-ratio: 16 / 10;
+ max-height: 380px;
+ background: var(--surface);
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow);
+ position: relative;
+ overflow: hidden;
+ margin-bottom: 28px;
+}
+
+.pattern-canvas {
+ position: absolute;
+ inset: 0;
+ transition: opacity 0.4s var(--ease), transform 0.5s var(--ease-out);
+}
+
+.pattern-canvas.exit {
+ opacity: 0;
+ transform: scale(1.03);
+}
+
+.pattern-canvas.enter {
+ animation: patternIn 0.55s var(--ease-out) both;
+}
+
+@keyframes patternIn {
+ from { opacity: 0; transform: scale(0.97); }
+ to { opacity: 1; transform: scale(1); }
+}
+
+/* Feedback flash */
+.stage-flash {
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ opacity: 0;
+ z-index: 5;
+ transition: opacity 0.25s var(--ease);
+}
+
+.stage-flash.correct {
+ background: radial-gradient(ellipse at center, rgba(201,169,97,0.35), transparent 70%);
+ opacity: 1;
+}
+
+.stage-flash.wrong {
+ background: radial-gradient(ellipse at center, rgba(160,60,50,0.3), transparent 70%);
+ opacity: 1;
+}
+
+/* ── Choice Buttons ── */
+.choices {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+ width: 100%;
+ margin-bottom: 24px;
+}
+
+.choice-btn {
+ appearance: none;
+ border: 1px solid var(--line);
+ background: var(--surface);
+ color: var(--text);
+ font-family: var(--sans);
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ padding: 18px 16px;
+ cursor: pointer;
+ transition: border-color 0.25s var(--ease), background 0.25s var(--ease), color 0.25s var(--ease), transform 0.2s var(--ease-pop);
+ position: relative;
+}
+
+.choice-btn:hover:not(:disabled) {
+ border-color: var(--accent);
+ background: var(--surface-2);
+ transform: translateY(-1px);
+}
+
+.choice-btn:active:not(:disabled) {
+ transform: translateY(0);
+}
+
+.choice-btn:disabled {
+ cursor: default;
+}
+
+.choice-btn.correct {
+ border-color: var(--accent);
+ background: rgba(201, 169, 97, 0.14);
+ color: var(--accent);
+}
+
+.choice-btn.wrong {
+ border-color: rgba(160, 80, 70, 0.6);
+ background: rgba(120, 40, 35, 0.2);
+ color: #c47870;
+}
+
+.choice-btn.dim {
+ opacity: 0.4;
+}
+
+/* ── Streak toast ── */
+.toast {
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--accent);
+ min-height: 18px;
+ text-align: center;
+ opacity: 0;
+ transition: opacity 0.3s var(--ease);
+}
+
+.toast.show { opacity: 1; }
+
+/* ── Overlays ── */
+.overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 200;
+ background: rgba(13, 13, 15, 0.88);
+ backdrop-filter: blur(8px);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24px;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.4s var(--ease);
+}
+
+.overlay.visible {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.panel {
+ background: var(--surface);
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow);
+ padding: 48px 40px;
+ max-width: 440px;
+ width: 100%;
+ text-align: center;
+ animation: panelIn 0.5s var(--ease-out) both;
+}
+
+@keyframes panelIn {
+ from { opacity: 0; transform: translateY(16px) scale(0.98); }
+ to { opacity: 1; transform: translateY(0) scale(1); }
+}
+
+.panel h2 {
+ font-family: var(--serif);
+ font-size: 38px;
+ font-weight: 400;
+ letter-spacing: 0.03em;
+ margin-bottom: 12px;
+ color: var(--text);
+}
+
+.panel .lead {
+ font-size: 15px;
+ color: var(--muted);
+ margin-bottom: 28px;
+ line-height: 1.6;
+}
+
+.panel .stat-row {
+ display: flex;
+ justify-content: center;
+ gap: 36px;
+ margin-bottom: 32px;
+ padding: 20px 0;
+ border-top: 1px solid var(--line-soft);
+ border-bottom: 1px solid var(--line-soft);
+}
+
+.panel .stat {
+ text-align: center;
+}
+
+.panel .stat .val {
+ font-family: var(--serif);
+ font-size: 32px;
+ color: var(--accent);
+ display: block;
+ line-height: 1.2;
+}
+
+.panel .stat .lbl {
+ font-size: 10px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.btn-primary {
+ appearance: none;
+ border: 1px solid var(--accent);
+ background: var(--accent);
+ color: var(--ink);
+ font-family: var(--sans);
+ font-size: 12px;
+ font-weight: 600;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ padding: 16px 36px;
+ cursor: pointer;
+ transition: background 0.25s var(--ease), transform 0.2s var(--ease-pop), box-shadow 0.25s var(--ease);
+}
+
+.btn-primary:hover {
+ background: #d4b86e;
+ box-shadow: 0 4px 20px rgba(201, 169, 97, 0.35);
+ transform: translateY(-1px);
+}
+
+.btn-ghost {
+ appearance: none;
+ border: 1px solid var(--line);
+ background: transparent;
+ color: var(--muted);
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ padding: 12px 24px;
+ cursor: pointer;
+ margin-top: 14px;
+ transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
+}
+
+.btn-ghost:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+}
+
+/* ══════════════════════════════════════
+ PATTERN MOTIFS — pure CSS / SVG
+ ══════════════════════════════════════ */
+
+/* DAMASK — ornate diamond medallions */
+.pat-damask {
+ background-color: #1a1512;
+ background-image:
+ radial-gradient(ellipse 40% 50% at 50% 50%, rgba(201,169,97,0.22) 0%, transparent 70%),
+ radial-gradient(ellipse 18% 22% at 50% 30%, rgba(201,169,97,0.35) 0%, transparent 60%),
+ radial-gradient(ellipse 14% 18% at 50% 70%, rgba(201,169,97,0.28) 0%, transparent 55%),
+ radial-gradient(circle at 50% 50%, transparent 28%, rgba(201,169,97,0.12) 29%, rgba(201,169,97,0.12) 32%, transparent 33%),
+ radial-gradient(circle at 0% 0%, transparent 40%, rgba(139,105,60,0.15) 41%, rgba(139,105,60,0.15) 44%, transparent 45%),
+ radial-gradient(circle at 100% 0%, transparent 40%, rgba(139,105,60,0.15) 41%, rgba(139,105,60,0.15) 44%, transparent 45%),
+ radial-gradient(circle at 0% 100%, transparent 40%, rgba(139,105,60,0.15) 41%, rgba(139,105,60,0.15) 44%, transparent 45%),
+ radial-gradient(circle at 100% 100%, transparent 40%, rgba(139,105,60,0.15) 41%, rgba(139,105,60,0.15) 44%, transparent 45%);
+ background-size: 120px 140px;
+}
+
+.pat-damask::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ radial-gradient(ellipse 8% 12% at 50% 50%, rgba(201,169,97,0.4) 0%, transparent 100%),
+ radial-gradient(circle at 25% 25%, rgba(201,169,97,0.18) 0 3px, transparent 4px),
+ radial-gradient(circle at 75% 25%, rgba(201,169,97,0.18) 0 3px, transparent 4px),
+ radial-gradient(circle at 25% 75%, rgba(201,169,97,0.18) 0 3px, transparent 4px),
+ radial-gradient(circle at 75% 75%, rgba(201,169,97,0.18) 0 3px, transparent 4px);
+ background-size: 120px 140px;
+ opacity: 0.9;
+}
+
+/* TOILE — pastoral scenic line-drawing feel via layered curves */
+.pat-toile {
+ background-color: #f0ebe3;
+ background-image:
+ radial-gradient(ellipse 60px 40px at 30% 35%, transparent 40%, rgba(45,70,90,0.15) 41%, rgba(45,70,90,0.15) 48%, transparent 49%),
+ radial-gradient(ellipse 50px 55px at 70% 60%, transparent 38%, rgba(45,70,90,0.12) 39%, rgba(45,70,90,0.12) 46%, transparent 47%),
+ radial-gradient(circle at 55% 25%, rgba(45,70,90,0.2) 0 2px, transparent 3px),
+ radial-gradient(circle at 20% 70%, rgba(45,70,90,0.18) 0 2px, transparent 3px),
+ radial-gradient(circle at 80% 40%, rgba(45,70,90,0.16) 0 1.5px, transparent 2.5px),
+ radial-gradient(ellipse 30px 20px at 45% 75%, transparent 50%, rgba(45,70,90,0.1) 51%, rgba(45,70,90,0.1) 60%, transparent 61%),
+ radial-gradient(ellipse 25px 35px at 15% 20%, transparent 45%, rgba(45,70,90,0.1) 46%, rgba(45,70,90,0.1) 55%, transparent 56%);
+ background-size: 200px 180px;
+}
+
+.pat-toile::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ /* tree-like vertical strokes */
+ linear-gradient(175deg, transparent 30%, rgba(45,70,90,0.1) 31%, rgba(45,70,90,0.1) 32%, transparent 33%),
+ linear-gradient(10deg, transparent 50%, rgba(45,70,90,0.08) 51%, rgba(45,70,90,0.08) 52%, transparent 53%),
+ /* small figure dots */
+ radial-gradient(ellipse 8px 14px at 40% 50%, rgba(45,70,90,0.22) 0%, transparent 70%),
+ radial-gradient(ellipse 6px 10px at 65% 30%, rgba(45,70,90,0.18) 0%, transparent 70%),
+ radial-gradient(circle at 25% 45%, rgba(45,70,90,0.15) 0 4px, transparent 5px);
+ background-size: 200px 180px;
+ opacity: 0.85;
+}
+
+/* IKAT — blurred staggered diamond / chevron dye-resist */
+.pat-ikat {
+ background-color: #2a1f18;
+ background-image:
+ repeating-linear-gradient(
+ 90deg,
+ #8b3a2a 0px, #8b3a2a 14px,
+ #c4a35a 14px, #c4a35a 28px,
+ #2a4a3a 28px, #2a4a3a 42px,
+ #c4a35a 42px, #c4a35a 56px,
+ #8b3a2a 56px, #8b3a2a 70px,
+ #1a3040 70px, #1a3040 84px
+ );
+ background-size: 84px 100%;
+ filter: none;
+ position: relative;
+}
+
+.pat-ikat::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ repeating-linear-gradient(
+ 0deg,
+ transparent 0px,
+ transparent 18px,
+ rgba(13,13,15,0.35) 18px,
+ rgba(13,13,15,0.15) 22px,
+ transparent 28px,
+ transparent 40px,
+ rgba(13,13,15,0.3) 40px,
+ rgba(13,13,15,0.12) 46px,
+ transparent 52px
+ );
+ mix-blend-mode: multiply;
+}
+
+.pat-ikat::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ transparent 0px,
+ rgba(245,242,234,0.06) 6px,
+ transparent 12px,
+ transparent 20px,
+ rgba(0,0,0,0.15) 28px,
+ transparent 36px,
+ transparent 42px
+ );
+ background-size: 84px 100%;
+ filter: blur(1.5px);
+}
+
+/* CHINOISERIE — pagoda / branch / bird motifs on silk ground */
+.pat-chinoiserie {
+ background-color: #1c2830;
+ background-image:
+ /* moon */
+ radial-gradient(circle at 78% 22%, rgba(245,230,200,0.35) 0 18px, transparent 19px),
+ /* branches */
+ radial-gradient(ellipse 80px 30px at 20% 60%, transparent 60%, rgba(180,140,90,0.25) 61%, rgba(180,140,90,0.25) 65%, transparent 66%),
+ radial-gradient(ellipse 60px 20px at 55% 40%, transparent 55%, rgba(180,140,90,0.2) 56%, rgba(180,140,90,0.2) 62%, transparent 63%),
+ /* blossoms */
+ radial-gradient(circle at 25% 45%, rgba(200,80,90,0.45) 0 5px, transparent 6px),
+ radial-gradient(circle at 32% 50%, rgba(200,80,90,0.35) 0 4px, transparent 5px),
+ radial-gradient(circle at 18% 52%, rgba(200,80,90,0.3) 0 3px, transparent 4px),
+ radial-gradient(circle at 60% 35%, rgba(200,80,90,0.4) 0 4px, transparent 5px),
+ radial-gradient(circle at 68% 38%, rgba(200,80,90,0.28) 0 3px, transparent 4px),
+ /* leaves */
+ radial-gradient(ellipse 10px 6px at 28% 55%, rgba(90,140,80,0.4) 0%, transparent 100%),
+ radial-gradient(ellipse 8px 5px at 40% 48%, rgba(90,140,80,0.35) 0%, transparent 100%),
+ radial-gradient(ellipse 12px 5px at 62% 42%, rgba(90,140,80,0.3) 0%, transparent 100%),
+ /* bird silhouette */
+ radial-gradient(ellipse 16px 8px at 48% 28%, rgba(245,230,200,0.3) 0%, transparent 100%),
+ radial-gradient(circle at 52% 26%, rgba(245,230,200,0.25) 0 3px, transparent 4px);
+ background-size: 220px 200px;
+}
+
+.pat-chinoiserie::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ /* pagoda roof suggestion */
+ linear-gradient(160deg, transparent 40%, rgba(201,169,97,0.12) 41%, rgba(201,169,97,0.12) 43%, transparent 44%),
+ linear-gradient(20deg, transparent 55%, rgba(201,169,97,0.1) 56%, rgba(201,169,97,0.1) 58%, transparent 59%),
+ radial-gradient(ellipse 40px 12px at 85% 70%, rgba(201,169,97,0.15) 0%, transparent 70%),
+ radial-gradient(circle at 10% 80%, rgba(200,80,90,0.2) 0 3px, transparent 4px),
+ radial-gradient(circle at 90% 55%, rgba(90,140,80,0.25) 0 4px, transparent 5px);
+ background-size: 220px 200px;
+}
+
+/* GEOMETRIC — crisp tessellation */
+.pat-geometric {
+ background-color: #12141a;
+ background-image:
+ linear-gradient(30deg, #c9a961 12%, transparent 12.5%, transparent 87%, #c9a961 87.5%, #c9a961),
+ linear-gradient(150deg, #c9a961 12%, transparent 12.5%, transparent 87%, #c9a961 87.5%, #c9a961),
+ linear-gradient(30deg, #c9a961 12%, transparent 12.5%, transparent 87%, #c9a961 87.5%, #c9a961),
+ linear-gradient(150deg, #c9a961 12%, transparent 12.5%, transparent 87%, #c9a961 87.5%, #c9a961),
+ linear-gradient(60deg, #3a4555 25%, transparent 25.5%, transparent 75%, #3a4555 75%, #3a4555),
+ linear-gradient(60deg, #3a4555 25%, transparent 25.5%, transparent 75%, #3a4555 75%, #3a4555);
+ background-size: 40px 70px;
+ background-position: 0 0, 0 0, 20px 35px, 20px 35px, 0 0, 20px 35px;
+ opacity: 1;
+}
+
+.pat-geometric::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(circle at center, transparent 30%, rgba(13,13,15,0.25) 100%);
+ pointer-events: none;
+}
+
+/* GRASSCLOTH — horizontal fiber weave texture */
+.pat-grasscloth {
+ background-color: #c4b8a0;
+ background-image:
+ repeating-linear-gradient(
+ 0deg,
+ transparent,
+ transparent 1px,
+ rgba(90, 75, 50, 0.08) 1px,
+ rgba(90, 75, 50, 0.08) 2px
+ ),
+ repeating-linear-gradient(
+ 90deg,
+ transparent,
+ transparent 3px,
+ rgba(70, 58, 40, 0.06) 3px,
+ rgba(70, 58, 40, 0.06) 4px
+ ),
+ repeating-linear-gradient(
+ 0deg,
+ rgba(140, 120, 85, 0.15),
+ rgba(180, 165, 130, 0.1) 4px,
+ rgba(120, 105, 75, 0.18) 8px,
+ rgba(160, 145, 110, 0.12) 12px
+ ),
+ linear-gradient(
+ 90deg,
+ rgba(100, 85, 55, 0.12) 0%,
+ transparent 30%,
+ rgba(90, 75, 50, 0.08) 50%,
+ transparent 70%,
+ rgba(100, 85, 55, 0.1) 100%
+ );
+ background-size: 100% 3px, 8px 100%, 100% 14px, 120px 100%;
+}
+
+.pat-grasscloth::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ repeating-linear-gradient(
+ 180deg,
+ rgba(60, 50, 35, 0.04) 0px,
+ transparent 1px,
+ transparent 5px,
+ rgba(60, 50, 35, 0.06) 6px
+ );
+ mix-blend-mode: multiply;
+}
+
+.pat-grasscloth::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(ellipse at 20% 40%, rgba(255,250,240,0.12) 0%, transparent 50%),
+ radial-gradient(ellipse at 80% 70%, rgba(80,65,40,0.1) 0%, transparent 40%);
+}
+
+/* SVG overlay patterns for richer damask/toile */
+.pattern-svg {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+}
+
+/* Round result chip */
+.result-chip {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) scale(0.8);
+ z-index: 6;
+ font-family: var(--serif);
+ font-size: 22px;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ padding: 12px 28px;
+ border: 1px solid var(--accent);
+ background: rgba(13, 13, 15, 0.85);
+ color: var(--accent);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.3s var(--ease), transform 0.35s var(--ease-pop);
+ white-space: nowrap;
+}
+
+.result-chip.show {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+}
+
+.result-chip.is-wrong {
+ border-color: #a05048;
+ color: #d09088;
+}
+
+@media (max-width: 560px) {
+ .wordmark { font-size: 16px; letter-spacing: 0.14em; max-width: 48vw; }
+ .header-meta { gap: 12px; font-size: 10px; }
+ .choices { grid-template-columns: 1fr; }
+ .panel { padding: 36px 24px; }
+ .panel h2 { font-size: 30px; }
+ header.brand-bar { padding: 0 16px; }
+ main { padding-left: 16px; padding-right: 16px; }
+}
+</style>
+</head>
+<body>
+
+<header class="brand-bar">
+ <div class="wordmark">Designer Wallcoverings</div>
+ <div class="header-meta">
+ <div>Score <b id="hdr-score">0</b></div>
+ <div>Best <b id="hdr-best">0</b></div>
+ </div>
+</header>
+
+<main>
+ <h1 class="game-title">Guess the Design Style</h1>
+ <p class="game-sub">Identify the wallcovering motif</p>
+
+ <div class="hud">
+ <div class="hud-item">Round <span id="round-num">1</span> / 10</div>
+ <div class="progress-track"><div class="progress-fill" id="progress"></div></div>
+ <div class="hud-item">Streak <span id="streak-num">0</span></div>
+ </div>
+
+ <div class="timer-bar"><div class="timer-fill" id="timer"></div></div>
+
+ <div class="stage" id="stage">
+ <div class="pattern-canvas" id="canvas"></div>
+ <div class="stage-flash" id="flash"></div>
+ <div class="result-chip" id="chip"></div>
+ </div>
+
+ <div class="choices" id="choices"></div>
+ <div class="toast" id="toast"></div>
+</main>
+
+<!-- Start Overlay -->
+<div class="overlay visible" id="start-overlay">
+ <div class="panel">
+ <h2>Guess the Style</h2>
+ <p class="lead">Ten rounds. A wallcovering motif appears — name its design tradition. Trust your eye.</p>
+ <div class="stat-row">
+ <div class="stat"><span class="val" id="start-best">0</span><span class="lbl">Best Score</span></div>
+ <div class="stat"><span class="val">10</span><span class="lbl">Rounds</span></div>
+ <div class="stat"><span class="val">8s</span><span class="lbl">Per Round</span></div>
+ </div>
+ <button class="btn-primary" id="btn-start">Begin</button>
+ </div>
+</div>
+
+<!-- End Overlay -->
+<div class="overlay" id="end-overlay">
+ <div class="panel">
+ <h2 id="end-title">Well Played</h2>
+ <p class="lead" id="end-lead">Your eye for pattern is refined.</p>
+ <div class="stat-row">
+ <div class="stat"><span class="val" id="end-score">0</span><span class="lbl">Score</span></div>
+ <div class="stat"><span class="val" id="end-streak">0</span><span class="lbl">Best Streak</span></div>
+ <div class="stat"><span class="val" id="end-best">0</span><span class="lbl">All-Time</span></div>
+ </div>
+ <button class="btn-primary" id="btn-restart">Play Again</button>
+ <br>
+ <button class="btn-ghost" id="btn-home">Return</button>
+ </div>
+</div>
+
+<script>
+(function () {
+ const STYLES = ['Damask', 'Toile', 'Ikat', 'Chinoiserie', 'Geometric', 'Grasscloth'];
+ const ROUND_TIME = 8000;
+ const TOTAL = 10;
+
+ const PATTERN_HTML = {
+ Damask: `
+ <div class="pat-damask" style="position:absolute;inset:0;"></div>
+ <svg class="pattern-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
+ <defs>
+ <pattern id="damaskTile" x="0" y="0" width="120" height="140" patternUnits="userSpaceOnUse">
+ <path d="M60 20 C70 35, 85 45, 60 70 C35 45, 50 35, 60 20 Z" fill="none" stroke="rgba(201,169,97,0.35)" stroke-width="1.2"/>
+ <path d="M60 70 C75 90, 90 100, 60 125 C30 100, 45 90, 60 70 Z" fill="none" stroke="rgba(201,169,97,0.28)" stroke-width="1"/>
+ <circle cx="60" cy="70" r="6" fill="none" stroke="rgba(201,169,97,0.4)" stroke-width="1"/>
+ <path d="M60 55 L65 65 L60 62 L55 65 Z" fill="rgba(201,169,97,0.3)"/>
+ <path d="M20 10 Q30 40 20 70 Q10 40 20 10" fill="none" stroke="rgba(201,169,97,0.15)" stroke-width="0.8"/>
+ <path d="M100 70 Q110 100 100 130 Q90 100 100 70" fill="none" stroke="rgba(201,169,97,0.15)" stroke-width="0.8"/>
+ <circle cx="30" cy="100" r="2" fill="rgba(201,169,97,0.25)"/>
+ <circle cx="90" cy="40" r="2" fill="rgba(201,169,97,0.25)"/>
+ </pattern>
+ </defs>
+ <rect width="100%" height="100%" fill="url(#damaskTile)"/>
+ </svg>`,
+
+ Toile: `
+ <div class="pat-toile" style="position:absolute;inset:0;"></div>
+ <svg class="pattern-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
+ <defs>
+ <pattern id="toileTile" x="0" y="0" width="200" height="180" patternUnits="userSpaceOnUse">
+ <!-- tree -->
+ <path d="M40 140 Q42 100 50 80 Q55 60 48 40" fill="none" stroke="rgba(45,70,90,0.35)" stroke-width="1.2"/>
+ <path d="M48 55 Q30 50 25 40" fill="none" stroke="rgba(45,70,90,0.28)" stroke-width="0.9"/>
+ <path d="M50 70 Q65 65 72 55" fill="none" stroke="rgba(45,70,90,0.28)" stroke-width="0.9"/>
+ <path d="M48 90 Q35 88 28 78" fill="none" stroke="rgba(45,70,90,0.22)" stroke-width="0.8"/>
+ <ellipse cx="48" cy="38" rx="14" ry="10" fill="none" stroke="rgba(45,70,90,0.3)" stroke-width="0.9"/>
+ <!-- figure -->
+ <circle cx="100" cy="95" r="5" fill="none" stroke="rgba(45,70,90,0.4)" stroke-width="1"/>
+ <path d="M100 100 L100 120 M100 105 L90 112 M100 105 L110 112 M100 120 L94 135 M100 120 L106 135" fill="none" stroke="rgba(45,70,90,0.35)" stroke-width="1"/>
+ <!-- bird -->
+ <path d="M150 50 Q160 45 170 50 Q160 48 150 50" fill="none" stroke="rgba(45,70,90,0.3)" stroke-width="0.9"/>
+ <path d="M155 50 Q158 55 162 50" fill="none" stroke="rgba(45,70,90,0.25)" stroke-width="0.7"/>
+ <!-- fence / ground -->
+ <path d="M10 150 Q60 145 100 152 Q140 148 190 155" fill="none" stroke="rgba(45,70,90,0.2)" stroke-width="0.8"/>
+ <!-- small house -->
+ <path d="M155 120 L155 140 L175 140 L175 120 Z" fill="none" stroke="rgba(45,70,90,0.28)" stroke-width="0.9"/>
+ <path d="M152 120 L165 108 L178 120" fill="none" stroke="rgba(45,70,90,0.3)" stroke-width="0.9"/>
+ <!-- foliage dots -->
+ <circle cx="70" cy="55" r="1.5" fill="rgba(45,70,90,0.25)"/>
+ <circle cx="35" cy="48" r="1.5" fill="rgba(45,70,90,0.2)"/>
+ <circle cx="130" cy="70" r="1" fill="rgba(45,70,90,0.2)"/>
+ </pattern>
+ </defs>
+ <rect width="100%" height="100%" fill="url(#toileTile)"/>
+ </svg>`,
+
+ Ikat: `
+ <div class="pat-ikat" style="position:absolute;inset:0;"></div>
+ <svg class="pattern-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" style="mix-blend-mode:soft-light;opacity:0.7">
+ <defs>
+ <pattern id="ikatWarp" x="0" y="0" width="84" height="60" patternUnits="userSpaceOnUse">
+ <path d="M0 10 Q7 5 14 10 Q21 15 28 10 Q35 5 42 10 Q49 15 56 10 Q63 5 70 10 Q77 15 84 10" fill="none" stroke="rgba(245,242,234,0.2)" stroke-width="6" stroke-linecap="round"/>
+ <path d="M0 30 Q7 38 14 30 Q21 22 28 30 Q35 38 42 30 Q49 22 56 30 Q63 38 70 30 Q77 22 84 30" fill="none" stroke="rgba(0,0,0,0.25)" stroke-width="8" stroke-linecap="round"/>
+ <path d="M0 50 Q7 45 14 50 Q21 55 28 50 Q35 45 42 50 Q49 55 56 50 Q63 45 70 50 Q77 55 84 50" fill="none" stroke="rgba(245,242,234,0.15)" stroke-width="5" stroke-linecap="round"/>
+ </pattern>
+ </defs>
+ <rect width="100%" height="100%" fill="url(#ikatWarp)"/>
+ </svg>`,
+
+ Chinoiserie: `
+ <div class="pat-chinoiserie" style="position:absolute;inset:0;"></div>
+ <svg class="pattern-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
+ <defs>
+ <pattern id="chinoTile" x="0" y="0" width="220" height="200" patternUnits="userSpaceOnUse">
+ <!-- willow branch -->
+ <path d="M10 30 Q40 50 30 90 Q25 120 50 150" fill="none" stroke="rgba(180,140,90,0.4)" stroke-width="1.4"/>
+ <path d="M30 90 Q55 85 70 100" fill="none" stroke="rgba(180,140,90,0.3)" stroke-width="1"/>
+ <path d="M28 70 Q5 75 0 90" fill="none" stroke="rgba(180,140,90,0.25)" stroke-width="0.9"/>
+ <!-- blossoms -->
+ <g fill="rgba(200,80,90,0.45)" stroke="none">
+ <circle cx="32" cy="65" r="3.5"/><circle cx="38" cy="62" r="2.5"/><circle cx="28" cy="60" r="2"/>
+ <circle cx="55" cy="95" r="3"/><circle cx="60" cy="92" r="2"/>
+ <circle cx="48" cy="140" r="2.5"/>
+ </g>
+ <!-- leaves -->
+ <ellipse cx="42" cy="80" rx="7" ry="3" fill="rgba(90,140,80,0.35)" transform="rotate(-30 42 80)"/>
+ <ellipse cx="20" cy="100" rx="6" ry="2.5" fill="rgba(90,140,80,0.3)" transform="rotate(20 20 100)"/>
+ <!-- crane / bird -->
+ <path d="M140 60 Q155 50 170 58 L165 55 Q155 48 145 55" fill="none" stroke="rgba(245,230,200,0.4)" stroke-width="1.2"/>
+ <circle cx="170" cy="57" r="2.5" fill="rgba(245,230,200,0.35)"/>
+ <path d="M155 55 Q158 48 162 52" fill="none" stroke="rgba(245,230,200,0.3)" stroke-width="0.8"/>
+ <!-- pagoda suggestion -->
+ <path d="M160 140 L175 125 L190 140" fill="none" stroke="rgba(201,169,97,0.35)" stroke-width="1.1"/>
+ <path d="M165 140 L165 160 L185 160 L185 140" fill="none" stroke="rgba(201,169,97,0.28)" stroke-width="1"/>
+ <path d="M158 125 L175 112 L192 125" fill="none" stroke="rgba(201,169,97,0.3)" stroke-width="1"/>
+ <!-- moon -->
+ <circle cx="190" cy="35" r="14" fill="none" stroke="rgba(245,230,200,0.2)" stroke-width="1"/>
+ <circle cx="190" cy="35" r="10" fill="rgba(245,230,200,0.08)"/>
+ </pattern>
+ </defs>
+ <rect width="100%" height="100%" fill="url(#chinoTile)"/>
+ </svg>`,
+
+ Geometric: `
+ <div class="pat-geometric" style="position:absolute;inset:0;"></div>
+ <svg class="pattern-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" style="opacity:0.55">
+ <defs>
+ <pattern id="geoTile" x="0" y="0" width="80" height="80" patternUnits="userSpaceOnUse">
+ <polygon points="40,5 75,40 40,75 5,40" fill="none" stroke="rgba(201,169,97,0.5)" stroke-width="1.2"/>
+ <polygon points="40,20 60,40 40,60 20,40" fill="none" stroke="rgba(201,169,97,0.3)" stroke-width="0.9"/>
+ <circle cx="40" cy="40" r="4" fill="rgba(201,169,97,0.35)"/>
+ <line x1="40" y1="0" x2="40" y2="10" stroke="rgba(90,110,140,0.4)" stroke-width="1"/>
+ <line x1="40" y1="70" x2="40" y2="80" stroke="rgba(90,110,140,0.4)" stroke-width="1"/>
+ <line x1="0" y1="40" x2="10" y2="40" stroke="rgba(90,110,140,0.4)" stroke-width="1"/>
+ <line x1="70" y1="40" x2="80" y2="40" stroke="rgba(90,110,140,0.4)" stroke-width="1"/>
+ </pattern>
+ </defs>
+ <rect width="100%" height="100%" fill="url(#geoTile)"/>
+ </svg>`,
+
+ Grasscloth: `
+ <div class="pat-grasscloth" style="position:absolute;inset:0;"></div>
+ <svg class="pattern-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" style="opacity:0.4;mix-blend-mode:multiply">
+ <defs>
+ <pattern id="grassTile" x="0" y="0" width="6" height="40" patternUnits="userSpaceOnUse">
+ <line x1="1" y1="0" x2="1.5" y2="40" stroke="rgba(70,55,35,0.35)" stroke-width="0.6"/>
+ <line x1="3" y1="0" x2="2.5" y2="40" stroke="rgba(90,75,50,0.25)" stroke-width="0.5"/>
+ <line x1="5" y1="0" x2="5.2" y2="40" stroke="rgba(60,48,30,0.3)" stroke-width="0.4"/>
+ </pattern>
+ <pattern id="grassHoriz" x="0" y="0" width="100" height="3" patternUnits="userSpaceOnUse">
+ <line x1="0" y1="1.5" x2="100" y2="1.5" stroke="rgba(80,65,40,0.15)" stroke-width="0.5"/>
+ </pattern>
+ </defs>
+ <rect width="100%" height="100%" fill="url(#grassTile)"/>
+ <rect width="100%" height="100%" fill="url(#grassHoriz)"/>
+ </svg>`
+ };
+
+ // State
+ let score = 0;
+ let streak = 0;
+ let bestStreak = 0;
+ let round = 0;
+ let currentAnswer = null;
+ let locked = false;
+ let timerId = null;
+ let timerStart = 0;
+ let sequence = [];
+
+ const $ = (id) => document.getElementById(id);
+ const canvas = $('canvas');
+ const choicesEl = $('choices');
+ const flash = $('flash');
+ const chip = $('chip');
+ const toast = $('toast');
+ const timerEl = $('timer');
+
+ function bestScore() {
+ return parseInt(localStorage.getItem('dw_guess_best') || '0', 10);
+ }
+ function saveBest(n) {
+ const b = bestScore();
+ if (n > b) localStorage.setItem('dw_guess_best', String(n));
+ }
+
+ function shuffle(arr) {
+ const a = arr.slice();
+ for (let i = a.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [a[i], a[j]] = [a[j], a[i]];
+ }
+ return a;
+ }
+
+ function buildSequence() {
+ // Ensure variety across 10 rounds using all 6 styles
+ let seq = [];
+ while (seq.length < TOTAL) {
+ seq = seq.concat(shuffle(STYLES));
+ }
+ return seq.slice(0, TOTAL);
+ }
+
+ function pickChoices(correct) {
+ const others = shuffle(STYLES.filter(s => s !== correct)).slice(0, 3);
+ return shuffle([correct, ...others]);
+ }
+
+ function updateHUD() {
+ $('hdr-score').textContent = score;
+ $('hdr-best').textContent = bestScore();
+ $('round-num').textContent = Math.min(round + 1, TOTAL);
+ $('streak-num').textContent = streak;
+ $('progress').style.width = ((round) / TOTAL * 100) + '%';
+ }
+
+ function showToast(msg) {
+ toast.textContent = msg;
+ toast.classList.add('show');
+ setTimeout(() => toast.classList.remove('show'), 1400);
+ }
+
+ function stopTimer() {
+ if (timerId) { clearTimeout(timerId); timerId = null; }
+ timerEl.classList.remove('running');
+ timerEl.style.animation = 'none';
+ }
+
+ function startTimer() {
+ stopTimer();
+ // force reflow to restart animation
+ void timerEl.offsetWidth;
+ timerEl.style.animation = '';
+ timerEl.style.animationDuration = (ROUND_TIME / 1000) + 's';
+ timerEl.classList.add('running');
+ timerStart = Date.now();
+ timerId = setTimeout(() => {
+ if (!locked) resolveRound(null);
+ }, ROUND_TIME);
+ }
+
+ function renderPattern(style) {
+ canvas.classList.remove('enter');
+ canvas.classList.add('exit');
+ setTimeout(() => {
+ canvas.innerHTML = PATTERN_HTML[style] || '';
+ canvas.classList.remove('exit');
+ canvas.classList.add('enter');
+ }, 280);
+ }
+
+ function renderChoices(correct) {
+ const opts = pickChoices(correct);
+ choicesEl.innerHTML = '';
+ opts.forEach(name => {
+ const btn = document.createElement('button');
+ btn.className = 'choice-btn';
+ btn.textContent = name;
+ btn.type = 'button';
+ btn.addEventListener('click', () => {
+ if (locked) return;
+ resolveRound(name);
+ });
+ choicesEl.appendChild(btn);
+ });
+ }
+
+ function resolveRound(picked) {
+ if (locked) return;
+ locked = true;
+ stopTimer();
+
+ const correct = picked === currentAnswer;
+ const elapsed = Date.now() - timerStart;
+ const speedBonus = correct ? Math.max(0, Math.round((1 - elapsed / ROUND_TIME) * 50)) : 0;
+ const points = correct ? (100 + speedBonus + streak * 10) : 0;
+
+ // Button states
+ const btns = choicesEl.querySelectorAll('.choice-btn');
+ btns.forEach(b => {
+ b.disabled = true;
+ if (b.textContent === currentAnswer) b.classList.add('correct');
+ else if (b.textContent === picked && !correct) b.classList.add('wrong');
+ else b.classList.add('dim');
+ });
+
+ // Flash + chip
+ flash.className = 'stage-flash ' + (correct ? 'correct' : 'wrong');
+ chip.textContent = correct ? ('+' + points) : currentAnswer;
+ chip.className = 'result-chip show' + (correct ? '' : ' is-wrong');
+
+ if (correct) {
+ score += points;
+ streak += 1;
+ bestStreak = Math.max(bestStreak, streak);
+ if (streak >= 3) showToast(streak + ' streak');
+ else if (speedBonus > 30) showToast('swift eye');
+ } else {
+ streak = 0;
+ if (picked === null) showToast('time expired');
+ }
+
+ updateHUD();
+
+ setTimeout(() => {
+ flash.className = 'stage-flash';
+ chip.className = 'result-chip';
+ round += 1;
+ if (round >= TOTAL) endGame();
+ else nextRound();
+ }, 1100);
+ }
+
+ function nextRound() {
+ locked = false;
+ currentAnswer = sequence[round];
+ updateHUD();
+ renderPattern(currentAnswer);
+ renderChoices(currentAnswer);
+ startTimer();
+ }
+
+ function endGame() {
+ stopTimer();
+ saveBest(score);
+ $('progress').style.width = '100%';
+ $('hdr-best').textContent = bestScore();
+
+ const title = score >= 900 ? 'Impeccable' : score >= 600 ? 'Well Played' : score >= 300 ? 'A Fine Start' : 'Keep Looking';
+ const lead = score >= 900
+ ? 'A connoisseur of pattern and tradition.'
+ : score >= 600
+ ? 'Your eye for wallcovering is refined.'
+ : score >= 300
+ ? 'The motifs are beginning to speak to you.'
+ : 'Each pattern holds a history — try again.';
+
+ $('end-title').textContent = title;
+ $('end-lead').textContent = lead;
+ $('end-score').textContent = score;
+ $('end-streak').textContent = bestStreak;
+ $('end-best').textContent = bestScore();
+ $('end-overlay').classList.add('visible');
+ }
+
+ function startGame() {
+ score = 0;
+ streak = 0;
+ bestStreak = 0;
+ round = 0;
+ sequence = buildSequence();
+ $('start-overlay').classList.remove('visible');
+ $('end-overlay').classList.remove('visible');
+ updateHUD();
+ nextRound();
+ }
+
+ function showStart() {
+ stopTimer();
+ $('start-best').textContent = bestScore();
+ $('hdr-best').textContent = bestScore();
+ $('end-overlay').classList.remove('visible');
+ $('start-overlay').classList.add('visible');
+ canvas.innerHTML = PATTERN_HTML['Damask'];
+ }
+
+ $('btn-start').addEventListener('click', startGame);
+ $('btn-restart').addEventListener('click', startGame);
+ $('btn-home').addEventListener('click', showStart);
+
+ // Init
+ $('hdr-best').textContent = bestScore();
+ $('start-best').textContent = bestScore();
+ canvas.innerHTML = PATTERN_HTML['Damask'];
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/e1961bf42e98/grok.png b/data/artifacts/e1961bf42e98/grok.png
new file mode 100644
index 0000000..1dbd9af
Binary files /dev/null and b/data/artifacts/e1961bf42e98/grok.png differ
diff --git a/data/artifacts/e1961bf42e98/kimi.html b/data/artifacts/e1961bf42e98/kimi.html
new file mode 100644
index 0000000..e17557f
--- /dev/null
+++ b/data/artifacts/e1961bf42e98/kimi.html
@@ -0,0 +1,729 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Guess the Design Style — Designer Wallcoverings</title>
+ <style>
+ /* DESIGN TOKENS — Luxe Noir Palette */
+ :root {
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-2: #1e1e24;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --accent-dim: #7d6a45;
+ --line: rgba(245, 242, 234, 0.12);
+ --shadow: rgba(0, 0, 0, 0.4);
+ --glow: rgba(201, 169, 97, 0.15);
+
+ --ease-swift: cubic-bezier(.22,.9,.24,1);
+ --ease-power: cubic-bezier(.77,0,.18,1);
+ --ease-overshoot: cubic-bezier(.34,1.56,.64,1);
+
+ --font-display: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ --font-body: 'Avenir Next', 'Century Gothic', Futura, 'Segoe UI', sans-serif;
+
+ --radius: 2px;
+ --hairline: 1px;
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ background: var(--bg);
+ color: var(--text);
+ font-family: var(--font-body);
+ line-height: 1.6;
+ min-height: 100vh;
+ overflow-x: hidden;
+ }
+
+ /* HEADER — Fixed Top Bar */
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 72px;
+ background: var(--surface);
+ border-bottom: var(--hairline) solid var(--line);
+ display: flex;
+ align-items: center;
+ padding: 0 48px;
+ z-index: 100;
+ box-shadow: 0 4px 24px var(--shadow);
+ }
+
+ .wordmark {
+ font-family: var(--font-display);
+ font-size: 42px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text);
+ font-weight: 400;
+ line-height: 1;
+ }
+
+ /* MAIN LAYOUT */
+ main {
+ padding-top: 120px;
+ max-width: 1200px;
+ margin: 0 auto;
+ padding-left: 48px;
+ padding-right: 48px;
+ padding-bottom: 80px;
+ }
+
+ /* HUD — Score/Timer */
+ .hud {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 48px;
+ padding-bottom: 24px;
+ border-bottom: var(--hairline) solid var(--line);
+ }
+
+ .hud-group {
+ display: flex;
+ gap: 48px;
+ }
+
+ .hud-item {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ }
+
+ .hud-label {
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--muted);
+ font-weight: 500;
+ }
+
+ .hud-value {
+ font-size: 28px;
+ color: var(--text);
+ font-weight: 300;
+ letter-spacing: 0.02em;
+ }
+
+ .hud-value.accent {
+ color: var(--accent);
+ }
+
+ .timer-bar {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ height: 2px;
+ background: var(--accent);
+ transition: width 1s linear;
+ }
+
+ /* PATTERN STAGE */
+ .stage {
+ position: relative;
+ width: 100%;
+ aspect-ratio: 16/10;
+ background: var(--surface);
+ border: var(--hairline) solid var(--line);
+ border-radius: var(--radius);
+ overflow: hidden;
+ box-shadow: 0 8px 48px var(--shadow);
+ margin-bottom: 48px;
+ }
+
+ .pattern-container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ }
+
+ /* Pattern Background Styles */
+ .pattern-damask {
+ background-color: var(--surface-2);
+ background-image:
+ radial-gradient(circle at 30% 30%, var(--accent-dim) 0%, transparent 40%),
+ radial-gradient(circle at 70% 70%, var(--accent-dim) 0%, transparent 40%),
+ radial-gradient(circle at 50% 50%, var(--muted) 0%, transparent 60%);
+ background-size: 200px 200px;
+ position: relative;
+ }
+ .pattern-damask::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: repeating-conic-gradient(
+ from 0deg at 50% 50%,
+ transparent 0deg,
+ var(--accent) 10deg,
+ transparent 20deg,
+ var(--accent-dim) 30deg,
+ transparent 40deg
+ );
+ opacity: 0.15;
+ }
+
+ .pattern-toile {
+ background-color: #f5f2ea;
+ background-image:
+ repeating-linear-gradient(45deg, transparent, transparent 35px, var(--line) 35px, var(--line) 36px),
+ repeating-linear-gradient(-45deg, transparent, transparent 35px, var(--line) 35px, var(--line) 36px);
+ position: relative;
+ }
+ .pattern-toile::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ radial-gradient(circle at 20% 30%, var(--bg) 2px, transparent 2px),
+ radial-gradient(circle at 80% 20%, var(--bg) 1.5px, transparent 1.5px),
+ radial-gradient(circle at 60% 70%, var(--bg) 2px, transparent 2px),
+ radial-gradient(circle at 30% 80%, var(--bg) 1.5px, transparent 1.5px);
+ background-size: 120px 100px;
+ opacity: 0.4;
+ }
+
+ .pattern-ikat {
+ background-color: var(--surface);
+ background-image:
+ repeating-linear-gradient(
+ 45deg,
+ transparent,
+ transparent 10px,
+ var(--accent) 10px,
+ var(--accent) 20px,
+ var(--accent-dim) 20px,
+ var(--accent-dim) 30px
+ ),
+ repeating-linear-gradient(
+ -45deg,
+ transparent,
+ transparent 15px,
+ var(--muted) 15px,
+ var(--muted) 25px
+ );
+ background-blend-mode: overlay;
+ opacity: 0.9;
+ }
+
+ .pattern-chinoiserie {
+ background-color: var(--surface-2);
+ position: relative;
+ overflow: hidden;
+ }
+ .pattern-chinoiserie::before {
+ content: '';
+ position: absolute;
+ inset: -50%;
+ width: 200%;
+ height: 200%;
+ background-image:
+ radial-gradient(ellipse 40px 120px at 30% 40%, var(--accent) 2px, transparent 2px),
+ radial-gradient(ellipse 30px 80px at 70% 60%, var(--accent) 1.5px, transparent 1.5px),
+ radial-gradient(circle 8px at 25% 45%, var(--accent-dim) 2px, transparent 2px),
+ radial-gradient(circle 6px at 75% 55%, var(--accent-dim) 1.5px, transparent 1.5px);
+ background-size: 200px 300px;
+ transform: rotate(-15deg);
+ opacity: 0.6;
+ }
+
+ .pattern-geometric {
+ background-color: var(--surface);
+ background-image:
+ linear-gradient(30deg, var(--accent) 12%, transparent 12.5%, transparent 87%, var(--accent) 87.5%, var(--accent)),
+ linear-gradient(150deg, var(--accent) 12%, transparent 12.5%, transparent 87%, var(--accent) 87.5%, var(--accent)),
+ linear-gradient(30deg, var(--accent) 12%, transparent 12.5%, transparent 87%, var(--accent) 87.5%, var(--accent)),
+ linear-gradient(150deg, var(--accent) 12%, transparent 12.5%, transparent 87%, var(--accent) 87.5%, var(--accent)),
+ linear-gradient(60deg, var(--accent-dim) 25%, transparent 25.5%, transparent 75%, var(--accent-dim) 75%, var(--accent-dim)),
+ linear-gradient(60deg, var(--accent-dim) 25%, transparent 25.5%, transparent 75%, var(--accent-dim) 75%, var(--accent-dim));
+ background-size: 80px 140px;
+ background-position: 0 0, 0 0, 40px 70px, 40px 70px, 0 0, 40px 70px;
+ opacity: 0.8;
+ }
+
+ .pattern-grasscloth {
+ background-color: var(--surface-2);
+ background-image:
+ repeating-linear-gradient(
+ 0deg,
+ transparent,
+ transparent 2px,
+ var(--muted) 2px,
+ var(--muted) 3px
+ );
+ position: relative;
+ }
+ .pattern-grasscloth::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ repeating-linear-gradient(
+ 90deg,
+ transparent,
+ transparent 1px,
+ var(--accent-dim) 1px,
+ var(--accent-dim) 2px
+ );
+ opacity: 0.3;
+ }
+
+ /* CHOICES GRID */
+ .choices {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 24px;
+ }
+
+ .choice-btn {
+ background: var(--surface);
+ border: var(--hairline) solid var(--line);
+ color: var(--text);
+ padding: 24px 16px;
+ font-family: var(--font-body);
+ font-size: 13px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ cursor: pointer;
+ transition: all 0.3s var(--ease-swift);
+ border-radius: var(--radius);
+ position: relative;
+ overflow: hidden;
+ }
+
+ .choice-btn:hover:not(:disabled) {
+ border-color: var(--accent);
+ transform: translateY(-2px);
+ box-shadow: 0 4px 24px var(--glow);
+ }
+
+ .choice-btn.correct {
+ background: rgba(201, 169, 97, 0.1);
+ border-color: var(--accent);
+ color: var(--accent);
+ }
+
+ .choice-btn.wrong {
+ background: rgba(139, 0, 0, 0.1);
+ border-color: #5c1a1a;
+ color: #a85a5a;
+ }
+
+ .choice-btn:disabled {
+ cursor: default;
+ opacity: 0.6;
+ }
+
+ /* OVERLAYS */
+ .overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(13, 13, 15, 0.95);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 200;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.5s var(--ease-power);
+ }
+
+ .overlay.active {
+ opacity: 1;
+ pointer-events: all;
+ }
+
+ .overlay-content {
+ text-align: center;
+ max-width: 600px;
+ padding: 48px;
+ }
+
+ .overlay-title {
+ font-family: var(--font-display);
+ font-size: 48px;
+ letter-spacing: 0.08em;
+ margin-bottom: 16px;
+ color: var(--text);
+ }
+
+ .overlay-subtitle {
+ font-size: 16px;
+ color: var(--muted);
+ margin-bottom: 48px;
+ letter-spacing: 0.05em;
+ }
+
+ .overlay-stats {
+ display: flex;
+ justify-content: center;
+ gap: 48px;
+ margin-bottom: 48px;
+ }
+
+ .stat {
+ text-align: center;
+ }
+
+ .stat-value {
+ font-size: 56px;
+ color: var(--accent);
+ font-family: var(--font-display);
+ line-height: 1;
+ margin-bottom: 8px;
+ }
+
+ .stat-label {
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--muted);
+ }
+
+ .btn-primary {
+ background: transparent;
+ border: var(--hairline) solid var(--accent);
+ color: var(--accent);
+ padding: 20px 48px;
+ font-family: var(--font-body);
+ font-size: 12px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ cursor: pointer;
+ transition: all 0.4s var(--ease-swift);
+ position: relative;
+ overflow: hidden;
+ }
+
+ .btn-primary:hover {
+ background: var(--accent);
+ color: var(--bg);
+ transform: translateY(-2px);
+ box-shadow: 0 8px 32px var(--glow);
+ }
+
+ /* Round Indicator */
+ .round-indicator {
+ position: absolute;
+ top: 24px;
+ right: 24px;
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--muted);
+ z-index: 10;
+ }
+
+ /* Feedback animation */
+ @keyframes pulse-accent {
+ 0%, 100% { box-shadow: 0 0 0 0 var(--glow); }
+ 50% { box-shadow: 0 0 30px 10px var(--glow); }
+ }
+
+ .feedback-pulse {
+ animation: pulse-accent 0.6s var(--ease-overshoot);
+ }
+
+ /* Hide patterns initially */
+ .pattern {
+ width: 100%;
+ height: 100%;
+ display: none;
+ }
+ .pattern.active {
+ display: block;
+ }
+
+ @media (max-width: 900px) {
+ .choices {
+ grid-template-columns: repeat(2, 1fr);
+ }
+ .wordmark {
+ font-size: 32px;
+ }
+ header {
+ padding: 0 24px;
+ }
+ main {
+ padding-left: 24px;
+ padding-right: 24px;
+ }
+ }
+ </style>
+</head>
+<body>
+
+ <header>
+ <div class="wordmark">Designer Wallcoverings</div>
+ </header>
+
+ <main>
+ <div class="hud" style="position: relative;">
+ <div class="hud-group">
+ <div class="hud-item">
+ <span class="hud-label">Score</span>
+ <span class="hud-value" id="score">0</span>
+ </div>
+ <div class="hud-item">
+ <span class="hud-label">Streak</span>
+ <span class="hud-value accent" id="streak">0</span>
+ </div>
+ <div class="hud-item">
+ <span class="hud-label">Best</span>
+ <span class="hud-value" id="best">0</span>
+ </div>
+ </div>
+ <div class="hud-item">
+ <span class="hud-label">Time</span>
+ <span class="hud-value" id="timer">15</span>
+ </div>
+ <div class="timer-bar" id="timerBar" style="width: 100%;"></div>
+ </div>
+
+ <div class="stage">
+ <div class="round-indicator">Round <span id="round">1</span> of 10</div>
+ <div class="pattern-container">
+ <div class="pattern pattern-damask" data-style="Damask"></div>
+ <div class="pattern pattern-toile" data-style="Toile"></div>
+ <div class="pattern pattern-ikat" data-style="Ikat"></div>
+ <div class="pattern pattern-chinoiserie" data-style="Chinoiserie"></div>
+ <div class="pattern pattern-geometric" data-style="Geometric"></div>
+ <div class="pattern pattern-grasscloth" data-style="Grasscloth"></div>
+ </div>
+ </div>
+
+ <div class="choices" id="choices">
+ <!-- Generated by JS -->
+ </div>
+ </main>
+
+ <!-- Start Overlay -->
+ <div class="overlay active" id="startOverlay">
+ <div class="overlay-content">
+ <h1 class="overlay-title">Identify the Style</h1>
+ <p class="overlay-subtitle">Test your eye for luxury wallcoverings.<br>10 rounds. 15 seconds each.</p>
+ <button class="btn-primary" onclick="game.start()">Begin</button>
+ </div>
+ </div>
+
+ <!-- Game Over Overlay -->
+ <div class="overlay" id="endOverlay">
+ <div class="overlay-content">
+ <h1 class="overlay-title" id="endTitle">Collection Complete</h1>
+ <div class="overlay-stats">
+ <div class="stat">
+ <div class="stat-value" id="finalScore">0</div>
+ <div class="stat-label">Score</div>
+ </div>
+ <div class="stat">
+ <div class="stat-value" id="finalBest">0</div>
+ <div class="stat-label">Best</div>
+ </div>
+ <div class="stat">
+ <div class="stat-value" id="finalStreak">0</div>
+ <div class="stat-label">Max Streak</div>
+ </div>
+ </div>
+ <button class="btn-primary" onclick="game.restart()">Play Again</button>
+ </div>
+ </div>
+
+ <script>
+ const STYLES = [
+ { name: 'Damask', class: 'pattern-damask' },
+ { name: 'Toile', class: 'pattern-toile' },
+ { name: 'Ikat', class: 'pattern-ikat' },
+ { name: 'Chinoiserie', class: 'pattern-chinoiserie' },
+ { name: 'Geometric', class: 'pattern-geometric' },
+ { name: 'Grasscloth', class: 'pattern-grasscloth' }
+ ];
+
+ const ROUND_TIME = 15;
+ const TOTAL_ROUNDS = 10;
+
+ class Game {
+ constructor() {
+ this.score = 0;
+ this.streak = 0;
+ this.maxStreak = 0;
+ this.round = 1;
+ this.currentStyle = null;
+ this.timer = null;
+ this.timeLeft = ROUND_TIME;
+ this.bestScore = parseInt(localStorage.getItem('dw_best_score') || '0');
+
+ this.updateDisplay();
+ document.getElementById('best').textContent = this.bestScore;
+ }
+
+ start() {
+ document.getElementById('startOverlay').classList.remove('active');
+ this.nextRound();
+ }
+
+ nextRound() {
+ if (this.round > TOTAL_ROUNDS) {
+ this.endGame();
+ return;
+ }
+
+ this.timeLeft = ROUND_TIME;
+ this.updateTimer();
+
+ // Pick random style for this round
+ this.currentStyle = STYLES[Math.floor(Math.random() * STYLES.length)];
+
+ // Show pattern
+ document.querySelectorAll('.pattern').forEach(p => p.classList.remove('active'));
+ document.querySelector(`.${this.currentStyle.class}`).classList.add('active');
+
+ // Generate 4 choices (including correct one)
+ const choices = this.generateChoices();
+ this.renderChoices(choices);
+
+ this.updateDisplay();
+ this.startTimer();
+ }
+
+ generateChoices() {
+ const correct = this.currentStyle.name;
+ const others = STYLES.filter(s => s.name !== correct).map(s => s.name);
+ const shuffled = others.sort(() => Math.random() - 0.5).slice(0, 3);
+ const all = [correct, ...shuffled].sort(() => Math.random() - 0.5);
+ return all;
+ }
+
+ renderChoices(choices) {
+ const container = document.getElementById('choices');
+ container.innerHTML = '';
+
+ choices.forEach(choice => {
+ const btn = document.createElement('button');
+ btn.className = 'choice-btn';
+ btn.textContent = choice;
+ btn.onclick = () => this.guess(choice, btn);
+ container.appendChild(btn);
+ });
+ }
+
+ guess(styleName, btnElement) {
+ clearInterval(this.timer);
+ const buttons = document.querySelectorAll('.choice-btn');
+ const isCorrect = styleName === this.currentStyle.name;
+
+ buttons.forEach(btn => {
+ btn.disabled = true;
+ if (btn.textContent === this.currentStyle.name) {
+ btn.classList.add('correct');
+ } else if (btn === btnElement && !isCorrect) {
+ btn.classList.add('wrong');
+ }
+ });
+
+ if (isCorrect) {
+ this.streak++;
+ if (this.streak > this.maxStreak) this.maxStreak = this.streak;
+ const timeBonus = Math.floor(this.timeLeft * 10);
+ const streakBonus = (this.streak - 1) * 50;
+ this.score += 100 + timeBonus + streakBonus;
+ btnElement.classList.add('feedback-pulse');
+ } else {
+ this.streak = 0;
+ }
+
+ this.updateDisplay();
+
+ setTimeout(() => {
+ this.round++;
+ this.nextRound();
+ }, 1500);
+ }
+
+ startTimer() {
+ clearInterval(this.timer);
+ this.timer = setInterval(() => {
+ this.timeLeft--;
+ this.updateTimer();
+
+ if (this.timeLeft <= 0) {
+ clearInterval(this.timer);
+ this.timeOut();
+ }
+ }, 1000);
+ }
+
+ timeOut() {
+ const buttons = document.querySelectorAll('.choice-btn');
+ buttons.forEach(btn => {
+ btn.disabled = true;
+ if (btn.textContent === this.currentStyle.name) {
+ btn.classList.add('correct');
+ }
+ });
+ this.streak = 0;
+ this.updateDisplay();
+
+ setTimeout(() => {
+ this.round++;
+ this.nextRound();
+ }, 2000);
+ }
+
+ updateTimer() {
+ document.getElementById('timer').textContent = this.timeLeft;
+ const pct = (this.timeLeft / ROUND_TIME) * 100;
+ document.getElementById('timerBar').style.width = pct + '%';
+ }
+
+ updateDisplay() {
+ document.getElementById('score').textContent = this.score;
+ document.getElementById('streak').textContent = this.streak;
+ document.getElementById('round').textContent = Math.min(this.round, TOTAL_ROUNDS);
+ }
+
+ endGame() {
+ clearInterval(this.timer);
+
+ if (this.score > this.bestScore) {
+ this.bestScore = this.score;
+ localStorage.setItem('dw_best_score', this.bestScore);
+ }
+
+ document.getElementById('finalScore').textContent = this.score;
+ document.getElementById('finalBest').textContent = this.bestScore;
+ document.getElementById('finalStreak').textContent = this.maxStreak;
+ document.getElementById('endOverlay').classList.add('active');
+ }
+
+ restart() {
+ this.score = 0;
+ this.streak = 0;
+ this.maxStreak = 0;
+ this.round = 1;
+ this.currentStyle = null;
+ this.timeLeft = ROUND_TIME;
+
+ document.getElementById('endOverlay').classList.remove('active');
+ document.getElementById('best').textContent = this.bestScore;
+
+ this.nextRound();
+ }
+ }
+
+ const game = new Game();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/e1961bf42e98/kimi.png b/data/artifacts/e1961bf42e98/kimi.png
new file mode 100644
index 0000000..a0b1c85
Binary files /dev/null and b/data/artifacts/e1961bf42e98/kimi.png differ
diff --git a/data/artifacts/e1961bf42e98/qwen25-7b.html b/data/artifacts/e1961bf42e98/qwen25-7b.html
new file mode 100644
index 0000000..d80ee07
--- /dev/null
+++ b/data/artifacts/e1961bf42e98/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>Guess the Design Style</title>
+ <style>
+ :root {
+ --bg: #17171c;
+ --surface: #f5f2ea;
+ --text: #3a2c22;
+ --muted: #8d7bb0;
+ --accent: #b0472e;
+ --line: 1px solid var(--muted);
+ --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);
+ }
+ body {
+ background-color: var(--bg);
+ color: var(--text);
+ font-family: 'Bodoni MT', Didot, Georgia, serif;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+ overflow: hidden;
+ }
+ header {
+ font-size: 52px;
+ letter-spacing: .3em;
+ color: var(--text);
+ padding-left: 24px;
+ }
+ #game-container {
+ max-width: 800px;
+ width: 100%;
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: var(--shadow);
+ overflow: hidden;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 24px;
+ }
+ .card {
+ width: calc(50% - 32px);
+ height: 180px;
+ margin-right: 32px;
+ position: relative;
+ border-radius: 14px;
+ background-color: var(--surface);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ overflow: hidden;
+ transition: transform .7s ease-in-out, box-shadow .5s var(--ease) both;
+ }
+ .card:hover {
+ transform: translateY(-16px);
+ box-shadow: 0 24px 80px rgba(0,0,0,.18), glow 0 0 32px var(--accent)@35%;
+ }
+ .design-style {
+ width: 120px;
+ height: 120px;
+ background-size: cover;
+ }
+ #scoreboard {
+ font-family: 'Apple SD Gothic Neo', sans-serif;
+ color: var(--text);
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ margin-left: 32px;
+ line-height: 1.5;
+ }
+ button {
+ padding: 8px 24px;
+ border: none;
+ background-color: var(--surface);
+ color: var(--text);
+ font-size: 16px;
+ text-transform: uppercase;
+ letter-spacing: .1em;
+ margin-right: 8px;
+ cursor: pointer;
+ transition: transform .25s ease-in-out, box-shadow .25s ease-in-out;
+ }
+ button:hover {
+ transform: scale(1.05);
+ box-shadow: inset 0 -4px var(--accent);
+ }
+ </style>
+</head>
+<body>
+<header>DESIGNER WALLCOVERINGS</header>
+<div id="game-container">
+ <div class="card" style="--bg-image: url('data:image/svg+xml;utf8,<svg width="120" height="120"><rect width="120" height="120" fill="url(#GradientBackground)" /><defs><linearGradient id="GradientBackground" x1="50%" y1="0%" x2="50%" y2="100%"><stop offset="0%" style="stop-color:#c9a961;stop-opacity:1" /><stop offset="100%" style="stop-color:#7d6a45;stop-opacity:1" /></linearGradient></defs></svg>');">
+ <img class="design-style" src="" alt="">
+ </div>
+ <button id="damask">Damask</button>
+ <button id="toile">Toile</button>
+ <button id="ikat">Ikat</button>
+ <button id="chinoiserie">Chinoiserie</button>
+</div>
+<div id="scoreboard">
+ Score: 0<br>Streak: 0<br>Best: 0
+</div>
+
+<script>
+let score = 0;
+let streak = 0;
+const bestScore = localStorage.getItem('bestScore') || 0;
+
+function setupGame() {
+ const wallpaper = document.querySelector('.card');
+ const designButtons = document.querySelectorAll('button');
+ const scoreboard = document.getElementById('scoreboard');
+
+ function updateScore(newScore) {
+ score += newScore;
+ streak++;
+ if (score > bestScore) {
+ localStorage.setItem('bestScore', score);
+ }
+ scoreboard.innerHTML = `Score: ${score}<br>Streak: ${streak}<br>Best: ${localStorage.getItem('bestScore')}`;
+ }
+
+ function resetGame() {
+ score = 0;
+ streak = 0;
+ document.getElementById('scoreboard').innerHTML = 'Score: 0<br>Streak: 0<br>Best: 0';
+ }
+
+ let currentDesignStyle = null;
+
+ designButtons.forEach(button => button.addEventListener('click', function() {
+ if (currentDesignStyle === this.textContent) {
+ updateScore(1);
+ wallpaper.style.backgroundColor = `url('data:image/svg+xml;utf8,<svg width="120" height="120"><rect width="120" height="120" fill="${this.getAttribute('id').toLowerCase()}-style" /><defs><linearGradient id="GradientBackground" x1="50%" y1="0%" x2="50%" y2="100%"><stop offset="0%" style="stop-color:#c9a961;stop-opacity:1" /><stop offset="100%" style="stop-color:#7d6a45;stop-opacity:1" /></linearGradient></defs></svg>');`);
+ currentDesignStyle = null;
+ } else {
+ updateScore(-1);
+ wallpaper.style.backgroundColor = `url('data:image/svg+xml;utf8,<svg width="120" height="120"><rect width="120" height="120" fill="${this.getAttribute('id').toLowerCase()}-style" /><defs><linearGradient id="GradientBackground" x1="50%" y1="0%" x2="50%" y2="100%"><stop offset="0%" style="stop-color:#c9a961;stop-opacity:1" /><stop offset="100%" style="stop-color:#7d6a45;stop-opacity:1" /></linearGradient></defs></svg>');`;
+ currentDesignStyle = this.textContent;
+ }
+ }));
+
+ // Initial design
+ wallpaper.style.backgroundColor = `url('data:image/svg+xml;utf8,<svg width="120" height="120"><rect width="120" height="120" fill="damask-style" /><defs><linearGradient id="GradientBackground" x1="50%" y1="0%" x2="50%" y2="100%"><stop offset="0%" style="stop-color:#c9a961;stop-opacity:1" /><stop offset="100%" style="stop-color:#7d6a45;stop-opacity:1" /></linearGradient></defs></svg>');`;
+ currentDesignStyle = 'Damask';
+}
+
+setupGame();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/e1961bf42e98/qwen25-7b.png b/data/artifacts/e1961bf42e98/qwen25-7b.png
new file mode 100644
index 0000000..6d5dd62
Binary files /dev/null and b/data/artifacts/e1961bf42e98/qwen25-7b.png differ
diff --git a/data/artifacts/e1961bf42e98/qwen3-14b.html b/data/artifacts/e1961bf42e98/qwen3-14b.html
new file mode 100644
index 0000000..74e391c
--- /dev/null
+++ b/data/artifacts/e1961bf42e98/qwen3-14b.html
@@ -0,0 +1,298 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Guess the Design Style</title>
+ <style>
+ :root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e;
+ --line: #e0e0e0;
+ --shadow: 0 8px 24px rgba(0,0,0,0.12);
+ --ease: cubic-bezier(0.22, 1, 0.36, 1);
+ --font-display: 'Playfair Display', Georgia, serif;
+ --font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ }
+
+ * {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ }
+
+ body {
+ font-family: var(--font-body);
+ background-color: var(--bg);
+ color: var(--text);
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ }
+
+ header {
+ font-family: var(--font-display);
+ font-size: 48px;
+ letter-spacing: 0.18em;
+ color: var(--text);
+ padding: 16px 32px;
+ background-color: var(--surface);
+ box-shadow: var(--shadow);
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ text-transform: uppercase;
+ min-height: 80px;
+ }
+
+ main {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 32px;
+ position: relative;
+ }
+
+ .game-container {
+ position: relative;
+ width: 100%;
+ max-width: 600px;
+ margin: 0 auto;
+ text-align: center;
+ }
+
+ .pattern {
+ width: 100%;
+ height: 300px;
+ background: linear-gradient(45deg, var(--accent) 25%, transparent 25%, transparent 50%, var(--accent) 50%, var(--accent) 75%, transparent 75%, transparent 100%);
+ background-size: 20px 20px;
+ border: 1px solid var(--line);
+ box-shadow: 0 0 16px rgba(0,0,0,0.05);
+ margin-bottom: 32px;
+ animation: drift 18s linear infinite;
+ }
+
+ @keyframes drift {
+ 0% {
+ background-position: 0 0;
+ }
+ 100% {
+ background-position: 40px 40px;
+ }
+ }
+
+ .scoreboard {
+ font-size: 14px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 32px;
+ }
+
+ .scoreboard span {
+ font-weight: bold;
+ color: var(--text);
+ }
+
+ .buttons {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 16px;
+ margin-bottom: 32px;
+ }
+
+ .button {
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ padding: 16px;
+ text-align: center;
+ font-size: 14px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--text);
+ transition: all 150ms var(--ease);
+ cursor: pointer;
+ }
+
+ .button:hover {
+ background-color: var(--accent);
+ color: var(--surface);
+ box-shadow: 0 0 12px rgba(0,0,0,0.2);
+ }
+
+ .overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0,0,0,0.8);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ visibility: hidden;
+ opacity: 0;
+ transition: all 250ms var(--ease);
+ }
+
+ .overlay.show {
+ visibility: visible;
+ opacity: 1;
+ }
+
+ .overlay-content {
+ background: var(--surface);
+ padding: 32px;
+ border-radius: 14px;
+ box-shadow: 0 0 24px rgba(0,0,0,0.2);
+ text-align: center;
+ font-size: 24px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--text);
+ }
+
+ .overlay-content .icon {
+ font-size: 48px;
+ margin-bottom: 16px;
+ }
+
+ .overlay-content .correct {
+ color: var(--accent);
+ }
+
+ .overlay-content .wrong {
+ color: var(--muted);
+ }
+
+ footer {
+ padding: 16px 32px;
+ font-size: 14px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--muted);
+ text-align: center;
+ }
+ </style>
+</head>
+<body>
+ <header>DESIGNER WALLCOVERINGS</header>
+ <main>
+ <div class="game-container">
+ <div class="scoreboard">
+ <span>Score: <span id="score">0</span></span> | <span>Streak: <span id="streak">0</span></span> | <span>Round: <span id="round">1</span>/10</span>
+ </div>
+ <div class="pattern" id="pattern"></div>
+ <div class="buttons">
+ <button class="button" data-style="Damask">Damask</button>
+ <button class="button" data-style="Toile">Toile</button>
+ <button class="button" data-style="Ikat">Ikat</button>
+ <button class="button" data-style="Chinoiserie">Chinoiserie</button>
+ <button class="button" data-style="Geometric">Geometric</button>
+ <button class="button" data-style="Grasscloth">Grasscloth</button>
+ </div>
+ <div class="overlay" id="overlay">
+ <div class="overlay-content" id="overlayContent">
+ <div class="icon" id="overlayIcon"></div>
+ <span id="overlayMessage">Correct!</span>
+ </div>
+ </div>
+ </div>
+ <footer>© 2025 Designer Wallcoverings</footer>
+ </main>
+ <script>
+ const styles = [
+ { name: "Damask", pattern: "linear-gradient(45deg, var(--accent) 25%, transparent 25%, transparent 50%, var(--accent) 50%, var(--accent) 75%, transparent 75%, transparent 100%)", backgroundSize: "16px 16px" },
+ { name: "Toile", pattern: "linear-gradient(45deg, var(--accent) 25%, transparent 25%, transparent 50%, var(--accent) 50%, var(--accent) 75%, transparent 75%, transparent 100%)", backgroundSize: "20px 20px" },
+ { name: "Ikat", pattern: "linear-gradient(45deg, var(--accent) 30%, transparent 30%, transparent 70%, var(--accent) 70%)", backgroundSize: "32px 32px" },
+ { name: "Chinoiserie", pattern: "radial-gradient(circle at 25% 25%, var(--accent) 30%, transparent 30%)", backgroundSize: "64px 64px" },
+ { name: "Geometric", pattern: "repeating-linear-gradient(45deg, var(--accent) 0, var(--accent) 10px, transparent 10px, transparent 20px)", backgroundSize: "40px 40px" },
+ { name: "Grasscloth", pattern: "linear-gradient(90deg, var(--accent) 50%, transparent 50%)", backgroundSize: "4px 4px" }
+ ];
+
+ let currentStyle, currentPattern, score = 0, streak = 0, round = 1;
+ const maxRounds = 10;
+ const patternElement = document.getElementById("pattern");
+ const overlay = document.getElementById("overlay");
+ const overlayContent = document.getElementById("overlayContent");
+ const overlayIcon = document.getElementById("overlayIcon");
+ const overlayMessage = document.getElementById("overlayMessage");
+ const scoreEl = document.getElementById("score");
+ const streakEl = document.getElementById("streak");
+ const roundEl = document.getElementById("round");
+
+ function getRandomStyle() {
+ return styles[Math.floor(Math.random() * styles.length)];
+ }
+
+ function showOverlay(correct) {
+ overlay.classList.add("show");
+ overlayIcon.innerHTML = correct ? "✅" : "❌";
+ overlayMessage.textContent = correct ? "Correct!" : "Wrong!";
+ setTimeout(() => {
+ overlay.classList.remove("show");
+ }, 1000);
+ }
+
+ function updateUI() {
+ scoreEl.textContent = score;
+ streakEl.textContent = streak;
+ roundEl.textContent = `${round}/${maxRounds}`;
+ }
+
+ function loadNextRound() {
+ if (round > maxRounds) {
+ overlay.classList.add("show");
+ overlayIcon.innerHTML = "🎉";
+ overlayMessage.textContent = `Game Over! Your score: ${score}`;
+ return;
+ }
+
+ currentStyle = getRandomStyle();
+ currentPattern = currentStyle.pattern;
+ patternElement.style.backgroundImage = currentPattern;
+ patternElement.style.backgroundSize = currentStyle.backgroundSize;
+ }
+
+ function init() {
+ loadNextRound();
+ updateUI();
+ document.querySelectorAll(".button").forEach(button => {
+ button.addEventListener("click", function () {
+ const userStyle = this.getAttribute("data-style");
+ const correct = userStyle === currentStyle.name;
+ if (correct) {
+ score++;
+ streak++;
+ } else {
+ streak = 0;
+ }
+ showOverlay(correct);
+ loadNextRound();
+ updateUI();
+ });
+ });
+ }
+
+ // Load best score from localStorage
+ const bestScore = localStorage.getItem("bestScore") || 0;
+ const bestScoreEl = document.createElement("div");
+ bestScoreEl.textContent = `Best Score: ${bestScore}`;
+ bestScoreEl.style = "position: absolute; top: 16px; right: 32px; font-size: 14px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted);";
+ document.body.appendChild(bestScoreEl);
+
+ // Update best score
+ if (score > parseInt(bestScore)) {
+ localStorage.setItem("bestScore", score);
+ bestScoreEl.textContent = `Best Score: ${score}`;
+ }
+
+ init();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/e1961bf42e98/qwen3-14b.png b/data/artifacts/e1961bf42e98/qwen3-14b.png
new file mode 100644
index 0000000..d8f9697
Binary files /dev/null and b/data/artifacts/e1961bf42e98/qwen3-14b.png differ
diff --git a/data/challenges.json b/data/challenges.json
index b38967c..c48d06f 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -27005,7 +27005,14 @@
"finished_at": "2026-07-25T13:50:17.919Z",
"queued_at": "2026-07-25T13:48:12.091Z",
"bytes": 22742,
- "thumb": true
+ "thumb": true,
+ "aiScore": 9.3,
+ "aiReason": "The HTML effectively fulfills the challenge requirements with elegant design and clear navigation.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 9.5
+ },
+ "aiSpread": 0.5
},
{
"model": "kimi",
@@ -27157,7 +27164,14 @@
"finished_at": "2026-07-25T13:58:41.883Z",
"queued_at": "2026-07-25T13:48:12.176Z",
"bytes": 8745,
- "thumb": true
+ "thumb": true,
+ "aiScore": 7.8,
+ "aiReason": "The HTML file effectively fulfills the challenge requirements with elegant UI elements and a cohesive luxury design.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 2.5
},
{
"model": "claude-code",
@@ -27241,95 +27255,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-25T13:59:48.456Z"
+ "seconds": 47,
+ "cost": 0,
+ "started_at": "2026-07-25T13:59:55.025Z",
+ "finished_at": "2026-07-25T14:00:42.373Z",
+ "queued_at": "2026-07-25T13:59:48.456Z",
+ "bytes": 6182,
+ "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-25T13:59:48.466Z"
+ "seconds": 58,
+ "cost": 0,
+ "started_at": "2026-07-25T14:00:42.390Z",
+ "finished_at": "2026-07-25T14:01:40.504Z",
+ "queued_at": "2026-07-25T13:59:48.466Z",
+ "bytes": 8193,
+ "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-25T13:59:48.475Z"
+ "seconds": 18,
+ "cost": 0,
+ "started_at": "2026-07-25T14:01:40.517Z",
+ "finished_at": "2026-07-25T14:01:58.949Z",
+ "queued_at": "2026-07-25T13:59:48.475Z",
+ "bytes": 3649,
+ "thumb": true
},
{
"model": "qwen25-7b",
- "status": "running",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
+ "seconds": 32,
+ "cost": 0,
"started_at": "2026-07-25T13:59:48.508Z",
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.480Z"
+ "finished_at": "2026-07-25T14:00:20.289Z",
+ "queued_at": "2026-07-25T13:59:48.480Z",
+ "bytes": 4447,
+ "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-25T13:59:48.486Z"
+ "seconds": 73,
+ "cost": 0,
+ "started_at": "2026-07-25T14:01:58.958Z",
+ "finished_at": "2026-07-25T14:03:12.023Z",
+ "queued_at": "2026-07-25T13:59:48.486Z",
+ "bytes": 4580,
+ "thumb": true
},
{
"model": "claude-code",
- "status": "running",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
+ "seconds": 88,
+ "cost": 0,
"started_at": "2026-07-25T13:59:48.516Z",
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.490Z"
+ "finished_at": "2026-07-25T14:01:16.647Z",
+ "queued_at": "2026-07-25T13:59:48.490Z",
+ "bytes": 17134,
+ "thumb": true
},
{
"model": "kimi",
- "status": "running",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
+ "seconds": 117,
+ "cost": 0.0156,
"started_at": "2026-07-25T13:59:48.522Z",
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.495Z"
+ "finished_at": "2026-07-25T14:01:45.702Z",
+ "queued_at": "2026-07-25T13:59:48.495Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 16152,
+ "thumb": true
},
{
"model": "gpt",
- "status": "running",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
+ "seconds": 129,
+ "cost": 0.1422,
"started_at": "2026-07-25T13:59:48.528Z",
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.499Z"
+ "finished_at": "2026-07-25T14:01:57.456Z",
+ "queued_at": "2026-07-25T13:59:48.499Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 33236,
+ "thumb": true
},
{
"model": "grok",
- "status": "running",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
+ "seconds": 76,
+ "cost": 0.1179,
"started_at": "2026-07-25T13:59:48.534Z",
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.504Z"
+ "finished_at": "2026-07-25T14:01:04.390Z",
+ "queued_at": "2026-07-25T13:59:48.504Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 20099,
+ "thumb": true
}
- ]
+ ],
+ "judging": true
},
{
"id": "e1961bf42e98",
@@ -27342,21 +27390,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-25T13:59:48.566Z"
+ "seconds": 62,
+ "cost": 0,
+ "started_at": "2026-07-25T14:03:12.034Z",
+ "finished_at": "2026-07-25T14:04:13.924Z",
+ "queued_at": "2026-07-25T13:59:48.566Z",
+ "bytes": 8958,
+ "thumb": true
},
{
"model": "gemma3-12b",
- "status": "queued",
+ "status": "running",
"error": null,
"seconds": null,
"cost": null,
- "started_at": null,
+ "started_at": "2026-07-25T14:04:13.937Z",
"finished_at": null,
"queued_at": "2026-07-25T13:59:48.571Z"
},
@@ -27372,13 +27422,15 @@
},
{
"model": "qwen25-7b",
- "status": "queued",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
- "started_at": null,
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.580Z"
+ "seconds": 47,
+ "cost": 0,
+ "started_at": "2026-07-25T14:00:20.302Z",
+ "finished_at": "2026-07-25T14:01:07.649Z",
+ "queued_at": "2026-07-25T13:59:48.580Z",
+ "bytes": 6246,
+ "thumb": true
},
{
"model": "hf-qwen-coder-32b",
@@ -27392,43 +27444,67 @@
},
{
"model": "claude-code",
- "status": "queued",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
- "started_at": null,
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.589Z"
+ "seconds": 168,
+ "cost": 0,
+ "started_at": "2026-07-25T14:01:16.653Z",
+ "finished_at": "2026-07-25T14:04:04.595Z",
+ "queued_at": "2026-07-25T13:59:48.589Z",
+ "bytes": 24511,
+ "thumb": true
},
{
"model": "kimi",
- "status": "queued",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
- "started_at": null,
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.594Z"
+ "seconds": 132,
+ "cost": 0.018,
+ "started_at": "2026-07-25T14:01:45.708Z",
+ "finished_at": "2026-07-25T14:03:57.472Z",
+ "queued_at": "2026-07-25T13:59:48.594Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 20254,
+ "thumb": true
},
{
"model": "gpt",
- "status": "queued",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
- "started_at": null,
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.598Z"
+ "seconds": 68,
+ "cost": 0.1313,
+ "started_at": "2026-07-25T14:01:57.461Z",
+ "finished_at": "2026-07-25T14:03:05.375Z",
+ "queued_at": "2026-07-25T13:59:48.598Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes",
+ "hyperframes"
+ ],
+ "bytes": 29929,
+ "thumb": true
},
{
"model": "grok",
- "status": "queued",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
- "started_at": null,
- "finished_at": null,
- "queued_at": "2026-07-25T13:59:48.602Z"
+ "seconds": 142,
+ "cost": 0.2129,
+ "started_at": "2026-07-25T14:01:04.402Z",
+ "finished_at": "2026-07-25T14:03:26.236Z",
+ "queued_at": "2026-07-25T13:59:48.602Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 37224,
+ "thumb": true
}
]
}
diff --git a/data/costlog.jsonl b/data/costlog.jsonl
index 4943be6..742903a 100644
--- a/data/costlog.jsonl
+++ b/data/costlog.jsonl
@@ -375,3 +375,9 @@
{"ts":"2026-07-25T13:51:13.290Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":7452,"output_tokens":11174,"cost_usd":0.032406}
{"ts":"2026-07-25T13:52:36.664Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4321,"output_tokens":9505,"cost_usd":0.155538}
{"ts":"2026-07-25T13:52:47.183Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":6531,"output_tokens":5575,"cost_usd":0.017856}
+{"ts":"2026-07-25T14:01:04.386Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4107,"output_tokens":7041,"cost_usd":0.117936}
+{"ts":"2026-07-25T14:01:45.701Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":3605,"output_tokens":5379,"cost_usd":0.01561}
+{"ts":"2026-07-25T14:01:57.455Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3355,"output_tokens":9735,"cost_usd":0.142161}
+{"ts":"2026-07-25T14:03:05.370Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3520,"output_tokens":8938,"cost_usd":0.131292}
+{"ts":"2026-07-25T14:03:26.232Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4079,"output_tokens":13378,"cost_usd":0.212907}
+{"ts":"2026-07-25T14:03:57.471Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":3630,"output_tokens":6314,"cost_usd":0.017963}
← 15e383c night-loop: cycle 06:59 — judged=b0bfeedddee6 · fired 2 →; F
·
back to Model Arena
·
night-loop: cycle 07:12 — judged=a0e105469b1f · fired 2 →; F c4e588d →