← back to Model Arena
night-loop: cycle 05:48 — judged=ab0c520893e3 · fired 2 →; FIRED idx=6/16 id=420dc7bd02b3 title=Designer Wallcoverings — Palette Builder Tool; FIRED idx=7/16 id=6f651f004b4c title=Designer Wallcoverings — Which Era Are You Game
bbe6f3ede697b3c6d5a7bf158acd49040b08245b · 2026-07-25 05:48:13 -0700 · Steve Abrams
Files touched
A data/artifacts/9e458dd990ce/claude-code.htmlA data/artifacts/9e458dd990ce/claude-code.pngA data/artifacts/9e458dd990ce/gemma3-12b.htmlA data/artifacts/9e458dd990ce/gemma3-12b.pngA data/artifacts/9e458dd990ce/gpt.htmlA data/artifacts/9e458dd990ce/gpt.pngA data/artifacts/9e458dd990ce/grok.htmlA data/artifacts/9e458dd990ce/grok.pngA data/artifacts/9e458dd990ce/hermes3-8b.htmlA data/artifacts/9e458dd990ce/hermes3-8b.pngA data/artifacts/9e458dd990ce/hf-qwen-coder-32b.htmlA data/artifacts/9e458dd990ce/hf-qwen-coder-32b.pngA data/artifacts/9e458dd990ce/kimi.htmlA data/artifacts/9e458dd990ce/kimi.pngA data/artifacts/9e458dd990ce/qwen25-7b.htmlA data/artifacts/9e458dd990ce/qwen25-7b.pngA data/artifacts/9e458dd990ce/qwen3-14b.htmlA data/artifacts/9e458dd990ce/qwen3-14b.pngA data/artifacts/ab0c520893e3/claude-code.htmlA data/artifacts/ab0c520893e3/claude-code.pngA data/artifacts/ab0c520893e3/gemma3-12b.htmlA data/artifacts/ab0c520893e3/gemma3-12b.pngA data/artifacts/ab0c520893e3/gpt.htmlA data/artifacts/ab0c520893e3/gpt.pngA data/artifacts/ab0c520893e3/grok.htmlA data/artifacts/ab0c520893e3/grok.pngA data/artifacts/ab0c520893e3/hermes3-8b.htmlA data/artifacts/ab0c520893e3/hermes3-8b.pngA data/artifacts/ab0c520893e3/hf-qwen-coder-32b.htmlA data/artifacts/ab0c520893e3/hf-qwen-coder-32b.pngA data/artifacts/ab0c520893e3/kimi.htmlA data/artifacts/ab0c520893e3/kimi.pngA data/artifacts/ab0c520893e3/qwen25-7b.htmlA data/artifacts/ab0c520893e3/qwen25-7b.pngA data/artifacts/ab0c520893e3/qwen3-14b.htmlA data/artifacts/ab0c520893e3/qwen3-14b.pngM data/challenges.jsonM data/costlog.jsonlM idea-run/.dw-brand-style-color-pointer
Diff
commit bbe6f3ede697b3c6d5a7bf158acd49040b08245b
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Jul 25 05:48:13 2026 -0700
night-loop: cycle 05:48 — judged=ab0c520893e3 · fired 2 →; FIRED idx=6/16 id=420dc7bd02b3 title=Designer Wallcoverings — Palette Builder Tool; FIRED idx=7/16 id=6f651f004b4c title=Designer Wallcoverings — Which Era Are You Game
---
data/artifacts/9e458dd990ce/claude-code.html | 408 +++++++
data/artifacts/9e458dd990ce/claude-code.png | Bin 0 -> 139038 bytes
data/artifacts/9e458dd990ce/gemma3-12b.html | 271 +++++
data/artifacts/9e458dd990ce/gemma3-12b.png | Bin 0 -> 82829 bytes
data/artifacts/9e458dd990ce/gpt.html | 952 ++++++++++++++++
data/artifacts/9e458dd990ce/gpt.png | Bin 0 -> 244378 bytes
data/artifacts/9e458dd990ce/grok.html | 1167 ++++++++++++++++++++
data/artifacts/9e458dd990ce/grok.png | Bin 0 -> 50488 bytes
data/artifacts/9e458dd990ce/hermes3-8b.html | 153 +++
data/artifacts/9e458dd990ce/hermes3-8b.png | Bin 0 -> 20264 bytes
data/artifacts/9e458dd990ce/hf-qwen-coder-32b.html | 212 ++++
data/artifacts/9e458dd990ce/hf-qwen-coder-32b.png | Bin 0 -> 106679 bytes
data/artifacts/9e458dd990ce/kimi.html | 678 ++++++++++++
data/artifacts/9e458dd990ce/kimi.png | Bin 0 -> 41253 bytes
data/artifacts/9e458dd990ce/qwen25-7b.html | 118 ++
data/artifacts/9e458dd990ce/qwen25-7b.png | Bin 0 -> 20636 bytes
data/artifacts/9e458dd990ce/qwen3-14b.html | 347 ++++++
data/artifacts/9e458dd990ce/qwen3-14b.png | Bin 0 -> 15658 bytes
data/artifacts/ab0c520893e3/claude-code.html | 506 +++++++++
data/artifacts/ab0c520893e3/claude-code.png | Bin 0 -> 73962 bytes
data/artifacts/ab0c520893e3/gemma3-12b.html | 342 ++++++
data/artifacts/ab0c520893e3/gemma3-12b.png | Bin 0 -> 20572 bytes
data/artifacts/ab0c520893e3/gpt.html | 1127 +++++++++++++++++++
data/artifacts/ab0c520893e3/gpt.png | Bin 0 -> 153134 bytes
data/artifacts/ab0c520893e3/grok.html | 765 +++++++++++++
data/artifacts/ab0c520893e3/grok.png | Bin 0 -> 53608 bytes
data/artifacts/ab0c520893e3/hermes3-8b.html | 181 +++
data/artifacts/ab0c520893e3/hermes3-8b.png | Bin 0 -> 23524 bytes
data/artifacts/ab0c520893e3/hf-qwen-coder-32b.html | 251 +++++
data/artifacts/ab0c520893e3/hf-qwen-coder-32b.png | Bin 0 -> 24089 bytes
data/artifacts/ab0c520893e3/kimi.html | 610 ++++++++++
data/artifacts/ab0c520893e3/kimi.png | Bin 0 -> 44757 bytes
data/artifacts/ab0c520893e3/qwen25-7b.html | 242 ++++
data/artifacts/ab0c520893e3/qwen25-7b.png | Bin 0 -> 26238 bytes
data/artifacts/ab0c520893e3/qwen3-14b.html | 490 ++++++++
data/artifacts/ab0c520893e3/qwen3-14b.png | Bin 0 -> 25057 bytes
data/challenges.json | 421 ++++++-
data/costlog.jsonl | 6 +
idea-run/.dw-brand-style-color-pointer | 2 +-
39 files changed, 9210 insertions(+), 39 deletions(-)
diff --git a/data/artifacts/9e458dd990ce/claude-code.html b/data/artifacts/9e458dd990ce/claude-code.html
new file mode 100644
index 0000000..ecbc25a
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/claude-code.html
@@ -0,0 +1,408 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>Shop by Color — Designer Wallcoverings</title>
+<style>
+ :root{
+ --bg:#f4f1ea; /* warm ivory ground */
+ --surface:#fffdf8;
+ --text:#1c1a17; /* darkest ink */
+ --muted:#8a8172;
+ --line:#e0dace; /* hairline */
+ --accent:#9c7a44; /* antique brass — single metallic accent */
+ --accent-deep:#6f562e;
+ --shadow:0 8px 28px rgba(28,26,23,.10);
+ --shadow-hi:0 18px 50px rgba(28,26,23,.16);
+ --ease:cubic-bezier(.22,1,.36,1);
+ --serif:'Didot','Bodoni MT','Playfair Display',Georgia,'Times New Roman',serif;
+ --sans:-apple-system,'Segoe UI','Helvetica Neue',Arial,sans-serif;
+ }
+ *{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
+ html,body{margin:0;padding:0;}
+ body{
+ background:var(--bg);
+ color:var(--text);
+ font-family:var(--sans);
+ -webkit-font-smoothing:antialiased;
+ overflow-x:hidden;
+ min-height:100vh;
+ }
+ /* ambient slow drift */
+ body::before{
+ content:"";position:fixed;inset:-20%;z-index:0;pointer-events:none;
+ background:
+ radial-gradient(circle at 20% 15%, rgba(156,122,68,.10), transparent 45%),
+ radial-gradient(circle at 85% 85%, rgba(111,86,46,.08), transparent 50%);
+ animation:drift 20s ease-in-out infinite alternate;
+ }
+ @keyframes drift{from{transform:translate(-2%,-1%) scale(1.02);}to{transform:translate(2%,2%) scale(1.06);}}
+
+ /* ---------- header / wordmark lockup ---------- */
+ header.topbar{
+ position:sticky;top:0;z-index:20;
+ display:flex;align-items:center;justify-content:space-between;
+ gap:16px;flex-wrap:wrap;
+ padding:18px clamp(16px,5vw,44px);
+ background:rgba(244,241,234,.82);
+ backdrop-filter:blur(12px);
+ border-bottom:1px solid var(--line);
+ }
+ .wordmark{
+ font-family:var(--serif);
+ color:var(--text); /* darkest ink — never surface/white */
+ font-weight:600;
+ font-size:clamp(21px,5.4vw,30px);
+ line-height:1;
+ letter-spacing:.18em;
+ text-transform:uppercase;
+ margin:0;
+ max-width:280px;
+ }
+ .wordmark span{display:block;font-size:.62em;letter-spacing:.42em;color:var(--accent-deep);margin-top:6px;font-weight:600;}
+ .topbar .badge{
+ font-family:var(--sans);font-size:11px;letter-spacing:.22em;text-transform:uppercase;
+ color:var(--muted);border:1px solid var(--line);border-radius:40px;
+ padding:8px 16px;white-space:nowrap;background:var(--surface);
+ }
+
+ /* ---------- main ---------- */
+ main{position:relative;z-index:1;padding:clamp(28px,6vw,64px) clamp(16px,5vw,44px) 96px;max-width:940px;margin:0 auto;}
+ .intro{text-align:center;margin-bottom:clamp(28px,5vw,48px);animation:fadeUp .8s var(--ease) both;}
+ .kicker{font-size:12px;letter-spacing:.28em;text-transform:uppercase;color:var(--accent-deep);margin:0 0 14px;}
+ .intro h1{
+ font-family:var(--serif);font-weight:600;
+ font-size:clamp(34px,8vw,58px);line-height:1.02;margin:0 0 14px;letter-spacing:.01em;
+ }
+ .intro p{max-width:440px;margin:0 auto;color:var(--muted);font-size:clamp(15px,3.5vw,17px);line-height:1.6;}
+
+ /* ---------- wheel ---------- */
+ .stage{display:flex;flex-direction:column;align-items:center;gap:8px;animation:fadeUp .8s .1s var(--ease) both;}
+ .wheel-wrap{
+ position:relative;width:min(76vw,320px);height:min(76vw,320px);
+ touch-action:none;user-select:none;margin:6px 0 4px;
+ }
+ .ring{
+ position:absolute;inset:0;border-radius:50%;
+ background:conic-gradient(from 0deg,
+ hsl(8 62% 52%) 0deg,
+ hsl(35 68% 54%) 45deg,
+ hsl(58 55% 50%) 90deg,
+ hsl(140 40% 44%) 135deg,
+ hsl(182 46% 42%) 180deg,
+ hsl(215 52% 50%) 225deg,
+ hsl(262 40% 54%) 270deg,
+ hsl(322 46% 56%) 315deg,
+ hsl(8 62% 52%) 360deg);
+ box-shadow:var(--shadow),inset 0 0 0 1px rgba(255,255,255,.35);
+ cursor:grab;
+ }
+ .wheel-wrap:active .ring{cursor:grabbing;}
+ .ring::after{ /* inner well */
+ content:"";position:absolute;inset:22%;border-radius:50%;
+ background:var(--surface);
+ box-shadow:0 6px 20px rgba(28,26,23,.14) inset, 0 1px 0 rgba(255,255,255,.6);
+ border:1px solid var(--line);
+ }
+ .hub{
+ position:absolute;inset:22%;border-radius:50%;
+ display:flex;flex-direction:column;align-items:center;justify-content:center;
+ text-align:center;pointer-events:none;padding:8%;
+ }
+ .hub .dot{
+ width:52px;height:52px;border-radius:50%;
+ background:var(--cur,#c9b48c);
+ box-shadow:0 4px 14px rgba(28,26,23,.22),0 0 0 6px rgba(255,255,255,.55);
+ transition:background .3s var(--ease);margin-bottom:12px;
+ }
+ .hub .fam{font-family:var(--serif);font-size:clamp(17px,4.4vw,22px);font-weight:600;line-height:1.05;}
+ .hub .lab{font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted);margin-top:6px;}
+ .handle{
+ position:absolute;width:26px;height:26px;border-radius:50%;
+ left:50%;top:50%;transform:translate(-50%,-50%);
+ background:var(--surface);border:2px solid var(--accent);
+ box-shadow:0 3px 10px rgba(28,26,23,.28);
+ transition:box-shadow .2s var(--ease);
+ }
+ .handle::after{content:"";position:absolute;inset:5px;border-radius:50%;background:var(--cur,#c9b48c);transition:background .3s var(--ease);}
+ .hint{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin-top:2px;}
+
+ /* ---------- filmstrip ---------- */
+ .strip-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:clamp(30px,6vw,54px) 4px 16px;}
+ .strip-head h2{font-family:var(--serif);font-weight:600;font-size:clamp(20px,5vw,28px);margin:0;}
+ .strip-head .count{font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--muted);}
+ .filmstrip{
+ display:grid;grid-auto-flow:column;grid-auto-columns:minmax(150px,1fr);
+ gap:16px;overflow-x:auto;padding:6px 4px 18px;scroll-snap-type:x mandatory;
+ -webkit-overflow-scrolling:touch;scrollbar-width:none;
+ }
+ .filmstrip::-webkit-scrollbar{display:none;}
+ @media(min-width:720px){.filmstrip{grid-auto-flow:row;grid-template-columns:repeat(4,1fr);overflow:visible;}}
+ .card{
+ scroll-snap-align:start;background:var(--surface);border:1px solid var(--line);
+ border-radius:14px;overflow:hidden;box-shadow:var(--shadow);
+ transition:transform .25s var(--ease),box-shadow .25s var(--ease);
+ }
+ .card:hover{transform:translateY(-4px);box-shadow:var(--shadow-hi);}
+ .swatch{height:132px;position:relative;background-color:var(--bgc,#eee);}
+ .swatch::after{content:"";position:absolute;inset:0;box-shadow:inset 0 -30px 30px -30px rgba(28,26,23,.16);}
+ .m-trellis{background-image:
+ repeating-linear-gradient(45deg,var(--c) 0 2px,transparent 2px 20px),
+ repeating-linear-gradient(-45deg,var(--c) 0 2px,transparent 2px 20px);}
+ .m-damask{background-image:
+ radial-gradient(circle at 50% 22%,var(--c) 0 5px,transparent 6px),
+ radial-gradient(ellipse 10px 16px at 50% 55%,var(--c) 0 60%,transparent 62%),
+ radial-gradient(circle at 22% 78%,var(--c) 0 3px,transparent 4px),
+ radial-gradient(circle at 78% 78%,var(--c) 0 3px,transparent 4px);
+ background-size:46px 62px;background-position:center;}
+ .m-grass{background-image:
+ repeating-linear-gradient(90deg,var(--c) 0 1px,transparent 1px 5px),
+ repeating-linear-gradient(0deg,rgba(28,26,23,.05) 0 1px,transparent 1px 7px);}
+ .m-chevron{background-image:
+ repeating-linear-gradient(-45deg,var(--c) 0 7px,transparent 7px 14px),
+ repeating-linear-gradient(45deg,var(--c) 0 7px,transparent 7px 14px);
+ background-size:20px 20px;}
+ .card .meta{padding:14px 16px 16px;}
+ .card .cname{font-family:var(--serif);font-size:18px;font-weight:600;margin:0;line-height:1.1;}
+ .card .mname{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin:7px 0 0;}
+ .card .hex{font-size:10px;letter-spacing:.14em;color:var(--accent-deep);margin-top:3px;font-variant-numeric:tabular-nums;}
+ .card.enter{animation:fadeUp .55s var(--ease) both;}
+
+ /* ---------- share bar ---------- */
+ .sharebar{
+ display:flex;flex-wrap:wrap;gap:10px;justify-content:center;
+ margin-top:clamp(30px,6vw,50px);padding-top:26px;border-top:1px solid var(--line);
+ }
+ .sharebar .lbl{width:100%;text-align:center;font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--muted);margin-bottom:4px;}
+ .sbtn{
+ display:inline-flex;align-items:center;gap:8px;
+ font-family:var(--sans);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
+ color:var(--text);background:var(--surface);border:1px solid var(--line);
+ border-radius:40px;padding:12px 20px;cursor:pointer;
+ transition:border-color .2s var(--ease),color .2s var(--ease),transform .15s var(--ease);
+ }
+ .sbtn:hover{border-color:var(--accent);color:var(--accent-deep);}
+ .sbtn:active{transform:scale(.96);}
+ .sbtn svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;}
+
+ /* ---------- toast overlay ---------- */
+ .toast{
+ position:fixed;left:50%;bottom:34px;transform:translate(-50%,20px);
+ z-index:50;background:var(--text);color:var(--surface);
+ font-size:12px;letter-spacing:.14em;text-transform:uppercase;
+ padding:14px 24px;border-radius:40px;box-shadow:var(--shadow-hi);
+ opacity:0;pointer-events:none;transition:opacity .3s var(--ease),transform .3s var(--ease);
+ display:flex;align-items:center;gap:10px;max-width:88vw;
+ }
+ .toast .swz{width:16px;height:16px;border-radius:50%;background:var(--accent);flex:none;}
+ .toast.show{opacity:1;transform:translate(-50%,0);}
+
+ @keyframes fadeUp{from{opacity:0;transform:translateY(26px);}to{opacity:1;transform:none;}}
+
+ footer{text-align:center;padding:0 20px 40px;color:var(--muted);font-size:11px;letter-spacing:.2em;text-transform:uppercase;position:relative;z-index:1;}
+ footer .fw{font-family:var(--serif);letter-spacing:.16em;color:var(--text);text-transform:uppercase;font-size:13px;}
+</style>
+</head>
+<body>
+
+ <header class="topbar">
+ <h1 class="wordmark">Designer Wallcoverings<span>Est. Atelier</span></h1>
+ <div class="badge">Shop by Color</div>
+ </header>
+
+ <main>
+ <section class="intro">
+ <p class="kicker">Interactive Palette</p>
+ <h1>Turn the Wheel,<br>Find Your Hue</h1>
+ <p>Drag the dial or tap a color to reveal four curated wallcovering patterns in that shade — each with its designer color name.</p>
+ </section>
+
+ <section class="stage">
+ <div class="wheel-wrap" id="wheelWrap">
+ <div class="ring" id="ring"></div>
+ <div class="hub">
+ <div class="dot" id="hubDot"></div>
+ <div class="fam" id="hubFam">Rosewood</div>
+ <div class="lab">Color Family</div>
+ </div>
+ <div class="handle" id="handle"></div>
+ </div>
+ <p class="hint" id="hint">Drag · or tap the wheel</p>
+ </section>
+
+ <div class="strip-head">
+ <h2 id="stripTitle">The Reds Collection</h2>
+ <span class="count">Four Patterns</span>
+ </div>
+ <div class="filmstrip" id="filmstrip"></div>
+
+ <section class="sharebar">
+ <span class="lbl">Share this palette</span>
+ <button class="sbtn" data-act="share">
+ <svg viewBox="0 0 24 24"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="M8.6 13.5l6.8 4M15.4 6.5l-6.8 4"/></svg>Share
+ </button>
+ <button class="sbtn" data-act="save">
+ <svg viewBox="0 0 24 24"><path d="M19 21l-7-4-7 4V5a2 2 0 012-2h10a2 2 0 012 2z"/></svg>Save Palette
+ </button>
+ <button class="sbtn" data-act="copy">
+ <svg viewBox="0 0 24 24"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 012-2h10"/></svg>Copy Link
+ </button>
+ </section>
+ </main>
+
+ <div class="toast" id="toast"><span class="swz" id="toastSwz"></span><span id="toastMsg"></span></div>
+
+ <footer>
+ Curated by <span class="fw">Designer Wallcoverings</span> · #ShopByColor
+ </footer>
+
+<script>
+(function(){
+ const families = [
+ {a:0, h:8, name:"Rosewood", title:"The Reds Collection",
+ names:["Rose Blush","Terracotta","Venetian Red","Oxblood"]},
+ {a:45, h:35, name:"Amber", title:"The Amber Collection",
+ names:["Fawn","Raw Sienna","Golden Amber","Burnt Caramel"]},
+ {a:90, h:58, name:"Antique Gold", title:"The Gold Collection",
+ names:["Wheat","Antique Gold","Ochre","Olive Bronze"]},
+ {a:135, h:140, name:"Fern", title:"The Greens Collection",
+ names:["Celadon","Sage","Fern","Forest"]},
+ {a:180, h:182, name:"Teal", title:"The Teal Collection",
+ names:["Seaglass","Verdigris","Peacock","Deep Teal"]},
+ {a:225, h:215, name:"Sapphire", title:"The Blues Collection",
+ names:["Powder Blue","Cornflower","Sapphire","Midnight Navy"]},
+ {a:270, h:262, name:"Amethyst", title:"The Violet Collection",
+ names:["Lilac","Wisteria","Amethyst","Aubergine"]},
+ {a:315, h:322, name:"Rose", title:"The Rose Collection",
+ names:["Blush","Rose Quartz","Fuchsia","Plum"]}
+ ];
+ const tints = [ {s:34,l:80}, {s:48,l:62}, {s:56,l:46}, {s:50,l:32} ];
+ const motifs = ["m-trellis","m-damask","m-grass","m-chevron"];
+ const motifNames = ["Lattice Trellis","Heritage Damask","Grasscloth Weave","Herringbone"];
+
+ const wrap = document.getElementById('wheelWrap');
+ const ring = document.getElementById('ring');
+ const handle = document.getElementById('handle');
+ const hubDot = document.getElementById('hubDot');
+ const hubFam = document.getElementById('hubFam');
+ const strip = document.getElementById('filmstrip');
+ const stripTitle = document.getElementById('stripTitle');
+ const hint = document.getElementById('hint');
+ const toast = document.getElementById('toast');
+ const toastMsg = document.getElementById('toastMsg');
+ const toastSwz = document.getElementById('toastSwz');
+
+ let curFam = families[0];
+ let toastTimer = null;
+
+ function hsl(h,s,l){return `hsl(${h} ${s}% ${l}%)`;}
+
+ function nearestFamily(deg){
+ let best=families[0], bd=999;
+ for(const f of families){
+ let d=Math.abs(((deg-f.a+540)%360)-180);
+ if(d<bd){bd=d;best=f;}
+ }
+ return best;
+ }
+
+ function placeHandle(deg){
+ const R = wrap.clientWidth*0.39;
+ const rad = (deg-90)*Math.PI/180;
+ const x = wrap.clientWidth/2 + R*Math.cos(rad);
+ const y = wrap.clientHeight/2 + R*Math.sin(rad);
+ handle.style.left = x+'px';
+ handle.style.top = y+'px';
+ }
+
+ function render(fam){
+ curFam = fam;
+ const mid = hsl(fam.h, tints[2].s, tints[2].l);
+ document.documentElement.style.setProperty('--cur', mid);
+ hubFam.textContent = fam.name;
+ stripTitle.textContent = fam.title;
+
+ strip.innerHTML = '';
+ fam.names.forEach((cn,i)=>{
+ const t = tints[i];
+ const c = hsl(fam.h, t.s, t.l);
+ const bg = hsl(fam.h, Math.max(18,t.s-24), Math.min(96, t.l+18));
+ const card = document.createElement('div');
+ card.className='card enter';
+ card.style.animationDelay = (i*90)+'ms';
+ card.innerHTML =
+ `<div class="swatch ${motifs[i]}" style="--c:${c};--bgc:${bg}"></div>
+ <div class="meta">
+ <p class="cname">${cn}</p>
+ <p class="mname">${motifNames[i]}</p>
+ <p class="hex">Hue ${fam.h}° · Family ${fam.name}</p>
+ </div>`;
+ strip.appendChild(card);
+ });
+ }
+
+ function angleFromEvent(e){
+ const r = wrap.getBoundingClientRect();
+ const cx = r.left + r.width/2, cy = r.top + r.height/2;
+ const p = e.touches ? e.touches[0] : e;
+ const dx = p.clientX - cx, dy = p.clientY - cy;
+ return (Math.atan2(dy,dx)*180/Math.PI + 90 + 360)%360;
+ }
+
+ function update(deg){
+ placeHandle(deg);
+ const fam = nearestFamily(deg);
+ if(fam!==curFam) render(fam);
+ else {
+ // keep tint live even within family (subtle)
+ document.documentElement.style.setProperty('--cur', hsl(fam.h,tints[2].s,tints[2].l));
+ }
+ }
+
+ let dragging=false;
+ function down(e){dragging=true;wrap.setPointerCapture&&e.pointerId!=null&&wrap.setPointerCapture(e.pointerId);update(angleFromEvent(e));hint.textContent='Release to shop';e.preventDefault();}
+ function move(e){if(!dragging)return;update(angleFromEvent(e));e.preventDefault();}
+ function up(){if(!dragging)return;dragging=false;hint.innerHTML='Drag · or tap the wheel';}
+
+ wrap.addEventListener('pointerdown',down);
+ window.addEventListener('pointermove',move,{passive:false});
+ window.addEventListener('pointerup',up);
+ window.addEventListener('pointercancel',up);
+ // touch fallback
+ wrap.addEventListener('touchstart',down,{passive:false});
+ window.addEventListener('touchmove',move,{passive:false});
+ window.addEventListener('touchend',up);
+
+ window.addEventListener('resize',()=>{ placeHandle(curFam.a); });
+
+ // share bar
+ function showToast(msg){
+ toastMsg.textContent = msg;
+ toastSwz.style.background = getComputedStyle(document.documentElement).getPropertyValue('--cur') || '#9c7a44';
+ toast.classList.add('show');
+ clearTimeout(toastTimer);
+ toastTimer = setTimeout(()=>toast.classList.remove('show'),2400);
+ }
+ document.querySelectorAll('.sbtn').forEach(b=>{
+ b.addEventListener('click',async()=>{
+ const act = b.dataset.act;
+ if(act==='share'){
+ const data={title:'Designer Wallcoverings — Shop by Color',text:`I'm loving the ${curFam.name} palette on Designer Wallcoverings.`};
+ if(navigator.share){try{await navigator.share(data);showToast(`Shared the ${curFam.name} palette`);}catch(_){showToast('Share canceled');}}
+ else showToast(`Palette ready to share`);
+ } else if(act==='save'){
+ showToast(`${curFam.name} palette saved`);
+ } else {
+ showToast('Link copied to clipboard');
+ }
+ });
+ });
+
+ // init
+ render(families[0]);
+ placeHandle(families[0].a);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/claude-code.png b/data/artifacts/9e458dd990ce/claude-code.png
new file mode 100644
index 0000000..bee829d
Binary files /dev/null and b/data/artifacts/9e458dd990ce/claude-code.png differ
diff --git a/data/artifacts/9e458dd990ce/gemma3-12b.html b/data/artifacts/9e458dd990ce/gemma3-12b.html
new file mode 100644
index 0000000..3d7775e
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/gemma3-12b.html
@@ -0,0 +1,271 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Designer Wallcoverings - Color Exploration</title>
+ <style>
+ :root {
+ --bg: #faf8f4; /* ivory-gallery */
+ --surface: #ffffff;
+ --text: #3a2c22; /* terracotta-sun */
+ --muted: #9b948a;
+ --accent: #c65f38; /* terracotta-sun */
+ --line: rgba(0, 0, 0, 0.1);
+ --shadow: rgba(0, 0, 0, 0.12);
+ --ease: cubic-bezier(.22,1,.36,1);
+ }
+
+ body {
+ font-family: system-ui, '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: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: left;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); /* Subtle shadow */
+ }
+
+ header h1 {
+ font-family: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ font-size: 58px; /* Adjusted for visibility */
+ line-height: 1;
+ letter-spacing: .18em;
+ margin: 0;
+ text-transform: uppercase;
+ flex-shrink: 0; /* Prevent shrinking on small screens */
+ }
+
+ .color-wheel {
+ width: 200px;
+ height: 200px;
+ border-radius: 50%;
+ background: conic-gradient(from 0deg, var(--accent) 45deg, #fff 45deg, var(--accent) 90deg, #fff 90deg, var(--accent) 135deg, #fff 135deg, var(--accent) 180deg, #fff 180deg, var(--accent) 225deg, #fff 225deg, var(--accent) 270deg, #fff 270deg, var(--accent) 315deg, #fff 315deg, var(--accent));
+ margin: 48px auto;
+ cursor: grab;
+ position: relative; /* For the color names */
+ }
+
+ .color-wheel:active {
+ cursor: grabbing;
+ }
+
+ .color-names {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 14px; /* Smaller font size */
+ text-align: center;
+ }
+
+ .filmstrip {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 24px;
+ margin-top: 32px;
+ }
+
+ .pattern-tile {
+ width: 180px;
+ height: 180px;
+ border-radius: 14px;
+ overflow: hidden; /* Ensure patterns stay within the tile */
+ box-shadow: 0 8px 24px var(--shadow);
+ position: relative;
+ }
+
+ .pattern-tile::before {
+ content: "";
+ display: block;
+ padding-bottom: 100%; /* Maintain square aspect ratio */
+ }
+
+ /* Pattern styles - use CSS gradients for visual distinction */
+ .pattern-tile.geometric {
+ background: linear-gradient(45deg, var(--accent) 20%, #fff 80%) left top / cover;
+ background-blend-mode: difference; /* Add a subtle blend effect */
+ }
+
+ .pattern-tile.floral {
+ background: conic-gradient(from 0deg, var(--accent) 30deg, rgba(255, 255, 255, 0.8) 30deg, var(--accent) 60deg, rgba(255, 255, 255, 0.8) 60deg);
+ }
+
+ .pattern-tile.abstract {
+ background: radial-gradient(circle, var(--accent), #fff);
+ filter: blur(4px); /* Add a blurred effect */
+ }
+
+ .pattern-tile.organic {
+ background: repeating-linear-gradient(45deg, var(--accent) 0%, var(--accent) 10px, rgba(255, 255, 255, 0.8) 10px, rgba(255, 255, 255, 0.8) 20px);
+ }
+
+ .share-bar {
+ background-color: var(--surface);
+ padding: 24px;
+ text-align: center;
+ border-top: 1px solid var(--line);
+ }
+
+ .share-button {
+ font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 12px;
+ letter-spacing: .15em;
+ text-transform: uppercase;
+ display: inline-block;
+ padding: 8px 16px;
+ background-color: var(--accent);
+ color: var(--surface);
+ border-radius: 4px;
+ text-decoration: none;
+ margin: 0 12px;
+ }
+
+ .overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(var(--text), .8); /* Darker overlay */
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ z-index: 1000;
+ opacity: 0;
+ transition: opacity .3s var(--ease);
+ }
+
+ .overlay p {
+ color: var(--surface);
+ font-size: 24px;
+ }
+
+
+ /* Draggable functionality */
+ .color-wheel {
+ user-select: none; /* Prevent text selection during drag */
+ }
+
+ </style>
+</head>
+<body>
+
+ <header>
+ <h1>DESIGNER WALLCOVERINGS</h1>
+ </header>
+
+ <div class="color-wheel">
+ <div class="color-names">Select a Hue</div>
+ </div>
+
+ <div class="filmstrip" id="patternContainer">
+ <!-- Patterns will be dynamically added here -->
+ </div>
+
+ <div class="share-bar">
+ <a href="#" class="share-button">Share</a>
+ <a href="#" class="share-button">Learn More</a>
+ </div>
+
+ <div class="overlay" id="overlay">
+ <p>Color Selected</p>
+ </div>
+
+ <script>
+ const colorWheel = document.querySelector('.color-wheel');
+ const patternContainer = document.getElementById('patternContainer');
+ const overlay = document.getElementById('overlay');
+
+
+ let angle = 0; // Current rotation angle
+
+ // Function to generate CSS patterns
+ function createPatternTile(color, className) {
+ const tile = document.createElement('div');
+ tile.classList.add('pattern-tile', className);
+ tile.style.backgroundColor = color;
+ return tile;
+ }
+
+
+ // Function to update the filmstrip with patterns based on selected hue
+ function updatePatterns(hue) {
+ patternContainer.innerHTML = ''; // Clear existing patterns
+
+ const patternColors = [
+ `hsl(${hue}, 70%, 85%)`,
+ `hsl(${hue}, 60%, 70%)`,
+ `hsl(${hue}, 50%, 60%)`,
+ `hsl(${hue}, 40%, 50%)`
+ ];
+
+ const patternClasses = ['geometric', 'floral', 'abstract', 'organic'];
+
+ for (let i = 0; i < patternColors.length; i++) {
+ const tile = createPatternTile(patternColors[i], patternClasses[i]);
+ patternContainer.appendChild(tile);
+ }
+ }
+
+
+ //Draggable and Clickable Color Wheel
+ colorWheel.addEventListener('mousedown', (e) => {
+ let isDragging = false;
+ let startAngle = angle;
+
+ colorWheel.addEventListener('mousemove', (e) => {
+ if (!isDragging) return;
+ const deltaX = e.clientX - colorWheel.getBoundingClientRect().left;
+ const relativeY = deltaX / colorWheel.offsetWidth;
+ angle = Math.round(relativeY * 360);
+
+ updatePatterns(angle); // Update patterns as the wheel is dragged
+
+ });
+
+ colorWheel.addEventListener('mouseup', () => {
+ isDragging = false;
+ });
+
+ colorWheel.addEventListener('mouseleave', () => {
+ isDragging = false;
+ });
+
+
+ isDragging = true;
+ });
+
+
+
+ colorWheel.addEventListener('click', (e) => {
+ const x = e.offsetX;
+ const y = e.offsetY;
+ const radius = colorWheel.offsetWidth / 2;
+ const distFromCenter = Math.sqrt(x * x + y * y);
+
+ if (distFromCenter <= radius) {
+ let angle = Math.atan2(y, x) * 180 / Math.PI ;
+ angle = (angle + 360) % 360; // Normalize to 0-360 degrees
+ updatePatterns(angle);
+ }
+ });
+
+
+
+ // Initial pattern generation
+ updatePatterns(0);
+
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/gemma3-12b.png b/data/artifacts/9e458dd990ce/gemma3-12b.png
new file mode 100644
index 0000000..9d1f8ee
Binary files /dev/null and b/data/artifacts/9e458dd990ce/gemma3-12b.png differ
diff --git a/data/artifacts/9e458dd990ce/gpt.html b/data/artifacts/9e458dd990ce/gpt.html
new file mode 100644
index 0000000..1a6389f
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/gpt.html
@@ -0,0 +1,952 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<title>Designer Wallcoverings – Shop by Color</title>
+<style>
+:root {
+ /* Design tokens */
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-soft: #1f1f26;
+ --text: #f5f2ea;
+ --text-muted: #8a8578;
+ --accent: #c9a961; /* metallic gold */
+ --accent-soft: #7d6a45;
+ --line: rgba(245, 242, 234, 0.14);
+ --line-strong: rgba(245, 242, 234, 0.28);
+ --shadow-soft: 0 18px 40px rgba(0, 0, 0, 0.65);
+ --shadow-subtle: 0 1px 0 rgba(255, 255, 255, 0.06);
+ --radius-xl: 26px;
+ --radius-lg: 20px;
+ --radius-md: 14px;
+ --radius-pill: 999px;
+ --space-xs: 6px;
+ --space-sm: 10px;
+ --space-md: 18px;
+ --space-lg: 28px;
+ --space-xl: 40px;
+ --space-2xl: 60px;
+
+ --font-display: 'Playfair Display', 'Times New Roman', Georgia, serif;
+ --font-serif-alt: 'EB Garamond', 'Cormorant Garamond', 'Times New Roman', Georgia, serif;
+ --font-sans: 'Avenir Next', 'Century Gothic', -apple-system, 'Segoe UI', 'Helvetica Neue', sans-serif;
+
+ --fs-caption: 12px;
+ --fs-label: 11px;
+ --fs-body: 16px;
+ --fs-lead: 21px;
+ --fs-h3: 28px;
+ --fs-h2: 38px;
+ --fs-h1: 50px;
+
+ --ease-swift: cubic-bezier(.22,.9,.24,1);
+ --ease-hero: cubic-bezier(.22,1,.36,1);
+ --ease-overshoot: cubic-bezier(.34,1.56,.64,1);
+
+ --wheel-size: min(420px, 68vw);
+}
+
+/* Global layout */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ background: radial-gradient(circle at top left, #17171c 0, #050507 52%, #000 100%);
+ color: var(--text);
+ font-family: var(--font-sans);
+ line-height: 1.6;
+ -webkit-font-smoothing: antialiased;
+}
+
+body {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+/* Header – wordmark */
+header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 10;
+ backdrop-filter: blur(18px);
+ background: linear-gradient(to bottom, rgba(5,5,7,0.9), rgba(5,5,7,0.7));
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
+ box-shadow: var(--shadow-subtle);
+}
+
+.header-inner {
+ max-width: 1120px;
+ margin: 0 auto;
+ padding: 14px 24px 12px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 18px;
+}
+
+.brand-lockup {
+ display: flex;
+ flex-direction: column;
+}
+
+.wordmark {
+ font-family: var(--font-serif-alt);
+ font-size: 44px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text); /* darkest ink */
+ line-height: 1.08;
+ white-space: normal;
+}
+
+.wordmark-sub {
+ margin-top: 4px;
+ font-family: var(--font-sans);
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+}
+
+.header-meta {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: 6px;
+ font-family: var(--font-sans);
+}
+
+.meta-tag {
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+}
+
+.meta-pill {
+ border-radius: var(--radius-pill);
+ border: 1px solid rgba(201, 169, 97, 0.4);
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
+ padding: 4px 12px 5px;
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--accent);
+}
+
+.meta-dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 999px;
+ background: radial-gradient(circle at 30% 20%, #f5f2ea, #c9a961 48%, #5a4622 100%);
+}
+
+/* Main content */
+main {
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ padding: 108px 16px 32px;
+}
+
+.shell {
+ width: 100%;
+ max-width: 1120px;
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.1fr);
+ gap: 34px;
+ align-items: center;
+}
+
+@media (max-width: 900px) {
+ .shell {
+ grid-template-columns: minmax(0, 1fr);
+ gap: 28px;
+ }
+}
+
+/* Left column – copy and share */
+.copy-block {
+ padding: 28px 26px 26px;
+ border-radius: var(--radius-xl);
+ background: radial-gradient(circle at top left, rgba(201,169,97,0.12), rgba(23,23,28,0.95));
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow-soft);
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+}
+
+.eyebrow {
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--accent);
+}
+
+h1 {
+ margin: 0;
+ font-family: var(--font-display);
+ font-weight: 500;
+ font-size: var(--fs-h1);
+ letter-spacing: 0.02em;
+ line-height: 1.08;
+}
+
+h1 span {
+ background: linear-gradient(120deg, var(--accent), #f5f2ea);
+ -webkit-background-clip: text;
+ color: transparent;
+}
+
+.lead {
+ font-size: var(--fs-lead);
+ color: rgba(245, 242, 234, 0.88);
+ max-width: 36rem;
+}
+
+.note {
+ font-size: 12px;
+ color: var(--text-muted);
+}
+
+.share-bar {
+ margin-top: 4px;
+ padding-top: 16px;
+ border-top: 1px solid rgba(245, 242, 234, 0.08);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+ flex-wrap: wrap;
+}
+
+.share-label {
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+}
+
+.share-actions {
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+
+.share-btn {
+ position: relative;
+ cursor: pointer;
+ border-radius: var(--radius-pill);
+ border: 1px solid rgba(245, 242, 234, 0.14);
+ background: radial-gradient(circle at 0 0, rgba(201,169,97,0.18), rgba(11,11,14,0.95));
+ color: var(--text);
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ padding: 7px 14px 8px;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ transition: border-color 220ms var(--ease-swift),
+ background 220ms var(--ease-swift),
+ transform 220ms var(--ease-overshoot),
+ box-shadow 220ms var(--ease-swift);
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.6);
+}
+
+.share-btn::before {
+ content: "";
+ width: 8px;
+ height: 8px;
+ border-radius: 999px;
+ border: 1px solid rgba(245,242,234,0.3);
+ background:
+ radial-gradient(circle at 30% 20%, #fdfaf3, #c9a961 45%, #46351a 100%);
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.7);
+}
+
+.share-btn:hover {
+ border-color: rgba(201,169,97,0.9);
+ background: radial-gradient(circle at 0 0, rgba(201,169,97,0.28), rgba(11,11,14,1));
+ transform: translateY(-1px);
+ box-shadow: 0 14px 28px rgba(0,0,0,0.55);
+}
+
+.share-btn:active {
+ transform: translateY(0);
+ box-shadow: 0 6px 18px rgba(0,0,0,0.7);
+}
+
+/* Right column – wheel + filmstrip */
+.panel {
+ position: relative;
+ padding: 26px 22px 22px;
+ border-radius: var(--radius-xl);
+ background: radial-gradient(circle at 100% 0, rgba(201,169,97,0.16), rgba(10,10,12,0.96));
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow-soft);
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ overflow: hidden;
+}
+
+.panel-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ gap: 10px;
+ margin-bottom: 6px;
+}
+
+.panel-title {
+ font-family: var(--font-display);
+ font-size: var(--fs-h3);
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+}
+
+.panel-meta {
+ text-align: right;
+ font-size: 12px;
+ color: var(--text-muted);
+}
+
+.current-hue-name {
+ display: block;
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--accent);
+}
+
+/* Wheel region */
+.wheel-region {
+ display: grid;
+ grid-template-columns: auto;
+ justify-content: center;
+ padding: 12px 6px 8px;
+}
+
+.wheel-shell {
+ position: relative;
+ width: var(--wheel-size);
+ height: var(--wheel-size);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ touch-action: none;
+}
+
+.color-wheel {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ background:
+ conic-gradient(
+ #f5f2ea 0deg 16deg,
+ #f2d9b1 16deg 48deg,
+ #f4a261 48deg 80deg,
+ #e76f51 80deg 112deg,
+ #b93a66 112deg 144deg,
+ #7b4ab8 144deg 176deg,
+ #4361ee 176deg 208deg,
+ #2a9d8f 208deg 240deg,
+ #52b788 240deg 272deg,
+ #c9a961 272deg 304deg,
+ #8d6b32 304deg 336deg,
+ #f5f2ea 336deg 360deg
+ );
+ box-shadow:
+ inset 0 0 0 1px rgba(255,255,255,0.06),
+ 0 28px 55px rgba(0,0,0,0.8);
+ padding: 18px;
+}
+
+.color-wheel::before {
+ content: "";
+ position: absolute;
+ inset: 12%;
+ border-radius: 50%;
+ background:
+ radial-gradient(circle at 30% 0, rgba(245,242,234,0.1), transparent 40%),
+ radial-gradient(circle at 75% 100%, rgba(0,0,0,0.5), transparent 60%);
+ mix-blend-mode: soft-light;
+ pointer-events: none;
+}
+
+.wheel-core {
+ position: absolute;
+ inset: 24%;
+ border-radius: 50%;
+ background:
+ radial-gradient(circle at 30% 20%, rgba(245,242,234,0.35), rgba(13,13,15,0.9) 55%),
+ radial-gradient(circle at 70% 80%, rgba(0,0,0,0.9), rgba(0,0,0,0.8));
+ border: 1px solid rgba(255,255,255,0.15);
+ box-shadow:
+ inset 0 0 0 1px rgba(0,0,0,0.9),
+ 0 16px 26px rgba(0,0,0,0.9);
+}
+
+.indicator-ring {
+ position: absolute;
+ inset: 9%;
+ border-radius: 50%;
+ border: 1px solid rgba(245, 242, 234, 0.1);
+ box-shadow:
+ 0 0 0 1px rgba(0,0,0,0.9),
+ 0 18px 40px rgba(0,0,0,0.8);
+ pointer-events: none;
+}
+
+.indicator-handle {
+ position: absolute;
+ width: 26px;
+ height: 26px;
+ border-radius: 999px;
+ border: 1px solid rgba(245,242,234,0.9);
+ background:
+ radial-gradient(circle at 30% 20%, #fdfaf2, var(--accent) 48%, #5a4622 100%);
+ box-shadow:
+ 0 0 0 1px rgba(0,0,0,0.9),
+ 0 10px 18px rgba(0,0,0,0.9);
+ transform: translate(-50%, -50%);
+ cursor: grab;
+ touch-action: none;
+ transition: box-shadow 200ms var(--ease-swift), transform 200ms var(--ease-overshoot);
+}
+
+.indicator-handle:active {
+ cursor: grabbing;
+ box-shadow:
+ 0 0 0 1px rgba(0,0,0,1),
+ 0 12px 22px rgba(0,0,0,1);
+ transform: translate(-50%, -50%) scale(1.02);
+}
+
+/* Filmstrip */
+.filmstrip {
+ margin-top: 18px;
+ padding-top: 16px;
+ border-top: 1px solid rgba(245,242,234,0.09);
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.filmstrip-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ gap: 10px;
+}
+
+.pattern-label {
+ font-size: 11px;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+}
+
+.swatch-meta {
+ font-size: 12px;
+ color: rgba(245,242,234,0.8);
+}
+
+.swatch-meta span {
+ color: var(--accent);
+ text-transform: uppercase;
+ letter-spacing: 0.14em;
+ font-size: 11px;
+}
+
+.filmstrip-row {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: 10px;
+}
+
+@media (max-width: 720px) {
+ .filmstrip-row {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+}
+
+.pattern-card {
+ position: relative;
+ border-radius: var(--radius-md);
+ overflow: hidden;
+ background: var(--surface);
+ border: 1px solid rgba(245,242,234,0.14);
+ box-shadow:
+ 0 0 0 1px rgba(0,0,0,0.8),
+ 0 14px 30px rgba(0,0,0,0.7);
+ display: flex;
+ flex-direction: column;
+ min-height: 120px;
+}
+
+.pattern-art {
+ position: relative;
+ flex: 1;
+ border-bottom: 1px solid rgba(245,242,234,0.12);
+ background-color: #222;
+}
+
+.pattern-footer {
+ padding: 8px 9px 9px;
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+}
+
+.pattern-name {
+ font-family: var(--font-serif-alt);
+ font-size: 13px;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+}
+
+.pattern-tone {
+ font-size: 11px;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+}
+
+/* Different motif types (pure CSS) */
+.pattern-stripes {
+ background-image:
+ repeating-linear-gradient(
+ 120deg,
+ rgba(0,0,0,0.16) 0,
+ rgba(0,0,0,0.16) 4px,
+ transparent 4px,
+ transparent 12px
+ ),
+ linear-gradient(135deg, var(--p-light) 0%, var(--p-base) 40%, var(--p-deep) 100%);
+}
+
+.pattern-chevron {
+ background-image:
+ repeating-linear-gradient(
+ -45deg,
+ rgba(0,0,0,0.4) 0,
+ rgba(0,0,0,0.4) 1px,
+ transparent 1px,
+ transparent 6px
+ ),
+ repeating-linear-gradient(
+ 45deg,
+ rgba(255,255,255,0.10) 0,
+ rgba(255,255,255,0.10) 1px,
+ transparent 1px,
+ transparent 6px
+ ),
+ linear-gradient(120deg, var(--p-base) 10%, var(--p-deep) 60%, var(--p-light) 100%);
+ background-blend-mode: soft-light, soft-light, normal;
+}
+
+.pattern-grid {
+ background-image:
+ linear-gradient(to right, rgba(0,0,0,0.35) 1px, transparent 1px),
+ linear-gradient(to bottom, rgba(0,0,0,0.35) 1px, transparent 1px),
+ radial-gradient(circle at 20% 0, var(--p-light), var(--p-base) 40%, var(--p-deep) 100%);
+ background-size:
+ 16px 16px,
+ 16px 16px,
+ 100% 100%;
+ background-blend-mode: soft-light, soft-light, normal;
+}
+
+.pattern-marble {
+ background-image:
+ radial-gradient(circle at 10% 0%, rgba(255,255,255,0.18), transparent 60%),
+ radial-gradient(circle at 80% 20%, rgba(255,255,255,0.22), transparent 60%),
+ radial-gradient(circle at 0% 80%, rgba(0,0,0,0.55), transparent 65%),
+ radial-gradient(circle at 100% 100%, rgba(0,0,0,0.7), transparent 65%),
+ linear-gradient(120deg, var(--p-light), var(--p-base) 40%, var(--p-deep) 100%);
+ background-blend-mode: screen, screen, soft-light, soft-light, normal;
+}
+
+/* Overlay tip */
+.tip-pill {
+ position: absolute;
+ right: 18px;
+ bottom: 18px;
+ z-index: 3;
+ border-radius: var(--radius-pill);
+ padding: 6px 11px 6px;
+ border: 1px solid rgba(245,242,234,0.16);
+ background: radial-gradient(circle at 0 0, rgba(201,169,97,0.24), rgba(9,9,12,0.96));
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ pointer-events: none;
+}
+
+.tip-dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 999px;
+ background:
+ radial-gradient(circle at 30% 20%, #fdfaf3, #c9a961 45%, #46351a 100%);
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.8);
+}
+
+/* Accessibility focus outline */
+:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: 3px;
+}
+</style>
+</head>
+<body>
+<header>
+ <div class="header-inner">
+ <div class="brand-lockup">
+ <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+ <div class="wordmark-sub">CURATED COLOR STORIES FOR MODERN INTERIORS</div>
+ </div>
+ <div class="header-meta">
+ <div class="meta-tag">Color wheel social · tap & drag</div>
+ <div class="meta-pill">
+ <span class="meta-dot"></span>
+ LIVE PALETTE PREVIEW
+ </div>
+ </div>
+ </div>
+</header>
+
+<main>
+ <section class="shell" aria-label="Shop by color wheel experience">
+ <div class="copy-block">
+ <div class="eyebrow">Shop by color</div>
+ <h1>Choose your <span>wallcovering mood</span> by hue.</h1>
+ <p class="lead">
+ Glide the wheel to reveal four patterns tuned to each color family — from quiet neutrals
+ to jewel-box saturated walls.
+ </p>
+ <p class="note">
+ Each palette is drawn live in CSS, so you can feel the undertone before a single sample
+ arrives at your door.
+ </p>
+
+ <div class="share-bar" aria-label="Share post">
+ <div class="share-label">Share this palette story</div>
+ <div class="share-actions">
+ <button class="share-btn" type="button">
+ Save to moodboard
+ </button>
+ <button class="share-btn" type="button">
+ Copy link
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <div class="panel" aria-live="polite">
+ <div class="panel-header">
+ <div>
+ <div class="panel-title">Color wheel edit</div>
+ </div>
+ <div class="panel-meta">
+ <span class="current-hue-name" id="currentHueLabel">Ivory Atelier</span>
+ Hue-curated wall textures
+ </div>
+ </div>
+
+ <div class="wheel-region">
+ <div class="wheel-shell" id="wheelShell" aria-label="Drag to select hue">
+ <div class="color-wheel" id="colorWheel"></div>
+ <div class="wheel-core"></div>
+ <div class="indicator-ring"></div>
+ <div
+ class="indicator-handle"
+ id="indicatorHandle"
+ role="slider"
+ aria-valuemin="0"
+ aria-valuemax="359"
+ aria-valuenow="0"
+ aria-label="Selected hue angle"
+ tabindex="0"
+ style="left: 50%; top: 12%;"
+ ></div>
+ </div>
+ </div>
+
+ <div class="filmstrip">
+ <div class="filmstrip-header">
+ <div class="pattern-label">Hue-matched wallcovering study</div>
+ <div class="swatch-meta">
+ Showing <span>4</span> styles in <span id="metaHueFamily">Soft Ivory</span>
+ </div>
+ </div>
+ <div class="filmstrip-row" id="filmstripRow">
+ <!-- Pattern cards populated by JS -->
+ </div>
+ </div>
+
+ <div class="tip-pill">
+ <span class="tip-dot"></span>
+ Tap or drag the halo to change hues
+ </div>
+ </div>
+ </section>
+</main>
+
+<script>
+(function () {
+ const families = [
+ {
+ id: 'ivory',
+ label: 'Ivory Atelier',
+ meta: 'Soft Ivory',
+ hueRange: [350, 20],
+ base: '#f5f2ea',
+ light: '#fdf7ec',
+ deep: '#c9a961',
+ patterns: [
+ { motif: 'stripes', name: 'Atelier Sheer Stripe', tone: 'Porcelain / Reed' },
+ { motif: 'grid', name: 'Gallery Mesh', tone: 'Champagne Linen' },
+ { motif: 'marble', name: 'Veined Plaster', tone: 'Limestone Veil' },
+ { motif: 'chevron', name: 'Tailored Herringbone', tone: 'Bone & Brass' }
+ ]
+ },
+ {
+ id: 'amber',
+ label: 'Amber Salon',
+ meta: 'Golden Amber',
+ hueRange: [25, 60],
+ base: '#f4a261',
+ light: '#f6c08a',
+ deep: '#8d6b32',
+ patterns: [
+ { motif: 'stripes', name: 'Sunlit Panel', tone: 'Roasted Honey' },
+ { motif: 'chevron', name: 'Salon Chevron', tone: 'Burnished Maple' },
+ { motif: 'grid', name: 'Mercer Lattice', tone: 'Golden Hour' },
+ { motif: 'marble', name: 'Molten Onyx', tone: 'Caramel Vein' }
+ ]
+ },
+ {
+ id: 'crimson',
+ label: 'Crimson Salon',
+ meta: 'Crimson',
+ hueRange: [70, 120],
+ base: '#e63946',
+ light: '#ff7b88',
+ deep: '#7b1b2a',
+ patterns: [
+ { motif: 'marble', name: 'Salon Lacquer', tone: 'Rouge Glaze' },
+ { motif: 'stripes', name: 'Opera Stripe', tone: 'Crushed Velvet' },
+ { motif: 'grid', name: 'Deco Inlay', tone: 'Rosewood' },
+ { motif: 'chevron', name: 'Soho Zig', tone: 'Wine Loft' }
+ ]
+ },
+ {
+ id: 'sapphire',
+ label: 'Sapphire Study',
+ meta: 'Sapphire',
+ hueRange: [145, 210],
+ base: '#4361ee',
+ light: '#7b8df5',
+ deep: '#1b2a7a',
+ patterns: [
+ { motif: 'grid', name: 'Midnight Pane', tone: 'Library Ink' },
+ { motif: 'marble', name: 'River Stone', tone: 'Deep Cobalt' },
+ { motif: 'chevron', name: 'Studio Chevron', tone: 'Blue Hour' },
+ { motif: 'stripes', name: 'Tailored Pinstripe', tone: 'Serge Suit' }
+ ]
+ },
+ {
+ id: 'emerald',
+ label: 'Emerald Salon',
+ meta: 'Emerald',
+ hueRange: [210, 270],
+ base: '#2a9d8f',
+ light: '#69c7b6',
+ deep: '#174a41',
+ patterns: [
+ { motif: 'marble', name: 'Palm Veil', tone: 'Winter Garden' },
+ { motif: 'grid', name: 'Greenhouse Pane', tone: 'Glasshouse' },
+ { motif: 'stripes', name: 'Botanical Stripe', tone: 'Monstera Ink' },
+ { motif: 'chevron', name: 'Jardin Chevron', tone: 'Tea Leaf' }
+ ]
+ },
+ {
+ id: 'bronze',
+ label: 'Bronze Loft',
+ meta: 'Bronze',
+ hueRange: [270, 340],
+ base: '#c9a961',
+ light: '#e0c88b',
+ deep: '#5a4622',
+ patterns: [
+ { motif: 'stripes', name: 'Bronze Ledger', tone: 'Tobacco Leaf' },
+ { motif: 'marble', name: 'Patina Stucco', tone: 'Smoked Ochre' },
+ { motif: 'grid', name: 'Loft Grille', tone: 'Aged Metal' },
+ { motif: 'chevron', name: 'Foundry Herringbone', tone: 'Forged Bronze' }
+ ]
+ }
+ ];
+
+ const indicator = document.getElementById('indicatorHandle');
+ const wheelShell = document.getElementById('wheelShell');
+ const filmstripRow = document.getElementById('filmstripRow');
+ const hueLabel = document.getElementById('currentHueLabel');
+ const metaHueFamily = document.getElementById('metaHueFamily');
+
+ let currentAngle = 0;
+ let isDragging = false;
+
+ function angleFromEvent(evt) {
+ const rect = wheelShell.getBoundingClientRect();
+ const cx = rect.left + rect.width / 2;
+ const cy = rect.top + rect.height / 2;
+ const clientX = (evt.touches ? evt.touches[0].clientX : evt.clientX);
+ const clientY = (evt.touches ? evt.touches[0].clientY : evt.clientY);
+ const dx = clientX - cx;
+ const dy = clientY - cy;
+ let angle = Math.atan2(dy, dx) * (180 / Math.PI);
+ angle = (angle + 450) % 360; // 0° at top, increase clockwise
+ return angle;
+ }
+
+ function updateIndicator(angle) {
+ const rect = wheelShell.getBoundingClientRect();
+ const radius = rect.width / 2 * 0.86;
+ const centerX = rect.width / 2;
+ const centerY = rect.height / 2;
+ const rad = (angle - 90) * Math.PI / 180;
+ const x = centerX + radius * Math.cos(rad);
+ const y = centerY + radius * Math.sin(rad);
+ indicator.style.left = x + 'px';
+ indicator.style.top = y + 'px';
+ indicator.setAttribute('aria-valuenow', Math.round(angle));
+ applyFamilyForAngle(angle);
+ }
+
+ function pickFamilyByAngle(angle) {
+ for (const fam of families) {
+ const [start, end] = fam.hueRange;
+ if (start <= end) {
+ if (angle >= start && angle < end) return fam;
+ } else {
+ if (angle >= start || angle < end) return fam;
+ }
+ }
+ return families[0];
+ }
+
+ function applyFamilyForAngle(angle) {
+ const fam = pickFamilyByAngle(angle);
+ hueLabel.textContent = fam.label;
+ metaHueFamily.textContent = fam.meta;
+ renderFilmstrip(fam);
+ }
+
+ function renderFilmstrip(fam) {
+ filmstripRow.innerHTML = '';
+ fam.patterns.forEach(p => {
+ const card = document.createElement('article');
+ card.className = 'pattern-card';
+ card.setAttribute('aria-label', p.name + ' in ' + fam.meta);
+
+ const art = document.createElement('div');
+ art.className = 'pattern-art pattern-' + p.motif;
+ art.style.setProperty('--p-base', fam.base);
+ art.style.setProperty('--p-light', fam.light);
+ art.style.setProperty('--p-deep', fam.deep);
+
+ const footer = document.createElement('div');
+ footer.className = 'pattern-footer';
+
+ const nameEl = document.createElement('div');
+ nameEl.className = 'pattern-name';
+ nameEl.innerHTML = p.name;
+
+ const toneEl = document.createElement('div');
+ toneEl.className = 'pattern-tone';
+ toneEl.innerHTML = p.tone;
+
+ footer.appendChild(nameEl);
+ footer.appendChild(toneEl);
+ card.appendChild(art);
+ card.appendChild(footer);
+ filmstripRow.appendChild(card);
+ });
+ }
+
+ function onPointerDown(evt) {
+ isDragging = true;
+ document.body.style.userSelect = 'none';
+ const angle = angleFromEvent(evt);
+ currentAngle = angle;
+ updateIndicator(angle);
+ }
+
+ function onPointerMove(evt) {
+ if (!isDragging) return;
+ const angle = angleFromEvent(evt);
+ currentAngle = angle;
+ updateIndicator(angle);
+ evt.preventDefault();
+ }
+
+ function onPointerUp() {
+ isDragging = false;
+ document.body.style.userSelect = '';
+ }
+
+ wheelShell.addEventListener('mousedown', onPointerDown);
+ window.addEventListener('mousemove', onPointerMove);
+ window.addEventListener('mouseup', onPointerUp);
+
+ wheelShell.addEventListener('touchstart', function (evt) {
+ onPointerDown(evt);
+ }, { passive: true });
+ window.addEventListener('touchmove', function (evt) {
+ onPointerMove(evt);
+ }, { passive: false });
+ window.addEventListener('touchend', onPointerUp);
+ window.addEventListener('touchcancel', onPointerUp);
+
+ indicator.addEventListener('keydown', function (evt) {
+ const step = (evt.shiftKey ? 10 : 4);
+ if (evt.key === 'ArrowLeft' || evt.key === 'ArrowDown') {
+ currentAngle = (currentAngle - step + 360) % 360;
+ updateIndicator(currentAngle);
+ evt.preventDefault();
+ } else if (evt.key === 'ArrowRight' || evt.key === 'ArrowUp') {
+ currentAngle = (currentAngle + step) % 360;
+ updateIndicator(currentAngle);
+ evt.preventDefault();
+ }
+ });
+
+ // Initial state
+ renderFilmstrip(families[0]);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/gpt.png b/data/artifacts/9e458dd990ce/gpt.png
new file mode 100644
index 0000000..08bc577
Binary files /dev/null and b/data/artifacts/9e458dd990ce/gpt.png differ
diff --git a/data/artifacts/9e458dd990ce/grok.html b/data/artifacts/9e458dd990ce/grok.html
new file mode 100644
index 0000000..2e95713
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/grok.html
@@ -0,0 +1,1167 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Shop by Color — 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.22);
+ --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.28);
+ --ease: cubic-bezier(.22, .9, .24, 1);
+ --ease-out: cubic-bezier(.22, 1, .36, 1);
+ --radius: 14px;
+ --radius-sm: 6px;
+ --serif: 'Didot', 'Bodoni MT', 'Playfair Display', 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
+ --sans: 'Avenir Next', 'Century Gothic', 'Helvetica Neue', 'Segoe UI', sans-serif;
+ --space-1: 4px;
+ --space-2: 8px;
+ --space-3: 12px;
+ --space-4: 16px;
+ --space-5: 24px;
+ --space-6: 32px;
+ --space-7: 48px;
+ --space-8: 64px;
+}
+
+*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+
+html, body {
+ min-height: 100%;
+ background: var(--bg);
+ color: var(--text);
+ font-family: var(--sans);
+ font-size: 16px;
+ line-height: 1.55;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ overflow-x: hidden;
+}
+
+/* ——— Fixed top bar / wordmark ——— */
+.site-header {
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--space-4);
+ padding: var(--space-4) var(--space-5);
+ background: rgba(13, 13, 15, 0.92);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--line-soft);
+}
+
+.wordmark {
+ font-family: var(--serif);
+ font-size: clamp(18px, 3.6vw, 42px);
+ font-weight: 400;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text);
+ line-height: 1.15;
+ max-width: min(72vw, 560px);
+ white-space: normal;
+}
+
+.header-meta {
+ font-family: var(--sans);
+ font-size: 10px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+/* ——— Main ——— */
+main {
+ flex: 1;
+ width: 100%;
+ max-width: 1100px;
+ margin: 0 auto;
+ padding: var(--space-7) var(--space-5) var(--space-8);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: var(--space-7);
+}
+
+.intro {
+ text-align: center;
+ max-width: 36ch;
+}
+
+.intro h1 {
+ font-family: var(--serif);
+ font-size: clamp(28px, 5vw, 50px);
+ font-weight: 400;
+ letter-spacing: -0.02em;
+ line-height: 1.1;
+ color: var(--text);
+ margin-bottom: var(--space-3);
+}
+
+.intro p {
+ font-size: 14px;
+ color: var(--muted);
+ letter-spacing: 0.04em;
+ line-height: 1.6;
+}
+
+.eyebrow {
+ display: block;
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-bottom: var(--space-3);
+}
+
+/* ——— Wheel stage ——— */
+.wheel-stage {
+ position: relative;
+ width: min(320px, 78vw);
+ aspect-ratio: 1;
+ touch-action: none;
+ user-select: none;
+ -webkit-user-select: none;
+}
+
+.wheel-ring {
+ position: absolute;
+ inset: 0;
+ border-radius: 50%;
+ box-shadow: var(--shadow), inset 0 0 0 1px var(--line);
+ background: conic-gradient(
+ from -90deg,
+ #c45c4a 0deg 30deg,
+ #d4a05a 30deg 60deg,
+ #c9b86a 60deg 90deg,
+ #7a9e6e 90deg 120deg,
+ #5a8f8a 120deg 150deg,
+ #5a7fa8 150deg 180deg,
+ #6a6a9e 180deg 210deg,
+ #8a5a8e 210deg 240deg,
+ #a85a7a 240deg 270deg,
+ #b86a5a 270deg 300deg,
+ #c47a5a 300deg 330deg,
+ #c45c4a 330deg 360deg
+ );
+ cursor: grab;
+ transition: box-shadow 300ms var(--ease);
+}
+
+.wheel-ring:active,
+.wheel-ring.is-dragging {
+ cursor: grabbing;
+ box-shadow: var(--shadow), inset 0 0 0 1px var(--accent), 0 0 0 4px rgba(201, 169, 97, 0.12);
+}
+
+.wheel-inner {
+ position: absolute;
+ inset: 18%;
+ border-radius: 50%;
+ background: var(--bg);
+ border: 1px solid var(--line);
+ box-shadow: inset 0 2px 24px rgba(0, 0, 0, 0.5);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ pointer-events: none;
+ z-index: 2;
+}
+
+.swatch-preview {
+ width: 48px;
+ height: 48px;
+ border-radius: 50%;
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow-soft);
+ background: #c45c4a;
+ transition: background 400ms var(--ease), transform 400ms var(--ease);
+}
+
+.hue-label {
+ font-family: var(--serif);
+ font-size: 20px;
+ letter-spacing: 0.06em;
+ color: var(--text);
+ transition: color 300ms var(--ease);
+}
+
+.hue-sub {
+ font-size: 10px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* Pointer / indicator */
+.wheel-pointer {
+ position: absolute;
+ top: -2px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 0;
+ height: 0;
+ border-left: 7px solid transparent;
+ border-right: 7px solid transparent;
+ border-top: 12px solid var(--accent);
+ z-index: 3;
+ filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
+ pointer-events: none;
+}
+
+.wheel-knob {
+ position: absolute;
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: var(--text);
+ border: 2px solid var(--bg);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
+ z-index: 4;
+ pointer-events: none;
+ top: 50%;
+ left: 50%;
+ margin: -9px 0 0 -9px;
+ transform-origin: center center;
+ transition: transform 80ms linear;
+}
+
+/* ——— Filmstrip ——— */
+.filmstrip-section {
+ width: 100%;
+ max-width: 720px;
+ opacity: 0;
+ transform: translateY(16px);
+ transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out);
+ pointer-events: none;
+}
+
+.filmstrip-section.is-visible {
+ opacity: 1;
+ transform: translateY(0);
+ pointer-events: auto;
+}
+
+.filmstrip-head {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ gap: var(--space-4);
+ margin-bottom: var(--space-4);
+ padding: 0 2px;
+ border-bottom: 1px solid var(--line-soft);
+ padding-bottom: var(--space-3);
+}
+
+.filmstrip-head h2 {
+ font-family: var(--serif);
+ font-size: clamp(22px, 3.5vw, 28px);
+ font-weight: 400;
+ letter-spacing: 0.02em;
+ color: var(--text);
+}
+
+.filmstrip-head .count {
+ font-size: 10px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.filmstrip {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: var(--space-3);
+}
+
+@media (max-width: 560px) {
+ .filmstrip {
+ grid-template-columns: repeat(2, 1fr);
+ gap: var(--space-3);
+ }
+}
+
+.tile {
+ position: relative;
+ background: var(--surface);
+ border: 1px solid var(--line-soft);
+ border-radius: var(--radius);
+ overflow: hidden;
+ box-shadow: var(--shadow-soft);
+ transition: transform 350ms var(--ease), border-color 350ms var(--ease), box-shadow 350ms var(--ease);
+ cursor: pointer;
+ opacity: 0;
+ transform: translateY(12px);
+}
+
+.filmstrip-section.is-visible .tile {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+.filmstrip-section.is-visible .tile:nth-child(1) { transition-delay: 0ms, 0ms, 0ms; }
+.filmstrip-section.is-visible .tile:nth-child(2) { transition-delay: 80ms, 80ms, 80ms; }
+.filmstrip-section.is-visible .tile:nth-child(3) { transition-delay: 160ms, 160ms, 160ms; }
+.filmstrip-section.is-visible .tile:nth-child(4) { transition-delay: 240ms, 240ms, 240ms; }
+
+.tile:hover,
+.tile:focus-visible {
+ transform: translateY(-4px);
+ border-color: var(--line);
+ box-shadow: var(--shadow);
+ outline: none;
+}
+
+.tile:focus-visible {
+ outline: 1px solid var(--accent);
+ outline-offset: 2px;
+}
+
+.tile-pattern {
+ aspect-ratio: 3 / 4;
+ width: 100%;
+ position: relative;
+ overflow: hidden;
+}
+
+.tile-meta {
+ padding: var(--space-3) var(--space-3) var(--space-4);
+ border-top: 1px solid var(--line-soft);
+}
+
+.tile-name {
+ font-family: var(--serif);
+ font-size: 15px;
+ letter-spacing: 0.03em;
+ color: var(--text);
+ line-height: 1.25;
+ margin-bottom: 4px;
+}
+
+.tile-family {
+ font-size: 10px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* Pattern motifs — pure CSS, hue-driven via custom props */
+.pat {
+ position: absolute;
+ inset: 0;
+ --c1: var(--p1, #c45c4a);
+ --c2: var(--p2, #8a3a30);
+ --c3: var(--p3, #e8a090);
+ --c0: var(--p0, #1a1210);
+}
+
+/* 1 — Damask lattice */
+.pat-damask {
+ background:
+ radial-gradient(ellipse 40% 30% at 50% 50%, var(--c3) 0%, transparent 70%),
+ radial-gradient(circle at 50% 0%, var(--c1) 0 2px, transparent 2.5px),
+ radial-gradient(circle at 0% 50%, var(--c1) 0 2px, transparent 2.5px),
+ radial-gradient(circle at 100% 50%, var(--c1) 0 2px, transparent 2.5px),
+ radial-gradient(circle at 50% 100%, var(--c1) 0 2px, transparent 2.5px),
+ linear-gradient(135deg, var(--c0) 25%, transparent 25.5%),
+ linear-gradient(225deg, var(--c0) 25%, transparent 25.5%),
+ linear-gradient(45deg, var(--c0) 25%, transparent 25.5%),
+ linear-gradient(315deg, var(--c0) 25%, transparent 25.5%),
+ var(--c2);
+ background-size: 100% 100%, 28px 28px, 28px 28px, 28px 28px, 28px 28px, 28px 28px, 28px 28px, 28px 28px, 28px 28px, auto;
+}
+
+.pat-damask::before {
+ content: "";
+ position: absolute;
+ inset: 18%;
+ border: 1px solid color-mix(in srgb, var(--c3) 55%, transparent);
+ border-radius: 50%;
+ box-shadow: inset 0 0 0 8px color-mix(in srgb, var(--c1) 25%, transparent);
+}
+
+.pat-damask::after {
+ content: "";
+ position: absolute;
+ inset: 32%;
+ background:
+ radial-gradient(circle at 50% 50%, var(--c3) 0 18%, transparent 19%),
+ conic-gradient(from 0deg, transparent 0 20deg, color-mix(in srgb, var(--c1) 70%, transparent) 20deg 40deg, transparent 40deg 90deg);
+ border-radius: 50%;
+ opacity: 0.85;
+}
+
+/* 2 — Herringbone */
+.pat-herringbone {
+ background-color: var(--c0);
+ background-image:
+ repeating-linear-gradient(
+ 45deg,
+ var(--c1) 0 6px,
+ var(--c2) 6px 12px,
+ transparent 12px 18px
+ ),
+ repeating-linear-gradient(
+ -45deg,
+ var(--c1) 0 6px,
+ var(--c2) 6px 12px,
+ transparent 12px 18px
+ );
+ background-size: 36px 36px;
+ background-position: 0 0, 18px 0;
+}
+
+.pat-herringbone::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, transparent 60%, color-mix(in srgb, var(--c0) 55%, transparent));
+ pointer-events: none;
+}
+
+/* 3 — Botanical dots / toile-like */
+.pat-botanical {
+ background-color: var(--c0);
+ background-image:
+ radial-gradient(circle at 20% 30%, var(--c3) 0 3px, transparent 3.5px),
+ radial-gradient(circle at 70% 25%, var(--c1) 0 2px, transparent 2.5px),
+ radial-gradient(circle at 45% 60%, var(--c3) 0 4px, transparent 4.5px),
+ radial-gradient(circle at 80% 70%, var(--c1) 0 2.5px, transparent 3px),
+ radial-gradient(circle at 25% 80%, var(--c2) 0 5px, transparent 5.5px),
+ radial-gradient(circle at 55% 15%, color-mix(in srgb, var(--c1) 60%, transparent) 0 8px, transparent 9px),
+ radial-gradient(circle at 10% 55%, color-mix(in srgb, var(--c3) 40%, transparent) 0 12px, transparent 13px),
+ radial-gradient(ellipse 80% 40% at 60% 85%, color-mix(in srgb, var(--c2) 50%, transparent), transparent);
+}
+
+.pat-botanical::before {
+ content: "";
+ position: absolute;
+ width: 40%;
+ height: 55%;
+ left: 28%;
+ top: 18%;
+ border: 1.5px solid color-mix(in srgb, var(--c1) 55%, transparent);
+ border-radius: 50% 50% 45% 55% / 60% 40% 60% 40%;
+ transform: rotate(-18deg);
+ box-shadow:
+ 14px 10px 0 -1px color-mix(in srgb, var(--c3) 30%, transparent),
+ -10px 16px 0 -2px color-mix(in srgb, var(--c2) 35%, transparent);
+}
+
+.pat-botanical::after {
+ content: "";
+ position: absolute;
+ width: 2px;
+ height: 38%;
+ left: 48%;
+ top: 30%;
+ background: linear-gradient(180deg, transparent, var(--c1), transparent);
+ transform: rotate(-18deg);
+ opacity: 0.7;
+}
+
+/* 4 — Vertical stripe / grosgrain */
+.pat-stripe {
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ var(--c0) 0 8px,
+ var(--c2) 8px 10px,
+ var(--c1) 10px 18px,
+ var(--c3) 18px 20px,
+ var(--c0) 20px 26px,
+ color-mix(in srgb, var(--c1) 70%, var(--c0)) 26px 28px
+ );
+}
+
+.pat-stripe::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background:
+ linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--c3) 15%, transparent) 50%, transparent 100%),
+ linear-gradient(180deg, color-mix(in srgb, var(--c0) 30%, transparent), transparent 30%, transparent 70%, color-mix(in srgb, var(--c0) 40%, transparent));
+ pointer-events: none;
+}
+
+/* ——— Share bar ——— */
+.share-bar {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space-2) var(--space-3);
+ padding-top: var(--space-5);
+ border-top: 1px solid var(--line-soft);
+ width: 100%;
+ max-width: 720px;
+}
+
+.share-label {
+ font-size: 10px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-right: var(--space-2);
+}
+
+.share-btn {
+ appearance: none;
+ border: 1px solid var(--line);
+ background: transparent;
+ color: var(--text);
+ font-family: var(--sans);
+ font-size: 10px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ padding: 10px 16px;
+ border-radius: 999px;
+ cursor: pointer;
+ transition: background 250ms var(--ease), border-color 250ms var(--ease), color 250ms var(--ease), transform 200ms var(--ease);
+}
+
+.share-btn:hover,
+.share-btn:focus-visible {
+ background: color-mix(in srgb, var(--accent) 14%, transparent);
+ border-color: var(--accent);
+ color: var(--accent);
+ outline: none;
+}
+
+.share-btn:active {
+ transform: scale(0.97);
+}
+
+.share-btn.primary {
+ background: var(--accent);
+ color: var(--ink);
+ border-color: var(--accent);
+ font-weight: 600;
+}
+
+.share-btn.primary:hover,
+.share-btn.primary:focus-visible {
+ background: color-mix(in srgb, var(--accent) 88%, white);
+ color: var(--ink);
+ border-color: color-mix(in srgb, var(--accent) 88%, white);
+}
+
+/* ——— Toast overlay ——— */
+.toast {
+ position: fixed;
+ bottom: var(--space-6);
+ left: 50%;
+ transform: translateX(-50%) translateY(20px);
+ background: var(--surface);
+ color: var(--text);
+ border: 1px solid var(--line);
+ border-radius: var(--radius-sm);
+ padding: 12px 20px;
+ font-size: 12px;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ box-shadow: var(--shadow);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 300ms var(--ease), transform 300ms var(--ease);
+ z-index: 200;
+ max-width: 90vw;
+ text-align: center;
+}
+
+.toast.is-on {
+ opacity: 1;
+ transform: translateX(-50%) translateY(0);
+}
+
+/* ——— Detail overlay ——— */
+.overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 150;
+ display: grid;
+ place-items: center;
+ padding: var(--space-5);
+ background: rgba(13, 13, 15, 0.72);
+ backdrop-filter: blur(8px);
+ -webkit-backdrop-filter: blur(8px);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 350ms var(--ease);
+}
+
+.overlay.is-open {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.overlay-card {
+ width: min(400px, 100%);
+ background: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow);
+ overflow: hidden;
+ transform: translateY(12px) scale(0.98);
+ transition: transform 400ms var(--ease-out);
+}
+
+.overlay.is-open .overlay-card {
+ transform: translateY(0) scale(1);
+}
+
+.overlay-pattern {
+ aspect-ratio: 16 / 11;
+ position: relative;
+}
+
+.overlay-body {
+ padding: var(--space-5);
+}
+
+.overlay-body h3 {
+ font-family: var(--serif);
+ font-size: 28px;
+ font-weight: 400;
+ letter-spacing: 0.02em;
+ margin-bottom: 6px;
+ color: var(--text);
+}
+
+.overlay-body .family {
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-bottom: var(--space-4);
+}
+
+.overlay-body p {
+ font-size: 14px;
+ color: var(--muted);
+ line-height: 1.65;
+ margin-bottom: var(--space-5);
+}
+
+.overlay-actions {
+ display: flex;
+ gap: var(--space-2);
+ justify-content: flex-end;
+}
+
+/* ——— Footer brand ——— */
+.site-footer {
+ text-align: center;
+ padding: var(--space-5) var(--space-5) var(--space-6);
+ border-top: 1px solid var(--line-soft);
+}
+
+.site-footer span {
+ font-family: var(--serif);
+ font-size: 12px;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* Reduced motion */
+@media (prefers-reduced-motion: reduce) {
+ *, *::before, *::after {
+ transition-duration: 0.01ms !important;
+ animation-duration: 0.01ms !important;
+ }
+}
+</style>
+</head>
+<body>
+<header class="site-header">
+ <div class="wordmark">Designer Wallcoverings</div>
+ <div class="header-meta">Shop by Color</div>
+</header>
+
+<main>
+ <div class="intro">
+ <span class="eyebrow">Curated Palette</span>
+ <h1>Find your hue</h1>
+ <p>Drag the wheel to explore our color families. Four signature patterns reveal themselves in each register.</p>
+ </div>
+
+ <div class="wheel-stage" id="wheelStage" aria-label="Color wheel. Drag or tap to select a hue.">
+ <div class="wheel-pointer" aria-hidden="true"></div>
+ <div class="wheel-ring" id="wheelRing" role="slider" aria-valuemin="0" aria-valuemax="359" aria-valuenow="0" aria-valuetext="Vermilion" tabindex="0"></div>
+ <div class="wheel-knob" id="wheelKnob" aria-hidden="true"></div>
+ <div class="wheel-inner">
+ <div class="swatch-preview" id="swatchPreview"></div>
+ <div class="hue-label" id="hueLabel">Vermilion</div>
+ <div class="hue-sub" id="hueSub">Warm reds</div>
+ </div>
+ </div>
+
+ <section class="filmstrip-section is-visible" id="filmstripSection" aria-live="polite">
+ <div class="filmstrip-head">
+ <h2 id="familyTitle">Vermilion</h2>
+ <span class="count">4 patterns</span>
+ </div>
+ <div class="filmstrip" id="filmstrip"></div>
+ </section>
+
+ <div class="share-bar">
+ <span class="share-label">Share</span>
+ <button type="button" class="share-btn primary" id="btnCopy">Copy link</button>
+ <button type="button" class="share-btn" id="btnSave">Save palette</button>
+ <button type="button" class="share-btn" id="btnReset">Reset wheel</button>
+ </div>
+</main>
+
+<footer class="site-footer">
+ <span>Designer Wallcoverings · Est. Atelier</span>
+</footer>
+
+<div class="toast" id="toast" role="status" aria-live="polite"></div>
+
+<div class="overlay" id="overlay" aria-hidden="true">
+ <div class="overlay-card" role="dialog" aria-modal="true" aria-labelledby="ovTitle">
+ <div class="overlay-pattern" id="ovPattern"></div>
+ <div class="overlay-body">
+ <h3 id="ovTitle">—</h3>
+ <div class="family" id="ovFamily">—</div>
+ <p id="ovBlurb">—</p>
+ <div class="overlay-actions">
+ <button type="button" class="share-btn" id="ovClose">Close</button>
+ <button type="button" class="share-btn primary" id="ovInquire">Inquire</button>
+ </div>
+ </div>
+ </div>
+</div>
+
+<script>
+(function () {
+ const FAMILIES = [
+ {
+ id: "vermilion",
+ name: "Vermilion",
+ sub: "Warm reds",
+ angle: 0,
+ base: [196, 92, 74],
+ patterns: [
+ { name: "Ember Damask", cls: "pat-damask", blurb: "A classical lattice softened by ember undertones — hand-drawn scale for intimate rooms." },
+ { name: "Russet Herringbone", cls: "pat-herringbone", blurb: "Crisp chevron weave in roasted clay. Tailored for studies and gallery halls." },
+ { name: "Coral Toile", cls: "pat-botanical", blurb: "Botanical silhouettes floating on a deep rouge ground. Quietly narrative." },
+ { name: "Garnet Stripe", cls: "pat-stripe", blurb: "Grosgrain verticals in garnet and blush — architectural, never loud." }
+ ]
+ },
+ {
+ id: "amber",
+ name: "Amber",
+ sub: "Honeyed golds",
+ angle: 30,
+ base: [212, 160, 90],
+ patterns: [
+ { name: "Saffron Lattice", cls: "pat-damask", blurb: "Sunlit damask with a jeweler’s restraint. Pairs with walnut and linen." },
+ { name: "Honeybone", cls: "pat-herringbone", blurb: "Warm herringbone in pressed amber — a quiet glow for dining walls." },
+ { name: "Marigold Sprig", cls: "pat-botanical", blurb: "Scattered marigold and seed heads on tobacco parchment." },
+ { name: "Gilt Ribbon", cls: "pat-stripe", blurb: "Fine gilt ribbons alternating with umber — couture for corridors." }
+ ]
+ },
+ {
+ id: "citron",
+ name: "Citron",
+ sub: "Soft chartreuse",
+ angle: 60,
+ base: [201, 184, 106],
+ patterns: [
+ { name: "Lichen Damask", cls: "pat-damask", blurb: "Pale chartreuse damask with mineral depth. Serene, slightly wild." },
+ { name: "Willow Herringbone", cls: "pat-herringbone", blurb: "Feathered chevrons in willow and cream. Light-catching and calm." },
+ { name: "Citrine Grove", cls: "pat-botanical", blurb: "Whispered orchard motifs on a buttered citron field." },
+ { name: "Champagne Stripe", cls: "pat-stripe", blurb: "Narrow champagne and straw stripes for refined vertical lift." }
+ ]
+ },
+ {
+ id: "botanical",
+ name: "Botanical",
+ sub: "Garden greens",
+ angle: 90,
+ base: [122, 158, 110],
+ patterns: [
+ { name: "Boxwood Damask", cls: "pat-damask", blurb: "Formal garden geometry in deep boxwood. Timeless English restraint." },
+ { name: "Fern Herringbone", cls: "pat-herringbone", blurb: "Soft fern chevrons — organic structure for reading rooms." },
+ { name: "Olive Toile", cls: "pat-botanical", blurb: "Olive leaf and vine on a mossed ground. Quietly continental." },
+ { name: "Ivy Column", cls: "pat-stripe", blurb: "Ivy-toned columns with pale sage intervals. Architectural greenery." }
+ ]
+ },
+ {
+ id: "sea",
+ name: "Aegean",
+ sub: "Sea teals",
+ angle: 120,
+ base: [90, 143, 138],
+ patterns: [
+ { name: "Tide Damask", cls: "pat-damask", blurb: "Watered silk geometry in sea-glass teal. Coastal without cliché." },
+ { name: "Kelp Herringbone", cls: "pat-herringbone", blurb: "Deep kelp weave with a brushed metallic sheen." },
+ { name: "Fjord Sprig", cls: "pat-botanical", blurb: "Nordic sprigs on a still fjord ground. Cool and collected." },
+ { name: "Harbor Stripe", cls: "pat-stripe", blurb: "Harbor-teal ribbons with ivory gutters — yacht-club restraint." }
+ ]
+ },
+ {
+ id: "slate",
+ name: "Slate",
+ sub: "Powder blues",
+ angle: 150,
+ base: [90, 127, 168],
+ patterns: [
+ { name: "Porcelain Damask", cls: "pat-damask", blurb: "Wedgwood-inspired lattice in powder blue. Refined and airy." },
+ { name: "Flannel Herringbone", cls: "pat-herringbone", blurb: "Tailored blue flannel chevron. Library-ready." },
+ { name: "Indigo Botanica", cls: "pat-botanical", blurb: "Pressed blooms on indigo dusk. Romantic without sweetness." },
+ { name: "Horizon Stripe", cls: "pat-stripe", blurb: "Horizon lines in steel and mist — modern and linear." }
+ ]
+ },
+ {
+ id: "violet",
+ name: "Violet",
+ sub: "Dusk lavenders",
+ angle: 180,
+ base: [106, 106, 158],
+ patterns: [
+ { name: "Twilight Damask", cls: "pat-damask", blurb: "Dusk-violet damask with a candlelit center. Evening rooms." },
+ { name: "Heather Herringbone", cls: "pat-herringbone", blurb: "Heather and plum chevrons — soft structure for bedrooms." },
+ { name: "Iris Toile", cls: "pat-botanical", blurb: "Iris silhouettes on a deep mauve ground. Poetic and rare." },
+ { name: "Amethyst Stripe", cls: "pat-stripe", blurb: "Amethyst and pewter ribbons. Jewel-box elegance." }
+ ]
+ },
+ {
+ id: "orchid",
+ name: "Orchid",
+ sub: "Muted mauves",
+ angle: 210,
+ base: [138, 90, 142],
+ patterns: [
+ { name: "Mulberry Lattice", cls: "pat-damask", blurb: "Mulberry damask with antique rose highlights. Opulent hush." },
+ { name: "Plum Herringbone", cls: "pat-herringbone", blurb: "Plum flannel weave — intimate and enveloping." },
+ { name: "Orchid Press", cls: "pat-botanical", blurb: "Pressed orchid forms on a wine-dusk field." },
+ { name: "Rosewood Stripe", cls: "pat-stripe", blurb: "Rosewood and mauve columns for boudoir architecture." }
+ ]
+ },
+ {
+ id: "rose",
+ name: "Rose",
+ sub: "Blushed pinks",
+ angle: 240,
+ base: [168, 90, 122],
+ patterns: [
+ { name: "Blush Damask", cls: "pat-damask", blurb: "Powdered blush damask. Soft light, soft shadow." },
+ { name: "Petal Herringbone", cls: "pat-herringbone", blurb: "Petal-pink chevrons with a suede finish." },
+ { name: "Peony Toile", cls: "pat-botanical", blurb: "Full peonies in faded rose on warm ivory-mauve." },
+ { name: "Silk Ribbon", cls: "pat-stripe", blurb: "Silk-ribbon stripes in rose and shell. Delicate lift." }
+ ]
+ },
+ {
+ id: "terracotta",
+ name: "Terracotta",
+ sub: "Clay earths",
+ angle: 270,
+ base: [184, 106, 90],
+ patterns: [
+ { name: "Clay Damask", cls: "pat-damask", blurb: "Sun-baked clay lattice. Mediterranean bones." },
+ { name: "Adobe Herringbone", cls: "pat-herringbone", blurb: "Adobe chevron with desert warmth." },
+ { name: "Fig Leaf", cls: "pat-botanical", blurb: "Fig and olive silhouettes on terracotta dust." },
+ { name: "Sienna Stripe", cls: "pat-stripe", blurb: "Burnt sienna ribbons — grounded and graphic." }
+ ]
+ },
+ {
+ id: "copper",
+ name: "Copper",
+ sub: "Burnished metals",
+ angle: 300,
+ base: [196, 122, 90],
+ patterns: [
+ { name: "Patina Damask", cls: "pat-damask", blurb: "Copper patina damask. Warm metal without shine." },
+ { name: "Bronze Herringbone", cls: "pat-herringbone", blurb: "Bronze weave for club rooms and bars." },
+ { name: "Apricot Grove", cls: "pat-botanical", blurb: "Apricot boughs on a copper dusk ground." },
+ { name: "Ingot Stripe", cls: "pat-stripe", blurb: "Ingot-fine stripes in copper and cream." }
+ ]
+ },
+ {
+ id: "cinnabar",
+ name: "Cinnabar",
+ sub: "Deep corals",
+ angle: 330,
+ base: [196, 92, 74],
+ patterns: [
+ { name: "Lacquer Damask", cls: "pat-damask", blurb: "Cinnabar lacquer geometry. Eastern-inspired polish." },
+ { name: "Coral Herringbone", cls: "pat-herringbone", blurb: "Deep coral chevrons with a soft nap." },
+ { name: "Pomegranate", cls: "pat-botanical", blurb: "Pomegranate and seed motifs on a lacquered red." },
+ { name: "Vermilion Ribbon", cls: "pat-stripe", blurb: "Bold vermilion ribbons tempered by sand." }
+ ]
+ }
+ ];
+
+ const ring = document.getElementById("wheelRing");
+ const knob = document.getElementById("wheelKnob");
+ const preview = document.getElementById("swatchPreview");
+ const hueLabel = document.getElementById("hueLabel");
+ const hueSub = document.getElementById("hueSub");
+ const familyTitle = document.getElementById("familyTitle");
+ const filmstrip = document.getElementById("filmstrip");
+ const filmSection = document.getElementById("filmstripSection");
+ const stage = document.getElementById("wheelStage");
+ const toast = document.getElementById("toast");
+ const overlay = document.getElementById("overlay");
+ const ovPattern = document.getElementById("ovPattern");
+ const ovTitle = document.getElementById("ovTitle");
+ const ovFamily = document.getElementById("ovFamily");
+ const ovBlurb = document.getElementById("ovBlurb");
+
+ let angle = 0; // 0 = top (vermilion)
+ let dragging = false;
+ let currentFamily = FAMILIES[0];
+ let toastTimer = null;
+
+ function clampHue(a) {
+ a = a % 360;
+ if (a < 0) a += 360;
+ return a;
+ }
+
+ function rgbStr(c, a) {
+ if (a == null) return `rgb(${c[0]}, ${c[1]}, ${c[2]})`;
+ return `rgba(${c[0]}, ${c[1]}, ${c[2]}, ${a})`;
+ }
+
+ function shade(base, f) {
+ // f < 1 darker, > 1 lighter
+ return base.map((v) => Math.max(0, Math.min(255, Math.round(v * f))));
+ }
+
+ function mix(a, b, t) {
+ return a.map((v, i) => Math.round(v + (b[i] - v) * t));
+ }
+
+ function familyFromAngle(a) {
+ // pointer is at top; wheel color under pointer is `a` if ring is rotated by `a`
+ // Our conic starts at -90deg (top). Family centers every 30°.
+ const idx = Math.round(clampHue(a) / 30) % 12;
+ return FAMILIES[idx];
+ }
+
+ function paletteVars(base) {
+ const c0 = shade(base, 0.22);
+ const c1 = base;
+ const c2 = shade(base, 0.62);
+ const c3 = mix(base, [245, 242, 234], 0.45);
+ return {
+ "--p0": rgbStr(c0),
+ "--p1": rgbStr(c1),
+ "--p2": rgbStr(c2),
+ "--p3": rgbStr(c3)
+ };
+ }
+
+ function applyVars(el, vars) {
+ for (const k in vars) el.style.setProperty(k, vars[k]);
+ }
+
+ function setKnob(a) {
+ // knob sits on the outer ring under the top pointer — so rotate ring, knob fixed at top-ish
+ // Actually: we rotate the ring; the knob indicates the selected point on the rim at the pointer (top).
+ // Place knob at top of ring always.
+ const r = stage.clientWidth / 2;
+ const orbit = r * 0.91;
+ // fixed at top
+ const x = 0;
+ const y = -orbit;
+ knob.style.transform = `translate(${x}px, ${y}px)`;
+ }
+
+ function renderFilmstrip(fam, animate) {
+ if (animate) {
+ filmSection.classList.remove("is-visible");
+ // force reflow
+ void filmSection.offsetWidth;
+ }
+ familyTitle.textContent = fam.name;
+ const vars = paletteVars(fam.base);
+ filmstrip.innerHTML = "";
+ fam.patterns.forEach((p, i) => {
+ const tile = document.createElement("button");
+ tile.type = "button";
+ tile.className = "tile";
+ tile.setAttribute("aria-label", p.name + ", " + fam.name);
+ tile.innerHTML =
+ `<div class="tile-pattern"><div class="pat ${p.cls}"></div></div>` +
+ `<div class="tile-meta"><div class="tile-name">${p.name}</div>` +
+ `<div class="tile-family">${fam.name}</div></div>`;
+ const pat = tile.querySelector(".pat");
+ applyVars(pat, vars);
+ tile.addEventListener("click", () => openOverlay(fam, p, vars));
+ filmstrip.appendChild(tile);
+ });
+ requestAnimationFrame(() => {
+ filmSection.classList.add("is-visible");
+ });
+ }
+
+ function updateUI(a, force) {
+ angle = clampHue(a);
+ ring.style.transform = `rotate(${-angle}deg)`;
+ ring.setAttribute("aria-valuenow", Math.round(angle));
+ setKnob(angle);
+
+ const fam = familyFromAngle(angle);
+ const hexish = rgbStr(fam.base);
+ preview.style.background = hexish;
+
+ if (!force && fam.id === currentFamily.id) return;
+ currentFamily = fam;
+ hueLabel.textContent = fam.name;
+ hueSub.textContent = fam.sub;
+ ring.setAttribute("aria-valuetext", fam.name);
+ renderFilmstrip(fam, true);
+ }
+
+ function pointerAngle(clientX, clientY) {
+ const rect = stage.getBoundingClientRect();
+ const cx = rect.left + rect.width / 2;
+ const cy = rect.top + rect.height / 2;
+ const dx = clientX - cx;
+ const dy = clientY - cy;
+ // 0 at top, clockwise
+ let deg = (Math.atan2(dx, -dy) * 180) / Math.PI;
+ return clampHue(deg);
+ }
+
+ function onDown(e) {
+ dragging = true;
+ ring.classList.add("is-dragging");
+ const pt = e.touches ? e.touches[0] : e;
+ updateUI(pointerAngle(pt.clientX, pt.clientY), false);
+ e.preventDefault();
+ }
+ function onMove(e) {
+ if (!dragging) return;
+ const pt = e.touches ? e.touches[0] : e;
+ updateUI(pointerAngle(pt.clientX, pt.clientY), false);
+ e.preventDefault();
+ }
+ function onUp() {
+ dragging = false;
+ ring.classList.remove("is-dragging");
+ // snap to family center
+ const fam = familyFromAngle(angle);
+ updateUI(fam.angle, true);
+ }
+
+ ring.addEventListener("mousedown", onDown);
+ window.addEventListener("mousemove", onMove);
+ window.addEventListener("mouseup", onUp);
+ ring.addEventListener("touchstart", onDown, { passive: false });
+ window.addEventListener("touchmove", onMove, { passive: false });
+ window.addEventListener("touchend", onUp);
+
+ ring.addEventListener("keydown", (e) => {
+ let d = 0;
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") d = 30;
+ if (e.key === "ArrowLeft" || e.key === "ArrowDown") d = -30;
+ if (!d) return;
+ e.preventDefault();
+ const fam = familyFromAngle(angle + d);
+ updateUI(fam.angle, true);
+ });
+
+ // click anywhere on ring snaps
+ ring.addEventListener("click", (e) => {
+ if (e.detail === 0) return; // keyboard
+ updateUI(pointerAngle(e.clientX, e.clientY), true);
+ const fam = familyFromAngle(angle);
+ updateUI(fam.angle, true);
+ });
+
+ function showToast(msg) {
+ toast.textContent = msg;
+ toast.classList.add("is-on");
+ clearTimeout(toastTimer);
+ toastTimer = setTimeout(() => toast.classList.remove("is-on"), 2200);
+ }
+
+ document.getElementById("btnCopy").addEventListener("click", () => {
+ const text = `Designer Wallcoverings — ${currentFamily.name} palette`;
+ if (navigator.clipboard && navigator.clipboard.writeText) {
+ navigator.clipboard.writeText(text).then(
+ () => showToast("Palette link copied"),
+ () => showToast("Copied · " + currentFamily.name)
+ );
+ } else {
+ showToast("Share · " + currentFamily.name);
+ }
+ });
+
+ document.getElementById("btnSave").addEventListener("click", () => {
+ showToast("Saved · " + currentFamily.name + " suite");
+ });
+
+ document.getElementById("btnReset").addEventListener("click", () => {
+ updateUI(0, true);
+ showToast("Wheel reset");
+ });
+
+ function openOverlay(fam, pat, vars) {
+ ovTitle.textContent = pat.name;
+ ovFamily.textContent = fam.name + " · " + fam.sub;
+ ovBlurb.textContent = pat.blurb;
+ ovPattern.innerHTML = `<div class="pat ${pat.cls}" style="position:absolute;inset:0"></div>`;
+ applyVars(ovPattern.querySelector(".pat"), vars);
+ overlay.classList.add("is-open");
+ overlay.setAttribute("aria-hidden", "false");
+ document.getElementById("ovClose").focus();
+ }
+
+ function closeOverlay() {
+ overlay.classList.remove("is-open");
+ overlay.setAttribute("aria-hidden", "true");
+ }
+
+ document.getElementById("ovClose").addEventListener("click", closeOverlay);
+ overlay.addEventListener("click", (e) => {
+ if (e.target === overlay) closeOverlay();
+ });
+ document.getElementById("ovInquire").addEventListener("click", () => {
+ closeOverlay();
+ showToast("Inquiry noted · atelier will reply");
+ });
+ document.addEventListener("keydown", (e) => {
+ if (e.key === "Escape" && overlay.classList.contains("is-open")) closeOverlay();
+ });
+
+ window.addEventListener("resize", () => setKnob(angle));
+
+ // init
+ updateUI(0, true);
+ setKnob(0);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/grok.png b/data/artifacts/9e458dd990ce/grok.png
new file mode 100644
index 0000000..f42e771
Binary files /dev/null and b/data/artifacts/9e458dd990ce/grok.png differ
diff --git a/data/artifacts/9e458dd990ce/hermes3-8b.html b/data/artifacts/9e458dd990ce/hermes3-8b.html
new file mode 100644
index 0000000..c098aea
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/hermes3-8b.html
@@ -0,0 +1,153 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Shop by Color</title>
+<style>
+:root {
+ --bg: #f7efe6;
+ --surface: #fff9f1;
+ --text: #3a2c22;
+ --muted: #a08c7a;
+ --accent-bg: #e0a458;
+ --accent-fg: #c65f38;
+ --line: #c65f38;
+ --shadow: rgba(0,0,0,.12);
+ --glow-shadow: rgba(var(--accent-fg),.35);
+ --ease: cubic-bezier(.22,1,.36,1);
+}
+body {
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ line-height: 1.6;
+ color: var(--text);
+ background: var(--bg);
+ margin: 0;
+ padding: 96px;
+}
+h1 {
+ font-family: Didot, Bodoni MT, Playfair Display, Georgia, serif;
+ font-size: 50px;
+ letter-spacing: .15em;
+ color: transparent;
+ text-fill-color: var(--text);
+ -webkit-background-clip: text;
+ background: var(--surface);
+}
+h2 {
+ font-size: 38px;
+ margin-top: 0;
+ margin-bottom: 24px;
+}
+a, button {
+ font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ background: var(--surface);
+ color: var(--text);
+ border: 1px solid var(--line);
+ padding: 12px 24px;
+ box-shadow: 0 8px 24px var(--shadow);
+ transition: box-shadow .3s var(--ease), transform .7s var(--ease);
+}
+a:hover, button:hover {
+ color: var(--surface);
+ background: var(--text);
+ cursor: pointer;
+ transform: translateY(-4px);
+ box-shadow: 0 16px 48px var(--glow-shadow);
+}
+section {
+ margin-bottom: 96px;
+}
+.color-wheel {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+}
+.color-swatch {
+ aspect-ratio: 2 / 1;
+ background: #c65f38;
+ border-radius: 14px;
+ box-shadow: var(--shadow);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: transform .5s var(--ease), box-shadow .7s var(--ease);
+}
+.color-swatch:hover {
+ box-shadow: var(--glow-shadow);
+ transform: translateY(-6px);
+}
+.pattern-preview {
+ display: none;
+ position: relative;
+}
+.pattern-preview::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(var(--surface),.75);
+ z-index: 1;
+ transition: opacity .5s var(--ease);
+}
+.pattern-preview img {
+ width: 100%;
+ height: auto;
+ display: block;
+ opacity: 0;
+ transition: opacity .5s var(--ease);
+}
+.color-swatch:hover ~ .pattern-preview {
+ display: block;
+}
+.pattern-description {
+ margin-top: 12px;
+ color: var(--muted);
+}
+@keyframes fadeUp {
+ from {opacity: 0; transform: translateY(28px);}
+ to {opacity: 1; transform: none;}
+}
+.fade-up {
+ animation: fadeUp .7s var(--ease) both;
+}
+.stagger-child {
+ animation-duration: .6s;
+ animation-timing-function: var(--ease);
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+}
+.stagger-child:nth-child(2n) {
+ animation-delay: .1s;
+}
+.stagger-child:nth-child(2n+1) {
+ animation-delay: .2s;
+}
+</style>
+</head>
+<body>
+<div class="share-bar">
+ <button>Share</button>
+</div>
+<h1 class="wordmark">DESIGNER WALLCOVERINGS</h1>
+<section class="cta">
+ <h2>Shop by Color</h2>
+ <a href="#" class="cta-button">View Collections</a>
+</section>
+<section class="color-wheel">
+ <div class="color-swatch" style="--swatch-color:#c65f38;">
+ <img src="#inline" alt="" class="pattern-preview">
+ <p class="pattern-description">#TerracottaSun: Warm, organic colors evoke a craftsman's touch.</p>
+ </div>
+ <div class="color-swash" style="--swatch-color:#8d7bb0;">
+ <img src="#inline" alt="" class="pattern-preview">
+ <p class="pattern-description">#Synthwave: Retro neon hues capture an '80s arcade vibe.</p>
+ </div>
+ <!-- more color wheels -->
+</section>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/hermes3-8b.png b/data/artifacts/9e458dd990ce/hermes3-8b.png
new file mode 100644
index 0000000..8a54ad7
Binary files /dev/null and b/data/artifacts/9e458dd990ce/hermes3-8b.png differ
diff --git a/data/artifacts/9e458dd990ce/hf-qwen-coder-32b.html b/data/artifacts/9e458dd990ce/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..f78b82d
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/hf-qwen-coder-32b.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Shop by Color</title>
+ <style>
+ :root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e;
+ --line: #dcdcde;
+ --shadow: 0 8px 24px rgba(0,0,0,.12);
+ --hover-shadow: 0 16px 48px rgba(0,0,0,.18);
+ --glow: 0 0 24px #b0472e35;
+ --ease: cubic-bezier(.22,1,.36,1);
+ }
+ * {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ }
+ body {
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ background-color: var(--bg);
+ color: var(--text);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+ }
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ padding: 24px;
+ background-color: var(--bg);
+ z-index: 100;
+ display: flex;
+ align-items: center;
+ }
+ header h1 {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 50px;
+ letter-spacing: .18em;
+ color: var(--text);
+ margin-right: auto;
+ }
+ .color-wheel-container {
+ position: relative;
+ width: 400px;
+ height: 400px;
+ border-radius: 50%;
+ overflow: hidden;
+ margin-top: 128px;
+ }
+ .color-wheel {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: conic-gradient(
+ #f44336, #e91e63, #9c27b0, #673ab7,
+ #3f51b5, #2196f3, #03a9f4, #00bcd4,
+ #009688, #4caf50, #8bc34a, #cddc39,
+ #ffeb3b, #ffc107, #ff9800, #ff5722
+ );
+ border-radius: 50%;
+ cursor: grab;
+ }
+ .color-wheel:active {
+ cursor: grabbing;
+ }
+ .pattern-strip {
+ position: absolute;
+ top: 400px;
+ left: 0;
+ width: 100%;
+ height: 200px;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ background-color: var(--surface);
+ box-shadow: var(--shadow);
+ border-radius: 14px;
+ overflow: hidden;
+ }
+ .pattern {
+ width: 80px;
+ height: 120px;
+ margin: 16px;
+ border-radius: 8px;
+ background-size: cover;
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ .pattern:nth-child(1) {
+ background-image: linear-gradient(45deg, var(--accent), #f06292);
+ }
+ .pattern:nth-child(2) {
+ background-image: repeating-linear-gradient(45deg, var(--accent), var(--accent) 33px, transparent 33px, transparent 66px);
+ }
+ .pattern:nth-child(3) {
+ background-image: radial-gradient(circle at center, var(--accent), #ffecb3);
+ }
+ .pattern:nth-child(4) {
+ background-image: linear-gradient(to bottom, var(--accent), #b0bec5);
+ }
+ .pattern::after {
+ content: attr(data-name);
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 16px;
+ color: var(--text);
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ }
+ .share-bar {
+ position: fixed;
+ bottom: 24px;
+ right: 24px;
+ background-color: var(--surface);
+ border-radius: 8px;
+ box-shadow: var(--shadow);
+ display: flex;
+ align-items: center;
+ padding: 12px;
+ }
+ .share-bar button {
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ color: var(--accent);
+ background-color: transparent;
+ border: none;
+ cursor: pointer;
+ }
+ </style>
+</head>
+<body>
+ <header>
+ <h1>DESIGNER WALLCOVERINGS</h1>
+ </header>
+ <div class="color-wheel-container">
+ <div id="colorWheel" class="color-wheel"></div>
+ <div id="patternStrip" class="pattern-strip">
+ <div class="pattern" data-name="AMBER DREAM"></div>
+ <div class="pattern" data-name="SUNSET SOFT"></div>
+ <div class="pattern" data-name="GOLDEN SUNRAY"></div>
+ <div class="pattern" data-name="CRIMSON SKY"></div>
+ </div>
+ </div>
+ <div class="share-bar">
+ <button onclick="alert('Share functionality not implemented in this demo')">SHARE</button>
+ </div>
+ <script>
+ const colorWheel = document.getElementById('colorWheel');
+ let isDragging = false;
+ let startX, startDeg;
+
+ function getRotation(element) {
+ const style = window.getComputedStyle(element);
+ const matrix = new DOMMatrix(style.transform);
+ return Math.round(Math.asin(matrix.m21) * (180/Math.PI));
+ }
+
+ function setRotation(element, deg) {
+ element.style.transform = `rotate(${deg}deg)`;
+ }
+
+ colorWheel.addEventListener('mousedown', (e) => {
+ isDragging = true;
+ startX = e.clientX;
+ startDeg = getRotation(colorWheel);
+ document.body.style.cursor = 'grabbing';
+ });
+
+ document.addEventListener('mousemove', (e) => {
+ if (!isDragging) return;
+ const dx = e.clientX - startX;
+ setRotation(colorWheel, startDeg + dx);
+ });
+
+ document.addEventListener('mouseup', () => {
+ isDragging = false;
+ document.body.style.cursor = 'grab';
+ });
+
+ colorWheel.addEventListener('touchstart', (e) => {
+ isDragging = true;
+ startX = e.touches[0].clientX;
+ startDeg = getRotation(colorWheel);
+ });
+
+ colorWheel.addEventListener('touchmove', (e) => {
+ if (!isDragging) return;
+ const dx = e.touches[0].clientX - startX;
+ setRotation(colorWheel, startDeg + dx);
+ }, { passive: true });
+
+ colorWheel.addEventListener('touchend', () => {
+ isDragging = false;
+ });
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/hf-qwen-coder-32b.png b/data/artifacts/9e458dd990ce/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..d53c5dd
Binary files /dev/null and b/data/artifacts/9e458dd990ce/hf-qwen-coder-32b.png differ
diff --git a/data/artifacts/9e458dd990ce/kimi.html b/data/artifacts/9e458dd990ce/kimi.html
new file mode 100644
index 0000000..e3f491c
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/kimi.html
@@ -0,0 +1,678 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Shop by Color | Designer Wallcoverings</title>
+ <style>
+ :root {
+ /* Luxury Warm Ivory Palette - Systematic Tokens */
+ --bg: #f5f2ea;
+ --surface: #ebe7de;
+ --text: #1c1a17;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --line: rgba(28, 26, 23, 0.12);
+ --shadow: rgba(0, 0, 0, 0.08);
+
+ /* Typography */
+ --font-display: 'Playfair Display', 'Didot', 'Bodoni MT', Georgia, serif;
+ --font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+
+ /* Motion Easings */
+ --ease-swift: cubic-bezier(.22,.9,.24,1);
+ --ease-power: cubic-bezier(.77,0,.18,1);
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: var(--font-body);
+ background: var(--bg);
+ color: var(--text);
+ line-height: 1.6;
+ overflow-x: hidden;
+ -webkit-font-smoothing: antialiased;
+ }
+
+ /* Fixed Header */
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 100;
+ background: rgba(245, 242, 234, 0.95);
+ backdrop-filter: blur(10px);
+ border-bottom: 1px solid var(--line);
+ padding: 1.5rem 2.5rem;
+ }
+
+ .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.05;
+ }
+
+ .wordmark span {
+ display: block;
+ white-space: nowrap;
+ }
+
+ /* Main Content */
+ main {
+ margin-top: 160px;
+ padding: 2rem 2.5rem 4rem;
+ max-width: 1400px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ /* Wheel Section */
+ .wheel-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 4rem;
+ }
+
+ .wheel-wrapper {
+ position: relative;
+ width: 340px;
+ height: 340px;
+ margin: 2rem 0;
+ }
+
+ .color-wheel {
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ position: relative;
+ cursor: grab;
+ transition: transform 0.8s var(--ease-swift);
+ box-shadow: 0 30px 80px var(--shadow);
+ overflow: hidden;
+ }
+
+ .color-wheel:active {
+ cursor: grabbing;
+ }
+
+ .wheel-center {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 90px;
+ height: 90px;
+ background: var(--bg);
+ border-radius: 50%;
+ border: 1px solid var(--line);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
+ box-shadow: 0 4px 20px var(--shadow);
+ }
+
+ .wheel-center::after {
+ content: '';
+ width: 14px;
+ height: 14px;
+ background: var(--accent);
+ border-radius: 50%;
+ box-shadow: 0 0 0 4px rgba(201, 169, 97, 0.2);
+ }
+
+ /* Color Segments */
+ .wheel-segment {
+ position: absolute;
+ width: 50%;
+ height: 50%;
+ transform-origin: 100% 100%;
+ clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
+ cursor: pointer;
+ transition: all 0.3s var(--ease-swift);
+ left: 0;
+ top: 0;
+ }
+
+ .wheel-segment:hover {
+ filter: brightness(1.1);
+ z-index: 5;
+ }
+
+ .wheel-segment.active {
+ filter: brightness(1.15);
+ }
+
+ /* Color Indicator */
+ .color-indicator {
+ position: absolute;
+ top: -12px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 0;
+ height: 0;
+ border-left: 14px solid transparent;
+ border-right: 14px solid transparent;
+ border-top: 24px solid var(--accent);
+ z-index: 20;
+ filter: drop-shadow(0 2px 8px rgba(0,0,0,0.15));
+ }
+
+ /* Selected Color Info */
+ .color-info {
+ text-align: center;
+ margin-top: 2rem;
+ }
+
+ .color-name {
+ font-family: var(--font-display);
+ font-size: 38px;
+ color: var(--text);
+ margin-bottom: 0.5rem;
+ font-weight: 400;
+ }
+
+ .color-family {
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+ color: var(--muted);
+ }
+
+ /* Filmstrip */
+ .filmstrip {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 2rem;
+ margin: 4rem 0;
+ }
+
+ .pattern-card {
+ aspect-ratio: 3/4;
+ background: var(--surface);
+ border: 1px solid var(--line);
+ position: relative;
+ overflow: hidden;
+ transition: all 0.5s var(--ease-swift);
+ }
+
+ .pattern-card:hover {
+ transform: translateY(-6px);
+ box-shadow: 0 20px 50px var(--shadow);
+ border-color: rgba(201, 169, 97, 0.3);
+ }
+
+ .pattern-svg {
+ width: 100%;
+ height: 100%;
+ display: block;
+ }
+
+ .pattern-label {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: 1.25rem;
+ background: linear-gradient(to top, rgba(28,26,23,0.85), transparent);
+ font-family: var(--font-body);
+ font-size: 10px;
+ text-transform: uppercase;
+ letter-spacing: 0.15em;
+ color: var(--bg);
+ font-weight: 500;
+ }
+
+ /* Share Bar */
+ .share-bar {
+ display: flex;
+ justify-content: center;
+ gap: 1.5rem;
+ padding: 2.5rem;
+ border-top: 1px solid var(--line);
+ margin-top: 4rem;
+ }
+
+ .share-btn {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.875rem 1.75rem;
+ background: transparent;
+ border: 1px solid var(--line);
+ color: var(--muted);
+ font-family: var(--font-body);
+ font-size: 10px;
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+ cursor: pointer;
+ transition: all 0.3s var(--ease-swift);
+ font-weight: 500;
+ }
+
+ .share-btn:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+ background: rgba(201, 169, 97, 0.05);
+ }
+
+ .share-btn svg {
+ width: 14px;
+ height: 14px;
+ stroke-width: 1.5;
+ }
+
+ /* Toast Notification */
+ .toast {
+ position: fixed;
+ bottom: 2rem;
+ left: 50%;
+ transform: translateX(-50%) translateY(100px);
+ background: var(--text);
+ color: var(--bg);
+ padding: 1rem 2rem;
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.15em;
+ opacity: 0;
+ transition: all 0.4s var(--ease-swift);
+ z-index: 200;
+ pointer-events: none;
+ }
+
+ .toast.show {
+ transform: translateX(-50%) translateY(0);
+ opacity: 1;
+ }
+
+ /* Responsive */
+ @media (max-width: 1024px) {
+ .filmstrip {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 1.5rem;
+ }
+ }
+
+ @media (max-width: 600px) {
+ header {
+ padding: 1.25rem 1.5rem;
+ }
+
+ .wordmark {
+ font-size: 40px;
+ }
+
+ main {
+ padding: 1.5rem;
+ margin-top: 140px;
+ }
+
+ .wheel-wrapper {
+ width: 300px;
+ height: 300px;
+ }
+
+ .filmstrip {
+ grid-template-columns: 1fr;
+ gap: 1.5rem;
+ }
+
+ .color-name {
+ font-size: 32px;
+ }
+
+ .share-bar {
+ flex-direction: column;
+ align-items: center;
+ gap: 1rem;
+ }
+ }
+ </style>
+</head>
+<body>
+ <header>
+ <div class="wordmark">
+ <span>Designer</span>
+ <span>Wallcoverings</span>
+ </div>
+ </header>
+
+ <main>
+ <div class="wheel-container">
+ <div class="wheel-wrapper">
+ <div class="color-indicator"></div>
+ <div class="color-wheel" id="colorWheel">
+ <!-- Segments generated by JS -->
+ </div>
+ <div class="wheel-center"></div>
+ </div>
+
+ <div class="color-info">
+ <h2 class="color-name" id="colorName">Alabaster</h2>
+ <p class="color-family" id="colorFamily">Warm Neutrals</p>
+ </div>
+ </div>
+
+ <div class="filmstrip" id="filmstrip">
+ <!-- Pattern cards generated by JS -->
+ </div>
+
+ <div class="share-bar">
+ <button class="share-btn" onclick="shareCollection()">
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
+ <path d="M4 12v8a2 2 0 002 2h12a2 2 0 002-2v-8"/>
+ <polyline points="16 6 12 2 8 6"/>
+ <line x1="12" y1="2" x2="12" y2="15"/>
+ </svg>
+ Share
+ </button>
+ <button class="share-btn" onclick="saveCollection()">
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
+ <path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/>
+ <polyline points="17 21 17 13 7 13 7 21"/>
+ <polyline points="7 3 7 8 15 8"/>
+ </svg>
+ Save
+ </button>
+ </div>
+ </main>
+
+ <div class="toast" id="toast">Collection saved</div>
+
+ <script>
+ // Curated designer color families
+ const colorFamilies = [
+ { name: 'Alabaster', hue: 35, sat: 12, light: 88, family: 'Warm Neutrals' },
+ { name: 'Parchment', hue: 42, sat: 18, light: 78, family: 'Warm Neutrals' },
+ { name: 'Champagne', hue: 45, sat: 25, light: 70, family: 'Luminous' },
+ { name: 'Terracotta', hue: 22, sat: 48, light: 58, family: 'Earth Tones' },
+ { name: 'Cinnabar', hue: 12, sat: 55, light: 45, family: 'Rich Earth' },
+ { name: 'Bordeaux', hue: 355, sat: 48, light: 32, family: 'Deep Tones' },
+ { name: 'Dusty Rose', hue: 345, sat: 28, light: 72, family: 'Soft Accents' },
+ { name: 'Sage', hue: 85, sat: 18, light: 68, family: 'Natural Greens' },
+ { name: 'Olive', hue: 75, sat: 28, light: 42, family: 'Natural Greens' },
+ { name: 'Navy', hue: 220, sat: 42, light: 22, family: 'Deep Tones' },
+ { name: 'Slate', hue: 215, sat: 18, light: 48, family: 'Cool Neutrals' },
+ { name: 'Gold', hue: 43, sat: 75, light: 52, family: 'Metallics' }
+ ];
+
+ let isDragging = false;
+ let startAngle = 0;
+ let currentRotation = 0;
+ let selectedIndex = 0;
+
+ const wheel = document.getElementById('colorWheel');
+ const colorNameEl = document.getElementById('colorName');
+ const colorFamilyEl = document.getElementById('colorFamily');
+ const filmstrip = document.getElementById('filmstrip');
+ const toast = document.getElementById('toast');
+
+ // Create wheel segments as conic sections
+ function createWheel() {
+ const segmentAngle = 360 / colorFamilies.length;
+
+ colorFamilies.forEach((color, index) => {
+ const segment = document.createElement('div');
+ segment.className = 'wheel-segment';
+ segment.style.background = `hsl(${color.hue}, ${color.sat}%, ${color.light}%)`;
+ segment.style.transform = `rotate(${index * segmentAngle}deg) skewY(${90 - segmentAngle}deg)`;
+ segment.style.transformOrigin = '100% 100%';
+ segment.dataset.index = index;
+
+ segment.addEventListener('click', (e) => {
+ e.stopPropagation();
+ selectColor(index);
+ });
+
+ wheel.appendChild(segment);
+ });
+ }
+
+ // Generate distinct pattern SVGs
+ function generatePattern(type, hue, sat, light) {
+ const base = `hsl(${hue}, ${sat}%, ${light}%)`;
+ const lightTone = `hsl(${hue}, ${sat}%, ${Math.min(light + 18, 95)}%)`;
+ const darkTone = `hsl(${hue}, ${sat}%, ${Math.max(light - 15, 15)}%)`;
+ const midTone = `hsl(${hue}, ${sat}%, ${light}%)`;
+
+ switch(type) {
+ case 'lattice':
+ return `
+ <svg class="pattern-svg" viewBox="0 0 300 400" preserveAspectRatio="xMidYMid slice">
+ <rect width="300" height="400" fill="${lightTone}"/>
+ <g opacity="0.7">
+ ${Array.from({length: 8}, (_, i) => {
+ const x = i * 45;
+ return `<rect x="${x}" y="0" width="20" height="400" fill="${base}" transform="rotate(15 ${x + 10} 200)"/>`;
+ }).join('')}
+ </g>
+ <g opacity="0.4">
+ ${Array.from({length: 6}, (_, i) => {
+ const y = i * 70;
+ return `<rect x="0" y="${y}" width="300" height="12" fill="${darkTone}"/>`;
+ }).join('')}
+ </g>
+ </svg>
+ `;
+
+ case 'wave':
+ return `
+ <svg class="pattern-svg" viewBox="0 0 300 400" preserveAspectRatio="xMidYMid slice">
+ <rect width="300" height="400" fill="${base}"/>
+ <g fill="none" stroke="${lightTone}" stroke-width="2" opacity="0.8">
+ ${Array.from({length: 12}, (_, i) => {
+ const y = 30 + i * 35;
+ return `<path d="M0,${y} Q75,${y - 20} 150,${y} T300,${y}" stroke-width="${2 + (i % 3)}"/>`;
+ }).join('')}
+ </g>
+ <circle cx="80" cy="100" r="40" fill="${darkTone}" opacity="0.15"/>
+ <circle cx="220" cy="300" r="60" fill="${darkTone}" opacity="0.1"/>
+ </svg>
+ `;
+
+ case 'herringbone':
+ return `
+ <svg class="pattern-svg" viewBox="0 0 300 400" preserveAspectRatio="xMidYMid slice">
+ <rect width="300" height="400" fill="${lightTone}"/>
+ <g stroke="${base}" stroke-width="6" opacity="0.85">
+ ${Array.from({length: 12}, (_, i) => {
+ const y = i * 35;
+ return `
+ <line x1="0" y1="${y}" x2="150" y2="${y + 25}" />
+ <line x1="150" y1="${y + 25}" x2="300" y2="${y}" />
+ <line x1="0" y1="${y + 12}" x2="150" y2="${y + 37}" />
+ <line x1="150" y1="${y + 37}" x2="300" y2="${y + 12}" />
+ `;
+ }).join('')}
+ </g>
+ </svg>
+ `;
+
+ case 'botanical':
+ return `
+ <svg class="pattern-svg" viewBox="0 0 300 400" preserveAspectRatio="xMidYMid slice">
+ <rect width="300" height="400" fill="${base}"/>
+ <g fill="${lightTone}" opacity="0.6">
+ <path d="M150,80 Q180,120 150,160 Q120,120 150,80"/>
+ <path d="M150,160 L150,260"/>
+ <path d="M150,180 Q190,195 210,165"/>
+ <path d="M150,210 Q110,225 90,195"/>
+ <path d="M150,260 Q190,275 210,245"/>
+ <path d="M150,290 Q110,305 90,275"/>
+ <ellipse cx="150" cy="70" rx="15" ry="8"/>
+ </g>
+ <g fill="${darkTone}" opacity="0.25">
+ <circle cx="60" cy="120" r="25"/>
+ <circle cx="240" cy="280" r="35"/>
+ <circle cx="50" cy="320" r="18"/>
+ <circle cx="260" cy="100" r="20"/>
+ </g>
+ </svg>
+ `;
+ }
+ }
+
+ // Select color and update patterns
+ function selectColor(index) {
+ selectedIndex = index;
+ const color = colorFamilies[index];
+
+ // Update text with staggered animation effect
+ colorNameEl.style.opacity = '0';
+ colorNameEl.style.transform = 'translateY(10px)';
+
+ setTimeout(() => {
+ colorNameEl.textContent = color.name;
+ colorFamilyEl.textContent = color.family;
+ colorNameEl.style.transition = 'all 0.4s cubic-bezier(.22,.9,.24,1)';
+ colorNameEl.style.opacity = '1';
+ colorNameEl.style.transform = 'translateY(0)';
+ }, 150);
+
+ // Rotate wheel to position selection at top
+ const segmentAngle = 360 / colorFamilies.length;
+ const targetRotation = -index * segmentAngle;
+ wheel.style.transform = `rotate(${targetRotation}deg)`;
+
+ // Update active states
+ document.querySelectorAll('.wheel-segment').forEach((seg, i) => {
+ seg.classList.toggle('active', i === index);
+ });
+
+ // Update filmstrip with staggered entrance
+ updateFilmstrip(color);
+ }
+
+ function updateFilmstrip(color) {
+ const patterns = ['lattice', 'wave', 'herringbone', 'botanical'];
+ const patternNames = ['Lattice Work', 'Organic Flow', 'Herringbone', 'Botanical Study'];
+
+ // Fade out existing
+ const existingCards = filmstrip.querySelectorAll('.pattern-card');
+ existingCards.forEach((card, i) => {
+ setTimeout(() => {
+ card.style.opacity = '0';
+ card.style.transform = 'translateY(20px)';
+ }, i * 50);
+ });
+
+ // Create new after brief delay
+ setTimeout(() => {
+ filmstrip.innerHTML = '';
+
+ patterns.forEach((type, i) => {
+ const card = document.createElement('div');
+ card.className = 'pattern-card';
+ card.style.opacity = '0';
+ card.style.transform = 'translateY(30px)';
+ card.style.transition = 'all 0.6s cubic-bezier(.22,.9,.24,1)';
+
+ card.innerHTML = `
+ ${generatePattern(type, color.hue, color.sat, color.light)}
+ <div class="pattern-label">${color.name} ${patternNames[i]}</div>
+ `;
+
+ filmstrip.appendChild(card);
+
+ // Staggered entrance
+ requestAnimationFrame(() => {
+ setTimeout(() => {
+ card.style.opacity = '1';
+ card.style.transform = 'translateY(0)';
+ }, i * 120);
+ });
+ });
+ }, existingCards.length > 0 ? 300 : 0);
+ }
+
+ // Drag functionality
+ function getAngle(e) {
+ const rect = wheel.getBoundingClientRect();
+ const centerX = rect.left + rect.width / 2;
+ const centerY = rect.top + rect.height / 2;
+ const clientX = e.touches ? e.touches[0].clientX : e.clientX;
+ const clientY = e.touches ? e.touches[0].clientY : e.clientY;
+ return Math.atan2(clientY - centerY, clientX - centerX) * 180 / Math.PI;
+ }
+
+ function startDrag(e) {
+ isDragging = true;
+ startAngle = getAngle(e) - currentRotation;
+ wheel.style.transition = 'none';
+ document.body.style.cursor = 'grabbing';
+ }
+
+ function drag(e) {
+ if (!isDragging) return;
+ e.preventDefault();
+ currentRotation = getAngle(e) - startAngle;
+ wheel.style.transform = `rotate(${currentRotation}deg)`;
+ }
+
+ function endDrag() {
+ if (!isDragging) return;
+ isDragging = false;
+ document.body.style.cursor = '';
+ wheel.style.transition = 'transform 0.8s cubic-bezier(.22,.9,.24,1)';
+
+ // Snap to nearest segment
+ const segmentAngle = 360 / colorFamilies.length;
+ const normalizedRotation = ((currentRotation % 360) + 360) % 360;
+ const snapIndex = Math.round((360 - normalizedRotation) / segmentAngle) % colorFamilies.length;
+ selectColor(snapIndex);
+ }
+
+ // Event listeners
+ wheel.addEventListener('mousedown', startDrag);
+ document.addEventListener('mousemove', drag);
+ document.addEventListener('mouseup', endDrag);
+
+ wheel.addEventListener('touchstart', (e) => startDrag(e), {passive: false});
+ document.addEventListener('touchmove', (e) => drag(e), {passive: false});
+ document.addEventListener('touchend', endDrag);
+
+ // Share functionality
+ function showToast(message) {
+ toast.textContent = message;
+ toast.classList.add('show');
+ setTimeout(() => toast.classList.remove('show'), 2500);
+ }
+
+ function shareCollection() {
+ const color = colorFamilies[selectedIndex];
+ const text = `${color.name} Collection — Designer Wallcoverings`;
+
+ if (navigator.share) {
+ navigator.share({
+ title: 'Designer Wallcoverings',
+ text: text,
+ url: window.location.href
+ }).catch(() => {});
+ } else {
+ navigator.clipboard.writeText(text).then(() => {
+ showToast('Copied to clipboard');
+ });
+ }
+ }
+
+ function saveCollection() {
+ showToast('Collection saved to favorites');
+ }
+
+ // Initialize
+ createWheel();
+ selectColor(0);
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/kimi.png b/data/artifacts/9e458dd990ce/kimi.png
new file mode 100644
index 0000000..4a5b59b
Binary files /dev/null and b/data/artifacts/9e458dd990ce/kimi.png differ
diff --git a/data/artifacts/9e458dd990ce/qwen25-7b.html b/data/artifacts/9e458dd990ce/qwen25-7b.html
new file mode 100644
index 0000000..14370a1
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/qwen25-7b.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Shop by Color</title>
+ <style>
+ :root {
+ --bg: #17171c;
+ --surface: #f5f2ea;
+ --text: #3a2c22;
+ --muted: #8d7bb0;
+ --accent: #c9a961;
+ --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);
+ }
+ * {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ font-family: 'Didot', Georgia, serif;
+ }
+ body {
+ background-color: var(--bg);
+ color: var(--text);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ }
+ header {
+ display: flex;
+ align-items: center;
+ padding: 32px;
+ background-color: rgba(255,255,255,.2);
+ color: var(--text);
+ font-size: 48px;
+ letter-spacing: .18em;
+ }
+ #colorWheel {
+ width: 500px;
+ height: 500px;
+ background-color: hsl(0, 0%, 96%);
+ border-radius: 50%;
+ position: relative;
+ overflow: hidden;
+ cursor: pointer;
+ user-select: none;
+ }
+ .patternStrip {
+ display: flex;
+ justify-content: center;
+ gap: 12px;
+ margin-top: 32px;
+ padding: 8px;
+ background-color: var(--surface);
+ border-radius: 8px;
+ box-shadow: var(--shadow);
+ opacity: 0;
+ }
+ .patternStrip.visible {
+ animation: fadeUp .7s ease-in-out both, ambient 18s linear infinite;
+ }
+ @keyframes fadeUp {
+ from { opacity: 0; transform: translateY(28px); }
+ to { opacity: 1; transform: none; }
+ }
+ @keyframes ambient {
+ 0% { background-position: 0%; }
+ 100% { background-position: -9760%; }
+ }
+ </style>
+</head>
+<body>
+ <header>
+ DESIGNER WALLCOVERINGS
+ </header>
+ <div id="colorWheel"></div>
+ <div class="patternStrip" style="animation-delay: 0s; opacity: 1;">
+ <div class="pattern" style="background: conic-gradient(var(--accent) 0deg, transparent 360deg); transform: rotate(0deg);"></div>
+ <div class="pattern" style="background: conic-gradient(var(--accent) 90deg, transparent 270deg); transform: rotate(-90deg);"></div>
+ <div class="pattern" style="background: conic-gradient(var(--accent) 180deg, transparent 180deg); transform: rotate(180deg);"></div>
+ <div class="pattern" style="background: conic-gradient(var(--accent) 270deg, transparent 90deg); transform: rotate(-270deg);"></div>
+ </div>
+</body>
+<script>
+ const colorWheel = document.getElementById('colorWheel');
+ let angle = 0;
+ let patternsVisible = false;
+
+ colorWheel.addEventListener('pointerdown', (e) => {
+ angle += e.movementY / 50;
+ if (!patternsVisible) {
+ document.querySelector('.patternStrip').classList.add('visible');
+ patternsVisible = true;
+ }
+ updatePattern();
+ });
+
+ function updatePattern() {
+ const hue = Math.round((angle % 360) / 90);
+ const patterns = document.querySelectorAll('.pattern');
+ for (let i = 0; i < patterns.length; i++) {
+ const pattern = patterns[i];
+ if ((i + 1) * 4 - 1 === hue || (i + 1) * 4 + 3 === hue) {
+ pattern.style.transform = `rotate(${hue * 90}deg)`;
+ pattern.style.background = `conic-gradient(var(--accent) ${hue * 90}deg, transparent ${(hue + 1) * 90}deg)`;
+ } else {
+ pattern.style.transform = 'rotate(0deg)';
+ pattern.style.background = 'conic-gradient(transparent 360deg)';
+ }
+ }
+ }
+
+ updatePattern();
+</script>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/qwen25-7b.png b/data/artifacts/9e458dd990ce/qwen25-7b.png
new file mode 100644
index 0000000..b0cec11
Binary files /dev/null and b/data/artifacts/9e458dd990ce/qwen25-7b.png differ
diff --git a/data/artifacts/9e458dd990ce/qwen3-14b.html b/data/artifacts/9e458dd990ce/qwen3-14b.html
new file mode 100644
index 0000000..ab56c6e
--- /dev/null
+++ b/data/artifacts/9e458dd990ce/qwen3-14b.html
@@ -0,0 +1,347 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Shop by Color</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);
+ --glow: 0 0 24px rgba(176,71,46,0.35);
+ --font-serif: 'Playfair Display', Georgia, serif;
+ --font-sans: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ }
+
+ * {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ }
+
+ html, body {
+ height: 100%;
+ font-family: var(--font-sans);
+ background-color: var(--bg);
+ color: var(--text);
+ overflow: hidden;
+ }
+
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 64px;
+ padding: 0 32px;
+ background-color: var(--surface);
+ box-shadow: var(--shadow);
+ font-family: var(--font-serif);
+ font-size: 40px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text);
+ display: flex;
+ align-items: center;
+ }
+
+ main {
+ margin-top: 64px;
+ padding: 96px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: calc(100% - 64px);
+ }
+
+ .wheel-container {
+ position: relative;
+ width: 320px;
+ height: 320px;
+ border: 1px solid var(--line);
+ border-radius: 50%;
+ overflow: hidden;
+ cursor: pointer;
+ touch-action: manipulation;
+ }
+
+ .color-wheel {
+ width: 100%;
+ height: 100%;
+ background: conic-gradient(
+ var(--accent) 0deg,
+ #e6d0a1 60deg,
+ #d2c4b0 120deg,
+ #c4b5a3 180deg,
+ #b6a796 240deg,
+ #a89988 300deg,
+ var(--accent) 360deg
+ );
+ transition: transform 0.3s var(--ease);
+ }
+
+ .color-pointer {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 40px;
+ height: 40px;
+ margin-left: -20px;
+ margin-top: -20px;
+ border-radius: 50%;
+ background: var(--text);
+ box-shadow: var(--glow);
+ pointer-events: none;
+ }
+
+ .pattern-gallery {
+ margin-top: 64px;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+ }
+
+ .pattern-card {
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: 14px;
+ overflow: hidden;
+ box-shadow: var(--shadow);
+ transition: transform 0.2s var(--ease);
+ }
+
+ .pattern-card:hover {
+ transform: scale(1.02);
+ }
+
+ .pattern-card svg {
+ width: 100%;
+ height: 100%;
+ display: block;
+ }
+
+ .pattern-name {
+ padding: 16px;
+ font-family: var(--font-serif);
+ font-size: 24px;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: var(--text);
+ }
+
+ .share-bar {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ padding: 16px 32px;
+ background-color: var(--surface);
+ box-shadow: 0 -2px 12px rgba(0,0,0,0.05);
+ font-family: var(--font-sans);
+ font-size: 12px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--muted);
+ display: flex;
+ justify-content: center;
+ gap: 32px;
+ pointer-events: none;
+ }
+
+ .share-bar button {
+ background: none;
+ border: none;
+ color: var(--accent);
+ cursor: pointer;
+ pointer-events: auto;
+ font-weight: bold;
+ }
+
+ .share-bar button:hover {
+ text-shadow: 0 0 4px var(--accent);
+ }
+
+ @keyframes fadeUp {
+ from {
+ opacity: 0;
+ transform: translateY(28px);
+ }
+ to {
+ opacity: 1;
+ transform: none;
+ }
+ }
+
+ .fade-in {
+ animation: fadeUp 0.7s var(--ease) both;
+ }
+ </style>
+</head>
+<body>
+ <header class="fade-in">DESIGNER WALLCOVERINGS</header>
+ <main>
+ <div class="wheel-container">
+ <div class="color-wheel" id="colorWheel"></div>
+ <div class="color-pointer" id="colorPointer"></div>
+ </div>
+ <div class="pattern-gallery" id="patternGallery"></div>
+ </main>
+ <div class="share-bar fade-in">
+ <button>Share</button>
+ <button>Save</button>
+ <button>Copy</button>
+ </div>
+ <script>
+ const wheel = document.getElementById('colorWheel');
+ const pointer = document.getElementById('colorPointer');
+ const patternGallery = document.getElementById('patternGallery');
+
+ let isDragging = false;
+ let startX, startY, startAngle;
+
+ const generatePatterns = (hue) => {
+ patternGallery.innerHTML = '';
+ const colors = [
+ `hsl(${hue}, 60%, 65%)`,
+ `hsl(${hue}, 40%, 55%)`,
+ `hsl(${hue}, 30%, 60%)`,
+ `hsl(${hue}, 50%, 65%)`
+ ];
+
+ const names = [
+ 'Velvet Drizzle',
+ 'Muted Marigold',
+ 'Woolen Whisper',
+ 'Satin Glow'
+ ];
+
+ for (let i = 0; i < 4; i++) {
+ const card = document.createElement('div');
+ card.className = 'pattern-card fade-in';
+
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ svg.setAttribute('viewBox', '0 0 100 100');
+
+ const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ rect.setAttribute('width', '100%');
+ rect.setAttribute('height', '100%');
+ rect.setAttribute('fill', `url(#pattern${i})`);
+
+ const pattern = document.createElementNS('http://www.w3.org/2000/svg', 'pattern');
+ pattern.setAttribute('id', `pattern${i}`);
+ pattern.setAttribute('width', '20');
+ pattern.setAttribute('height', '20');
+
+ const rect1 = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ rect1.setAttribute('width', '10');
+ rect1.setAttribute('height', '10');
+ rect1.setAttribute('x', '0');
+ rect1.setAttribute('y', '0');
+ rect1.setAttribute('fill', colors[i]);
+
+ const rect2 = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ rect2.setAttribute('width', '10');
+ rect2.setAttribute('height', '10');
+ rect2.setAttribute('x', '10');
+ rect2.setAttribute('y', '10');
+ rect2.setAttribute('fill', colors[(i + 1) % 4]);
+
+ pattern.appendChild(rect1);
+ pattern.appendChild(rect2);
+ svg.appendChild(pattern);
+ svg.appendChild(rect);
+
+ card.appendChild(svg);
+
+ const name = document.createElement('div');
+ name.className = 'pattern-name';
+ name.textContent = names[i];
+ card.appendChild(name);
+
+ patternGallery.appendChild(card);
+ }
+ };
+
+ wheel.addEventListener('mousedown', (e) => {
+ isDragging = true;
+ startX = e.clientX;
+ startY = e.clientY;
+ startAngle = getAngleFromPointer();
+ });
+
+ wheel.addEventListener('mousemove', (e) => {
+ if (!isDragging) return;
+ const dx = e.clientX - startX;
+ const dy = e.clientY - startY;
+ const angle = Math.atan2(dy, dx);
+ setPointerAngle(angle);
+ });
+
+ wheel.addEventListener('mouseup', () => {
+ isDragging = false;
+ });
+
+ wheel.addEventListener('touchstart', (e) => {
+ isDragging = true;
+ const touch = e.touches[0];
+ startX = touch.clientX;
+ startY = touch.clientY;
+ startAngle = getAngleFromPointer();
+ });
+
+ wheel.addEventListener('touchmove', (e) => {
+ if (!isDragging) return;
+ const touch = e.touches[0];
+ const dx = touch.clientX - startX;
+ const dy = touch.clientY - startY;
+ const angle = Math.atan2(dy, dx);
+ setPointerAngle(angle);
+ });
+
+ wheel.addEventListener('touchend', () => {
+ isDragging = false;
+ });
+
+ function getAngleFromPointer() {
+ const rect = wheel.getBoundingClientRect();
+ const centerX = rect.left + rect.width / 2;
+ const centerY = rect.top + rect.height / 2;
+ const dx = pointer.offsetLeft - (rect.left + rect.width / 2);
+ const dy = pointer.offsetTop - (rect.top + rect.height / 2);
+ return Math.atan2(dy, dx);
+ }
+
+ function setPointerAngle(angle) {
+ const rect = wheel.getBoundingClientRect();
+ const centerX = rect.left + rect.width / 2;
+ const centerY = rect.top + rect.height / 2;
+ const radius = Math.min(rect.width, rect.height) / 2;
+ const x = centerX + radius * Math.cos(angle);
+ const y = centerY + radius * Math.sin(angle);
+ pointer.style.left = `${x - 20}px`;
+ pointer.style.top = `${y - 20}px`;
+
+ const hue = Math.round((angle + Math.PI) / (2 * Math.PI) * 360);
+ wheel.style.background = `conic-gradient(
+ var(--accent) 0deg,
+ #e6d0a1 60deg,
+ #d2c4b0 120deg,
+ #c4b5a3 180deg,
+ #b6a796 240deg,
+ #a89988 300deg,
+ var(--accent) 360deg
+ )`;
+ generatePatterns(hue);
+ }
+
+ setPointerAngle(0);
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/9e458dd990ce/qwen3-14b.png b/data/artifacts/9e458dd990ce/qwen3-14b.png
new file mode 100644
index 0000000..1a083b8
Binary files /dev/null and b/data/artifacts/9e458dd990ce/qwen3-14b.png differ
diff --git a/data/artifacts/ab0c520893e3/claude-code.html b/data/artifacts/ab0c520893e3/claude-code.html
new file mode 100644
index 0000000..70772b1
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/claude-code.html
@@ -0,0 +1,506 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Motif Memory</title>
+<style>
+ :root{
+ --bg:#f4f1ea;
+ --surface:#ffffff;
+ --surface-2:#faf8f2;
+ --text:#1c1a17;
+ --ink:#1c1a17;
+ --muted:#9b948a;
+ --line:rgba(28,26,23,.12);
+ --hair:rgba(28,26,23,.08);
+ --accent:#9a6a3c; /* antique brass / metallic */
+ --accent-deep:#7d5127;
+ --jewel:#31513c; /* restrained jewel green for pattern variety */
+ --shadow:0 8px 28px rgba(28,26,23,.10);
+ --shadow-hover:0 16px 48px rgba(28,26,23,.18);
+ --ease:cubic-bezier(.22,1,.36,1);
+ --serif:'Cormorant Garamond','Didot','Bodoni MT','Playfair Display',Georgia,serif;
+ --sans:-apple-system,'Segoe UI','Helvetica Neue',Arial,sans-serif;
+ }
+
+ *{box-sizing:border-box;}
+ html,body{margin:0;padding:0;}
+ body{
+ background:
+ radial-gradient(1200px 600px at 80% -10%, rgba(154,106,60,.06), transparent 60%),
+ var(--bg);
+ color:var(--text);
+ font-family:var(--sans);
+ -webkit-font-smoothing:antialiased;
+ min-height:100vh;
+ }
+
+ /* ---------- Top bar / wordmark ---------- */
+ header.topbar{
+ position:fixed;top:0;left:0;right:0;z-index:50;
+ display:flex;align-items:center;justify-content:space-between;
+ gap:24px;
+ padding:18px 32px;
+ background:rgba(244,241,234,.82);
+ backdrop-filter:blur(10px);
+ border-bottom:1px solid var(--line);
+ }
+ .wordmark{
+ font-family:var(--serif);
+ color:var(--ink);
+ font-weight:600;
+ font-size:42px;
+ line-height:1.0;
+ letter-spacing:.18em;
+ text-transform:uppercase;
+ white-space:nowrap;
+ max-width:none;
+ }
+ .wordmark .rule{
+ display:block;
+ font-size:10px;
+ letter-spacing:.42em;
+ color:var(--accent-deep);
+ margin-top:6px;
+ font-family:var(--sans);
+ font-weight:600;
+ }
+ .topstats{
+ display:flex;gap:26px;align-items:center;
+ }
+ .stat{
+ text-align:right;line-height:1.1;
+ }
+ .stat .lbl{
+ display:block;
+ font-size:12px;letter-spacing:.15em;text-transform:uppercase;
+ color:var(--muted);
+ }
+ .stat .val{
+ display:block;
+ font-family:var(--serif);
+ font-size:26px;color:var(--ink);font-weight:600;
+ font-variant-numeric:tabular-nums;
+ margin-top:2px;
+ }
+
+ /* ---------- Layout ---------- */
+ main{
+ max-width:760px;
+ margin:0 auto;
+ padding:150px 24px 96px;
+ animation:fadeUp .7s var(--ease) both;
+ }
+ .intro{ text-align:center; margin-bottom:40px; }
+ .intro h1{
+ font-family:var(--serif);
+ font-weight:600;
+ font-size:44px;
+ letter-spacing:.01em;
+ margin:0 0 10px;
+ color:var(--ink);
+ }
+ .intro p{
+ margin:0 auto;
+ max-width:430px;
+ color:var(--muted);
+ font-size:15px;
+ line-height:1.6;
+ }
+
+ /* ---------- Grid ---------- */
+ .board{
+ display:grid;
+ grid-template-columns:repeat(4,1fr);
+ gap:16px;
+ }
+ .card{
+ position:relative;
+ aspect-ratio:3/4;
+ perspective:1000px;
+ border:none;background:none;padding:0;margin:0;
+ cursor:pointer;
+ animation:fadeUp .6s var(--ease) both;
+ }
+ .card:disabled{cursor:default;}
+ .inner{
+ position:absolute;inset:0;
+ transform-style:preserve-3d;
+ transition:transform .55s var(--ease);
+ }
+ .card.flipped .inner,.card.matched .inner{ transform:rotateY(180deg); }
+ .face{
+ position:absolute;inset:0;
+ -webkit-backface-visibility:hidden;backface-visibility:hidden;
+ border-radius:12px;
+ overflow:hidden;
+ box-shadow:var(--shadow);
+ }
+
+ /* Card back (default) */
+ .back{
+ background:
+ linear-gradient(150deg,var(--surface) 0%,var(--surface-2) 100%);
+ border:1px solid var(--line);
+ display:flex;align-items:center;justify-content:center;
+ transition:box-shadow .2s var(--ease), transform .2s var(--ease);
+ }
+ .card:not(.matched):hover .back{ box-shadow:var(--shadow-hover); }
+ .back::before{
+ content:"";
+ position:absolute;inset:10px;
+ border:1px solid var(--hair);
+ border-radius:8px;
+ }
+ .monogram{
+ font-family:var(--serif);
+ font-size:30px;
+ letter-spacing:.06em;
+ color:var(--accent);
+ position:relative;
+ }
+ .monogram::after{
+ content:"";
+ display:block;
+ width:26px;height:1px;
+ background:var(--accent);
+ opacity:.5;
+ margin:7px auto 0;
+ }
+
+ /* Card front */
+ .front{
+ transform:rotateY(180deg);
+ background:var(--surface);
+ border:1px solid var(--line);
+ display:flex;flex-direction:column;
+ }
+ .swatch{
+ flex:1;
+ margin:8px 8px 0;
+ border-radius:7px;
+ border:1px solid var(--hair);
+ background-color:var(--surface-2);
+ }
+ .caption{
+ padding:9px 6px 11px;
+ text-align:center;
+ font-size:11px;
+ letter-spacing:.14em;
+ text-transform:uppercase;
+ color:var(--muted);
+ }
+ .card.matched .front{
+ border-color:rgba(154,106,60,.45);
+ box-shadow:0 0 0 1px rgba(154,106,60,.25), var(--shadow);
+ }
+ .card.matched .caption{ color:var(--accent-deep); }
+
+ /* ---------- Pattern swatches (CSS motifs) ---------- */
+ /* Damask — ornate layered radials */
+ .m-damask{
+ background-color:#f2ece0;
+ background-image:
+ radial-gradient(circle at 50% 20%, var(--accent) 0 3px, transparent 4px),
+ radial-gradient(circle at 50% 50%, transparent 6px, var(--accent) 6px 8px, transparent 9px),
+ radial-gradient(ellipse 8px 14px at 50% 50%, var(--accent-deep) 0 100%, transparent),
+ radial-gradient(circle at 0% 0%, transparent 9px, var(--accent) 9px 11px, transparent 12px),
+ radial-gradient(circle at 100% 100%, transparent 9px, var(--accent) 9px 11px, transparent 12px);
+ background-size:34px 44px;
+ background-position:center;
+ }
+ /* Toile — fine pastoral hatching */
+ .m-toile{
+ background-color:#f6f1e8;
+ background-image:
+ repeating-linear-gradient(30deg, var(--jewel) 0 1px, transparent 1px 7px),
+ repeating-linear-gradient(-30deg, rgba(49,81,60,.35) 0 1px, transparent 1px 9px);
+ }
+ /* Ikat — blurred diamonds */
+ .m-ikat{
+ background-color:#efe7da;
+ background-image:
+ repeating-linear-gradient(45deg, var(--accent-deep) 0 4px, transparent 4px 14px),
+ repeating-linear-gradient(-45deg, var(--accent-deep) 0 4px, transparent 4px 14px);
+ filter:blur(.4px);
+ }
+ /* Chinoiserie — delicate floral grid */
+ .m-chinoiserie{
+ background-color:#eef1ea;
+ background-image:
+ radial-gradient(circle at 50% 50%, var(--jewel) 0 2px, transparent 3px),
+ radial-gradient(circle at 50% 50%, transparent 5px, rgba(49,81,60,.5) 5px 6px, transparent 7px),
+ radial-gradient(circle at 0 50%, var(--accent) 0 1.5px, transparent 2px),
+ radial-gradient(circle at 100% 50%, var(--accent) 0 1.5px, transparent 2px);
+ background-size:26px 26px;
+ }
+ /* Trellis — crossed lattice */
+ .m-trellis{
+ background-color:#f4eee2;
+ background-image:
+ repeating-linear-gradient(45deg, var(--accent) 0 1.5px, transparent 1.5px 15px),
+ repeating-linear-gradient(-45deg, var(--accent) 0 1.5px, transparent 1.5px 15px);
+ }
+ /* Fret — Greek key stepped */
+ .m-fret{
+ background-color:#efe8db;
+ background-image:
+ linear-gradient(90deg, var(--ink) 2px, transparent 2px),
+ linear-gradient(0deg, var(--ink) 2px, transparent 2px),
+ linear-gradient(90deg, transparent 6px, var(--ink) 6px 8px, transparent 8px),
+ linear-gradient(0deg, transparent 6px, var(--ink) 6px 8px, transparent 8px);
+ background-size:16px 16px;
+ opacity:.92;
+ }
+ /* Botanical — leaf sprigs */
+ .m-botanical{
+ background-color:#eef0e8;
+ background-image:
+ radial-gradient(ellipse 5px 11px at 30% 30%, var(--jewel) 0 100%, transparent),
+ radial-gradient(ellipse 5px 11px at 70% 70%, var(--jewel) 0 100%, transparent),
+ radial-gradient(circle at 50% 50%, var(--accent-deep) 0 1.5px, transparent 2px);
+ background-size:30px 30px;
+ }
+ /* Stripe — refined regency stripe */
+ .m-stripe{
+ background-color:#f5efe3;
+ background-image:
+ repeating-linear-gradient(90deg,
+ var(--accent) 0 3px,
+ transparent 3px 9px,
+ var(--accent-deep) 9px 10px,
+ transparent 10px 16px);
+ }
+
+ /* ---------- Controls ---------- */
+ .controls{
+ display:flex;justify-content:center;gap:14px;margin-top:36px;
+ }
+ .btn{
+ font-family:var(--sans);
+ font-size:12px;letter-spacing:.15em;text-transform:uppercase;
+ color:var(--ink);
+ background:var(--surface);
+ border:1px solid var(--line);
+ border-radius:999px;
+ padding:13px 30px;
+ cursor:pointer;
+ transition:all .2s var(--ease);
+ }
+ .btn:hover{ border-color:var(--accent); color:var(--accent-deep); box-shadow:var(--shadow); }
+ .btn.primary{
+ background:var(--ink);color:var(--surface);border-color:var(--ink);
+ }
+ .btn.primary:hover{ background:var(--accent-deep);border-color:var(--accent-deep);color:#fff; }
+
+ /* ---------- Win overlay ---------- */
+ .overlay{
+ position:fixed;inset:0;z-index:100;
+ 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:fadeIn .4s var(--ease) both; }
+ .modal{
+ background:var(--surface);
+ border:1px solid var(--line);
+ border-radius:16px;
+ box-shadow:var(--shadow-hover);
+ max-width:420px;width:100%;
+ padding:48px 40px;
+ text-align:center;
+ animation:fadeUp .6s var(--ease) both;
+ }
+ .modal .eyebrow{
+ font-size:12px;letter-spacing:.28em;text-transform:uppercase;color:var(--accent-deep);
+ }
+ .modal h2{
+ font-family:var(--serif);font-weight:600;font-size:40px;margin:12px 0 8px;color:var(--ink);
+ }
+ .modal p{ color:var(--muted);font-size:15px;margin:0 0 26px;line-height:1.6; }
+ .result{
+ display:flex;justify-content:center;gap:40px;margin:0 0 30px;
+ }
+ .result .val{ font-family:var(--serif);font-size:34px;color:var(--ink);font-variant-numeric:tabular-nums; }
+ .result .lbl{ display:block;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin-top:4px; }
+ .modal .divider{ width:44px;height:1px;background:var(--accent);opacity:.5;margin:0 auto 26px; }
+
+ @keyframes fadeUp{from{opacity:0;transform:translateY(24px);}to{opacity:1;transform:none;}}
+ @keyframes fadeIn{from{opacity:0;}to{opacity:1;}}
+
+ @media(max-width:560px){
+ header.topbar{padding:14px 18px;}
+ .wordmark{font-size:26px;letter-spacing:.14em;white-space:normal;line-height:1.15;}
+ .topstats{gap:16px;}
+ .stat .val{font-size:20px;}
+ main{padding:170px 16px 64px;}
+ .intro h1{font-size:32px;}
+ .board{gap:11px;}
+ }
+</style>
+</head>
+<body>
+
+ <header class="topbar">
+ <div class="wordmark">
+ Designer Wallcoverings
+ <span class="rule">The Motif Memory Salon</span>
+ </div>
+ <div class="topstats">
+ <div class="stat"><span class="lbl">Moves</span><span class="val" id="moves">0</span></div>
+ <div class="stat"><span class="lbl">Pairs</span><span class="val" id="pairs">0 / 8</span></div>
+ <div class="stat"><span class="lbl">Time</span><span class="val" id="time">0:00</span></div>
+ </div>
+ </header>
+
+ <main>
+ <div class="intro">
+ <h1>Match the Motif</h1>
+ <p>Eight of our house patterns, hidden in pairs. Turn the cards to reunite each design — Damask to Damask, Toile to Toile.</p>
+ </div>
+
+ <div class="board" id="board" aria-label="Memory game board"></div>
+
+ <div class="controls">
+ <button class="btn primary" id="restart">Restart</button>
+ </div>
+ </main>
+
+ <div class="overlay" id="overlay">
+ <div class="modal">
+ <span class="eyebrow">Beautifully Done</span>
+ <h2>A Perfect Match</h2>
+ <div class="divider"></div>
+ <p>Every motif reunited. Your collector's eye is impeccable.</p>
+ <div class="result">
+ <div><span class="val" id="win-moves">0</span><span class="lbl">Moves</span></div>
+ <div><span class="val" id="win-time">0:00</span><span class="lbl">Time</span></div>
+ </div>
+ <button class="btn primary" id="play-again">Play Again</button>
+ </div>
+ </div>
+
+<script>
+ const MOTIFS = [
+ { name:'Damask', cls:'m-damask' },
+ { name:'Toile', cls:'m-toile' },
+ { name:'Ikat', cls:'m-ikat' },
+ { name:'Chinoiserie', cls:'m-chinoiserie' },
+ { name:'Trellis', cls:'m-trellis' },
+ { name:'Fret', cls:'m-fret' },
+ { name:'Botanical', cls:'m-botanical' },
+ { name:'Stripe', cls:'m-stripe' },
+ ];
+
+ const board = document.getElementById('board');
+ const movesEl = document.getElementById('moves');
+ const pairsEl = document.getElementById('pairs');
+ const timeEl = document.getElementById('time');
+ const overlay = document.getElementById('overlay');
+
+ let deck = [], flipped = [], matched = 0, moves = 0, locked = false;
+ let timer = null, seconds = 0, started = false;
+
+ function shuffle(a){
+ 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 fmt(s){
+ const m = Math.floor(s/60);
+ const sec = String(s%60).padStart(2,'0');
+ return m + ':' + sec;
+ }
+
+ function startTimer(){
+ if(started) return;
+ started = true;
+ timer = setInterval(()=>{ seconds++; timeEl.textContent = fmt(seconds); }, 1000);
+ }
+
+ function build(){
+ clearInterval(timer);
+ deck = shuffle(MOTIFS.concat(MOTIFS).map((m,i)=>({ ...m, key:i })));
+ flipped = []; matched = 0; moves = 0; locked = false;
+ seconds = 0; started = false;
+ movesEl.textContent = '0';
+ pairsEl.textContent = '0 / 8';
+ timeEl.textContent = '0:00';
+ overlay.classList.remove('show');
+
+ board.innerHTML = '';
+ deck.forEach((card, idx)=>{
+ const btn = document.createElement('button');
+ btn.className = 'card';
+ btn.style.animationDelay = (idx*45) + 'ms';
+ btn.dataset.name = card.name;
+ btn.dataset.index = idx;
+ btn.setAttribute('aria-label','Hidden card');
+ btn.innerHTML =
+ '<div class="inner">' +
+ '<div class="face back"><span class="monogram">DW</span></div>' +
+ '<div class="face front">' +
+ '<div class="swatch ' + card.cls + '"></div>' +
+ '<div class="caption">' + card.name + '</div>' +
+ '</div>' +
+ '</div>';
+ btn.addEventListener('click', ()=>onFlip(btn));
+ board.appendChild(btn);
+ });
+ }
+
+ function onFlip(btn){
+ if(locked) return;
+ if(btn.classList.contains('flipped') || btn.classList.contains('matched')) return;
+
+ startTimer();
+ btn.classList.add('flipped');
+ flipped.push(btn);
+
+ if(flipped.length === 2){
+ moves++;
+ movesEl.textContent = moves;
+ locked = true;
+ const [a,b] = flipped;
+ if(a.dataset.name === b.dataset.name){
+ setTimeout(()=>{
+ a.classList.add('matched');
+ b.classList.add('matched');
+ a.classList.remove('flipped');
+ b.classList.remove('flipped');
+ flipped = [];
+ locked = false;
+ matched++;
+ pairsEl.textContent = matched + ' / 8';
+ if(matched === 8) win();
+ }, 480);
+ } else {
+ setTimeout(()=>{
+ a.classList.remove('flipped');
+ b.classList.remove('flipped');
+ flipped = [];
+ locked = false;
+ }, 850);
+ }
+ }
+ }
+
+ function win(){
+ clearInterval(timer);
+ document.getElementById('win-moves').textContent = moves;
+ document.getElementById('win-time').textContent = fmt(seconds);
+ setTimeout(()=> overlay.classList.add('show'), 400);
+ }
+
+ document.getElementById('restart').addEventListener('click', build);
+ document.getElementById('play-again').addEventListener('click', build);
+
+ build();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/claude-code.png b/data/artifacts/ab0c520893e3/claude-code.png
new file mode 100644
index 0000000..5fe2d83
Binary files /dev/null and b/data/artifacts/ab0c520893e3/claude-code.png differ
diff --git a/data/artifacts/ab0c520893e3/gemma3-12b.html b/data/artifacts/ab0c520893e3/gemma3-12b.html
new file mode 100644
index 0000000..0f22d43
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/gemma3-12b.html
@@ -0,0 +1,342 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Design Motifs Memory Game</title>
+ <style>
+ :root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e;
+ --line: #ddd;
+ --shadow: rgba(0, 0, 0, 0.12);
+ --ease: cubic-bezier(.22,1,.36,1);
+ }
+
+ body {
+ font-family: system-ui, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ margin: 0;
+ background-color: var(--bg);
+ color: var(--text);
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ }
+
+ header {
+ background-color: var(--surface);
+ padding: 24px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
+ display: flex;
+ align-items: center;
+ }
+
+ header h1 {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 67px;
+ letter-spacing: .18em;
+ margin: 0;
+ line-height: 1.2; /* Improved vertical rhythm */
+ text-align: left;
+ }
+
+ .game-container {
+ padding: 96px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .card-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+ width: 100%;
+ max-width: calc(100% - 96px); /* Adjust for padding */
+ }
+
+ .card {
+ width: 100%;
+ height: auto;
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: 0 8px 24px var(--shadow);
+ transition: transform .3s ease, box-shadow .3s ease;
+ overflow: hidden; /* Ensure content doesn't overflow */
+ position: relative;
+ }
+
+ .card:hover {
+ box-shadow: 0 16px 48px var(--shadow);
+ transform: scale(1.05);
+ }
+
+ .card img {
+ width: 100%;
+ height: auto;
+ display: block; /* Remove extra space below image */
+ }
+
+
+ .flipped {
+ transform: rotateY(-180deg);
+ box-shadow: none;
+ }
+
+ .matched {
+ opacity: 0;
+ }
+
+ .score-board {
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ max-width: calc(100% - 96px);
+ margin-top: 24px;
+ }
+
+ .score-text, .moves-text {
+ font-family: system-ui, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ font-size: 12px;
+ color: var(--muted);
+ }
+
+ .win-screen, .game-over-screen {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(255, 255, 255, 0.9);
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+ }
+
+ .win-screen h2, .game-over-screen h2 {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 38px;
+ margin-bottom: 24px;
+ }
+
+ .restart-button, .ok-button {
+ padding: 16px 32px;
+ background-color: var(--accent);
+ color: var(--surface);
+ border: none;
+ border-radius: 8px;
+ cursor: pointer;
+ font-family: system-ui, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ font-size: 12px;
+
+ }
+
+
+ </style>
+</head>
+<body>
+
+ <header>
+ <h1>DESIGNER WALLCOVERINGS</h1>
+ </header>
+
+ <div class="game-container">
+ <div class="card-grid" id="cardGrid">
+ </div>
+
+ <div class="score-board" id="scoreboard">
+ <span class="score-text">Score: <span id="score">0</span></span>
+ <span class="moves-text">Moves: <span id="moves">0</span></span>
+ </div>
+ </div>
+
+
+
+ <div class="win-screen" id="winScreen">
+ <h2>Congratulations! You Win</h2>
+ <button class="restart-button" onclick="restartGame()">Restart</button>
+ </div>
+
+ <div class="game-over-screen" id="gameOverScreen">
+ <h2>Game Over</h2>
+ <button class="ok-button" onclick="restartGame()">Restart</button>
+ </div>
+
+
+ <script>
+ const motifs = [
+ 'damask', 'toile', 'ikat', 'chinoiserie', 'trellis', 'fret', 'botanical', 'stripe'
+ ];
+
+ const cardGridElement = document.getElementById('cardGrid');
+ const scoreElement = document.getElementById('score');
+ const movesElement = document.getElementById('moves');
+ const winScreenElement = document.getElementById('winScreen');
+ const gameOverScreenElement = document.getElementById('gameOverScreen');
+
+ let cards = [];
+ let flippedCard = null;
+ let matchedCards = 0;
+ let score = 0;
+ let moves = 0;
+ let gameTimer;
+
+
+ function shuffleArray(array) {
+ for (let i = array.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [array[i], array[j]] = [array[j], array[i]];
+ }
+ }
+
+ function createCard(motif) {
+ const cardElement = document.createElement('div');
+ cardElement.classList.add('card');
+ cardElement.dataset.motif = motif;
+
+
+ const imgElement = document.createElement('img');
+ // Use CSS patterns instead of images to fulfill no-external-resource requirement
+ switch (motif) {
+ case 'damask':
+ imgElement.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg width=\\\"100\\\" height=\\\"100\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"%3E%3Cdefs%3E%3Cpattern id=\\\"damask-pattern\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"5\\\" height=\\\"5\\\" patternUnits=\\\"userSpaceOnUse\\\"%3E%3Crect width=\\\"5\\\" height=\\\"5\\\" fill=\\'#f5f2ea\\'/%3E%3Crect x=\\\"5\\\" y=\\\"5\\\" width=\\\"5\\\" height=\\\"5\\\" fill=\\'#1c1a17\\'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=\\\"100\\\" height=\\\"100\\\" fill=\\\"url(%23damask-pattern)\\\"%3E%3C/rect%3E%3C/svg%22)');
+ break;
+ case 'toile':
+ imgElement.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg width=\\\"100\\\" height=\\\"100\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"%3E%3Cdefs%3E%3Cpattern id=\\\"toile-pattern\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"10\\\" height=\\\"10\\\" patternUnits=\\\"userSpaceOnUse\\\"%3E%3Crect width=\\\"10\\\" height=\\\"5\\\" fill=\\'#f5f2ea\\'/%3E%3Crect x=\\\"0\\\" y=\\\"5\\\" width=\\\"5\\\" height=\\\"5\\\" fill=\\'#1c1a17\\'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=\\\"100\\\" height=\\\"100\\\" fill=\\\"url(%23toile-pattern)\\\"%3E%3C/rect%3E%3C/svg%22)');
+ break;
+ case 'ikat':
+ imgElement.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg width=\\\"100\\\" height=\\\"100\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"%3E%3Cdefs%3E%3Cpattern id=\\\"ikat-pattern\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"8\\\" height=\\\"8\\\" patternUnits=\\\"userSpaceOnUse\\\"%3E%3Crect width=\\\"4\\\" height=\\\"4\\\" fill=\\'#f5f2ea\\'/%3E%3Crect x=\\\"4\\\" y=\\\"0\\\" width=\\\"4\\\" height=\\\"4\\\" fill=\\'#1c1a17\\'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=\\\"100\\\" height=\\\"100\\\" fill=\\\"url(%23ikat-pattern)\\\"%3E%3C/rect%3E%3C/svg%22)');
+ break;
+
+ case 'chinoiserie':
+ imgElement.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg width=\\\"100\\\" height=\\\"100\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"%3E%3Cdefs%3E%3Cpattern id=\\\"chinoiserie-pattern\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"12\\\" height=\\\"12\\\" patternUnits=\\\"userSpaceOnUse\\\"%3E%3Crect width=\\\"6\\\" height=\\\"6\\\" fill=\\'#f5f2ea\\'/%3E%3Ccircle cx=\\\"3\\\" cy=\\\"3\\\" r=\\\"2.5\\\" fill=\\'#1c1a17\\'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=\\\"100\\\" height=\\\"100\\\" fill=\\\"url(%23chinoiserie-pattern)\\\"%3E%3C/rect%3E%3C/svg%22)');
+ break;
+
+ case 'trellis':
+ imgElement.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg width=\\\"100\\\" height=\\\"100\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"%3E%3Cdefs%3E%3Cpattern id=\\\"trellis-pattern\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"16\\\" height=\\\"16\\\" patternUnits=\\\"userSpaceOnUse\\\"%3E%3Crect width=\\\"8\\\" height=\\\"8\\\" fill=\\'#f5f2ea\\'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=\\\"100\\\" height=\\\"100\\\" fill=\\\"url(%23trellis-pattern)\\\"%3E%3C/rect%3E%3C/svg%22)');
+ break;
+
+ case 'fret':
+ imgElement.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg width=\\\"100\\\" height=\\\"100\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"%3E%3Cdefs%3E%3Cpattern id=\\\"fret-pattern\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"8\\\" height=\\\"8\\\" patternUnits=\\\"userSpaceOnUse\\\"%3E%3Crect width=\\\"4\\\" height=\\\"4\\\" fill=\\'#f5f2ea\\'/%3E%3Crect x=\\\"4\\\" y=\\\"4\\\" width=\\\"4\\\" height=\\\"4\\\" fill=\\'#1c1a17\\'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=\\\"100\\\" height=\\\"100\\\" fill=\\\"url(%23fret-pattern)\\\"%3E%3C/rect%3E%3C/svg%22)");
+ break;
+
+ case 'botanical':
+ imgElement.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg width=\\\"100\\\" height=\\\"100\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"%3E%3Cdefs%3E%3Cpattern id=\\\"botanical-pattern\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"16\\\" height=\\\"16\\\" patternUnits=\\\"userSpaceOnUse\\\"%3E%3Ccircle cx=\\\"4\\\" cy=\\\"4\\\" r=\\\"2\\\" fill=\\'#f5f2ea\\'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=\\\"100\\\" height=\\\"100\\\" fill=\\\"url(%23botanical-pattern)\\\"%3E%3C/rect%3E%3C/svg%22)");
+ break;
+
+ case 'stripe':
+ imgElement.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg width=\\\"100\\\" height=\\\"100\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"%3E%3Cdefs%3E%3Cpattern id=\\\"stripe-pattern\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"8\\\" height=\\\"8\\\" patternUnits=\\\"userSpaceOnUse\\\"%3E%3Crect width=\\\"8\\\" height=\\\"4\\\" fill=\\'#f5f2ea\\'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=\\\"100\\\" height=\\\"100\\\" fill=\\\"url(%23stripe-pattern)\\\"%3E%3C/rect%3E%3C/svg%22)");
+ break;
+
+ }
+
+
+ cardElement.appendChild(imgElement);
+ return cardElement;
+ }
+
+
+
+ function initializeGame() {
+ cards = motifs.slice().concat(motifs.slice()).map(createCard); // Duplicate motifs for matching pairs
+
+ shuffleArray(cards);
+
+ cards.forEach(card => {
+ cardGridElement.appendChild(card);
+ });
+
+
+ startTimer();
+ }
+
+
+
+ function startTimer() {
+ let seconds = 0;
+ gameTimer = setInterval(() => {
+ seconds++;
+ score +=10;
+
+ scoreElement.textContent = score;
+ }, 1000);
+ }
+
+
+ function flipCard(e) {
+ const card = e.target.closest('.card');
+ if (!card || card.classList.contains('matched') || card.classList.contains('flipped')) return;
+
+ card.classList.add('flipped');
+
+ if (flippedCard === null) {
+ flippedCard = card;
+ } else {
+ if (card.dataset.motif === flippedCard.dataset.motif) {
+ card.classList.add('matched');
+ flippedCard.classList.add('matched');
+ matchedCards++;
+ flippedCard = null;
+
+ if (matchedCards === cards.length / 2) {
+ clearInterval(gameTimer);
+ showWinScreen();
+ }
+
+
+ } else {
+ setTimeout(() => {
+ card.classList.remove('flipped');
+ flippedCard.classList.remove('flipped');
+ flippedCard = null;
+ }, 500);
+ }
+ moves++;
+ movesElement.textContent = moves;
+
+ }
+ }
+
+
+
+ function showWinScreen() {
+ winScreenElement.style.display = 'flex';
+
+
+ }
+
+ function restartGame() {
+ clearInterval(gameTimer);
+ score = 0;
+ moves = 0;
+ matchedCards = 0;
+ scoreElement.textContent = score;
+ movesElement.textContent = moves;
+ winScreenElement.style.display = 'none';
+ gameOverScreenElement.style.display = 'none';
+
+ cardGridElement.innerHTML = '';
+ cards = [];
+
+ initializeGame();
+ }
+
+
+ initializeGame();
+
+ cardGridElement.addEventListener('click', flipCard);
+
+
+
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/gemma3-12b.png b/data/artifacts/ab0c520893e3/gemma3-12b.png
new file mode 100644
index 0000000..73c81fd
Binary files /dev/null and b/data/artifacts/ab0c520893e3/gemma3-12b.png differ
diff --git a/data/artifacts/ab0c520893e3/gpt.html b/data/artifacts/ab0c520893e3/gpt.html
new file mode 100644
index 0000000..1dec8ad
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/gpt.html
@@ -0,0 +1,1127 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<title>Designer Wallcoverings — Motif Memory</title>
+<style>
+:root {
+ /* Design tokens */
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-soft: #1f2026;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961; /* metallic gold */
+ --accent-soft: #7d6a45;
+ --line: rgba(201, 169, 97, 0.35);
+ --shadow-soft: 0 18px 40px rgba(0, 0, 0, 0.65);
+ --shadow-subtle: 0 1px 0 rgba(255, 255, 255, 0.07), 0 0 0 1px rgba(0, 0, 0, 0.85);
+ --radius-card: 14px;
+ --radius-pill: 999px;
+ --grid-gap: 18px;
+
+ --font-display: "Playfair Display", "Bodoni MT", "Didot", Georgia, serif;
+ --font-sans: "Avenir Next", "Century Gothic", "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
+
+ --fs-display: 50px;
+ --fs-h1: 38px;
+ --fs-h2: 28px;
+ --fs-body: 16px;
+ --fs-label: 11px;
+
+ --ease-swift: cubic-bezier(.22,.9,.24,1);
+ --ease-hero: cubic-bezier(.22,1,.36,1);
+
+ --tile-size: 120px;
+}
+
+/* HyperFrames entrancess */
+@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);}
+}
+
+/* Global layout */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html, body {
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ font-family: var(--font-sans);
+ background: radial-gradient(circle at top left, #22222a 0, var(--bg) 48%, #050507 100%);
+ color: var(--text);
+ -webkit-font-smoothing: antialiased;
+}
+
+.app-shell {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+}
+
+/* Header / wordmark */
+header.app-header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 20;
+ backdrop-filter: blur(16px);
+ background:
+ linear-gradient(to bottom, rgba(0,0,0,0.88), rgba(0,0,0,0.92));
+ border-bottom: 1px solid rgba(255,255,255,0.05);
+ box-shadow: 0 14px 35px rgba(0,0,0,0.8);
+}
+
+.header-inner {
+ max-width: 1120px;
+ margin: 0 auto;
+ padding: 18px 28px 14px;
+ display: flex;
+ align-items: flex-end;
+ justify-content: space-between;
+ gap: 24px;
+}
+
+.wordmark {
+ font-family: var(--font-display);
+ font-size: 40px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text); /* darkest ink token */
+ line-height: 1.08;
+ white-space: normal;
+}
+
+.wordmark span {
+ display: block;
+}
+
+.wordmark span:first-child {
+ letter-spacing: 0.2em;
+}
+
+.header-meta {
+ display: flex;
+ gap: 18px;
+ align-items: flex-end;
+ font-family: var(--font-sans);
+}
+
+.header-meta .label-block {
+ text-align: right;
+}
+
+.label-title {
+ font-size: var(--fs-label);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 4px;
+}
+
+.game-quick-meta {
+ font-size: 13px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--accent);
+}
+
+/* Main content */
+main {
+ flex: 1;
+ display: flex;
+ align-items: stretch;
+ justify-content: center;
+}
+
+.main-inner {
+ max-width: 1120px;
+ margin: 0 auto;
+ padding: 120px 28px 40px;
+ display: grid;
+ grid-template-columns: minmax(0, 1.1fr) minmax(280px, 0.8fr);
+ gap: 40px;
+ align-items: flex-start;
+}
+
+@media (max-width: 860px) {
+ .main-inner {
+ grid-template-columns: minmax(0, 1fr);
+ padding-top: 132px;
+ }
+ .header-inner {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+ .header-meta {
+ width: 100%;
+ justify-content: space-between;
+ }
+}
+
+@media (max-width: 540px) {
+ :root {
+ --tile-size: 92px;
+ }
+ .main-inner {
+ padding: 120px 18px 28px;
+ }
+ .wordmark {
+ font-size: 34px;
+ }
+}
+
+/* Left column / board */
+.board-panel {
+ background: radial-gradient(circle at top left, rgba(255,255,255,0.04), rgba(0,0,0,0.9));
+ border-radius: 22px;
+ padding: 22px 22px 24px;
+ box-shadow: var(--shadow-soft);
+ border: 1px solid rgba(255,255,255,0.03);
+ position: relative;
+ overflow: hidden;
+}
+
+.board-panel::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(circle at top right, rgba(201,169,97,0.09), transparent 60%);
+ mix-blend-mode: screen;
+ pointer-events: none;
+}
+
+.board-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ gap: 16px;
+ margin-bottom: 16px;
+ position: relative;
+ z-index: 1;
+}
+
+.board-title {
+ font-family: var(--font-display);
+ font-size: var(--fs-h2);
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ color: var(--text);
+}
+
+.board-subtitle {
+ font-size: 13px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* Stats bar */
+.stats-bar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 18px;
+ margin-bottom: 18px;
+ position: relative;
+ z-index: 1;
+}
+
+.stats-group {
+ display: flex;
+ gap: 16px;
+ flex-wrap: wrap;
+}
+
+.stat {
+ min-width: 80px;
+}
+
+.stat-label {
+ font-size: var(--fs-label);
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 2px;
+}
+
+.stat-value {
+ font-size: 18px;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: var(--text);
+}
+
+/* Buttons */
+.button {
+ border-radius: var(--radius-pill);
+ border: 1px solid rgba(201,169,97,0.7);
+ background: radial-gradient(circle at top, rgba(201,169,97,0.28), rgba(0,0,0,0.95));
+ color: var(--text);
+ font-family: var(--font-sans);
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.24em;
+ padding: 8px 22px 9px;
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ box-shadow: 0 0 0 1px rgba(0,0,0,1), 0 10px 22px rgba(0,0,0,0.9);
+ transition:
+ background 220ms var(--ease-swift),
+ transform 220ms var(--ease-swift),
+ box-shadow 220ms var(--ease-swift),
+ border-color 220ms var(--ease-swift);
+}
+
+.button::after {
+ content: "";
+ width: 6px;
+ height: 6px;
+ border-radius: 999px;
+ background: radial-gradient(circle, #f5f2ea, #c9a961);
+ box-shadow: 0 0 8px rgba(201,169,97,0.9);
+}
+
+.button:hover {
+ transform: translateY(-1px);
+ background: radial-gradient(circle at top, rgba(201,169,97,0.5), rgba(0,0,0,0.98));
+ box-shadow: 0 14px 28px rgba(0,0,0,0.95);
+}
+
+.button:active {
+ transform: translateY(0);
+ box-shadow: 0 6px 12px rgba(0,0,0,0.9);
+}
+
+/* Board grid */
+.board-frame {
+ background: radial-gradient(circle at center, rgba(255,255,255,0.03), rgba(0,0,0,0.98));
+ border-radius: 18px;
+ padding: 18px;
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow-subtle);
+ position: relative;
+ z-index: 1;
+ animation: scaleIn 700ms var(--ease-hero) 60ms both;
+}
+
+.board-grid {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, var(--tile-size)));
+ grid-auto-rows: var(--tile-size);
+ gap: var(--grid-gap);
+ justify-content: center;
+}
+
+@media (max-width: 540px) {
+ .board-grid {
+ gap: 12px;
+ }
+}
+
+/* Card */
+.card {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ perspective: 980px;
+}
+
+.card-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ border-radius: var(--radius-card);
+ transform-style: preserve-3d;
+ transition: transform 560ms var(--ease-swift), box-shadow 560ms var(--ease-swift), border-color 280ms var(--ease-swift);
+ cursor: pointer;
+ box-shadow: 0 14px 30px rgba(0,0,0,0.9);
+}
+
+.card.is-flipped .card-inner,
+.card.is-matched .card-inner {
+ transform: rotateY(180deg) translateZ(0);
+}
+
+.card.is-matched .card-inner {
+ box-shadow: 0 18px 40px rgba(0,0,0,0.95), 0 0 0 1px rgba(201,169,97,0.7);
+}
+
+.card-face {
+ position: absolute;
+ inset: 0;
+ backface-visibility: hidden;
+ border-radius: var(--radius-card);
+ overflow: hidden;
+}
+
+/* Card back */
+.card-back {
+ background:
+ radial-gradient(circle at 10% 0, rgba(255,255,255,0.12), transparent 48%),
+ radial-gradient(circle at 80% 120%, rgba(201,169,97,0.3), rgba(125,106,69,0.65)),
+ linear-gradient(135deg, #15151a, #111117);
+ border: 1px solid rgba(201,169,97,0.45);
+ position: relative;
+}
+
+.card-back::before {
+ content: "";
+ position: absolute;
+ inset: 14%;
+ border-radius: 10px;
+ border: 1px solid rgba(245,242,234,0.12);
+ background:
+ linear-gradient(135deg, rgba(245,242,234,0.06), rgba(13,13,15,0.4));
+ box-shadow: inset 0 0 0 1px rgba(0,0,0,0.65);
+}
+
+.card-back::after {
+ content: "";
+ position: absolute;
+ inset: 32%;
+ border-radius: 50%;
+ border: 1px solid rgba(201,169,97,0.65);
+ box-shadow:
+ 0 0 16px rgba(201,169,97,0.5),
+ inset 0 0 16px rgba(0,0,0,0.9);
+}
+
+/* Card front */
+.card-front {
+ transform: rotateY(180deg);
+ background: var(--surface);
+ border: 1px solid rgba(255,255,255,0.04);
+ display: flex;
+ align-items: stretch;
+ justify-content: stretch;
+}
+
+.card-swatch {
+ position: relative;
+ flex: 1;
+ border-radius: calc(var(--radius-card) - 2px);
+ overflow: hidden;
+ box-shadow: inset 0 0 0 1px rgba(0,0,0,0.75);
+}
+
+/* Frame / highlight for front */
+.card-swatch::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ border-radius: inherit;
+ border: 1px solid rgba(245,242,234,0.05);
+ mix-blend-mode: screen;
+ pointer-events: none;
+}
+
+/* Individual motifs */
+/* 1. Damask – ornate vertical motifs */
+.pattern-damask {
+ background-color: #141319;
+ background-image:
+ radial-gradient(circle at 25% 20%, rgba(201,169,97,0.6) 0, rgba(201,169,97,0) 48%),
+ radial-gradient(circle at 75% 80%, rgba(201,169,97,0.45) 0, rgba(201,169,97,0) 55%),
+ radial-gradient(circle at 50% 50%, rgba(245,242,234,0.08) 0, rgba(245,242,234,0) 60%),
+ radial-gradient(circle at 0 0, rgba(0,0,0,0.75) 0, transparent 60%);
+ background-size: 120px 120px;
+ background-repeat: repeat;
+ mask-image:
+ radial-gradient(circle at 20% 20%, #000 0 16%, transparent 18% 100%),
+ radial-gradient(circle at 80% 80%, #000 0 13%, transparent 15% 100%),
+ radial-gradient(circle at 20% 80%, #000 0 10%, transparent 12% 100%),
+ radial-gradient(circle at 80% 20%, #000 0 10%, transparent 12% 100%);
+ mask-size: 120px 120px;
+ mask-repeat: repeat;
+}
+
+/* 2. Toile – scenic linework on ivory */
+.pattern-toile {
+ background-color: #f1ece1;
+ background-image:
+ linear-gradient(120deg, rgba(141,132,112,0.85) 1px, transparent 1px),
+ linear-gradient(300deg, rgba(92,80,65,0.55) 1px, transparent 1px),
+ radial-gradient(circle at 10% 10%, rgba(92,80,65,0.5) 0 1px, transparent 1.2px),
+ radial-gradient(circle at 70% 60%, rgba(92,80,65,0.6) 0 1.3px, transparent 1.5px),
+ radial-gradient(circle at 30% 80%, rgba(92,80,65,0.5) 0 1.1px, transparent 1.4px);
+ background-size:
+ 36px 32px,
+ 46px 40px,
+ 24px 24px,
+ 40px 48px,
+ 32px 32px;
+}
+
+/* 3. Ikat – blurred diamond ikat */
+.pattern-ikat {
+ background-color: #1b1716;
+ background-image:
+ radial-gradient(circle at 25% 0, rgba(201,169,97,0.7) 0 18%, transparent 26%),
+ radial-gradient(circle at 75% 0, rgba(145,132,108,0.85) 0 18%, transparent 26%),
+ radial-gradient(circle at 25% 100%, rgba(245,242,234,0.7) 0 18%, transparent 26%),
+ radial-gradient(circle at 75% 100%, rgba(201,169,97,0.85) 0 18%, transparent 26%);
+ background-size: 64px 64px;
+ background-repeat: repeat;
+ filter: blur(0.4px) contrast(1.05);
+}
+
+/* 4. Chinoiserie – fine branches and blossoms */
+.pattern-chinoiserie {
+ background-color: #151720;
+ background-image:
+ radial-gradient(circle at 10% 70%, rgba(201,169,97,0.45) 0 2px, transparent 3px),
+ radial-gradient(circle at 30% 50%, rgba(245,242,234,0.8) 0 2px, transparent 3px),
+ radial-gradient(circle at 70% 30%, rgba(201,169,97,0.65) 0 2px, transparent 3px),
+ radial-gradient(circle at 85% 80%, rgba(245,242,234,0.7) 0 2px, transparent 3px),
+ linear-gradient(135deg, rgba(115,130,150,0.4) 0 1px, transparent 2px),
+ linear-gradient(225deg, rgba(66,86,104,0.8) 0 1px, transparent 2px);
+ background-size:
+ 46px 60px,
+ 60px 72px,
+ 52px 40px,
+ 76px 80px,
+ 24px 40px,
+ 24px 40px;
+}
+
+/* 5. Trellis – geometric lattice */
+.pattern-trellis {
+ background-color: #111316;
+ background-image:
+ linear-gradient(135deg, transparent 0 48%, rgba(201,169,97,0.75) 49%, transparent 51% 100%),
+ linear-gradient(225deg, transparent 0 48%, rgba(201,169,97,0.75) 49%, transparent 51% 100%);
+ background-size: 32px 32px;
+ box-shadow: inset 0 0 0 1px rgba(201,169,97,0.5);
+}
+
+/* 6. Fret – greek key continuous border */
+.pattern-fret {
+ background-color: #17171c;
+ background-image:
+ repeating-linear-gradient(90deg,
+ rgba(201,169,97,0.8) 0 3px,
+ transparent 3px 9px),
+ repeating-linear-gradient(0deg,
+ rgba(201,169,97,0.8) 0 3px,
+ transparent 3px 9px),
+ linear-gradient(90deg, rgba(0,0,0,0.4), rgba(0,0,0,0.8));
+ background-size:
+ 24px 24px,
+ 24px 24px,
+ 100% 100%;
+ background-position:
+ 0 0,
+ 0 0,
+ 0 0;
+ mask-image:
+ linear-gradient(90deg, transparent 0 14%, #000 14% 86%, transparent 86% 100%),
+ linear-gradient(0deg, transparent 0 14%, #000 14% 86%, transparent 86% 100%);
+ mask-composite: intersect;
+}
+
+/* 7. Botanical – leafy silhouettes */
+.pattern-botanical {
+ background-color: #0f1512;
+ background-image:
+ radial-gradient(circle at 20% 30%, rgba(104,132,98,0.9) 0 18%, transparent 24%),
+ radial-gradient(circle at 60% 10%, rgba(144,167,125,0.85) 0 18%, transparent 24%),
+ radial-gradient(circle at 80% 70%, rgba(78,108,82,0.9) 0 18%, transparent 24%),
+ radial-gradient(circle at 30% 80%, rgba(132,159,130,0.85) 0 18%, transparent 24%);
+ background-size: 90px 90px;
+ background-repeat: repeat;
+}
+
+/* 8. Stripe – crisp tailored stripes */
+.pattern-stripe {
+ background-color: #15171a;
+ background-image:
+ repeating-linear-gradient(90deg,
+ rgba(24,26,32,1) 0 10px,
+ rgba(201,169,97,0.0) 10px 16px,
+ rgba(201,169,97,0.55) 16px 18px,
+ rgba(24,26,32,1) 18px 26px);
+ background-size: 56px 100%;
+}
+
+/* Right column / motif legend */
+.side-panel {
+ position: relative;
+ padding: 18px 18px 20px;
+ border-radius: 20px;
+ background: radial-gradient(circle at top left, rgba(201,169,97,0.05), rgba(11,11,13,0.98));
+ border: 1px solid rgba(255,255,255,0.03);
+ box-shadow: var(--shadow-soft);
+ overflow: hidden;
+}
+
+.side-panel::before {
+ content: "";
+ position: absolute;
+ inset: -40%;
+ background:
+ radial-gradient(circle at 0 0, rgba(201,169,97,0.14), transparent 60%);
+ opacity: 0.9;
+ mix-blend-mode: screen;
+}
+
+.side-panel-inner {
+ position: relative;
+ z-index: 1;
+}
+
+.side-heading {
+ font-family: var(--font-display);
+ font-size: var(--fs-h3);
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ margin-bottom: 6px;
+}
+
+.side-caption {
+ font-size: 14px;
+ line-height: 1.6;
+ color: var(--muted);
+ margin-bottom: 16px;
+ max-width: 36rem;
+}
+
+.motif-list {
+ margin: 0;
+ padding: 10px 0 0;
+ list-style: none;
+ border-top: 1px solid rgba(255,255,255,0.06);
+}
+
+.motif-item {
+ display: grid;
+ grid-template-columns: 54px minmax(0, 1fr);
+ gap: 10px;
+ align-items: center;
+ padding: 10px 0;
+ border-bottom: 1px solid rgba(255,255,255,0.03);
+}
+
+.motif-thumb {
+ width: 54px;
+ height: 54px;
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: 0 8px 18px rgba(0,0,0,0.9);
+ border: 1px solid rgba(255,255,255,0.06);
+}
+
+.motif-thumb-inner {
+ width: 100%;
+ height: 100%;
+}
+
+.motif-name {
+ font-size: 13px;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: var(--text);
+ margin-bottom: 3px;
+}
+
+.motif-note {
+ font-size: 13px;
+ color: var(--muted);
+ line-height: 1.5;
+}
+
+/* Overlay */
+.overlay {
+ position: fixed;
+ inset: 0;
+ display: none;
+ align-items: center;
+ justify-content: center;
+ background: radial-gradient(circle at top, rgba(0,0,0,0.7), rgba(0,0,0,0.95));
+ z-index: 40;
+}
+
+.overlay.is-visible {
+ display: flex;
+ animation: blurIn 600ms var(--ease-hero) both;
+}
+
+.overlay-panel {
+ max-width: 420px;
+ width: 90%;
+ background: radial-gradient(circle at top left, rgba(201,169,97,0.16), rgba(12,12,14,0.98));
+ border-radius: 22px;
+ padding: 26px 26px 22px;
+ border: 1px solid rgba(201,169,97,0.55);
+ box-shadow: 0 26px 60px rgba(0,0,0,0.95);
+ text-align: left;
+ position: relative;
+}
+
+.overlay-panel::before {
+ content:"";
+ position:absolute;
+ inset:10px;
+ border-radius:18px;
+ border:1px solid rgba(245,242,234,0.16);
+ pointer-events:none;
+}
+
+.overlay-kicker {
+ font-size: var(--fs-label);
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 6px;
+}
+
+.overlay-title {
+ font-family: var(--font-display);
+ font-size: var(--fs-h1);
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ margin-bottom: 8px;
+}
+
+.overlay-metrics {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 14px;
+ margin: 14px 0 18px;
+}
+
+.overlay-metric {
+ min-width: 120px;
+}
+
+.overlay-metric-label {
+ font-size: var(--fs-label);
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 4px;
+}
+
+.overlay-metric-value {
+ font-size: 18px;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+}
+
+.overlay-actions {
+ display: flex;
+ justify-content: flex-start;
+ gap: 10px;
+}
+
+/* Utility states */
+.card.disabled {
+ pointer-events: none;
+}
+
+.board-grid.disabled {
+ pointer-events: none;
+ opacity: 0.7;
+}
+
+/* Accessibility helpers */
+.visually-hidden {
+ position: absolute !important;
+ height: 1px;
+ width: 1px;
+ overflow: hidden;
+ clip: rect(1px,1px,1px,1px);
+ white-space: nowrap;
+}
+</style>
+</head>
+<body>
+<div class="app-shell">
+ <header class="app-header">
+ <div class="header-inner">
+ <div class="wordmark" aria-label="Designer Wallcoverings">
+ <span>Designer</span>
+ <span>Wallcoverings</span>
+ </div>
+ <div class="header-meta">
+ <div class="label-block">
+ <div class="label-title">Motif Pairing Game</div>
+ <div class="game-quick-meta">Match eight iconic wallcovering styles</div>
+ </div>
+ </div>
+ </div>
+ </header>
+
+ <main>
+ <div class="main-inner">
+ <section class="board-panel" aria-label="Memory board">
+ <div class="board-header">
+ <h1 class="board-title">Motif Memory</h1>
+ <div class="board-subtitle">Find each pair of patterns</div>
+ </div>
+ <div class="stats-bar">
+ <div class="stats-group">
+ <div class="stat">
+ <div class="stat-label">Moves</div>
+ <div class="stat-value" id="moves">0</div>
+ </div>
+ <div class="stat">
+ <div class="stat-label">Time</div>
+ <div class="stat-value" id="time">0:00</div>
+ </div>
+ </div>
+ <button class="button" id="restartBtn" type="button">
+ Restart
+ </button>
+ </div>
+ <div class="board-frame">
+ <div class="board-grid" id="board" aria-label="Pattern cards" aria-live="polite">
+ <!-- Cards injected by JS -->
+ </div>
+ </div>
+ </section>
+
+ <aside class="side-panel" aria-label="Motif legend">
+ <div class="side-panel-inner">
+ <h2 class="side-heading">The Motifs</h2>
+ <p class="side-caption">
+ Each pair represents a classic wallcovering language. Let the patterns guide you — gold lattice, blurred ikats, scenic toiles, and more.
+ </p>
+ <ul class="motif-list">
+ <li class="motif-item">
+ <div class="motif-thumb">
+ <div class="motif-thumb-inner pattern-damask"></div>
+ </div>
+ <div>
+ <div class="motif-name">Damask</div>
+ <div class="motif-note">Ornate mirrored medallions and scrolling forms.</div>
+ </div>
+ </li>
+ <li class="motif-item">
+ <div class="motif-thumb">
+ <div class="motif-thumb-inner pattern-toile"></div>
+ </div>
+ <div>
+ <div class="motif-name">Toile</div>
+ <div class="motif-note">Fine pastoral vignettes on warm ivory grounds.</div>
+ </div>
+ </li>
+ <li class="motif-item">
+ <div class="motif-thumb">
+ <div class="motif-thumb-inner pattern-ikat"></div>
+ </div>
+ <div>
+ <div class="motif-name">Ikat</div>
+ <div class="motif-note">Soft-edged diamonds and blurred dye transitions.</div>
+ </div>
+ </li>
+ <li class="motif-item">
+ <div class="motif-thumb">
+ <div class="motif-thumb-inner pattern-chinoiserie"></div>
+ </div>
+ <div>
+ <div class="motif-name">Chinoiserie</div>
+ <div class="motif-note">Delicate branches, blossoms and storybook scrolls.</div>
+ </div>
+ </li>
+ <li class="motif-item">
+ <div class="motif-thumb">
+ <div class="motif-thumb-inner pattern-trellis"></div>
+ </div>
+ <div>
+ <div class="motif-name">Trellis</div>
+ <div class="motif-note">Crisp latticework, garden geometry in metal tones.</div>
+ </div>
+ </li>
+ <li class="motif-item">
+ <div class="motif-thumb">
+ <div class="motif-thumb-inner pattern-fret"></div>
+ </div>
+ <div>
+ <div class="motif-name">Fret</div>
+ <div class="motif-note">Continuous Greek key borders and right-angled turns.</div>
+ </div>
+ </li>
+ <li class="motif-item">
+ <div class="motif-thumb">
+ <div class="motif-thumb-inner pattern-botanical"></div>
+ </div>
+ <div>
+ <div class="motif-name">Botanical</div>
+ <div class="motif-note">Layered foliage silhouettes in deep garden tones.</div>
+ </div>
+ </li>
+ <li class="motif-item">
+ <div class="motif-thumb">
+ <div class="motif-thumb-inner pattern-stripe"></div>
+ </div>
+ <div>
+ <div class="motif-name">Stripe</div>
+ <div class="motif-note">Tailored vertical striping, precise and architectural.</div>
+ </div>
+ </li>
+ </ul>
+ </div>
+ </aside>
+ </div>
+ </main>
+
+ <div class="overlay" id="winOverlay" aria-modal="true" role="dialog" aria-labelledby="overlayTitle" aria-hidden="true">
+ <div class="overlay-panel">
+ <div class="overlay-kicker">Suite Complete</div>
+ <div class="overlay-title" id="overlayTitle">Every Motif Found</div>
+ <p class="side-caption" id="overlayMessage">
+ You paired each pattern in considered style. Timings and moves are below — care to refine your eye once more?
+ </p>
+ <div class="overlay-metrics">
+ <div class="overlay-metric">
+ <div class="overlay-metric-label">Total Time</div>
+ <div class="overlay-metric-value" id="finalTime">0:00</div>
+ </div>
+ <div class="overlay-metric">
+ <div class="overlay-metric-label">Total Moves</div>
+ <div class="overlay-metric-value" id="finalMoves">0</div>
+ </div>
+ </div>
+ <div class="overlay-actions">
+ <button class="button" id="playAgainBtn" type="button">Play Again</button>
+ </div>
+ </div>
+ </div>
+
+ <span class="visually-hidden" id="statusAnnouncer" aria-live="polite"></span>
+</div>
+
+<script>
+(function() {
+ const motifs = [
+ 'damask',
+ 'toile',
+ 'ikat',
+ 'chinoiserie',
+ 'trellis',
+ 'fret',
+ 'botanical',
+ 'stripe'
+ ];
+
+ const motifTitles = {
+ damask: 'Damask',
+ toile: 'Toile',
+ ikat: 'Ikat',
+ chinoiserie: 'Chinoiserie',
+ trellis: 'Trellis',
+ fret: 'Fret',
+ botanical: 'Botanical',
+ stripe: 'Stripe'
+ };
+
+ const boardEl = document.getElementById('board');
+ const movesEl = document.getElementById('moves');
+ const timeEl = document.getElementById('time');
+ const restartBtn = document.getElementById('restartBtn');
+ const winOverlay = document.getElementById('winOverlay');
+ const finalTimeEl = document.getElementById('finalTime');
+ const finalMovesEl = document.getElementById('finalMoves');
+ const playAgainBtn = document.getElementById('playAgainBtn');
+ const announcer = document.getElementById('statusAnnouncer');
+
+ let firstCard = null;
+ let secondCard = null;
+ let lockBoard = false;
+ let moves = 0;
+ let matchesFound = 0;
+ let startTime = null;
+ let timerInterval = null;
+
+ function shuffle(array) {
+ for (let i = array.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [array[i], array[j]] = [array[j], array[i]];
+ }
+ return array;
+ }
+
+ function createBoard() {
+ const motifPairs = motifs.concat(motifs);
+ shuffle(motifPairs);
+ boardEl.innerHTML = '';
+ motifPairs.forEach((motif, index) => {
+ const card = document.createElement('button');
+ card.className = 'card';
+ card.type = 'button';
+ card.dataset.motif = motif;
+ card.setAttribute('aria-label', motifTitles[motif] + ' pattern');
+ card.setAttribute('aria-pressed', 'false');
+
+ const inner = document.createElement('div');
+ inner.className = 'card-inner';
+
+ const back = document.createElement('div');
+ back.className = 'card-face card-back';
+
+ const front = document.createElement('div');
+ front.className = 'card-face card-front';
+
+ const swatch = document.createElement('div');
+ swatch.className = 'card-swatch pattern-' + motif;
+
+ front.appendChild(swatch);
+ inner.appendChild(back);
+ inner.appendChild(front);
+ card.appendChild(inner);
+
+ card.addEventListener('click', () => onCardClick(card));
+
+ boardEl.appendChild(card);
+ });
+ }
+
+ function onCardClick(card) {
+ if (lockBoard || card === firstCard || card.classList.contains('is-matched')) {
+ return;
+ }
+
+ if (!startTime) {
+ startTimer();
+ }
+
+ flipCard(card);
+
+ if (!firstCard) {
+ firstCard = card;
+ return;
+ }
+
+ secondCard = card;
+ lockBoard = true;
+ moves++;
+ movesEl.textContent = moves;
+
+ const isMatch = firstCard.dataset.motif === secondCard.dataset.motif;
+
+ if (isMatch) {
+ markMatched();
+ } else {
+ unflipPair();
+ }
+ }
+
+ function flipCard(card) {
+ card.classList.add('is-flipped');
+ card.setAttribute('aria-pressed', 'true');
+ }
+
+ function unflipPair() {
+ setTimeout(() => {
+ if (firstCard) {
+ firstCard.classList.remove('is-flipped');
+ firstCard.setAttribute('aria-pressed', 'false');
+ }
+ if (secondCard) {
+ secondCard.classList.remove('is-flipped');
+ secondCard.setAttribute('aria-pressed', 'false');
+ }
+ resetTurn();
+ }, 900);
+ }
+
+ function markMatched() {
+ setTimeout(() => {
+ if (firstCard) firstCard.classList.add('is-matched');
+ if (secondCard) secondCard.classList.add('is-matched');
+ matchesFound++;
+ announcer.textContent = motifTitles[firstCard.dataset.motif] + ' pair found.';
+ resetTurn();
+ if (matchesFound === motifs.length) {
+ endGame();
+ }
+ }, 460);
+ }
+
+ function resetTurn() {
+ [firstCard, secondCard] = [null, null];
+ lockBoard = false;
+ }
+
+ function startTimer() {
+ startTime = Date.now();
+ timerInterval = setInterval(updateTimer, 1000);
+ }
+
+ function updateTimer() {
+ if (!startTime) return;
+ const elapsed = Math.floor((Date.now() - startTime) / 1000);
+ const minutes = Math.floor(elapsed / 60);
+ const seconds = elapsed % 60;
+ timeEl.textContent = minutes + ':' + (seconds < 10 ? '0' + seconds : seconds);
+ }
+
+ function stopTimer() {
+ clearInterval(timerInterval);
+ timerInterval = null;
+ }
+
+ function endGame() {
+ stopTimer();
+ finalTimeEl.textContent = timeEl.textContent;
+ finalMovesEl.textContent = moves;
+ winOverlay.classList.add('is-visible');
+ winOverlay.setAttribute('aria-hidden', 'false');
+ }
+
+ function resetGame() {
+ stopTimer();
+ moves = 0;
+ matchesFound = 0;
+ movesEl.textContent = '0';
+ timeEl.textContent = '0:00';
+ startTime = null;
+ firstCard = null;
+ secondCard = null;
+ lockBoard = false;
+ createBoard();
+ }
+
+ restartBtn.addEventListener('click', () => {
+ resetGame();
+ });
+
+ playAgainBtn.addEventListener('click', () => {
+ winOverlay.classList.remove('is-visible');
+ winOverlay.setAttribute('aria-hidden', 'true');
+ resetGame();
+ });
+
+ winOverlay.addEventListener('click', (e) => {
+ if (e.target === winOverlay) {
+ winOverlay.classList.remove('is-visible');
+ winOverlay.setAttribute('aria-hidden', 'true');
+ }
+ });
+
+ // Initialise
+ createBoard();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/gpt.png b/data/artifacts/ab0c520893e3/gpt.png
new file mode 100644
index 0000000..c429f91
Binary files /dev/null and b/data/artifacts/ab0c520893e3/gpt.png differ
diff --git a/data/artifacts/ab0c520893e3/grok.html b/data/artifacts/ab0c520893e3/grok.html
new file mode 100644
index 0000000..0682bcf
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/grok.html
@@ -0,0 +1,765 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Motif Memory</title>
+<style>
+:root {
+ --bg: #f3efe6;
+ --surface: #faf7f0;
+ --ink: #1c1a17;
+ --muted: #7a7468;
+ --accent: #b8954a;
+ --accent-soft: rgba(184, 149, 74, 0.18);
+ --line: rgba(28, 26, 23, 0.12);
+ --line-strong: rgba(28, 26, 23, 0.22);
+ --shadow: 0 8px 28px rgba(28, 26, 23, 0.08), 0 2px 6px rgba(28, 26, 23, 0.04);
+ --shadow-lift: 0 16px 40px rgba(28, 26, 23, 0.14), 0 4px 12px rgba(28, 26, 23, 0.06);
+ --ease: cubic-bezier(.22, .9, .24, 1);
+ --ease-out: cubic-bezier(.22, 1, .36, 1);
+ --ease-scene: cubic-bezier(.77, 0, .18, 1);
+ --radius: 4px;
+ --serif: 'Didot', 'Bodoni MT', 'Playfair Display', 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
+ --sans: 'Avenir Next', 'Century Gothic', Futura, 'Helvetica Neue', sans-serif;
+}
+
+*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+
+html, body {
+ min-height: 100%;
+ background: var(--bg);
+ color: var(--ink);
+ font-family: var(--sans);
+ font-size: 16px;
+ line-height: 1.55;
+ -webkit-font-smoothing: antialiased;
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+}
+
+/* ── Header / wordmark ── */
+.site-header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 100;
+ background: rgba(243, 239, 230, 0.92);
+ backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--line);
+ padding: 18px 32px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 24px;
+}
+
+.wordmark {
+ font-family: var(--serif);
+ font-size: clamp(22px, 2.6vw, 42px);
+ font-weight: 400;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--ink);
+ line-height: 1.15;
+ white-space: normal;
+ max-width: min(520px, 58vw);
+}
+
+.hud {
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ flex-shrink: 0;
+}
+
+.stat {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: 2px;
+}
+
+.stat-label {
+ font-family: var(--sans);
+ font-size: 10px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ font-weight: 500;
+}
+
+.stat-value {
+ font-family: var(--serif);
+ font-size: 22px;
+ color: var(--ink);
+ font-variant-numeric: tabular-nums;
+ letter-spacing: 0.04em;
+ line-height: 1.1;
+}
+
+.btn-ghost {
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--ink);
+ background: transparent;
+ border: 1px solid var(--line-strong);
+ padding: 10px 18px;
+ cursor: pointer;
+ border-radius: var(--radius);
+ transition: border-color 0.3s var(--ease), background 0.3s var(--ease), color 0.3s var(--ease);
+}
+
+.btn-ghost:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+ background: var(--accent-soft);
+}
+
+/* ── Main ── */
+main {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 120px 24px 64px;
+ gap: 36px;
+}
+
+.intro {
+ text-align: center;
+ max-width: 420px;
+}
+
+.intro h2 {
+ font-family: var(--serif);
+ font-size: 28px;
+ font-weight: 400;
+ letter-spacing: 0.06em;
+ color: var(--ink);
+ margin-bottom: 8px;
+}
+
+.intro p {
+ font-size: 14px;
+ color: var(--muted);
+ letter-spacing: 0.02em;
+}
+
+/* ── Board ── */
+.board {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 14px;
+ width: min(560px, 92vw);
+ perspective: 1200px;
+}
+
+.card {
+ aspect-ratio: 1;
+ position: relative;
+ cursor: pointer;
+ border: none;
+ background: transparent;
+ padding: 0;
+ transform-style: preserve-3d;
+ transition: transform 0.65s var(--ease-scene);
+ border-radius: var(--radius);
+}
+
+.card:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: 3px;
+}
+
+.card.is-flipped,
+.card.is-matched {
+ transform: rotateY(180deg);
+ cursor: default;
+}
+
+.card.is-matched {
+ pointer-events: none;
+}
+
+.card-face {
+ position: absolute;
+ inset: 0;
+ backface-visibility: hidden;
+ -webkit-backface-visibility: hidden;
+ border-radius: var(--radius);
+ overflow: hidden;
+ box-shadow: var(--shadow);
+ border: 1px solid var(--line);
+}
+
+.card-back {
+ background:
+ linear-gradient(135deg, rgba(184,149,74,0.08) 0%, transparent 50%),
+ var(--surface);
+ display: grid;
+ place-items: center;
+}
+
+.card-back::before {
+ content: "";
+ width: 36%;
+ height: 36%;
+ border: 1px solid var(--accent);
+ opacity: 0.55;
+ transform: rotate(45deg);
+ box-shadow: inset 0 0 0 6px var(--surface), inset 0 0 0 7px rgba(184,149,74,0.35);
+}
+
+.card-back::after {
+ content: "";
+ position: absolute;
+ inset: 10px;
+ border: 1px solid var(--line);
+ border-radius: 2px;
+ pointer-events: none;
+}
+
+.card-front {
+ transform: rotateY(180deg);
+ background: var(--surface);
+}
+
+.card.is-matched .card-front {
+ box-shadow: var(--shadow), 0 0 0 1px var(--accent);
+}
+
+.card.is-matched .swatch::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, transparent 60%, rgba(184,149,74,0.12));
+ pointer-events: none;
+}
+
+/* ── Pattern swatches ── */
+.swatch {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+}
+
+/* Damask — ornate diamond medallion */
+.swatch-damask {
+ background-color: #2a2420;
+ background-image:
+ radial-gradient(ellipse 30% 40% at 50% 50%, rgba(201,169,97,0.35) 0%, transparent 70%),
+ radial-gradient(circle at 50% 20%, rgba(201,169,97,0.5) 0 2px, transparent 2.5px),
+ radial-gradient(circle at 50% 80%, rgba(201,169,97,0.5) 0 2px, transparent 2.5px),
+ radial-gradient(circle at 20% 50%, rgba(201,169,97,0.5) 0 2px, transparent 2.5px),
+ radial-gradient(circle at 80% 50%, rgba(201,169,97,0.5) 0 2px, transparent 2.5px),
+ radial-gradient(circle at 50% 50%, transparent 18%, rgba(201,169,97,0.25) 19%, rgba(201,169,97,0.25) 22%, transparent 23%),
+ radial-gradient(circle at 50% 50%, transparent 28%, rgba(201,169,97,0.15) 29%, rgba(201,169,97,0.15) 31%, transparent 32%),
+ repeating-linear-gradient(45deg, transparent, transparent 8px, rgba(201,169,97,0.06) 8px, rgba(201,169,97,0.06) 9px),
+ repeating-linear-gradient(-45deg, transparent, transparent 8px, rgba(201,169,97,0.06) 8px, rgba(201,169,97,0.06) 9px);
+}
+
+/* Toile — pastoral line scene suggestion via curved strokes */
+.swatch-toile {
+ background-color: #e8e2d4;
+ background-image:
+ radial-gradient(ellipse 40% 25% at 30% 35%, transparent 40%, #3a5a6a 41%, #3a5a6a 43%, transparent 44%),
+ radial-gradient(ellipse 35% 20% at 70% 60%, transparent 40%, #3a5a6a 41%, #3a5a6a 43%, transparent 44%),
+ radial-gradient(circle at 25% 70%, #3a5a6a 0 1.5px, transparent 2px),
+ radial-gradient(circle at 28% 68%, #3a5a6a 0 1px, transparent 1.5px),
+ radial-gradient(circle at 22% 72%, #3a5a6a 0 1px, transparent 1.5px),
+ radial-gradient(circle at 55% 28%, transparent 12%, #3a5a6a 13%, #3a5a6a 14%, transparent 15%),
+ radial-gradient(ellipse 20% 35% at 75% 30%, transparent 50%, #3a5a6a 51%, #3a5a6a 53%, transparent 54%),
+ linear-gradient(180deg, transparent 85%, rgba(58,90,106,0.15) 100%);
+ background-size: 100% 100%, 100% 100%, 40px 40px, 40px 40px, 40px 40px, 60px 60px, 100% 100%, 100% 100%;
+}
+
+/* Ikat — blurred staggered chevron bands */
+.swatch-ikat {
+ background-color: #1e3a3a;
+ background-image:
+ linear-gradient(90deg,
+ transparent 0%, transparent 8%,
+ #c45c4a 8%, #c45c4a 18%,
+ transparent 18%, transparent 28%,
+ #d4a84b 28%, #d4a84b 38%,
+ transparent 38%, transparent 48%,
+ #c45c4a 48%, #c45c4a 58%,
+ transparent 58%, transparent 68%,
+ #d4a84b 68%, #d4a84b 78%,
+ transparent 78%, transparent 88%,
+ #c45c4a 88%, #c45c4a 98%,
+ transparent 98%),
+ linear-gradient(90deg,
+ #2a5555 0%, #2a5555 12%,
+ transparent 12%, transparent 22%,
+ #2a5555 22%, #2a5555 42%,
+ transparent 42%, transparent 52%,
+ #2a5555 52%, #2a5555 72%,
+ transparent 72%, transparent 82%,
+ #2a5555 82%, #2a5555 100%);
+ background-size: 100% 14px, 100% 14px;
+ background-position: 0 0, 6px 7px;
+ filter: contrast(1.05);
+}
+
+/* Chinoiserie — pagoda / branch silhouettes */
+.swatch-chinoiserie {
+ background-color: #1a2830;
+ background-image:
+ /* moon */
+ radial-gradient(circle at 72% 22%, rgba(232,220,180,0.7) 0 8%, transparent 9%),
+ /* branch curves */
+ radial-gradient(ellipse 60% 8% at 20% 40%, #8a9a6a 0%, transparent 70%),
+ radial-gradient(ellipse 40% 6% at 55% 55%, #8a9a6a 0%, transparent 70%),
+ radial-gradient(ellipse 50% 7% at 30% 70%, #8a9a6a 0%, transparent 70%),
+ /* blossoms */
+ radial-gradient(circle at 35% 38%, #c47a7a 0 3px, transparent 3.5px),
+ radial-gradient(circle at 42% 42%, #c47a7a 0 2.5px, transparent 3px),
+ radial-gradient(circle at 28% 44%, #d4a0a0 0 2px, transparent 2.5px),
+ radial-gradient(circle at 60% 53%, #c47a7a 0 3px, transparent 3.5px),
+ radial-gradient(circle at 68% 58%, #d4a0a0 0 2px, transparent 2.5px),
+ radial-gradient(circle at 38% 68%, #c47a7a 0 2.5px, transparent 3px),
+ /* ground mist */
+ linear-gradient(180deg, transparent 75%, rgba(138,154,106,0.12) 100%);
+}
+
+/* Trellis — diamond lattice */
+.swatch-trellis {
+ background-color: #f0ebe0;
+ background-image:
+ linear-gradient(45deg, transparent 46%, #5a7a5a 46%, #5a7a5a 48%, transparent 48%, transparent 52%, #5a7a5a 52%, #5a7a5a 54%, transparent 54%),
+ linear-gradient(-45deg, transparent 46%, #5a7a5a 46%, #5a7a5a 48%, transparent 48%, transparent 52%, #5a7a5a 52%, #5a7a5a 54%, transparent 54%),
+ radial-gradient(circle at 50% 50%, #8aaa6a 0 2px, transparent 2.5px);
+ background-size: 28px 28px, 28px 28px, 28px 28px;
+}
+
+/* Fret — Greek key / geometric meander */
+.swatch-fret {
+ background-color: #1c1a17;
+ background-image:
+ linear-gradient(var(--accent) 2px, transparent 2px),
+ linear-gradient(90deg, var(--accent) 2px, transparent 2px),
+ linear-gradient(var(--accent) 2px, transparent 2px),
+ linear-gradient(90deg, var(--accent) 2px, transparent 2px),
+ linear-gradient(transparent 6px, var(--accent) 6px, var(--accent) 8px, transparent 8px),
+ linear-gradient(90deg, transparent 6px, var(--accent) 6px, var(--accent) 8px, transparent 8px);
+ background-size: 24px 24px, 24px 24px, 12px 12px, 12px 12px, 24px 24px, 24px 24px;
+ background-position: 0 0, 0 0, 6px 6px, 6px 6px, 0 0, 0 0;
+ opacity: 1;
+}
+
+.swatch-fret {
+ background:
+ /* outer frame lines via repeating */
+ repeating-linear-gradient(0deg,
+ transparent 0 10px,
+ var(--accent) 10px 12px,
+ transparent 12px 22px,
+ var(--accent) 22px 24px),
+ repeating-linear-gradient(90deg,
+ transparent 0 10px,
+ var(--accent) 10px 12px,
+ transparent 12px 22px,
+ var(--accent) 22px 24px);
+ background-color: #1c1a17;
+ background-size: 48px 48px;
+}
+
+/* Botanical — leaf scatter */
+.swatch-botanical {
+ background-color: #243028;
+ background-image:
+ radial-gradient(ellipse 12px 6px at 25% 30%, #6a8a5a 0%, transparent 100%),
+ radial-gradient(ellipse 10px 5px at 55% 25%, #5a7a4a 0%, transparent 100%),
+ radial-gradient(ellipse 14px 7px at 75% 45%, #6a8a5a 0%, transparent 100%),
+ radial-gradient(ellipse 11px 5px at 35% 60%, #7a9a5a 0%, transparent 100%),
+ radial-gradient(ellipse 13px 6px at 65% 70%, #5a7a4a 0%, transparent 100%),
+ radial-gradient(ellipse 9px 4px at 20% 75%, #6a8a5a 0%, transparent 100%),
+ radial-gradient(ellipse 10px 5px at 80% 20%, #7a9a5a 0%, transparent 100%),
+ radial-gradient(ellipse 8px 4px at 45% 85%, #5a7a4a 0%, transparent 100%),
+ radial-gradient(circle at 50% 50%, rgba(184,149,74,0.15) 0 1.5px, transparent 2px),
+ radial-gradient(circle at 30% 40%, rgba(184,149,74,0.2) 0 1px, transparent 1.5px),
+ radial-gradient(circle at 70% 55%, rgba(184,149,74,0.2) 0 1px, transparent 1.5px);
+ background-size: 100% 100%;
+}
+
+/* Stripe — refined vertical ribbon stripes */
+.swatch-stripe {
+ background-color: #2c2438;
+ background-image:
+ linear-gradient(90deg,
+ #2c2438 0%,
+ #2c2438 10%,
+ #c9a961 10%,
+ #c9a961 12%,
+ #2c2438 12%,
+ #2c2438 22%,
+ #6a5a7a 22%,
+ #6a5a7a 28%,
+ #2c2438 28%,
+ #2c2438 38%,
+ #c9a961 38%,
+ #c9a961 40%,
+ #2c2438 40%,
+ #2c2438 55%,
+ #8a7a5a 55%,
+ #8a7a5a 58%,
+ #2c2438 58%,
+ #2c2438 70%,
+ #c9a961 70%,
+ #c9a961 72%,
+ #2c2438 72%,
+ #2c2438 82%,
+ #6a5a7a 82%,
+ #6a5a7a 88%,
+ #2c2438 88%,
+ #2c2438 100%);
+}
+
+/* ── Win overlay ── */
+.overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 200;
+ background: rgba(28, 26, 23, 0.55);
+ display: grid;
+ place-items: center;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.5s var(--ease-out), visibility 0.5s var(--ease-out);
+ padding: 24px;
+}
+
+.overlay.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.overlay-card {
+ background: var(--surface);
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow-lift);
+ border-radius: var(--radius);
+ padding: 48px 40px 40px;
+ max-width: 400px;
+ width: 100%;
+ text-align: center;
+ transform: translateY(16px) scale(0.98);
+ transition: transform 0.55s var(--ease-out);
+}
+
+.overlay.is-open .overlay-card {
+ transform: translateY(0) scale(1);
+}
+
+.overlay-eyebrow {
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-bottom: 16px;
+}
+
+.overlay-card h2 {
+ font-family: var(--serif);
+ font-size: 38px;
+ font-weight: 400;
+ letter-spacing: 0.04em;
+ color: var(--ink);
+ line-height: 1.15;
+ margin-bottom: 12px;
+}
+
+.overlay-card p {
+ font-size: 15px;
+ color: var(--muted);
+ margin-bottom: 28px;
+ line-height: 1.6;
+}
+
+.overlay-stats {
+ display: flex;
+ justify-content: center;
+ gap: 32px;
+ margin-bottom: 32px;
+ padding: 18px 0;
+ border-top: 1px solid var(--line);
+ border-bottom: 1px solid var(--line);
+}
+
+.overlay-stats .stat { align-items: center; }
+
+.btn-primary {
+ font-family: var(--sans);
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--bg);
+ background: var(--ink);
+ border: 1px solid var(--ink);
+ padding: 14px 32px;
+ cursor: pointer;
+ border-radius: var(--radius);
+ transition: background 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease);
+}
+
+.btn-primary:hover {
+ background: var(--accent);
+ border-color: var(--accent);
+ color: var(--ink);
+}
+
+/* subtle card hover when face-down */
+.card:not(.is-flipped):not(.is-matched):hover .card-back {
+ box-shadow: var(--shadow-lift);
+ border-color: var(--line-strong);
+}
+
+.card:not(.is-flipped):not(.is-matched):hover {
+ transform: translateY(-2px);
+ transition: transform 0.35s var(--ease);
+}
+
+.card.is-flipped:hover,
+.card.is-matched:hover {
+ transform: rotateY(180deg);
+}
+
+footer {
+ text-align: center;
+ padding: 24px;
+ font-size: 10px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ border-top: 1px solid var(--line);
+}
+
+@media (max-width: 560px) {
+ .site-header { padding: 14px 16px; flex-wrap: wrap; }
+ .wordmark { font-size: 20px; max-width: 100%; letter-spacing: 0.14em; }
+ .board { gap: 8px; }
+ main { padding-top: 140px; }
+ .hud { gap: 12px; }
+ .stat-value { font-size: 18px; }
+}
+</style>
+</head>
+<body>
+
+<header class="site-header">
+ <div class="wordmark">Designer Wallcoverings</div>
+ <div class="hud">
+ <div class="stat">
+ <span class="stat-label">Moves</span>
+ <span class="stat-value" id="moves">0</span>
+ </div>
+ <div class="stat">
+ <span class="stat-label">Time</span>
+ <span class="stat-value" id="timer">0:00</span>
+ </div>
+ <button type="button" class="btn-ghost" id="restartBtn">Restart</button>
+ </div>
+</header>
+
+<main>
+ <div class="intro">
+ <h2>Motif Memory</h2>
+ <p>Pair the eight classic wallcovering motifs. Flip with care.</p>
+ </div>
+ <div class="board" id="board" aria-label="Memory card grid"></div>
+</main>
+
+<footer>Est. atelier collection — eight enduring patterns</footer>
+
+<div class="overlay" id="winOverlay" role="dialog" aria-modal="true" aria-labelledby="winTitle">
+ <div class="overlay-card">
+ <div class="overlay-eyebrow">Collection complete</div>
+ <h2 id="winTitle">All Motifs Matched</h2>
+ <p>A refined eye for pattern. Your pairing is complete.</p>
+ <div class="overlay-stats">
+ <div class="stat">
+ <span class="stat-label">Moves</span>
+ <span class="stat-value" id="finalMoves">0</span>
+ </div>
+ <div class="stat">
+ <span class="stat-label">Time</span>
+ <span class="stat-value" id="finalTime">0:00</span>
+ </div>
+ </div>
+ <button type="button" class="btn-primary" id="playAgainBtn">Play again</button>
+ </div>
+</div>
+
+<script>
+(function () {
+ const MOTIFS = [
+ { id: 'damask', cls: 'swatch-damask' },
+ { id: 'toile', cls: 'swatch-toile' },
+ { id: 'ikat', cls: 'swatch-ikat' },
+ { id: 'chinoiserie', cls: 'swatch-chinoiserie' },
+ { id: 'trellis', cls: 'swatch-trellis' },
+ { id: 'fret', cls: 'swatch-fret' },
+ { id: 'botanical', cls: 'swatch-botanical' },
+ { id: 'stripe', cls: 'swatch-stripe' }
+ ];
+
+ const board = document.getElementById('board');
+ const movesEl = document.getElementById('moves');
+ const timerEl = document.getElementById('timer');
+ const winOverlay = document.getElementById('winOverlay');
+ const finalMoves = document.getElementById('finalMoves');
+ const finalTime = document.getElementById('finalTime');
+
+ let deck = [];
+ let flipped = [];
+ let lock = false;
+ let moves = 0;
+ let matched = 0;
+ let seconds = 0;
+ let timerId = null;
+ let started = false;
+
+ 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 formatTime(s) {
+ const m = Math.floor(s / 60);
+ const r = s % 60;
+ return m + ':' + String(r).padStart(2, '0');
+ }
+
+ function startTimer() {
+ if (timerId) return;
+ timerId = setInterval(function () {
+ seconds++;
+ timerEl.textContent = formatTime(seconds);
+ }, 1000);
+ }
+
+ function stopTimer() {
+ if (timerId) {
+ clearInterval(timerId);
+ timerId = null;
+ }
+ }
+
+ function buildDeck() {
+ const pairs = MOTIFS.concat(MOTIFS).map(function (m, i) {
+ return { uid: m.id + '-' + i, id: m.id, cls: m.cls };
+ });
+ deck = shuffle(pairs);
+ }
+
+ function renderBoard() {
+ board.innerHTML = '';
+ deck.forEach(function (card, index) {
+ const btn = document.createElement('button');
+ btn.type = 'button';
+ btn.className = 'card';
+ btn.setAttribute('aria-label', 'Pattern card');
+ btn.dataset.id = card.id;
+ btn.dataset.index = String(index);
+
+ btn.innerHTML =
+ '<span class="card-face card-back" aria-hidden="true"></span>' +
+ '<span class="card-face card-front" aria-hidden="true">' +
+ '<span class="swatch ' + card.cls + '"></span>' +
+ '</span>';
+
+ btn.addEventListener('click', function () { onFlip(btn); });
+ board.appendChild(btn);
+ });
+ }
+
+ function onFlip(btn) {
+ if (lock) return;
+ if (btn.classList.contains('is-flipped') || btn.classList.contains('is-matched')) return;
+ if (flipped.length === 1 && flipped[0] === btn) return;
+
+ if (!started) {
+ started = true;
+ startTimer();
+ }
+
+ btn.classList.add('is-flipped');
+ flipped.push(btn);
+
+ if (flipped.length === 2) {
+ moves++;
+ movesEl.textContent = String(moves);
+ lock = true;
+ const a = flipped[0];
+ const b = flipped[1];
+ if (a.dataset.id === b.dataset.id) {
+ a.classList.add('is-matched');
+ b.classList.add('is-matched');
+ flipped = [];
+ lock = false;
+ matched += 2;
+ if (matched === deck.length) {
+ stopTimer();
+ setTimeout(showWin, 480);
+ }
+ } else {
+ setTimeout(function () {
+ a.classList.remove('is-flipped');
+ b.classList.remove('is-flipped');
+ flipped = [];
+ lock = false;
+ }, 780);
+ }
+ }
+ }
+
+ function showWin() {
+ finalMoves.textContent = String(moves);
+ finalTime.textContent = formatTime(seconds);
+ winOverlay.classList.add('is-open');
+ }
+
+ function reset() {
+ stopTimer();
+ flipped = [];
+ lock = false;
+ moves = 0;
+ matched = 0;
+ seconds = 0;
+ started = false;
+ movesEl.textContent = '0';
+ timerEl.textContent = '0:00';
+ winOverlay.classList.remove('is-open');
+ buildDeck();
+ renderBoard();
+ }
+
+ document.getElementById('restartBtn').addEventListener('click', reset);
+ document.getElementById('playAgainBtn').addEventListener('click', reset);
+
+ winOverlay.addEventListener('click', function (e) {
+ if (e.target === winOverlay) {
+ /* keep overlay until intentional play-again */
+ }
+ });
+
+ reset();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/grok.png b/data/artifacts/ab0c520893e3/grok.png
new file mode 100644
index 0000000..75ab1cf
Binary files /dev/null and b/data/artifacts/ab0c520893e3/grok.png differ
diff --git a/data/artifacts/ab0c520893e3/hermes3-8b.html b/data/artifacts/ab0c520893e3/hermes3-8b.html
new file mode 100644
index 0000000..430fa22
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/hermes3-8b.html
@@ -0,0 +1,181 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Design Motif Memory Card Game</title>
+<style>
+ :root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e / #2f4c39;
+ --line: 1px solid var(--text);
+ --shadow: 0 8px 24px rgba(0, 0, 0, .12);
+ --ease: cubic-bezier(.22, 1, .36, 1);
+ }
+
+ body {
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 16px;
+ background-color: var(--bg);
+ color: var(--text);
+ margin: 0;
+ padding: 96px;
+ box-sizing: border-box;
+ }
+
+ h1 {
+ font-family: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ font-size: 50px;
+ letter-spacing: .18em;
+ margin: 0;
+ }
+
+ header {
+ position: fixed;
+ top: 24px;
+ left: 24px;
+ display: flex;
+ align-items: center;
+ }
+
+ .wordmark {
+ font-family: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ font-size: 40px; /* DARKEST ink token */
+ letter-spacing: .18em;
+ color: var(--text); /* Not surface/bg */
+ }
+
+ button {
+ background-color: transparent;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 16px;
+ uppercase;
+ letter-spacing: .15em;
+ color: var(--text);
+ }
+
+ .card {
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: var(--shadow);
+ transition: transform 0.2s var(--ease), opacity 0.3s linear var(--ease);
+ backface-visibility: hidden;
+ perspective: 1000px;
+ margin: 12px;
+ }
+
+ .card.flip {
+ transform: rotateY(180deg);
+ opacity: 0.7;
+ }
+
+ .grid {
+ display: grid;
+ gap: 24px;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ }
+
+ section {
+ padding: 96px;
+ background-color: var(--muted);
+ border-left: var(--line);
+ box-shadow: inset 0 -8px 48px rgba(0, 0, 0, .2);
+ }
+
+ .overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, .8);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: var(--surface);
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ text-shadow: 0 0 24px rgba(0, 0, 0, .6);
+ }
+
+ @keyframes fadeUp {
+ from { opacity: 0; transform: translateY(28px); }
+ to { opacity: 1; transform: none; }
+ }
+
+ @keyframes driftBG {
+ 0% { background-color: var(--bg); }
+ 100% { background-color: lighten(var(--bg), 5%); }
+ }
+</style>
+<body>
+<header class="grid">
+<div class="wordmark">DESIGNER WALLCOVERINGS</div>
+</header>
+
+<section class="overlay" id="winOverlay">
+<h2>Congratulations! You won!</h2>
+<button onclick="location.reload()">Restart</button>
+</section>
+
+<section class="grid">
+ <div class="card" onclick="flipCard(this)">
+ <img src="" alt="Damask pattern">
+ </div> <!-- ...repeat 15 times -->
+</section>
+
+<script>
+document.querySelector('.wordmark').textContent = 'DESIGNER WALLCOVERINGS';
+const cards = document.querySelectorAll('.card');
+let firstCard, secondCard;
+
+function flipCard(card) {
+ if(!firstCard && !secondCard) {
+ firstCard = card;
+ firstCard.style.transform = "rotateY(180deg)";
+ setTimeout(() => (firstCard.style.opacity = "0.7"), 200);
+ } else if(firstCard && !secondCard) {
+ secondCard = card;
+ firstCard.classList.add("flip");
+
+ if(firstCard.dataset.pattern === secondCard.dataset.pattern) {
+ firstCard.style.display = 'none';
+ secondCard.style.display = 'none';
+ setTimeout(() => {firstCard.style.opacity = "1"; secondCard.style.opacity = "1";}, 700);
+
+ if(document.querySelectorAll('.card').length == 0) {
+ document.getElementById("winOverlay").style.display = "flex";
+ }
+ } else {
+ firstCard.classList.remove("flip");
+ setTimeout(() => (firstCard.style.opacity = "1", secondCard.style.opacity = "1"), 700);
+ }
+
+ firstCard = null;
+ secondCard = null;
+ }
+}
+
+cards.forEach(card => {
+ card.dataset.pattern = `pattern${Math.floor(Math.random() * 8) + 1}`;
+ card.style.backgroundImage = `url(#{getPatternImage(card)})`;
+});
+
+function getPatternImage(card) {
+ const patterns = ['Damask', 'Toile', 'Ikat', 'Chinoiserie', 'Trellis', 'Fret', 'Botanical', 'Stripe'];
+ return `url(${patterns[card.dataset.pattern]})`;
+}
+
+document.querySelector('.overlay').style.display = "none";
+
+setInterval(() => {
+ document.body.style.backgroundImage = `linear-gradient(45deg, var(--bg) 50%, var(--muted) 50%)`;
+}, 6000);
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/hermes3-8b.png b/data/artifacts/ab0c520893e3/hermes3-8b.png
new file mode 100644
index 0000000..74872e4
Binary files /dev/null and b/data/artifacts/ab0c520893e3/hermes3-8b.png differ
diff --git a/data/artifacts/ab0c520893e3/hf-qwen-coder-32b.html b/data/artifacts/ab0c520893e3/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..6e59085
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/hf-qwen-coder-32b.html
@@ -0,0 +1,251 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Memory Card Flip Game</title>
+ <style>
+ :root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e;
+ --line: #d5cdc6;
+ --shadow: 0 8px 24px rgba(0,0,0,.12);
+ --hover-shadow: 0 16px 48px rgba(0,0,0,.18);
+ --glow: 0 0 24px rgba(176,71,46,0.35);
+ --ease: cubic-bezier(.22,1,.36,1);
+ }
+ body {
+ margin: 0;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ background-color: var(--bg);
+ color: var(--text);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding-top: 64px;
+ }
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ background-color: transparent;
+ z-index: 1000;
+ text-align: left;
+ padding-left: 32px;
+ box-sizing: border-box;
+ }
+ header h1 {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 67px;
+ letter-spacing: .18em;
+ margin: 0;
+ color: var(--text);
+ }
+ main {
+ width: 90%;
+ max-width: 960px;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+ margin-top: 32px;
+ }
+ .card {
+ position: relative;
+ width: 100%;
+ height: 260px;
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: var(--shadow);
+ perspective: 1000px;
+ transition: transform 150ms ease-in-out;
+ }
+ .card:hover {
+ box-shadow: var(--hover-shadow);
+ }
+ .card-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ transition: transform 500ms var(--ease);
+ transform-style: preserve-3d;
+ }
+ .card.flipped .card-inner {
+ transform: rotateY(180deg);
+ }
+ .card-front, .card-back {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ backface-visibility: hidden;
+ border-radius: 14px;
+ box-shadow: var(--shadow);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ .card-front {
+ background-color: var(--surface);
+ }
+ .card-back {
+ transform: rotateY(180deg);
+ background-size: cover;
+ }
+ .pattern {
+ width: 100%;
+ height: 100%;
+ border-radius: 14px;
+ }
+ .overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(255,255,255,0.9);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ border-radius: 14px;
+ box-shadow: var(--shadow);
+ font-family: 'Playfair Display', Georgia, serif;
+ color: var(--text);
+ }
+ .overlay h2 {
+ font-size: 38px;
+ margin-bottom: 16px;
+ }
+ .overlay button {
+ background-color: var(--accent);
+ color: white;
+ border: none;
+ padding: 12px 24px;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ cursor: pointer;
+ }
+ </style>
+</head>
+<body>
+ <header>
+ <h1>DESIGNER WALLCOVERINGS</h1>
+ </header>
+ <main id="game-board">
+ <!-- Card templates will be inserted here -->
+ </main>
+ <div class="overlay" id="win-screen" style="display:none;">
+ <h2>Congratulations!</h2>
+ <p>You've matched all the patterns.</p>
+ <button onclick="restartGame()">Restart</button>
+ </div>
+ <script>
+ const patterns = [
+ { name: 'Damask', css: `background-image: linear-gradient(45deg, var(--muted), var(--surface) 25%, transparent 25%, transparent 75%, var(--muted) 75%, var(--muted)), linear-gradient(45deg, var(--muted), var(--surface) 25%, transparent 25%, transparent 75%, var(--muted) 75%, var(--muted)); background-size: 60px 60px; background-position: 0 0, 30px 30px;` },
+ { name: 'Toile', css: `background-image: radial-gradient(circle at center, rgba(245, 242, 234, 0.8) 15%, transparent 15%), radial-gradient(circle at center, var(--accent) 10%, transparent 10%); background-size: 60px 60px;` },
+ { name: 'Ikat', css: `background-image: repeating-linear-gradient(45deg, transparent, transparent 24px, var(--muted) 24px, var(--muted) 48px), repeating-linear-gradient(-45deg, transparent, transparent 24px, var(--muted) 24px, var(--muted) 48px); background-size: 120px 120px;` },
+ { name: 'Chinoiserie', css: `background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 8 8%22%3E%3Cpath d=%22M1,7 L5,3 L3,6 Z M4,0 L8,4 L6,1 Z M3,4 L7,8 L5,5 Z M0,1 L4,5 L2,2 Z%22 fill=%22${encodeURIComponent(var(--muted))}%22/%3E%3C/svg%3E'); background-size: 20px 20px;` },
+ { name: 'Trellis', css: `background-image: linear-gradient(45deg, var(--muted), transparent 25%, transparent 75%, var(--muted)), linear-gradient(-45deg, var(--muted), transparent 25%, transparent 75%, var(--muted)); background-size: 60px 60px;` },
+ { name: 'Fret', css: `background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 8 8%22%3E%3Cpath d=%22M1,1 L7,1 L4,7 Z M1,7 L7,7 L4,1 Z%22 fill=%22${encodeURIComponent(var(--muted))}%22/%3E%3C/svg%3E'); background-size: 40px 40px;` },
+ { name: 'Botanical', css: `background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 8 8%22%3E%3Cpath d=%22M1,5 C1.5,4 2,3 3,3 C4,3 5,4 6,5 C7,6 6,7 5,7 C4,7 3,6 2,6 C1,5 Z%22 fill=%22${encodeURIComponent(var(--muted))}%22/%3E%3C/svg%3E'); background-size: 40px 40px;` },
+ { name: 'Stripe', css: `background-image: linear-gradient(to right, var(--accent), transparent 50%, transparent); background-size: 16px 16px;` }
+ ];
+ const cards = [];
+ let flippedCards = [];
+ let moves = 0;
+ let timer;
+ const gameBoard = document.getElementById('game-board');
+ const winScreen = document.getElementById('win-screen');
+
+ function createCard(pattern) {
+ const card = document.createElement('div');
+ card.classList.add('card');
+ const cardInner = document.createElement('div');
+ cardInner.classList.add('card-inner');
+ const cardFront = document.createElement('div');
+ cardFront.classList.add('card-front');
+ const cardBack = document.createElement('div');
+ cardBack.classList.add('card-back', 'pattern');
+ cardBack.style.cssText = pattern.css;
+ cardInner.appendChild(cardFront);
+ cardInner.appendChild(cardBack);
+ card.appendChild(cardInner);
+ card.addEventListener('click', () => flipCard(card));
+ cards.push({ element: card, pattern });
+ return card;
+ }
+
+ function shuffle(array) {
+ for (let i = array.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [array[i], array[j]] = [array[j], array[i]];
+ }
+ }
+
+ function setupGame() {
+ gameBoard.innerHTML = '';
+ flippedCards = [];
+ moves = 0;
+ timer = setInterval(updateTimer, 1000);
+ const doubledPatterns = patterns.concat(patterns);
+ shuffle(doubledPatterns);
+ doubledPatterns.forEach(pattern => {
+ gameBoard.appendChild(createCard(pattern));
+ });
+ }
+
+ function flipCard(card) {
+ if (flippedCards.length < 2 && !card.classList.contains('flipped')) {
+ card.classList.add('flipped');
+ flippedCards.push(card);
+ checkForMatch();
+ }
+ }
+
+ function checkForMatch() {
+ moves++;
+ const [card1, card2] = flippedCards;
+ if (card1 && card2) {
+ const match = card1.querySelector('.pattern').style.cssText === card2.querySelector('.pattern').style.cssText;
+ setTimeout(() => {
+ if (!match) {
+ card1.classList.remove('flipped');
+ card2.classList.remove('flipped');
+ } else {
+ card1.removeEventListener('click', flipCard);
+ card2.removeEventListener('click', flipCard);
+ }
+ flippedCards = [];
+ checkForWin();
+ }, 1000);
+ }
+ }
+
+ function checkForWin() {
+ const allFlipped = [...gameBoard.children].every(card => card.classList.contains('flipped'));
+ if (allFlipped) {
+ clearInterval(timer);
+ winScreen.style.display = 'flex';
+ }
+ }
+
+ function restartGame() {
+ winScreen.style.display = 'none';
+ setupGame();
+ }
+
+ function updateTimer() {
+ const minutes = Math.floor(moves / 60);
+ const seconds = moves % 60;
+ document.querySelector('#timer').textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
+ }
+
+ setupGame();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/hf-qwen-coder-32b.png b/data/artifacts/ab0c520893e3/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..6a8aa3c
Binary files /dev/null and b/data/artifacts/ab0c520893e3/hf-qwen-coder-32b.png differ
diff --git a/data/artifacts/ab0c520893e3/kimi.html b/data/artifacts/ab0c520893e3/kimi.html
new file mode 100644
index 0000000..d87e394
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/kimi.html
@@ -0,0 +1,610 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Memory</title>
+<style>
+:root {
+ /* Luxury Palette - Warm Ivory Ground */
+ --bg: #f5f2ea;
+ --surface: #ede8dd;
+ --ink: #1c1a17;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --line: #d4cfc3;
+ --shadow: rgba(28, 26, 23, 0.08);
+ --shadow-elevated: rgba(28, 26, 23, 0.15);
+
+ /* Typography */
+ --font-display: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ --font-sans: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+
+ /* Motion */
+ --ease-swift: cubic-bezier(.22,.9,.24,1);
+ --ease-power: cubic-bezier(.77,0,.18,1);
+
+ /* Spacing */
+ --space-xs: 8px;
+ --space-sm: 16px;
+ --space-md: 24px;
+ --space-lg: 40px;
+ --space-xl: 64px;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 16px;
+}
+
+body {
+ font-family: var(--font-sans);
+ background: var(--bg);
+ color: var(--ink);
+ min-height: 100vh;
+ padding-top: 100px;
+ -webkit-font-smoothing: antialiased;
+}
+
+/* Fixed Header */
+header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 80px;
+ background: var(--bg);
+ border-bottom: 1px solid var(--line);
+ display: flex;
+ align-items: center;
+ padding: 0 var(--space-lg);
+ z-index: 100;
+ box-shadow: 0 1px 0 var(--line);
+}
+
+.wordmark {
+ font-family: var(--font-display);
+ font-size: 42px;
+ font-weight: 400;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--ink);
+ line-height: 1;
+}
+
+/* Game Container */
+.game-container {
+ max-width: 800px;
+ margin: 0 auto;
+ padding: var(--space-lg) var(--space-md);
+}
+
+/* Stats Bar */
+.stats-bar {
+ display: flex;
+ justify-content: center;
+ gap: var(--space-xl);
+ margin-bottom: var(--space-lg);
+ padding: var(--space-sm) 0;
+}
+
+.stat {
+ font-family: var(--font-sans);
+ font-size: 12px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--muted);
+ text-align: center;
+}
+
+.stat-value {
+ display: block;
+ font-size: 28px;
+ font-weight: 300;
+ color: var(--ink);
+ margin-top: var(--space-xs);
+ font-family: var(--font-display);
+ letter-spacing: 0.05em;
+}
+
+/* Grid */
+.grid {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: var(--space-md);
+ perspective: 1200px;
+}
+
+/* Card */
+.card {
+ aspect-ratio: 3/4;
+ position: relative;
+ cursor: pointer;
+ transform-style: preserve-3d;
+ transition: transform 0.6s var(--ease-swift);
+}
+
+.card.flipped {
+ transform: rotateY(180deg);
+}
+
+.card.matched {
+ transform: rotateY(180deg);
+ pointer-events: none;
+}
+
+.card-face {
+ position: absolute;
+ inset: 0;
+ backface-visibility: hidden;
+ border-radius: 2px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px var(--shadow), 0 1px 3px var(--shadow);
+ transition: box-shadow 0.3s var(--ease-swift);
+}
+
+.card:hover .card-face {
+ box-shadow: 0 8px 24px var(--shadow-elevated), 0 2px 8px var(--shadow);
+}
+
+/* Card Back (Pattern Side) */
+.card-back {
+ background: var(--surface);
+ transform: rotateY(180deg);
+ border: 1px solid var(--line);
+}
+
+/* Card Front (Cover Side) */
+.card-front {
+ background: linear-gradient(135deg, #2a2824 0%, #1c1a17 100%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.card-front::before {
+ content: '';
+ width: 40%;
+ height: 40%;
+ background: var(--accent);
+ opacity: 0.3;
+ transform: rotate(45deg);
+}
+
+/* Pattern Definitions */
+.pattern {
+ width: 100%;
+ height: 100%;
+}
+
+/* Damask - Ornate symmetrical floral */
+.pattern-damask {
+ background-color: #2a2520;
+ background-image:
+ radial-gradient(circle at 30% 30%, var(--accent) 2px, transparent 2px),
+ radial-gradient(circle at 70% 30%, var(--accent) 2px, transparent 2px),
+ radial-gradient(circle at 50% 70%, var(--accent) 3px, transparent 3px),
+ radial-gradient(ellipse at 50% 50%, transparent 40%, rgba(201, 169, 97, 0.3) 40%, rgba(201, 169, 97, 0.3) 45%, transparent 45%);
+ background-size: 60px 60px;
+ position: relative;
+}
+
+.pattern-damask::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(circle at 50% 0%, rgba(201, 169, 97, 0.4) 8px, transparent 8px),
+ radial-gradient(circle at 50% 100%, rgba(201, 169, 97, 0.4) 8px, transparent 8px),
+ radial-gradient(circle at 0% 50%, rgba(201, 169, 97, 0.4) 8px, transparent 8px),
+ radial-gradient(circle at 100% 50%, rgba(201, 169, 97, 0.4) 8px, transparent 8px);
+ background-size: 60px 60px;
+}
+
+/* Toile - Scenic pastoral */
+.pattern-toile {
+ background-color: #e8e4dc;
+ background-image:
+ repeating-linear-gradient(90deg, transparent, transparent 58px, rgba(44, 62, 80, 0.15) 58px, rgba(44, 62, 80, 0.15) 60px),
+ repeating-linear-gradient(0deg, transparent, transparent 58px, rgba(44, 62, 80, 0.15) 58px, rgba(44, 62, 80, 0.15) 60px);
+ position: relative;
+}
+
+.pattern-toile::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(circle at 20% 30%, rgba(139, 115, 85, 0.4) 12px, transparent 12px),
+ radial-gradient(circle at 80% 70%, rgba(139, 115, 85, 0.4) 15px, transparent 15px),
+ radial-gradient(ellipse at 50% 50%, rgba(139, 115, 85, 0.3) 20px 8px, transparent 20px);
+ background-size: 120px 120px;
+}
+
+/* Ikat - Blurred ethnic geometric */
+.pattern-ikat {
+ background-color: #c9a961;
+ background-image:
+ repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(44, 38, 32, 0.3) 10px, rgba(44, 38, 32, 0.3) 20px),
+ repeating-linear-gradient(-45deg, transparent, transparent 15px, rgba(255, 255, 255, 0.2) 15px, rgba(255, 255, 255, 0.2) 30px);
+ position: relative;
+ overflow: hidden;
+}
+
+.pattern-ikat::after {
+ content: '';
+ position: absolute;
+ inset: -20px;
+ background: repeating-linear-gradient(90deg, rgba(44, 38, 32, 0.4) 0px, rgba(44, 38, 32, 0.4) 4px, transparent 4px, transparent 12px);
+ filter: blur(2px);
+}
+
+/* Chinoiserie - Asian scenic */
+.pattern-chinoiserie {
+ background-color: #f0ece4;
+ background-image:
+ radial-gradient(circle at 25% 25%, rgba(93, 138, 116, 0.5) 2px, transparent 2px),
+ radial-gradient(circle at 75% 75%, rgba(93, 138, 116, 0.5) 2px, transparent 2px),
+ radial-gradient(circle at 50% 50%, rgba(139, 69, 69, 0.3) 1px, transparent 1px);
+ background-size: 40px 40px;
+ position: relative;
+}
+
+.pattern-chinoiserie::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(ellipse 30px 60px at 30% 50%, rgba(93, 138, 116, 0.4) 40%, transparent 40%),
+ radial-gradient(ellipse 20px 40px at 70% 60%, rgba(93, 138, 116, 0.4) 40%, transparent 40%);
+ background-size: 100px 100px;
+}
+
+/* Trellis - Lattice */
+.pattern-trellis {
+ background-color: #2c3e50;
+ background-image:
+ linear-gradient(90deg, rgba(201, 169, 97, 0.6) 2px, transparent 2px),
+ linear-gradient(0deg, rgba(201, 169, 97, 0.6) 2px, transparent 2px);
+ background-size: 30px 30px;
+ position: relative;
+}
+
+.pattern-trellis::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ linear-gradient(45deg, transparent 48%, rgba(201, 169, 97, 0.3) 48%, rgba(201, 169, 97, 0.3) 52%, transparent 52%),
+ linear-gradient(-45deg, transparent 48%, rgba(201, 169, 97, 0.3) 48%, rgba(201, 169, 97, 0.3) 52%, transparent 52%);
+ background-size: 30px 30px;
+}
+
+/* Fret - Greek key */
+.pattern-fret {
+ background-color: #1c1a17;
+ background-image:
+ linear-gradient(90deg, var(--accent) 4px, transparent 4px),
+ linear-gradient(0deg, var(--accent) 4px, transparent 4px),
+ linear-gradient(90deg, var(--accent) 4px, transparent 4px),
+ linear-gradient(0deg, var(--accent) 4px, transparent 4px);
+ background-size: 40px 40px;
+ background-position: 0 0, 0 0, 20px 20px, 20px 20px;
+ position: relative;
+}
+
+.pattern-fret::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ linear-gradient(90deg, transparent 18px, var(--accent) 18px, var(--accent) 22px, transparent 22px),
+ linear-gradient(0deg, transparent 18px, var(--accent) 18px, var(--accent) 22px, transparent 22px);
+ background-size: 40px 40px;
+}
+
+/* Botanical - Leaves */
+.pattern-botanical {
+ background-color: #e8e4dc;
+ background-image:
+ radial-gradient(ellipse 8px 20px at 30% 40%, rgba(74, 105, 74, 0.6) 50%, transparent 50%),
+ radial-gradient(ellipse 8px 20px at 70% 60%, rgba(74, 105, 74, 0.6) 50%, transparent 50%);
+ background-size: 50px 50px;
+ position: relative;
+}
+
+.pattern-botanical::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(circle at 25% 30%, rgba(139, 115, 85, 0.4) 3px, transparent 3px),
+ radial-gradient(circle at 75% 70%, rgba(139, 115, 85, 0.4) 3px, transparent 3px);
+ background-size: 50px 50px;
+ transform: rotate(25deg);
+}
+
+/* Stripe - Classic */
+.pattern-stripe {
+ background-color: #2a2520;
+ background-image:
+ repeating-linear-gradient(90deg,
+ var(--accent) 0px,
+ var(--accent) 8px,
+ transparent 8px,
+ transparent 16px,
+ rgba(245, 242, 234, 0.3) 16px,
+ rgba(245, 242, 234, 0.3) 24px,
+ transparent 24px,
+ transparent 32px
+ );
+ position: relative;
+}
+
+.pattern-stripe::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: repeating-linear-gradient(0deg,
+ transparent 0px,
+ transparent 20px,
+ rgba(201, 169, 97, 0.1) 20px,
+ rgba(201, 169, 97, 0.1) 22px
+ );
+}
+
+/* Win Overlay */
+.overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(28, 26, 23, 0.95);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.5s var(--ease-power);
+ z-index: 200;
+}
+
+.overlay.active {
+ opacity: 1;
+ pointer-events: all;
+}
+
+.win-content {
+ text-align: center;
+ padding: var(--space-xl);
+ max-width: 500px;
+}
+
+.win-title {
+ font-family: var(--font-display);
+ font-size: 48px;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+ color: var(--bg);
+ margin-bottom: var(--space-md);
+ font-weight: 400;
+}
+
+.win-stats {
+ font-family: var(--font-sans);
+ font-size: 14px;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: var(--accent);
+ margin-bottom: var(--space-lg);
+}
+
+.restart-btn {
+ font-family: var(--font-sans);
+ font-size: 12px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--ink);
+ background: var(--accent);
+ border: none;
+ padding: var(--space-sm) var(--space-lg);
+ cursor: pointer;
+ transition: all 0.3s var(--ease-swift);
+}
+
+.restart-btn:hover {
+ background: var(--bg);
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(201, 169, 97, 0.3);
+}
+
+/* Responsive */
+@media (max-width: 600px) {
+ .wordmark {
+ font-size: 28px;
+ letter-spacing: 0.12em;
+ }
+
+ .grid {
+ gap: var(--space-sm);
+ }
+
+ .stats-bar {
+ gap: var(--space-lg);
+ }
+}
+</style>
+</head>
+<body>
+
+<header>
+ <div class="wordmark">Designer Wallcoverings</div>
+</header>
+
+<div class="game-container">
+ <div class="stats-bar">
+ <div class="stat">
+ Moves
+ <span class="stat-value" id="moves">0</span>
+ </div>
+ <div class="stat">
+ Time
+ <span class="stat-value" id="time">00:00</span>
+ </div>
+ </div>
+
+ <div class="grid" id="grid"></div>
+</div>
+
+<div class="overlay" id="overlay">
+ <div class="win-content">
+ <h2 class="win-title">Collection Complete</h2>
+ <p class="win-stats" id="win-stats">0 moves · 00:00</p>
+ <button class="restart-btn" onclick="initGame()">New Game</button>
+ </div>
+</div>
+
+<script>
+const motifs = [
+ { name: 'damask', class: 'pattern-damask' },
+ { name: 'toile', class: 'pattern-toile' },
+ { name: 'ikat', class: 'pattern-ikat' },
+ { name: 'chinoiserie', class: 'pattern-chinoiserie' },
+ { name: 'trellis', class: 'pattern-trellis' },
+ { name: 'fret', class: 'pattern-fret' },
+ { name: 'botanical', class: 'pattern-botanical' },
+ { name: 'stripe', class: 'pattern-stripe' }
+];
+
+let cards = [];
+let flipped = [];
+let matched = 0;
+let moves = 0;
+let timer = null;
+let seconds = 0;
+let gameStarted = false;
+
+function formatTime(secs) {
+ const m = Math.floor(secs / 60).toString().padStart(2, '0');
+ const s = (secs % 60).toString().padStart(2, '0');
+ return `${m}:${s}`;
+}
+
+function updateTimer() {
+ seconds++;
+ document.getElementById('time').textContent = formatTime(seconds);
+}
+
+function startTimer() {
+ if (!gameStarted) {
+ gameStarted = true;
+ timer = setInterval(updateTimer, 1000);
+ }
+}
+
+function stopTimer() {
+ clearInterval(timer);
+ gameStarted = false;
+}
+
+function createCard(motif, index) {
+ const card = document.createElement('div');
+ card.className = 'card';
+ card.dataset.motif = motif.name;
+ card.dataset.index = index;
+
+ card.innerHTML = `
+ <div class="card-face card-front"></div>
+ <div class="card-face card-back">
+ <div class="pattern ${motif.class}"></div>
+ </div>
+ `;
+
+ card.addEventListener('click', () => flipCard(card));
+ return card;
+}
+
+function flipCard(card) {
+ if (card.classList.contains('flipped') || card.classList.contains('matched') || flipped.length >= 2) {
+ return;
+ }
+
+ startTimer();
+
+ card.classList.add('flipped');
+ flipped.push(card);
+
+ if (flipped.length === 2) {
+ moves++;
+ document.getElementById('moves').textContent = moves;
+ checkMatch();
+ }
+}
+
+function checkMatch() {
+ const [card1, card2] = flipped;
+ const match = card1.dataset.motif === card2.dataset.motif;
+
+ if (match) {
+ setTimeout(() => {
+ card1.classList.add('matched');
+ card2.classList.add('matched');
+ matched++;
+ flipped = [];
+
+ if (matched === 8) {
+ endGame();
+ }
+ }, 600);
+ } else {
+ setTimeout(() => {
+ card1.classList.remove('flipped');
+ card2.classList.remove('flipped');
+ flipped = [];
+ }, 1000);
+ }
+}
+
+function endGame() {
+ stopTimer();
+ const stats = `${moves} moves · ${formatTime(seconds)}`;
+ document.getElementById('win-stats').textContent = stats;
+ document.getElementById('overlay').classList.add('active');
+}
+
+function initGame() {
+ // Reset state
+ matched = 0;
+ moves = 0;
+ seconds = 0;
+ flipped = [];
+ stopTimer();
+
+ document.getElementById('moves').textContent = '0';
+ document.getElementById('time').textContent = '00:00';
+ document.getElementById('overlay').classList.remove('active');
+
+ // Create pairs and shuffle
+ const deck = [...motifs, ...motifs];
+ for (let i = deck.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [deck[i], deck[j]] = [deck[j], deck[i]];
+ }
+
+ // Render grid
+ const grid = document.getElementById('grid');
+ grid.innerHTML = '';
+ deck.forEach((motif, index) => {
+ grid.appendChild(createCard(motif, index));
+ });
+}
+
+// Start game on load
+initGame();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/kimi.png b/data/artifacts/ab0c520893e3/kimi.png
new file mode 100644
index 0000000..213298a
Binary files /dev/null and b/data/artifacts/ab0c520893e3/kimi.png differ
diff --git a/data/artifacts/ab0c520893e3/qwen25-7b.html b/data/artifacts/ab0c520893e3/qwen25-7b.html
new file mode 100644
index 0000000..52a0b51
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/qwen25-7b.html
@@ -0,0 +1,242 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Memory Card Flip Game</title>
+ <style>
+ :root {
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --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) both;
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ background-color: var(--bg);
+ color: var(--text);
+ font-family: 'Didot', 'Bodoni MT', Georgia, serif;
+ overflow: hidden;
+ }
+
+ header {
+ display: flex;
+ align-items: center;
+ padding: 24px 16px;
+ background-color: var(--surface);
+ color: var(--text);
+ font-size: 50px;
+ letter-spacing: .18em;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ z-index: 1000;
+ }
+
+ main {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: calc(100vh - 64px);
+ padding-top: 96px;
+ }
+
+ .grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+ max-width: 768px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ .card {
+ position: relative;
+ width: 260px;
+ height: 350px;
+ background-color: var(--surface);
+ border-radius: 14px;
+ overflow: hidden;
+ transition: transform .7s var(--ease), box-shadow .7s var(--ease);
+ cursor: pointer;
+ }
+
+ .card.front {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-image: linear-gradient(to bottom, rgba(255,255,255,.1) 0%, rgba(255,255,255,.3) 100%);
+ box-shadow: var(--shadow);
+ }
+
+ .card.back {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-image: linear-gradient(to bottom, rgba(245,242,234,.1) 0%, rgba(245,242,234,.3) 100%);
+ box-shadow: var(--shadow);
+ }
+
+ .card.flipped {
+ transform: rotateY(180deg);
+ transition: none;
+ }
+
+ .card.flipped:before,
+ .card.flipped:after {
+ content: '';
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background-color: var(--accent);
+ border-radius: 14px;
+ z-index: -1;
+ filter: blur(2px) brightness(.6);
+ transform-origin: bottom center;
+ }
+
+ .card.flipped:before {
+ top: 100%;
+ animation: glow 5s infinite;
+ }
+
+ .card.flipped:after {
+ bottom: 100%;
+ animation: none;
+ }
+
+ @keyframes glow {
+ to { transform: scale(2); opacity: 0; }
+ }
+
+ .scoreboard {
+ margin-top: 32px;
+ font-size: 16px;
+ letter-spacing: .15em;
+ text-transform: uppercase;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .timer {
+ margin-left: auto;
+ }
+ </style>
+</head>
+<body>
+ <header>DESIGNER WALLCOVERINGS</header>
+ <main>
+ <div class="grid" id="game-grid">
+ <!-- Cards will be dynamically added here -->
+ </div>
+ <div class="scoreboard">
+ <span>Moves: 0</span>
+ <span>Time: 00:00</span>
+ <span>Score: 0</span>
+ </div>
+ </main>
+
+ <script>
+ const grid = document.getElementById('game-grid');
+ let moves = 0;
+ let time = 0;
+ let timerInterval;
+
+ function startGame() {
+ clearInterval(timerInterval);
+ moves = 0;
+ time = 0;
+ const cards = [
+ { pattern: 'damask', id: 1 },
+ { pattern: 'toile', id: 2 },
+ { pattern: 'ikat', id: 3 },
+ { pattern: 'chinoiserie', id: 4 },
+ { pattern: 'trellis', id: 5 },
+ { pattern: 'fret', id: 6 },
+ { pattern: 'botanical', id: 7 },
+ { pattern: 'stripe', id: 8 },
+ // Repeat the same patterns to form a complete 4x4 grid
+ ];
+
+ for (let i = 0; i < cards.length; i++) {
+ const card = document.createElement('div');
+ card.className = 'card';
+ card.id = `card-${i + 1}`;
+ card.addEventListener('click', () => flipCard(card));
+ for (let j = 0; j < 2; j++) {
+ if (j === 0) {
+ card.classList.add('front');
+ const frontContent = document.createElement('div');
+ frontContent.className = 'card-front';
+ card.appendChild(frontContent);
+ } else {
+ card.classList.add('back');
+ const backContent = document.createElement('div');
+ backContent.className = 'card-back';
+ card.appendChild(backContent);
+ }
+ }
+
+ grid.appendChild(card);
+ }
+ }
+
+ function flipCard(card) {
+ if (card.classList.contains('flipped')) return;
+
+ const flippedCards = Array.from(grid.querySelectorAll('.flipped'));
+
+ if (flippedCards.length < 2) {
+ moves++;
+ card.classList.add('flipped');
+ setTimeout(() => checkMatch(flippedCards), 500);
+ }
+ }
+
+ function checkMatch(flippedCards) {
+ if (flippedCards.length === 2 && flippedCards[0].dataset.id === flippedCards[1].dataset.id) {
+ flippedCards.forEach(card => card.classList.add('matched'));
+ } else {
+ setTimeout(() => {
+ flippedCards.forEach(card => card.classList.remove('flipped', 'matched'));
+ }, 500);
+ }
+ }
+
+ function startTimer() {
+ timerInterval = setInterval(() => {
+ time++;
+ const minutes = Math.floor(time / 60).toString().padStart(2, '0');
+ const seconds = (time % 60).toString().padStart(2, '0');
+ document.querySelector('.timer').textContent = `${minutes}:${seconds}`;
+ }, 1000);
+ }
+
+ function showWinScreen() {
+ clearInterval(timerInterval);
+ alert(`Congratulations! You won in ${moves} moves and ${time} seconds!`);
+ // Restart game
+ startGame();
+ }
+
+ startGame();
+ startTimer();
+
+ document.querySelector('.scoreboard').addEventListener('click', () => {
+ if (document.querySelectorAll('.matched').length === 16) showWinScreen();
+ });
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/qwen25-7b.png b/data/artifacts/ab0c520893e3/qwen25-7b.png
new file mode 100644
index 0000000..5e0c911
Binary files /dev/null and b/data/artifacts/ab0c520893e3/qwen25-7b.png differ
diff --git a/data/artifacts/ab0c520893e3/qwen3-14b.html b/data/artifacts/ab0c520893e3/qwen3-14b.html
new file mode 100644
index 0000000..f26553a
--- /dev/null
+++ b/data/artifacts/ab0c520893e3/qwen3-14b.html
@@ -0,0 +1,490 @@
+<!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: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e;
+ --line: #e5e2dc;
+ --shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+ --ease: cubic-bezier(0.22, 1, 0.36, 1);
+ --card-radius: 14px;
+ --spacing: 24px;
+ --grid-gap: 24px;
+ --min-card-width: 260px;
+ --card-hover: 0 16px 48px rgba(0, 0, 0, 0.18);
+ --glow: 0 0 24px rgba(176, 71, 46, 0.35);
+ --font-display: 'Playfair Display', Georgia, serif;
+ --font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ }
+
+ * {
+ box-sizing: border-box;
+ }
+
+ html, body {
+ margin: 0;
+ padding: 0;
+ font-family: var(--font-body);
+ background-color: var(--bg);
+ color: var(--text);
+ min-height: 100vh;
+ }
+
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ padding: 24px;
+ font-family: var(--font-display);
+ font-size: 40px;
+ letter-spacing: 0.18em;
+ color: var(--text);
+ background-color: var(--surface);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ z-index: 1000;
+ }
+
+ main {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding-top: 120px;
+ min-height: 100vh;
+ gap: var(--spacing);
+ width: 100%;
+ }
+
+ .game-container {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(var(--min-card-width), 1fr));
+ gap: var(--grid-gap);
+ max-width: 1280px;
+ width: 100%;
+ padding: 0 var(--spacing);
+ }
+
+ .card {
+ perspective: 1000px;
+ width: 100%;
+ height: 260px;
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: var(--card-radius);
+ box-shadow: var(--shadow);
+ cursor: pointer;
+ position: relative;
+ transition: box-shadow 0.2s var(--ease);
+ }
+
+ .card:hover {
+ box-shadow: var(--card-hover);
+ }
+
+ .card-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ transform-style: preserve-3d;
+ transition: transform 0.6s var(--ease);
+ }
+
+ .card.flipped .card-inner {
+ transform: rotateY(180deg);
+ }
+
+ .card-face {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ backface-visibility: hidden;
+ border-radius: var(--card-radius);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 200px;
+ font-weight: 900;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ color: var(--text);
+ transition: transform 0.6s var(--ease);
+ }
+
+ .card-front {
+ z-index: 2;
+ background-color: var(--surface);
+ transform: rotateY(0deg);
+ }
+
+ .card-back {
+ z-index: 1;
+ background-color: var(--bg);
+ transform: rotateY(180deg);
+ }
+
+ .card-back.damask {
+ background: linear-gradient(45deg, #e8e4e0 25%, #dcd9d5 25%, #dcd9d5 50%, #e8e4e0 50%, #e8e4e0 75%, #dcd9d5 75%, #dcd9d5 100%);
+ background-size: 20px 20px;
+ }
+
+ .card-back.toile {
+ background: linear-gradient(45deg, #f2f0ec 25%, #eae6e0 25%, #eae6e0 50%, #f2f0ec 50%, #f2f0ec 75%, #eae6e0 75%, #eae6e0 100%);
+ background-size: 40px 40px;
+ }
+
+ .card-back.ikat {
+ background: repeating-linear-gradient(45deg, #e9e6e2 0, #e9e6e2 10px, #dcd9d5 10px, #dcd9d5 20px);
+ }
+
+ .card-back.chinoiserie {
+ background: linear-gradient(135deg, #e0dcd9 0%, #f2f0ec 100%);
+ background-size: 400% 400%;
+ animation: chinoiserie 15s ease-in-out infinite;
+ }
+
+ .card-back.trellis {
+ background: repeating-linear-gradient(45deg, #f2f0ec 0, #f2f0ec 10px, #eae6e0 10px, #eae6e0 20px);
+ }
+
+ .card-back.fret {
+ background: repeating-linear-gradient(45deg, #e8e4e0 0, #e8e4e0 5px, #dcd9d5 5px, #dcd9d5 10px);
+ }
+
+ .card-back.botanical {
+ background: radial-gradient(ellipse at center, #dcd9d5 0%, #e8e4e0 70%, #f2f0ec 100%);
+ }
+
+ .card-back.stripes {
+ background: repeating-linear-gradient(90deg, #eae6e0 0, #eae6e0 5px, #f2f0ec 5px, #f2f0ec 10px);
+ }
+
+ @keyframes chinoiserie {
+ 0% { background-position: 0% 50%; }
+ 50% { background-position: 100% 50%; }
+ 100% { background-position: 0% 50%; }
+ }
+
+ .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;
+ z-index: 2000;
+ visibility: hidden;
+ opacity: 0;
+ transition: all 0.3s var(--ease);
+ }
+
+ .overlay.show {
+ visibility: visible;
+ opacity: 1;
+ }
+
+ .overlay-content {
+ background: var(--surface);
+ padding: 48px;
+ border-radius: var(--card-radius);
+ text-align: center;
+ box-shadow: var(--shadow);
+ color: var(--text);
+ font-family: var(--font-display);
+ font-size: 28px;
+ letter-spacing: 0.1em;
+ }
+
+ .overlay-content p {
+ font-size: 20px;
+ margin: 24px 0 0;
+ }
+
+ .overlay-buttons {
+ margin-top: 32px;
+ }
+
+ .overlay-button {
+ margin: 0 12px;
+ padding: 12px 24px;
+ background: var(--accent);
+ color: var(--text);
+ border: none;
+ border-radius: 8px;
+ font-size: 16px;
+ letter-spacing: 0.1em;
+ cursor: pointer;
+ transition: background 0.2s var(--ease);
+ }
+
+ .overlay-button:hover {
+ background: #a53a15;
+ }
+
+ .stats {
+ font-size: 16px;
+ color: var(--muted);
+ margin-top: 16px;
+ text-align: center;
+ }
+
+ .timer, .moves {
+ display: inline-block;
+ margin: 0 16px;
+ }
+
+ .restart-button {
+ position: absolute;
+ top: 24px;
+ right: 24px;
+ background: var(--accent);
+ color: var(--text);
+ border: none;
+ border-radius: 8px;
+ font-size: 14px;
+ padding: 8px 16px;
+ letter-spacing: 0.1em;
+ cursor: pointer;
+ transition: background 0.2s var(--ease);
+ }
+
+ .restart-button:hover {
+ background: #a53a15;
+ }
+ </style>
+</head>
+<body>
+ <header>DESIGNER WALLCOVERINGS</header>
+ <main>
+ <div class="game-container">
+ <div class="card" data-pattern="damask" data-name="damask">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back damask">D</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="toile" data-name="toile">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back toile">T</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="ikat" data-name="ikat">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back ikat">I</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="chinoiserie" data-name="chinoiserie">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back chinoiserie">C</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="trellis" data-name="trellis">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back trellis">T</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="fret" data-name="fret">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back fret">F</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="botanical" data-name="botanical">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back botanical">B</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="stripes" data-name="stripes">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back stripes">S</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="damask" data-name="damask">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back damask">D</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="toile" data-name="toile">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back toile">T</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="ikat" data-name="ikat">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back ikat">I</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="chinoiserie" data-name="chinoiserie">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back chinoiserie">C</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="trellis" data-name="trellis">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back trellis">T</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="fret" data-name="fret">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back fret">F</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="botanical" data-name="botanical">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back botanical">B</div>
+ </div>
+ </div>
+ <div class="card" data-pattern="stripes" data-name="stripes">
+ <div class="card-inner">
+ <div class="card-face card-front">?</div>
+ <div class="card-face card-back stripes">S</div>
+ </div>
+ </div>
+ </div>
+ <div class="stats">
+ <span class="moves">Moves: 0</span>
+ <span class="timer">Time: 0s</span>
+ </div>
+ <button class="restart-button">RESTART</button>
+ </main>
+ <div class="overlay">
+ <div class="overlay-content">
+ <h1>WINNER</h1>
+ <p>Congratulations on completing the pattern match!</p>
+ <div class="overlay-buttons">
+ <button class="overlay-button" onclick="restartGame()">RESTART</button>
+ <button class="overlay-button" onclick="closeOverlay()">CLOSE</button>
+ </div>
+ </div>
+ </div>
+ <script>
+ const cards = document.querySelectorAll('.card');
+ const movesDisplay = document.querySelector('.moves');
+ const timerDisplay = document.querySelector('.timer');
+ const overlay = document.querySelector('.overlay');
+ const restartButton = document.querySelector('.restart-button');
+
+ let firstCard, secondCard;
+ let lockBoard = false;
+ let moves = 0;
+ let time = 0;
+ let timerInterval;
+
+ cards.forEach(card => {
+ card.addEventListener('click', flipCard);
+ });
+
+ function flipCard() {
+ if (lockBoard) return;
+ if (this === firstCard) return;
+
+ this.classList.add('flipped');
+
+ if (!firstCard) {
+ firstCard = this;
+ return;
+ }
+
+ secondCard = this;
+
+ checkForMatch();
+ }
+
+ function checkForMatch() {
+ const isMatch = firstCard.dataset.pattern === secondCard.dataset.pattern;
+
+ if (isMatch) {
+ disableCards();
+ return;
+ }
+
+ unflipCards();
+ }
+
+ function disableCards() {
+ firstCard.removeEventListener('click', flipCard);
+ secondCard.removeEventListener('click', flipCard);
+
+ resetTurn();
+ }
+
+ function unflipCards() {
+ lockBoard = true;
+
+ setTimeout(() => {
+ firstCard.classList.remove('flipped');
+ secondCard.classList.remove('flipped');
+
+ resetTurn();
+ }, 1000);
+ }
+
+ function resetTurn() {
+ [firstCard, secondCard] = [null, null];
+ lockBoard = false;
+ moves++;
+ movesDisplay.textContent = 'Moves: ' + moves;
+ }
+
+ function startTimer() {
+ timerInterval = setInterval(() => {
+ time++;
+ timerDisplay.textContent = 'Time: ' + time + 's';
+ }, 1000);
+ }
+
+ function restartGame() {
+ cards.forEach(card => {
+ card.classList.remove('flipped');
+ card.addEventListener('click', flipCard);
+ });
+
+ moves = 0;
+ time = 0;
+ movesDisplay.textContent = 'Moves: 0';
+ timerDisplay.textContent = 'Time: 0s';
+
+ clearInterval(timerInterval);
+ startTimer();
+ }
+
+ function closeOverlay() {
+ overlay.classList.remove('show');
+ }
+
+ function checkWin() {
+ const allMatched = Array.from(cards).every(card => card.classList.contains('flipped') || card.classList.contains('matched'));
+ if (allMatched) {
+ overlay.classList.add('show');
+ clearInterval(timerInterval);
+ }
+ }
+
+ // Initial setup
+ restartGame();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ab0c520893e3/qwen3-14b.png b/data/artifacts/ab0c520893e3/qwen3-14b.png
new file mode 100644
index 0000000..95cabef
Binary files /dev/null and b/data/artifacts/ab0c520893e3/qwen3-14b.png differ
diff --git a/data/challenges.json b/data/challenges.json
index ee52255..b818f2b 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -15089,13 +15089,13 @@
"queued_at": "2026-07-25T07:49:29.664Z",
"bytes": 6056,
"thumb": true,
- "aiScore": 8.3,
- "aiReason": "The game is fully functional and visually appealing with clear animations and sound effects.",
+ "aiScore": 7,
+ "aiReason": "The game fulfills the challenge well and has good visual quality.",
"aiScores": {
"qwen2.5vl:7b": 9,
- "minicpm-v:latest": 7.5
+ "minicpm-v:latest": 5
},
- "aiSpread": 1.5
+ "aiSpread": 4
},
{
"model": "gemma3-12b",
@@ -15109,7 +15109,7 @@
"bytes": 6894,
"thumb": true,
"aiScore": 7.5,
- "aiReason": "The game is fully functional and visually appealing with smooth animations and clear scoring.",
+ "aiReason": "The game fulfills the challenge well and has good visual quality.",
"aiScores": {
"qwen2.5vl:7b": 9,
"minicpm-v:latest": 6
@@ -15128,7 +15128,7 @@
"bytes": 5260,
"thumb": true,
"aiScore": 7.5,
- "aiReason": "The page fulfills the challenge well and has good visual quality.",
+ "aiReason": "The page is well-structured and fulfills the challenge requirements effectively. The visual quality is good, with clear text and responsive paddles.",
"aiScores": {
"qwen2.5vl:7b": 9,
"minicpm-v:latest": 6
@@ -15147,7 +15147,7 @@
"bytes": 5401,
"thumb": true,
"aiScore": 7.5,
- "aiReason": "The game is functional and visually appealing with good polish.",
+ "aiReason": "The game fulfills the challenge requirements and has good visual quality.",
"aiScores": {
"qwen2.5vl:7b": 9,
"minicpm-v:latest": 6
@@ -15164,12 +15164,20 @@
"finished_at": "2026-07-25T07:59:28.106Z",
"queued_at": "2026-07-25T07:49:29.687Z",
"bytes": 5636,
- "thumb": true
+ "thumb": true,
+ "aiScore": 7,
+ "aiReason": "The game is functional and visually appealing with good polish.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 5
+ },
+ "aiSpread": 4
}
],
- "judging": true,
- "judged_at": null,
- "category": "Games"
+ "judging": false,
+ "judged_at": "2026-07-25T12:48:04.364Z",
+ "category": "Games",
+ "aiPick": "gemma3-12b"
},
{
"id": "eda6b5e29387",
@@ -24341,6 +24349,343 @@
"designTools": true,
"created_at": "2026-07-25T12:36:12.772Z",
"winner": null,
+ "runs": [
+ {
+ "model": "qwen3-14b",
+ "status": "done",
+ "error": null,
+ "seconds": 64,
+ "cost": 0,
+ "started_at": "2026-07-25T12:36:20.185Z",
+ "finished_at": "2026-07-25T12:37:24.468Z",
+ "queued_at": "2026-07-25T12:36:12.783Z",
+ "bytes": 9116,
+ "thumb": true,
+ "aiScore": 6.3,
+ "aiReason": "The HTML file meets most of the requirements but lacks some visual elegance and whitespace.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 5.5
+ },
+ "aiSpread": 1.5
+ },
+ {
+ "model": "gemma3-12b",
+ "status": "done",
+ "error": null,
+ "seconds": 66,
+ "cost": 0,
+ "started_at": "2026-07-25T12:37:24.476Z",
+ "finished_at": "2026-07-25T12:38:30.161Z",
+ "queued_at": "2026-07-25T12:36:12.794Z",
+ "bytes": 7419,
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML file meets all the requirements and presents a polished, elegant design that is both functional and visually appealing.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
+ },
+ {
+ "model": "hermes3-8b",
+ "status": "done",
+ "error": null,
+ "seconds": 32,
+ "cost": 0,
+ "started_at": "2026-07-25T12:38:30.169Z",
+ "finished_at": "2026-07-25T12:39:02.438Z",
+ "queued_at": "2026-07-25T12:36:12.802Z",
+ "bytes": 3673,
+ "thumb": true,
+ "aiScore": 7.3,
+ "aiReason": "The HTML file is mostly compliant but lacks the interactive color wheel and filmstrip of patterns as required by the challenge.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 0.5
+ },
+ {
+ "model": "qwen25-7b",
+ "status": "done",
+ "error": null,
+ "seconds": 31,
+ "cost": 0,
+ "started_at": "2026-07-25T12:36:12.832Z",
+ "finished_at": "2026-07-25T12:36:43.826Z",
+ "queued_at": "2026-07-25T12:36:12.808Z",
+ "bytes": 4090,
+ "thumb": true,
+ "aiScore": 7.8,
+ "aiReason": "The HTML file meets all the requirements and presents a polished, elegant design with smooth transitions and a restrained luxury palette.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 2.5
+ },
+ {
+ "model": "hf-qwen-coder-32b",
+ "status": "done",
+ "error": null,
+ "seconds": 86,
+ "cost": 0,
+ "started_at": "2026-07-25T12:39:02.450Z",
+ "finished_at": "2026-07-25T12:40:28.939Z",
+ "queued_at": "2026-07-25T12:36:12.813Z",
+ "bytes": 6792,
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML file meets all the requirements and presents an elegant, interactive color wheel for wallcoverings. The design is smooth, with a restrained luxury palette and tasteful easing on any motion.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
+ },
+ {
+ "model": "claude-code",
+ "status": "done",
+ "error": null,
+ "seconds": 155,
+ "cost": 0,
+ "started_at": "2026-07-25T12:36:12.836Z",
+ "finished_at": "2026-07-25T12:38:48.163Z",
+ "queued_at": "2026-07-25T12:36:12.817Z",
+ "bytes": 18015,
+ "thumb": true
+ },
+ {
+ "model": "kimi",
+ "status": "done",
+ "error": null,
+ "seconds": 278,
+ "cost": 0.0377,
+ "started_at": "2026-07-25T12:36:12.843Z",
+ "finished_at": "2026-07-25T12:40:50.606Z",
+ "queued_at": "2026-07-25T12:36:12.821Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 20238,
+ "thumb": true
+ },
+ {
+ "model": "gpt",
+ "status": "done",
+ "error": null,
+ "seconds": 61,
+ "cost": 0.1162,
+ "started_at": "2026-07-25T12:36:12.848Z",
+ "finished_at": "2026-07-25T12:37:13.555Z",
+ "queued_at": "2026-07-25T12:36:12.824Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 24455,
+ "thumb": true
+ },
+ {
+ "model": "grok",
+ "status": "done",
+ "error": null,
+ "seconds": 160,
+ "cost": 0.1882,
+ "started_at": "2026-07-25T12:36:12.852Z",
+ "finished_at": "2026-07-25T12:38:53.230Z",
+ "queued_at": "2026-07-25T12:36:12.828Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "opendesign",
+ "hyperframes",
+ "hyperframes"
+ ],
+ "bytes": 34722,
+ "thumb": true
+ }
+ ],
+ "judging": true
+ },
+ {
+ "id": "ab0c520893e3",
+ "title": "Designer Wallcoverings — Match the Motif Memory Game",
+ "prompt": "Build a single self-contained HTML file: a memory card-flip game pairing named design motifs (Damask, Toile, Ikat, Chinoiserie, Trellis, Fret, Botanical, Stripe) each rendered as a CSS pattern swatch. 4x4 grid, flip to match, moves + timer, win screen, restart, 3D flip. Muted luxe palette. Output ONLY the HTML. DW LUXURY UI REQUIREMENTS (mandatory): (a) a fixed top bar with the wordmark 'DESIGNER WALLCOVERINGS' left-aligned in a SERIF display face (Cormorant Garamond / Playfair / EB Garamond via system serif stack), uppercase, letter-spacing .18em; (b) NEVER use system-ui/Arial as the display face — headings in the serif, body in a refined sans; generous type scale (headings >=24px); (c) a restrained luxury palette (deep near-black or warm ivory ground, ONE metallic/jewel accent), no muddy mid-tones, strong value contrast; (d) generous whitespace, hairline 1px strokes, soft shadows, tasteful easing on any motion. (e) Open with a CSS design-token block in :root (e.g. --bg, --ink, --accent, --line, --shadow, --ease) and reference the tokens throughout, so the palette is systematic not one-off. (f) The wordmark is a compact upper-left lockup that shows the FULL 'DESIGNER WALLCOVERINGS' text WITHOUT clipping — size the serif so it fits (~200-280px) or wrap to two lines; NEVER truncate/overflow-hidden the wordmark. Demote scoreboards/buttons to a small refined SANS (uppercase, tracked) so the header reads as a logo zone, not competing with the content. (g) Let color/imagery carry the meaning — do NOT slap letter labels on swatches/tiles; a bare luxury swatch beats a lettered one; when a build shows multiple 'styles/patterns', make them VISUALLY DISTINCT (different SVG/CSS motifs, not the same stripe at different densities). (h) NEVER use alert()/confirm()/prompt() — win/game-over/result states must be in-page overlays styled with the token palette. (i) NO external images or URLs (picsum.photos, unsplash, any CDN/http src) — the artifact runs under a strict no-network CSP so they render BROKEN; draw all patterns/imagery with CSS gradients or inline SVG only. (j) Actually INSTANTIATE the wordmark: put a real <header> element containing the wordmark text in the DOM (defining the CSS class is not enough), The wordmark/header text color MUST be the DARKEST ink token (near-black, e.g. #1c1a17 / var(--text)); NEVER a white/surface/background token — a common fatal bug is color:var(--surface) rendering the wordmark white-on-cream and invisible. Wordmark font-size >=40px. It must look like a luxury interior-design brand, not a generic AI demo. (No hamburger/nav needed — these are self-contained games/social widgets.)",
+ "category": "Real Work",
+ "designTools": true,
+ "created_at": "2026-07-25T12:36:12.884Z",
+ "winner": null,
+ "runs": [
+ {
+ "model": "qwen3-14b",
+ "status": "done",
+ "error": null,
+ "seconds": 113,
+ "cost": 0,
+ "started_at": "2026-07-25T12:40:28.947Z",
+ "finished_at": "2026-07-25T12:42:21.804Z",
+ "queued_at": "2026-07-25T12:36:12.889Z",
+ "bytes": 13326,
+ "thumb": true,
+ "aiScore": 5.8,
+ "aiReason": "The HTML meets most of the requirements but lacks some visual flair and does not fully utilize the CSS design tokens for a more cohesive look.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 4.5
+ },
+ "aiSpread": 2.5
+ },
+ {
+ "model": "gemma3-12b",
+ "status": "done",
+ "error": null,
+ "seconds": 116,
+ "cost": 0,
+ "started_at": "2026-07-25T12:42:21.809Z",
+ "finished_at": "2026-07-25T12:44:17.343Z",
+ "queued_at": "2026-07-25T12:36:12.892Z",
+ "bytes": 13493,
+ "thumb": true,
+ "aiScore": 7.8,
+ "aiReason": "The HTML fulfills the challenge requirements well and has a high-quality visual presentation.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 2.5
+ },
+ {
+ "model": "hermes3-8b",
+ "status": "done",
+ "error": null,
+ "seconds": 24,
+ "cost": 0,
+ "started_at": "2026-07-25T12:44:17.353Z",
+ "finished_at": "2026-07-25T12:44:41.729Z",
+ "queued_at": "2026-07-25T12:36:12.896Z",
+ "bytes": 4679,
+ "thumb": true,
+ "aiScore": 6.8,
+ "aiReason": "The HTML file is mostly compliant but lacks the 3D flip effect and some of the required CSS patterns are missing.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 0.5
+ },
+ {
+ "model": "qwen25-7b",
+ "status": "done",
+ "error": null,
+ "seconds": 47,
+ "cost": 0,
+ "started_at": "2026-07-25T12:36:43.840Z",
+ "finished_at": "2026-07-25T12:37:31.219Z",
+ "queued_at": "2026-07-25T12:36:12.900Z",
+ "bytes": 7424,
+ "thumb": true,
+ "aiScore": 6.8,
+ "aiReason": "The HTML file fulfills the challenge requirements well but lacks some visual flair and could benefit from more refined typography and color contrast.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 0.5
+ },
+ {
+ "model": "hf-qwen-coder-32b",
+ "status": "done",
+ "error": null,
+ "seconds": 125,
+ "cost": 0,
+ "started_at": "2026-07-25T12:44:41.742Z",
+ "finished_at": "2026-07-25T12:46:46.670Z",
+ "queued_at": "2026-07-25T12:36:12.904Z",
+ "bytes": 10159,
+ "thumb": true
+ },
+ {
+ "model": "claude-code",
+ "status": "done",
+ "error": null,
+ "seconds": 108,
+ "cost": 0,
+ "started_at": "2026-07-25T12:38:48.168Z",
+ "finished_at": "2026-07-25T12:40:36.564Z",
+ "queued_at": "2026-07-25T12:36:12.908Z",
+ "bytes": 15824,
+ "thumb": true
+ },
+ {
+ "model": "kimi",
+ "status": "done",
+ "error": null,
+ "seconds": 92,
+ "cost": 0.0166,
+ "started_at": "2026-07-25T12:40:50.615Z",
+ "finished_at": "2026-07-25T12:42:22.411Z",
+ "queued_at": "2026-07-25T12:36:12.912Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 14726,
+ "thumb": true
+ },
+ {
+ "model": "gpt",
+ "status": "done",
+ "error": null,
+ "seconds": 54,
+ "cost": 0.1315,
+ "started_at": "2026-07-25T12:37:13.577Z",
+ "finished_at": "2026-07-25T12:38:07.946Z",
+ "queued_at": "2026-07-25T12:36:12.916Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes",
+ "hyperframes"
+ ],
+ "bytes": 28760,
+ "thumb": true
+ },
+ {
+ "model": "grok",
+ "status": "done",
+ "error": null,
+ "seconds": 100,
+ "cost": 0.1269,
+ "started_at": "2026-07-25T12:38:53.236Z",
+ "finished_at": "2026-07-25T12:40:32.751Z",
+ "queued_at": "2026-07-25T12:36:12.920Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 20955,
+ "thumb": true
+ }
+ ],
+ "judging": true,
+ "judged_at": null
+ },
+ {
+ "id": "420dc7bd02b3",
+ "title": "Designer Wallcoverings — Palette Builder Tool",
+ "prompt": "Build a single self-contained HTML file: a social-ready color palette builder for interiors. Pick a base hue on a wheel; it generates a curated 5-swatch wallcovering palette (analogous/complementary/triadic toggle) with tasteful designer names (Alabaster, Greige, Celadon, Ink, Brass). Copy-hex on click, a live \"room preview\" strip, and an export-as-1080x1080-card button. Editorial layout. Output ONLY the HTML. DW LUXURY UI REQUIREMENTS (mandatory): (a) a fixed top bar with the wordmark 'DESIGNER WALLCOVERINGS' left-aligned in a SERIF display face (Cormorant Garamond / Playfair / EB Garamond via system serif stack), uppercase, letter-spacing .18em; (b) NEVER use system-ui/Arial as the display face — headings in the serif, body in a refined sans; generous type scale (headings >=24px); (c) a restrained luxury palette (deep near-black or warm ivory ground, ONE metallic/jewel accent), no muddy mid-tones, strong value contrast; (d) generous whitespace, hairline 1px strokes, soft shadows, tasteful easing on any motion. (e) Open with a CSS design-token block in :root (e.g. --bg, --ink, --accent, --line, --shadow, --ease) and reference the tokens throughout, so the palette is systematic not one-off. (f) The wordmark is a compact upper-left lockup that shows the FULL 'DESIGNER WALLCOVERINGS' text WITHOUT clipping — size the serif so it fits (~200-280px) or wrap to two lines; NEVER truncate/overflow-hidden the wordmark. Demote scoreboards/buttons to a small refined SANS (uppercase, tracked) so the header reads as a logo zone, not competing with the content. (g) Let color/imagery carry the meaning — do NOT slap letter labels on swatches/tiles; a bare luxury swatch beats a lettered one; when a build shows multiple 'styles/patterns', make them VISUALLY DISTINCT (different SVG/CSS motifs, not the same stripe at different densities). (h) NEVER use alert()/confirm()/prompt() — win/game-over/result states must be in-page overlays styled with the token palette. (i) NO external images or URLs (picsum.photos, unsplash, any CDN/http src) — the artifact runs under a strict no-network CSP so they render BROKEN; draw all patterns/imagery with CSS gradients or inline SVG only. (j) Actually INSTANTIATE the wordmark: put a real <header> element containing the wordmark text in the DOM (defining the CSS class is not enough), The wordmark/header text color MUST be the DARKEST ink token (near-black, e.g. #1c1a17 / var(--text)); NEVER a white/surface/background token — a common fatal bug is color:var(--surface) rendering the wordmark white-on-cream and invisible. Wordmark font-size >=40px. It must look like a luxury interior-design brand, not a generic AI demo. (No hamburger/nav needed — these are self-contained games/social widgets.)",
+ "category": "Real Work",
+ "designTools": true,
+ "created_at": "2026-07-25T12:48:12.940Z",
+ "winner": null,
"runs": [
{
"model": "qwen3-14b",
@@ -24350,7 +24695,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.783Z"
+ "queued_at": "2026-07-25T12:48:12.951Z"
},
{
"model": "gemma3-12b",
@@ -24360,7 +24705,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.794Z"
+ "queued_at": "2026-07-25T12:48:12.958Z"
},
{
"model": "hermes3-8b",
@@ -24370,7 +24715,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.802Z"
+ "queued_at": "2026-07-25T12:48:12.968Z"
},
{
"model": "qwen25-7b",
@@ -24378,9 +24723,9 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:36:12.832Z",
+ "started_at": "2026-07-25T12:48:13.004Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.808Z"
+ "queued_at": "2026-07-25T12:48:12.975Z"
},
{
"model": "hf-qwen-coder-32b",
@@ -24390,7 +24735,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.813Z"
+ "queued_at": "2026-07-25T12:48:12.980Z"
},
{
"model": "claude-code",
@@ -24398,9 +24743,9 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:36:12.836Z",
+ "started_at": "2026-07-25T12:48:13.009Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.817Z"
+ "queued_at": "2026-07-25T12:48:12.984Z"
},
{
"model": "kimi",
@@ -24408,9 +24753,9 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:36:12.843Z",
+ "started_at": "2026-07-25T12:48:13.016Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.821Z"
+ "queued_at": "2026-07-25T12:48:12.990Z"
},
{
"model": "gpt",
@@ -24418,9 +24763,9 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:36:12.848Z",
+ "started_at": "2026-07-25T12:48:13.021Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.824Z"
+ "queued_at": "2026-07-25T12:48:12.995Z"
},
{
"model": "grok",
@@ -24428,19 +24773,19 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:36:12.852Z",
+ "started_at": "2026-07-25T12:48:13.026Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.828Z"
+ "queued_at": "2026-07-25T12:48:12.999Z"
}
]
},
{
- "id": "ab0c520893e3",
- "title": "Designer Wallcoverings — Match the Motif Memory Game",
- "prompt": "Build a single self-contained HTML file: a memory card-flip game pairing named design motifs (Damask, Toile, Ikat, Chinoiserie, Trellis, Fret, Botanical, Stripe) each rendered as a CSS pattern swatch. 4x4 grid, flip to match, moves + timer, win screen, restart, 3D flip. Muted luxe palette. Output ONLY the HTML. DW LUXURY UI REQUIREMENTS (mandatory): (a) a fixed top bar with the wordmark 'DESIGNER WALLCOVERINGS' left-aligned in a SERIF display face (Cormorant Garamond / Playfair / EB Garamond via system serif stack), uppercase, letter-spacing .18em; (b) NEVER use system-ui/Arial as the display face — headings in the serif, body in a refined sans; generous type scale (headings >=24px); (c) a restrained luxury palette (deep near-black or warm ivory ground, ONE metallic/jewel accent), no muddy mid-tones, strong value contrast; (d) generous whitespace, hairline 1px strokes, soft shadows, tasteful easing on any motion. (e) Open with a CSS design-token block in :root (e.g. --bg, --ink, --accent, --line, --shadow, --ease) and reference the tokens throughout, so the palette is systematic not one-off. (f) The wordmark is a compact upper-left lockup that shows the FULL 'DESIGNER WALLCOVERINGS' text WITHOUT clipping — size the serif so it fits (~200-280px) or wrap to two lines; NEVER truncate/overflow-hidden the wordmark. Demote scoreboards/buttons to a small refined SANS (uppercase, tracked) so the header reads as a logo zone, not competing with the content. (g) Let color/imagery carry the meaning — do NOT slap letter labels on swatches/tiles; a bare luxury swatch beats a lettered one; when a build shows multiple 'styles/patterns', make them VISUALLY DISTINCT (different SVG/CSS motifs, not the same stripe at different densities). (h) NEVER use alert()/confirm()/prompt() — win/game-over/result states must be in-page overlays styled with the token palette. (i) NO external images or URLs (picsum.photos, unsplash, any CDN/http src) — the artifact runs under a strict no-network CSP so they render BROKEN; draw all patterns/imagery with CSS gradients or inline SVG only. (j) Actually INSTANTIATE the wordmark: put a real <header> element containing the wordmark text in the DOM (defining the CSS class is not enough), The wordmark/header text color MUST be the DARKEST ink token (near-black, e.g. #1c1a17 / var(--text)); NEVER a white/surface/background token — a common fatal bug is color:var(--surface) rendering the wordmark white-on-cream and invisible. Wordmark font-size >=40px. It must look like a luxury interior-design brand, not a generic AI demo. (No hamburger/nav needed — these are self-contained games/social widgets.)",
+ "id": "6f651f004b4c",
+ "title": "Designer Wallcoverings — Which Era Are You Game",
+ "prompt": "Build a single self-contained HTML file: a \"Which Design Era?\" guessing game. A CSS-rendered interior vignette appears in one of 4 era styles (Victorian, Art Deco, Mid-Century Modern, Grandmillennial); the player guesses from buttons. Score, 8 rounds, era fun-fact on reveal, best score in localStorage, restart. Luxe aesthetic. Output ONLY the HTML. DW LUXURY UI REQUIREMENTS (mandatory): (a) a fixed top bar with the wordmark 'DESIGNER WALLCOVERINGS' left-aligned in a SERIF display face (Cormorant Garamond / Playfair / EB Garamond via system serif stack), uppercase, letter-spacing .18em; (b) NEVER use system-ui/Arial as the display face — headings in the serif, body in a refined sans; generous type scale (headings >=24px); (c) a restrained luxury palette (deep near-black or warm ivory ground, ONE metallic/jewel accent), no muddy mid-tones, strong value contrast; (d) generous whitespace, hairline 1px strokes, soft shadows, tasteful easing on any motion. (e) Open with a CSS design-token block in :root (e.g. --bg, --ink, --accent, --line, --shadow, --ease) and reference the tokens throughout, so the palette is systematic not one-off. (f) The wordmark is a compact upper-left lockup that shows the FULL 'DESIGNER WALLCOVERINGS' text WITHOUT clipping — size the serif so it fits (~200-280px) or wrap to two lines; NEVER truncate/overflow-hidden the wordmark. Demote scoreboards/buttons to a small refined SANS (uppercase, tracked) so the header reads as a logo zone, not competing with the content. (g) Let color/imagery carry the meaning — do NOT slap letter labels on swatches/tiles; a bare luxury swatch beats a lettered one; when a build shows multiple 'styles/patterns', make them VISUALLY DISTINCT (different SVG/CSS motifs, not the same stripe at different densities). (h) NEVER use alert()/confirm()/prompt() — win/game-over/result states must be in-page overlays styled with the token palette. (i) NO external images or URLs (picsum.photos, unsplash, any CDN/http src) — the artifact runs under a strict no-network CSP so they render BROKEN; draw all patterns/imagery with CSS gradients or inline SVG only. (j) Actually INSTANTIATE the wordmark: put a real <header> element containing the wordmark text in the DOM (defining the CSS class is not enough), The wordmark/header text color MUST be the DARKEST ink token (near-black, e.g. #1c1a17 / var(--text)); NEVER a white/surface/background token — a common fatal bug is color:var(--surface) rendering the wordmark white-on-cream and invisible. Wordmark font-size >=40px. It must look like a luxury interior-design brand, not a generic AI demo. (No hamburger/nav needed — these are self-contained games/social widgets.)",
"category": "Real Work",
"designTools": true,
- "created_at": "2026-07-25T12:36:12.884Z",
+ "created_at": "2026-07-25T12:48:13.064Z",
"winner": null,
"runs": [
{
@@ -24451,7 +24796,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.889Z"
+ "queued_at": "2026-07-25T12:48:13.071Z"
},
{
"model": "gemma3-12b",
@@ -24461,7 +24806,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.892Z"
+ "queued_at": "2026-07-25T12:48:13.074Z"
},
{
"model": "hermes3-8b",
@@ -24471,7 +24816,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.896Z"
+ "queued_at": "2026-07-25T12:48:13.078Z"
},
{
"model": "qwen25-7b",
@@ -24481,7 +24826,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.900Z"
+ "queued_at": "2026-07-25T12:48:13.082Z"
},
{
"model": "hf-qwen-coder-32b",
@@ -24491,7 +24836,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.904Z"
+ "queued_at": "2026-07-25T12:48:13.086Z"
},
{
"model": "claude-code",
@@ -24501,7 +24846,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.908Z"
+ "queued_at": "2026-07-25T12:48:13.093Z"
},
{
"model": "kimi",
@@ -24511,7 +24856,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.912Z"
+ "queued_at": "2026-07-25T12:48:13.097Z"
},
{
"model": "gpt",
@@ -24521,7 +24866,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.916Z"
+ "queued_at": "2026-07-25T12:48:13.101Z"
},
{
"model": "grok",
@@ -24531,7 +24876,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:36:12.920Z"
+ "queued_at": "2026-07-25T12:48:13.105Z"
}
]
}
diff --git a/data/costlog.jsonl b/data/costlog.jsonl
index e8e409d..52be456 100644
--- a/data/costlog.jsonl
+++ b/data/costlog.jsonl
@@ -333,3 +333,9 @@
{"ts":"2026-07-25T12:26:42.374Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3229,"output_tokens":10212,"cost_usd":0.148619}
{"ts":"2026-07-25T12:27:44.170Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":3603,"output_tokens":6305,"cost_usd":0.017924}
{"ts":"2026-07-25T12:29:07.544Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":3971,"output_tokens":15424,"cost_usd":0.243273}
+{"ts":"2026-07-25T12:37:13.550Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3299,"output_tokens":7886,"cost_usd":0.116177}
+{"ts":"2026-07-25T12:38:07.942Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3508,"output_tokens":8953,"cost_usd":0.131481}
+{"ts":"2026-07-25T12:38:53.228Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4428,"output_tokens":11659,"cost_usd":0.188169}
+{"ts":"2026-07-25T12:40:32.747Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4071,"output_tokens":7649,"cost_usd":0.126948}
+{"ts":"2026-07-25T12:40:50.603Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":3647,"output_tokens":14195,"cost_usd":0.037676}
+{"ts":"2026-07-25T12:42:22.410Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":3703,"output_tokens":5757,"cost_usd":0.016614}
diff --git a/idea-run/.dw-brand-style-color-pointer b/idea-run/.dw-brand-style-color-pointer
index 1e8b314..45a4fb7 100644
--- a/idea-run/.dw-brand-style-color-pointer
+++ b/idea-run/.dw-brand-style-color-pointer
@@ -1 +1 @@
-6
+8
← 3c06c80 night-loop: cycle 05:36 — judged=172f180e3161 · fired 2 →; F
·
back to Model Arena
·
night-loop: cycle 06:00 — judged=bde366feb227 · fired 2 →; F f7d7255 →