← back to Model Arena
night-loop: cycle 06:00 — judged=bde366feb227 · fired 2 →; FIRED idx=8/16 id=c86c17be0c9b title=Designer Wallcoverings — Brand Mood Board Maker; FIRED idx=9/16 id=0a809ac3ac48 title=Designer Wallcoverings — Trending Color Reel
f7d72555f23ee0a090c1d6322efeaee37445781a · 2026-07-25 06:00:06 -0700 · Steve Abrams
Files touched
A data/artifacts/420dc7bd02b3/claude-code.htmlA data/artifacts/420dc7bd02b3/claude-code.pngA data/artifacts/420dc7bd02b3/gemma3-12b.htmlA data/artifacts/420dc7bd02b3/gemma3-12b.pngA data/artifacts/420dc7bd02b3/gpt.htmlA data/artifacts/420dc7bd02b3/gpt.pngA data/artifacts/420dc7bd02b3/grok.htmlA data/artifacts/420dc7bd02b3/grok.pngA data/artifacts/420dc7bd02b3/hermes3-8b.htmlA data/artifacts/420dc7bd02b3/hermes3-8b.pngA data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.htmlA data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.pngA data/artifacts/420dc7bd02b3/kimi.htmlA data/artifacts/420dc7bd02b3/kimi.pngA data/artifacts/420dc7bd02b3/qwen25-7b.htmlA data/artifacts/420dc7bd02b3/qwen25-7b.pngA data/artifacts/420dc7bd02b3/qwen3-14b.htmlA data/artifacts/420dc7bd02b3/qwen3-14b.pngA data/artifacts/6f651f004b4c/claude-code.htmlA data/artifacts/6f651f004b4c/claude-code.pngA data/artifacts/6f651f004b4c/gemma3-12b.htmlA data/artifacts/6f651f004b4c/gemma3-12b.pngA data/artifacts/6f651f004b4c/gpt.htmlA data/artifacts/6f651f004b4c/gpt.pngA data/artifacts/6f651f004b4c/grok.htmlA data/artifacts/6f651f004b4c/grok.pngA data/artifacts/6f651f004b4c/hermes3-8b.htmlA data/artifacts/6f651f004b4c/hermes3-8b.pngA data/artifacts/6f651f004b4c/hf-qwen-coder-32b.htmlA data/artifacts/6f651f004b4c/hf-qwen-coder-32b.pngA data/artifacts/6f651f004b4c/kimi.htmlA data/artifacts/6f651f004b4c/kimi.pngA data/artifacts/6f651f004b4c/qwen25-7b.htmlA data/artifacts/6f651f004b4c/qwen25-7b.pngA data/artifacts/6f651f004b4c/qwen3-14b.htmlA data/artifacts/6f651f004b4c/qwen3-14b.pngM data/challenges.jsonM data/costlog.jsonlM idea-run/.dw-brand-style-color-pointer
Diff
commit f7d72555f23ee0a090c1d6322efeaee37445781a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Jul 25 06:00:06 2026 -0700
night-loop: cycle 06:00 — judged=bde366feb227 · fired 2 →; FIRED idx=8/16 id=c86c17be0c9b title=Designer Wallcoverings — Brand Mood Board Maker; FIRED idx=9/16 id=0a809ac3ac48 title=Designer Wallcoverings — Trending Color Reel
---
data/artifacts/420dc7bd02b3/claude-code.html | 666 ++++++++
data/artifacts/420dc7bd02b3/claude-code.png | Bin 0 -> 68603 bytes
data/artifacts/420dc7bd02b3/gemma3-12b.html | 301 ++++
data/artifacts/420dc7bd02b3/gemma3-12b.png | Bin 0 -> 31325 bytes
data/artifacts/420dc7bd02b3/gpt.html | 1549 +++++++++++++++++++
data/artifacts/420dc7bd02b3/gpt.png | Bin 0 -> 165168 bytes
data/artifacts/420dc7bd02b3/grok.html | 1237 +++++++++++++++
data/artifacts/420dc7bd02b3/grok.png | Bin 0 -> 53774 bytes
data/artifacts/420dc7bd02b3/hermes3-8b.html | 180 +++
data/artifacts/420dc7bd02b3/hermes3-8b.png | Bin 0 -> 26134 bytes
data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.html | 215 +++
data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.png | Bin 0 -> 23155 bytes
data/artifacts/420dc7bd02b3/kimi.html | 885 +++++++++++
data/artifacts/420dc7bd02b3/kimi.png | Bin 0 -> 113249 bytes
data/artifacts/420dc7bd02b3/qwen25-7b.html | 120 ++
data/artifacts/420dc7bd02b3/qwen25-7b.png | Bin 0 -> 33299 bytes
data/artifacts/420dc7bd02b3/qwen3-14b.html | 319 ++++
data/artifacts/420dc7bd02b3/qwen3-14b.png | Bin 0 -> 44131 bytes
data/artifacts/6f651f004b4c/claude-code.html | 584 +++++++
data/artifacts/6f651f004b4c/claude-code.png | Bin 0 -> 79616 bytes
data/artifacts/6f651f004b4c/gemma3-12b.html | 249 +++
data/artifacts/6f651f004b4c/gemma3-12b.png | Bin 0 -> 25522 bytes
data/artifacts/6f651f004b4c/gpt.html | 1597 ++++++++++++++++++++
data/artifacts/6f651f004b4c/gpt.png | Bin 0 -> 238996 bytes
data/artifacts/6f651f004b4c/grok.html | 1425 +++++++++++++++++
data/artifacts/6f651f004b4c/grok.png | Bin 0 -> 37473 bytes
data/artifacts/6f651f004b4c/hermes3-8b.html | 238 +++
data/artifacts/6f651f004b4c/hermes3-8b.png | Bin 0 -> 27358 bytes
data/artifacts/6f651f004b4c/hf-qwen-coder-32b.html | 300 ++++
data/artifacts/6f651f004b4c/hf-qwen-coder-32b.png | Bin 0 -> 63741 bytes
data/artifacts/6f651f004b4c/kimi.html | 707 +++++++++
data/artifacts/6f651f004b4c/kimi.png | Bin 0 -> 60618 bytes
data/artifacts/6f651f004b4c/qwen25-7b.html | 163 ++
data/artifacts/6f651f004b4c/qwen25-7b.png | Bin 0 -> 22904 bytes
data/artifacts/6f651f004b4c/qwen3-14b.html | 337 +++++
data/artifacts/6f651f004b4c/qwen3-14b.png | Bin 0 -> 67435 bytes
data/challenges.json | 552 ++++++-
data/costlog.jsonl | 6 +
idea-run/.dw-brand-style-color-pointer | 2 +-
39 files changed, 11591 insertions(+), 41 deletions(-)
diff --git a/data/artifacts/420dc7bd02b3/claude-code.html b/data/artifacts/420dc7bd02b3/claude-code.html
new file mode 100644
index 0000000..9423545
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/claude-code.html
@@ -0,0 +1,666 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Palette Atelier</title>
+<style>
+ :root{
+ /* ——— design tokens ——— */
+ --bg:#faf8f4;
+ --surface:#ffffff;
+ --text:#1c1a17;
+ --ink:#1c1a17;
+ --muted:#9b948a;
+ --line:#e6e0d6;
+ --accent:#2f4c39; /* jewel — deep viridian */
+ --accent-2:#b0472e; /* terracotta hairline highlight */
+ --shadow:0 8px 24px rgba(28,26,23,.10);
+ --shadow-hover:0 16px 48px rgba(28,26,23,.16);
+ --ease:cubic-bezier(.22,1,.36,1);
+ --serif:'Didot','Bodoni MT','Playfair Display',Georgia,'Times New Roman',serif;
+ --sans:-apple-system,'Segoe UI','Helvetica Neue',Arial,sans-serif;
+ --r:14px;
+ }
+
+ *{box-sizing:border-box;margin:0;padding:0}
+ html,body{background:var(--bg);color:var(--text);font-family:var(--sans);}
+ body{
+ min-height:100vh;
+ -webkit-font-smoothing:antialiased;
+ background:
+ radial-gradient(1200px 600px at 80% -10%, rgba(47,76,57,.05), transparent 60%),
+ radial-gradient(900px 500px at -10% 110%, rgba(176,71,46,.04), transparent 60%),
+ var(--bg);
+ }
+
+ /* ——— header / wordmark lockup ——— */
+ header.topbar{
+ position:sticky;top:0;z-index:50;
+ display:flex;align-items:center;justify-content:space-between;
+ gap:24px;
+ padding:20px 40px;
+ background:rgba(250,248,244,.86);
+ backdrop-filter:blur(14px);
+ border-bottom:1px solid var(--line);
+ }
+ .wordmark{
+ font-family:var(--serif);
+ color:var(--ink);
+ font-size:42px;
+ line-height:.98;
+ font-weight:600;
+ text-transform:uppercase;
+ letter-spacing:.18em;
+ white-space:normal;
+ max-width:300px;
+ }
+ .wordmark small{display:block;font-size:42px;letter-spacing:.18em;}
+ .topbar .rail{
+ display:flex;align-items:center;gap:28px;
+ }
+ .topbar .meta{
+ font-family:var(--sans);
+ text-transform:uppercase;
+ letter-spacing:.15em;
+ font-size:12px;
+ color:var(--muted);
+ }
+ .topbar .meta b{color:var(--text);font-weight:600;}
+
+ /* ——— layout ——— */
+ main{max-width:1180px;margin:0 auto;padding:64px 40px 128px;}
+ .lede{
+ max-width:640px;margin-bottom:56px;
+ animation:fadeUp .7s var(--ease) both;
+ }
+ .kicker{
+ text-transform:uppercase;letter-spacing:.15em;font-size:12px;
+ color:var(--accent);font-weight:600;margin-bottom:16px;
+ }
+ h1{
+ font-family:var(--serif);font-weight:600;
+ font-size:54px;line-height:1.04;letter-spacing:.01em;
+ margin-bottom:18px;
+ }
+ .lede p{font-size:19px;line-height:1.6;color:#4a453d;}
+
+ .studio{
+ display:grid;
+ grid-template-columns:340px 1fr;
+ gap:48px;
+ align-items:start;
+ }
+ @media(max-width:880px){ .studio{grid-template-columns:1fr;gap:40px;} }
+
+ /* ——— wheel panel ——— */
+ .panel{
+ background:var(--surface);
+ border:1px solid var(--line);
+ border-radius:var(--r);
+ box-shadow:var(--shadow);
+ padding:32px;
+ animation:fadeUp .7s var(--ease) both;
+ }
+ .panel.d2{animation-delay:.09s}
+ .panel h3{
+ font-family:var(--serif);font-size:26px;font-weight:600;margin-bottom:6px;
+ }
+ .panel .sub{
+ text-transform:uppercase;letter-spacing:.15em;font-size:12px;
+ color:var(--muted);margin-bottom:24px;
+ }
+
+ .wheel-wrap{position:relative;width:260px;height:260px;margin:0 auto 8px;}
+ #wheel{border-radius:50%;cursor:crosshair;display:block;
+ box-shadow:inset 0 0 0 1px var(--line), var(--shadow);}
+ .wheel-hole{
+ position:absolute;inset:64px;border-radius:50%;
+ background:var(--surface);
+ display:flex;align-items:center;justify-content:center;
+ flex-direction:column;text-align:center;
+ box-shadow:inset 0 0 0 1px var(--line);
+ pointer-events:none;
+ }
+ .wheel-hole .hx{font-family:var(--serif);font-size:22px;letter-spacing:.04em;}
+ .wheel-hole .hl{text-transform:uppercase;letter-spacing:.15em;font-size:10px;color:var(--muted);margin-top:4px;}
+ #picker{
+ position:absolute;width:22px;height:22px;border-radius:50%;
+ border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.35),0 4px 10px rgba(0,0,0,.3);
+ transform:translate(-50%,-50%);pointer-events:none;transition:left .15s var(--ease),top .15s var(--ease);
+ }
+
+ .harmony{
+ display:flex;gap:0;margin:28px 0 22px;
+ border:1px solid var(--line);border-radius:999px;padding:4px;background:var(--bg);
+ }
+ .harmony button{
+ flex:1;border:0;background:transparent;cursor:pointer;
+ font-family:var(--sans);text-transform:uppercase;letter-spacing:.12em;
+ font-size:11px;font-weight:600;color:var(--muted);
+ padding:10px 6px;border-radius:999px;transition:all .2s var(--ease);
+ }
+ .harmony button.on{background:var(--accent);color:#fff;box-shadow:var(--shadow);}
+
+ .tune{margin-top:6px}
+ .tune label{
+ display:flex;justify-content:space-between;
+ text-transform:uppercase;letter-spacing:.12em;font-size:11px;color:var(--muted);
+ margin:16px 0 8px;
+ }
+ input[type=range]{
+ -webkit-appearance:none;width:100%;height:2px;background:var(--line);border-radius:2px;outline:0;
+ }
+ input[type=range]::-webkit-slider-thumb{
+ -webkit-appearance:none;width:18px;height:18px;border-radius:50%;
+ background:var(--surface);border:1px solid var(--accent);cursor:pointer;box-shadow:var(--shadow);
+ }
+ input[type=range]::-moz-range-thumb{
+ width:18px;height:18px;border-radius:50%;background:var(--surface);
+ border:1px solid var(--accent);cursor:pointer;
+ }
+
+ .btn{
+ font-family:var(--sans);text-transform:uppercase;letter-spacing:.14em;font-weight:600;
+ font-size:12px;cursor:pointer;border-radius:999px;
+ padding:14px 22px;transition:all .2s var(--ease);
+ border:1px solid var(--ink);background:var(--ink);color:var(--bg);
+ }
+ .btn:hover{transform:translateY(-1px);box-shadow:var(--shadow-hover);}
+ .btn.ghost{background:transparent;color:var(--ink);}
+ .btn.ghost:hover{background:var(--ink);color:var(--bg);}
+ .btn-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:26px}
+
+ /* ——— palette panel ——— */
+ .swatches{
+ display:grid;grid-template-columns:repeat(5,1fr);gap:0;
+ border-radius:var(--r);overflow:hidden;border:1px solid var(--line);box-shadow:var(--shadow);
+ }
+ @media(max-width:620px){ .swatches{grid-template-columns:repeat(5,1fr);} }
+ .sw{
+ position:relative;cursor:pointer;
+ min-height:280px;
+ display:flex;flex-direction:column;justify-content:flex-end;
+ padding:20px 16px;
+ transition:flex .3s var(--ease);
+ animation:fadeUp .6s var(--ease) both;
+ }
+ .sw::after{
+ content:"";position:absolute;inset:0;
+ background:linear-gradient(to top, rgba(0,0,0,.32), rgba(0,0,0,0) 46%);
+ opacity:0;transition:opacity .25s var(--ease);pointer-events:none;
+ }
+ .sw:hover::after{opacity:1}
+ .sw .info{position:relative;z-index:2;transition:transform .25s var(--ease)}
+ .sw:hover .info{transform:translateY(-4px)}
+ .sw .name{font-family:var(--serif);font-size:21px;font-weight:600;line-height:1.05;}
+ .sw .hex{
+ font-family:var(--sans);text-transform:uppercase;letter-spacing:.14em;
+ font-size:11px;margin-top:6px;opacity:.82;
+ }
+ .sw .copy-tag{
+ position:absolute;top:14px;left:16px;z-index:2;
+ text-transform:uppercase;letter-spacing:.14em;font-size:10px;font-weight:600;
+ opacity:0;transition:opacity .25s var(--ease);
+ }
+ .sw:hover .copy-tag{opacity:.7}
+
+ /* ——— room preview ——— */
+ .roomblock{margin-top:40px;animation:fadeUp .7s var(--ease) both;animation-delay:.12s}
+ .roomblock .caption{
+ text-transform:uppercase;letter-spacing:.15em;font-size:12px;color:var(--muted);margin-bottom:16px;
+ }
+ .room{
+ position:relative;height:220px;border-radius:var(--r);overflow:hidden;
+ border:1px solid var(--line);box-shadow:var(--shadow);
+ display:flex;
+ }
+ .room .wall{flex:2;position:relative;}
+ .room .wall .molding{position:absolute;left:0;right:0;bottom:0;height:14%;border-top:1px solid rgba(0,0,0,.12);}
+ .room .accentwall{flex:1;border-left:1px solid rgba(0,0,0,.10);position:relative;}
+ .room .rug{
+ position:absolute;left:8%;right:34%;bottom:10px;height:26px;border-radius:6px;
+ box-shadow:0 6px 14px rgba(0,0,0,.22);
+ }
+ .room .sofa{
+ position:absolute;left:12%;bottom:34px;width:34%;height:70px;border-radius:12px 12px 6px 6px;
+ box-shadow:0 8px 18px rgba(0,0,0,.22);
+ }
+ .room .sofa .cushion{position:absolute;top:10px;left:8%;width:26%;height:26px;border-radius:6px;opacity:.85}
+ .room .sofa .cushion.two{left:auto;right:8%}
+ .room .art{
+ position:absolute;top:26px;right:16%;width:60px;height:78px;border-radius:3px;
+ border:4px solid rgba(255,255,255,.5);box-shadow:0 6px 14px rgba(0,0,0,.25);
+ }
+ .room .vase{position:absolute;right:8%;bottom:34px;width:34px;height:64px;border-radius:8px 8px 20px 20px;box-shadow:0 6px 14px rgba(0,0,0,.28)}
+
+ /* ——— toast overlay ——— */
+ .toast{
+ position:fixed;left:50%;bottom:40px;transform:translate(-50%,120%);
+ background:var(--ink);color:var(--bg);
+ padding:14px 26px;border-radius:999px;box-shadow:var(--shadow-hover);
+ font-size:12px;text-transform:uppercase;letter-spacing:.14em;font-weight:600;
+ z-index:100;transition:transform .4s var(--ease);
+ display:flex;align-items:center;gap:10px;
+ }
+ .toast.show{transform:translate(-50%,0)}
+ .toast .dot{width:12px;height:12px;border-radius:50%;box-shadow:0 0 0 1px rgba(255,255,255,.4)}
+
+ footer{
+ text-align:center;padding:40px;color:var(--muted);
+ text-transform:uppercase;letter-spacing:.15em;font-size:11px;border-top:1px solid var(--line);
+ }
+
+ @keyframes fadeUp{from{opacity:0;transform:translateY(28px)}to{opacity:1;transform:none}}
+</style>
+</head>
+<body>
+
+<header class="topbar">
+ <div class="wordmark">Designer<small>Wallcoverings</small></div>
+ <div class="rail">
+ <span class="meta">Palette Atelier</span>
+ <span class="meta">Est. <b>MCMXCII</b></span>
+ </div>
+</header>
+
+<main>
+ <section class="lede">
+ <div class="kicker">The Colour Studio</div>
+ <h1>Compose a wallcovering palette worth framing.</h1>
+ <p>Turn the wheel to choose a base hue. The atelier returns a curated five-tone palette — each shade named in the language of the trade — ready to copy, preview on the wall, and share.</p>
+ </section>
+
+ <div class="studio">
+ <!-- controls -->
+ <div class="panel">
+ <h3>The Wheel</h3>
+ <div class="sub">Select a base hue</div>
+ <div class="wheel-wrap">
+ <canvas id="wheel" width="260" height="260"></canvas>
+ <div class="wheel-hole">
+ <span class="hx" id="baseHex">#000000</span>
+ <span class="hl">Base Tone</span>
+ </div>
+ <div id="picker"></div>
+ </div>
+
+ <div class="harmony" id="harmony">
+ <button data-mode="analogous" class="on">Analogous</button>
+ <button data-mode="complementary">Complement</button>
+ <button data-mode="triadic">Triadic</button>
+ </div>
+
+ <div class="tune">
+ <label>Saturation <span id="satVal">62%</span></label>
+ <input type="range" id="sat" min="20" max="90" value="62">
+ <label>Softness <span id="litVal">balanced</span></label>
+ <input type="range" id="lit" min="0" max="100" value="50">
+ </div>
+
+ <div class="btn-row">
+ <button class="btn ghost" id="shuffle">Reshuffle</button>
+ <button class="btn" id="export">Export Card ▸</button>
+ </div>
+ </div>
+
+ <!-- palette + room -->
+ <div class="panel d2">
+ <h3>The Palette</h3>
+ <div class="sub">Click any tone to copy its hex</div>
+ <div class="swatches" id="swatches"></div>
+
+ <div class="roomblock">
+ <div class="caption">Live Room Preview</div>
+ <div class="room" id="room">
+ <div class="wall" id="rWall"><div class="molding" id="rMold"></div></div>
+ <div class="accentwall" id="rAccent">
+ <div class="art" id="rArt"></div>
+ </div>
+ <div class="rug" id="rRug"></div>
+ <div class="sofa" id="rSofa">
+ <div class="cushion" id="rC1"></div>
+ <div class="cushion two" id="rC2"></div>
+ </div>
+ <div class="vase" id="rVase"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+</main>
+
+<div class="toast" id="toast"><span class="dot" id="toastDot"></span><span id="toastMsg">Copied</span></div>
+
+<footer>Designer Wallcoverings · Palette Atelier · Colours for the considered interior</footer>
+
+<canvas id="exportCanvas" width="1080" height="1080" style="display:none"></canvas>
+
+<script>
+(function(){
+ "use strict";
+
+ /* ---------- color utilities ---------- */
+ function hslToRgb(h,s,l){
+ h/=360;s/=100;l/=100;
+ let r,g,b;
+ if(s===0){r=g=b=l;}
+ else{
+ const q=l<.5?l*(1+s):l+s-l*s, p=2*l-q;
+ const hue2rgb=(p,q,t)=>{
+ if(t<0)t+=1; if(t>1)t-=1;
+ if(t<1/6)return p+(q-p)*6*t;
+ if(t<1/2)return q;
+ if(t<2/3)return p+(q-p)*(2/3-t)*6;
+ return p;
+ };
+ r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);
+ }
+ return [Math.round(r*255),Math.round(g*255),Math.round(b*255)];
+ }
+ function hslToHex(h,s,l){
+ const [r,g,b]=hslToRgb(h,s,l);
+ return "#"+[r,g,b].map(x=>x.toString(16).padStart(2,"0")).join("");
+ }
+ function luminance(h,s,l){
+ const [r,g,b]=hslToRgb(h,s,l).map(v=>{v/=255;return v<=.03928?v/12.92:Math.pow((v+.055)/1.055,2.4);});
+ return .2126*r+.7152*g+.0722*b;
+ }
+ function textOn(h,s,l){ return luminance(h,s,l)>.42 ? "#1c1a17" : "#f5f2ea"; }
+
+ /* ---------- designer name lexicon ---------- */
+ // keyed by hue family, chosen by lightness band
+ const NAMES = {
+ red: {light:["Blush","Shell Pink","Rosewater"], mid:["Terracotta","Cinnabar","Madder"], dark:["Oxblood","Claret","Garnet"]},
+ orange: {light:["Alabaster","Fawn","Bisque"], mid:["Ochre","Amber","Sienna"], dark:["Bronze","Umber","Ember"]},
+ yellow: {light:["Chalk","Straw","Buttermilk"], mid:["Brass","Saffron","Honey"], dark:["Antique Gold","Bronze","Mustard"]},
+ chartreuse:{light:["Linen","Pistachio","Vellum"], mid:["Celadon","Moss","Olive"], dark:["Verdigris","Bay Leaf","Cypress"]},
+ green: {light:["Celadon","Seafoam","Sage"], mid:["Fern","Viridian","Malachite"], dark:["Forest","Bottle Green","Ink Green"]},
+ teal: {light:["Duck Egg","Aqua Mist","Frost"], mid:["Celadon Teal","Peacock","Verde"], dark:["Deep Teal","Spruce","Hunter"]},
+ blue: {light:["Powder","Wedgwood","Sky"], mid:["Delft","Prussian","Cerulean"], dark:["Indigo","Midnight","Ink"]},
+ indigo: {light:["Wisteria","Lavender Grey","Haze"],mid:["Iris","Periwinkle","Ultramarine"],dark:["Indigo","Navy Ink","Slate Blue"]},
+ violet: {light:["Orchid Mist","Heather","Lilac"], mid:["Amethyst","Plum","Mauve"], dark:["Aubergine","Damson","Byzantium"]},
+ magenta: {light:["Petal","Fondant","Rose Quartz"], mid:["Fuchsia","Raspberry","Magenta"], dark:["Wine","Mulberry","Tyrian"]},
+ neutral: {light:["Alabaster","Greige","Oatmeal"], mid:["Taupe","Fossil","Stone"], dark:["Charcoal","Graphite","Ink"]}
+ };
+ function hueFamily(h,s){
+ if(s<12) return "neutral";
+ if(h<15||h>=345) return "red";
+ if(h<40) return "orange";
+ if(h<62) return "yellow";
+ if(h<85) return "chartreuse";
+ if(h<150) return "green";
+ if(h<185) return "teal";
+ if(h<225) return "blue";
+ if(h<260) return "indigo";
+ if(h<290) return "violet";
+ return "magenta";
+ }
+ function nameFor(h,s,l,idx){
+ const fam=NAMES[hueFamily(h,s)];
+ const band = l>66?"light" : l<38?"dark" : "mid";
+ const pool=fam[band];
+ return pool[idx % pool.length];
+ }
+
+ /* ---------- state ---------- */
+ let baseHue=170, mode="analogous", satBase=62, litSpread=50;
+ let palette=[]; // {h,s,l,hex,name}
+
+ const R=130, CX=130, CY=130;
+
+ /* ---------- draw wheel ---------- */
+ const wheel=document.getElementById("wheel");
+ const wctx=wheel.getContext("2d");
+ function drawWheel(){
+ const img=wctx.createImageData(260,260);
+ for(let y=0;y<260;y++){
+ for(let x=0;x<260;x++){
+ const dx=x-CX, dy=y-CY, dist=Math.sqrt(dx*dx+dy*dy);
+ const i=(y*260+x)*4;
+ if(dist>R||dist<64){ img.data[i+3]=0; continue; }
+ let ang=Math.atan2(dy,dx)*180/Math.PI; if(ang<0)ang+=360;
+ const [r,g,b]=hslToRgb(ang,58,52);
+ img.data[i]=r;img.data[i+1]=g;img.data[i+2]=b;img.data[i+3]=255;
+ }
+ }
+ wctx.putImageData(img,0,0);
+ }
+ drawWheel();
+
+ function placePicker(){
+ const rad=(R+64)/2;
+ const a=baseHue*Math.PI/180;
+ const px=CX+Math.cos(a)*rad, py=CY+Math.sin(a)*rad;
+ const pk=document.getElementById("picker");
+ pk.style.left=px+"px"; pk.style.top=py+"px";
+ pk.style.background=hslToHex(baseHue,satBase,50);
+ }
+
+ wheel.addEventListener("click",e=>{
+ const rect=wheel.getBoundingClientRect();
+ const x=e.clientX-rect.left, y=e.clientY-rect.top;
+ let ang=Math.atan2(y-CY,x-CX)*180/Math.PI; if(ang<0)ang+=360;
+ baseHue=Math.round(ang);
+ build();
+ });
+
+ /* ---------- harmony offsets ---------- */
+ function offsets(){
+ if(mode==="analogous") return [-32,-16,0,16,32];
+ if(mode==="complementary")return [0,-14,180,166,194];
+ return [0,120,240,60,300]; // triadic + splits
+ }
+
+ /* ---------- build palette ---------- */
+ function build(){
+ const offs=offsets();
+ // lightness ladder from soft to deep, shaped by litSpread
+ const spread = 0.4 + (litSpread/100)*0.6; // 0.4 - 1.0
+ const centers=[82,66,50,34,20];
+ palette=offs.map((o,i)=>{
+ const h=((baseHue+o)%360+360)%360;
+ // saturation tapers slightly at the extremes for a refined, un-muddy read
+ let s=satBase;
+ if(centers[i]>=78) s=Math.max(14,satBase*0.35); // near-white: chalky
+ else if(centers[i]<=24) s=Math.min(90,satBase*0.9+8);
+ // apply softness spread around center
+ let l = 50 + (centers[i]-50)*spread;
+ l=Math.max(12,Math.min(90,l));
+ const hex=hslToHex(h,s,l);
+ return {h,s,l,hex,name:nameFor(h,s,l,i)};
+ });
+ render();
+ }
+
+ /* ---------- render ---------- */
+ const swEl=document.getElementById("swatches");
+ function render(){
+ document.getElementById("baseHex").textContent=hslToHex(baseHue,satBase,50).toUpperCase();
+ placePicker();
+
+ swEl.innerHTML="";
+ palette.forEach((p,i)=>{
+ const t=textOn(p.h,p.s,p.l);
+ const d=document.createElement("div");
+ d.className="sw";
+ d.style.background=p.hex;
+ d.style.color=t;
+ d.style.animationDelay=(i*0.06)+"s";
+ d.innerHTML=`
+ <span class="copy-tag">Copy</span>
+ <div class="info">
+ <div class="name">${p.name}</div>
+ <div class="hex">${p.hex.toUpperCase()}</div>
+ </div>`;
+ d.addEventListener("click",()=>copy(p));
+ swEl.appendChild(d);
+ });
+ paintRoom();
+ }
+
+ /* ---------- room preview ---------- */
+ function paintRoom(){
+ // map palette tones: [lightest, light, mid, deep, darkest]
+ const [c0,c1,c2,c3,c4]=palette;
+ document.getElementById("rWall").style.background =
+ `linear-gradient(180deg, ${c1.hex} 0%, ${c0.hex} 100%)`;
+ document.getElementById("rMold").style.background=c0.hex;
+ document.getElementById("rAccent").style.background=c3.hex;
+ document.getElementById("rSofa").style.background=c2.hex;
+ document.getElementById("rC1").style.background=c4.hex;
+ document.getElementById("rC2").style.background=c0.hex;
+ document.getElementById("rRug").style.background=
+ `repeating-linear-gradient(90deg, ${c2.hex} 0 14px, ${c3.hex} 14px 28px)`;
+ document.getElementById("rArt").style.background=
+ `linear-gradient(135deg, ${c0.hex}, ${c2.hex})`;
+ document.getElementById("rVase").style.background=c4.hex;
+ }
+
+ /* ---------- copy ---------- */
+ const toast=document.getElementById("toast");
+ let toastT;
+ function showToast(msg,color){
+ document.getElementById("toastMsg").textContent=msg;
+ document.getElementById("toastDot").style.background=color||"var(--accent)";
+ toast.classList.add("show");
+ clearTimeout(toastT);
+ toastT=setTimeout(()=>toast.classList.remove("show"),1800);
+ }
+ function copy(p){
+ const hx=p.hex.toUpperCase();
+ if(navigator.clipboard&&navigator.clipboard.writeText){
+ navigator.clipboard.writeText(hx).then(
+ ()=>showToast(p.name+" · "+hx,p.hex),
+ ()=>fallbackCopy(hx,p)
+ );
+ } else fallbackCopy(hx,p);
+ }
+ function fallbackCopy(hx,p){
+ const ta=document.createElement("textarea");
+ ta.value=hx;ta.style.position="fixed";ta.style.opacity="0";
+ document.body.appendChild(ta);ta.select();
+ try{document.execCommand("copy");showToast(p.name+" · "+hx,p.hex);}
+ catch(e){showToast("Hex: "+hx,p.hex);}
+ document.body.removeChild(ta);
+ }
+
+ /* ---------- controls wiring ---------- */
+ document.querySelectorAll("#harmony button").forEach(b=>{
+ b.addEventListener("click",()=>{
+ document.querySelectorAll("#harmony button").forEach(x=>x.classList.remove("on"));
+ b.classList.add("on");
+ mode=b.dataset.mode;
+ build();
+ });
+ });
+ const satEl=document.getElementById("sat");
+ satEl.addEventListener("input",()=>{
+ satBase=+satEl.value;
+ document.getElementById("satVal").textContent=satBase+"%";
+ build();
+ });
+ const litEl=document.getElementById("lit");
+ litEl.addEventListener("input",()=>{
+ litSpread=+litEl.value;
+ document.getElementById("litVal").textContent=
+ litSpread<34?"gentle":litSpread>66?"dramatic":"balanced";
+ build();
+ });
+ document.getElementById("shuffle").addEventListener("click",()=>{
+ baseHue=Math.floor(Math.random()*360);
+ satBase=48+Math.floor(Math.random()*36);
+ satEl.value=satBase;document.getElementById("satVal").textContent=satBase+"%";
+ build();
+ showToast("New base hue",hslToHex(baseHue,satBase,50));
+ });
+
+ /* ---------- export 1080x1080 card ---------- */
+ document.getElementById("export").addEventListener("click",exportCard);
+ function exportCard(){
+ const c=document.getElementById("exportCanvas");
+ const x=c.getContext("2d");
+ const W=1080,H=1080;
+ // ground
+ x.fillStyle="#faf8f4";x.fillRect(0,0,W,H);
+
+ // top wordmark
+ x.fillStyle="#1c1a17";
+ x.textBaseline="alphabetic";
+ x.font="600 46px 'Didot','Bodoni MT',Georgia,serif";
+ x.textAlign="left";
+ x.save();
+ // manual letter-spacing
+ drawTracked(x,"DESIGNER WALLCOVERINGS",80,120,6);
+ x.restore();
+ x.strokeStyle="#e6e0d6";x.lineWidth=1;
+ x.beginPath();x.moveTo(80,150);x.lineTo(W-80,150);x.stroke();
+
+ // subtitle
+ x.fillStyle="#9b948a";
+ x.font="600 20px -apple-system,'Segoe UI',Arial,sans-serif";
+ drawTracked(x,"PALETTE ATELIER · "+mode.toUpperCase(),80,192,4);
+
+ // palette title
+ x.fillStyle="#1c1a17";
+ x.font="600 60px 'Didot','Bodoni MT',Georgia,serif";
+ x.fillText("The "+ (palette[0]? hueFamily(baseHue,satBase).replace(/^\w/,m=>m.toUpperCase()):"") +" Story",80,270);
+
+ // big swatch stack
+ const startY=320, blockH=118, gap=0, sx=80, sw=W-160;
+ palette.forEach((p,i)=>{
+ const y=startY+i*blockH;
+ x.fillStyle=p.hex;
+ x.fillRect(sx,y,sw,blockH);
+ const t=textOn(p.h,p.s,p.l);
+ x.fillStyle=t;
+ x.font="600 40px 'Didot','Bodoni MT',Georgia,serif";
+ x.textAlign="left";
+ x.fillText(p.name,sx+40,y+blockH/2+2);
+ x.font="600 24px -apple-system,'Segoe UI',Arial,sans-serif";
+ x.textAlign="right";
+ drawTracked(x,p.hex.toUpperCase(),sx+sw-40,y+blockH/2+8,4,"right");
+ x.textAlign="left";
+ });
+
+ // footer bar
+ const fy=startY+palette.length*blockH+56;
+ x.fillStyle="#2f4c39";
+ x.fillRect(80,fy,W-160,4);
+ x.fillStyle="#9b948a";
+ x.font="600 20px -apple-system,'Segoe UI',Arial,sans-serif";
+ x.textAlign="center";
+ drawTracked(x,"COLOURS FOR THE CONSIDERED INTERIOR",W/2,fy+52,4,"center");
+ x.textAlign="left";
+
+ // download
+ c.toBlob(function(blob){
+ const url=URL.createObjectURL(blob);
+ const a=document.createElement("a");
+ a.href=url;a.download="dw-palette-"+mode+".png";
+ document.body.appendChild(a);a.click();document.body.removeChild(a);
+ setTimeout(()=>URL.revokeObjectURL(url),1500);
+ showToast("Card exported · 1080×1080","#2f4c39");
+ },"image/png");
+ }
+ function drawTracked(ctx,str,x,y,tracking,align){
+ align=align||"left";
+ // compute total width with tracking
+ let total=0;
+ for(const ch of str) total+=ctx.measureText(ch).width+tracking;
+ total-=tracking;
+ let cx = align==="right" ? x-total : align==="center" ? x-total/2 : x;
+ const savedAlign=ctx.textAlign; ctx.textAlign="left";
+ for(const ch of str){
+ ctx.fillText(ch,cx,y);
+ cx+=ctx.measureText(ch).width+tracking;
+ }
+ ctx.textAlign=savedAlign;
+ }
+
+ /* ---------- init ---------- */
+ document.getElementById("litVal").textContent="balanced";
+ build();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/claude-code.png b/data/artifacts/420dc7bd02b3/claude-code.png
new file mode 100644
index 0000000..54da35b
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/claude-code.png differ
diff --git a/data/artifacts/420dc7bd02b3/gemma3-12b.html b/data/artifacts/420dc7bd02b3/gemma3-12b.html
new file mode 100644
index 0000000..e1d53a2
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/gemma3-12b.html
@@ -0,0 +1,301 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Designer Wallcoverings Palette Builder</title>
+ <style>
+ :root {
+ --bg: #faf8f4; /* Ivory Gallery */
+ --surface: #ffffff;
+ --text: #3a2c22; /* Terracotta Sun */
+ --muted: #9b948a; /* Ivory Gallery */
+ --accent: #b0472e; /* Ivory Gallery - Deep Red */
+ --line: rgba(58, 46, 34, 0.1);
+ --shadow: rgba(0, 0, 0, 0.12);
+ --ease: cubic-bezier(.22,1,.36,1);
+
+ /* Synthwave for demo purposes - can be switched out */
+ /*
+ --bg: #12002b;
+ --surface: #1e0b3d;
+ --text: #f3e9ff;
+ --muted: #8d7bb0;
+ --accent: #ff2e88;
+ */
+ }
+
+ body {
+ font-family: sans-serif;
+ background-color: var(--bg);
+ color: var(--text);
+ margin: 0;
+ padding: 0;
+ overflow-x: hidden; /* Prevent horizontal scroll */
+ }
+
+ header {
+ background-color: var(--surface);
+ padding: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: left;
+ font-family: 'Didot', serif; /* Or other serif font */
+ font-size: 67px;
+ letter-spacing: .18em;
+ text-transform: uppercase;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); /* Subtle shadow */
+ }
+
+ main {
+ padding: 96px 24px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+ section {
+ margin-bottom: 48px;
+ }
+
+ .palette-controls {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 32px;
+ }
+
+ .control-button {
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ padding: 8px 16px;
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ cursor: pointer;
+ margin: 0 8px;
+ border-radius: 4px;
+ transition: background-color 0.2s var(--ease);
+ }
+
+ .control-button:hover {
+ background-color: rgba(255, 255, 255, 0.9);
+ }
+
+
+ .palette-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+ width: 100%;
+ }
+
+ .color-swatch {
+ background-color: transparent; /* Make background transparent */
+ border: 1px solid var(--line);
+ padding: 32px;
+ text-align: center;
+ border-radius: 14px;
+ box-shadow: 0 8px 24px var(--shadow);
+ transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
+ cursor: pointer;
+ }
+
+ .color-swatch:hover {
+ transform: translateY(-8px);
+ box-shadow: 0 16px 48px var(--shadow);
+ }
+
+
+ .room-preview {
+ width: 100%;
+ max-width: 600px;
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ padding: 16px;
+ margin-top: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .room-preview div {
+ width:48%;
+ height: 100px;
+ border: 1px solid var(--line);
+ margin: 0 8px;
+ background-size: cover;
+ }
+
+ .export-button {
+ background-color: var(--accent);
+ color: var(--surface);
+ padding: 12px 24px;
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ border: none;
+ cursor: pointer;
+ border-radius: 4px;
+ transition: background-color 0.2s var(--ease);
+ margin-top: 32px;
+
+ }
+
+ .export-button:hover {
+ background-color: rgba(176, 67, 40, 0.8)
+ }
+
+ /* Animations */
+ @keyframes fadeUp {
+ from { opacity: 0; transform: translateY(28px); }
+ to { opacity: 1; transform: none; }
+ }
+
+ body.loaded {
+ animation: fadeUp .7s var(--ease) both;
+ }
+
+
+ </style>
+</head>
+<body class="preload">
+ <header>
+ DESIGNER WALLCOVERINGS
+ </header>
+
+ <main>
+ <h1>Curated Wallcovering Palettes</h1>
+
+ <section>
+ <div class="palette-controls">
+ <button class="control-button" data-mode="analogous">Analogous</button>
+ <button class="control-button" data-mode="complementary">Complementary</button>
+ <button class="control-button" data-mode="triadic">Triadic</button>
+ </div>
+
+ <div class="palette-grid" id="paletteGrid">
+ <!-- Swatches will be generated here -->
+ </div>
+ </section>
+
+
+ <section>
+ <h2>Room Preview</h2>
+ <div class="room-preview" >
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ </div>
+ </section>
+
+ <button class="export-button" id="exportButton">Export as 1080x1080 Card</button>
+ </main>
+
+
+
+ <script>
+ document.addEventListener('DOMContentLoaded', () => {
+ const paletteGrid = document.getElementById('paletteGrid');
+ const roomPreviewDivs = document.querySelectorAll('.room-preview div');
+
+ let currentHue = 0; // Start with a default hue (e.g., red)
+ let paletteMode = 'analogous';
+
+ const hues = [0, 60, 120, 180, 240, 300]; // Example hues for demonstration
+ const colorNames = ["Alabaster", "Greige", "Celadon", "Ink", "Brass"];
+
+
+ function generatePalette() {
+ const palette = [];
+
+ for (let i = 0; i < 5; i++) {
+ let hueOffset = 0;
+ if(paletteMode === 'analogous') {
+ hueOffset = (i * 30) % 360; //Analogous: close hues.
+ } else if (paletteMode === 'complementary'){
+ hueOffset = ((i * 45) + 180) % 360; //Complementary: opposite hue.
+ } else {
+ hueOffset = ((i * 72) + currentHue) % 360; // Triadic: equally spaced hues.
+ }
+
+
+ const saturation = 50 + Math.floor(Math.random() * 15);
+ const lightness = 40 + Math.floor(Math.random() * 20);
+
+ palette.push(`hsl(${hueOffset}, ${saturation}%, ${lightness}%)`);
+ }
+ return palette;
+ }
+
+
+ function renderPalette(palette) {
+ paletteGrid.innerHTML = ''; // Clear existing swatches
+
+ for (let i = 0; i < palette.length; i++) {
+ const swatch = document.createElement('div');
+ swatch.classList.add('color-swatch');
+ swatch.style.backgroundColor = palette[i];
+ swatch.title = colorNames[i]; // Add a tooltip with the name
+
+ swatch.addEventListener('click', () => {
+ navigator.clipboard.writeText(palette[i]);
+ alert(`Copied ${colorNames[i]} to clipboard: ${palette[i]}`); //Simple alert - no external dependencies!
+ });
+
+ paletteGrid.appendChild(swatch);
+ }
+ }
+
+
+ function updateRoomPreview(palette) {
+ for (let i = 0; i < roomPreviewDivs.length; i++) {
+ roomPreviewDivs[i].style.backgroundImage = `linear-gradient(${palette[i]}`;
+ }
+ }
+
+ const exportButton = document.getElementById('exportButton');
+ exportButton.addEventListener("click", () => {
+ // Simple canvas hack - no external libs/network.
+ const canvas = document.createElement('canvas');
+ canvas.width = 1080;
+ canvas.height = 1080;
+
+ const ctx = canvas.getContext('2d');
+ ctx.fillStyle = paletteGrid.children[0].style.backgroundColor; //First swatch is representative color
+ ctx.fillRect(0,0, canvas.width, canvas.height);
+
+
+ const link = document.createElement('a');
+ link.download = 'wallcovering-palette.png';
+ link.href = canvas.toDataURL();
+ link.click();
+
+ });
+
+
+
+
+ document.querySelectorAll('.control-button').forEach(button => {
+ button.addEventListener('click', (event) => {
+ paletteMode = event.target.dataset.mode;
+ renderPalette(generatePalette());
+ updateRoomPreview(generatePalette());
+ });
+ });
+
+ // Initial palette generation and rendering
+ const initialPalette = generatePalette();
+ renderPalette(initialPalette);
+ updateRoomPreview(initialPalette);
+
+
+ document.body.classList.add('loaded');
+ });
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/gemma3-12b.png b/data/artifacts/420dc7bd02b3/gemma3-12b.png
new file mode 100644
index 0000000..5d16815
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/gemma3-12b.png differ
diff --git a/data/artifacts/420dc7bd02b3/gpt.html b/data/artifacts/420dc7bd02b3/gpt.html
new file mode 100644
index 0000000..60b3b84
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/gpt.html
@@ -0,0 +1,1549 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<title>Designer Wallcoverings — Palette Builder</title>
+<style>
+:root {
+ /* Design tokens */
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-soft: #1d1f24;
+ --surface-elevated: #20222a;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961; /* brass */
+ --accent-soft: #7d6a45;
+ --line: rgba(245,242,234,0.12);
+ --shadow-soft: 0 18px 45px rgba(0,0,0,0.55);
+ --shadow-subtle: 0 1px 0 rgba(255,255,255,0.02), 0 0 0 1px rgba(0,0,0,0.8);
+ --radius-s: 6px;
+ --radius-m: 10px;
+ --radius-l: 18px;
+ --ease-out: cubic-bezier(.22,1,.36,1); /* ease-out-quint */
+ --ease-move: cubic-bezier(.77,0,.18,1); /* power-in-out */
+ --duration-fast: 180ms;
+ --duration-med: 320ms;
+ --duration-slow: 640ms;
+
+ --font-display: 'Playfair Display', 'Didot', 'Bodoni MT', Georgia, 'Times New Roman', serif;
+ --font-sans: 'Avenir Next', 'Century Gothic', 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
+
+ --fs-display: 67px;
+ --fs-h1: 50px;
+ --fs-h2: 38px;
+ --fs-h3: 28px;
+ --fs-lead: 21px;
+ --fs-body: 16px;
+ --fs-caption: 12px;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ background: radial-gradient(circle at top left, #191b22 0, #050509 54%, #020204 100%);
+ color: var(--text);
+ font-family: var(--font-sans);
+ line-height: 1.6;
+ -webkit-font-smoothing: antialiased;
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+}
+
+/* Header / wordmark */
+
+header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 10;
+ background: linear-gradient(to bottom, rgba(13,13,15,0.98), rgba(13,13,15,0.92));
+ border-bottom: 1px solid rgba(255,255,255,0.04);
+ backdrop-filter: blur(20px);
+}
+
+.header-inner {
+ max-width: 1120px;
+ margin: 0 auto;
+ padding: 16px 24px 14px;
+ display: flex;
+ align-items: flex-end;
+ justify-content: space-between;
+ gap: 32px;
+}
+
+.wordmark-lockup {
+ display: flex;
+ flex-direction: column;
+}
+
+.wordmark {
+ font-family: var(--font-display);
+ font-size: 44px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text);
+ line-height: 1.1;
+ white-space: normal;
+}
+
+.wordmark-sub {
+ margin-top: 4px;
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+ color: var(--muted);
+}
+
+.header-meta {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: 6px;
+}
+
+.meta-label {
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+ color: var(--muted);
+}
+
+.meta-pill {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 10px;
+ border-radius: 999px;
+ border: 1px solid rgba(201,169,97,0.55);
+ background: radial-gradient(circle at 0 0, rgba(201,169,97,0.2), transparent 55%);
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.75);
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.16em;
+ color: var(--accent);
+}
+
+.meta-dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 999px;
+ background: var(--accent);
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.7), 0 0 8px rgba(201,169,97,0.9);
+}
+
+/* Layout */
+
+main {
+ flex: 1;
+ padding: 112px 24px 32px;
+}
+
+.app-shell {
+ max-width: 1120px;
+ margin: 0 auto 32px;
+ display: grid;
+ grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
+ gap: 32px;
+}
+
+@media (max-width: 880px) {
+ .app-shell {
+ grid-template-columns: minmax(0, 1fr);
+ }
+ .header-inner {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+ .header-meta {
+ align-items: flex-start;
+ }
+}
+
+.panel {
+ background: radial-gradient(circle at top left, rgba(255,255,255,0.06), transparent 55%), var(--surface);
+ border-radius: 20px;
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow-soft);
+ padding: 22px 22px 20px;
+ position: relative;
+ overflow: hidden;
+}
+
+.panel::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(circle at 0 0, rgba(201,169,97,0.16), transparent 55%);
+ mix-blend-mode: screen;
+ opacity: 0.85;
+ pointer-events: none;
+}
+
+.panel-inner {
+ position: relative;
+ z-index: 1;
+}
+
+/* Typography within panels */
+
+.section-kicker {
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+ color: var(--muted);
+ margin-bottom: 10px;
+}
+
+.section-title {
+ font-family: var(--font-display);
+ font-size: 32px;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ margin: 0 0 12px;
+}
+
+.section-lead {
+ font-size: 14px;
+ color: rgba(245,242,234,0.78);
+ max-width: 36rem;
+}
+
+/* Controls */
+
+.controls-row {
+ margin-top: 22px;
+ display: grid;
+ grid-template-columns: minmax(0, 2.1fr) minmax(0, 1.4fr);
+ gap: 18px;
+}
+
+@media (max-width: 720px) {
+ .controls-row {
+ grid-template-columns: minmax(0, 1fr);
+ }
+}
+
+.control-block {
+ padding-top: 4px;
+}
+
+.control-label-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ margin-bottom: 6px;
+}
+
+.control-label {
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.16em;
+ color: var(--muted);
+}
+
+.control-value {
+ font-size: 12px;
+ color: var(--text);
+}
+
+/* Hue slider styled as wheel proxy */
+
+.hue-slider-wrap {
+ position: relative;
+ padding: 10px 12px 12px;
+ border-radius: 999px;
+ background: linear-gradient(to right,
+ #ff0000 0%,
+ #ff7f00 16%,
+ #ffff00 33%,
+ #00ff00 50%,
+ #0000ff 66%,
+ #4b0082 83%,
+ #ff00ff 100%);
+ box-shadow: var(--shadow-subtle);
+}
+
+.hue-slider-wrap::before {
+ content: '';
+ position: absolute;
+ inset: 1px;
+ border-radius: inherit;
+ border: 1px solid rgba(0,0,0,0.8);
+ pointer-events: none;
+}
+
+input[type="range"] {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 100%;
+ background: transparent;
+}
+
+input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #f5f2ea;
+ border: 1px solid rgba(0,0,0,0.9);
+ box-shadow: 0 0 0 2px rgba(201,169,97,0.6), 0 0 0 4px rgba(0,0,0,0.85);
+ cursor: pointer;
+ margin-top: -4px;
+}
+
+input[type="range"]::-moz-range-thumb {
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #f5f2ea;
+ border: 1px solid rgba(0,0,0,0.9);
+ box-shadow: 0 0 0 2px rgba(201,169,97,0.6), 0 0 0 4px rgba(0,0,0,0.85);
+ cursor: pointer;
+}
+
+input[type="range"]::-webkit-slider-runnable-track {
+ height: 8px;
+ border-radius: 999px;
+ background: rgba(0,0,0,0.22);
+}
+
+input[type="range"]::-moz-range-track {
+ height: 8px;
+ border-radius: 999px;
+ background: rgba(0,0,0,0.22);
+}
+
+/* Scheme toggle */
+
+.scheme-toggle {
+ display: inline-flex;
+ border-radius: 999px;
+ padding: 3px;
+ background: rgba(4,4,6,0.8);
+ border: 1px solid rgba(255,255,255,0.06);
+ box-shadow: var(--shadow-subtle);
+}
+
+.scheme-toggle button {
+ position: relative;
+ border: none;
+ background: transparent;
+ color: var(--muted);
+ padding: 6px 14px;
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.16em;
+ cursor: pointer;
+ border-radius: 999px;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ transition: color var(--duration-fast) var(--ease-out),
+ background var(--duration-fast) var(--ease-out),
+ transform var(--duration-fast) var(--ease-out),
+ box-shadow var(--duration-fast) var(--ease-out);
+}
+
+.scheme-toggle button span.dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 999px;
+ background: transparent;
+ box-shadow: none;
+ transition: all var(--duration-fast) var(--ease-out);
+}
+
+.scheme-toggle button.active {
+ background: radial-gradient(circle at 0 0, rgba(201,169,97,0.6), rgba(201,169,97,0.1) 55%, transparent 80%);
+ color: var(--text);
+ box-shadow: 0 0 0 1px rgba(201,169,97,0.8), 0 8px 20px rgba(0,0,0,0.9);
+ transform: translateY(-0.5px);
+}
+
+.scheme-toggle button.active span.dot {
+ background: var(--accent);
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.7), 0 0 10px rgba(201,169,97,0.9);
+}
+
+/* Palette swatches */
+
+.palette-grid {
+ margin-top: 24px;
+ display: grid;
+ grid-template-columns: repeat(5, minmax(0, 1fr));
+ gap: 12px;
+}
+
+@media (max-width: 720px) {
+ .palette-grid {
+ grid-template-columns: repeat(5, minmax(0, 1fr));
+ overflow-x: auto;
+ padding-bottom: 4px;
+ }
+}
+
+.swatch {
+ position: relative;
+ border-radius: 16px;
+ background: #333;
+ height: 150px;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ color: #fff;
+ overflow: hidden;
+ cursor: pointer;
+ box-shadow: var(--shadow-subtle);
+ transform: translateY(0);
+ transition: transform var(--duration-med) var(--ease-move),
+ box-shadow var(--duration-med) var(--ease-out),
+ border-color var(--duration-med) var(--ease-out);
+ border: 1px solid rgba(245,242,234,0.05);
+}
+
+.swatch::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(circle at top left, rgba(255,255,255,0.16), transparent 55%);
+ mix-blend-mode: soft-light;
+ opacity: 0.7;
+ pointer-events: none;
+}
+
+/* distinct pattern motifs */
+.swatch-pattern-neutral::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ linear-gradient(135deg, rgba(255,255,255,0.22) 1px, transparent 1px),
+ linear-gradient(315deg, rgba(0,0,0,0.35) 1px, transparent 1px);
+ background-size: 22px 22px;
+ mix-blend-mode: soft-light;
+ opacity: 0.35;
+ pointer-events: none;
+}
+
+.swatch-pattern-linen::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ linear-gradient(90deg, rgba(255,255,255,0.06) 1px, transparent 1px),
+ linear-gradient(0deg, rgba(255,255,255,0.04) 1px, transparent 1px);
+ background-size: 3px 5px;
+ mix-blend-mode: soft-light;
+ opacity: 0.55;
+ pointer-events: none;
+}
+
+.swatch-pattern-celadon::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ radial-gradient(circle at 0 0, rgba(255,255,255,0.16) 0, transparent 42%),
+ radial-gradient(circle at 100% 100%, rgba(0,0,0,0.45) 0, transparent 52%);
+ mix-blend-mode: soft-light;
+ opacity: 0.7;
+ pointer-events: none;
+}
+
+.swatch-pattern-ink::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ linear-gradient(180deg, rgba(255,255,255,0.35) 0, transparent 40%),
+ radial-gradient(circle at 50% 0, rgba(0,0,0,0.9), transparent 60%);
+ mix-blend-mode: screen;
+ opacity: 0.4;
+ pointer-events: none;
+}
+
+.swatch-pattern-brass::after {
+ content: '';
+ position: absolute;
+ inset: -20%;
+ background:
+ conic-gradient(from 80deg, rgba(255,255,255,0.75), rgba(201,169,97,0.1), rgba(0,0,0,0.9), rgba(201,169,97,0.7), rgba(255,255,255,0.7));
+ mix-blend-mode: hard-light;
+ opacity: 0.8;
+ pointer-events: none;
+}
+
+.swatch:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 22px 55px rgba(0,0,0,0.9);
+ border-color: rgba(245,242,234,0.45);
+}
+
+.swatch-meta {
+ position: relative;
+ z-index: 1;
+ padding: 12px 12px 10px;
+ background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);
+}
+
+.swatch-name {
+ font-family: var(--font-display);
+ font-size: 15px;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ margin-bottom: 3px;
+}
+
+.swatch-hex {
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: rgba(245,242,234,0.75);
+}
+
+/* Copy toast */
+
+.copy-toast {
+ position: fixed;
+ left: 50%;
+ bottom: 30px;
+ transform: translateX(-50%) translateY(100%);
+ background: rgba(5,5,7,0.96);
+ color: var(--text);
+ padding: 10px 16px;
+ border-radius: 999px;
+ border: 1px solid rgba(201,169,97,0.85);
+ box-shadow: 0 16px 40px rgba(0,0,0,0.9);
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ opacity: 0;
+ pointer-events: none;
+ transition: transform var(--duration-med) var(--ease-out),
+ opacity var(--duration-med) var(--ease-out);
+ z-index: 20;
+}
+
+.copy-toast.active {
+ opacity: 1;
+ transform: translateX(-50%) translateY(0);
+}
+
+.copy-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 999px;
+ background: var(--accent);
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.9), 0 0 12px rgba(201,169,97,1);
+}
+
+/* Right column: room preview + export */
+
+.room-panel-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ gap: 12px;
+ margin-bottom: 14px;
+}
+
+.room-title {
+ font-family: var(--font-display);
+ font-size: 26px;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ margin: 0;
+}
+
+.room-sub {
+ font-size: 12px;
+ color: rgba(245,242,234,0.72);
+}
+
+.room-strip {
+ position: relative;
+ border-radius: 18px;
+ overflow: hidden;
+ background: #111;
+ border: 1px solid rgba(0,0,0,0.9);
+ box-shadow: var(--shadow-soft);
+ height: 210px;
+ display: grid;
+ grid-template-columns: 42% 11% 27% 20%;
+}
+
+@media (max-width: 480px) {
+ .room-strip {
+ height: 180px;
+ }
+}
+
+/* Room segments */
+.room-wall-main {
+ position: relative;
+ overflow: hidden;
+}
+
+.room-wall-main::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ linear-gradient(135deg, rgba(0,0,0,0.12) 1px, transparent 1px),
+ linear-gradient(45deg, rgba(255,255,255,0.07) 1px, transparent 1px);
+ background-size: 22px 22px;
+ mix-blend-mode: soft-light;
+ opacity: 0.6;
+ pointer-events: none;
+}
+
+.room-paneling {
+ position: relative;
+ overflow: hidden;
+}
+
+.room-paneling::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ linear-gradient(0deg, rgba(0,0,0,0.65) 0, transparent 38%),
+ linear-gradient(180deg, rgba(255,255,255,0.08) 0, transparent 60%);
+ opacity: 0.8;
+ pointer-events: none;
+}
+
+.room-accent {
+ position: relative;
+ overflow: hidden;
+}
+
+.room-accent::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(circle at 20% 0, rgba(255,255,255,0.25), transparent 60%),
+ radial-gradient(circle at 80% 100%, rgba(0,0,0,0.9), transparent 70%);
+ mix-blend-mode: soft-light;
+ opacity: 0.9;
+ pointer-events: none;
+}
+
+.room-brass {
+ position: relative;
+ overflow: hidden;
+}
+
+.room-brass::before {
+ content: '';
+ position: absolute;
+ inset: -20%;
+ background:
+ conic-gradient(from 180deg, rgba(255,255,255,0.9), rgba(201,169,97,0.15), rgba(0,0,0,0.8), rgba(201,169,97,0.85), rgba(255,255,255,0.9));
+ mix-blend-mode: hard-light;
+ opacity: 0.95;
+ pointer-events: none;
+}
+
+/* Simple "room" architecture lines */
+.room-wall-main::after,
+.room-paneling::after,
+.room-accent::after,
+.room-brass::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ border-right: 1px solid rgba(0,0,0,0.7);
+ border-left: 1px solid rgba(255,255,255,0.06);
+ opacity: 0.8;
+ pointer-events: none;
+}
+
+/* foreground furniture using pseudo-elements */
+
+.room-wall-main .sofa {
+ position: absolute;
+ bottom: 18px;
+ left: 12%;
+ width: 76%;
+ height: 30%;
+ border-radius: 18px;
+ background: linear-gradient(180deg, rgba(255,255,255,0.12), rgba(0,0,0,0.8));
+ box-shadow: 0 16px 40px rgba(0,0,0,0.85);
+ border: 1px solid rgba(0,0,0,0.9);
+}
+
+.room-wall-main .sofa::before {
+ content: '';
+ position: absolute;
+ inset: 15% 10% auto 10%;
+ height: 28%;
+ border-radius: 999px;
+ border: 1px solid rgba(0,0,0,0.9);
+ background: radial-gradient(circle at 20% 0, rgba(255,255,255,0.2), transparent 60%);
+}
+
+.room-wall-main .sofa::after {
+ content: '';
+ position: absolute;
+ inset: auto 14% -14% 14%;
+ height: 22%;
+ background: rgba(0,0,0,0.95);
+ filter: blur(6px);
+}
+
+.room-paneling .art {
+ position: absolute;
+ top: 18%;
+ left: 16%;
+ right: 12%;
+ bottom: 34%;
+ border-radius: 12px;
+ background: linear-gradient(135deg, rgba(255,255,255,0.15), rgba(0,0,0,0.9));
+ border: 1px solid rgba(255,255,255,0.15);
+ box-shadow: 0 10px 28px rgba(0,0,0,0.8);
+}
+
+.room-paneling .art::before {
+ content: '';
+ position: absolute;
+ inset: 16% 20%;
+ border-radius: 999px;
+ border: 1px dashed rgba(255,255,255,0.2);
+}
+
+.room-accent .table {
+ position: absolute;
+ bottom: 18px;
+ left: 18%;
+ right: 18%;
+ height: 26%;
+ border-radius: 999px;
+ background: radial-gradient(circle at 50% 0, rgba(255,255,255,0.6), rgba(0,0,0,0.95));
+ border: 1px solid rgba(0,0,0,0.95);
+ box-shadow: 0 16px 40px rgba(0,0,0,0.9);
+}
+
+.room-accent .table::before {
+ content: '';
+ position: absolute;
+ inset: -26% 18% auto 18%;
+ height: 26%;
+ border-radius: 999px;
+ background: radial-gradient(circle at 50% 0, rgba(255,255,255,0.4), transparent 80%);
+}
+
+.room-brass .lamp {
+ position: absolute;
+ bottom: 16px;
+ left: 28%;
+ right: 28%;
+ height: 30%;
+ border-radius: 999px;
+ background: linear-gradient(180deg, rgba(0,0,0,0.4), rgba(0,0,0,0.95));
+ border: 1px solid rgba(0,0,0,0.9);
+ box-shadow: 0 14px 32px rgba(0,0,0,0.9);
+}
+
+.room-brass .lamp::before {
+ content: '';
+ position: absolute;
+ inset: -46% 20% auto 20%;
+ border-radius: 999px 999px 40% 40%;
+ background: linear-gradient(180deg, rgba(255,255,255,0.7), rgba(201,169,97,0.05));
+ border: 1px solid rgba(0,0,0,0.85);
+}
+
+.room-brass .lamp::after {
+ content: '';
+ position: absolute;
+ inset: -76% 40% auto 40%;
+ border-radius: 999px;
+ background: radial-gradient(circle at 50% 0, rgba(255,255,255,0.6), transparent 70%);
+}
+
+/* Export button + hints */
+
+.footer-row {
+ margin-top: 18px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 12px;
+ flex-wrap: wrap;
+}
+
+.export-button {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 16px;
+ border-radius: 999px;
+ border: 1px solid rgba(201,169,97,0.9);
+ background: radial-gradient(circle at 0 0, rgba(201,169,97,0.7), rgba(201,169,97,0.1) 55%, rgba(0,0,0,0.95) 100%);
+ color: var(--text);
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+ cursor: pointer;
+ box-shadow: 0 18px 40px rgba(0,0,0,0.9);
+ transition: transform var(--duration-med) var(--ease-move),
+ box-shadow var(--duration-med) var(--ease-out),
+ background var(--duration-med) var(--ease-out);
+}
+
+.export-button:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 26px 60px rgba(0,0,0,0.95);
+}
+
+.export-button:active {
+ transform: translateY(0);
+ box-shadow: 0 12px 30px rgba(0,0,0,0.9);
+}
+
+.export-icon {
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ border: 1px solid rgba(0,0,0,0.9);
+ background: radial-gradient(circle at 30% 0, rgba(255,255,255,0.9), rgba(201,169,97,0.2), rgba(0,0,0,0.95));
+ position: relative;
+}
+
+.export-icon::before {
+ content: '';
+ position: absolute;
+ inset: 3px 4px auto 4px;
+ height: 6px;
+ border-radius: 2px;
+ border: 1px solid rgba(0,0,0,0.9);
+ background: rgba(0,0,0,0.95);
+}
+
+.export-icon::after {
+ content: '';
+ position: absolute;
+ left: 6px;
+ top: 3px;
+ width: 2px;
+ height: 5px;
+ background: rgba(0,0,0,0.9);
+ box-shadow: 0 2px 0 rgba(201,169,97,0.8);
+}
+
+.footer-hint {
+ font-size: 11px;
+ color: var(--muted);
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+}
+
+/* Export overlay */
+
+.export-overlay {
+ position: fixed;
+ inset: 0;
+ background: radial-gradient(circle at top left, rgba(201,169,97,0.22), rgba(0,0,0,0.96));
+ display: none;
+ align-items: center;
+ justify-content: center;
+ z-index: 30;
+}
+
+.export-overlay.active {
+ display: flex;
+}
+
+.export-card-shell {
+ max-width: 1080px;
+ width: min(92vw, 1080px);
+ border-radius: 24px;
+ background: linear-gradient(145deg, #111117, #050506);
+ border: 1px solid rgba(201,169,97,0.7);
+ box-shadow: 0 40px 120px rgba(0,0,0,1);
+ padding: 18px 18px 18px;
+ position: relative;
+}
+
+.export-close {
+ position: absolute;
+ top: 14px;
+ right: 18px;
+ width: 26px;
+ height: 26px;
+ border-radius: 999px;
+ border: 1px solid rgba(255,255,255,0.08);
+ background: rgba(5,5,7,0.95);
+ color: var(--muted);
+ font-size: 16px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: var(--shadow-subtle);
+ transition: background var(--duration-fast) var(--ease-out),
+ transform var(--duration-fast) var(--ease-out);
+}
+
+.export-close:hover {
+ background: rgba(20,20,24,1);
+ transform: translateY(-1px);
+}
+
+.export-layout {
+ display: grid;
+ grid-template-columns: 1.1fr 1fr;
+ gap: 16px;
+}
+
+@media (max-width: 780px) {
+ .export-layout {
+ grid-template-columns: 1fr;
+ }
+}
+
+.export-left {
+ border-radius: 20px;
+ overflow: hidden;
+ border: 1px solid rgba(255,255,255,0.04);
+ background: #111;
+}
+
+.export-right {
+ padding: 10px 8px 6px;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.export-logo {
+ font-family: var(--font-display);
+ font-size: 18px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text);
+}
+
+.export-caption {
+ margin-top: 4px;
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.export-note {
+ margin-top: 10px;
+ font-size: 12px;
+ color: rgba(245,242,234,0.78);
+}
+
+.export-instruction {
+ margin-top: 10px;
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.16em;
+ color: var(--muted);
+}
+
+.export-palette-row {
+ display: grid;
+ grid-template-columns: repeat(5, minmax(0, 1fr));
+ gap: 8px;
+ margin-top: 12px;
+}
+
+.export-swatch {
+ border-radius: 12px;
+ overflow: hidden;
+ position: relative;
+ height: 80px;
+ border: 1px solid rgba(0,0,0,0.8);
+ box-shadow: 0 6px 12px rgba(0,0,0,0.85);
+}
+
+.export-swatch::after {
+ content: attr(data-name);
+ position: absolute;
+ left: 10px;
+ bottom: 8px;
+ font-family: var(--font-display);
+ font-size: 11px;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: #f5f2ea;
+ text-shadow: 0 1px 3px rgba(0,0,0,0.8);
+}
+
+/* Canvas-esque card preview */
+
+.export-canvas {
+ position: relative;
+ width: 100%;
+ padding-top: 100%; /* 1:1 square */
+ background: radial-gradient(circle at 0 0, rgba(201,169,97,0.26), transparent 60%), #0a0a0d;
+}
+
+.export-canvas-inner {
+ position: absolute;
+ inset: 10% 9%;
+ border-radius: 24px;
+ background: linear-gradient(150deg, #121218, #050506);
+ border: 1px solid rgba(255,255,255,0.04);
+ overflow: hidden;
+ box-shadow: var(--shadow-soft);
+ display: grid;
+ grid-template-rows: 64% 36%;
+}
+
+.export-canvas-top {
+ position: relative;
+ display: grid;
+ grid-template-columns: 1.1fr 0.9fr;
+}
+
+.export-canvas-top .canvas-room {
+ position: relative;
+ overflow: hidden;
+}
+
+.export-canvas-top .canvas-room::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ linear-gradient(135deg, rgba(255,255,255,0.16) 1px, transparent 1px),
+ linear-gradient(45deg, rgba(0,0,0,0.45) 1px, transparent 1px);
+ background-size: 22px 22px;
+ mix-blend-mode: soft-light;
+ opacity: 0.7;
+}
+
+.export-canvas-top .canvas-room::after {
+ content: '';
+ position: absolute;
+ inset: auto 12% 9% 16%;
+ height: 18%;
+ border-radius: 999px;
+ background: radial-gradient(circle at 50% 0, rgba(255,255,255,0.7), rgba(0,0,0,1));
+ box-shadow: 0 18px 48px rgba(0,0,0,0.95);
+ border: 1px solid rgba(0,0,0,0.9);
+}
+
+.export-canvas-top .canvas-stack {
+ display: grid;
+ grid-template-rows: 1fr 1fr;
+}
+
+.export-canvas-top .canvas-stack-upper,
+.export-canvas-top .canvas-stack-lower {
+ position: relative;
+ overflow: hidden;
+}
+
+.export-canvas-top .canvas-stack-upper::before,
+.export-canvas-top .canvas-stack-lower::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ mix-blend-mode: soft-light;
+ opacity: 0.8;
+}
+
+.export-canvas-top .canvas-stack-upper::before {
+ background:
+ radial-gradient(circle at 0 0, rgba(255,255,255,0.4), transparent 65%),
+ radial-gradient(circle at 100% 100%, rgba(0,0,0,0.9), transparent 70%);
+}
+
+.export-canvas-top .canvas-stack-lower::before {
+ background:
+ conic-gradient(from 120deg, rgba(255,255,255,0.9), rgba(201,169,97,0.2), rgba(0,0,0,0.9), rgba(201,169,97,0.9));
+}
+
+.export-canvas-bottom {
+ padding: 12px 16px 14px;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.export-canvas-brand {
+ font-family: var(--font-display);
+ font-size: 15px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+}
+
+.export-canvas-meta {
+ margin-top: 4px;
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+ color: var(--muted);
+}
+
+.export-canvas-swatches {
+ margin-top: 10px;
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 6px;
+}
+
+.export-canvas-swatches div {
+ height: 18px;
+ border-radius: 999px;
+ border: 1px solid rgba(0,0,0,0.9);
+ box-shadow: 0 3px 8px rgba(0,0,0,0.85);
+}
+
+/* Reduced motion */
+
+@media (prefers-reduced-motion: reduce) {
+ * {
+ scroll-behavior: auto !important;
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ }
+}
+</style>
+</head>
+<body>
+<header>
+ <div class="header-inner">
+ <div class="wordmark-lockup">
+ <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+ <div class="wordmark-sub">Social-ready palette builder for interiors</div>
+ </div>
+ <div class="header-meta">
+ <div class="meta-label">Palette mode</div>
+ <div class="meta-pill">
+ <span class="meta-dot"></span>
+ <span id="header-mode-label">Analogous</span>
+ </div>
+ </div>
+ </div>
+</header>
+
+<main>
+ <div class="app-shell">
+ <!-- Left: controls + swatches -->
+ <section class="panel">
+ <div class="panel-inner">
+ <div class="section-kicker">Palette atelier</div>
+ <h1 class="section-title">Wallcovering stories</h1>
+ <p class="section-lead">
+ Dial in a base hue, choose a harmony, and receive a five-swatch interior palette with
+ designer naming. Tap any swatch to copy its hex, ready for boards and specifications.
+ </p>
+
+ <div class="controls-row">
+ <div class="control-block">
+ <div class="control-label-row">
+ <div class="control-label">Base hue</div>
+ <div class="control-value"><span id="hue-deg-label">32°</span> on the wheel</div>
+ </div>
+ <div class="hue-slider-wrap">
+ <input id="hue-slider" type="range" min="0" max="359" value="32" />
+ </div>
+ </div>
+ <div class="control-block">
+ <div class="control-label-row">
+ <div class="control-label">Harmony</div>
+ </div>
+ <div class="scheme-toggle">
+ <button type="button" data-scheme="analogous" class="active">
+ <span class="dot"></span> Analogous
+ </button>
+ <button type="button" data-scheme="complementary">
+ <span class="dot"></span> Complementary
+ </button>
+ <button type="button" data-scheme="triadic">
+ <span class="dot"></span> Triadic
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <div class="palette-grid" id="palette-grid">
+ <!-- Swatches injected by JS -->
+ </div>
+ </div>
+ </section>
+
+ <!-- Right: room preview + export -->
+ <section class="panel">
+ <div class="panel-inner">
+ <div class="room-panel-header">
+ <div>
+ <div class="section-kicker">Room preview</div>
+ <h2 class="room-title">Study vignette</h2>
+ </div>
+ <div class="room-sub">
+ Palette applied to walls, paneling, textiles, and metalwork for instant context.
+ </div>
+ </div>
+
+ <div class="room-strip" id="room-strip">
+ <div class="room-wall-main">
+ <div class="sofa"></div>
+ </div>
+ <div class="room-paneling">
+ <div class="art"></div>
+ </div>
+ <div class="room-accent">
+ <div class="table"></div>
+ </div>
+ <div class="room-brass">
+ <div class="lamp"></div>
+ </div>
+ </div>
+
+ <div class="footer-row">
+ <button class="export-button" id="export-button" type="button">
+ <span class="export-icon"></span>
+ Export 1080×1080 card
+ </button>
+ <div class="footer-hint">
+ Copy hex on click — perfect for moodboards and reels
+ </div>
+ </div>
+ </div>
+ </section>
+ </div>
+</main>
+
+<div class="copy-toast" id="copy-toast">
+ <div class="copy-dot"></div>
+ <div id="copy-toast-text">Hex copied</div>
+</div>
+
+<!-- Export overlay -->
+<div class="export-overlay" id="export-overlay">
+ <div class="export-card-shell">
+ <button class="export-close" type="button" id="export-close" aria-label="Close export view">
+ ×
+ </button>
+ <div class="export-layout">
+ <div class="export-left">
+ <div class="export-canvas" id="export-canvas">
+ <div class="export-canvas-inner">
+ <div class="export-canvas-top">
+ <div class="canvas-room" id="export-room-main"></div>
+ <div class="canvas-stack">
+ <div class="canvas-stack-upper" id="export-room-secondary"></div>
+ <div class="canvas-stack-lower" id="export-room-brass"></div>
+ </div>
+ </div>
+ <div class="export-canvas-bottom">
+ <div>
+ <div class="export-canvas-brand">DESIGNER WALLCOVERINGS</div>
+ <div class="export-canvas-meta">
+ <span id="export-scheme-label">Analogous</span> —
+ <span id="export-hue-label">32° base</span>
+ </div>
+ </div>
+ <div class="export-canvas-swatches" id="export-canvas-swatches">
+ <!-- mini swatches -->
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="export-right">
+ <div>
+ <div class="export-logo">DW / Palette Card</div>
+ <div class="export-caption">Ready for Instagram, Pinterest & client decks</div>
+ <div class="export-note">
+ This overlay shows how your palette will sit in a 1080×1080 export card.
+ Use your browser’s screenshot or export tooling to capture it at full resolution.
+ </div>
+ <div class="export-note" id="export-names">
+ <!-- palette names injected -->
+ </div>
+ </div>
+ <div>
+ <div class="export-instruction">
+ Tip — keep walls soft and ink accents sparing for a calm, collected room.
+ </div>
+ <div class="export-palette-row" id="export-palette-row">
+ <!-- export swatches -->
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<script>
+(function() {
+ const hueSlider = document.getElementById('hue-slider');
+ const hueDegLabel = document.getElementById('hue-deg-label');
+ const schemeButtons = document.querySelectorAll('.scheme-toggle button');
+ const paletteGrid = document.getElementById('palette-grid');
+ const headerModeLabel = document.getElementById('header-mode-label');
+ const copyToast = document.getElementById('copy-toast');
+ const copyToastText = document.getElementById('copy-toast-text');
+ const roomStrip = document.getElementById('room-strip');
+ const exportButton = document.getElementById('export-button');
+ const exportOverlay = document.getElementById('export-overlay');
+ const exportClose = document.getElementById('export-close');
+ const exportSchemeLabel = document.getElementById('export-scheme-label');
+ const exportHueLabel = document.getElementById('export-hue-label');
+ const exportCanvasSwatches = document.getElementById('export-canvas-swatches');
+ const exportPaletteRow = document.getElementById('export-palette-row');
+ const exportNames = document.getElementById('export-names');
+ const exportRoomMain = document.getElementById('export-room-main');
+ const exportRoomSecondary = document.getElementById('export-room-secondary');
+ const exportRoomBrass = document.getElementById('export-room-brass');
+
+ const SWATCH_NAMES = ['Alabaster', 'Greige', 'Celadon', 'Ink', 'Brass'];
+
+ function clamp(v, min, max) {
+ return Math.min(max, Math.max(min, v));
+ }
+
+ // HSL <-> HEX helpers
+ function hslToRgb(h, s, l){
+ h /= 360; s /= 100; l /= 100;
+ let r, g, b;
+ if(s === 0){
+ r = g = b = l;
+ } else {
+ const hue2rgb = function hue2rgb(p, q, t){
+ if(t < 0) t += 1;
+ if(t > 1) t -= 1;
+ if(t < 1/6) return p + (q - p) * 6 * t;
+ if(t < 1/2) return q;
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
+ return p;
+ };
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ const p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1/3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1/3);
+ }
+ const toHex = x => {
+ const v = Math.round(x * 255);
+ const h = v.toString(16).padStart(2, '0');
+ return h;
+ };
+ return '#' + toHex(r) + toHex(g) + toHex(b);
+ }
+
+ // Palette generator
+ function generatePalette(baseHue, scheme) {
+ const variations = [];
+ if (scheme === 'analogous') {
+ variations.push(baseHue - 18, baseHue - 6, baseHue + 10, baseHue + 28);
+ } else if (scheme === 'complementary') {
+ const comp = (baseHue + 180) % 360;
+ variations.push(baseHue - 14, baseHue, comp - 12, comp, comp + 12);
+ } else if (scheme === 'triadic') {
+ const tri1 = (baseHue + 120) % 360;
+ const tri2 = (baseHue + 240) % 360;
+ variations.push(baseHue - 8, tri1 - 6, baseHue + 8, tri2 - 6, tri2 + 10);
+ }
+
+ const palette = [];
+
+ // Alabaster — warm, almost white
+ palette.push({
+ name: SWATCH_NAMES[0],
+ hex: hslToRgb((variations[0] + 360) % 360, 18, 93),
+ role: 'alabaster'
+ });
+ // Greige — soft neutral
+ palette.push({
+ name: SWATCH_NAMES[1],
+ hex: hslToRgb((variations[1] + 360) % 360, 16, 72),
+ role: 'greige'
+ });
+ // Celadon — desaturated cool accent
+ palette.push({
+ name: SWATCH_NAMES[2],
+ hex: hslToRgb((variations[2] + 360) % 360, 24, 64),
+ role: 'celadon'
+ });
+ // Ink — deep near-black
+ palette.push({
+ name: SWATCH_NAMES[3],
+ hex: hslToRgb((variations[3] + 360) % 360, 24, 16),
+ role: 'ink'
+ });
+ // Brass — fixed metallic accent leaning into base hue
+ const brassHue = (baseHue + 28) % 360;
+ palette.push({
+ name: SWATCH_NAMES[4],
+ hex: hslToRgb(brassHue, 58, 54),
+ role: 'brass'
+ });
+
+ return palette;
+ }
+
+ function updateRoomPreview(palette) {
+ const [alabaster, greige, celadon, ink, brass] = palette.map(p => p.hex);
+ const parts = roomStrip.children;
+ if (parts[0]) parts[0].style.background = greige;
+ if (parts[1]) parts[1].style.background = alabaster;
+ if (parts[2]) parts[2].style.background = celadon;
+ if (parts[3]) parts[3].style.background = brass;
+
+ const sofa = roomStrip.querySelector('.sofa');
+ if (sofa) sofa.style.background = `linear-gradient(180deg, ${alabaster} 0, ${ink} 80%)`;
+ const art = roomStrip.querySelector('.art');
+ if (art) art.style.background = `linear-gradient(135deg, ${celadon} 0, ${ink} 80%)`;
+ const table = roomStrip.querySelector('.table');
+ if (table) table.style.background = `radial-gradient(circle at 50% 0, ${alabaster}, ${ink})`;
+ const lamp = roomStrip.querySelector('.lamp');
+ if (lamp) lamp.style.background = `linear-gradient(180deg, ${ink}, ${ink})`;
+ }
+
+ function renderSwatches(palette) {
+ paletteGrid.innerHTML = '';
+ const patternClasses = [
+ 'swatch-pattern-neutral',
+ 'swatch-pattern-linen',
+ 'swatch-pattern-celadon',
+ 'swatch-pattern-ink',
+ 'swatch-pattern-brass'
+ ];
+
+ palette.forEach((swatch, index) => {
+ const el = document.createElement('button');
+ el.type = 'button';
+ el.className = 'swatch ' + patternClasses[index];
+ el.style.background = swatch.hex;
+ el.setAttribute('data-hex', swatch.hex);
+ el.setAttribute('data-name', swatch.name);
+ el.innerHTML = `
+ <div class="swatch-meta">
+ <div class="swatch-name">${swatch.name}</div>
+ <div class="swatch-hex">${swatch.hex}</div>
+ </div>
+ `;
+ el.addEventListener('click', () => {
+ copyHex(swatch.hex, swatch.name);
+ });
+ paletteGrid.appendChild(el);
+ });
+ }
+
+ let toastTimeout;
+ function copyHex(hex, name) {
+ if (navigator.clipboard && navigator.clipboard.writeText) {
+ navigator.clipboard.writeText(hex).catch(() => {});
+ }
+ copyToastText.textContent = `${name.toUpperCase()} · ${hex} COPIED`;
+ copyToast.classList.add('active');
+ clearTimeout(toastTimeout);
+ toastTimeout = setTimeout(() => {
+ copyToast.classList.remove('active');
+ }, 1500);
+ }
+
+ function updateExportViews(palette, scheme, baseHue) {
+ exportSchemeLabel.textContent = scheme.charAt(0).toUpperCase() + scheme.slice(1);
+ exportHueLabel.innerHTML = `${baseHue}° base`;
+
+ exportCanvasSwatches.innerHTML = '';
+ exportPaletteRow.innerHTML = '';
+
+ palette.forEach(p => {
+ const mini = document.createElement('div');
+ mini.style.background = p.hex;
+ exportCanvasSwatches.appendChild(mini);
+
+ const expSw = document.createElement('div');
+ expSw.className = 'export-swatch';
+ expSw.style.background = p.hex;
+ expSw.setAttribute('data-name', p.name);
+ exportPaletteRow.appendChild(expSw);
+ });
+
+ const [alabaster, greige, celadon, ink, brass] = palette.map(p => p.hex);
+ exportRoomMain.style.background = greige;
+ exportRoomSecondary.style.background = alabaster;
+ exportRoomBrass.style.background = brass;
+
+ exportRoomMain.style.backgroundImage =
+ `linear-gradient(135deg, rgba(255,255,255,0.18) 1px, transparent 1px),
+ linear-gradient(45deg, rgba(0,0,0,0.45) 1px, transparent 1px)`;
+ exportRoomSecondary.style.backgroundImage =
+ `radial-gradient(circle at 0 0, rgba(255,255,255,0.4), transparent 65%),
+ radial-gradient(circle at 100% 100%, rgba(0,0,0,0.9), transparent 70%)`;
+ exportRoomBrass.style.backgroundImage =
+ `conic-gradient(from 160deg, rgba(255,255,255,0.9), rgba(201,169,97,0.2), rgba(0,0,0,0.9), rgba(201,169,97,0.9))`;
+
+ exportNames.textContent =
+ `${palette.map(p => p.name).join(' · ')} — a ${scheme} wallcovering story.`;
+ }
+
+ function regenerate() {
+ const baseHue = parseInt(hueSlider.value, 10) || 0;
+ const scheme = getCurrentScheme();
+ hueDegLabel.textContent = `${baseHue}\u00B0`;
+ headerModeLabel.textContent = scheme.charAt(0).toUpperCase() + scheme.slice(1);
+ const palette = generatePalette(baseHue, scheme);
+ renderSwatches(palette);
+ updateRoomPreview(palette);
+ updateExportViews(palette, scheme, baseHue);
+ }
+
+ function getCurrentScheme() {
+ const active = document.querySelector('.scheme-toggle button.active');
+ return active ? active.getAttribute('data-scheme') : 'analogous';
+ }
+
+ schemeButtons.forEach(btn => {
+ btn.addEventListener('click', () => {
+ schemeButtons.forEach(b => b.classList.remove('active'));
+ btn.classList.add('active');
+ regenerate();
+ });
+ });
+
+ hueSlider.addEventListener('input', regenerate);
+
+ exportButton.addEventListener('click', () => {
+ exportOverlay.classList.add('active');
+ });
+
+ exportClose.addEventListener('click', () => {
+ exportOverlay.classList.remove('active');
+ });
+
+ exportOverlay.addEventListener('click', (e) => {
+ if (e.target === exportOverlay) {
+ exportOverlay.classList.remove('active');
+ }
+ });
+
+ // Initial render
+ regenerate();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/gpt.png b/data/artifacts/420dc7bd02b3/gpt.png
new file mode 100644
index 0000000..89d04f3
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/gpt.png differ
diff --git a/data/artifacts/420dc7bd02b3/grok.html b/data/artifacts/420dc7bd02b3/grok.html
new file mode 100644
index 0000000..ed46862
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/grok.html
@@ -0,0 +1,1237 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings — Palette Builder</title>
+<style>
+:root {
+ --bg: #f7f3eb;
+ --surface: #fffdf8;
+ --ink: #1c1a17;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --accent-deep: #7d6a45;
+ --line: rgba(28, 26, 23, 0.12);
+ --line-strong: rgba(28, 26, 23, 0.22);
+ --shadow: 0 12px 40px rgba(28, 26, 23, 0.08);
+ --shadow-soft: 0 4px 16px rgba(28, 26, 23, 0.06);
+ --ease: cubic-bezier(.22, .9, .24, 1);
+ --ease-out: cubic-bezier(.22, 1, .36, 1);
+ --serif: 'Didot', 'Bodoni MT', 'Playfair Display', 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
+ --sans: 'Avenir Next', 'Century Gothic', 'Helvetica Neue', Futura, sans-serif;
+ --mono: 'SF Mono', 'Cascadia Code', Consolas, Menlo, monospace;
+ --r-tight: 6px;
+ --r-card: 14px;
+ --header-h: 72px;
+}
+
+*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+
+html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
+
+body {
+ font-family: var(--sans);
+ font-size: 16px;
+ line-height: 1.6;
+ color: var(--ink);
+ background: var(--bg);
+ min-height: 100vh;
+}
+
+/* —— Fixed top bar —— */
+.site-header {
+ position: fixed;
+ top: 0; left: 0; right: 0;
+ z-index: 100;
+ height: var(--header-h);
+ background: rgba(247, 243, 235, 0.92);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--line);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 32px;
+}
+
+.wordmark {
+ font-family: var(--serif);
+ font-size: 22px;
+ font-weight: 500;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--ink);
+ line-height: 1.15;
+ white-space: normal;
+ max-width: 280px;
+}
+
+.header-meta {
+ font-family: var(--sans);
+ font-size: 10px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* —— Layout —— */
+main {
+ max-width: 1120px;
+ margin: 0 auto;
+ padding: calc(var(--header-h) + 48px) 32px 96px;
+}
+
+.hero {
+ text-align: center;
+ margin-bottom: 56px;
+}
+
+.hero-eyebrow {
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--accent-deep);
+ margin-bottom: 16px;
+}
+
+.hero h1 {
+ font-family: var(--serif);
+ font-size: 50px;
+ font-weight: 400;
+ line-height: 1.1;
+ letter-spacing: -0.02em;
+ color: var(--ink);
+ margin-bottom: 12px;
+}
+
+.hero p {
+ font-size: 16px;
+ color: var(--muted);
+ max-width: 42ch;
+ margin: 0 auto;
+ line-height: 1.65;
+}
+
+/* —— Studio grid —— */
+.studio {
+ display: grid;
+ grid-template-columns: 300px 1fr;
+ gap: 40px;
+ align-items: start;
+}
+
+@media (max-width: 860px) {
+ .studio { grid-template-columns: 1fr; gap: 32px; }
+ .hero h1 { font-size: 38px; }
+ .wordmark { font-size: 18px; max-width: 220px; }
+ main { padding-left: 20px; padding-right: 20px; }
+}
+
+/* —— Control panel —— */
+.panel {
+ background: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: var(--r-card);
+ padding: 28px;
+ box-shadow: var(--shadow-soft);
+ position: sticky;
+ top: calc(var(--header-h) + 24px);
+}
+
+.panel-label {
+ font-size: 10px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 14px;
+ display: block;
+}
+
+/* Hue wheel */
+.wheel-wrap {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 28px;
+}
+
+.wheel-stage {
+ position: relative;
+ width: 200px;
+ height: 200px;
+}
+
+.hue-wheel {
+ width: 200px;
+ height: 200px;
+ border-radius: 50%;
+ background: conic-gradient(
+ hsl(0, 62%, 52%),
+ hsl(30, 62%, 52%),
+ hsl(60, 62%, 52%),
+ hsl(90, 62%, 52%),
+ hsl(120, 62%, 52%),
+ hsl(150, 62%, 52%),
+ hsl(180, 62%, 52%),
+ hsl(210, 62%, 52%),
+ hsl(240, 62%, 52%),
+ hsl(270, 62%, 52%),
+ hsl(300, 62%, 52%),
+ hsl(330, 62%, 52%),
+ hsl(0, 62%, 52%)
+ );
+ box-shadow: inset 0 0 0 1px var(--line-strong), var(--shadow-soft);
+ cursor: crosshair;
+ position: relative;
+}
+
+.wheel-inner {
+ position: absolute;
+ inset: 52px;
+ border-radius: 50%;
+ background: var(--surface);
+ box-shadow: 0 0 0 1px var(--line);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ pointer-events: none;
+}
+
+.wheel-center-swatch {
+ width: 44px;
+ height: 44px;
+ border-radius: 50%;
+ border: 1px solid var(--line-strong);
+ box-shadow: var(--shadow-soft);
+ transition: background 0.35s var(--ease);
+}
+
+.wheel-marker {
+ position: absolute;
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ border: 2px solid #fff;
+ box-shadow: 0 1px 6px rgba(0,0,0,0.28);
+ transform: translate(-50%, -50%);
+ pointer-events: none;
+ transition: background 0.2s var(--ease);
+ z-index: 2;
+}
+
+.hue-readout {
+ margin-top: 14px;
+ font-family: var(--mono);
+ font-size: 12px;
+ letter-spacing: 0.06em;
+ color: var(--muted);
+}
+
+/* Harmony toggle */
+.harmony {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 6px;
+ margin-bottom: 28px;
+ padding: 4px;
+ background: var(--bg);
+ border-radius: var(--r-tight);
+ border: 1px solid var(--line);
+}
+
+.harmony button {
+ font-family: var(--sans);
+ font-size: 10px;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ padding: 10px 4px;
+ border: none;
+ background: transparent;
+ color: var(--muted);
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.3s var(--ease);
+}
+
+.harmony button[aria-pressed="true"] {
+ background: var(--ink);
+ color: var(--bg);
+}
+
+.harmony button:hover:not([aria-pressed="true"]) {
+ color: var(--ink);
+}
+
+/* Actions */
+.panel-actions {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.btn {
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ padding: 14px 18px;
+ border-radius: var(--r-tight);
+ cursor: pointer;
+ transition: all 0.3s var(--ease);
+ border: 1px solid transparent;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+}
+
+.btn-primary {
+ background: var(--ink);
+ color: var(--bg);
+ border-color: var(--ink);
+}
+
+.btn-primary:hover {
+ background: var(--accent-deep);
+ border-color: var(--accent-deep);
+}
+
+.btn-ghost {
+ background: transparent;
+ color: var(--ink);
+ border-color: var(--line-strong);
+}
+
+.btn-ghost:hover {
+ border-color: var(--ink);
+ background: var(--surface);
+}
+
+/* —— Results —— */
+.results { min-width: 0; }
+
+.section-head {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ margin-bottom: 20px;
+ gap: 16px;
+}
+
+.section-head h2 {
+ font-family: var(--serif);
+ font-size: 28px;
+ font-weight: 400;
+ letter-spacing: -0.01em;
+ color: var(--ink);
+}
+
+.section-head .hint {
+ font-size: 11px;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* Swatches */
+.swatches {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 12px;
+ margin-bottom: 40px;
+}
+
+@media (max-width: 640px) {
+ .swatches { grid-template-columns: repeat(2, 1fr); }
+ .swatches .swatch:last-child { grid-column: span 2; }
+}
+
+.swatch {
+ background: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: var(--r-card);
+ overflow: hidden;
+ cursor: pointer;
+ transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
+ box-shadow: var(--shadow-soft);
+ position: relative;
+}
+
+.swatch:hover {
+ transform: translateY(-3px);
+ box-shadow: var(--shadow);
+}
+
+.swatch:active { transform: translateY(-1px); }
+
+.swatch-chip {
+ height: 120px;
+ position: relative;
+ transition: background 0.4s var(--ease);
+}
+
+.swatch-chip::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(160deg, rgba(255,255,255,0.14) 0%, transparent 48%);
+ pointer-events: none;
+}
+
+.swatch-meta {
+ padding: 14px 14px 16px;
+ border-top: 1px solid var(--line);
+}
+
+.swatch-name {
+ font-family: var(--serif);
+ font-size: 16px;
+ font-weight: 400;
+ color: var(--ink);
+ margin-bottom: 4px;
+ line-height: 1.2;
+}
+
+.swatch-hex {
+ font-family: var(--mono);
+ font-size: 11px;
+ letter-spacing: 0.04em;
+ color: var(--muted);
+ text-transform: uppercase;
+}
+
+.swatch.copied .swatch-chip::before {
+ content: 'Copied';
+ position: absolute;
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(28, 26, 23, 0.55);
+ color: #f5f2ea;
+ font-family: var(--sans);
+ font-size: 10px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ z-index: 1;
+ animation: fadeCopy 0.9s var(--ease) forwards;
+}
+
+@keyframes fadeCopy {
+ 0% { opacity: 0; }
+ 15% { opacity: 1; }
+ 70% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+/* Room preview */
+.room-block {
+ margin-bottom: 40px;
+}
+
+.room-frame {
+ border: 1px solid var(--line);
+ border-radius: var(--r-card);
+ overflow: hidden;
+ background: var(--surface);
+ box-shadow: var(--shadow);
+}
+
+.room-strip {
+ display: grid;
+ grid-template-columns: 1.1fr 0.9fr 1.2fr 0.85fr 1fr;
+ height: 220px;
+ position: relative;
+}
+
+.room-panel {
+ position: relative;
+ transition: background 0.45s var(--ease);
+ overflow: hidden;
+}
+
+/* Distinct wallcovering motifs via CSS only */
+.room-panel:nth-child(1)::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image: repeating-linear-gradient(
+ 90deg,
+ transparent 0,
+ transparent 11px,
+ rgba(255,255,255,0.06) 11px,
+ rgba(255,255,255,0.06) 12px
+ );
+ opacity: 0.9;
+}
+
+.room-panel:nth-child(2)::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ radial-gradient(circle at 30% 40%, rgba(255,255,255,0.1) 0 1.5px, transparent 2px),
+ radial-gradient(circle at 70% 70%, rgba(0,0,0,0.06) 0 1px, transparent 1.5px);
+ background-size: 18px 18px, 14px 14px;
+}
+
+.room-panel:nth-child(3)::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ linear-gradient(135deg, rgba(255,255,255,0.08) 25%, transparent 25.5%),
+ linear-gradient(225deg, rgba(255,255,255,0.06) 25%, transparent 25.5%);
+ background-size: 28px 28px;
+}
+
+.room-panel:nth-child(4)::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image: repeating-linear-gradient(
+ -18deg,
+ transparent,
+ transparent 7px,
+ rgba(0,0,0,0.05) 7px,
+ rgba(0,0,0,0.05) 8px
+ );
+}
+
+.room-panel:nth-child(5)::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ radial-gradient(ellipse 80% 50% at 50% 100%, rgba(0,0,0,0.12), transparent 70%),
+ linear-gradient(180deg, rgba(255,255,255,0.1), transparent 40%);
+}
+
+.room-floor {
+ height: 28px;
+ background:
+ linear-gradient(90deg, #c4b49a 0%, #d4c4a8 20%, #bba888 50%, #d0c0a0 80%, #c4b49a 100%);
+ border-top: 1px solid var(--line-strong);
+ position: relative;
+}
+
+.room-floor::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image: repeating-linear-gradient(
+ 90deg,
+ transparent 0,
+ transparent 48px,
+ rgba(0,0,0,0.06) 48px,
+ rgba(0,0,0,0.06) 49px
+ );
+}
+
+.room-caption {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 14px 18px;
+ border-top: 1px solid var(--line);
+ background: var(--surface);
+}
+
+.room-caption span {
+ font-size: 11px;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.room-caption strong {
+ font-family: var(--serif);
+ font-size: 15px;
+ font-weight: 400;
+ color: var(--ink);
+ letter-spacing: 0.02em;
+}
+
+/* Palette story */
+.story {
+ border-top: 1px solid var(--line);
+ padding-top: 28px;
+ display: grid;
+ grid-template-columns: 1fr auto;
+ gap: 24px;
+ align-items: end;
+}
+
+.story p {
+ font-size: 15px;
+ line-height: 1.7;
+ color: var(--muted);
+ max-width: 52ch;
+}
+
+.story p em {
+ font-family: var(--serif);
+ font-style: italic;
+ color: var(--ink);
+ font-size: 17px;
+}
+
+/* Toast overlay */
+.toast {
+ position: fixed;
+ bottom: 32px;
+ left: 50%;
+ transform: translateX(-50%) translateY(20px);
+ background: var(--ink);
+ color: var(--bg);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ padding: 14px 28px;
+ border-radius: var(--r-tight);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
+ z-index: 200;
+ box-shadow: var(--shadow);
+}
+
+.toast.show {
+ opacity: 1;
+ transform: translateX(-50%) translateY(0);
+}
+
+/* Export overlay */
+.overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(28, 26, 23, 0.48);
+ z-index: 300;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24px;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.4s var(--ease);
+}
+
+.overlay.open {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.overlay-card {
+ background: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: var(--r-card);
+ padding: 28px;
+ max-width: 440px;
+ width: 100%;
+ box-shadow: var(--shadow);
+ transform: translateY(12px);
+ transition: transform 0.4s var(--ease-out);
+}
+
+.overlay.open .overlay-card {
+ transform: translateY(0);
+}
+
+.overlay-card h3 {
+ font-family: var(--serif);
+ font-size: 28px;
+ font-weight: 400;
+ margin-bottom: 8px;
+ color: var(--ink);
+}
+
+.overlay-card p {
+ font-size: 14px;
+ color: var(--muted);
+ margin-bottom: 20px;
+ line-height: 1.6;
+}
+
+.overlay-actions {
+ display: flex;
+ gap: 8px;
+ justify-content: flex-end;
+}
+
+/* Hidden export canvas host */
+#exportHost {
+ position: absolute;
+ left: -9999px;
+ top: 0;
+ width: 1080px;
+ height: 1080px;
+ overflow: hidden;
+ pointer-events: none;
+}
+
+/* Accent hairline rule under hero */
+.hero::after {
+ content: '';
+ display: block;
+ width: 48px;
+ height: 1px;
+ background: var(--accent);
+ margin: 28px auto 0;
+}
+</style>
+</head>
+<body>
+<header class="site-header">
+ <div class="wordmark">Designer Wallcoverings</div>
+ <div class="header-meta">Palette Atelier</div>
+</header>
+
+<main>
+ <section class="hero">
+ <div class="hero-eyebrow">Interior Color Studio</div>
+ <h1>Compose a wallcovering palette</h1>
+ <p>Select a base hue. We curate five refined finishes — named as a designer would specify them on a finish schedule.</p>
+ </section>
+
+ <div class="studio">
+ <aside class="panel">
+ <span class="panel-label">Base Hue</span>
+ <div class="wheel-wrap">
+ <div class="wheel-stage" id="wheelStage">
+ <div class="hue-wheel" id="hueWheel" role="slider" aria-label="Base hue" aria-valuemin="0" aria-valuemax="360" aria-valuenow="32" tabindex="0"></div>
+ <div class="wheel-inner">
+ <div class="wheel-center-swatch" id="centerSwatch"></div>
+ </div>
+ <div class="wheel-marker" id="wheelMarker"></div>
+ </div>
+ <div class="hue-readout" id="hueReadout">H 32°</div>
+ </div>
+
+ <span class="panel-label">Harmony</span>
+ <div class="harmony" role="group" aria-label="Color harmony">
+ <button type="button" data-mode="analogous" aria-pressed="true">Analogous</button>
+ <button type="button" data-mode="complementary" aria-pressed="false">Complement</button>
+ <button type="button" data-mode="triadic" aria-pressed="false">Triadic</button>
+ </div>
+
+ <div class="panel-actions">
+ <button type="button" class="btn btn-primary" id="btnExport">Export 1080 Card</button>
+ <button type="button" class="btn btn-ghost" id="btnShuffle">Reshuffle Names</button>
+ </div>
+ </aside>
+
+ <section class="results">
+ <div class="section-head">
+ <h2>Curated Swatches</h2>
+ <span class="hint">Click to copy hex</span>
+ </div>
+
+ <div class="swatches" id="swatches" aria-live="polite"></div>
+
+ <div class="room-block">
+ <div class="section-head">
+ <h2>Room Preview</h2>
+ <span class="hint">Live wallcovering strip</span>
+ </div>
+ <div class="room-frame">
+ <div class="room-strip" id="roomStrip"></div>
+ <div class="room-floor"></div>
+ <div class="room-caption">
+ <span>Elevation study</span>
+ <strong id="roomTitle">Warm Ivory Suite</strong>
+ </div>
+ </div>
+ </div>
+
+ <div class="story">
+ <p id="storyText">A quiet progression of <em>warm plaster tones</em> anchored by deep ink — suited to a salon or primary suite with morning light.</p>
+ <button type="button" class="btn btn-ghost" id="btnCopyAll">Copy All Hex</button>
+ </div>
+ </section>
+ </div>
+</main>
+
+<div class="toast" id="toast" role="status"></div>
+
+<div class="overlay" id="exportOverlay" aria-hidden="true">
+ <div class="overlay-card" role="dialog" aria-labelledby="exportTitle">
+ <h3 id="exportTitle">Card ready</h3>
+ <p id="exportMsg">Your 1080×1080 social card has been prepared. Download the PNG to share.</p>
+ <div class="overlay-actions">
+ <button type="button" class="btn btn-ghost" id="btnCloseOverlay">Close</button>
+ <button type="button" class="btn btn-primary" id="btnDownload">Download PNG</button>
+ </div>
+ </div>
+</div>
+
+<div id="exportHost" aria-hidden="true"></div>
+
+<script>
+(function () {
+ 'use strict';
+
+ const NAME_POOL = [
+ 'Alabaster', 'Greige', 'Celadon', 'Ink', 'Brass',
+ 'Parchment', 'Sable', 'Dove', 'Champagne', 'Slate',
+ 'Linen', 'Moss', 'Ivory', 'Charcoal', 'Clay',
+ 'Bone', 'Olive', 'Smoke', 'Sand', 'Noir',
+ 'Porcelain', 'Taupe', 'Sage', 'Bronze', 'Pearl',
+ 'Ecru', 'Umber', 'Mist', 'Copper', 'Chalk',
+ 'Flax', 'Graphite', 'Bisque', 'Verdant', 'Oyster',
+ 'Putty', 'Teal', 'Stone', 'Gilt', 'Ash'
+ ];
+
+ const STORY_BITS = {
+ analogous: [
+ 'A quiet progression of <em>neighboring hues</em> that wrap a room in calm continuity — ideal for galleries and primary suites.',
+ 'Softly related tones that read as one family under natural light, finished with a deeper anchor for trim and millwork.',
+ 'An unbroken chromatic whisper — walls that feel composed rather than decorated.'
+ ],
+ complementary: [
+ 'A poised dialogue between <em>opposing temperatures</em> — warm plaster against a cool counterpoint for dining rooms and libraries.',
+ 'Balanced tension: the base finds its answer across the wheel, refined into livable interiors rather than high contrast.',
+ 'Complementary restraint — jewel depth tempered by pale ground for evening rooms.'
+ ],
+ triadic: [
+ 'A triad resolved into <em>five livable finishes</em> — lively enough for a foyer, quiet enough for a study.',
+ 'Three-point harmony distilled for walls: character without clamour, structure without severity.',
+ 'Architectural color with triangular balance — each swatch earns its place on the schedule.'
+ ]
+ };
+
+ const SUITE_TITLES = [
+ 'Warm Ivory Suite', 'Morning Salon', 'Library Elevation',
+ 'Garden Wing', 'North Atelier', 'Evening Parlor', 'Courtyard Study'
+ ];
+
+ let hue = 32;
+ let mode = 'analogous';
+ let palette = [];
+ let nameSeed = 0;
+ let exportUrl = null;
+
+ const $ = (id) => document.getElementById(id);
+ const wheel = $('hueWheel');
+ const marker = $('wheelMarker');
+ const center = $('centerSwatch');
+ const readout = $('hueReadout');
+ const swatchesEl = $('swatches');
+ const roomStrip = $('roomStrip');
+ const storyText = $('storyText');
+ const roomTitle = $('roomTitle');
+ const toast = $('toast');
+ const overlay = $('exportOverlay');
+
+ function clamp(n, a, b) { return Math.max(a, Math.min(b, n)); }
+
+ function hslToRgb(h, s, l) {
+ h = ((h % 360) + 360) % 360;
+ s = clamp(s, 0, 100) / 100;
+ l = clamp(l, 0, 100) / 100;
+ const c = (1 - Math.abs(2 * l - 1)) * s;
+ const x = c * (1 - Math.abs((h / 60) % 2 - 1));
+ const m = l - c / 2;
+ let r = 0, g = 0, b = 0;
+ if (h < 60) { r = c; g = x; }
+ else if (h < 120) { r = x; g = c; }
+ else if (h < 180) { g = c; b = x; }
+ else if (h < 240) { g = x; b = c; }
+ else if (h < 300) { r = x; b = c; }
+ else { r = c; b = x; }
+ return [
+ Math.round((r + m) * 255),
+ Math.round((g + m) * 255),
+ Math.round((b + m) * 255)
+ ];
+ }
+
+ function rgbToHex(r, g, b) {
+ return '#' + [r, g, b].map(v => v.toString(16).padStart(2, '0')).join('').toUpperCase();
+ }
+
+ function hslHex(h, s, l) {
+ return rgbToHex(...hslToRgb(h, s, l));
+ }
+
+ function relativeLuminance(hex) {
+ const r = parseInt(hex.slice(1, 3), 16) / 255;
+ const g = parseInt(hex.slice(3, 5), 16) / 255;
+ const b = parseInt(hex.slice(5, 7), 16) / 255;
+ const f = (c) => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
+ return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b);
+ }
+
+ /* Designer-grade interior finishes from a base hue */
+ function buildPalette(h, m) {
+ const specs = [];
+ if (m === 'analogous') {
+ specs.push(
+ { h: h - 18, s: 18, l: 88 },
+ { h: h - 8, s: 14, l: 74 },
+ { h: h, s: 22, l: 58 },
+ { h: h + 12, s: 16, l: 36 },
+ { h: h + 22, s: 28, l: 22 }
+ );
+ } else if (m === 'complementary') {
+ const c = h + 180;
+ specs.push(
+ { h: h, s: 16, l: 90 },
+ { h: h, s: 22, l: 72 },
+ { h: h + 8, s: 18, l: 48 },
+ { h: c, s: 20, l: 38 },
+ { h: c - 6, s: 24, l: 20 }
+ );
+ } else {
+ const t1 = h + 120;
+ const t2 = h + 240;
+ specs.push(
+ { h: h, s: 14, l: 89 },
+ { h: t1, s: 18, l: 68 },
+ { h: h, s: 20, l: 52 },
+ { h: t2, s: 16, l: 34 },
+ { h: h, s: 22, l: 18 }
+ );
+ }
+
+ // Metallic brass accent on middle-dark for luxury feel when hue is warm
+ const colors = specs.map((sp, i) => {
+ let { h: hh, s, l } = sp;
+ // Keep interiors tasteful: mute chroma on very light / very dark
+ if (l > 82) s = Math.min(s, 16);
+ if (l < 25) s = Math.min(s, 26);
+ // Fourth swatch leans toward ink when too colorful
+ if (i === 3 && s > 22) s = 18;
+ const hex = hslHex(hh, s, l);
+ return { h: hh, s, l, hex };
+ });
+
+ // Ensure brass-like metallic appears as the warm accent when base is warm-neutral
+ if (m === 'analogous' && (h < 50 || h > 340)) {
+ colors[4] = { h: 42, s: 42, l: 42, hex: hslHex(42, 42, 42) };
+ }
+
+ return colors;
+ }
+
+ function pickNames(n) {
+ const pool = NAME_POOL.slice();
+ // deterministic-ish shuffle from seed + hue
+ let s = (nameSeed * 9301 + Math.round(hue) * 49297) % 233280;
+ const rand = () => {
+ s = (s * 9301 + 49297) % 233280;
+ return s / 233280;
+ };
+ for (let i = pool.length - 1; i > 0; i--) {
+ const j = Math.floor(rand() * (i + 1));
+ [pool[i], pool[j]] = [pool[j], pool[i]];
+ }
+ // Prefer classic set first pass
+ const classic = ['Alabaster', 'Greige', 'Celadon', 'Ink', 'Brass'];
+ if (nameSeed === 0) return classic.slice(0, n);
+ return pool.slice(0, n);
+ }
+
+ function setMarker(h) {
+ const rad = (h - 90) * Math.PI / 180;
+ const r = 100 - 14; // radius to ring center
+ const cx = 100 + r * Math.cos(rad);
+ const cy = 100 + r * Math.sin(rad);
+ marker.style.left = cx + 'px';
+ marker.style.top = cy + 'px';
+ const hex = hslHex(h, 55, 50);
+ marker.style.background = hex;
+ center.style.background = hex;
+ readout.textContent = 'H ' + Math.round(h) + '°';
+ wheel.setAttribute('aria-valuenow', String(Math.round(h)));
+ }
+
+ function hueFromEvent(e) {
+ const rect = wheel.getBoundingClientRect();
+ const x = (e.clientX - rect.left) - rect.width / 2;
+ const y = (e.clientY - rect.top) - rect.height / 2;
+ let deg = Math.atan2(y, x) * 180 / Math.PI + 90;
+ if (deg < 0) deg += 360;
+ return deg;
+ }
+
+ function showToast(msg) {
+ toast.textContent = msg;
+ toast.classList.add('show');
+ clearTimeout(showToast._t);
+ showToast._t = setTimeout(() => toast.classList.remove('show'), 1600);
+ }
+
+ function copyText(text) {
+ if (navigator.clipboard && navigator.clipboard.writeText) {
+ return navigator.clipboard.writeText(text).then(() => true).catch(() => fallbackCopy(text));
+ }
+ return Promise.resolve(fallbackCopy(text));
+ }
+
+ function fallbackCopy(text) {
+ const ta = document.createElement('textarea');
+ ta.value = text;
+ ta.setAttribute('readonly', '');
+ ta.style.cssText = 'position:fixed;left:-9999px;top:0';
+ document.body.appendChild(ta);
+ ta.select();
+ let ok = false;
+ try { ok = document.execCommand('copy'); } catch (_) {}
+ document.body.removeChild(ta);
+ return ok;
+ }
+
+ function render() {
+ palette = buildPalette(hue, mode);
+ const names = pickNames(5);
+ palette.forEach((p, i) => { p.name = names[i]; });
+
+ setMarker(hue);
+
+ swatchesEl.innerHTML = '';
+ palette.forEach((p, i) => {
+ const el = document.createElement('button');
+ el.type = 'button';
+ el.className = 'swatch';
+ el.setAttribute('aria-label', p.name + ' ' + p.hex + ', copy hex');
+ el.innerHTML =
+ '<div class="swatch-chip" style="background:' + p.hex + '"></div>' +
+ '<div class="swatch-meta">' +
+ '<div class="swatch-name">' + p.name + '</div>' +
+ '<div class="swatch-hex">' + p.hex + '</div>' +
+ '</div>';
+ el.addEventListener('click', () => {
+ copyText(p.hex).then((ok) => {
+ el.classList.remove('copied');
+ void el.offsetWidth;
+ el.classList.add('copied');
+ showToast(ok ? p.name + ' · ' + p.hex : 'Copy unavailable');
+ setTimeout(() => el.classList.remove('copied'), 900);
+ });
+ });
+ swatchesEl.appendChild(el);
+ });
+
+ roomStrip.innerHTML = '';
+ palette.forEach((p) => {
+ const panel = document.createElement('div');
+ panel.className = 'room-panel';
+ panel.style.background = p.hex;
+ roomStrip.appendChild(panel);
+ });
+
+ const bits = STORY_BITS[mode];
+ storyText.innerHTML = bits[Math.floor(hue / 60) % bits.length];
+ roomTitle.textContent = SUITE_TITLES[Math.floor(hue / 51) % SUITE_TITLES.length];
+ }
+
+ /* Wheel interaction */
+ let dragging = false;
+
+ function onPointer(e) {
+ hue = hueFromEvent(e);
+ render();
+ }
+
+ wheel.addEventListener('pointerdown', (e) => {
+ dragging = true;
+ wheel.setPointerCapture(e.pointerId);
+ onPointer(e);
+ });
+ wheel.addEventListener('pointermove', (e) => {
+ if (!dragging) return;
+ onPointer(e);
+ });
+ wheel.addEventListener('pointerup', () => { dragging = false; });
+ wheel.addEventListener('pointercancel', () => { dragging = false; });
+
+ wheel.addEventListener('keydown', (e) => {
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {
+ hue = (hue - 2 + 360) % 360; render(); e.preventDefault();
+ } else if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {
+ hue = (hue + 2) % 360; render(); e.preventDefault();
+ }
+ });
+
+ /* Harmony */
+ document.querySelectorAll('.harmony button').forEach((btn) => {
+ btn.addEventListener('click', () => {
+ document.querySelectorAll('.harmony button').forEach((b) => b.setAttribute('aria-pressed', 'false'));
+ btn.setAttribute('aria-pressed', 'true');
+ mode = btn.getAttribute('data-mode');
+ render();
+ });
+ });
+
+ $('btnShuffle').addEventListener('click', () => {
+ nameSeed += 1;
+ render();
+ showToast('Names reshuffled');
+ });
+
+ $('btnCopyAll').addEventListener('click', () => {
+ const block = palette.map((p) => p.name + ' ' + p.hex).join('\n');
+ copyText(block).then((ok) => showToast(ok ? 'Palette copied' : 'Copy unavailable'));
+ });
+
+ /* Export 1080 card via canvas */
+ function drawCard() {
+ const size = 1080;
+ const canvas = document.createElement('canvas');
+ canvas.width = size;
+ canvas.height = size;
+ const ctx = canvas.getContext('2d');
+
+ // Ivory ground
+ ctx.fillStyle = '#f7f3eb';
+ ctx.fillRect(0, 0, size, size);
+
+ // Outer hairline frame
+ ctx.strokeStyle = 'rgba(28,26,23,0.14)';
+ ctx.lineWidth = 1;
+ ctx.strokeRect(48, 48, size - 96, size - 96);
+
+ // Wordmark
+ ctx.fillStyle = '#1c1a17';
+ ctx.font = '500 28px Didot, "Bodoni MT", Georgia, serif';
+ ctx.letterSpacing = '0.18em';
+ ctx.textAlign = 'center';
+ ctx.fillText('DESIGNER WALLCOVERINGS', size / 2, 120);
+
+ // Accent rule
+ ctx.strokeStyle = '#c9a961';
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ ctx.moveTo(size / 2 - 28, 148);
+ ctx.lineTo(size / 2 + 28, 148);
+ ctx.stroke();
+
+ // Title
+ ctx.fillStyle = '#1c1a17';
+ ctx.font = '400 54px Didot, "Bodoni MT", Georgia, serif';
+ ctx.fillText(roomTitle.textContent, size / 2, 220);
+
+ // Harmony label
+ ctx.fillStyle = '#8a8578';
+ ctx.font = '500 16px "Avenir Next", "Helvetica Neue", sans-serif';
+ const modeLabel = mode.toUpperCase() + ' · H ' + Math.round(hue) + '°';
+ ctx.fillText(modeLabel, size / 2, 258);
+
+ // Five vertical panels
+ const stripY = 310;
+ const stripH = 420;
+ const stripX = 100;
+ const stripW = size - 200;
+ const pw = stripW / 5;
+
+ palette.forEach((p, i) => {
+ const x = stripX + i * pw;
+ ctx.fillStyle = p.hex;
+ ctx.fillRect(x, stripY, pw + 0.5, stripH);
+
+ // subtle motif lines
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(x, stripY, pw, stripH);
+ ctx.clip();
+ ctx.strokeStyle = 'rgba(255,255,255,0.08)';
+ ctx.lineWidth = 1;
+ if (i % 2 === 0) {
+ for (let lx = x; lx < x + pw; lx += 14) {
+ ctx.beginPath();
+ ctx.moveTo(lx, stripY);
+ ctx.lineTo(lx, stripY + stripH);
+ ctx.stroke();
+ }
+ } else {
+ for (let ly = stripY; ly < stripY + stripH; ly += 18) {
+ ctx.beginPath();
+ ctx.moveTo(x, ly);
+ ctx.lineTo(x + pw, ly);
+ ctx.stroke();
+ }
+ }
+ ctx.restore();
+ });
+
+ // Floor band
+ const grad = ctx.createLinearGradient(stripX, 0, stripX + stripW, 0);
+ grad.addColorStop(0, '#c4b49a');
+ grad.addColorStop(0.5, '#d4c4a8');
+ grad.addColorStop(1, '#bba888');
+ ctx.fillStyle = grad;
+ ctx.fillRect(stripX, stripY + stripH, stripW, 36);
+
+ // Names + hex under strip
+ const metaY = stripY + stripH + 90;
+ palette.forEach((p, i) => {
+ const cx = stripX + i * pw + pw / 2;
+ ctx.fillStyle = '#1c1a17';
+ ctx.font = '400 22px Didot, Georgia, serif';
+ ctx.textAlign = 'center';
+ ctx.fillText(p.name, cx, metaY);
+ ctx.fillStyle = '#8a8578';
+ ctx.font = '500 14px "SF Mono", Consolas, monospace';
+ ctx.fillText(p.hex, cx, metaY + 28);
+ });
+
+ // Footer
+ ctx.fillStyle = '#8a8578';
+ ctx.font = '500 14px "Avenir Next", "Helvetica Neue", sans-serif';
+ ctx.textAlign = 'center';
+ ctx.fillText('PALETTE ATELIER · INTERIOR FINISH SCHEDULE', size / 2, size - 80);
+
+ return canvas;
+ }
+
+ $('btnExport').addEventListener('click', () => {
+ const canvas = drawCard();
+ if (exportUrl) URL.revokeObjectURL(exportUrl);
+ canvas.toBlob((blob) => {
+ if (!blob) {
+ $('exportTitle').textContent = 'Export unavailable';
+ $('exportMsg').textContent = 'The browser could not encode the card. Try another browser.';
+ $('btnDownload').style.display = 'none';
+ overlay.classList.add('open');
+ overlay.setAttribute('aria-hidden', 'false');
+ return;
+ }
+ exportUrl = URL.createObjectURL(blob);
+ $('exportTitle').textContent = 'Card ready';
+ $('exportMsg').textContent = 'Your 1080×1080 social card has been prepared. Download the PNG to share on Instagram or Pinterest.';
+ $('btnDownload').style.display = '';
+ overlay.classList.add('open');
+ overlay.setAttribute('aria-hidden', 'false');
+ }, 'image/png');
+ });
+
+ $('btnDownload').addEventListener('click', () => {
+ if (!exportUrl) return;
+ const a = document.createElement('a');
+ a.href = exportUrl;
+ a.download = 'designer-wallcoverings-palette.png';
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ showToast('Download started');
+ });
+
+ function closeOverlay() {
+ overlay.classList.remove('open');
+ overlay.setAttribute('aria-hidden', 'true');
+ }
+
+ $('btnCloseOverlay').addEventListener('click', closeOverlay);
+ overlay.addEventListener('click', (e) => {
+ if (e.target === overlay) closeOverlay();
+ });
+ document.addEventListener('keydown', (e) => {
+ if (e.key === 'Escape' && overlay.classList.contains('open')) closeOverlay();
+ });
+
+ render();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/grok.png b/data/artifacts/420dc7bd02b3/grok.png
new file mode 100644
index 0000000..0cc8339
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/grok.png differ
diff --git a/data/artifacts/420dc7bd02b3/hermes3-8b.html b/data/artifacts/420dc7bd02b3/hermes3-8b.html
new file mode 100644
index 0000000..05db0b3
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/hermes3-8b.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Designer Wallcoverings Color Palette Builder</title>
+<style>
+:root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e / #2f4c39;
+ --line: rgba(0, 0, 0, .12);
+ --shadow: rgba(0, 0, 0, .18);
+ --ease: cubic-bezier(.22, 1, .36, 1);
+}
+
+body {
+ background-color: var(--bg);
+ color: var(--text);
+ font-family: 'EB Garamond', serif;
+ line-height: 1.6;
+}
+
+h1, h2, h3 {
+ font-family: 'Cormorant Garamond', serif;
+ text-transform: uppercase;
+ letter-spacing: .18em;
+}
+
+.header {
+ background-color: var(--surface);
+ padding: 24px;
+}
+
+.wordmark {
+ display: block;
+ margin: 0 auto;
+ font-size: 40px;
+ color: var(--text);
+ --wordmark-font-family: 'Cormorant Garamond', serif;
+}
+
+.card {
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: 0 8px 24px var(--line), 0 16px 48px var(--shadow) hover:~'0 16px 48px rgba(0, 0, 0, .18)';
+ transition: transform .7s var(--ease), opacity .7s var(--ease);
+}
+
+.card:nth-child(3n+1) {
+ grid-row: span 2;
+}
+
+.card img {
+ display: block;
+ width: 100%;
+ height: auto;
+}
+
+.card p {
+ margin: 8px 0 0;
+ color: var(--muted);
+}
+
+button {
+ background-color: var(--accent);
+ border: none;
+ color: var(--surface);
+ font-family: 'EB Garamond', serif;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ padding: 12px 24px;
+ margin-top: 16px;
+}
+
+button:hover {
+ background-color: var(--accent) o(1%);
+}
+
+.overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(var(--bg), .9);
+ color: var(--text);
+ font-family: 'EB Garamond', serif;
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+ opacity: 0;
+ visibility: hidden;
+}
+
+.overlay.active {
+ opacity: 1;
+ visibility: visible;
+}
+
+.overlay img {
+ max-width: 60%;
+}
+
+.overlay button {
+ background-color: var(--surface);
+ border-radius: 50%;
+ box-shadow: 0 0 24px var(--accent)@35%;
+ padding: 8px;
+}
+
+.overlay p {
+ margin: 16px auto;
+}
+
+.fadeUp {
+ animation: fadeUp .7s var(--ease) both;
+}
+
+.stagger {
+ animation: stagger .3s var(--ease) both;
+ animation-delay: calc(.3s * var(--stagger));
+}
+
+@keyframes fadeUp {
+ from {opacity: 0; transform: translateY(28px);}
+ to {opacity: 1; transform: none;}
+}
+
+@keyframes stagger {
+ from {transform: translateY(var(--start)); opacity: .6}
+ to {transform: translateY(0); opacity: 1}
+}
+
+</style>
+</head>
+<body>
+
+<header class="header wordmark">DESIGNER WALLCOVERINGS</header>
+
+<main class="grid" style="--gap:24px; --muted:#9b948a; --accent:#2f4c39 / #b0472e;">
+<div class="card fadeUp stagger" style="--delay:.3s;" aria-hidden="true">Alabaster</div>
+<div class="card fadeUp stagger" style="--delay:.5s;" aria-hidden="true">Greige</div>
+<div class="card fadeUp stagger" style="--delay:.7s;" aria-hidden="true">Celadon</div>
+<div class="card fadeUp stagger" style="--delay:.9s;">Ink</div>
+<div class="card fadeUp stagger" style="--delay:1.1s;">Brass</div>
+</main>
+
+<button onclick="this.nextElementSibling.classList.toggle('active')">Preview Room</button>
+
+<aside class="overlay active">
+ <img src=none style='--swatch:#faf8f4' alt='' aria-hidden=true>
+ <p>Exporting as 1080x1080 card...</p>
+ <button class="fadeUp">Close</button>
+</aside>
+
+<script>
+function copyToClipboard(text) {
+ navigator.clipboard.writeText(text).then(() => {
+ document.querySelector('.overlay.active').querySelector('p').textContent = 'Copied!';
+ setTimeout(() => {
+ document.querySelector('.overlay.active').querySelector('p').textContent = 'Exporting as 1080x1080 card...';
+ }, 2000);
+ });
+}
+
+document.querySelectorAll('.card p').forEach(el => {
+ el.addEventListener('click', () => {
+ const hex = el.parentElement.style.setProperty('--swatch', '');
+ document.querySelector('.overlay img').setAttribute('src', 'none');
+ document.querySelector('.overlay img').style.setProperty('background-color', `var(--swatch)`, 'important');
+ copyToClipboard(hex);
+ });
+});
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/hermes3-8b.png b/data/artifacts/420dc7bd02b3/hermes3-8b.png
new file mode 100644
index 0000000..4d8ff13
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/hermes3-8b.png differ
diff --git a/data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.html b/data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..825a574
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.html
@@ -0,0 +1,215 @@
+<!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: #dcd6ce;
+ --shadow: rgba(0, 0, 0, .12);
+ --hover-shadow: rgba(0, 0, 0, .18);
+ --glow: rgba(176, 71, 46, .35);
+ --ease: cubic-bezier(.22, 1, .36, 1);
+ }
+ body {
+ margin: 0;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ background-color: var(--bg);
+ color: var(--text);
+ line-height: 1.5;
+ }
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ padding: 24px;
+ background-color: var(--bg);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, .06);
+ z-index: 1000;
+ }
+ header h1 {
+ margin: 0;
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 48px;
+ letter-spacing: .18em;
+ text-transform: uppercase;
+ color: var(--text);
+ }
+ main {
+ padding-top: 96px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ min-height: 100vh;
+ }
+ .controls {
+ margin-bottom: 48px;
+ display: flex;
+ gap: 24px;
+ }
+ .controls button {
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ color: var(--text);
+ padding: 12px 24px;
+ font-size: 16px;
+ letter-spacing: .15em;
+ text-transform: uppercase;
+ cursor: pointer;
+ transition: background-color .3s var(--ease), box-shadow .3s var(--ease);
+ }
+ .controls button:hover {
+ background-color: var(--accent);
+ color: var(--surface);
+ box-shadow: 0 4px 16px rgba(0, 0, 0, .12);
+ }
+ .palette {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+ }
+ .swatch {
+ position: relative;
+ width: 100%;
+ padding-bottom: 56.25%; /* 16/9 ratio */
+ background-color: #000;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 8px 24px var(--shadow);
+ transition: transform .3s var(--ease), box-shadow .3s var(--ease);
+ }
+ .swatch:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 16px 48px var(--hover-shadow);
+ }
+ .swatch span {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 24px;
+ color: #fff;
+ opacity: 0;
+ transition: opacity .3s var(--ease);
+ }
+ .swatch:hover span {
+ opacity: 1;
+ }
+ .preview {
+ width: 100%;
+ max-width: 800px;
+ height: 120px;
+ margin-bottom: 48px;
+ background-color: var(--surface);
+ border-radius: 8px;
+ overflow: hidden;
+ display: flex;
+ }
+ .preview div {
+ flex: 1;
+ }
+ .export-btn {
+ background-color: var(--accent);
+ color: var(--surface);
+ padding: 12px 24px;
+ font-size: 16px;
+ letter-spacing: .15em;
+ text-transform: uppercase;
+ cursor: pointer;
+ border-radius: 8px;
+ transition: background-color .3s var(--ease), box-shadow .3s var(--ease);
+ }
+ .export-btn:hover {
+ background-color: #2f4c39;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, .12);
+ }
+ </style>
+</head>
+<body>
+ <header>
+ <h1>DESIGNER WALLCOVERINGS</h1>
+ </header>
+ <main>
+ <div class="controls">
+ <button onclick="generatePalette('analogous')">ANALOGOUS</button>
+ <button onclick="generatePalette('complementary')">COMPLEMENTARY</button>
+ <button onclick="generatePalette('triadic')">TRIADIC</button>
+ </div>
+ <div class="palette" id="palette"></div>
+ <div class="preview" id="preview">
+ <!-- Swatches will be dynamically added here -->
+ </div>
+ <button class="export-btn" onclick="exportPalette()">EXPORT AS 1080x1080 CARD</button>
+ </main>
+ <script>
+ const hues = {
+ analogous: ['#e6d3b4', '#c9a961', '#7d6a45', '#5f472a', '#413413'],
+ complementary: ['#e6d3b4', '#b0472e', '#ff8c66', '#ffc1aa', '#ffe6cc'],
+ triadic: ['#e6d3b4', '#b0472e', '#2f4c39', '#95a88d', '#6fa385']
+ };
+ const names = ['Alabaster', 'Greige', 'Celadon', 'Ink', 'Brass'];
+
+ function generatePalette(type) {
+ const colors = hues[type];
+ const paletteContainer = document.getElementById('palette');
+ paletteContainer.innerHTML = '';
+ const previewContainer = document.getElementById('preview');
+ previewContainer.innerHTML = '';
+
+ colors.forEach((color, index) => {
+ const swatch = document.createElement('div');
+ swatch.className = 'swatch';
+ swatch.style.backgroundColor = color;
+ swatch.addEventListener('click', () => copyHex(color));
+
+ const span = document.createElement('span');
+ span.textContent = names[index];
+ swatch.appendChild(span);
+
+ paletteContainer.appendChild(swatch);
+
+ const previewSwatch = document.createElement('div');
+ previewSwatch.style.backgroundColor = color;
+ previewContainer.appendChild(previewSwatch);
+ });
+ }
+
+ function copyHex(hex) {
+ navigator.clipboard.writeText(hex).then(() => {
+ alert(`Copied ${hex} to clipboard!`);
+ }, () => {
+ alert('Failed to copy text!');
+ });
+ }
+
+ function exportPalette() {
+ const paletteContainer = document.getElementById('palette');
+ const canvas = document.createElement('canvas');
+ canvas.width = 1080;
+ canvas.height = 1080;
+ const ctx = canvas.getContext('2d');
+
+ Array.from(paletteContainer.children).forEach((swatch, index) => {
+ const color = swatch.style.backgroundColor;
+ ctx.fillStyle = color;
+ ctx.fillRect(index * (canvas.width / 5), 0, canvas.width / 5, canvas.height);
+ });
+
+ const link = document.createElement('a');
+ link.href = canvas.toDataURL();
+ link.download = 'wallcovering_palette.png';
+ link.click();
+ }
+
+ generatePalette('analogous'); // Default palette
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.png b/data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..19cc5bc
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/hf-qwen-coder-32b.png differ
diff --git a/data/artifacts/420dc7bd02b3/kimi.html b/data/artifacts/420dc7bd02b3/kimi.html
new file mode 100644
index 0000000..644ca9f
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/kimi.html
@@ -0,0 +1,885 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Designer Wallcoverings — Curated Palette Builder</title>
+ <style>
+ /* DESIGN TOKENS */
+ :root {
+ /* Luxury Noir Palette */
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-2: #1e1e24;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --ink: #1c1a17;
+
+ /* Lines & Shadows */
+ --line: rgba(245, 242, 234, 0.12);
+ --line-strong: rgba(245, 242, 234, 0.22);
+ --shadow-sm: 0 1px 2px rgba(0,0,0,.06);
+ --shadow-md: 0 2px 8px rgba(0,0,0,.08);
+ --shadow-lg: 0 8px 24px rgba(0,0,0,.12);
+ --shadow-xl: 0 16px 48px rgba(0,0,0,.18);
+ --glow-accent: 0 0 24px 2px rgba(201, 169, 97, 0.35);
+
+ /* Typography */
+ --font-display: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ --font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ --font-mono: 'SF Mono', 'Cascadia Code', Consolas, Menlo, monospace;
+
+ /* Motion */
+ --ease-swift: cubic-bezier(.22,.9,.24,1);
+ --ease-power: cubic-bezier(.77,0,.18,1);
+ --ease-hero: cubic-bezier(.22,1,.36,1);
+ --duration: 0.6s;
+
+ /* Spacing */
+ --space-xs: 8px;
+ --space-sm: 16px;
+ --space-md: 24px;
+ --space-lg: 48px;
+ --space-xl: 80px;
+
+ /* Sizes */
+ --header-height: 80px;
+ }
+
+ /* RESET & BASE */
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ html {
+ font-size: 16px;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ }
+
+ body {
+ font-family: var(--font-body);
+ background-color: var(--bg);
+ color: var(--text);
+ line-height: 1.6;
+ padding-top: var(--header-height);
+ }
+
+ /* HEADER */
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: var(--header-height);
+ background-color: var(--surface);
+ border-bottom: 1px solid var(--line);
+ display: flex;
+ align-items: center;
+ padding: 0 var(--space-lg);
+ z-index: 100;
+ box-shadow: var(--shadow-md);
+ }
+
+ .wordmark {
+ font-family: var(--font-display);
+ font-size: 44px;
+ font-weight: 400;
+ color: var(--text);
+ text-transform: uppercase;
+ letter-spacing: 0.18em;
+ line-height: 1.1;
+ }
+
+ /* MAIN LAYOUT */
+ main {
+ max-width: 1400px;
+ margin: 0 auto;
+ padding: var(--space-xl) var(--space-lg);
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--space-xl);
+ align-items: start;
+ }
+
+ @media (max-width: 1024px) {
+ main {
+ grid-template-columns: 1fr;
+ }
+ }
+
+ /* TYPOGRAPHY */
+ h1, h2, h3 {
+ font-family: var(--font-display);
+ font-weight: 400;
+ line-height: 1.1;
+ color: var(--text);
+ }
+
+ h2 {
+ font-size: 38px;
+ margin-bottom: var(--space-md);
+ letter-spacing: -0.02em;
+ }
+
+ h3 {
+ font-size: 28px;
+ margin-bottom: var(--space-sm);
+ }
+
+ .label {
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+ color: var(--muted);
+ margin-bottom: var(--space-xs);
+ font-weight: 500;
+ }
+
+ /* COLOR WHEEL SECTION */
+ .wheel-section {
+ animation: fadeUp 0.8s var(--ease-hero) both;
+ }
+
+ .wheel-container {
+ position: relative;
+ width: 400px;
+ height: 400px;
+ margin: var(--space-lg) auto;
+ }
+
+ #colorWheel {
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ cursor: crosshair;
+ box-shadow: var(--shadow-xl), var(--glow-accent);
+ }
+
+ .wheel-center {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 120px;
+ height: 120px;
+ background-color: var(--surface);
+ border-radius: 50%;
+ border: 1px solid var(--line-strong);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ pointer-events: none;
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
+ }
+
+ .current-hue {
+ width: 80px;
+ height: 80px;
+ border-radius: 50%;
+ border: 1px solid var(--line);
+ transition: background-color 0.3s var(--ease-swift);
+ }
+
+ /* HARMONY TOGGLE */
+ .harmony-toggle {
+ display: flex;
+ gap: var(--space-xs);
+ margin-top: var(--space-md);
+ justify-content: center;
+ }
+
+ .harmony-btn {
+ padding: 12px 24px;
+ background-color: transparent;
+ border: 1px solid var(--line);
+ color: var(--muted);
+ font-family: var(--font-body);
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.15em;
+ cursor: pointer;
+ transition: all 0.3s var(--ease-swift);
+ }
+
+ .harmony-btn:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+ }
+
+ .harmony-btn.active {
+ background-color: var(--accent);
+ color: var(--ink);
+ border-color: var(--accent);
+ }
+
+ /* PALETTE SECTION */
+ .palette-section {
+ animation: fadeUp 0.8s var(--ease-hero) 0.15s both;
+ }
+
+ .palette-grid {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: var(--space-sm);
+ margin-top: var(--space-lg);
+ }
+
+ .swatch-card {
+ position: relative;
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: 2px;
+ overflow: hidden;
+ cursor: pointer;
+ transition: all 0.4s var(--ease-swift);
+ animation: scaleIn 0.6s var(--ease-hero) both;
+ }
+
+ .swatch-card:hover {
+ transform: translateY(-4px);
+ box-shadow: var(--shadow-lg), 0 0 0 1px var(--accent);
+ }
+
+ .swatch-card.copied::after {
+ content: 'COPIED';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 10px;
+ letter-spacing: 0.2em;
+ color: var(--text);
+ background-color: var(--surface);
+ padding: 8px 12px;
+ border: 1px solid var(--accent);
+ animation: fadeUp 0.3s var(--ease-swift);
+ }
+
+ .swatch-color {
+ height: 140px;
+ width: 100%;
+ border-bottom: 1px solid var(--line);
+ transition: background-color 0.5s var(--ease-swift);
+ }
+
+ .swatch-info {
+ padding: var(--space-sm);
+ text-align: center;
+ }
+
+ .swatch-name {
+ font-family: var(--font-display);
+ font-size: 16px;
+ color: var(--text);
+ margin-bottom: 4px;
+ letter-spacing: 0.02em;
+ }
+
+ .swatch-hex {
+ font-family: var(--font-mono);
+ font-size: 11px;
+ color: var(--muted);
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+ }
+
+ /* ROOM PREVIEW STRIP */
+ .preview-section {
+ margin-top: var(--space-xl);
+ padding: var(--space-lg);
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ animation: fadeUp 0.8s var(--ease-hero) 0.3s both;
+ }
+
+ .preview-strip {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ height: 200px;
+ margin-top: var(--space-md);
+ border: 1px solid var(--line);
+ overflow: hidden;
+ }
+
+ .preview-panel {
+ position: relative;
+ transition: all 0.5s var(--ease-swift);
+ }
+
+ .preview-panel:not(:last-child) {
+ border-right: 1px solid var(--line);
+ }
+
+ /* Different patterns for each panel */
+ .pattern-geo {
+ background-image: repeating-linear-gradient(
+ 45deg,
+ transparent,
+ transparent 10px,
+ rgba(255,255,255,0.03) 10px,
+ rgba(255,255,255,0.03) 20px
+ );
+ }
+
+ .pattern-floral {
+ background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.04'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
+ }
+
+ .pattern-stripe {
+ background-image: repeating-linear-gradient(
+ 90deg,
+ transparent,
+ transparent 20px,
+ rgba(255,255,255,0.04) 20px,
+ rgba(255,255,255,0.04) 22px
+ );
+ }
+
+ .pattern-dot {
+ background-image: radial-gradient(
+ rgba(255,255,255,0.06) 1px,
+ transparent 1px
+ );
+ background-size: 20px 20px;
+ }
+
+ .pattern-lattice {
+ background-image: url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.04' fill-rule='evenodd'%3E%3Cpath d='M0 40L40 0H20L0 20M40 40V20L20 40'/%3E%3C/g%3E%3C/svg%3E");
+ }
+
+ /* EXPORT SECTION */
+ .export-section {
+ margin-top: var(--space-lg);
+ text-align: center;
+ }
+
+ .export-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--space-sm);
+ padding: 18px 48px;
+ background-color: var(--accent);
+ color: var(--ink);
+ border: none;
+ font-family: var(--font-body);
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.4s var(--ease-swift);
+ box-shadow: 0 4px 16px rgba(201, 169, 97, 0.3);
+ }
+
+ .export-btn:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 32px rgba(201, 169, 97, 0.4);
+ }
+
+ .export-btn:active {
+ transform: translateY(0);
+ }
+
+ /* CANVAS EXPORT HIDDEN */
+ #exportCanvas {
+ display: none;
+ }
+
+ /* ANIMATIONS */
+ @keyframes fadeUp {
+ from {
+ opacity: 0;
+ transform: translateY(28px);
+ }
+ to {
+ opacity: 1;
+ transform: none;
+ }
+ }
+
+ @keyframes scaleIn {
+ from {
+ opacity: 0;
+ transform: scale(0.92);
+ }
+ to {
+ opacity: 1;
+ transform: none;
+ }
+ }
+
+ /* TOAST NOTIFICATION */
+ .toast {
+ position: fixed;
+ bottom: var(--space-lg);
+ left: 50%;
+ transform: translateX(-50%) translateY(100px);
+ background-color: var(--surface-2);
+ color: var(--text);
+ padding: var(--space-sm) var(--space-lg);
+ border: 1px solid var(--accent);
+ font-size: 12px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ opacity: 0;
+ transition: all 0.4s var(--ease-swift);
+ z-index: 200;
+ pointer-events: none;
+ }
+
+ .toast.show {
+ opacity: 1;
+ transform: translateX(-50%) translateY(0);
+ }
+
+ /* STAGGERED ANIMATION DELAYS */
+ .swatch-card:nth-child(1) { animation-delay: 0.1s; }
+ .swatch-card:nth-child(2) { animation-delay: 0.2s; }
+ .swatch-card:nth-child(3) { animation-delay: 0.3s; }
+ .swatch-card:nth-child(4) { animation-delay: 0.4s; }
+ .swatch-card:nth-child(5) { animation-delay: 0.5s; }
+
+ /* RESPONSIVE */
+ @media (max-width: 768px) {
+ .wordmark {
+ font-size: 32px;
+ }
+
+ .palette-grid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ .preview-strip {
+ grid-template-columns: repeat(2, 1fr);
+ height: 300px;
+ }
+
+ .preview-panel:nth-child(2) {
+ border-right: none;
+ }
+
+ .preview-panel:nth-child(3),
+ .preview-panel:nth-child(4) {
+ border-top: 1px solid var(--line);
+ }
+
+ .wheel-container {
+ width: 300px;
+ height: 300px;
+ }
+ }
+ </style>
+</head>
+<body>
+ <header>
+ <div class="wordmark">Designer Wallcoverings</div>
+ </header>
+
+ <main>
+ <section class="wheel-section">
+ <p class="label">Select Foundation</p>
+ <h2>Color Wheel</h2>
+
+ <div class="wheel-container">
+ <canvas id="colorWheel" width="400" height="400"></canvas>
+ <div class="wheel-center">
+ <div class="current-hue" id="currentHue"></div>
+ </div>
+ </div>
+
+ <div class="harmony-toggle">
+ <button class="harmony-btn active" data-mode="analogous">Analogous</button>
+ <button class="harmony-btn" data-mode="complementary">Complementary</button>
+ <button class="harmony-btn" data-mode="triadic">Triadic</button>
+ </div>
+ </section>
+
+ <section class="palette-section">
+ <p class="label">Curated Palette</p>
+ <h2>Designer Collection</h2>
+
+ <div class="palette-grid" id="paletteGrid">
+ <div class="swatch-card" data-index="0">
+ <div class="swatch-color" style="background-color: #c9a961;"></div>
+ <div class="swatch-info">
+ <div class="swatch-name">Alabaster</div>
+ <div class="swatch-hex">#C9A961</div>
+ </div>
+ </div>
+ <div class="swatch-card" data-index="1">
+ <div class="swatch-color" style="background-color: #d4b896;"></div>
+ <div class="swatch-info">
+ <div class="swatch-name">Greige</div>
+ <div class="swatch-hex">#D4B896</div>
+ </div>
+ </div>
+ <div class="swatch-card" data-index="2">
+ <div class="swatch-color" style="background-color: #8a9a87;"></div>
+ <div class="swatch-info">
+ <div class="swatch-name">Celadon</div>
+ <div class="swatch-hex">#8A9A87</div>
+ </div>
+ </div>
+ <div class="swatch-card" data-index="3">
+ <div class="swatch-color" style="background-color: #1c1a17;"></div>
+ <div class="swatch-info">
+ <div class="swatch-name">Ink</div>
+ <div class="swatch-hex">#1C1A17</div>
+ </div>
+ </div>
+ <div class="swatch-card" data-index="4">
+ <div class="swatch-color" style="background-color: #7d6a45;"></div>
+ <div class="swatch-info">
+ <div class="swatch-name">Brass</div>
+ <div class="swatch-hex">#7D6A45</div>
+ </div>
+ </div>
+ </div>
+ </section>
+ </main>
+
+ <section class="preview-section">
+ <p class="label">Spatial Visualization</p>
+ <h3>Room Preview</h3>
+ <div class="preview-strip" id="previewStrip">
+ <div class="preview-panel pattern-geo" style="background-color: #c9a961;"></div>
+ <div class="preview-panel pattern-floral" style="background-color: #d4b896;"></div>
+ <div class="preview-panel pattern-stripe" style="background-color: #8a9a87;"></div>
+ <div class="preview-panel pattern-dot" style="background-color: #1c1a17;"></div>
+ <div class="preview-panel pattern-lattice" style="background-color: #7d6a45;"></div>
+ </div>
+ <div class="export-section">
+ <button class="export-btn" id="exportBtn">
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5">
+ <path d="M8 12V4M4 8l4-4 4 4"/>
+ </svg>
+ Export 1080×1080 Card
+ </button>
+ </div>
+ </section>
+
+ <canvas id="exportCanvas" width="1080" height="1080"></canvas>
+ <div class="toast" id="toast">Palette exported</div>
+
+ <script>
+ /* DESIGNER NAMES POOL */
+ const designerNames = [
+ 'Alabaster', 'Greige', 'Celadon', 'Ink', 'Brass',
+ 'Ochre', 'Sienna', 'Umber', 'Terracotta', 'Sage',
+ 'Madder', 'Woad', 'Oxblood', 'Champagne', 'Graphite',
+ 'Linen', 'Denim', 'Aubergine', 'Moss', 'Pewter'
+ ];
+
+ /* STATE */
+ let currentHue = 45; // Start with warm gold
+ let harmonyMode = 'analogous';
+ let currentPalette = [];
+
+ /* ELEMENTS */
+ const wheel = document.getElementById('colorWheel');
+ const wheelCtx = wheel.getContext('2d');
+ const currentHueEl = document.getElementById('currentHue');
+ const paletteGrid = document.getElementById('paletteGrid');
+ const previewStrip = document.getElementById('previewStrip');
+ const harmonyBtns = document.querySelectorAll('.harmony-btn');
+ const exportBtn = document.getElementById('exportBtn');
+ const exportCanvas = document.getElementById('exportCanvas');
+ const toast = document.getElementById('toast');
+
+ /* COLOR UTILITIES */
+ function hslToHex(h, s, l) {
+ l /= 100;
+ const a = s * Math.min(l, 1 - l) / 100;
+ const f = n => {
+ const k = (n + h / 30) % 12;
+ const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
+ return Math.round(255 * color).toString(16).padStart(2, '0');
+ };
+ return `#${f(0)}${f(8)}${f(4)}`.toUpperCase();
+ }
+
+ function hexToHsl(hex) {
+ const r = parseInt(hex.slice(1, 3), 16) / 255;
+ const g = parseInt(hex.slice(3, 5), 16) / 255;
+ const b = parseInt(hex.slice(5, 7), 16) / 255;
+
+ const max = Math.max(r, g, b);
+ const min = Math.min(r, g, b);
+ let h, s, l = (max + min) / 2;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ const d = max - min;
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+ switch (max) {
+ case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
+ case g: h = ((b - r) / d + 2) / 6; break;
+ case b: h = ((r - g) / d + 4) / 6; break;
+ }
+ }
+
+ return {
+ h: Math.round(h * 360),
+ s: Math.round(s * 100),
+ l: Math.round(l * 100)
+ };
+ }
+
+ function generatePalette(hue, mode) {
+ const palette = [];
+
+ if (mode === 'analogous') {
+ // 5 colors: -30, -15, base, +15, +30 degrees
+ const offsets = [-30, -15, 0, 15, 30];
+ offsets.forEach((offset, i) => {
+ const h = (hue + offset + 360) % 360;
+ const s = i === 2 ? 45 : 35 + Math.random() * 20;
+ const l = i === 2 ? 50 : 40 + (i % 2) * 15;
+ palette.push({
+ hex: hslToHex(h, s, l),
+ hue: h,
+ sat: s,
+ light: l
+ });
+ });
+ } else if (mode === 'complementary') {
+ // Base, base + small variations, complement, complement variations
+ palette.push({ hex: hslToHex(hue, 40, 55), hue, sat: 40, light: 55 });
+ palette.push({ hex: hslToHex(hue, 30, 75), hue, sat: 30, light: 75 });
+ palette.push({ hex: hslToHex(hue, 35, 40), hue, sat: 35, light: 40 });
+ const comp = (hue + 180) % 360;
+ palette.push({ hex: hslToHex(comp, 45, 50), hue: comp, sat: 45, light: 50 });
+ palette.push({ hex: hslToHex(comp, 35, 30), hue: comp, sat: 35, light: 30 });
+ } else if (mode === 'triadic') {
+ // Base, triadic variations with different lightness
+ palette.push({ hex: hslToHex(hue, 42, 58), hue, sat: 42, light: 58 });
+ palette.push({ hex: hslToHex(hue, 35, 80), hue, sat: 35, light: 80 });
+ const tri1 = (hue + 120) % 360;
+ const tri2 = (hue + 240) % 360;
+ palette.push({ hex: hslToHex(tri1, 40, 45), hue: tri1, sat: 40, light: 45 });
+ palette.push({ hex: hslToHex(tri2, 38, 65), hue: tri2, sat: 38, light: 65 });
+ palette.push({ hex: hslToHex(hue, 25, 25), hue, sat: 25, light: 25 });
+ }
+
+ return palette;
+ }
+
+ function getDesignerName(index, hex) {
+ // Deterministic name selection based on hue and index
+ const hue = hexToHsl(hex).h;
+ const nameIndex = (Math.floor(hue / 18) + index) % designerNames.length;
+ return designerNames[nameIndex];
+ }
+
+ /* DRAW COLOR WHEEL */
+ function drawColorWheel() {
+ const centerX = wheel.width / 2;
+ const centerY = wheel.height / 2;
+ const radius = Math.min(centerX, centerY) - 10;
+
+ wheelCtx.clearRect(0, 0, wheel.width, wheel.height);
+
+ // Draw hue wheel
+ for (let angle = 0; angle < 360; angle++) {
+ const startAngle = (angle - 2) * Math.PI / 180;
+ const endAngle = (angle + 2) * Math.PI / 180;
+
+ const gradient = wheelCtx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);
+ gradient.addColorStop(0, `hsl(${angle}, 0%, 100%)`);
+ gradient.addColorStop(0.5, `hsl(${angle}, 100%, 50%)`);
+ gradient.addColorStop(1, `hsl(${angle}, 100%, 25%)`);
+
+ wheelCtx.beginPath();
+ wheelCtx.moveTo(centerX, centerY);
+ wheelCtx.arc(centerX, centerY, radius, startAngle, endAngle);
+ wheelCtx.closePath();
+ wheelCtx.fillStyle = gradient;
+ wheelCtx.fill();
+ }
+
+ // Draw selector indicator
+ const selectorAngle = currentHue * Math.PI / 180;
+ const selectorX = centerX + Math.cos(selectorAngle) * (radius * 0.85);
+ const selectorY = centerY + Math.sin(selectorAngle) * (radius * 0.85);
+
+ wheelCtx.beginPath();
+ wheelCtx.arc(selectorX, selectorY, 8, 0, Math.PI * 2);
+ wheelCtx.fillStyle = '#f5f2ea';
+ wheelCtx.strokeStyle = '#c9a961';
+ wheelCtx.lineWidth = 2;
+ wheelCtx.fill();
+ wheelCtx.stroke();
+ }
+
+ /* UPDATE UI */
+ function updatePalette() {
+ currentPalette = generatePalette(currentHue, harmonyMode);
+
+ const cards = paletteGrid.querySelectorAll('.swatch-card');
+ const panels = previewStrip.querySelectorAll('.preview-panel');
+
+ currentPalette.forEach((color, i) => {
+ const card = cards[i];
+ const panel = panels[i];
+ const name = getDesignerName(i, color.hex);
+
+ // Update card
+ card.querySelector('.swatch-color').style.backgroundColor = color.hex;
+ card.querySelector('.swatch-hex').textContent = color.hex;
+ card.querySelector('.swatch-name').textContent = name;
+
+ // Update preview
+ panel.style.backgroundColor = color.hex;
+ });
+
+ currentHueEl.style.backgroundColor = hslToHex(currentHue, 70, 50);
+ }
+
+ function copyHex(hex) {
+ navigator.clipboard.writeText(hex).then(() => {
+ showToast(`Copied ${hex}`);
+ });
+ }
+
+ function showToast(message) {
+ toast.textContent = message;
+ toast.classList.add('show');
+ setTimeout(() => {
+ toast.classList.remove('show');
+ }, 2000);
+ }
+
+ /* EXPORT FUNCTION */
+ function exportCard() {
+ const ctx = exportCanvas.getContext('2d');
+ const w = 1080;
+ const h = 1080;
+
+ // Background
+ ctx.fillStyle = '#0d0d0f';
+ ctx.fillRect(0, 0, w, h);
+
+ // Title
+ ctx.font = '48px "Playfair Display", Georgia, serif';
+ ctx.fillStyle = '#f5f2ea';
+ ctx.textAlign = 'center';
+ ctx.letterSpacing = '0.15em';
+ ctx.fillText('DESIGNER WALLCOVERINGS', w/2, 100);
+
+ // Subtitle
+ ctx.font = '300 18px -apple-system, sans-serif';
+ ctx.fillStyle = '#8a8578';
+ ctx.letterSpacing = '0.3em';
+ ctx.fillText('CURATED PALETTE', w/2, 150);
+
+ // Swatches
+ const swatchWidth = 160;
+ const swatchHeight = 700;
+ const gap = 24;
+ const startX = (w - (5 * swatchWidth + 4 * gap)) / 2;
+ const startY = 220;
+
+ currentPalette.forEach((color, i) => {
+ const x = startX + i * (swatchWidth + gap);
+ const y = startY;
+
+ // Swatch background
+ ctx.fillStyle = color.hex;
+ ctx.fillRect(x, y, swatchWidth, swatchHeight);
+
+ // Pattern overlay (subtle)
+ ctx.fillStyle = 'rgba(255,255,255,0.03)';
+ if (i % 2 === 0) {
+ // Diagonal lines
+ ctx.beginPath();
+ for (let j = 0; j < swatchHeight; j += 20) {
+ ctx.moveTo(x, y + j);
+ ctx.lineTo(x + swatchWidth, y + j + 20);
+ }
+ ctx.stroke();
+ }
+
+ // Label background
+ ctx.fillStyle = '#17171c';
+ ctx.fillRect(x, y + swatchHeight - 80, swatchWidth, 80);
+
+ // Name
+ ctx.font = '24px "Playfair Display", Georgia, serif';
+ ctx.fillStyle = '#f5f2ea';
+ ctx.textAlign = 'center';
+ const name = getDesignerName(i, color.hex);
+ ctx.fillText(name.toUpperCase(), x + swatchWidth/2, y + swatchHeight - 45);
+
+ // Hex
+ ctx.font = '16px "SF Mono", monospace';
+ ctx.fillStyle = '#8a8578';
+ ctx.fillText(color.hex, x + swatchWidth/2, y + swatchHeight - 20);
+ });
+
+ // Border
+ ctx.strokeStyle = '#c9a961';
+ ctx.lineWidth = 1;
+ ctx.strokeRect(40, 40, w - 80, h - 80);
+
+ // Download
+ const link = document.createElement('a');
+ link.download = `designer-wallcoverings-${Date.now()}.png`;
+ link.href = exportCanvas.toDataURL();
+ link.click();
+
+ showToast('Card exported to downloads');
+ }
+
+ /* EVENTS */
+ wheel.addEventListener('click', (e) => {
+ const rect = wheel.getBoundingClientRect();
+ const x = e.clientX - rect.left - wheel.width/2;
+ const y = e.clientY - rect.top - wheel.height/2;
+
+ currentHue = (Math.atan2(y, x) * 180 / Math.PI + 360) % 360;
+ drawColorWheel();
+ updatePalette();
+ });
+
+ wheel.addEventListener('mousemove', (e) => {
+ if (e.buttons === 1) {
+ const rect = wheel.getBoundingClientRect();
+ const x = e.clientX - rect.left - wheel.width/2;
+ const y = e.clientY - rect.top - wheel.height/2;
+
+ currentHue = (Math.atan2(y, x) * 180 / Math.PI + 360) % 360;
+ drawColorWheel();
+ updatePalette();
+ }
+ });
+
+ harmonyBtns.forEach(btn => {
+ btn.addEventListener('click', () => {
+ harmonyBtns.forEach(b => b.classList.remove('active'));
+ btn.classList.add('active');
+ harmonyMode = btn.dataset.mode;
+ updatePalette();
+ });
+ });
+
+ paletteGrid.querySelectorAll('.swatch-card').forEach((card, i) => {
+ card.addEventListener('click', () => {
+ copyHex(currentPalette[i].hex);
+ card.classList.add('copied');
+ setTimeout(() => card.classList.remove('copied'), 1000);
+ });
+ });
+
+ exportBtn.addEventListener('click', exportCard);
+
+ /* INIT */
+ drawColorWheel();
+ updatePalette();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/kimi.png b/data/artifacts/420dc7bd02b3/kimi.png
new file mode 100644
index 0000000..90d8b5e
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/kimi.png differ
diff --git a/data/artifacts/420dc7bd02b3/qwen25-7b.html b/data/artifacts/420dc7bd02b3/qwen25-7b.html
new file mode 100644
index 0000000..1176032
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/qwen25-7b.html
@@ -0,0 +1,120 @@
+<!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: #0d0d0f;
+ --surface: #17171c;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --line: 1px solid var(--surface);
+ --shadow: 0 8px 24px rgba(0,0,0,.12), hover 0 16px 48px rgba(0,0,0,.18), glow = 0 0 24px var(--accent)@35%;
+ --ease: cubic-bezier(.22,1,.36,1);
+ }
+ body {
+ background-color: var(--bg);
+ color: var(--text);
+ font-family: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+ }
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ background-color: var(--surface);
+ color: var(--text);
+ padding: 24px 32px;
+ text-align: left;
+ font-size: 50px;
+ line-height: 67px;
+ letter-spacing: .18em;
+ }
+ h1 {
+ margin-top: 96px;
+ font-size: 50px;
+ line-height: 67px;
+ text-align: center;
+ }
+ .swatch {
+ display: inline-block;
+ width: 260px;
+ height: 260px;
+ background-color: var(--accent);
+ margin: 16px;
+ border-radius: 14px;
+ overflow: hidden;
+ cursor: pointer;
+ box-shadow: var(--shadow);
+ }
+ .room-preview {
+ width: 50%;
+ height: 300px;
+ background-color: var(--surface);
+ margin-top: 24px;
+ border-radius: 14px;
+ overflow: hidden;
+ }
+ .export-btn {
+ display: inline-block;
+ padding: 16px 32px;
+ background-color: var(--accent);
+ color: var(--text);
+ text-decoration: none;
+ font-size: 18px;
+ line-height: 24px;
+ margin-top: 96px;
+ border-radius: 14px;
+ transition: all .3s ease-in-out;
+ }
+ .export-btn:hover {
+ transform: translateY(-2px);
+ }
+ </style>
+</head>
+<body>
+<header>
+ DESIGNER WALLCOVERINGS
+</header>
+<h1>Color Palette Builder</h1>
+
+<div class="swatch" id="swatch1"></div>
+<div class="swatch" id="swatch2"></div>
+<div class="swatch" id="swatch3"></div>
+<div class="swatch" id="swatch4"></div>
+<div class="swatch" id="swatch5"></div>
+
+<div class="room-preview" id="roomPreview"></div>
+
+<a href="#" class="export-btn">Export as 1080x1080 Card</a>
+
+<script>
+ const swatches = document.querySelectorAll('.swatch');
+ const roomPreview = document.getElementById('roomPreview');
+ const exportBtn = document.querySelector('.export-btn');
+
+ function updatePreview() {
+ roomPreview.style.backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--accent');
+ }
+
+ swatches.forEach(swatch => {
+ swatch.addEventListener('click', () => {
+ updatePreview();
+ });
+ });
+
+ exportBtn.addEventListener('click', () => {
+ alert('Card exported successfully!');
+ });
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/qwen25-7b.png b/data/artifacts/420dc7bd02b3/qwen25-7b.png
new file mode 100644
index 0000000..777503e
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/qwen25-7b.png differ
diff --git a/data/artifacts/420dc7bd02b3/qwen3-14b.html b/data/artifacts/420dc7bd02b3/qwen3-14b.html
new file mode 100644
index 0000000..e165e40
--- /dev/null
+++ b/data/artifacts/420dc7bd02b3/qwen3-14b.html
@@ -0,0 +1,319 @@
+<!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: #0d0d0f;
+ --surface: #17171c;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --line: #2a2a2e;
+ --shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+ --ease: cubic-bezier(.22, 1, .36, 1);
+ --glow: 0 0 24px var(--accent, #c9a961)35%;
+ }
+
+ * {
+ 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);
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ }
+
+ header {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 40px;
+ letter-spacing: 0.18em;
+ color: var(--text);
+ padding: 16px 32px;
+ background-color: var(--surface);
+ display: flex;
+ align-items: center;
+ text-transform: uppercase;
+ }
+
+ main {
+ flex: 1;
+ padding: 96px 32px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 32px;
+ }
+
+ .palette-section {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 24px;
+ }
+
+ .palette-header {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 28px;
+ letter-spacing: 0.1em;
+ color: var(--text);
+ text-transform: uppercase;
+ }
+
+ .swatch-container {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+ max-width: 100%;
+ }
+
+ .swatch {
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: 14px;
+ padding: 16px;
+ position: relative;
+ overflow: hidden;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: var(--shadow);
+ transition: box-shadow 150ms var(--ease);
+ }
+
+ .swatch:hover {
+ box-shadow: 0 16px 48px rgba(0, 0, 0, 0.18);
+ }
+
+ .swatch::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: linear-gradient(135deg, transparent 25%, var(--accent) 25%, var(--accent) 75%, transparent 75%);
+ opacity: 0.1;
+ pointer-events: none;
+ z-index: 0;
+ }
+
+ .swatch-text {
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 12px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--muted);
+ position: absolute;
+ bottom: 8px;
+ left: 8px;
+ z-index: 1;
+ }
+
+ .hex {
+ position: absolute;
+ top: 8px;
+ right: 8px;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 12px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--text);
+ background: rgba(0, 0, 0, 0.1);
+ padding: 4px 8px;
+ border-radius: 4px;
+ z-index: 1;
+ }
+
+ .room-preview {
+ width: 100%;
+ max-width: 800px;
+ height: 300px;
+ background: linear-gradient(135deg, var(--accent) 25%, var(--muted) 75%);
+ border: 1px solid var(--line);
+ border-radius: 14px;
+ box-shadow: var(--shadow);
+ position: relative;
+ overflow: hidden;
+ }
+
+ .room-preview::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, var(--surface) 25%, var(--bg) 75%);
+ opacity: 0.2;
+ pointer-events: none;
+ }
+
+ .palette-toggle {
+ display: flex;
+ gap: 16px;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 12px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--muted);
+ }
+
+ .palette-toggle button {
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 4px 8px;
+ transition: color 150ms var(--ease);
+ }
+
+ .palette-toggle button.active {
+ color: var(--accent);
+ }
+
+ .export-button {
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 12px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--accent);
+ background: none;
+ border: 1px solid var(--accent);
+ padding: 8px 16px;
+ border-radius: 8px;
+ cursor: pointer;
+ transition: background 150ms var(--ease), color 150ms var(--ease);
+ }
+
+ .export-button:hover {
+ background: var(--accent);
+ color: var(--text);
+ }
+
+ @keyframes fadeUp {
+ from { opacity: 0; transform: translateY(28px); }
+ to { opacity: 1; transform: none; }
+ }
+
+ .fade-up {
+ animation: fadeUp 0.7s var(--ease) both;
+ }
+ </style>
+</head>
+<body>
+ <header>
+ DESIGNER WALLCOVERINGS
+ </header>
+ <main>
+ <div class="palette-section">
+ <div class="palette-header">Select a Base Hue</div>
+ <div class="swatch-container">
+ <div class="swatch" style="background-color:#c9a961" data-hex="#c9a961">
+ <div class="swatch-text">alabaster</div>
+ <div class="hex">#c9a961</div>
+ </div>
+ <div class="swatch" style="background-color:#8a8578" data-hex="#8a8578">
+ <div class="swatch-text">greige</div>
+ <div class="hex">#8a8578</div>
+ </div>
+ <div class="swatch" style="background-color:#2f4c39" data-hex="#2f4c39">
+ <div class="swatch-text">celadon</div>
+ <div class="hex">#2f4c39</div>
+ </div>
+ <div class="swatch" style="background-color:#1c1a17" data-hex="#1c1a17">
+ <div class="swatch-text">ink</div>
+ <div class="hex">#1c1a17</div>
+ </div>
+ <div class="swatch" style="background-color:#b0472e" data-hex="#b0472e">
+ <div class="swatch-text">brass</div>
+ <div class="hex">#b0472e</div>
+ </div>
+ </div>
+ </div>
+ <div class="palette-section">
+ <div class="palette-header">Palette Style</div>
+ <div class="palette-toggle">
+ <button class="active" data-style="analogous">Analogous</button>
+ <button data-style="complementary">Complementary</button>
+ <button data-style="triadic">Triadic</button>
+ </div>
+ <div class="swatch-container">
+ <div class="swatch" style="background-color:#e8d9b1" data-hex="#e8d9b1">
+ <div class="swatch-text">alabaster</div>
+ <div class="hex">#e8d9b1</div>
+ </div>
+ <div class="swatch" style="background-color:#d0b585" data-hex="#d0b585">
+ <div class="swatch-text">greige</div>
+ <div class="hex">#d0b585</div>
+ </div>
+ <div class="swatch" style="background-color:#c1a98d" data-hex="#c1a98d">
+ <div class="swatch-text">celadon</div>
+ <div class="hex">#c1a98d</div>
+ </div>
+ <div class="swatch" style="background-color:#a8977f" data-hex="#a8977f">
+ <div class="swatch-text">ink</div>
+ <div class="hex">#a8977f</div>
+ </div>
+ <div class="swatch" style="background-color:#928068" data-hex="#928068">
+ <div class="swatch-text">brass</div>
+ <div class="hex">#928068</div>
+ </div>
+ </div>
+ </div>
+ <div class="palette-section">
+ <div class="room-preview"></div>
+ <button class="export-button">Export as 1080x1080 Card</button>
+ </div>
+ </main>
+ <script>
+ const swatches = document.querySelectorAll('.swatch');
+ const exportButton = document.querySelector('.export-button');
+ const roomPreview = document.querySelector('.room-preview');
+ const paletteToggleButtons = document.querySelectorAll('.palette-toggle button');
+ let selectedBase = null;
+ let selectedStyle = 'analogous';
+
+ swatches.forEach(swatch => {
+ swatch.addEventListener('click', () => {
+ if (!selectedBase) {
+ selectedBase = swatch;
+ swatch.classList.add('active');
+ }
+ });
+ });
+
+ paletteToggleButtons.forEach(button => {
+ button.addEventListener('click', () => {
+ paletteToggleButtons.forEach(b => b.classList.remove('active'));
+ button.classList.add('active');
+ selectedStyle = button.getAttribute('data-style');
+ });
+ });
+
+ exportButton.addEventListener('click', () => {
+ const canvas = document.createElement('canvas');
+ canvas.width = 1080;
+ canvas.height = 1080;
+ const ctx = canvas.getContext('2d');
+ const gradient = ctx.createLinearGradient(0, 0, 1080, 1080);
+ gradient.addColorStop(0, 'var(--accent)');
+ gradient.addColorStop(1, 'var(--muted)');
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, 0, 1080, 1080);
+ const link = document.createElement('a');
+ link.download = 'palette-card.png';
+ link.href = canvas.toDataURL();
+ link.click();
+ });
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/420dc7bd02b3/qwen3-14b.png b/data/artifacts/420dc7bd02b3/qwen3-14b.png
new file mode 100644
index 0000000..173a536
Binary files /dev/null and b/data/artifacts/420dc7bd02b3/qwen3-14b.png differ
diff --git a/data/artifacts/6f651f004b4c/claude-code.html b/data/artifacts/6f651f004b4c/claude-code.html
new file mode 100644
index 0000000..6fc33ff
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/claude-code.html
@@ -0,0 +1,584 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Which Design Era? — Designer Wallcoverings</title>
+<style>
+ :root{
+ --bg:#0d0d0f;
+ --surface:#17171c;
+ --surface-2:#1f1f26;
+ --text:#f5f2ea;
+ --muted:#8a8578;
+ --accent:#c9a961;
+ --accent-deep:#7d6a45;
+ --line:rgba(201,169,97,.24);
+ --hairline:rgba(245,242,234,.09);
+ --shadow:0 8px 24px rgba(0,0,0,.45);
+ --shadow-hi:0 16px 48px rgba(0,0,0,.55);
+ --glow:0 0 28px rgba(201,169,97,.30);
+ --ease:cubic-bezier(.22,1,.36,1);
+ --ink:#1c1a17;
+ --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;margin:0;padding:0}
+ html,body{height:100%}
+ body{
+ background:var(--bg);
+ color:var(--text);
+ font-family:var(--sans);
+ font-size:16px;
+ line-height:1.55;
+ -webkit-font-smoothing:antialiased;
+ min-height:100%;
+ overflow-x:hidden;
+ }
+ body::before{
+ content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
+ background:
+ radial-gradient(1200px 600px at 15% -10%,rgba(201,169,97,.10),transparent 60%),
+ radial-gradient(900px 500px at 100% 110%,rgba(125,106,69,.12),transparent 60%);
+ animation:drift 20s ease-in-out infinite alternate;
+ }
+ @keyframes drift{from{transform:transl3d(0,0,0) scale(1)}to{transform:translate3d(-2%,1%,0) scale(1.05)}}
+
+ /* ---------- Top Bar ---------- */
+ header.topbar{
+ position:fixed;top:0;left:0;right:0;z-index:20;
+ display:flex;align-items:center;justify-content:space-between;
+ gap:24px;padding:18px 32px;
+ background:linear-gradient(180deg,rgba(13,13,15,.96),rgba(13,13,15,.80));
+ backdrop-filter:blur(10px);
+ border-bottom:1px solid var(--hairline);
+ }
+ .wordmark{
+ font-family:var(--serif);
+ color:var(--text); /* darkest-on-dark ground: ivory text is the ink here */
+ text-transform:uppercase;
+ letter-spacing:.18em;
+ font-weight:500;
+ font-size:clamp(19px,2.4vw,26px);
+ line-height:1.05;
+ white-space:nowrap;
+ }
+ .wordmark .amp{color:var(--accent);display:block;font-size:.5em;letter-spacing:.34em;margin-top:3px}
+ .topbar .scoreboard{
+ display:flex;gap:22px;align-items:center;
+ font-family:var(--sans);text-transform:uppercase;letter-spacing:.15em;
+ font-size:12px;color:var(--muted);white-space:nowrap;
+ }
+ .scoreboard b{color:var(--accent);font-size:14px;letter-spacing:.1em;margin-left:6px}
+ .scoreboard .divider{width:1px;height:26px;background:var(--hairline)}
+
+ /* ---------- Layout ---------- */
+ main{
+ position:relative;z-index:1;
+ max-width:960px;margin:0 auto;
+ padding:132px 24px 80px;
+ display:flex;flex-direction:column;align-items:center;gap:34px;
+ }
+ .eyebrow{
+ font-size:12px;text-transform:uppercase;letter-spacing:.28em;color:var(--muted);
+ display:flex;align-items:center;gap:14px;
+ }
+ .eyebrow::before,.eyebrow::after{content:"";width:34px;height:1px;background:var(--line)}
+ h1.title{
+ font-family:var(--serif);font-weight:500;
+ font-size:clamp(34px,6vw,58px);line-height:1.02;text-align:center;letter-spacing:.01em;
+ }
+ h1.title em{font-style:italic;color:var(--accent)}
+ .sub{color:var(--muted);text-align:center;max-width:520px;font-size:16px;margin-top:-14px}
+
+ /* ---------- Vignette Stage ---------- */
+ .stage-wrap{
+ width:100%;max-width:620px;
+ animation:fadeUp .7s var(--ease) both;
+ }
+ .vignette{
+ position:relative;width:100%;aspect-ratio:4/3;border-radius:14px;overflow:hidden;
+ border:1px solid var(--line);box-shadow:var(--shadow),var(--glow);
+ background:#000;
+ }
+ .vignette svg{position:absolute;inset:0;width:100%;height:100%;display:block}
+ .frame-badge{
+ position:absolute;left:16px;bottom:14px;z-index:3;
+ font-family:var(--sans);font-size:11px;letter-spacing:.24em;text-transform:uppercase;
+ color:var(--text);background:rgba(13,13,15,.55);backdrop-filter:blur(4px);
+ padding:7px 13px;border:1px solid var(--hairline);border-radius:40px;
+ }
+
+ /* ---------- Choices ---------- */
+ .prompt{font-size:13px;letter-spacing:.22em;text-transform:uppercase;color:var(--muted)}
+ .choices{
+ width:100%;max-width:620px;
+ display:grid;grid-template-columns:repeat(2,1fr);gap:14px;
+ }
+ .choice{
+ font-family:var(--sans);cursor:pointer;
+ text-transform:uppercase;letter-spacing:.14em;font-size:13px;font-weight:600;color:var(--text);
+ background:var(--surface);border:1px solid var(--hairline);border-radius:12px;
+ padding:20px 16px;text-align:center;
+ transition:transform .2s var(--ease),border-color .2s var(--ease),background .2s var(--ease),box-shadow .2s var(--ease);
+ }
+ .choice small{display:block;margin-top:6px;font-size:10px;letter-spacing:.14em;color:var(--muted);font-weight:500}
+ .choice:hover:not(:disabled){transform:translateY(-3px);border-color:var(--line);box-shadow:var(--shadow-hi)}
+ .choice:disabled{cursor:default}
+ .choice.correct{border-color:var(--accent);background:linear-gradient(180deg,var(--surface-2),var(--surface));box-shadow:var(--glow)}
+ .choice.correct small{color:var(--accent)}
+ .choice.wrong{border-color:#7a3b34;opacity:.65}
+
+ /* ---------- Overlay ---------- */
+ .overlay{
+ position:fixed;inset:0;z-index:40;display:none;align-items:center;justify-content:center;padding:24px;
+ background:rgba(8,8,10,.72);backdrop-filter:blur(8px);
+ }
+ .overlay.show{display:flex;animation:fadeIn .3s ease both}
+ .card{
+ position:relative;width:100%;max-width:520px;
+ background:var(--surface);border:1px solid var(--line);border-radius:14px;
+ box-shadow:var(--shadow-hi);padding:44px 38px 38px;text-align:center;
+ animation:fadeUp .5s var(--ease) both;
+ }
+ .card .verdict{font-size:12px;letter-spacing:.28em;text-transform:uppercase;margin-bottom:14px}
+ .card .verdict.hit{color:var(--accent)}
+ .card .verdict.miss{color:#c07a6f}
+ .card h2{font-family:var(--serif);font-weight:500;font-size:34px;line-height:1.1;margin-bottom:6px}
+ .card h2 em{font-style:italic;color:var(--accent)}
+ .card .era-line{font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin-bottom:22px}
+ .fact{
+ background:var(--surface-2);border:1px solid var(--hairline);border-left:2px solid var(--accent);
+ border-radius:10px;padding:18px 20px;text-align:left;color:var(--text);font-size:15px;line-height:1.6;
+ }
+ .fact .lbl{display:block;font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--accent);margin-bottom:8px}
+ .card .btn-row{margin-top:26px;display:flex;gap:12px;justify-content:center}
+ .btn{
+ font-family:var(--sans);cursor:pointer;text-transform:uppercase;letter-spacing:.16em;font-size:12px;font-weight:600;
+ padding:14px 30px;border-radius:40px;transition:transform .2s var(--ease),box-shadow .2s var(--ease),background .2s var(--ease);
+ }
+ .btn-primary{background:var(--accent);color:var(--ink);border:1px solid var(--accent)}
+ .btn-primary:hover{transform:translateY(-2px);box-shadow:var(--glow)}
+ .btn-ghost{background:transparent;color:var(--text);border:1px solid var(--line)}
+ .btn-ghost:hover{transform:translateY(-2px);border-color:var(--accent)}
+
+ /* Final card */
+ .final .score-big{font-family:var(--serif);font-size:64px;line-height:1;color:var(--accent);margin:6px 0}
+ .final .score-of{color:var(--muted);font-size:14px;letter-spacing:.14em}
+ .final .rank{font-size:13px;letter-spacing:.2em;text-transform:uppercase;color:var(--text);margin-top:16px}
+ .final .best-note{font-size:12px;letter-spacing:.14em;color:var(--muted);margin-top:8px}
+
+ .progress-dots{display:flex;gap:9px;margin-top:2px}
+ .dot{width:8px;height:8px;border-radius:50%;background:var(--hairline);transition:background .3s var(--ease)}
+ .dot.done{background:var(--accent-deep)}
+ .dot.active{background:var(--accent);box-shadow:var(--glow)}
+
+ @keyframes fadeUp{from{opacity:0;transform:translateY(28px)}to{opacity:1;transform:none}}
+ @keyframes fadeIn{from{opacity:0}to{opacity:1}}
+ .swap{animation:fadeUp .55s var(--ease) both}
+
+ @media(max-width:560px){
+ header.topbar{padding:14px 18px}
+ .topbar .scoreboard{gap:14px}
+ main{padding:120px 16px 60px}
+ .card{padding:36px 24px 30px}
+ }
+</style>
+</head>
+<body>
+
+ <header class="topbar">
+ <div class="wordmark">Designer Wallcoverings<span class="amp">Est. Atelier</span></div>
+ <div class="scoreboard">
+ <span>Round<b id="sbRound">1</b></span>
+ <span class="divider"></span>
+ <span>Score<b id="sbScore">0</b></span>
+ <span class="divider"></span>
+ <span>Best<b id="sbBest">0</b></span>
+ </div>
+ </header>
+
+ <main>
+ <div class="eyebrow">The Interiors Parlour Game</div>
+ <h1 class="title">Which <em>Design Era</em>?</h1>
+ <p class="sub">A vignette appears. Read its palette, its ornament, its restraint — then name the era it belongs to.</p>
+
+ <div class="progress-dots" id="dots"></div>
+
+ <div class="stage-wrap">
+ <div class="vignette" id="vignette"></div>
+ </div>
+
+ <div class="prompt">Name the era</div>
+ <div class="choices" id="choices"></div>
+ </main>
+
+ <!-- Round reveal overlay -->
+ <div class="overlay" id="reveal">
+ <div class="card" role="dialog" aria-modal="true">
+ <div class="verdict" id="verdict">Correct</div>
+ <h2 id="revealName">Era</h2>
+ <div class="era-line" id="revealYears">years</div>
+ <div class="fact">
+ <span class="lbl">From the Archive</span>
+ <span id="revealFact">fact</span>
+ </div>
+ <div class="btn-row">
+ <button class="btn btn-primary" id="nextBtn">Next Room</button>
+ </div>
+ </div>
+ </div>
+
+ <!-- Final overlay -->
+ <div class="overlay" id="final">
+ <div class="card final" role="dialog" aria-modal="true">
+ <div class="verdict hit">The Portfolio Is Complete</div>
+ <div class="score-big" id="finalScore">0</div>
+ <div class="score-of">out of 8 rooms named</div>
+ <div class="rank" id="finalRank">—</div>
+ <div class="best-note" id="finalBest">—</div>
+ <div class="btn-row">
+ <button class="btn btn-primary" id="restartBtn">Play Again</button>
+ </div>
+ </div>
+ </div>
+
+<script>
+(function(){
+ "use strict";
+
+ // ---------- Era definitions with distinct CSS/SVG vignettes ----------
+ const ERAS = [
+ {
+ key:"victorian",
+ name:"Victorian",
+ years:"c. 1837 – 1901",
+ fact:"Victorians layered pattern on pattern — a damask wall, a floral border, and a bold dado — believing bare surfaces betrayed a want of taste. Deep jewel tones came from newly cheap aniline dyes.",
+ render: victorian
+ },
+ {
+ key:"artdeco",
+ name:"Art Deco",
+ years:"c. 1920 – 1939",
+ fact:"Art Deco worshipped the machine and the sunburst — sharp symmetry, stepped 'ziggurat' forms, lacquer black, and gold. Its geometry celebrated a jazz-age faith in speed, luxury and the future.",
+ render: artdeco
+ },
+ {
+ key:"midcentury",
+ name:"Mid-Century Modern",
+ years:"c. 1945 – 1969",
+ fact:"Post-war optimism gave us clean legs, organic curves and a warm palette of mustard, teal and walnut. Form followed function — but a boomerang or starburst was always welcome.",
+ render: midcentury
+ },
+ {
+ key:"grandmillennial",
+ name:"Grandmillennial",
+ years:"c. 2019 – today",
+ fact:"Nicknamed 'granny chic', Grandmillennial style revives chintz, scallops, skirted tables and blue-and-white porcelain — heirloom comfort worn with a wink, mixing the antique with the fresh.",
+ render: grandmillennial
+ }
+ ];
+
+ const ROUNDS = 8;
+ const BEST_KEY = "dw_design_era_best";
+
+ // ---------- SVG vignette renderers ----------
+ // Each returns an SVG string for a 4:3 stage. Visually distinct motifs.
+
+ function frame(inner, ground){
+ return `<svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
+ <rect width="400" height="300" fill="${ground}"/>
+ ${inner}
+ </svg>`;
+ }
+
+ function victorian(){
+ // Deep burgundy damask wall, ornate gilt frame, dark wainscot
+ let damask="";
+ for(let y=18;y<210;y+=44){
+ for(let x=22;x<400;x+=52){
+ const off=((y/44)%2)?26:0;
+ damask+=`<g transform="translate(${x+off},${y})" opacity="0.55">
+ <path d="M0,-11 C7,-6 7,6 0,11 C-7,6 -7,-6 0,-11 Z" fill="#8a2b3a"/>
+ <path d="M-11,0 C-6,-7 6,-7 11,0 C6,7 -6,7 -11,0 Z" fill="#a5324a"/>
+ <circle cx="0" cy="0" r="3" fill="#d9a441"/>
+ </g>`;
+ }
+ }
+ const inner=`
+ <rect width="400" height="300" fill="#3a1220"/>
+ <rect x="0" y="0" width="400" height="230" fill="#5a1a2c"/>
+ ${damask}
+ <!-- wainscot -->
+ <rect x="0" y="228" width="400" height="72" fill="#2a1712"/>
+ <rect x="0" y="226" width="400" height="6" fill="#d9a441" opacity="0.75"/>
+ <g stroke="#1c0f0b" stroke-width="2" opacity="0.6">
+ <line x1="66" y1="232" x2="66" y2="300"/>
+ <line x1="200" y1="232" x2="200" y2="300"/>
+ <line x1="334" y1="232" x2="334" y2="300"/>
+ </g>
+ <!-- gilt portrait frame -->
+ <rect x="150" y="46" width="100" height="128" rx="6" fill="#1c0f0b" stroke="#d9a441" stroke-width="7"/>
+ <rect x="150" y="46" width="100" height="128" rx="6" fill="none" stroke="#8a6a2a" stroke-width="2"/>
+ <ellipse cx="200" cy="96" rx="26" ry="30" fill="#6b3446"/>
+ <rect x="176" y="118" width="48" height="52" fill="#402030"/>
+ `;
+ return frame(inner,"#3a1220");
+ }
+
+ function artdeco(){
+ // Black & gold sunburst, stepped geometry, symmetry
+ let rays="";
+ const cx=200,cy=250;
+ for(let a=-90;a<=90;a+=15){
+ const r=(a/-90);
+ const rad=(a*Math.PI)/180;
+ const x=cx+Math.cos(rad+Math.PI*1.5)*260;
+ const y=cy+Math.sin(rad+Math.PI*1.5)*260;
+ rays+=`<line x1="${cx}" y1="${cy}" x2="${x}" y2="${y}" stroke="#c9a961" stroke-width="${a%30===0?3:1.4}" opacity="0.8"/>`;
+ }
+ const inner=`
+ <rect width="400" height="300" fill="#101014"/>
+ <g>${rays}</g>
+ <!-- stepped ziggurat frame -->
+ <g fill="none" stroke="#c9a961" stroke-width="2.4" opacity="0.9">
+ <rect x="120" y="40" width="160" height="180"/>
+ <rect x="108" y="52" width="184" height="156"/>
+ <rect x="96" y="64" width="208" height="132"/>
+ </g>
+ <!-- central fan -->
+ <path d="M200,210 L150,110 A56 56 0 0 1 250 110 Z" fill="#1b1b22" stroke="#c9a961" stroke-width="2"/>
+ ${[0,1,2,3,4].map(i=>`<line x1="200" y1="210" x2="${160+i*20}" y2="112" stroke="#c9a961" stroke-width="1.6" opacity="0.85"/>`).join("")}
+ <circle cx="200" cy="210" r="6" fill="#c9a961"/>
+ <!-- chevron floor -->
+ <g stroke="#7d6a45" stroke-width="4" opacity="0.55">
+ ${[0,1,2,3,4,5].map(i=>`<polyline points="${i*80-40},300 ${i*80},268 ${i*80+40},300" fill="none"/>`).join("")}
+ </g>
+ `;
+ return frame(inner,"#101014");
+ }
+
+ function midcentury(){
+ // Warm mustard/teal, boomerang, tapered-leg credenza, starburst
+ const inner=`
+ <rect width="400" height="300" fill="#c98a2e"/>
+ <rect x="0" y="0" width="400" height="196" fill="#d9a441"/>
+ <!-- atomic starburst -->
+ <g transform="translate(96,64)">
+ ${Array.from({length:12}).map((_,i)=>{
+ const a=(i*30)*Math.PI/180;
+ return `<line x1="0" y1="0" x2="${Math.cos(a)*30}" y2="${Math.sin(a)*30}" stroke="#2f4c39" stroke-width="2.4"/><circle cx="${Math.cos(a)*30}" cy="${Math.sin(a)*30}" r="3" fill="#2f4c39"/>`;
+ }).join("")}
+ <circle r="5" fill="#b0472e"/>
+ </g>
+ <!-- teal wall panel -->
+ <rect x="230" y="34" width="140" height="120" fill="#2f6b63"/>
+ <rect x="246" y="50" width="108" height="88" fill="none" stroke="#e8ddc4" stroke-width="2"/>
+ <circle cx="300" cy="94" r="26" fill="#b0472e"/>
+ <!-- walnut credenza -->
+ <rect x="60" y="196" width="280" height="66" rx="4" fill="#6b4426"/>
+ <rect x="60" y="196" width="280" height="10" fill="#8a5a34"/>
+ <rect x="150" y="212" width="2" height="36" fill="#3a2414"/>
+ <rect x="250" y="212" width="2" height="36" fill="#3a2414"/>
+ <!-- tapered legs -->
+ <g stroke="#2a1a0e" stroke-width="4">
+ <line x1="82" y1="262" x2="70" y2="292"/>
+ <line x1="318" y1="262" x2="330" y2="292"/>
+ <line x1="200" y1="262" x2="200" y2="292"/>
+ </g>
+ <ellipse cx="200" cy="220" rx="30" ry="8" fill="#2f4c39" opacity="0.5"/>
+ `;
+ return frame(inner,"#c98a2e");
+ }
+
+ function grandmillennial(){
+ // Blue & white chintz, scalloped valance, ginger jar, skirted table
+ let chintz="";
+ for(let y=16;y<300;y+=40){
+ for(let x=20;x<400;x+=48){
+ const off=((y/40)%2)?24:0;
+ chintz+=`<g transform="translate(${x+off},${y})" opacity="0.9">
+ <circle r="5" fill="#3a5f8f"/>
+ <path d="M0,-9 C4,-4 4,4 0,9 C-4,4 -4,-4 0,-9 Z" fill="#5f83b0" opacity="0.7"/>
+ <path d="M-9,0 C-4,-4 4,-4 9,0 C4,4 -4,4 -9,0 Z" fill="#5f83b0" opacity="0.7"/>
+ </g>`;
+ }
+ }
+ const inner=`
+ <rect width="400" height="300" fill="#eef2f6"/>
+ ${chintz}
+ <!-- scalloped valance -->
+ <g fill="#3a5f8f">
+ <rect x="0" y="0" width="400" height="14"/>
+ ${Array.from({length:11}).map((_,i)=>`<circle cx="${i*40+20}" cy="14" r="20"/>`).join("")}
+ </g>
+ <rect x="0" y="0" width="400" height="14" fill="#2c4a72"/>
+ <!-- skirted table -->
+ <rect x="128" y="196" width="144" height="90" fill="#ffffff"/>
+ <path d="M128,196 h144 v14 h-144 Z" fill="#dfe7f0"/>
+ <g stroke="#c3d0e0" stroke-width="2">
+ ${Array.from({length:9}).map((_,i)=>`<line x1="${140+i*16}" y1="210" x2="${140+i*16}" y2="286"/>`).join("")}
+ </g>
+ <ellipse cx="200" cy="196" rx="80" ry="10" fill="#3a5f8f" opacity="0.25"/>
+ <!-- blue & white ginger jar -->
+ <g transform="translate(200,150)">
+ <path d="M-26,44 C-34,10 -30,-14 0,-22 C30,-14 34,10 26,44 Z" fill="#ffffff" stroke="#3a5f8f" stroke-width="2"/>
+ <path d="M-14,-22 h28 l-4,-8 h-20 Z" fill="#ffffff" stroke="#3a5f8f" stroke-width="2"/>
+ <path d="M-24,20 C-10,8 10,8 24,20" fill="none" stroke="#3a5f8f" stroke-width="2"/>
+ <circle cx="-8" cy="4" r="4" fill="#3a5f8f"/>
+ <circle cx="9" cy="10" r="5" fill="#5f83b0"/>
+ <path d="M-16,28 q16,10 32,0" fill="none" stroke="#5f83b0" stroke-width="2"/>
+ </g>
+ `;
+ return frame(inner,"#eef2f6");
+ }
+
+ // ---------- Game state ----------
+ let sequence=[]; // era keys per round
+ let round=0;
+ let score=0;
+ let best=parseInt(localStorage.getItem(BEST_KEY)||"0",10)||0;
+ let locked=false;
+
+ const el={
+ vignette:document.getElementById("vignette"),
+ choices:document.getElementById("choices"),
+ dots:document.getElementById("dots"),
+ sbRound:document.getElementById("sbRound"),
+ sbScore:document.getElementById("sbScore"),
+ sbBest:document.getElementById("sbBest"),
+ reveal:document.getElementById("reveal"),
+ verdict:document.getElementById("verdict"),
+ revealName:document.getElementById("revealName"),
+ revealYears:document.getElementById("revealYears"),
+ revealFact:document.getElementById("revealFact"),
+ nextBtn:document.getElementById("nextBtn"),
+ final:document.getElementById("final"),
+ finalScore:document.getElementById("finalScore"),
+ finalRank:document.getElementById("finalRank"),
+ finalBest:document.getElementById("finalBest"),
+ restartBtn:document.getElementById("restartBtn")
+ };
+
+ 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 eraByKey(k){return ERAS.find(e=>e.key===k);}
+
+ function buildSequence(){
+ // Ensure variety: base on shuffled full set, cycled, then final shuffle
+ let pool=[];
+ while(pool.length<ROUNDS){pool=pool.concat(shuffle(ERAS.map(e=>e.key)));}
+ sequence=shuffle(pool).slice(0,ROUNDS);
+ }
+
+ function buildDots(){
+ el.dots.innerHTML="";
+ for(let i=0;i<ROUNDS;i++){
+ const d=document.createElement("div");
+ d.className="dot";
+ el.dots.appendChild(d);
+ }
+ }
+ function updateDots(){
+ [...el.dots.children].forEach((d,i)=>{
+ d.className="dot"+(i<round?" done":"")+(i===round?" active":"");
+ });
+ }
+
+ function updateScoreboard(){
+ el.sbRound.textContent=Math.min(round+1,ROUNDS);
+ el.sbScore.textContent=score;
+ el.sbBest.textContent=best;
+ }
+
+ function renderRound(){
+ locked=false;
+ const era=eraByKey(sequence[round]);
+ el.vignette.classList.remove("swap");
+ void el.vignette.offsetWidth;
+ el.vignette.innerHTML=era.render()+`<div class="frame-badge">Vignette № ${round+1}</div>`;
+ el.vignette.classList.add("swap");
+
+ // choices — always all four eras, shuffled order
+ el.choices.innerHTML="";
+ shuffle(ERAS.map(e=>e.key)).forEach(k=>{
+ const e=eraByKey(k);
+ const btn=document.createElement("button");
+ btn.className="choice";
+ btn.innerHTML=`${e.name}<small>${e.years}</small>`;
+ btn.dataset.key=k;
+ btn.addEventListener("click",()=>guess(k,btn));
+ el.choices.appendChild(btn);
+ });
+ updateDots();
+ updateScoreboard();
+ }
+
+ function guess(key,btn){
+ if(locked)return;
+ locked=true;
+ const era=eraByKey(sequence[round]);
+ const correct=key===era.key;
+ if(correct)score++;
+
+ [...el.choices.children].forEach(c=>{
+ c.disabled=true;
+ if(c.dataset.key===era.key)c.classList.add("correct");
+ else if(c===btn)c.classList.add("wrong");
+ });
+
+ updateScoreboard();
+
+ // reveal overlay
+ el.verdict.textContent=correct?"Correct — Well Curated":"Not Quite";
+ el.verdict.className="verdict "+(correct?"hit":"miss");
+ el.revealName.innerHTML=era.name.replace(/(Modern|Deco|Victorian|Grandmillennial)/,'<em>$1</em>');
+ el.revealYears.textContent=era.years;
+ el.revealFact.textContent=era.fact;
+ el.nextBtn.textContent=(round+1>=ROUNDS)?"See Results":"Next Room";
+ setTimeout(()=>el.reveal.classList.add("show"),620);
+ }
+
+ function nextRound(){
+ el.reveal.classList.remove("show");
+ round++;
+ if(round>=ROUNDS){endGame();return;}
+ setTimeout(renderRound,180);
+ }
+
+ function rankFor(s){
+ if(s===ROUNDS)return "Master Curator";
+ if(s>=6)return "Senior Designer";
+ if(s>=4)return "Design Apprentice";
+ if(s>=2)return "Keen Eye";
+ return "Fresh Enthusiast";
+ }
+
+ function endGame(){
+ updateDots();
+ let newBest=false;
+ if(score>best){best=score;localStorage.setItem(BEST_KEY,String(best));newBest=true;}
+ el.sbBest.textContent=best;
+ el.finalScore.textContent=score;
+ el.finalRank.textContent=rankFor(score);
+ el.finalBest.textContent=newBest?`✦ New personal best — ${best}/${ROUNDS}`:`Your best: ${best}/${ROUNDS}`;
+ el.final.classList.add("show");
+ }
+
+ function startGame(){
+ round=0;score=0;
+ el.final.classList.remove("show");
+ el.reveal.classList.remove("show");
+ buildSequence();
+ buildDots();
+ renderRound();
+ }
+
+ el.nextBtn.addEventListener("click",nextRound);
+ el.restartBtn.addEventListener("click",startGame);
+
+ el.sbBest.textContent=best;
+ startGame();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/claude-code.png b/data/artifacts/6f651f004b4c/claude-code.png
new file mode 100644
index 0000000..edf61aa
Binary files /dev/null and b/data/artifacts/6f651f004b4c/claude-code.png differ
diff --git a/data/artifacts/6f651f004b4c/gemma3-12b.html b/data/artifacts/6f651f004b4c/gemma3-12b.html
new file mode 100644
index 0000000..b6fd60d
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/gemma3-12b.html
@@ -0,0 +1,249 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Which Design Era?</title>
+ <style>
+ :root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e;
+ --line: #dddfe2;
+ --shadow: rgba(0, 0, 0, 0.12);
+ --ease: cubic-bezier(.22,1,.36,1);
+ }
+
+ body {
+ font-family: 'apple-system', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ background-color: var(--bg);
+ color: var(--text);
+ margin: 0;
+ padding: 0;
+ overflow-x: hidden; /* Prevent horizontal scroll */
+ }
+
+ header {
+ background-color: var(--surface);
+ padding: 24px;
+ text-align: left;
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 67px; /* Increased font size for visibility */
+ letter-spacing: .18em;
+ color: var(--text);
+ }
+
+ .container {
+ padding: 96px;
+ max-width: 1200px;
+ margin: 0 auto;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+ #vignette {
+ width: 500px;
+ height: 400px;
+ border-radius: 14px;
+ background-color: var(--surface);
+ box-shadow: 0 8px 24px var(--shadow);
+ margin-bottom: 48px;
+ position: relative; /* For absolute positioning of elements */
+ }
+
+ .era-buttons {
+ display: flex;
+ gap: 24px;
+ margin-bottom: 48px;
+ }
+
+ button {
+ background-color: var(--surface);
+ border: 1px solid var(--line);
+ padding: 12px 24px;
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ color: var(--muted);
+ border-radius: 8px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ }
+
+ button:hover {
+ background-color: #f7efe6; /* Slightly darker on hover */
+ }
+
+ #score, #round {
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ color: var(--muted);
+ margin-bottom: 32px;
+ }
+
+ .overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(255, 255, 255, 0.9);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ z-index: 1000;
+ padding: 48px;
+ }
+
+ .overlay h2 {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 38px;
+ text-align: center;
+ margin-bottom: 24px;
+ }
+
+ .overlay p {
+ font-size: 16px;
+ text-align: center;
+ margin-bottom: 32px;
+ }
+
+ #restart-button {
+ background-color: var(--accent);
+ color: var(--surface);
+ padding: 12px 24px;
+ font-size: 16px;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ border: none;
+ border-radius: 8px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ }
+
+ #restart-button:hover {
+ background-color: #a73d26; /* Darker accent on hover */
+ }
+
+
+ /* Era Specific Styles (Hidden by default) */
+ .victorian { background: linear-gradient(to bottom, #f8e7c4, #ede1be); }
+ .art-deco { background: radial-gradient(circle, #2a231d, #191610); color: #eee;}
+ .mid-century { background: linear-gradient(to bottom, #b8d7e4, #a7c4ca);}
+ .grandmillennial {background: url('data:image/svg+xml,<svg width="100%" height="100%" viewBox="0 0 200 200"><g fill="#f5f2ea" stroke="#dddfe2" stroke-width="2"/><rect x="0" y="0" width="200" height="200"/></svg>') repeat; }
+
+
+ </style>
+</head>
+<body>
+
+ <header>DESIGNER WALLCOVERINGS</header>
+
+ <div class="container">
+ <div id="vignette"></div>
+
+ <div class="era-buttons">
+ <button data-era="victorian">Victorian</button>
+ <button data-era="art-deco">Art Deco</button>
+ <button data-era="mid-century">Mid-Century Modern</button>
+ <button data-era="grandmillennial">Grandmillennial</button>
+ </div>
+
+ <div id="score">Score: 0 / 8</div>
+ <div id="round">Round: 1</div>
+
+ <script>
+ const eras = ["victorian", "art-deco", "mid-century", "grandmillennial"];
+ let currentRound = 1;
+ let score = 0;
+ let bestScore = localStorage.getItem('bestScore') || 0;
+
+ const vignette = document.getElementById("vignette");
+ const eraButtons = document.querySelectorAll(".era-buttons button");
+ const scoreElement = document.getElementById("score");
+ const roundElement = document.getElementById("round");
+
+ function getRandomEra() {
+ return eras[Math.floor(Math.random() * eras.length)];
+ }
+
+ function setVignetteStyle(era) {
+ vignette.className = "vignette " + era;
+ }
+
+ function updateScoreboard() {
+ scoreElement.textContent = `Score: ${score} / 8`;
+ }
+
+ function updateRound() {
+ roundElement.textContent = `Round: ${currentRound}`;
+ }
+
+ function showOverlay(message, eraName, funFact) {
+ const overlay = document.createElement('div');
+ overlay.className = 'overlay';
+ overlay.innerHTML = `<h2>${message}</h2><p>${funFact}</p><button id="restart-button">Restart</button>`;
+ document.body.appendChild(overlay);
+
+ const restartButton = document.getElementById("restart-button");
+ restartButton.addEventListener("click", () => {
+ overlay.remove();
+ resetGame();
+ });
+ }
+
+
+ function resetGame() {
+ currentRound = 1;
+ score = 0;
+ updateScoreboard();
+ updateRound();
+ nextRound();
+ }
+
+ const eraFacts = {
+ "victorian": "Victorian design emphasizes ornate details, rich colors, and a sense of grandeur.",
+ "art-deco": "Art Deco is characterized by geometric shapes, luxurious materials, and a focus on modernity.",
+ "mid-century": "Mid-Century Modern embraces clean lines, organic forms, and functionality.",
+ "grandmillennial": "Grandmillennial style blends traditional elements with a contemporary twist, creating a cozy and nostalgic atmosphere."
+ };
+
+ function nextRound() {
+ if (currentRound > 8) {
+ showOverlay(`Game Over! Your Score: ${score}`, "", eraFacts[getRandomEra()],);
+ return;
+ }
+
+ const randomEra = getRandomEra();
+ setVignetteStyle(randomEra);
+ updateScoreboard();
+ updateRound();
+ }
+
+
+ eraButtons.forEach(button => {
+ button.addEventListener("click", () => {
+ if (button.dataset.era === vignette.className.split(' ')[1]) {
+ score++;
+ updateScoreboard();
+ } else {
+ // Optional: Add a slight penalty for incorrect answers
+ }
+ nextRound();
+ });
+ });
+
+ bestScore = parseInt(localStorage.getItem('bestScore')) || 0;
+
+ nextRound();
+
+
+ </script>
+ </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/gemma3-12b.png b/data/artifacts/6f651f004b4c/gemma3-12b.png
new file mode 100644
index 0000000..9c47dba
Binary files /dev/null and b/data/artifacts/6f651f004b4c/gemma3-12b.png differ
diff --git a/data/artifacts/6f651f004b4c/gpt.html b/data/artifacts/6f651f004b4c/gpt.html
new file mode 100644
index 0000000..a05c84f
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/gpt.html
@@ -0,0 +1,1597 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<title>Which Design Era? · Designer Wallcoverings</title>
+<style>
+:root {
+ /* Design tokens */
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --surface-soft: #1f1f26;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961; /* soft metallic gold */
+ --accent-deep: #7d6a45;
+ --line: rgba(245, 242, 234, 0.14);
+ --line-strong: rgba(245, 242, 234, 0.32);
+ --shadow-soft: 0 18px 45px rgba(0, 0, 0, 0.45);
+ --shadow-subtle: 0 1px 0 rgba(255,255,255,0.02), 0 0 0 1px rgba(0,0,0,0.7);
+ --radius-lg: 20px;
+ --radius-md: 12px;
+ --radius-sm: 8px;
+ --transition-fast: 160ms cubic-bezier(.22,.9,.24,1); /* swift-out */
+ --transition-med: 260ms cubic-bezier(.22,1,.36,1); /* ease-out-quint */
+ --transition-slow: 420ms cubic-bezier(.77,0,.18,1); /* power-in-out */
+ --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
+ --font-serif-alt: "EB Garamond", "Cormorant Garamond", Georgia, serif;
+ --font-sans: "Avenir Next", "Century Gothic", "Segoe UI", system-ui, sans-serif;
+ --fs-display: 3.5rem; /* ~56px for wordmark */
+ --fs-h1: 2.4rem;
+ --fs-h2: 1.75rem;
+ --fs-body: 1rem;
+ --fs-label: 0.7rem;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ min-height: 100%;
+ background: radial-gradient(circle at top left, #17171c 0, #0d0d0f 52%, #050507 100%);
+ color: var(--text);
+ font-family: var(--font-sans);
+ line-height: 1.6;
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+}
+
+/* Header / wordmark */
+.app-header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 84px;
+ padding: 16px 42px 14px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background:
+ linear-gradient(to bottom, rgba(10,10,12,0.95), rgba(10,10,12,0.9)),
+ radial-gradient(circle at top left, rgba(120,110,90,0.18), transparent 52%);
+ border-bottom: 1px solid var(--line);
+ box-shadow: 0 22px 40px rgba(0,0,0,0.56);
+ z-index: 10;
+}
+
+.brand-lockup {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.wordmark {
+ font-family: var(--font-display);
+ font-size: 3.1rem; /* >= 40px as required, tuned for fit */
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text); /* darkest ink token */
+ line-height: 1.02;
+ white-space: nowrap;
+}
+
+.wordmark-sub {
+ font-family: var(--font-sans);
+ font-size: 0.68rem;
+ letter-spacing: 0.25em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-top: 4px;
+}
+
+/* Header right: score + controls */
+.header-meta {
+ display: flex;
+ align-items: center;
+ gap: 28px;
+}
+
+.meta-block {
+ text-align: right;
+}
+
+.meta-label {
+ font-size: var(--fs-label);
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.meta-value {
+ font-size: 0.95rem;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--text);
+ margin-top: 4px;
+}
+
+.header-controls {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+/* Buttons */
+.btn {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 120px;
+ padding: 9px 18px 8px;
+ border-radius: 999px;
+ border: 1px solid rgba(201,169,97,0.8);
+ background:
+ radial-gradient(circle at 10% 0, rgba(255,255,255,0.12), transparent 55%),
+ linear-gradient(135deg, rgba(10,10,12,0.95), rgba(24,24,30,0.98));
+ color: var(--text);
+ font-family: var(--font-sans);
+ font-size: 0.72rem;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ cursor: pointer;
+ box-shadow: var(--shadow-subtle);
+ transition:
+ transform var(--transition-fast),
+ box-shadow var(--transition-fast),
+ border-color var(--transition-fast),
+ background var(--transition-med),
+ color var(--transition-fast),
+ opacity var(--transition-fast);
+}
+
+.btn::before {
+ content: "";
+ position: absolute;
+ inset: 1px;
+ border-radius: inherit;
+ background: linear-gradient(135deg, rgba(255,255,255,0.04), rgba(0,0,0,0.5));
+ mix-blend-mode: screen;
+ opacity: 0.8;
+ pointer-events: none;
+}
+
+.btn:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 10px 26px rgba(0,0,0,0.7);
+ border-color: rgba(234,203,128,0.95);
+}
+
+.btn:active {
+ transform: translateY(0);
+ box-shadow: 0 4px 18px rgba(0,0,0,0.7);
+}
+
+.btn-ghost {
+ background: transparent;
+ border-color: rgba(245,242,234,0.32);
+ box-shadow: none;
+}
+
+.btn-ghost::before {
+ display: none;
+}
+
+.btn-ghost:hover {
+ background: radial-gradient(circle at 0 0, rgba(255,255,255,0.08), transparent 55%);
+ border-color: rgba(245,242,234,0.55);
+}
+
+/* Layout */
+.app-shell {
+ margin-top: 84px;
+ padding: 26px 40px 40px;
+ display: flex;
+ justify-content: center;
+}
+
+.app-inner {
+ width: min(1120px, 100%);
+ display: grid;
+ grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.9fr);
+ gap: 36px;
+ align-items: stretch;
+}
+
+@media (max-width: 960px) {
+ .wordmark {
+ font-size: 2.4rem;
+ letter-spacing: 0.16em;
+ }
+ .app-inner {
+ grid-template-columns: minmax(0, 1fr);
+ }
+ .app-shell {
+ padding-inline: 20px;
+ }
+}
+
+@media (max-width: 720px) {
+ .app-header {
+ flex-direction: column;
+ align-items: flex-start;
+ height: auto;
+ padding-bottom: 18px;
+ gap: 10px;
+ }
+ .header-meta {
+ width: 100%;
+ justify-content: space-between;
+ }
+ .meta-block {
+ text-align: left;
+ }
+ .app-shell {
+ margin-top: 120px;
+ }
+}
+
+/* Game card */
+.game-card {
+ position: relative;
+ background:
+ radial-gradient(circle at top left, rgba(201,169,97,0.12), transparent 56%),
+ linear-gradient(145deg, #181820, #111118 60%, #08080b);
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--line-strong);
+ box-shadow: var(--shadow-soft);
+ padding: 20px 20px 24px;
+ display: flex;
+ flex-direction: column;
+ gap: 18px;
+ overflow: hidden;
+}
+
+.game-card::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ border-radius: inherit;
+ background:
+ linear-gradient(120deg, rgba(255,255,255,0.08), transparent 30%, transparent 70%, rgba(255,255,255,0.06));
+ mix-blend-mode: soft-light;
+ opacity: 0.6;
+ pointer-events: none;
+}
+
+.game-card-header {
+ position: relative;
+ z-index: 1;
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ gap: 16px;
+}
+
+.game-title {
+ font-family: var(--font-display);
+ font-size: var(--fs-h1);
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ margin: 0;
+ color: var(--text);
+}
+
+.game-subtitle {
+ font-size: 0.88rem;
+ color: var(--muted);
+ max-width: 32rem;
+}
+
+.round-indicator {
+ font-size: var(--fs-label);
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+/* Vignette wrapper */
+.vignette-shell {
+ position: relative;
+ z-index: 1;
+ flex: 1;
+ border-radius: calc(var(--radius-md) + 2px);
+ padding: 16px;
+ background:
+ linear-gradient(to bottom right, rgba(249,244,224,0.09), rgba(12,12,15,0.9)),
+ radial-gradient(circle at top left, rgba(248,230,170,0.24), transparent 60%);
+ border: 1px solid rgba(255,255,255,0.08);
+ box-shadow: inset 0 0 0 1px rgba(0,0,0,0.5);
+}
+
+.vignette-inner {
+ position: relative;
+ border-radius: var(--radius-md);
+ overflow: hidden;
+ background: radial-gradient(circle at top, #f5f2ea 0, #e0d8c5 40%, #b8ac97 80%);
+ box-shadow:
+ inset 0 0 0 1px rgba(255,255,255,0.25),
+ 0 18px 30px rgba(0,0,0,0.7);
+ min-height: 260px;
+}
+
+/* Generic room base */
+.room {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 260px;
+ overflow: hidden;
+}
+
+/* Base walls and floor */
+.room-wall {
+ position: absolute;
+ inset: 0;
+}
+
+.room-floor {
+ position: absolute;
+ left: -10%;
+ right: -10%;
+ bottom: -15%;
+ height: 48%;
+ transform: skewX(-12deg);
+ transform-origin: bottom left;
+}
+
+/* Utility for panels */
+.wall-panel {
+ position: absolute;
+ top: 0;
+ bottom: 28%;
+ width: 20%;
+ border-radius: 24px;
+ box-shadow: 0 16px 24px rgba(0,0,0,0.35);
+}
+
+/* Era-specific styling */
+/* Victorian */
+.room--victorian .room-wall {
+ background:
+ linear-gradient(to bottom, #f7f0e4 0, #f1e3d2 30%, #e2cdb4 65%, #d2b496 100%);
+}
+
+.room--victorian .room-wall::before {
+ content: "";
+ position: absolute;
+ inset: 12% 12% 36% 12%;
+ border-radius: 32px;
+ border: 2px solid rgba(125,106,69,0.9);
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,0.6);
+ background:
+ repeating-linear-gradient(
+ 45deg,
+ rgba(135,104,89,0.26) 0,
+ rgba(135,104,89,0.26) 6px,
+ rgba(227,205,183,0.0) 6px,
+ rgba(227,205,183,0.0) 14px
+ );
+}
+
+.room--victorian .room-wall::after {
+ content: "";
+ position: absolute;
+ left: 14%;
+ right: 14%;
+ bottom: 32%;
+ height: 36px;
+ border-radius: 20px;
+ background:
+ linear-gradient(to bottom, #d9c5ac, #c19c76);
+ box-shadow:
+ 0 10px 20px rgba(0,0,0,0.4),
+ inset 0 0 0 1px rgba(255,255,255,0.65);
+}
+
+/* Victorian floor: dark herringbone wood */
+.room--victorian .room-floor {
+ background:
+ repeating-linear-gradient(
+ 135deg,
+ #4b3222 0,
+ #4b3222 14px,
+ #3a2518 14px,
+ #3a2518 28px
+ );
+ box-shadow:
+ 0 -8px 16px rgba(0,0,0,0.65),
+ inset 0 8px 16px rgba(0,0,0,0.7);
+}
+
+/* Victorian furniture */
+.victorian-chaise {
+ position: absolute;
+ bottom: 10%;
+ left: 17%;
+ width: 46%;
+ height: 26%;
+ border-radius: 34px 34px 22px 22px;
+ background:
+ radial-gradient(circle at 20% 0, rgba(255,255,255,0.25), transparent 55%),
+ linear-gradient(145deg, #b76e79, #7c343d);
+ box-shadow: 0 16px 28px rgba(0,0,0,0.7);
+}
+
+.victorian-chaise::before {
+ content: "";
+ position: absolute;
+ left: -10%;
+ top: -35%;
+ width: 40%;
+ height: 90%;
+ border-radius: 42px 50px 18px 34px;
+ background:
+ radial-gradient(circle at 10% 20%, rgba(255,255,255,0.35), transparent 55%),
+ linear-gradient(145deg, #8d3e49, #61212c);
+ box-shadow: 0 14px 22px rgba(0,0,0,0.7);
+}
+
+.victorian-chaise::after {
+ content: "";
+ position: absolute;
+ left: 10%;
+ right: 8%;
+ top: 22%;
+ height: 32%;
+ border-radius: 22px;
+ border: 1px solid rgba(255,255,255,0.45);
+ background:
+ radial-gradient(circle at 0 0, rgba(255,255,255,0.32), transparent 60%),
+ repeating-linear-gradient(
+ 135deg,
+ rgba(255,255,255,0.25) 0,
+ rgba(255,255,255,0.25) 4px,
+ rgba(255,255,255,0.0) 4px,
+ rgba(255,255,255,0.0) 8px
+ );
+}
+
+/* Victorian lamp */
+.victorian-lamp {
+ position: absolute;
+ bottom: 34%;
+ right: 18%;
+ width: 12%;
+ height: 38%;
+}
+
+.victorian-lamp::before {
+ content: "";
+ position: absolute;
+ bottom: 36%;
+ left: 18%;
+ right: 18%;
+ height: 46%;
+ border-radius: 50% 50% 35% 35%;
+ background:
+ radial-gradient(circle at 50% 0, rgba(255,255,255,0.9), rgba(248,230,200,0.5) 42%, rgba(210,178,125,0.9) 100%);
+ box-shadow: 0 10px 18px rgba(0,0,0,0.6);
+}
+
+.victorian-lamp::after {
+ content: "";
+ position: absolute;
+ bottom: 20%;
+ left: 45%;
+ width: 10%;
+ height: 18%;
+ background: linear-gradient(to bottom, #d6c59e, #a79163);
+ box-shadow: 0 2px 4px rgba(0,0,0,0.5);
+}
+
+/* Victorian side table */
+.victorian-table {
+ position: absolute;
+ bottom: 7%;
+ right: 22%;
+ width: 12%;
+ height: 18%;
+ border-radius: 18px;
+ background:
+ radial-gradient(circle at 50% 0, rgba(255,255,255,0.4), transparent 55%),
+ linear-gradient(145deg, #8a6744, #4a2d18);
+ box-shadow: 0 14px 20px rgba(0,0,0,0.75);
+}
+
+/* Art Deco */
+.room--artdeco .room-wall {
+ background:
+ linear-gradient(135deg, #111218, #191b24 45%, #15141f 70%, #101018 100%);
+}
+
+.room--artdeco .room-wall::before {
+ content: "";
+ position: absolute;
+ inset: 10% 10% 36% 10%;
+ border-radius: 26px;
+ background:
+ radial-gradient(circle at 50% 0, rgba(255,255,255,0.16), transparent 60%),
+ repeating-conic-gradient(
+ from 0deg,
+ rgba(201,169,97,0.24) 0 6deg,
+ transparent 6deg 12deg
+ );
+ mask-image: radial-gradient(circle at top, black 0 60%, transparent 70%);
+ opacity: 0.9;
+}
+
+.room--artdeco .room-wall::after {
+ content: "";
+ position: absolute;
+ left: 12%;
+ right: 12%;
+ bottom: 34%;
+ height: 50px;
+ border-radius: 27px;
+ background:
+ linear-gradient(to right, #201d1a, #c9a961 12%, #f2e3b8 30%, #c9a961 46%, #18171c 100%);
+ box-shadow:
+ 0 14px 26px rgba(0,0,0,0.7),
+ inset 0 0 0 1px rgba(0,0,0,0.7);
+}
+
+/* Art Deco floor: high-contrast marble inlay */
+.room--artdeco .room-floor {
+ background:
+ linear-gradient(to bottom, #181821 0, #050507 100%),
+ repeating-linear-gradient(
+ 135deg,
+ rgba(255,255,255,0.08) 0,
+ rgba(255,255,255,0.08) 4px,
+ rgba(0,0,0,0.4) 4px,
+ rgba(0,0,0,0.4) 8px
+ );
+ box-shadow:
+ 0 -8px 18px rgba(0,0,0,0.7),
+ inset 0 12px 18px rgba(0,0,0,0.9);
+}
+
+/* Art Deco sofa */
+.artdeco-sofa {
+ position: absolute;
+ bottom: 11%;
+ left: 18%;
+ width: 48%;
+ height: 24%;
+ border-radius: 32px;
+ background:
+ linear-gradient(135deg, #23232a, #0f0f13);
+ box-shadow: 0 20px 30px rgba(0,0,0,0.8);
+}
+
+.artdeco-sofa::before {
+ content: "";
+ position: absolute;
+ left: 6%;
+ right: 6%;
+ top: 18%;
+ height: 40%;
+ border-radius: 20px;
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ #353541 0,
+ #353541 8px,
+ #262631 8px,
+ #262631 16px
+ );
+}
+
+.artdeco-sofa::after {
+ content: "";
+ position: absolute;
+ left: 14%;
+ right: 14%;
+ top: 6%;
+ height: 22%;
+ border-radius: 18px 18px 12px 12px;
+ background:
+ linear-gradient(135deg, #c9a961, #f5e3b8);
+}
+
+/* Art Deco screen panels */
+.artdeco-panel-left,
+.artdeco-panel-right {
+ position: absolute;
+ top: 8%;
+ bottom: 30%;
+ width: 14%;
+ border-radius: 26px;
+ background:
+ linear-gradient(180deg, rgba(0,0,0,0.9), rgba(0,0,0,0.2)),
+ repeating-linear-gradient(
+ 0deg,
+ rgba(201,169,97,0.65) 0,
+ rgba(201,169,97,0.65) 4px,
+ rgba(0,0,0,0.0) 4px,
+ rgba(0,0,0,0.0) 9px
+ );
+ box-shadow: 0 18px 30px rgba(0,0,0,0.8);
+}
+
+.artdeco-panel-left {
+ left: 6%;
+}
+
+.artdeco-panel-right {
+ right: 6%;
+}
+
+/* Art Deco low table */
+.artdeco-table {
+ position: absolute;
+ bottom: 6%;
+ left: 42%;
+ width: 20%;
+ height: 10%;
+ border-radius: 18px;
+ background:
+ linear-gradient(135deg, #181414, #b59b72);
+ box-shadow: 0 14px 20px rgba(0,0,0,0.85);
+}
+
+/* Mid-century modern */
+.room--midcentury .room-wall {
+ background:
+ linear-gradient(to bottom, #f9f4e7 0, #f1e4ce 36%, #e3d0b0 70%);
+}
+
+.room--midcentury .room-wall::before {
+ content: "";
+ position: absolute;
+ inset: 10% 8% 38% 8%;
+ background:
+ radial-gradient(circle at 20% 20%, #f4c979 0, #f4c979 8%, transparent 10%),
+ radial-gradient(circle at 50% 40%, #f07f5d 0, #f07f5d 7%, transparent 10%),
+ radial-gradient(circle at 78% 22%, #4cb0a6 0, #4cb0a6 8%, transparent 10%),
+ repeating-linear-gradient(
+ 135deg,
+ rgba(40,34,28,0.18) 0,
+ rgba(40,34,28,0.18) 4px,
+ rgba(255,255,255,0.0) 4px,
+ rgba(255,255,255,0.0) 12px
+ );
+ border-radius: 40px;
+ box-shadow:
+ inset 0 0 0 1px rgba(255,255,255,0.7),
+ 0 16px 20px rgba(0,0,0,0.25);
+}
+
+/* Mid-century floor: warm blonde wood */
+.room--midcentury .room-floor {
+ background:
+ linear-gradient(to bottom, #d4b182 0, #b18351 80%);
+ box-shadow:
+ 0 -10px 18px rgba(0,0,0,0.55),
+ inset 0 10px 18px rgba(0,0,0,0.55);
+}
+
+/* Mid-century sofa */
+.midcentury-sofa {
+ position: absolute;
+ bottom: 12%;
+ left: 18%;
+ width: 52%;
+ height: 26%;
+ border-radius: 18px 18px 12px 12px;
+ background:
+ linear-gradient(145deg, #4cb0a6, #2d6f67);
+ box-shadow: 0 20px 26px rgba(0,0,0,0.7);
+}
+
+.midcentury-sofa::before {
+ content: "";
+ position: absolute;
+ left: 10%;
+ right: 10%;
+ top: 18%;
+ height: 26%;
+ border-radius: 18px;
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ rgba(255,255,255,0.18) 0,
+ rgba(255,255,255,0.18) 6px,
+ rgba(255,255,255,0.0) 6px,
+ rgba(255,255,255,0.0) 12px
+ );
+}
+
+.midcentury-sofa::after {
+ content: "";
+ position: absolute;
+ left: 15%;
+ right: 52%;
+ top: 42%;
+ height: 30%;
+ border-radius: 16px;
+ background:
+ linear-gradient(145deg, #f4c979, #f59f4b);
+}
+
+/* Mid-century credenza */
+.midcentury-credenza {
+ position: absolute;
+ bottom: 12%;
+ right: 14%;
+ width: 18%;
+ height: 22%;
+ border-radius: 12px 12px 6px 6px;
+ background:
+ linear-gradient(145deg, #b97a4a, #7d4a2a);
+ box-shadow: 0 18px 22px rgba(0,0,0,0.7);
+}
+
+.midcentury-credenza::before,
+.midcentury-credenza::after {
+ content: "";
+ position: absolute;
+ top: 18%;
+ width: 6%;
+ height: 68%;
+ border-radius: 10px;
+ background: rgba(255,255,255,0.2);
+}
+
+.midcentury-credenza::before {
+ left: 18%;
+}
+
+.midcentury-credenza::after {
+ right: 18%;
+}
+
+/* Mid-century clock */
+.midcentury-clock {
+ position: absolute;
+ top: 14%;
+ right: 20%;
+ width: 12%;
+ height: 22%;
+}
+
+.midcentury-clock::before {
+ content: "";
+ position: absolute;
+ inset: 10% 20%;
+ border-radius: 50%;
+ background:
+ radial-gradient(circle at 50% 50%, #f0e9da 0, #f0e9da 50%, #d4c7af 55%, #8d7b61 75%, #f0e9da 78%);
+ box-shadow: 0 10px 16px rgba(0,0,0,0.3);
+}
+
+.midcentury-clock::after {
+ content: "";
+ position: absolute;
+ inset: 35% 48% 25% 46%;
+ background: #4b3a2b;
+}
+
+/* Grandmillennial */
+.room--grandmillennial .room-wall {
+ background:
+ linear-gradient(to bottom, #f9f5f0 0, #f4ece3 30%, #ebded0 70%);
+}
+
+.room--grandmillennial .room-wall::before {
+ content: "";
+ position: absolute;
+ inset: 10% 10% 40% 10%;
+ border-radius: 32px;
+ background:
+ repeating-linear-gradient(
+ 45deg,
+ #d5e3f5 0,
+ #d5e3f5 10px,
+ #f9f5f0 10px,
+ #f9f5f0 20px
+ );
+ mask-image: radial-gradient(circle at top, black 0 68%, transparent 80%);
+ box-shadow:
+ inset 0 0 0 1px rgba(255,255,255,0.9),
+ 0 12px 20px rgba(0,0,0,0.2);
+}
+
+/* Grandmillennial floor: creamy checkerboard */
+.room--grandmillennial .room-floor {
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ #f7efe4 0,
+ #f7efe4 26px,
+ #eadac8 26px,
+ #eadac8 52px
+ );
+ box-shadow:
+ 0 -8px 18px rgba(0,0,0,0.4),
+ inset 0 12px 18px rgba(0,0,0,0.6);
+}
+
+/* Grandmillennial skirted sofa */
+.grand-sofa {
+ position: absolute;
+ bottom: 10%;
+ left: 18%;
+ width: 54%;
+ height: 26%;
+ border-radius: 22px 22px 14px 14px;
+ background:
+ linear-gradient(145deg, #f8f2ea, #dfd1c2);
+ box-shadow: 0 20px 26px rgba(0,0,0,0.7);
+}
+
+.grand-sofa::before {
+ content: "";
+ position: absolute;
+ left: 12%;
+ right: 12%;
+ top: 16%;
+ height: 34%;
+ border-radius: 20px;
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ #f2e1e7 0,
+ #f2e1e7 12px,
+ #e0d4e6 12px,
+ #e0d4e6 24px
+ );
+}
+
+.grand-sofa::after {
+ content: "";
+ position: absolute;
+ left: 10%;
+ right: 10%;
+ bottom: 0;
+ height: 38%;
+ border-radius: 0 0 16px 16px;
+ background:
+ repeating-linear-gradient(
+ -45deg,
+ #f4e6dd 0,
+ #f4e6dd 10px,
+ #e1d2c8 10px,
+ #e1d2c8 20px
+ );
+}
+
+/* Grandmillennial floral armchair */
+.grand-chair {
+ position: absolute;
+ bottom: 14%;
+ right: 16%;
+ width: 18%;
+ height: 26%;
+ border-radius: 22px;
+ background:
+ radial-gradient(circle at 20% 0, rgba(255,255,255,0.5), transparent 60%),
+ repeating-linear-gradient(
+ 45deg,
+ #f2dde3 0,
+ #f2dde3 8px,
+ #e0cad8 8px,
+ #e0cad8 16px
+ );
+ box-shadow: 0 18px 22px rgba(0,0,0,0.6);
+}
+
+/* Grandmillennial ruffled lamp */
+.grand-lamp {
+ position: absolute;
+ bottom: 36%;
+ left: 24%;
+ width: 10%;
+ height: 34%;
+}
+
+.grand-lamp::before {
+ content: "";
+ position: absolute;
+ bottom: 40%;
+ left: 10%;
+ right: 10%;
+ height: 42%;
+ border-radius: 50% 50% 40% 40%;
+ background:
+ radial-gradient(circle at 50% 0, #ffffff, #f9e8de 55%, #f0d7c8 100%);
+ box-shadow: 0 12px 18px rgba(0,0,0,0.45);
+}
+
+.grand-lamp::after {
+ content: "";
+ position: absolute;
+ bottom: 32%;
+ left: 20%;
+ right: 20%;
+ height: 10%;
+ border-radius: 999px;
+ background:
+ repeating-linear-gradient(
+ 90deg,
+ #f6e1d8 0,
+ #f6e1d8 3px,
+ #eac5c0 3px,
+ #eac5c0 6px
+ );
+}
+
+/* Grandmillennial framed plates */
+.grand-plates {
+ position: absolute;
+ top: 16%;
+ left: 22%;
+ width: 20%;
+ height: 18%;
+}
+
+.grand-plates::before,
+.grand-plates::after {
+ content: "";
+ position: absolute;
+ top: 8%;
+ width: 42%;
+ height: 76%;
+ border-radius: 50%;
+ border: 3px solid #d3e0f2;
+ box-shadow: 0 6px 10px rgba(0,0,0,0.18);
+ background:
+ radial-gradient(circle at 50% 50%, #fdfbf7 0, #f7f1ea 52%, #e1d2bf 100%),
+ radial-gradient(circle at 30% 30%, rgba(146,176,214,0.5) 0, transparent 45%);
+}
+
+.grand-plates::before {
+ left: 0;
+}
+
+.grand-plates::after {
+ right: 0;
+}
+
+/* Guess controls */
+.guess-panel {
+ position: relative;
+ z-index: 1;
+ margin-top: 14px;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px;
+}
+
+.guess-btn {
+ width: 100%;
+}
+
+/* State styles for guess buttons */
+.guess-btn.correct {
+ border-color: #9dd787;
+ background:
+ radial-gradient(circle at 0 0, rgba(255,255,255,0.2), transparent 60%),
+ linear-gradient(135deg, #193120, #28532f);
+}
+
+.guess-btn.wrong {
+ border-color: #f07f5d;
+ background:
+ linear-gradient(135deg, #421718, #250809);
+ opacity: 0.9;
+}
+
+.guess-btn.disabled {
+ pointer-events: none;
+ opacity: 0.68;
+}
+
+/* Side panel info */
+.info-card {
+ background:
+ radial-gradient(circle at top left, rgba(201,169,97,0.18), transparent 60%),
+ linear-gradient(160deg, #15151b, #09090d);
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--line-strong);
+ box-shadow: var(--shadow-soft);
+ padding: 22px 22px 24px;
+ display: flex;
+ flex-direction: column;
+ gap: 18px;
+ position: relative;
+ overflow: hidden;
+}
+
+.info-card::before {
+ content: "";
+ position: absolute;
+ inset: -40%;
+ background:
+ radial-gradient(circle at 20% 0, rgba(255,255,255,0.08), transparent 60%),
+ radial-gradient(circle at 80% 100%, rgba(201,169,97,0.12), transparent 55%);
+ opacity: 0.85;
+ pointer-events: none;
+}
+
+.info-header {
+ position: relative;
+ z-index: 1;
+}
+
+.info-title {
+ font-family: var(--font-display);
+ font-size: var(--fs-h2);
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ margin: 0 0 6px;
+}
+
+.info-era-label {
+ font-size: var(--fs-label);
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--accent);
+}
+
+.info-body {
+ position: relative;
+ z-index: 1;
+ font-size: 0.92rem;
+ color: rgba(245,242,234,0.94);
+}
+
+.info-body p {
+ margin: 0 0 8px;
+}
+
+.info-body p:last-child {
+ margin-bottom: 0;
+}
+
+/* Swatch row */
+.swatch-row {
+ position: relative;
+ z-index: 1;
+ display: flex;
+ gap: 10px;
+ margin-top: 6px;
+}
+
+.swatch {
+ flex: 1;
+ height: 44px;
+ border-radius: 999px;
+ border: 1px solid rgba(255,255,255,0.1);
+ box-shadow: 0 8px 16px rgba(0,0,0,0.6);
+ overflow: hidden;
+}
+
+/* Distinct motifs, no labels */
+.swatch--victorian {
+ background:
+ repeating-linear-gradient(
+ 135deg,
+ #c18a8a 0,
+ #c18a8a 12px,
+ #f0d0be 12px,
+ #f0d0be 24px
+ );
+}
+
+.swatch--artdeco {
+ background:
+ radial-gradient(circle at 20% 0, #f5e0a8 0, #f5e0a8 30%, transparent 40%),
+ repeating-linear-gradient(
+ 90deg,
+ #15151e 0,
+ #15151e 6px,
+ #c9a961 6px,
+ #c9a961 8px
+ );
+}
+
+.swatch--midcentury {
+ background:
+ radial-gradient(circle at 10% 0, #f4c979 0, #f4c979 28%, transparent 40%),
+ radial-gradient(circle at 80% 80%, #4cb0a6 0, #4cb0a6 26%, transparent 40%),
+ linear-gradient(135deg, #f9f4e7, #e3cfb0);
+}
+
+.swatch--grand {
+ background:
+ repeating-linear-gradient(
+ 45deg,
+ #f2dde3 0,
+ #f2dde3 8px,
+ #d5e3f5 8px,
+ #d5e3f5 16px
+ );
+}
+
+/* Overlay */
+.overlay {
+ position: fixed;
+ inset: 0;
+ display: none;
+ align-items: center;
+ justify-content: center;
+ padding: 24px;
+ background: radial-gradient(circle at top, rgba(0,0,0,0.82), rgba(0,0,0,0.96));
+ z-index: 20;
+}
+
+.overlay.visible {
+ display: flex;
+}
+
+.overlay-card {
+ width: min(520px, 100%);
+ background:
+ radial-gradient(circle at top left, rgba(201,169,97,0.24), transparent 60%),
+ linear-gradient(160deg, #181820, #0b0b10);
+ border-radius: 24px;
+ border: 1px solid rgba(201,169,97,0.5);
+ box-shadow:
+ 0 24px 48px rgba(0,0,0,0.85),
+ inset 0 0 0 1px rgba(0,0,0,0.75);
+ padding: 26px 26px 20px;
+ color: var(--text);
+ transform: translateY(24px);
+ opacity: 0;
+ transition:
+ opacity var(--transition-med),
+ transform var(--transition-med);
+}
+
+.overlay.visible .overlay-card {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+.overlay-title {
+ font-family: var(--font-display);
+ font-size: 2.1rem;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ margin: 0 0 10px;
+}
+
+.overlay-sub {
+ font-size: 0.92rem;
+ color: var(--muted);
+ margin-bottom: 16px;
+}
+
+.overlay-metrics {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 14px 28px;
+ margin-bottom: 20px;
+}
+
+.metric-label {
+ font-size: var(--fs-label);
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.metric-value {
+ font-size: 1rem;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+}
+
+.overlay-actions {
+ display: flex;
+ justify-content: flex-end;
+ gap: 10px;
+}
+
+/* Animations */
+.vignette-inner,
+.info-card {
+ animation: sceneIn 520ms cubic-bezier(.22,1,.36,1);
+}
+
+@keyframes sceneIn {
+ from {
+ opacity: 0;
+ transform: translateY(12px) scale(0.99);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+}
+</style>
+</head>
+<body>
+<header class="app-header">
+ <div class="brand-lockup">
+ <div class="wordmark">DESIGNER WALLCOVERINGS</div>
+ <div class="wordmark-sub">INTERIOR ERA STUDY</div>
+ </div>
+ <div class="header-meta">
+ <div class="meta-block">
+ <div class="meta-label">Round</div>
+ <div class="meta-value" id="roundDisplay">1 / 8</div>
+ </div>
+ <div class="meta-block">
+ <div class="meta-label">Score</div>
+ <div class="meta-value" id="scoreDisplay">0</div>
+ </div>
+ <div class="meta-block">
+ <div class="meta-label">Best</div>
+ <div class="meta-value" id="bestScoreDisplay">–</div>
+ </div>
+ <div class="header-controls">
+ <button class="btn btn-ghost" id="restartBtn" type="button">Restart Game</button>
+ </div>
+ </div>
+</header>
+
+<main class="app-shell">
+ <div class="app-inner">
+ <section class="game-card" aria-labelledby="gameTitle">
+ <div class="game-card-header">
+ <div>
+ <h1 class="game-title" id="gameTitle">Which Design Era?</h1>
+ <p class="game-subtitle">Study the vignette — the wall treatment, silhouettes, and color palette. Then commit to an era.</p>
+ </div>
+ <div class="round-indicator" id="roundIndicatorLabel">Guess the era</div>
+ </div>
+
+ <div class="vignette-shell" aria-label="Interior vignette">
+ <div class="vignette-inner">
+ <div class="room room--victorian" id="room">
+ <div class="room-wall"></div>
+ <div class="room-floor"></div>
+ <div class="victorian-chaise"></div>
+ <div class="victorian-lamp"></div>
+ <div class="victorian-table"></div>
+ </div>
+ </div>
+ </div>
+
+ <div class="guess-panel" aria-label="Choose the era">
+ <button class="btn guess-btn" data-era="Victorian" type="button">Victorian</button>
+ <button class="btn guess-btn" data-era="Art Deco" type="button">Art Deco</button>
+ <button class="btn guess-btn" data-era="Mid-Century Modern" type="button">Mid-Century Modern</button>
+ <button class="btn guess-btn" data-era="Grandmillennial" type="button">Grandmillennial</button>
+ </div>
+ </section>
+
+ <aside class="info-card" aria-live="polite">
+ <div class="info-header">
+ <div class="info-era-label" id="infoEraLabel">Victorian · 1837–1901</div>
+ <h2 class="info-title" id="infoTitle">Ornate, romantic, deeply layered.</h2>
+ </div>
+ <div class="info-body" id="infoBody">
+ <p>Victorian interiors revel in ornament: carved wood, tufted upholstery, rich jewel tones, and intricate floral wallpapers. Symmetry, curves, and fringe are at home here.</p>
+ <p><strong>Fun fact:</strong> Industrial printing made patterned wallpapers affordable, turning parlors into immersive, highly decorative showcases of status and taste.</p>
+ </div>
+
+ <div class="swatch-row">
+ <div class="swatch swatch--victorian" aria-hidden="true"></div>
+ <div class="swatch swatch--artdeco" aria-hidden="true"></div>
+ <div class="swatch swatch--midcentury" aria-hidden="true"></div>
+ <div class="swatch swatch--grand" aria-hidden="true"></div>
+ </div>
+ </aside>
+ </div>
+</main>
+
+<!-- Overlay for end-of-game -->
+<div class="overlay" id="overlay" role="dialog" aria-modal="true" aria-labelledby="overlayTitle">
+ <div class="overlay-card">
+ <h2 class="overlay-title" id="overlayTitle">Game Complete</h2>
+ <p class="overlay-sub" id="overlaySubtitle">You’ve toured the eras. Here’s how your eye performed.</p>
+
+ <div class="overlay-metrics">
+ <div>
+ <div class="metric-label">Total Score</div>
+ <div class="metric-value" id="overlayScore">0 / 8</div>
+ </div>
+ <div>
+ <div class="metric-label">Best Run</div>
+ <div class="metric-value" id="overlayBest">0</div>
+ </div>
+ <div>
+ <div class="metric-label">Accuracy</div>
+ <div class="metric-value" id="overlayAccuracy">0%</div>
+ </div>
+ </div>
+
+ <div class="overlay-actions">
+ <button class="btn btn-ghost" id="overlayClose" type="button">Close</button>
+ <button class="btn" id="overlayRestart" type="button">Play Again</button>
+ </div>
+ </div>
+</div>
+
+<script>
+(function() {
+ const eras = [
+ {
+ name: "Victorian",
+ className: "room--victorian",
+ label: "Victorian · 1837–1901",
+ title: "Ornate, romantic, deeply layered.",
+ body: [
+ "Victorian interiors revel in ornament: carved wood, tufted upholstery, rich jewel tones, and intricate floral wallpapers. Symmetry, curves, and fringe are at home here.",
+ "Fun fact: Industrial printing made patterned wallpapers affordable, turning parlors into immersive, highly decorative showcases of status and taste."
+ ]
+ },
+ {
+ name: "Art Deco",
+ className: "room--artdeco",
+ label: "Art Deco · 1920s–1930s",
+ title: "Glamour with geometry and gleam.",
+ body: [
+ "Art Deco is about streamlined luxury: sharp geometry, sunburst motifs, lacquered surfaces, and metallic inlays. Think cinemas, liners, and cocktail bars with dramatic lighting.",
+ "Fun fact: The style drew from ancient Egypt, skyscraper silhouettes, and machine-age optimism—filtered through chrome, lacquer, and inlaid woods."
+ ]
+ },
+ {
+ name: "Mid-Century Modern",
+ className: "room--midcentury",
+ label: "Mid-Century Modern · 1940s–1960s",
+ title: "Clean lines, optimistic color.",
+ body: [
+ "Mid-century modern favors low silhouettes, tapered legs, and honest materials. Graphic shapes and hits of citrus, teal, and ochre keep everything playful yet refined.",
+ "Fun fact: Mass production and postwar optimism made good design more democratic—plastic, plywood, and steel entered everyday living rooms."
+ ]
+ },
+ {
+ name: "Grandmillennial",
+ className: "room--grandmillennial",
+ label: "Grandmillennial · 2010s–Now",
+ title: "Nostalgic, floral, refreshingly unapologetic.",
+ body: [
+ "Grandmillennial style layers chintz, pleated shades, scallops, and embroidery—but with an edited, intentional eye. It’s cottagecore’s more tailored cousin.",
+ "Fun fact: The movement was a quiet rebellion against minimalist gray boxes, reviving \"grandma\" motifs with fresh color and smart curation."
+ ]
+ }
+ ];
+
+ const roomEl = document.getElementById("room");
+ const roundDisplay = document.getElementById("roundDisplay");
+ const scoreDisplay = document.getElementById("scoreDisplay");
+ const bestScoreDisplay = document.getElementById("bestScoreDisplay");
+ const roundIndicatorLabel = document.getElementById("roundIndicatorLabel");
+ const infoEraLabel = document.getElementById("infoEraLabel");
+ const infoTitle = document.getElementById("infoTitle");
+ const infoBody = document.getElementById("infoBody");
+ const guessButtons = Array.from(document.querySelectorAll(".guess-btn"));
+ const restartBtn = document.getElementById("restartBtn");
+
+ const overlay = document.getElementById("overlay");
+ const overlayScore = document.getElementById("overlayScore");
+ const overlayBest = document.getElementById("overlayBest");
+ const overlayAccuracy = document.getElementById("overlayAccuracy");
+ const overlayClose = document.getElementById("overlayClose");
+ const overlayRestart = document.getElementById("overlayRestart");
+
+ const MAX_ROUNDS = 8;
+ let currentRound = 1;
+ let currentEraIndex = 0;
+ let score = 0;
+ let hasGuessedThisRound = false;
+ const STORAGE_KEY = "dw-era-best-score";
+
+ function shuffle(array) {
+ const arr = array.slice();
+ for (let i = arr.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [arr[i], arr[j]] = [arr[j], arr[i]];
+ }
+ return arr;
+ }
+
+ function pickRandomEra() {
+ const idx = Math.floor(Math.random() * eras.length);
+ return idx;
+ }
+
+ function updateBestScoreDisplay() {
+ let best = localStorage.getItem(STORAGE_KEY);
+ if (best === null) {
+ bestScoreDisplay.textContent = "–";
+ } else {
+ bestScoreDisplay.textContent = best;
+ }
+ }
+
+ function setRoomToEra(eraIndex) {
+ const era = eras[eraIndex];
+ roomEl.className = "room " + era.className;
+ roomEl.innerHTML = ""; // clear and rebuild furniture for each era
+
+ const wall = document.createElement("div");
+ wall.className = "room-wall";
+ const floor = document.createElement("div");
+ floor.className = "room-floor";
+ roomEl.appendChild(wall);
+ roomEl.appendChild(floor);
+
+ if (era.name === "Victorian") {
+ const chaise = document.createElement("div");
+ chaise.className = "victorian-chaise";
+ const lamp = document.createElement("div");
+ lamp.className = "victorian-lamp";
+ const table = document.createElement("div");
+ table.className = "victorian-table";
+ roomEl.appendChild(chaise);
+ roomEl.appendChild(lamp);
+ roomEl.appendChild(table);
+ } else if (era.name === "Art Deco") {
+ const panelL = document.createElement("div");
+ panelL.className = "artdeco-panel-left";
+ const panelR = document.createElement("div");
+ panelR.className = "artdeco-panel-right";
+ const sofa = document.createElement("div");
+ sofa.className = "artdeco-sofa";
+ const table = document.createElement("div");
+ table.className = "artdeco-table";
+ roomEl.appendChild(panelL);
+ roomEl.appendChild(panelR);
+ roomEl.appendChild(sofa);
+ roomEl.appendChild(table);
+ } else if (era.name === "Mid-Century Modern") {
+ const sofa = document.createElement("div");
+ sofa.className = "midcentury-sofa";
+ const cred = document.createElement("div");
+ cred.className = "midcentury-credenza";
+ const clock = document.createElement("div");
+ clock.className = "midcentury-clock";
+ roomEl.appendChild(sofa);
+ roomEl.appendChild(cred);
+ roomEl.appendChild(clock);
+ } else if (era.name === "Grandmillennial") {
+ const sofa = document.createElement("div");
+ sofa.className = "grand-sofa";
+ const chair = document.createElement("div");
+ chair.className = "grand-chair";
+ const lamp = document.createElement("div");
+ lamp.className = "grand-lamp";
+ const plates = document.createElement("div");
+ plates.className = "grand-plates";
+ roomEl.appendChild(sofa);
+ roomEl.appendChild(chair);
+ roomEl.appendChild(lamp);
+ roomEl.appendChild(plates);
+ }
+ }
+
+ function updateInfoPanel(eraIndex) {
+ const era = eras[eraIndex];
+ infoEraLabel.textContent = era.label;
+ infoTitle.textContent = era.title;
+ infoBody.innerHTML = era.body.map(p => "<p>" + p + "</p>").join("");
+ }
+
+ function resetGuessButtons() {
+ guessButtons.forEach(btn => {
+ btn.classList.remove("correct", "wrong", "disabled");
+ });
+ }
+
+ function startRound() {
+ if (currentRound > MAX_ROUNDS) {
+ endGame();
+ return;
+ }
+ hasGuessedThisRound = false;
+ currentEraIndex = pickRandomEra();
+ setRoomToEra(currentEraIndex);
+ updateInfoPanel(currentEraIndex);
+ roundDisplay.textContent = currentRound + " / " + MAX_ROUNDS;
+ roundIndicatorLabel.textContent = "Guess the era";
+ resetGuessButtons();
+ }
+
+ function endGame() {
+ const accuracy = Math.round((score / MAX_ROUNDS) * 100);
+ overlayScore.textContent = score + " / " + MAX_ROUNDS;
+ overlayAccuracy.textContent = accuracy + "%";
+
+ let bestStored = localStorage.getItem(STORAGE_KEY);
+ if (bestStored === null || score > parseInt(bestStored, 10)) {
+ localStorage.setItem(STORAGE_KEY, String(score));
+ bestStored = String(score);
+ }
+ overlayBest.textContent = bestStored;
+ overlay.classList.add("visible");
+ updateBestScoreDisplay();
+ }
+
+ function handleGuess(guess) {
+ if (hasGuessedThisRound) return;
+ hasGuessedThisRound = true;
+
+ const correctEra = eras[currentEraIndex].name;
+ const isCorrect = guess === correctEra;
+ if (isCorrect) {
+ score += 1;
+ scoreDisplay.textContent = String(score);
+ roundIndicatorLabel.textContent = "Spot on: " + correctEra;
+ } else {
+ roundIndicatorLabel.textContent = "It was " + correctEra;
+ }
+
+ guessButtons.forEach(btn => {
+ const era = btn.getAttribute("data-era");
+ if (era === correctEra) {
+ btn.classList.add("correct");
+ } else if (era === guess) {
+ btn.classList.add("wrong");
+ }
+ btn.classList.add("disabled");
+ });
+
+ setTimeout(() => {
+ currentRound += 1;
+ if (currentRound > MAX_ROUNDS) {
+ endGame();
+ } else {
+ startRound();
+ }
+ }, 900);
+ }
+
+ guessButtons.forEach(btn => {
+ btn.addEventListener("click", () => {
+ const era = btn.getAttribute("data-era");
+ handleGuess(era);
+ });
+ });
+
+ restartBtn.addEventListener("click", () => {
+ overlay.classList.remove("visible");
+ score = 0;
+ currentRound = 1;
+ scoreDisplay.textContent = "0";
+ startRound();
+ });
+
+ overlayClose.addEventListener("click", () => {
+ overlay.classList.remove("visible");
+ });
+
+ overlayRestart.addEventListener("click", () => {
+ overlay.classList.remove("visible");
+ score = 0;
+ currentRound = 1;
+ scoreDisplay.textContent = "0";
+ startRound();
+ });
+
+ document.addEventListener("keydown", (e) => {
+ if (e.key === "Escape") {
+ overlay.classList.remove("visible");
+ }
+ });
+
+ updateBestScoreDisplay();
+ startRound();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/gpt.png b/data/artifacts/6f651f004b4c/gpt.png
new file mode 100644
index 0000000..279f556
Binary files /dev/null and b/data/artifacts/6f651f004b4c/gpt.png differ
diff --git a/data/artifacts/6f651f004b4c/grok.html b/data/artifacts/6f651f004b4c/grok.html
new file mode 100644
index 0000000..b91aa6f
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/grok.html
@@ -0,0 +1,1425 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Which Design Era? — Designer Wallcoverings</title>
+<style>
+:root {
+ --bg: #f3efe6;
+ --bg-deep: #ebe4d6;
+ --surface: #fffcf5;
+ --ink: #1c1a17;
+ --ink-soft: #3d3830;
+ --muted: #8a8478;
+ --accent: #b8954a;
+ --accent-deep: #8a6e32;
+ --accent-soft: rgba(184, 149, 74, 0.14);
+ --line: rgba(28, 26, 23, 0.12);
+ --line-strong: rgba(28, 26, 23, 0.22);
+ --shadow: 0 12px 40px rgba(28, 26, 23, 0.08), 0 2px 8px rgba(28, 26, 23, 0.04);
+ --shadow-lg: 0 24px 64px rgba(28, 26, 23, 0.14), 0 4px 16px rgba(28, 26, 23, 0.06);
+ --ease: cubic-bezier(.22, .9, .24, 1);
+ --ease-out: cubic-bezier(.22, 1, .36, 1);
+ --ease-scene: cubic-bezier(.77, 0, .18, 1);
+ --serif: 'Didot', 'Bodoni MT', 'Playfair Display', 'EB Garamond', Georgia, 'Times New Roman', serif;
+ --sans: 'Avenir Next', 'Century Gothic', Futura, 'Segoe UI', 'Helvetica Neue', sans-serif;
+ --radius: 2px;
+ --header-h: 72px;
+}
+
+*, *::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.6;
+ -webkit-font-smoothing: antialiased;
+}
+
+/* —— Header / Wordmark —— */
+.site-header {
+ position: fixed;
+ top: 0; left: 0; right: 0;
+ z-index: 100;
+ height: var(--header-h);
+ background: var(--surface);
+ border-bottom: 1px solid var(--line);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 clamp(20px, 4vw, 48px);
+ box-shadow: 0 1px 0 var(--line);
+}
+
+.wordmark {
+ font-family: var(--serif);
+ font-size: clamp(18px, 2.4vw, 22px);
+ font-weight: 400;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--ink);
+ line-height: 1.25;
+ max-width: min(280px, 52vw);
+ white-space: normal;
+}
+
+.header-meta {
+ display: flex;
+ align-items: center;
+ gap: 28px;
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.header-meta strong {
+ color: var(--ink);
+ font-weight: 500;
+}
+
+/* —— Layout —— */
+main {
+ max-width: 920px;
+ margin: 0 auto;
+ padding: calc(var(--header-h) + 48px) clamp(20px, 4vw, 40px) 80px;
+}
+
+.intro {
+ text-align: center;
+ margin-bottom: 40px;
+}
+
+.eyebrow {
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--accent-deep);
+ margin-bottom: 14px;
+}
+
+h1 {
+ font-family: var(--serif);
+ font-size: clamp(32px, 5vw, 50px);
+ font-weight: 400;
+ letter-spacing: -0.02em;
+ line-height: 1.1;
+ color: var(--ink);
+ margin-bottom: 14px;
+}
+
+.lede {
+ font-size: 16px;
+ color: var(--ink-soft);
+ max-width: 42ch;
+ margin: 0 auto;
+ line-height: 1.65;
+}
+
+/* —— Stage —— */
+.stage {
+ background: var(--surface);
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow);
+ padding: clamp(20px, 3vw, 32px);
+ margin-bottom: 28px;
+}
+
+.stage-label {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ margin-bottom: 18px;
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+}
+
+.vignette-frame {
+ position: relative;
+ width: 100%;
+ aspect-ratio: 16 / 10;
+ overflow: hidden;
+ border: 1px solid var(--line-strong);
+ background: #2a2620;
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,0.04);
+}
+
+.vignette {
+ position: absolute;
+ inset: 0;
+ opacity: 0;
+ transform: scale(1.03);
+ transition: opacity 0.7s var(--ease-out), transform 0.9s var(--ease-scene);
+ pointer-events: none;
+}
+
+.vignette.active {
+ opacity: 1;
+ transform: scale(1);
+ pointer-events: auto;
+}
+
+/* ========== ERA VIGNETTES ========== */
+
+/* —— Victorian —— */
+.v-victorian {
+ background:
+ radial-gradient(ellipse 80% 60% at 50% 100%, rgba(60,20,20,0.5) 0%, transparent 70%),
+ linear-gradient(180deg, #2c1810 0%, #1a0e0a 100%);
+}
+
+/* Damask wallpaper */
+.v-victorian .wall {
+ position: absolute;
+ inset: 0 0 32% 0;
+ background-color: #4a1c28;
+ background-image:
+ radial-gradient(ellipse 18px 22px at 50% 35%, rgba(184,149,74,0.35) 0%, transparent 70%),
+ radial-gradient(ellipse 8px 10px at 50% 55%, rgba(184,149,74,0.25) 0%, transparent 70%),
+ radial-gradient(circle at 25% 50%, transparent 40%, rgba(0,0,0,0.15) 41%, transparent 42%),
+ radial-gradient(circle at 75% 50%, transparent 40%, rgba(0,0,0,0.15) 41%, transparent 42%);
+ background-size: 48px 64px, 48px 64px, 96px 128px, 96px 128px;
+}
+
+.v-victorian .wainscot {
+ position: absolute;
+ left: 0; right: 0; bottom: 28%;
+ height: 18%;
+ background: linear-gradient(180deg, #3d2418 0%, #2a1810 100%);
+ border-top: 3px solid #b8954a;
+ box-shadow: inset 0 8px 0 rgba(184,149,74,0.15);
+}
+
+.v-victorian .wainscot::after {
+ content: '';
+ position: absolute;
+ left: 0; right: 0; top: 10px;
+ height: 1px;
+ background: rgba(184,149,74,0.4);
+}
+
+.v-victorian .floor {
+ position: absolute;
+ left: 0; right: 0; bottom: 0;
+ height: 28%;
+ background:
+ repeating-linear-gradient(90deg,
+ #1a1008 0px, #1a1008 40px,
+ #24160c 40px, #24160c 42px,
+ #1f140a 42px, #1f140a 82px,
+ #24160c 82px, #24160c 84px);
+ transform: perspective(400px) rotateX(28deg);
+ transform-origin: bottom center;
+}
+
+.v-victorian .mantel {
+ position: absolute;
+ left: 50%;
+ bottom: 28%;
+ transform: translateX(-50%);
+ width: 38%;
+ height: 42%;
+}
+
+.v-victorian .mantel-body {
+ position: absolute;
+ inset: 12% 8% 0;
+ background: linear-gradient(180deg, #5c4030 0%, #3d2818 100%);
+ border: 2px solid #b8954a;
+}
+
+.v-victorian .mantel-opening {
+ position: absolute;
+ left: 18%; right: 18%; top: 28%; bottom: 8%;
+ background: radial-gradient(ellipse at 50% 80%, #e85d04 0%, #9a031e 30%, #1a0808 70%);
+ border: 1px solid #8a6e32;
+}
+
+.v-victorian .mantel-shelf {
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 14%;
+ background: linear-gradient(180deg, #6b4a32, #4a3020);
+ border: 2px solid #c9a961;
+ box-shadow: 0 4px 8px rgba(0,0,0,0.4);
+}
+
+.v-victorian .mirror {
+ position: absolute;
+ top: -28%; left: 15%; right: 15%;
+ height: 30%;
+ background: linear-gradient(135deg, #3a5068 0%, #1c2a38 50%, #4a6070 100%);
+ border: 3px solid #c9a961;
+ border-radius: 50% 50% 4px 4px;
+ box-shadow: inset 0 0 20px rgba(255,255,255,0.1);
+}
+
+.v-victorian .drape-l,
+.v-victorian .drape-r {
+ position: absolute;
+ top: 0; bottom: 28%;
+ width: 14%;
+ background: linear-gradient(90deg,
+ #6b1c2a 0%, #8b2a3a 20%, #5a1520 40%,
+ #8b2a3a 60%, #6b1c2a 80%, #4a1018 100%);
+ box-shadow: inset -8px 0 16px rgba(0,0,0,0.3);
+}
+
+.v-victorian .drape-l { left: 0; border-right: 1px solid #b8954a; }
+.v-victorian .drape-r { right: 0; border-left: 1px solid #b8954a; }
+
+.v-victorian .chandelier {
+ position: absolute;
+ top: 4%; left: 50%;
+ transform: translateX(-50%);
+ width: 4px; height: 18%;
+ background: linear-gradient(180deg, #c9a961, #8a6e32);
+}
+
+.v-victorian .chandelier::before {
+ content: '';
+ position: absolute;
+ bottom: 0; left: 50%;
+ transform: translateX(-50%);
+ width: 60px; height: 28px;
+ background:
+ radial-gradient(circle at 10% 50%, #f0e6c8 0 4px, transparent 5px),
+ radial-gradient(circle at 30% 70%, #f0e6c8 0 3px, transparent 4px),
+ radial-gradient(circle at 50% 40%, #fff8e0 0 5px, transparent 6px),
+ radial-gradient(circle at 70% 70%, #f0e6c8 0 3px, transparent 4px),
+ radial-gradient(circle at 90% 50%, #f0e6c8 0 4px, transparent 5px);
+ filter: drop-shadow(0 0 8px rgba(255,220,120,0.6));
+}
+
+/* —— Art Deco —— */
+.v-deco {
+ background: linear-gradient(180deg, #0a0a0c 0%, #14141a 40%, #1a1a22 100%);
+}
+
+.v-deco .wall {
+ position: absolute;
+ inset: 0 0 30% 0;
+ background:
+ linear-gradient(180deg, #12121a 0%, #1c1c28 100%);
+}
+
+/* Sunburst */
+.v-deco .sunburst {
+ position: absolute;
+ top: 8%; left: 50%;
+ transform: translateX(-50%);
+ width: 55%; height: 55%;
+ background:
+ conic-gradient(from 0deg at 50% 100%,
+ #c9a961 0deg, transparent 8deg,
+ #c9a961 16deg, transparent 24deg,
+ #c9a961 32deg, transparent 40deg,
+ #c9a961 48deg, transparent 56deg,
+ #c9a961 64deg, transparent 72deg,
+ #c9a961 80deg, transparent 88deg,
+ #c9a961 96deg, transparent 104deg,
+ #c9a961 112deg, transparent 120deg,
+ #c9a961 128deg, transparent 136deg,
+ #c9a961 144deg, transparent 152deg,
+ #c9a961 160deg, transparent 168deg,
+ #c9a961 176deg, transparent 184deg);
+ opacity: 0.35;
+ mask-image: radial-gradient(ellipse 100% 100% at 50% 100%, black 0%, transparent 70%);
+ -webkit-mask-image: radial-gradient(ellipse 100% 100% at 50% 100%, black 0%, transparent 70%);
+}
+
+.v-deco .chevrons {
+ position: absolute;
+ left: 0; right: 0; top: 0;
+ height: 12%;
+ background:
+ repeating-linear-gradient(90deg,
+ transparent 0, transparent 20px,
+ #c9a961 20px, #c9a961 21px,
+ transparent 21px, transparent 40px),
+ linear-gradient(180deg, #0e0e14, transparent);
+ opacity: 0.5;
+}
+
+.v-deco .floor {
+ position: absolute;
+ left: 0; right: 0; bottom: 0;
+ height: 30%;
+ background:
+ repeating-linear-gradient(90deg, #1a1a22 0 48px, #c9a961 48px 49px, #12121a 49px 97px, #c9a961 97px 98px),
+ linear-gradient(180deg, #0e0e14, #1a1a22);
+ background-blend-mode: overlay;
+}
+
+.v-deco .floor::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ linear-gradient(90deg, transparent 48%, rgba(201,169,97,0.15) 49%, transparent 51%),
+ repeating-linear-gradient(0deg, transparent 0 20px, rgba(201,169,97,0.08) 20px 21px);
+}
+
+.v-deco .console {
+ position: absolute;
+ left: 50%; bottom: 30%;
+ transform: translateX(-50%);
+ width: 44%; height: 22%;
+}
+
+.v-deco .console-top {
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 18%;
+ background: linear-gradient(180deg, #e8d5a3, #c9a961);
+ clip-path: polygon(0 100%, 5% 0, 95% 0, 100% 100%);
+}
+
+.v-deco .console-body {
+ position: absolute;
+ top: 16%; left: 8%; right: 8%; bottom: 0;
+ background: linear-gradient(180deg, #1e3a4c 0%, #0f2430 100%);
+ border: 1px solid #c9a961;
+ clip-path: polygon(0 0, 100% 0, 92% 100%, 8% 100%);
+}
+
+.v-deco .console-body::after {
+ content: '';
+ position: absolute;
+ left: 20%; right: 20%; top: 30%; bottom: 30%;
+ border: 1px solid rgba(201,169,97,0.5);
+ clip-path: polygon(10% 0, 90% 0, 100% 50%, 90% 100%, 10% 100%, 0 50%);
+}
+
+.v-deco .lamp {
+ position: absolute;
+ bottom: 50%; left: 22%;
+ width: 8%; height: 28%;
+}
+
+.v-deco .lamp-shade {
+ position: absolute;
+ top: 0; left: 50%;
+ transform: translateX(-50%);
+ width: 100%; height: 40%;
+ background: linear-gradient(180deg, #f0e6c8, #c9a961);
+ clip-path: polygon(10% 100%, 0 0, 100% 0, 90% 100%);
+ box-shadow: 0 0 20px rgba(201,169,97,0.4);
+}
+
+.v-deco .lamp-stem {
+ position: absolute;
+ top: 38%; left: 50%;
+ transform: translateX(-50%);
+ width: 3px; height: 50%;
+ background: #c9a961;
+}
+
+.v-deco .lamp-base {
+ position: absolute;
+ bottom: 0; left: 50%;
+ transform: translateX(-50%);
+ width: 70%; height: 12%;
+ background: #c9a961;
+ clip-path: polygon(0 100%, 15% 0, 85% 0, 100% 100%);
+}
+
+.v-deco .lamp-r { left: auto; right: 22%; }
+
+.v-deco .steps {
+ position: absolute;
+ right: 6%; top: 18%;
+ width: 16%; height: 40%;
+}
+
+.v-deco .step {
+ position: absolute;
+ right: 0;
+ background: linear-gradient(90deg, #1a3040, #0f1e28);
+ border: 1px solid rgba(201,169,97,0.3);
+}
+
+.v-deco .step:nth-child(1) { top: 0; width: 40%; height: 22%; }
+.v-deco .step:nth-child(2) { top: 22%; width: 65%; height: 22%; }
+.v-deco .step:nth-child(3) { top: 44%; width: 90%; height: 22%; }
+.v-deco .step:nth-child(4) { top: 66%; width: 100%; height: 28%; background: linear-gradient(90deg, #c9a96144, #1a3040); }
+
+/* —— Mid-Century Modern —— */
+.v-mcm {
+ background: linear-gradient(180deg, #e8dcc8 0%, #d4c4a8 100%);
+}
+
+.v-mcm .wall {
+ position: absolute;
+ inset: 0 0 34% 0;
+ background:
+ linear-gradient(180deg, #c8b89a 0%, #d4c4a8 100%);
+}
+
+/* Atomic / starburst wall art */
+.v-mcm .atomic {
+ position: absolute;
+ top: 12%; left: 50%;
+ transform: translateX(-50%);
+ width: 120px; height: 120px;
+}
+
+.v-mcm .atomic::before,
+.v-mcm .atomic::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ border: 2px solid #c45c26;
+ border-radius: 50%;
+}
+
+.v-mcm .atomic::before { transform: scaleX(0.35) rotate(30deg); }
+.v-mcm .atomic::after { transform: scaleX(0.35) rotate(-30deg); }
+
+.v-mcm .atomic-core {
+ position: absolute;
+ top: 50%; left: 50%;
+ transform: translate(-50%, -50%);
+ width: 14px; height: 14px;
+ background: #2a6b6b;
+ border-radius: 50%;
+ box-shadow:
+ 0 0 0 40px transparent,
+ 48px -20px 0 -4px #c45c26,
+ -48px 20px 0 -4px #c45c26,
+ -20px -48px 0 -4px #e8a838,
+ 20px 48px 0 -4px #e8a838,
+ 0 -55px 0 -5px #2a6b6b,
+ 0 55px 0 -5px #2a6b6b;
+}
+
+.v-mcm .floor {
+ position: absolute;
+ left: 0; right: 0; bottom: 0;
+ height: 34%;
+ background:
+ repeating-linear-gradient(90deg,
+ #8b6914 0px, #a07828 3px, #8b6914 8px, #6b5010 12px, #8b6914 18px);
+ box-shadow: inset 0 8px 24px rgba(0,0,0,0.15);
+}
+
+.v-mcm .sofa {
+ position: absolute;
+ left: 50%; bottom: 28%;
+ transform: translateX(-50%);
+ width: 48%; height: 28%;
+}
+
+.v-mcm .sofa-body {
+ position: absolute;
+ left: 5%; right: 5%; bottom: 8%;
+ height: 55%;
+ background: #2a6b6b;
+ border-radius: 8px 8px 2px 2px;
+}
+
+.v-mcm .sofa-back {
+ position: absolute;
+ left: 8%; right: 8%; top: 0;
+ height: 50%;
+ background: #245c5c;
+ border-radius: 40% 40% 0 0 / 60% 60% 0 0;
+}
+
+.v-mcm .sofa-leg {
+ position: absolute;
+ bottom: 0;
+ width: 3px; height: 18%;
+ background: #3d2810;
+ transform: skewX(-12deg);
+}
+
+.v-mcm .sofa-leg.l { left: 12%; }
+.v-mcm .sofa-leg.r { right: 12%; transform: skewX(12deg); }
+
+.v-mcm .sofa-cushion {
+ position: absolute;
+ bottom: 30%; left: 12%;
+ width: 28%; height: 22%;
+ background: #e8a838;
+ border-radius: 4px;
+}
+
+.v-mcm .sofa-cushion.r { left: auto; right: 12%; background: #c45c26; }
+
+.v-mcm .plant {
+ position: absolute;
+ bottom: 32%; right: 10%;
+ width: 10%; height: 30%;
+}
+
+.v-mcm .plant-pot {
+ position: absolute;
+ bottom: 0; left: 20%; right: 20%;
+ height: 28%;
+ background: #c45c26;
+ clip-path: polygon(10% 0, 90% 0, 100% 100%, 0 100%);
+}
+
+.v-mcm .plant-leaf {
+ position: absolute;
+ bottom: 24%;
+ width: 40%; height: 50%;
+ background: #2d6a4f;
+ border-radius: 0 80% 0 80%;
+}
+
+.v-mcm .plant-leaf:nth-child(1) { left: 10%; transform: rotate(-30deg); }
+.v-mcm .plant-leaf:nth-child(2) { left: 30%; height: 70%; background: #40916c; transform: rotate(5deg); border-radius: 80% 0 80% 0; }
+.v-mcm .plant-leaf:nth-child(3) { right: 10%; transform: rotate(35deg); }
+
+.v-mcm .side-table {
+ position: absolute;
+ bottom: 32%; left: 12%;
+ width: 12%; height: 18%;
+}
+
+.v-mcm .side-table-top {
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 12%;
+ background: #5c4030;
+ border-radius: 50%;
+ box-shadow: 0 2px 0 #3d2810;
+}
+
+.v-mcm .side-table-leg {
+ position: absolute;
+ top: 10%; left: 50%;
+ width: 2px; height: 90%;
+ background: #3d2810;
+ transform: translateX(-50%);
+}
+
+.v-mcm .boomerang {
+ position: absolute;
+ top: 20%; left: 12%;
+ width: 70px; height: 40px;
+ border: 3px solid #2a6b6b;
+ border-radius: 50% 50% 50% 0;
+ transform: rotate(-25deg);
+ opacity: 0.5;
+}
+
+.v-mcm .window-mcm {
+ position: absolute;
+ top: 10%; right: 8%;
+ width: 18%; height: 40%;
+ background: linear-gradient(180deg, #87a8b8 0%, #b8d0d8 100%);
+ border: 4px solid #5c4030;
+ box-shadow: inset 0 0 0 2px #d4c4a8;
+}
+
+.v-mcm .window-mcm::after {
+ content: '';
+ position: absolute;
+ left: 50%; top: 0; bottom: 0;
+ width: 3px;
+ background: #5c4030;
+ transform: translateX(-50%);
+}
+
+/* —— Grandmillennial —— */
+.v-grand {
+ background: #f5f0e8;
+}
+
+.v-grand .wall {
+ position: absolute;
+ inset: 0 0 30% 0;
+ background-color: #e8f0e8;
+ background-image:
+ radial-gradient(circle at 20% 30%, #d4a0a0 0 3px, transparent 4px),
+ radial-gradient(circle at 50% 20%, #7a9e7a 0 2px, transparent 3px),
+ radial-gradient(circle at 70% 45%, #c48b9f 0 3px, transparent 4px),
+ radial-gradient(circle at 35% 60%, #d4a0a0 0 2px, transparent 3px),
+ radial-gradient(circle at 80% 25%, #7a9e7a 0 3px, transparent 4px),
+ radial-gradient(circle at 15% 70%, #a8c4a8 0 4px, transparent 5px),
+ radial-gradient(circle at 55% 75%, #c48b9f 0 2px, transparent 3px),
+ radial-gradient(circle at 90% 60%, #d4a0a0 0 3px, transparent 4px),
+ radial-gradient(circle at 40% 40%, #e8c4a0 0 2px, transparent 3px),
+ /* leaf shapes via elongated ellipses */
+ radial-gradient(ellipse 6px 3px at 25% 50%, #6b8f6b 0 100%, transparent 100%),
+ radial-gradient(ellipse 5px 2px at 60% 35%, #6b8f6b 0 100%, transparent 100%),
+ radial-gradient(ellipse 6px 3px at 75% 70%, #8f6b7a 0 100%, transparent 100%);
+ background-size: 64px 72px;
+}
+
+.v-grand .chair-rail {
+ position: absolute;
+ left: 0; right: 0; bottom: 30%;
+ height: 3px;
+ background: #5a7a8a;
+ box-shadow: 0 -1px 0 #8a9aaa, 0 8px 0 #f0e8d8;
+}
+
+.v-grand .wainscot-g {
+ position: absolute;
+ left: 0; right: 0; bottom: 30%;
+ height: 14%;
+ background:
+ repeating-linear-gradient(90deg,
+ #f0e8d8 0 48px,
+ #e8e0d0 48px 49px),
+ linear-gradient(180deg, #f5efe4, #ebe3d4);
+ border-top: 3px solid transparent;
+}
+
+.v-grand .floor {
+ position: absolute;
+ left: 0; right: 0; bottom: 0;
+ height: 30%;
+ background:
+ repeating-linear-gradient(90deg,
+ #c4a882 0px, #d4bc9a 20px, #c4a882 40px);
+ box-shadow: inset 0 6px 20px rgba(80,50,20,0.12);
+}
+
+.v-grand .sofa-g {
+ position: absolute;
+ left: 50%; bottom: 26%;
+ transform: translateX(-50%);
+ width: 50%; height: 32%;
+}
+
+.v-grand .sofa-g-body {
+ position: absolute;
+ left: 0; right: 0; bottom: 10%;
+ height: 50%;
+ background: #5a7a8a;
+ border-radius: 6px 6px 0 0;
+ /* skirt */
+ box-shadow: 0 14px 0 #4a6a7a;
+}
+
+.v-grand .sofa-g-body::after {
+ content: '';
+ position: absolute;
+ left: 0; right: 0; bottom: -14px;
+ height: 14px;
+ background:
+ repeating-linear-gradient(90deg,
+ #4a6a7a 0 8px, #3a5a6a 8px 10px);
+ /* pleated skirt suggestion */
+ clip-path: polygon(0 0, 100% 0, 100% 100%, 96% 70%, 92% 100%, 88% 70%, 84% 100%, 80% 70%, 76% 100%, 72% 70%, 68% 100%, 64% 70%, 60% 100%, 56% 70%, 52% 100%, 48% 70%, 44% 100%, 40% 70%, 36% 100%, 32% 70%, 28% 100%, 24% 70%, 20% 100%, 16% 70%, 12% 100%, 8% 70%, 4% 100%, 0 70%);
+}
+
+.v-grand .sofa-g-back {
+ position: absolute;
+ left: 4%; right: 4%; top: 5%;
+ height: 48%;
+ background: #6a8a9a;
+ border-radius: 50% 50% 0 0 / 30% 30% 0 0;
+ border: 2px solid #4a6a7a;
+}
+
+.v-grand .pillow {
+ position: absolute;
+ bottom: 38%;
+ width: 16%; height: 22%;
+ border-radius: 4px;
+}
+
+.v-grand .pillow.p1 { left: 10%; background: #c48b9f; }
+.v-grand .pillow.p2 { left: 28%; background: #d4a060; transform: rotate(-4deg); }
+.v-grand .pillow.p3 { right: 28%; background: #e8d5a0; transform: rotate(3deg); }
+.v-grand .pillow.p4 { right: 10%; background: #7a9e7a; }
+
+.v-grand .ottoman {
+ position: absolute;
+ left: 50%; bottom: 22%;
+ transform: translateX(-50%);
+ width: 16%; height: 12%;
+ background: #c48b9f;
+ border-radius: 4px;
+ box-shadow: 0 6px 0 #a86b7f;
+}
+
+.v-grand .lamp-g {
+ position: absolute;
+ bottom: 30%; left: 8%;
+ width: 10%; height: 36%;
+}
+
+.v-grand .lamp-g-shade {
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 35%;
+ background: #f5efe4;
+ border: 1px solid #d4c4a8;
+ border-radius: 4px 4px 2px 2px;
+ box-shadow: inset 0 0 12px rgba(255,240,200,0.5);
+}
+
+.v-grand .lamp-g-base {
+ position: absolute;
+ top: 34%; left: 35%; right: 35%;
+ bottom: 8%;
+ background: linear-gradient(180deg, #e8e4dc, #c8c0b0);
+ border-radius: 40% 40% 20% 20%;
+ border: 1px solid #b0a890;
+}
+
+.v-grand .lamp-g-foot {
+ position: absolute;
+ bottom: 0; left: 20%; right: 20%;
+ height: 10%;
+ background: #8a7a60;
+ border-radius: 2px;
+}
+
+.v-grand .frame-art {
+ position: absolute;
+ top: 12%; right: 14%;
+ width: 14%; height: 28%;
+ background: #d4e0d4;
+ border: 4px solid #c9a961;
+ box-shadow: 2px 2px 0 #8a6e32, inset 0 0 0 3px #f5efe4;
+}
+
+.v-grand .frame-art::before {
+ content: '';
+ position: absolute;
+ inset: 12%;
+ background:
+ radial-gradient(ellipse at 50% 70%, #7a9e7a 0 20%, transparent 21%),
+ radial-gradient(circle at 30% 40%, #c48b9f 0 8%, transparent 9%),
+ radial-gradient(circle at 70% 35%, #d4a060 0 6%, transparent 7%),
+ linear-gradient(180deg, #b8d0e0 0%, #d4e8d4 100%);
+}
+
+.v-grand .frame-art-2 {
+ position: absolute;
+ top: 18%; right: 30%;
+ width: 10%; height: 18%;
+ background: #e8d8c8;
+ border: 3px solid #5a7a8a;
+ box-shadow: 1px 1px 0 #3a5a6a;
+}
+
+/* —— Guess buttons —— */
+.guesses {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 12px;
+ margin-bottom: 8px;
+}
+
+@media (min-width: 640px) {
+ .guesses { grid-template-columns: repeat(4, 1fr); }
+}
+
+.guess-btn {
+ appearance: none;
+ border: 1px solid var(--line-strong);
+ background: var(--surface);
+ color: var(--ink);
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ padding: 16px 12px;
+ cursor: pointer;
+ transition: border-color 0.3s var(--ease), background 0.3s var(--ease), color 0.3s var(--ease), transform 0.3s var(--ease);
+ position: relative;
+}
+
+.guess-btn:hover:not(:disabled) {
+ border-color: var(--accent);
+ background: var(--accent-soft);
+ transform: translateY(-1px);
+}
+
+.guess-btn:disabled {
+ cursor: default;
+ opacity: 0.55;
+}
+
+.guess-btn.correct {
+ border-color: var(--accent-deep);
+ background: var(--accent-soft);
+ color: var(--accent-deep);
+ opacity: 1;
+ box-shadow: inset 0 0 0 1px var(--accent);
+}
+
+.guess-btn.wrong {
+ border-color: rgba(140, 40, 40, 0.35);
+ background: rgba(140, 40, 40, 0.06);
+ color: #6a3030;
+ opacity: 1;
+}
+
+/* —— Fact panel —— */
+.fact-panel {
+ max-height: 0;
+ overflow: hidden;
+ opacity: 0;
+ transition: max-height 0.55s var(--ease), opacity 0.45s var(--ease), margin 0.4s var(--ease), padding 0.4s var(--ease);
+ border: 1px solid transparent;
+ margin-top: 0;
+ padding: 0 24px;
+ background: var(--surface);
+}
+
+.fact-panel.show {
+ max-height: 220px;
+ opacity: 1;
+ margin-top: 20px;
+ padding: 22px 24px;
+ border-color: var(--line);
+ box-shadow: var(--shadow);
+}
+
+.fact-panel .result-line {
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ margin-bottom: 8px;
+}
+
+.fact-panel .result-line.ok { color: var(--accent-deep); }
+.fact-panel .result-line.no { color: #8a4040; }
+
+.fact-panel h3 {
+ font-family: var(--serif);
+ font-size: 28px;
+ font-weight: 400;
+ letter-spacing: -0.01em;
+ margin-bottom: 8px;
+ color: var(--ink);
+}
+
+.fact-panel p {
+ font-size: 15px;
+ color: var(--ink-soft);
+ line-height: 1.65;
+ max-width: 62ch;
+}
+
+.fact-actions {
+ margin-top: 16px;
+ display: flex;
+ justify-content: flex-end;
+}
+
+.btn {
+ appearance: none;
+ border: 1px solid var(--ink);
+ background: var(--ink);
+ color: var(--bg);
+ font-family: var(--sans);
+ font-size: 11px;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ padding: 14px 28px;
+ cursor: pointer;
+ transition: background 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease), transform 0.3s var(--ease);
+}
+
+.btn:hover {
+ background: var(--accent-deep);
+ border-color: var(--accent-deep);
+ transform: translateY(-1px);
+}
+
+.btn-ghost {
+ background: transparent;
+ color: var(--ink);
+ border-color: var(--line-strong);
+}
+
+.btn-ghost:hover {
+ border-color: var(--ink);
+ background: transparent;
+ color: var(--ink);
+}
+
+/* —— Overlay —— */
+.overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 200;
+ background: rgba(28, 26, 23, 0.48);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24px;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.45s var(--ease);
+}
+
+.overlay.open {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.modal {
+ background: var(--surface);
+ border: 1px solid var(--line);
+ box-shadow: var(--shadow-lg);
+ max-width: 440px;
+ width: 100%;
+ padding: 48px 40px;
+ text-align: center;
+ transform: translateY(12px) scale(0.98);
+ transition: transform 0.5s var(--ease-out);
+}
+
+.overlay.open .modal {
+ transform: translateY(0) scale(1);
+}
+
+.modal .eyebrow { margin-bottom: 12px; }
+
+.modal h2 {
+ font-family: var(--serif);
+ font-size: clamp(28px, 4vw, 38px);
+ font-weight: 400;
+ letter-spacing: -0.02em;
+ line-height: 1.15;
+ margin-bottom: 12px;
+ color: var(--ink);
+}
+
+.modal .score-big {
+ font-family: var(--serif);
+ font-size: 67px;
+ line-height: 1;
+ color: var(--accent-deep);
+ margin: 20px 0 8px;
+ letter-spacing: -0.03em;
+}
+
+.modal .score-sub {
+ font-size: 12px;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-bottom: 28px;
+}
+
+.modal p {
+ color: var(--ink-soft);
+ font-size: 15px;
+ margin-bottom: 28px;
+ line-height: 1.65;
+}
+
+.modal .btn-row {
+ display: flex;
+ gap: 12px;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+/* —— Progress dots —— */
+.progress {
+ display: flex;
+ gap: 6px;
+ justify-content: center;
+ margin-top: 32px;
+}
+
+.progress span {
+ width: 6px; height: 6px;
+ border-radius: 50%;
+ background: var(--line-strong);
+ transition: background 0.3s var(--ease), transform 0.3s var(--ease);
+}
+
+.progress span.done { background: var(--accent); }
+.progress span.current { background: var(--ink); transform: scale(1.35); }
+
+/* start hidden until ready */
+.game-ui { display: none; }
+.game-ui.ready { display: block; }
+
+.hidden { display: none !important; }
+</style>
+</head>
+<body>
+
+<header class="site-header">
+ <div class="wordmark">Designer Wallcoverings</div>
+ <div class="header-meta">
+ <span>Round <strong id="roundNum">1</strong> / 8</span>
+ <span>Score <strong id="scoreNum">0</strong></span>
+ <span>Best <strong id="bestNum">0</strong></span>
+ </div>
+</header>
+
+<main>
+ <div class="intro">
+ <div class="eyebrow">A connoisseur’s quiz</div>
+ <h1>Which Design Era?</h1>
+ <p class="lede">Study the interior vignette. Name the era. Eight rooms. One refined eye.</p>
+ </div>
+
+ <div class="game-ui" id="gameUi">
+ <div class="stage">
+ <div class="stage-label">
+ <span>Interior study</span>
+ <span id="stageHint">Select an era below</span>
+ </div>
+ <div class="vignette-frame" id="frame">
+ <!-- Victorian -->
+ <div class="vignette v-victorian" data-era="victorian">
+ <div class="wall"></div>
+ <div class="drape-l"></div>
+ <div class="drape-r"></div>
+ <div class="chandelier"></div>
+ <div class="wainscot"></div>
+ <div class="floor"></div>
+ <div class="mantel">
+ <div class="mirror"></div>
+ <div class="mantel-shelf"></div>
+ <div class="mantel-body">
+ <div class="mantel-opening"></div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Art Deco -->
+ <div class="vignette v-deco" data-era="deco">
+ <div class="wall"></div>
+ <div class="chevrons"></div>
+ <div class="sunburst"></div>
+ <div class="steps">
+ <div class="step"></div>
+ <div class="step"></div>
+ <div class="step"></div>
+ <div class="step"></div>
+ </div>
+ <div class="floor"></div>
+ <div class="lamp">
+ <div class="lamp-shade"></div>
+ <div class="lamp-stem"></div>
+ <div class="lamp-base"></div>
+ </div>
+ <div class="lamp lamp-r">
+ <div class="lamp-shade"></div>
+ <div class="lamp-stem"></div>
+ <div class="lamp-base"></div>
+ </div>
+ <div class="console">
+ <div class="console-top"></div>
+ <div class="console-body"></div>
+ </div>
+ </div>
+
+ <!-- Mid-Century Modern -->
+ <div class="vignette v-mcm" data-era="mcm">
+ <div class="wall"></div>
+ <div class="boomerang"></div>
+ <div class="window-mcm"></div>
+ <div class="atomic"><div class="atomic-core"></div></div>
+ <div class="floor"></div>
+ <div class="side-table">
+ <div class="side-table-top"></div>
+ <div class="side-table-leg"></div>
+ </div>
+ <div class="sofa">
+ <div class="sofa-back"></div>
+ <div class="sofa-body"></div>
+ <div class="sofa-cushion"></div>
+ <div class="sofa-cushion r"></div>
+ <div class="sofa-leg l"></div>
+ <div class="sofa-leg r"></div>
+ </div>
+ <div class="plant">
+ <div class="plant-leaf"></div>
+ <div class="plant-leaf"></div>
+ <div class="plant-leaf"></div>
+ <div class="plant-pot"></div>
+ </div>
+ </div>
+
+ <!-- Grandmillennial -->
+ <div class="vignette v-grand" data-era="grand">
+ <div class="wall"></div>
+ <div class="frame-art"></div>
+ <div class="frame-art-2"></div>
+ <div class="chair-rail"></div>
+ <div class="wainscot-g"></div>
+ <div class="floor"></div>
+ <div class="lamp-g">
+ <div class="lamp-g-shade"></div>
+ <div class="lamp-g-base"></div>
+ <div class="lamp-g-foot"></div>
+ </div>
+ <div class="sofa-g">
+ <div class="sofa-g-back"></div>
+ <div class="sofa-g-body"></div>
+ <div class="pillow p1"></div>
+ <div class="pillow p2"></div>
+ <div class="pillow p3"></div>
+ <div class="pillow p4"></div>
+ </div>
+ <div class="ottoman"></div>
+ </div>
+ </div>
+ </div>
+
+ <div class="guesses" id="guesses">
+ <button type="button" class="guess-btn" data-guess="victorian">Victorian</button>
+ <button type="button" class="guess-btn" data-guess="deco">Art Deco</button>
+ <button type="button" class="guess-btn" data-guess="mcm">Mid-Century</button>
+ <button type="button" class="guess-btn" data-guess="grand">Grandmillennial</button>
+ </div>
+
+ <div class="fact-panel" id="factPanel">
+ <div class="result-line" id="resultLine"></div>
+ <h3 id="factTitle"></h3>
+ <p id="factBody"></p>
+ <div class="fact-actions">
+ <button type="button" class="btn" id="nextBtn">Next Room</button>
+ </div>
+ </div>
+
+ <div class="progress" id="progress"></div>
+ </div>
+</main>
+
+<!-- Start overlay -->
+<div class="overlay open" id="startOverlay">
+ <div class="modal">
+ <div class="eyebrow">Designer Wallcoverings</div>
+ <h2>Which Design Era?</h2>
+ <p>Eight carefully composed rooms. Each belongs to one of four eras. Trust your eye for pattern, silhouette, and finish.</p>
+ <div class="btn-row">
+ <button type="button" class="btn" id="startBtn">Begin</button>
+ </div>
+ </div>
+</div>
+
+<!-- End overlay -->
+<div class="overlay" id="endOverlay">
+ <div class="modal">
+ <div class="eyebrow" id="endEyebrow">Collection complete</div>
+ <h2 id="endTitle">Your eye, scored</h2>
+ <div class="score-big" id="endScore">0</div>
+ <div class="score-sub" id="endSub">of 8 correct</div>
+ <p id="endCopy">A polished finish.</p>
+ <div class="btn-row">
+ <button type="button" class="btn" id="restartBtn">Play Again</button>
+ </div>
+ </div>
+</div>
+
+<script>
+(function () {
+ const ERAS = {
+ victorian: {
+ name: 'Victorian',
+ fact: 'Victorian interiors reveled in ornament: damask walls, dark woods, layered drapery, and gaslight glitter. Abundance signaled taste and prosperity.'
+ },
+ deco: {
+ name: 'Art Deco',
+ fact: 'Art Deco (1920s–30s) favored geometry, sunbursts, stepped forms, and high-contrast metallics—modern glamour after the Great War.'
+ },
+ mcm: {
+ name: 'Mid-Century Modern',
+ fact: 'Mid-century modern stripped away fuss for clean lines, tapered legs, organic curves, and honest materials like teak, wool, and glass.'
+ },
+ grand: {
+ name: 'Grandmillennial',
+ fact: 'Grandmillennial style reclaims chintz, skirted sofas, blue-and-white china, and collected charm—heritage warmth with a knowing wink.'
+ }
+ };
+
+ const TOTAL = 8;
+ const KEYS = Object.keys(ERAS);
+
+ let round = 0;
+ let score = 0;
+ let sequence = [];
+ let locked = false;
+ let best = 0;
+
+ const $ = (id) => document.getElementById(id);
+ const roundNum = $('roundNum');
+ const scoreNum = $('scoreNum');
+ const bestNum = $('bestNum');
+ const gameUi = $('gameUi');
+ const factPanel = $('factPanel');
+ const resultLine = $('resultLine');
+ const factTitle = $('factTitle');
+ const factBody = $('factBody');
+ const nextBtn = $('nextBtn');
+ const stageHint = $('stageHint');
+ const progress = $('progress');
+ const guessBtns = Array.from(document.querySelectorAll('.guess-btn'));
+ const vignettes = Array.from(document.querySelectorAll('.vignette'));
+ const startOverlay = $('startOverlay');
+ const endOverlay = $('endOverlay');
+
+ try {
+ best = parseInt(localStorage.getItem('dw-era-best') || '0', 10) || 0;
+ } catch (e) { best = 0; }
+ bestNum.textContent = best;
+
+ function shuffle(arr) {
+ const a = arr.slice();
+ for (let i = a.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [a[i], a[j]] = [a[j], a[i]];
+ }
+ return a;
+ }
+
+ function buildSequence() {
+ // Balanced: two of each era across 8 rounds, shuffled
+ const base = KEYS.concat(KEYS);
+ return shuffle(base);
+ }
+
+ function renderProgress() {
+ progress.innerHTML = '';
+ for (let i = 0; i < TOTAL; i++) {
+ const s = document.createElement('span');
+ if (i < round) s.classList.add('done');
+ if (i === round) s.classList.add('current');
+ progress.appendChild(s);
+ }
+ }
+
+ function showVignette(era) {
+ vignettes.forEach(v => {
+ v.classList.toggle('active', v.getAttribute('data-era') === era);
+ });
+ }
+
+ function resetButtons() {
+ guessBtns.forEach(b => {
+ b.disabled = false;
+ b.classList.remove('correct', 'wrong');
+ });
+ }
+
+ function startRound() {
+ locked = false;
+ factPanel.classList.remove('show');
+ resetButtons();
+ stageHint.textContent = 'Select an era below';
+ roundNum.textContent = String(round + 1);
+ scoreNum.textContent = String(score);
+ renderProgress();
+ showVignette(sequence[round]);
+ }
+
+ function onGuess(guess) {
+ if (locked) return;
+ locked = true;
+ const answer = sequence[round];
+ const correct = guess === answer;
+
+ guessBtns.forEach(b => {
+ b.disabled = true;
+ const g = b.getAttribute('data-guess');
+ if (g === answer) b.classList.add('correct');
+ else if (g === guess && !correct) b.classList.add('wrong');
+ });
+
+ if (correct) {
+ score += 1;
+ scoreNum.textContent = String(score);
+ resultLine.textContent = 'Correct';
+ resultLine.className = 'result-line ok';
+ } else {
+ resultLine.textContent = 'Not quite';
+ resultLine.className = 'result-line no';
+ }
+
+ factTitle.textContent = ERAS[answer].name;
+ factBody.textContent = ERAS[answer].fact;
+ stageHint.textContent = correct ? 'Well seen' : 'The reveal';
+ nextBtn.textContent = round >= TOTAL - 1 ? 'See Results' : 'Next Room';
+
+ // trigger reflow for transition
+ void factPanel.offsetWidth;
+ factPanel.classList.add('show');
+ }
+
+ function next() {
+ if (round >= TOTAL - 1) {
+ finish();
+ return;
+ }
+ round += 1;
+ startRound();
+ }
+
+ function finish() {
+ renderProgress();
+ let isNewBest = false;
+ if (score > best) {
+ best = score;
+ isNewBest = true;
+ try { localStorage.setItem('dw-era-best', String(best)); } catch (e) {}
+ bestNum.textContent = best;
+ }
+
+ $('endScore').textContent = String(score);
+ $('endSub').textContent = 'of 8 correct' + (isNewBest ? ' · new best' : (best ? ' · best ' + best : ''));
+
+ let title, copy, eye;
+ if (score >= 8) {
+ eye = 'Mastery';
+ title = 'Impeccable eye';
+ copy = 'Every room placed. You read pattern, proportion, and period like a seasoned decorator.';
+ } else if (score >= 6) {
+ eye = 'Refined';
+ title = 'A discerning finish';
+ copy = 'Strong instincts. A little more time with archives and you will be unassailable.';
+ } else if (score >= 4) {
+ eye = 'Developing';
+ title = 'A solid foundation';
+ copy = 'You catch the big gestures. Study the details—legs, metals, motifs—and the eras will separate cleanly.';
+ } else {
+ eye = 'Beginner';
+ title = 'The eye is training';
+ copy = 'Eras blur at first. Play again and let damask, sunburst, teak, and chintz settle into memory.';
+ }
+ $('endEyebrow').textContent = eye;
+ $('endTitle').textContent = title;
+ $('endCopy').textContent = copy;
+ endOverlay.classList.add('open');
+ }
+
+ function beginGame() {
+ sequence = buildSequence();
+ round = 0;
+ score = 0;
+ scoreNum.textContent = '0';
+ gameUi.classList.add('ready');
+ startOverlay.classList.remove('open');
+ endOverlay.classList.remove('open');
+ startRound();
+ }
+
+ guessBtns.forEach(b => {
+ b.addEventListener('click', () => onGuess(b.getAttribute('data-guess')));
+ });
+ nextBtn.addEventListener('click', next);
+ $('startBtn').addEventListener('click', beginGame);
+ $('restartBtn').addEventListener('click', beginGame);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/grok.png b/data/artifacts/6f651f004b4c/grok.png
new file mode 100644
index 0000000..82e2198
Binary files /dev/null and b/data/artifacts/6f651f004b4c/grok.png differ
diff --git a/data/artifacts/6f651f004b4c/hermes3-8b.html b/data/artifacts/6f651f004b4c/hermes3-8b.html
new file mode 100644
index 0000000..0b33f5e
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/hermes3-8b.html
@@ -0,0 +1,238 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Which Design Era?</title>
+<style>
+:root {
+ --bg: #0d0d0f;
+ --surface: #17171c;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --line: #7d6a45;
+ --shadow: rgba(0,0,0,.12);
+ --ease: cubic-bezier(.22,1,.36,1);
+}
+
+body {
+ background-color: var(--bg);
+ color: var(--text);
+ display: flex;
+ flex-direction: column;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 16px;
+ line-height: 1.5;
+}
+
+h1 {
+ background-color: var(--surface);
+ color: inherit;
+ display: flex;
+ font-family: Didot, Bodoni MT, Playfair Display, Georgia, serif;
+ font-size: 50px;
+ letter-spacing: .18em;
+ margin: 0 auto;
+}
+
+header {
+ background-color: var(--surface);
+ color: var(--text);
+ display: flex;
+ font-family: Didot, Bodoni MT, Playfair Display, Georgia, serif;
+ font-size: 50px;
+ letter-spacing: .18em;
+ padding: 16px;
+}
+
+button {
+ background-color: transparent;
+ border: 1px solid var(--line);
+ color: var(--text);
+ cursor: pointer;
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 14px;
+ letter-spacing: .15em;
+ margin: 0 auto;
+ padding: 8px 16px;
+ position: relative;
+ z-index: 2;
+}
+
+button::after {
+ background-color: var(--accent);
+ content: '';
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ transition: background-color .3s var(--ease);
+ width: 100%;
+ z-index: -1;
+}
+
+button:hover::after {
+ background-color: var(--accent)/*#7d6a45*/;
+}
+
+main {
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ gap: 48px;
+ justify-content: center;
+ margin: 96px auto;
+ max-width: 640px;
+ padding: 64px;
+ text-align: center;
+}
+
+section {
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: 0 8px 24px var(--shadow);
+ display: flex;
+ gap: 24px;
+ margin: auto;
+ max-width: calc(100vw - 32px);
+ padding: 32px;
+}
+
+img {
+ align-self: center;
+ border-radius: 50%;
+ box-shadow: 0 16px 48px rgba(0,0,0,.18);
+ display: block;
+ height: 128px;
+ width: 128px;
+}
+
+svg {
+ display: block;
+ fill: var(--text);
+ max-height: 100px;
+}
+
+@keyframes fadeUp {
+ from {opacity:0;transform:translateY(28px);}
+ to {opacity:1;transform:none;}
+}
+
+.fade-up {
+ animation: fadeUp .7s var(--ease) both;
+ opacity: 0;
+}
+
+.stagger {
+ animation: none;
+ transition: all .3s var(--ease);
+}
+
+.stagger:nth-child(odd) {
+ animation-duration: .7s;
+ animation-delay: 90ms;
+ animation-fill-mode: forwards;
+}
+
+/* Ambient background gradient drift */
+@keyframes bgDrift {
+ from {background-color: #17171c;}
+ to {background-color: #0d0d0f;}
+}
+
+body::before {
+ background-image: linear-gradient(var(--bg) 0%, var(--surface) 100%);
+ content: '';
+ height: 200%;
+ left: 0;
+ position: fixed;
+ top: -50%;
+ width: 100vw;
+ z-index: -2;
+}
+
+body::after {
+ background-color: var(--surface);
+ content: '';
+ height: 50%;
+ left: 0;
+ position: fixed;
+ top: 0;
+ width: 100vw;
+ z-index: -1;
+ animation: bgDrift 18s var(--ease) linear infinite;
+}
+
+@media (max-width:640px) {
+ header, h1, button, main, section {
+ max-width: 90vw;
+ margin: auto;
+ }
+}
+</style>
+<body>
+<header class="header">
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle fill='%231c1a17' r='50' /%3E%3C/svg%3E" alt="">
+ <h1>DESIGNER WALLCOVERINGS</h1>
+</header>
+
+<main class="main">
+ <button id="start">Start Game</button>
+
+ <div id="game">
+ <section class="section fade-up stagger">
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 150'%3E%3Crect x='20' y='70' width='60' height='40' /%3E%3Ccircle cx='50' cy='75' r='15' fill='%f5f2ea' stroke='%f5f2ea' stroke-width='1' /%3E%3Crect x='20' y='100' width='60' height='50' /%3E%3Ccircle cx='50' cy='130' r='15' fill='%17171c' stroke='%17171c' stroke-width='1' /%3E%3C/svg%3E" alt="Victorian vignette">
+ <p class="muted">Victorian</p>
+ </section>
+
+ <!-- More sections for other eras -->
+
+ <div id="scoreboard">
+ <span class="label">Score:</span>
+ <span id="score" class="score">0</span>
+ </div>
+ </div>
+
+ <button id="restart" class="fade-up stagger hidden">Restart</button>
+</main>
+
+<script>
+document.getElementById('start').addEventListener('click', startGame);
+document.getElementById('restart').addEventListener('click', startGame);
+
+function startGame() {
+ const scoreboard = document.getElementById('scoreboard');
+ scoreboard.classList.add('hidden');
+
+ const sections = Array.from(document.querySelectorAll('.section'));
+ const eraButtons = Array.from(document.querySelectorAll('button'));
+ eraButtons.forEach(button => button.classList.remove('hidden'));
+
+ let score = 0;
+
+ sections.forEach((section, index) => {
+ section.addEventListener('click', () => {
+ if (index == 0) {
+ score++;
+ document.getElementById('score').textContent = score;
+
+ // Show facts about the era
+ alert(`Fun fact about ${eraButtons[index].textContent}: ...`);
+
+ eraButtons.forEach(button => button.classList.add('hidden'));
+ scoreboard.classList.remove('hidden');
+
+ if (index == sections.length - 1) {
+ alert(`Congratulations! Your final score is ${score}.`);
+ }
+ } else {
+ // Alert the player for an incorrect guess
+ alert(`${eraButtons[index].textContent} is not correct. Try again.`);
+ }
+ });
+ });
+}
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/hermes3-8b.png b/data/artifacts/6f651f004b4c/hermes3-8b.png
new file mode 100644
index 0000000..1083357
Binary files /dev/null and b/data/artifacts/6f651f004b4c/hermes3-8b.png differ
diff --git a/data/artifacts/6f651f004b4c/hf-qwen-coder-32b.html b/data/artifacts/6f651f004b4c/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..4c7987e
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/hf-qwen-coder-32b.html
@@ -0,0 +1,300 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Which Design Era?</title>
+ <style>
+ :root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e;
+ --line: #e0e0e0;
+ --shadow: rgba(0, 0, 0, .12);
+ --glow: rgba(176, 71, 46, .35);
+ --ease: cubic-bezier(.22, 1, .36, 1);
+ }
+
+ body {
+ font-family: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ background-color: var(--bg);
+ color: var(--text);
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ font-size: 16px;
+ }
+
+ header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ background-color: var(--bg);
+ padding: 24px 32px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, .06);
+ z-index: 10;
+ }
+
+ header h1 {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 50px;
+ margin: 0;
+ letter-spacing: .18em;
+ text-transform: uppercase;
+ color: var(--text);
+ }
+
+ main {
+ padding-top: 128px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+ }
+
+ .card-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 24px;
+ margin-bottom: 32px;
+ width: 90%;
+ max-width: 800px;
+ }
+
+ .card {
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: 0 8px 24px var(--shadow);
+ transition: transform .15s ease, box-shadow .15s ease;
+ overflow: hidden;
+ position: relative;
+ }
+
+ .card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 16px 48px rgba(0, 0, 0, .18);
+ }
+
+ .card-content {
+ padding: 32px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .card::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(255, 255, 255, .08);
+ transition: opacity .3s ease;
+ }
+
+ .card:hover::after {
+ opacity: 0;
+ }
+
+ button {
+ font-family: 'Playfair Display', Georgia, serif;
+ font-size: 14px;
+ letter-spacing: .15em;
+ text-transform: uppercase;
+ background-color: var(--accent);
+ color: white;
+ border: none;
+ padding: 8px 24px;
+ cursor: pointer;
+ transition: background-color .3s ease, transform .3s ease;
+ margin-top: 16px;
+ }
+
+ button:hover {
+ background-color: #9b2c0f;
+ transform: translateY(-2px);
+ }
+
+ .overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, .75);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 20;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity .3s ease;
+ }
+
+ .overlay.active {
+ opacity: 1;
+ pointer-events: all;
+ }
+
+ .overlay-content {
+ background-color: var(--surface);
+ padding: 48px;
+ border-radius: 16px;
+ text-align: center;
+ box-shadow: 0 24px 32px rgba(0, 0, 0, .2);
+ animation: fadeUp .7s var(--ease) both;
+ }
+
+ .overlay-content h2 {
+ font-size: 38px;
+ margin-bottom: 16px;
+ }
+
+ .overlay-content p {
+ font-size: 18px;
+ color: var(--muted);
+ margin-bottom: 24px;
+ }
+
+ .overlay-content button {
+ background-color: #b0472e;
+ padding: 12px 32px;
+ border-radius: 8px;
+ font-size: 16px;
+ letter-spacing: .1em;
+ text-transform: uppercase;
+ }
+ </style>
+</head>
+<body>
+ <header>
+ <h1>DESIGNER WALLCOVERINGS</h1>
+ </header>
+ <main>
+ <div class="card-grid" id="eraGrid"></div>
+ <button onclick="restartGame()">RESTART GAME</button>
+ <div class="overlay" id="resultOverlay">
+ <div class="overlay-content">
+ <h2 id="resultTitle">ROUND OVER!</h2>
+ <p id="resultText">You guessed correctly! Here's a fun fact about the Victorian era: Victorians were known for their intricate and ornate designs in wallpaper, reflecting their love for luxury and tradition.</p>
+ <button onclick="closeOverlay()">CONTINUE</button>
+ </div>
+ </div>
+ </main>
+
+ <script>
+ const eras = [
+ { name: 'Victorian', style: 'background: linear-gradient(135deg, #a62f0c 0%, #9b2c0f 47%, #8e281d 100%);' },
+ { name: 'Art Deco', style: 'background: linear-gradient(to right, #ff5e62, #bf3f4a);' },
+ { name: 'Mid-Century Modern', style: 'background: linear-gradient(135deg, #c0d8dc 0%, #f9f6fb 100%);' },
+ { name: 'Grandmillennial', style: 'background: linear-gradient(to right, #ff7e5f, #feb47b);' }
+ ];
+
+ const eraFacts = {
+ Victorian: "Victorians were known for their intricate and ornate designs in wallpaper, reflecting their love for luxury and tradition.",
+ ArtDeco: "Art Deco era was characterized by bold geometric shapes and metallic accents, symbolizing modernity and progress.",
+ Mid_Century_Modern: "Mid-Century Modern style emphasized simplicity and functionality, using organic forms and vibrant colors.",
+ Grandmillennial: "Grandmillennial design blends classic elegance with modern flair, featuring rich textures and luxurious materials."
+ };
+
+ let score = 0;
+ let currentEraIndex;
+ let round = 1;
+
+ 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(era, index) {
+ const card = document.createElement('div');
+ card.className = 'card';
+ card.innerHTML = `
+ <div class="card-content" style="${era.style}"></div>
+ `;
+ card.addEventListener('click', () => checkAnswer(index));
+ return card;
+ }
+
+ function setupRound() {
+ shuffleArray(eras);
+ currentEraIndex = Math.floor(Math.random() * eras.length);
+
+ const eraGrid = document.getElementById('eraGrid');
+ eraGrid.innerHTML = '';
+
+ for (let i = 0; i < eras.length; i++) {
+ eraGrid.appendChild(createCard(eras[i], i));
+ }
+ }
+
+ function checkAnswer(selectedIndex) {
+ if (selectedIndex === currentEraIndex) {
+ score++;
+ showOverlay(true);
+ } else {
+ showOverlay(false);
+ }
+
+ round++;
+
+ if (round > 8) {
+ endGame();
+ } else {
+ setTimeout(setupRound, 1000);
+ }
+ }
+
+ function showOverlay(correct) {
+ const overlay = document.getElementById('resultOverlay');
+ const resultTitle = document.getElementById('resultTitle');
+ const resultText = document.getElementById('resultText');
+
+ if (correct) {
+ resultTitle.textContent = 'CORRECT!';
+ resultText.textContent = eraFacts[eras[currentEraIndex].name];
+ } else {
+ resultTitle.textContent = 'WRONG!';
+ resultText.textContent = `The correct answer was ${eras[currentEraIndex].name}. Here's a fun fact: ${eraFacts[eras[currentEraIndex].name]}`;
+ }
+
+ overlay.classList.add('active');
+ }
+
+ function closeOverlay() {
+ const overlay = document.getElementById('resultOverlay');
+ overlay.classList.remove('active');
+ }
+
+ function endGame() {
+ let bestScore = localStorage.getItem('bestScore') || 0;
+ if (score > bestScore) {
+ localStorage.setItem('bestScore', score);
+ bestScore = score;
+ }
+ const resultTitle = document.getElementById('resultTitle');
+ const resultText = document.getElementById('resultText');
+
+ resultTitle.textContent = 'GAME OVER!';
+ resultText.innerHTML = `Your final score is ${score}.<br>Your best score is ${bestScore}.`;
+ }
+
+ function restartGame() {
+ score = 0;
+ round = 1;
+ setupRound();
+ closeOverlay();
+ }
+
+ setupRound();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/hf-qwen-coder-32b.png b/data/artifacts/6f651f004b4c/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..5931575
Binary files /dev/null and b/data/artifacts/6f651f004b4c/hf-qwen-coder-32b.png differ
diff --git a/data/artifacts/6f651f004b4c/kimi.html b/data/artifacts/6f651f004b4c/kimi.html
new file mode 100644
index 0000000..4f315b9
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/kimi.html
@@ -0,0 +1,707 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>DESIGNER WALLCOVERINGS — Which Design Era?</title>
+<style>
+:root{
+ /* Design Tokens — luxe-noir palette */
+ --bg:#0d0d0f;
+ --surface:#17171c;
+ --text:#f5f2ea;
+ --muted:#8a8578;
+ --accent:#c9a961;
+ --accent2:#7d6a45;
+
+ /* Line and shadow */
+ --line:#2a2a30;
+ --shadow:rgba(0,0,0,0.4);
+
+ /* Typography — luxe-display stack */
+ --font-display:'Didot','Bodoni MT','Playfair Display',Georgia,serif;
+ --font-sans:-apple-system,'Segoe UI','Helvetica Neue',Arial,sans-serif;
+
+ /* Motion */
+ --ease:cubic-bezier(.22,1,.36,1);
+ --ease-bounce:cubic-bezier(.34,1.56,.64,1);
+}
+
+*{
+ margin:0;
+ padding:0;
+ box-sizing:border-box;
+}
+
+html{
+ font-size:16px;
+ background:var(--bg);
+ color:var(--text);
+}
+
+body{
+ font-family:var(--font-sans);
+ line-height:1.6;
+ min-height:100vh;
+ padding-top:100px;
+ background:var(--bg);
+}
+
+/* Fixed Header */
+header{
+ position:fixed;
+ top:0;
+ left:0;
+ right:0;
+ height:80px;
+ background:var(--surface);
+ border-bottom:1px solid var(--line);
+ display:flex;
+ align-items:center;
+ padding:0 40px;
+ z-index:100;
+ box-shadow:0 4px 24px var(--shadow);
+}
+
+.wordmark{
+ font-family:var(--font-display);
+ font-size:42px;
+ font-weight:400;
+ letter-spacing:0.18em;
+ text-transform:uppercase;
+ color:var(--text);
+ line-height:1.1;
+}
+
+/* Game Container */
+.game-container{
+ max-width:900px;
+ margin:0 auto;
+ padding:40px;
+}
+
+/* Scoreboard */
+.scoreboard{
+ display:flex;
+ justify-content:space-between;
+ align-items:center;
+ margin-bottom:48px;
+ padding:24px 0;
+ border-bottom:1px solid var(--line);
+}
+
+.score-item{
+ font-family:var(--font-sans);
+ font-size:12px;
+ letter-spacing:0.16em;
+ text-transform:uppercase;
+ color:var(--muted);
+}
+
+.score-item span{
+ color:var(--accent);
+ font-size:28px;
+ font-weight:300;
+ display:block;
+ margin-top:4px;
+ font-family:var(--font-display);
+}
+
+/* Room Vignette */
+.room-vignette{
+ width:100%;
+ aspect-ratio:4/3;
+ background:var(--surface);
+ border:1px solid var(--line);
+ border-radius:4px;
+ position:relative;
+ overflow:hidden;
+ margin-bottom:48px;
+ box-shadow:0 24px 48px var(--shadow);
+ animation:fadeUp 0.8s var(--ease) both;
+}
+
+/* Victorian Style */
+.room-vignette.victorian{
+ background:linear-gradient(135deg,#1a1512 0%,#2d1810 100%);
+}
+.room-vignette.victorian::before{
+ content:'';
+ position:absolute;
+ inset:0;
+ background:
+ repeating-linear-gradient(45deg,transparent,transparent 20px,rgba(201,169,97,0.08) 20px,rgba(201,169,97,0.08) 22px),
+ repeating-linear-gradient(-45deg,transparent,transparent 20px,rgba(201,169,97,0.05) 20px,rgba(201,169,97,0.05) 40px);
+}
+.room-vignette.victorian::after{
+ content:'';
+ position:absolute;
+ top:10%;
+ left:50%;
+ transform:translateX(-50%);
+ width:40%;
+ height:30%;
+ background:radial-gradient(ellipse at center,rgba(201,169,97,0.3) 0%,transparent 70%);
+ border:3px double rgba(201,169,97,0.4);
+ border-radius:50% 50% 0 0;
+}
+
+/* Art Deco Style */
+.room-vignette.art-deco{
+ background:linear-gradient(180deg,#1c1c24 0%,#0f0f14 100%);
+}
+.room-vignette.art-deco::before{
+ content:'';
+ position:absolute;
+ inset:0;
+ background:
+ linear-gradient(45deg,transparent 48%,rgba(201,169,97,0.2) 49%,rgba(201,169,97,0.2) 51%,transparent 52%),
+ linear-gradient(-45deg,transparent 48%,rgba(201,169,97,0.2) 49%,rgba(201,169,97,0.2) 51%,transparent 52%);
+ background-size:60px 60px;
+}
+.room-vignette.art-deco::after{
+ content:'';
+ position:absolute;
+ top:50%;
+ left:50%;
+ transform:translate(-50%,-50%);
+ width:200px;
+ height:200px;
+ background:
+ conic-gradient(from 0deg at 50% 50%,transparent 0deg,rgba(201,169,97,0.3) 20deg,transparent 40deg,rgba(201,169,97,0.3) 60deg,transparent 80deg,rgba(201,169,97,0.3) 100deg,transparent 120deg,rgba(201,169,97,0.3) 140deg,transparent 160deg,rgba(201,169,97,0.3) 180deg,transparent 200deg,rgba(201,169,97,0.3) 220deg,transparent 240deg,rgba(201,169,97,0.3) 260deg,transparent 280deg,rgba(201,169,97,0.3) 300deg,transparent 320deg,rgba(201,169,97,0.3) 340deg,transparent 360deg);
+ border-radius:50%;
+}
+
+/* Mid-Century Modern Style */
+.room-vignette.midcentury{
+ background:linear-gradient(135deg,#e8e4dc 0%,#d4cfc4 100%);
+}
+.room-vignette.midcentury::before{
+ content:'';
+ position:absolute;
+ inset:0;
+ background:
+ radial-gradient(circle at 30% 40%,rgba(201,169,97,0.15) 0%,transparent 50%),
+ radial-gradient(circle at 70% 60%,rgba(139,90,43,0.1) 0%,transparent 50%);
+}
+.room-vignette.midcentury::after{
+ content:'';
+ position:absolute;
+ bottom:20%;
+ left:10%;
+ right:10%;
+ height:40%;
+ background:
+ linear-gradient(90deg,transparent 0%,rgba(139,90,43,0.3) 20%,rgba(139,90,43,0.3) 80%,transparent 100%);
+ border-radius:50% 50% 0 0;
+ transform:scaleY(0.3);
+}
+
+/* Grandmillennial Style */
+.room-vignette.grandmillennial{
+ background:linear-gradient(135deg,#f5f2ea 0%,#ebe6dc 100%);
+}
+.room-vignette.grandmillennial::before{
+ content:'';
+ position:absolute;
+ inset:0;
+ background-image:url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23c9a961' fill-opacity='0.15'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
+}
+.room-vignette.grandmillennial::after{
+ content:'';
+ position:absolute;
+ top:15%;
+ left:50%;
+ transform:translateX(-50%);
+ width:120px;
+ height:160px;
+ background:linear-gradient(180deg,rgba(139,90,43,0.2) 0%,rgba(201,169,97,0.1) 100%);
+ border:2px solid rgba(201,169,97,0.3);
+ border-radius:60% 60% 45% 45%;
+}
+
+/* Era Label in corner */
+.era-hint{
+ position:absolute;
+ top:20px;
+ right:20px;
+ font-family:var(--font-sans);
+ font-size:11px;
+ letter-spacing:0.2em;
+ text-transform:uppercase;
+ color:var(--muted);
+ opacity:0.7;
+}
+
+/* Guess Buttons */
+.guess-grid{
+ display:grid;
+ grid-template-columns:repeat(4,1fr);
+ gap:16px;
+ margin-bottom:32px;
+}
+
+.guess-btn{
+ background:var(--surface);
+ border:1px solid var(--line);
+ padding:24px 16px;
+ cursor:pointer;
+ transition:all 0.3s var(--ease);
+ font-family:var(--font-sans);
+ font-size:11px;
+ letter-spacing:0.16em;
+ text-transform:uppercase;
+ color:var(--text);
+ position:relative;
+ overflow:hidden;
+}
+
+.guess-btn:hover{
+ border-color:var(--accent);
+ transform:translateY(-2px);
+ box-shadow:0 8px 24px var(--shadow);
+}
+
+.guess-btn:active{
+ transform:translateY(0);
+}
+
+.guess-btn.correct{
+ border-color:var(--accent);
+ background:rgba(201,169,97,0.1);
+ color:var(--accent);
+}
+
+.guess-btn.wrong{
+ border-color:#5c3a3a;
+ background:rgba(60,30,30,0.3);
+ opacity:0.6;
+}
+
+/* Reveal Panel */
+.reveal-panel{
+ background:var(--surface);
+ border:1px solid var(--line);
+ padding:32px;
+ margin-bottom:32px;
+ opacity:0;
+ transform:translateY(20px);
+ transition:all 0.5s var(--ease);
+ display:none;
+}
+
+.reveal-panel.active{
+ display:block;
+ opacity:1;
+ transform:translateY(0);
+}
+
+.reveal-title{
+ font-family:var(--font-display);
+ font-size:28px;
+ color:var(--accent);
+ margin-bottom:16px;
+ letter-spacing:0.04em;
+}
+
+.reveal-fact{
+ font-size:16px;
+ line-height:1.7;
+ color:var(--text);
+ margin-bottom:24px;
+}
+
+.next-btn{
+ background:transparent;
+ border:1px solid var(--accent);
+ color:var(--accent);
+ padding:16px 32px;
+ font-family:var(--font-sans);
+ font-size:12px;
+ letter-spacing:0.16em;
+ text-transform:uppercase;
+ cursor:pointer;
+ transition:all 0.3s var(--ease);
+}
+
+.next-btn:hover{
+ background:var(--accent);
+ color:var(--bg);
+}
+
+/* Overlay */
+.overlay{
+ position:fixed;
+ inset:0;
+ background:rgba(13,13,15,0.95);
+ display:none;
+ align-items:center;
+ justify-content:center;
+ z-index:200;
+ backdrop-filter:blur(8px);
+}
+
+.overlay.active{
+ display:flex;
+ animation:fadeUp 0.5s var(--ease) both;
+}
+
+.overlay-content{
+ text-align:center;
+ padding:48px;
+ max-width:500px;
+}
+
+.overlay-title{
+ font-family:var(--font-display);
+ font-size:48px;
+ color:var(--accent);
+ margin-bottom:24px;
+ letter-spacing:0.04em;
+}
+
+.overlay-score{
+ font-size:72px;
+ font-family:var(--font-display);
+ color:var(--text);
+ margin-bottom:16px;
+}
+
+.overlay-best{
+ color:var(--muted);
+ font-size:12px;
+ letter-spacing:0.16em;
+ text-transform:uppercase;
+ margin-bottom:48px;
+}
+
+.restart-btn{
+ background:var(--accent);
+ color:var(--bg);
+ border:none;
+ padding:20px 48px;
+ font-family:var(--font-sans);
+ font-size:12px;
+ letter-spacing:0.16em;
+ text-transform:uppercase;
+ cursor:pointer;
+ transition:all 0.3s var(--ease);
+}
+
+.restart-btn:hover{
+ transform:scale(1.05);
+ box-shadow:0 12px 32px rgba(201,169,97,0.3);
+}
+
+/* Animations */
+@keyframes fadeUp{
+ from{opacity:0;transform:translateY(28px)}
+ to{opacity:1;transform:none}
+}
+
+@keyframes scaleIn{
+ from{opacity:0;transform:scale(0.92)}
+ to{opacity:1;transform:scale(1)}
+}
+
+/* Round indicator */
+.round-indicator{
+ text-align:center;
+ margin-bottom:32px;
+ font-family:var(--font-sans);
+ font-size:12px;
+ letter-spacing:0.16em;
+ text-transform:uppercase;
+ color:var(--muted);
+}
+
+/* Responsive */
+@media(max-width:768px){
+ .wordmark{
+ font-size:32px;
+ }
+
+ .guess-grid{
+ grid-template-columns:repeat(2,1fr);
+ }
+
+ .room-vignette{
+ aspect-ratio:1/1;
+ }
+}
+
+/* Visual distinctiveness helpers for room contents */
+.room-content{
+ position:absolute;
+ inset:0;
+ pointer-events:none;
+}
+
+/* Victorian details */
+.victorian .room-content{
+ background:radial-gradient(circle at 50% 30%,rgba(139,90,43,0.3) 0%,transparent 40%);
+}
+.victorian .room-content::before{
+ content:'';
+ position:absolute;
+ bottom:0;
+ left:10%;
+ right:10%;
+ height:40%;
+ background:linear-gradient(180deg,rgba(60,40,30,0.5) 0%,transparent 100%);
+}
+
+/* Art Deco details */
+.art-deco .room-content{
+ background:linear-gradient(180deg,rgba(201,169,97,0.1) 0%,transparent 30%,transparent 70%,rgba(201,169,97,0.1) 100%);
+}
+.art-deco .room-content::before{
+ content:'';
+ position:absolute;
+ top:20%;
+ left:50%;
+ transform:translateX(-50%);
+ width:60%;
+ height:4px;
+ background:linear-gradient(90deg,transparent,rgba(201,169,97,0.5),transparent);
+}
+
+/* Mid-Century details */
+.midcentury .room-content{
+ background:linear-gradient(135deg,rgba(201,169,97,0.1) 0%,transparent 50%);
+}
+.midcentury .room-content::before{
+ content:'';
+ position:absolute;
+ bottom:15%;
+ left:20%;
+ width:30%;
+ height:8px;
+ background:rgba(139,90,43,0.4);
+ border-radius:4px;
+ transform:rotate(-5deg);
+}
+
+/* Grandmillennial details */
+.grandmillennial .room-content{
+ background:radial-gradient(ellipse at 30% 70%,rgba(201,169,97,0.15) 0%,transparent 50%);
+}
+.grandmillennial .room-content::before{
+ content:'';
+ position:absolute;
+ top:25%;
+ right:15%;
+ width:40px;
+ height:60px;
+ background:rgba(139,90,43,0.15);
+ border-radius:50%;
+ border:1px solid rgba(201,169,97,0.3);
+}
+</style>
+</head>
+<body>
+
+<header>
+ <div class="wordmark">Designer Wallcoverings</div>
+</header>
+
+<div class="game-container">
+ <div class="scoreboard">
+ <div class="score-item">
+ Score
+ <span id="score">0</span>
+ </div>
+ <div class="score-item">
+ Round
+ <span id="round">1/8</span>
+ </div>
+ <div class="score-item">
+ Best
+ <span id="best">0</span>
+ </div>
+ </div>
+
+ <div class="round-indicator" id="round-indicator">Round 1 of 8</div>
+
+ <div class="room-vignette" id="room-vignette">
+ <div class="room-content"></div>
+ </div>
+
+ <div class="reveal-panel" id="reveal-panel">
+ <div class="reveal-title" id="reveal-title">Victorian</div>
+ <div class="reveal-fact" id="reveal-fact">This era is known for ornate detail and dark woods.</div>
+ <button class="next-btn" id="next-btn">Next Room</button>
+ </div>
+
+ <div class="guess-grid" id="guess-grid">
+ <button class="guess-btn" data-era="victorian">Victorian</button>
+ <button class="guess-btn" data-era="art-deco">Art Deco</button>
+ <button class="guess-btn" data-era="midcentury">Mid-Century Modern</button>
+ <button class="guess-btn" data-era="grandmillennial">Grandmillennial</button>
+ </div>
+</div>
+
+<div class="overlay" id="game-over">
+ <div class="overlay-content">
+ <div class="overlay-title">Game Complete</div>
+ <div class="overlay-score" id="final-score">0/8</div>
+ <div class="overlay-best" id="final-best">Best: 0</div>
+ <button class="restart-btn" id="restart-btn">Play Again</button>
+ </div>
+</div>
+
+<script>
+// Game Data
+const eras = ['victorian','art-deco','midcentury','grandmillennial'];
+const eraNames = {
+ 'victorian':'Victorian',
+ 'art-deco':'Art Deco',
+ 'midcentury':'Mid-Century Modern',
+ 'grandmillennial':'Grandmillennial'
+};
+const eraFacts = {
+ 'victorian':'Victorian interiors (1837-1901) revel in maximalism: dark mahogany, ornate wallpapers, heavy draperies, and intricate moldings. The Industrial Revolution made previously handcrafted luxuries accessible to the middle class, leading to rooms stuffed with pattern-on-pattern textiles and carved furniture.',
+ 'art-deco':'Art Deco (1920s-1930s) channels geometric precision and exotic materials. Sunburst mirrors, lacquered surfaces, chrome accents, and bold zigzag patterns define this era of streamlined luxury that celebrated the machine age while retaining handcrafted glamour.',
+ 'midcentury':'Mid-Century Modern (1940s-1960s) embraces organic curves, clean lines, and honest materials. Teak and walnut woods, tapered legs, and open floor plans reflect post-war optimism. This era rejected ornament in favor of functional beauty and indoor-outdoor connection.',
+ 'grandmillennial':'Grandmillennial (2010s-present) reinterprets granny chic for a new generation: chintz wallpapers, needlepoint pillows, skirted furniture, and wicker accents. It celebrates collected-over-time warmth, rejecting minimalism in favor of pattern-rich, nostalgic comfort.'
+};
+
+// Game State
+let currentRound = 1;
+const totalRounds = 8;
+let score = 0;
+let currentEra = '';
+let canGuess = true;
+
+// DOM Elements
+const roomVignette = document.getElementById('room-vignette');
+const scoreEl = document.getElementById('score');
+const roundEl = document.getElementById('round');
+const bestEl = document.getElementById('best');
+const roundIndicator = document.getElementById('round-indicator');
+const revealPanel = document.getElementById('reveal-panel');
+const revealTitle = document.getElementById('reveal-title');
+const revealFact = document.getElementById('reveal-fact');
+const nextBtn = document.getElementById('next-btn');
+const guessBtns = document.querySelectorAll('.guess-btn');
+const gameOverOverlay = document.getElementById('game-over');
+const finalScoreEl = document.getElementById('final-score');
+const finalBestEl = document.getElementById('final-best');
+const restartBtn = document.getElementById('restart-btn');
+
+// Load best score
+function loadBestScore(){
+ const best = localStorage.getItem('dw-best-score');
+ if(best) bestEl.textContent = best;
+}
+loadBestScore();
+
+function saveBestScore(){
+ const best = parseInt(localStorage.getItem('dw-best-score')||'0');
+ if(score > best){
+ localStorage.setItem('dw-best-score',score);
+ bestEl.textContent = score;
+ }
+}
+
+function getRandomEra(){
+ return eras[Math.floor(Math.random()*eras.length)];
+}
+
+function setRoomStyle(era){
+ roomVignette.className = 'room-vignette ' + era;
+ // Trigger reflow for animation
+ void roomVignette.offsetWidth;
+ roomVignette.style.animation = 'none';
+ setTimeout(()=>{
+ roomVignette.style.animation = 'fadeUp 0.8s cubic-bezier(.22,1,.36,1) both';
+ },10);
+}
+
+function updateUI(){
+ scoreEl.textContent = score;
+ roundEl.textContent = `${currentRound}/${totalRounds}`;
+ roundIndicator.textContent = `Round ${currentRound} of ${totalRounds}`;
+}
+
+function startRound(){
+ canGuess = true;
+ currentEra = getRandomEra();
+ setRoomStyle(currentEra);
+ revealPanel.classList.remove('active');
+
+ // Reset buttons
+ guessBtns.forEach(btn=>{
+ btn.classList.remove('correct','wrong');
+ btn.disabled = false;
+ });
+}
+
+function handleGuess(btn){
+ if(!canGuess) return;
+ canGuess = false;
+
+ const guessedEra = btn.dataset.era;
+ const isCorrect = guessedEra === currentEra;
+
+ if(isCorrect){
+ score++;
+ btn.classList.add('correct');
+ }else{
+ btn.classList.add('wrong');
+ // Highlight correct answer
+ guessBtns.forEach(b=>{
+ if(b.dataset.era === currentEra) b.classList.add('correct');
+ });
+ }
+
+ updateUI();
+
+ // Show reveal panel
+ setTimeout(()=>{
+ revealTitle.textContent = eraNames[currentEra];
+ revealFact.textContent = eraFacts[currentEra];
+ revealPanel.classList.add('active');
+ },400);
+}
+
+function endGame(){
+ saveBestScore();
+ finalScoreEl.textContent = `${score}/${totalRounds}`;
+ finalBestEl.textContent = `Best: ${localStorage.getItem('dw-best-score')||score}`;
+ gameOverOverlay.classList.add('active');
+}
+
+function restartGame(){
+ currentRound = 1;
+ score = 0;
+ updateUI();
+ gameOverOverlay.classList.remove('active');
+ startRound();
+}
+
+function nextRound(){
+ if(currentRound >= totalRounds){
+ endGame();
+ }else{
+ currentRound++;
+ updateUI();
+ startRound();
+ }
+}
+
+// Event Listeners
+guessBtns.forEach(btn=>{
+ btn.addEventListener('click',()=>handleGuess(btn));
+});
+
+nextBtn.addEventListener('click',nextRound);
+restartBtn.addEventListener('click',restartGame);
+
+// Start game
+startRound();
+updateUI();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/kimi.png b/data/artifacts/6f651f004b4c/kimi.png
new file mode 100644
index 0000000..ae749d6
Binary files /dev/null and b/data/artifacts/6f651f004b4c/kimi.png differ
diff --git a/data/artifacts/6f651f004b4c/qwen25-7b.html b/data/artifacts/6f651f004b4c/qwen25-7b.html
new file mode 100644
index 0000000..4dfb411
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/qwen25-7b.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Which Design Era?</title>
+ <style>
+ :root {
+ --bg: #17171c;
+ --surface: #f5f2ea;
+ --text: #f5f2ea;
+ --muted: #8a8578;
+ --accent: #c9a961;
+ --line: 1px solid rgba(0,0,0,.1);
+ --shadow: 0 8px 24px rgba(0,0,0,.12), hover 0 16px 48px rgba(0,0,0,.18);
+ --ease: cubic-bezier(.22,1,.36,1) both;
+ }
+
+ body {
+ background-color: var(--bg);
+ color: var(--text);
+ margin: 0;
+ font-family: 'Didot', Georgia, serif;
+ font-size: 16px;
+ line-height: 1.5;
+ padding-top: 96px;
+ transition: all .7s var(--ease);
+ }
+
+ header {
+ display: flex;
+ align-items: center;
+ justify-content: left;
+ margin-bottom: 32px;
+ }
+
+ .header-text {
+ font-size: 50px;
+ letter-spacing: .18em;
+ text-transform: uppercase;
+ color: var(--text);
+ }
+
+ .game-container {
+ max-width: 640px;
+ margin: auto;
+ padding-bottom: 96px;
+ box-sizing: border-box;
+ }
+
+ .card-grid {
+ display: grid;
+ gap: 24px;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ justify-content: center;
+ margin-top: -32px;
+ padding: 0 24px;
+ }
+
+ .card {
+ background-color: var(--surface);
+ border-radius: 14px;
+ box-shadow: var(--shadow);
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ overflow: hidden;
+ transition: transform .7s var(--ease), box-shadow .7s var(--ease);
+ }
+
+ .card:hover {
+ box-shadow: var(--shadow, hover);
+ transform: translateY(-8px);
+ }
+
+ .card-header {
+ padding: 24px;
+ }
+
+ .card-body {
+ flex-grow: 1;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 24px;
+ }
+
+ .card-footer {
+ padding: 24px;
+ text-align: center;
+ font-size: 16px;
+ letter-spacing: .15em;
+ color: var(--muted);
+ line-height: 1.25;
+ }
+
+ button {
+ background-color: transparent;
+ border: none;
+ padding: 8px 16px;
+ color: var(--text);
+ font-size: 14px;
+ cursor: pointer;
+ transition: all .2s ease;
+ text-transform: uppercase;
+ letter-spacing: .15em;
+ }
+
+ button:hover {
+ background-color: rgba(0,0,0,.08);
+ }
+
+ #scoreboard {
+ margin-top: 32px;
+ font-size: 16px;
+ text-align: center;
+ color: var(--muted);
+ }
+ </style>
+</head>
+<body>
+<header class="header-text">DESIGNER WALLCOVERINGS</header>
+
+<div class="game-container">
+ <div id="game-content" class="card-grid"></div>
+ <div id="scoreboard"></div>
+ <button onclick="startGame()">Start Game</button>
+</div>
+
+<script>
+function startGame() {
+ const eras = ['Victorian', 'Art Deco', 'Mid-Century Modern', 'Grandmillennial'];
+ const randomEra = eras[Math.floor(Math.random() * 4)];
+ document.getElementById('game-content').innerHTML = `
+ <div class="card">
+ <div class="card-header">Which era is this?</div>
+ <div class="card-body">${randomEra}</div>
+ <div class="card-footer">
+ <button onclick="checkAnswer('Victorian')">Victorian</button>
+ <button onclick="checkAnswer('Art Deco')">Art Deco</button>
+ <button onclick="checkAnswer('Mid-Century Modern')">Mid-Century Modern</button>
+ <button onclick="checkAnswer('Grandmillennial')">Grandmillennial</button>
+ </div>
+ </div>
+ `;
+
+ function checkAnswer(answer) {
+ if (answer === randomEra) {
+ alert("Correct!");
+ document.getElementById('scoreboard').innerText = "Score: 1";
+ } else {
+ alert(`Wrong! It was ${randomEra}.`);
+ }
+ startGame();
+ }
+
+ document.getElementById('scoreboard').innerText = localStorage.getItem('score') || 0;
+}
+
+window.onload = startGame;
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/qwen25-7b.png b/data/artifacts/6f651f004b4c/qwen25-7b.png
new file mode 100644
index 0000000..14b878b
Binary files /dev/null and b/data/artifacts/6f651f004b4c/qwen25-7b.png differ
diff --git a/data/artifacts/6f651f004b4c/qwen3-14b.html b/data/artifacts/6f651f004b4c/qwen3-14b.html
new file mode 100644
index 0000000..a979bd1
--- /dev/null
+++ b/data/artifacts/6f651f004b4c/qwen3-14b.html
@@ -0,0 +1,337 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Which Design Era?</title>
+ <style>
+ :root {
+ --bg: #faf8f4;
+ --surface: #ffffff;
+ --text: #1c1a17;
+ --muted: #9b948a;
+ --accent: #b0472e;
+ --line: #ebe9e3;
+ --shadow: 0 8px 24px rgba(0,0,0,0.12);
+ --ease: cubic-bezier(0.22, 1, 0.36, 1);
+ --glow: 0 0 24px var(--accent)35%;
+ --spacing: 16px;
+ --radius: 14px;
+ --font-display: 'Playfair Display', Georgia, serif;
+ --font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ }
+
+ * {
+ box-sizing: border-box;
+ }
+
+ body {
+ margin: 0;
+ font-family: var(--font-body);
+ background-color: var(--bg);
+ color: var(--text);
+ line-height: 1.6;
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ }
+
+ header {
+ font-family: var(--font-display);
+ font-size: 48px;
+ letter-spacing: 0.18em;
+ color: var(--text);
+ padding: var(--spacing) var(--spacing) var(--spacing) var(--spacing);
+ background-color: var(--surface);
+ display: flex;
+ align-items: center;
+ box-shadow: var(--shadow);
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1000;
+ }
+
+ main {
+ padding-top: 80px;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ }
+
+ .vignette {
+ width: 100%;
+ max-width: 800px;
+ height: 600px;
+ background: linear-gradient(135deg, var(--accent)10%, var(--surface)60%, var(--muted)20%);
+ border: 1px solid var(--line);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+ position: relative;
+ z-index: 1;
+ }
+
+ .vignette::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, var(--accent)20%, transparent 50%, transparent 100%);
+ opacity: 0.1;
+ z-index: 0;
+ }
+
+ .era {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><pattern id="victorian" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse"><path d="M 0 0 L 20 0 L 20 20 L 0 20 Z" fill="none" stroke="var(--text)" stroke-width="1"/><line x1="0" y1="0" x2="20" y2="20" stroke="var(--text)" stroke-width="1"/><line x1="20" y1="0" x2="0" y2="20" stroke="var(--text)" stroke-width="1"/></pattern><rect width="100%" height="100%" fill="url(#victorian)" /></svg>');
+ transition: opacity 0.3s ease-in-out;
+ }
+
+ .era.victorian {
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><pattern id="victorian" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse"><path d="M 0 0 L 20 0 L 20 20 L 0 20 Z" fill="none" stroke="var(--text)" stroke-width="1"/><line x1="0" y1="0" x2="20" y2="20" stroke="var(--text)" stroke-width="1"/><line x1="20" y1="0" x2="0" y2="20" stroke="var(--text)" stroke-width="1"/></pattern><rect width="100%" height="100%" fill="url(#victorian)" /></svg>');
+ }
+
+ .era.art-deco {
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><pattern id="art-deco" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse"><circle cx="20" cy="20" r="10" fill="var(--text)" opacity="0.15"/><path d="M 0 0 L 40 40" stroke="var(--text)" stroke-width="1"/><path d="M 0 40 L 40 0" stroke="var(--text)" stroke-width="1"/></pattern><rect width="100%" height="100%" fill="url(#art-deco)" /></svg>');
+ }
+
+ .era.mid-century {
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><pattern id="mid-century" x="0" y="0" width="30" height="30" patternUnits="userSpaceOnUse"><rect x="0" y="0" width="5" height="5" fill="var(--text)" /><rect x="20" y="0" width="5" height="5" fill="var(--text)" /><rect x="0" y="20" width="5" height="5" fill="var(--text)" /><rect x="20" y="20" width="5" height="5" fill="var(--text)" /></pattern><rect width="100%" height="100%" fill="url(#mid-century)" /></svg>');
+ }
+
+ .era.grandmillennial {
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><pattern id="grandmillennial" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="4" fill="var(--text)" opacity="0.2"/><path d="M 0 0 L 20 20" stroke="var(--text)" stroke-width="1"/><path d="M 0 20 L 20 0" stroke="var(--text)" stroke-width="1"/></pattern><rect width="100%" height="100%" fill="url(#grandmillennial)" /></svg>');
+ }
+
+ .overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.8);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 1001;
+ visibility: hidden;
+ opacity: 0;
+ transition: visibility 0.3s, opacity 0.3s;
+ }
+
+ .overlay.active {
+ visibility: visible;
+ opacity: 1;
+ }
+
+ .overlay-content {
+ background-color: var(--surface);
+ padding: 48px;
+ border-radius: var(--radius);
+ max-width: 600px;
+ width: 90%;
+ box-shadow: var(--shadow);
+ text-align: center;
+ }
+
+ .overlay-content h2 {
+ font-family: var(--font-display);
+ font-size: 32px;
+ margin-bottom: 24px;
+ }
+
+ .overlay-content p {
+ font-size: 18px;
+ color: var(--muted);
+ }
+
+ .scoreboard {
+ position: fixed;
+ top: var(--spacing);
+ right: var(--spacing);
+ background-color: var(--surface);
+ padding: 12px 16px;
+ border-radius: var(--radius);
+ box-shadow: var(--shadow);
+ font-family: var(--font-body);
+ font-size: 14px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--muted);
+ }
+
+ .buttons {
+ display: flex;
+ gap: 16px;
+ margin-top: 32px;
+ }
+
+ .button {
+ font-family: var(--font-body);
+ font-size: 14px;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ background-color: var(--surface);
+ color: var(--text);
+ border: 1px solid var(--line);
+ border-radius: var(--radius);
+ padding: 12px 24px;
+ cursor: pointer;
+ transition: background-color 0.2s, box-shadow 0.2s;
+ }
+
+ .button:hover {
+ background-color: var(--muted);
+ box-shadow: var(--glow);
+ }
+
+ @keyframes fadeUp {
+ from {
+ opacity: 0;
+ transform: translateY(28px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ .fade-in {
+ animation: fadeUp 0.7s var(--ease) both;
+ }
+ </style>
+</head>
+<body>
+ <header>
+ DESIGNER WALLCOVERINGS
+ </header>
+ <main>
+ <div class="vignette" id="vignette">
+ <div class="era victorian" id="victorian"></div>
+ <div class="era art-deco" id="art-deco"></div>
+ <div class="era mid-century" id="mid-century"></div>
+ <div class="era grandmillennial" id="grandmillennial"></div>
+ </div>
+ <div class="scoreboard" id="scoreboard">Score: 0 / 8</div>
+ <div class="buttons" id="buttons">
+ <button class="button" data-era="victorian">VICTORIAN</button>
+ <button class="button" data-era="art-deco">ART DECO</button>
+ <button class="button" data-era="mid-century">MID-CENTURY</button>
+ <button class="button" data-era="grandmillennial">GRANDMILL ennial</button>
+ </div>
+ </main>
+
+ <div class="overlay" id="overlay">
+ <div class="overlay-content">
+ <h2 id="overlay-title">Era Revealed</h2>
+ <p id="overlay-text"></p>
+ <button class="button" id="next-btn">Next</button>
+ </div>
+ </div>
+
+ <script>
+ const eras = ['victorian', 'art-deco', 'mid-century', 'grandmillennial'];
+ const vignette = document.getElementById('vignette');
+ const buttons = document.querySelectorAll('.button');
+ const overlay = document.getElementById('overlay');
+ const overlayTitle = document.getElementById('overlay-title');
+ const overlayText = document.getElementById('overlay-text');
+ const nextBtn = document.getElementById('next-btn');
+ const scoreboard = document.getElementById('scoreboard');
+ const facts = {
+ victorian: "Victorian design was influenced by the Industrial Revolution, with a focus on symmetry, ornate detail, and rich materials.",
+ 'art-deco': "Art Deco embraced modernity and luxury, characterized by geometric shapes, bold colors, and lavish ornamentation.",
+ 'mid-century': "Mid-Century Modern design emphasized simplicity, clean lines, and functionality, often using wood and leather.",
+ 'grandmillennial': "Grandmillennial style is a modern take on opulent interiors, combining vintage and contemporary elements with a soft, romantic feel."
+ };
+
+ let currentRound = 0;
+ let score = 0;
+ let currentEra = '';
+ const rounds = 8;
+ let history = JSON.parse(localStorage.getItem('bestScore')) || { score: 0 };
+
+ function getRandomEra() {
+ return eras[Math.floor(Math.random() * eras.length)];
+ }
+
+ function showEra(era) {
+ vignette.classList.remove(...eras.map(e => `era-${e}`));
+ vignette.classList.add(`era-${era}`);
+ currentEra = era;
+ }
+
+ function startRound() {
+ if (currentRound >= rounds) {
+ endGame();
+ return;
+ }
+ currentEra = getRandomEra();
+ showEra(currentEra);
+ overlay.classList.remove('active');
+ overlayTitle.textContent = '';
+ overlayText.textContent = '';
+ nextBtn.disabled = true;
+ }
+
+ function endGame() {
+ overlay.classList.add('active');
+ overlayTitle.textContent = 'Game Over!';
+ overlayText.textContent = `You scored ${score} out of ${rounds}!\nBest score: ${history.score}`;
+ nextBtn.textContent = 'Restart';
+ nextBtn.disabled = false;
+ }
+
+ function updateScoreboard() {
+ scoreboard.textContent = `Score: ${score} / ${rounds}`;
+ }
+
+ function updateBestScore() {
+ if (score > history.score) {
+ history.score = score;
+ localStorage.setItem('bestScore', JSON.stringify(history));
+ }
+ }
+
+ buttons.forEach(btn => {
+ btn.addEventListener('click', () => {
+ const guessedEra = btn.getAttribute('data-era');
+ if (guessedEra === currentEra) {
+ score++;
+ updateScoreboard();
+ }
+ currentRound++;
+ startRound();
+ });
+ });
+
+ nextBtn.addEventListener('click', () => {
+ if (currentRound < rounds) {
+ startRound();
+ } else {
+ score = 0;
+ currentRound = 0;
+ startRound();
+ updateScoreboard();
+ }
+ });
+
+ startRound();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/6f651f004b4c/qwen3-14b.png b/data/artifacts/6f651f004b4c/qwen3-14b.png
new file mode 100644
index 0000000..1f2b522
Binary files /dev/null and b/data/artifacts/6f651f004b4c/qwen3-14b.png differ
diff --git a/data/challenges.json b/data/challenges.json
index b818f2b..4662732 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -15066,7 +15066,8 @@
"thumb": true
}
],
- "judging": false
+ "judging": true,
+ "judged_at": null
},
{
"id": "172f180e3161",
@@ -24455,7 +24456,14 @@
"finished_at": "2026-07-25T12:38:48.163Z",
"queued_at": "2026-07-25T12:36:12.817Z",
"bytes": 18015,
- "thumb": true
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML file fulfills all the requirements of the challenge 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": "kimi",
@@ -24472,7 +24480,14 @@
"hyperframes"
],
"bytes": 20238,
- "thumb": true
+ "thumb": true,
+ "aiScore": 7.8,
+ "aiReason": "The HTML file meets all the requirements and presents an elegant, interactive color wheel for a wallcovering brand.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 2.5
},
{
"model": "gpt",
@@ -24489,7 +24504,14 @@
"hyperframes"
],
"bytes": 24455,
- "thumb": true
+ "thumb": true,
+ "aiScore": 9.3,
+ "aiReason": "The HTML fulfills all the requirements and presents an elegant, luxury-themed interactive color wheel for wallcoverings.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 9.5
+ },
+ "aiSpread": 0.5
},
{
"model": "grok",
@@ -24508,10 +24530,19 @@
"hyperframes"
],
"bytes": 34722,
- "thumb": true
+ "thumb": true,
+ "aiScore": 9.3,
+ "aiReason": "The HTML fulfills all the requirements and presents an elegant, interactive color wheel for a wallcovering brand.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 9.5
+ },
+ "aiSpread": 0.5
}
],
- "judging": true
+ "judging": false,
+ "aiPick": "gpt",
+ "judged_at": "2026-07-25T12:58:25.878Z"
},
{
"id": "ab0c520893e3",
@@ -24608,7 +24639,14 @@
"finished_at": "2026-07-25T12:46:46.670Z",
"queued_at": "2026-07-25T12:36:12.904Z",
"bytes": 10159,
- "thumb": true
+ "thumb": true,
+ "aiScore": 7.3,
+ "aiReason": "The HTML meets most of the requirements but lacks some visual flair and does not fully utilize the CSS design tokens for color contrast.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 0.5
},
{
"model": "claude-code",
@@ -24620,7 +24658,14 @@
"finished_at": "2026-07-25T12:40:36.564Z",
"queued_at": "2026-07-25T12:36:12.908Z",
"bytes": 15824,
- "thumb": true
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML fulfills all the requirements and presents a visually appealing game with a polished design.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
},
{
"model": "kimi",
@@ -24637,7 +24682,14 @@
"hyperframes"
],
"bytes": 14726,
- "thumb": true
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML meets all the requirements and presents a polished, on-brief result.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
},
{
"model": "gpt",
@@ -24655,7 +24707,14 @@
"hyperframes"
],
"bytes": 28760,
- "thumb": true
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML fulfills all the requirements and presents a polished, on-brief memory card-flip game.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
},
{
"model": "grok",
@@ -24672,11 +24731,19 @@
"hyperframes"
],
"bytes": 20955,
- "thumb": true
+ "thumb": true,
+ "aiScore": 9.3,
+ "aiReason": "The HTML meets all the requirements and presents a visually appealing memory card-flip game with a luxurious design.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 9.5
+ },
+ "aiSpread": 0.5
}
],
- "judging": true,
- "judged_at": null
+ "judging": false,
+ "judged_at": "2026-07-25T12:58:35.993Z",
+ "aiPick": "grok"
},
{
"id": "420dc7bd02b3",
@@ -24686,6 +24753,411 @@
"designTools": true,
"created_at": "2026-07-25T12:48:12.940Z",
"winner": null,
+ "runs": [
+ {
+ "model": "qwen3-14b",
+ "status": "done",
+ "error": null,
+ "seconds": 66,
+ "cost": 0,
+ "started_at": "2026-07-25T12:48:19.882Z",
+ "finished_at": "2026-07-25T12:49:26.330Z",
+ "queued_at": "2026-07-25T12:48:12.951Z",
+ "bytes": 9133,
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML fulfills the challenge requirements and presents a high-quality luxury color palette builder with clear typography and restrained design elements.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
+ },
+ {
+ "model": "gemma3-12b",
+ "status": "done",
+ "error": null,
+ "seconds": 64,
+ "cost": 0,
+ "started_at": "2026-07-25T12:49:26.343Z",
+ "finished_at": "2026-07-25T12:50:29.973Z",
+ "queued_at": "2026-07-25T12:48:12.958Z",
+ "bytes": 9256,
+ "thumb": true,
+ "aiScore": 7.8,
+ "aiReason": "The HTML file meets all the DW LUXURY UI REQUIREMENTS and presents a polished, on-brief result.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 2.5
+ },
+ {
+ "model": "hermes3-8b",
+ "status": "done",
+ "error": null,
+ "seconds": 36,
+ "cost": 0,
+ "started_at": "2026-07-25T12:50:29.977Z",
+ "finished_at": "2026-07-25T12:51:05.783Z",
+ "queued_at": "2026-07-25T12:48:12.968Z",
+ "bytes": 4122,
+ "thumb": true,
+ "aiScore": 6.8,
+ "aiReason": "The HTML file fulfills the challenge requirements but lacks some visual refinement and whitespace.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 0.5
+ },
+ {
+ "model": "qwen25-7b",
+ "status": "done",
+ "error": null,
+ "seconds": 26,
+ "cost": 0,
+ "started_at": "2026-07-25T12:48:13.004Z",
+ "finished_at": "2026-07-25T12:48:39.492Z",
+ "queued_at": "2026-07-25T12:48:12.975Z",
+ "bytes": 3469,
+ "thumb": true,
+ "aiScore": 6.8,
+ "aiReason": "The design fulfills the requirements well but lacks some refinement in typography and spacing.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 0.5
+ },
+ {
+ "model": "hf-qwen-coder-32b",
+ "status": "done",
+ "error": null,
+ "seconds": 88,
+ "cost": 0,
+ "started_at": "2026-07-25T12:51:05.793Z",
+ "finished_at": "2026-07-25T12:52:33.485Z",
+ "queued_at": "2026-07-25T12:48:12.980Z",
+ "bytes": 7264,
+ "thumb": true,
+ "aiScore": 7.3,
+ "aiReason": "The HTML file fulfills the challenge requirements well and presents a polished, on-brief result.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 5.5
+ },
+ "aiSpread": 3.5
+ },
+ {
+ "model": "claude-code",
+ "status": "done",
+ "error": null,
+ "seconds": 135,
+ "cost": 0,
+ "started_at": "2026-07-25T12:48:13.009Z",
+ "finished_at": "2026-07-25T12:50:27.606Z",
+ "queued_at": "2026-07-25T12:48:12.984Z",
+ "bytes": 24971,
+ "thumb": true,
+ "aiScore": 8,
+ "aiReason": "The HTML file fulfills the challenge requirements and presents a visually appealing luxury color palette builder.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7
+ },
+ "aiSpread": 2
+ },
+ {
+ "model": "kimi",
+ "status": "done",
+ "error": null,
+ "seconds": 143,
+ "cost": 0.0257,
+ "started_at": "2026-07-25T12:48:13.016Z",
+ "finished_at": "2026-07-25T12:50:36.231Z",
+ "queued_at": "2026-07-25T12:48:12.990Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 26273,
+ "thumb": true,
+ "aiScore": 6.8,
+ "aiReason": "The design is visually appealing and adheres to the luxury UI requirements. However, it lacks some of the specified features such as a curated palette with swatches and an export button.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 0.5
+ },
+ {
+ "model": "gpt",
+ "status": "done",
+ "error": null,
+ "seconds": 76,
+ "cost": 0.1812,
+ "started_at": "2026-07-25T12:48:13.021Z",
+ "finished_at": "2026-07-25T12:49:28.871Z",
+ "queued_at": "2026-07-25T12:48:12.995Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes",
+ "hyperframes"
+ ],
+ "bytes": 39377,
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML file fulfills the challenge requirements well and has a polished visual quality.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
+ },
+ {
+ "model": "grok",
+ "status": "done",
+ "error": null,
+ "seconds": 134,
+ "cost": 0.1768,
+ "started_at": "2026-07-25T12:48:13.026Z",
+ "finished_at": "2026-07-25T12:50:27.506Z",
+ "queued_at": "2026-07-25T12:48:12.999Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 32315,
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML file effectively fulfills the challenge requirements with a polished and refined design. It includes all necessary elements such as a fixed top bar, color wheel interaction, swatch preview, a",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
+ }
+ ],
+ "judging": false,
+ "aiPick": "qwen3-14b",
+ "judged_at": "2026-07-25T12:59:27.423Z"
+ },
+ {
+ "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:48:13.064Z",
+ "winner": null,
+ "runs": [
+ {
+ "model": "qwen3-14b",
+ "status": "done",
+ "error": null,
+ "seconds": 83,
+ "cost": 0,
+ "started_at": "2026-07-25T12:52:33.493Z",
+ "finished_at": "2026-07-25T12:53:56.106Z",
+ "queued_at": "2026-07-25T12:48:13.071Z",
+ "bytes": 11186,
+ "thumb": true,
+ "aiScore": 6.3,
+ "aiReason": "The HTML file meets all the requirements and presents a polished, on-brief result.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 3.5
+ },
+ "aiSpread": 5.5
+ },
+ {
+ "model": "gemma3-12b",
+ "status": "done",
+ "error": null,
+ "seconds": 54,
+ "cost": 0,
+ "started_at": "2026-07-25T12:53:56.116Z",
+ "finished_at": "2026-07-25T12:54:50.524Z",
+ "queued_at": "2026-07-25T12:48:13.074Z",
+ "bytes": 7091,
+ "thumb": true,
+ "aiScore": 5.3,
+ "aiReason": "The HTML file meets most of the requirements but lacks some visual elements and transitions that would enhance its luxury aesthetic.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 3.5
+ },
+ "aiSpread": 3.5
+ },
+ {
+ "model": "hermes3-8b",
+ "status": "done",
+ "error": null,
+ "seconds": 36,
+ "cost": 0,
+ "started_at": "2026-07-25T12:54:50.539Z",
+ "finished_at": "2026-07-25T12:55:26.850Z",
+ "queued_at": "2026-07-25T12:48:13.078Z",
+ "bytes": 5584,
+ "thumb": true,
+ "aiScore": 7.8,
+ "aiReason": "The HTML file meets all the requirements and has a polished, luxurious aesthetic.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 2.5
+ },
+ {
+ "model": "qwen25-7b",
+ "status": "done",
+ "error": null,
+ "seconds": 32,
+ "cost": 0,
+ "started_at": "2026-07-25T12:48:39.503Z",
+ "finished_at": "2026-07-25T12:49:11.752Z",
+ "queued_at": "2026-07-25T12:48:13.082Z",
+ "bytes": 4605,
+ "thumb": true,
+ "aiScore": 6.8,
+ "aiReason": "The HTML meets most of the requirements but lacks some visual flair and does not fully utilize the available space for a more engaging user experience.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 0.5
+ },
+ {
+ "model": "hf-qwen-coder-32b",
+ "status": "done",
+ "error": null,
+ "seconds": 106,
+ "cost": 0,
+ "started_at": "2026-07-25T12:55:26.861Z",
+ "finished_at": "2026-07-25T12:57:12.949Z",
+ "queued_at": "2026-07-25T12:48:13.086Z",
+ "bytes": 9498,
+ "thumb": true,
+ "aiScore": 7.8,
+ "aiReason": "The HTML fulfills the challenge requirements well and presents a polished, luxurious aesthetic.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 6.5
+ },
+ "aiSpread": 2.5
+ },
+ {
+ "model": "claude-code",
+ "status": "done",
+ "error": null,
+ "seconds": 123,
+ "cost": 0,
+ "started_at": "2026-07-25T12:50:27.611Z",
+ "finished_at": "2026-07-25T12:52:30.636Z",
+ "queued_at": "2026-07-25T12:48:13.093Z",
+ "bytes": 23367,
+ "thumb": true,
+ "aiScore": 8,
+ "aiReason": "The HTML file fulfills the challenge requirements and presents a visually appealing luxury aesthetic.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7
+ },
+ "aiSpread": 2
+ },
+ {
+ "model": "kimi",
+ "status": "done",
+ "error": null,
+ "seconds": 90,
+ "cost": 0.0194,
+ "started_at": "2026-07-25T12:50:36.236Z",
+ "finished_at": "2026-07-25T12:52:06.618Z",
+ "queued_at": "2026-07-25T12:48:13.097Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes",
+ "hyperframes"
+ ],
+ "bytes": 17564,
+ "thumb": true,
+ "aiScore": 5.8,
+ "aiReason": "The game is well-structured and adheres to the design brief, but lacks some visual flair in terms of pattern variety.",
+ "aiScores": {
+ "qwen2.5vl:7b": 7,
+ "minicpm-v:latest": 4.5
+ },
+ "aiSpread": 2.5
+ },
+ {
+ "model": "gpt",
+ "status": "done",
+ "error": null,
+ "seconds": 76,
+ "cost": 0.1834,
+ "started_at": "2026-07-25T12:49:28.875Z",
+ "finished_at": "2026-07-25T12:50:44.397Z",
+ "queued_at": "2026-07-25T12:48:13.101Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 38829,
+ "thumb": true,
+ "aiScore": 8.3,
+ "aiReason": "The HTML fulfills the challenge requirements and presents a polished, luxurious aesthetic with clear design tokens and visual distinctiveness.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7.5
+ },
+ "aiSpread": 1.5
+ },
+ {
+ "model": "grok",
+ "status": "done",
+ "error": null,
+ "seconds": 187,
+ "cost": 0.2197,
+ "started_at": "2026-07-25T12:50:27.515Z",
+ "finished_at": "2026-07-25T12:53:34.420Z",
+ "queued_at": "2026-07-25T12:48:13.105Z",
+ "toolCalls": [
+ "opendesign",
+ "opendesign",
+ "hyperframes"
+ ],
+ "bytes": 37455,
+ "thumb": true,
+ "aiScore": 8,
+ "aiReason": "The HTML meets all the challenge requirements and presents a polished, luxurious aesthetic.",
+ "aiScores": {
+ "qwen2.5vl:7b": 9,
+ "minicpm-v:latest": 7
+ },
+ "aiSpread": 2
+ }
+ ],
+ "judging": false,
+ "aiPick": "gpt",
+ "judged_at": "2026-07-25T12:59:27.426Z"
+ },
+ {
+ "id": "c86c17be0c9b",
+ "title": "Designer Wallcoverings — Brand Mood Board Maker",
+ "prompt": "Build a single self-contained HTML file: a shareable mood-board generator for a luxury wallcovering brand. A 1080x1350 canvas auto-arranges a curated set (a hero CSS pattern, 3 color chips with names, a type-pairing sample, a texture tile); a \"Regenerate\" button reshuffles into a new on-brand board with easing. Pick a style theme (Classic, Coastal, Moody, Botanical). 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-25T13:00:05.824Z",
+ "winner": null,
"runs": [
{
"model": "qwen3-14b",
@@ -24695,7 +25167,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.951Z"
+ "queued_at": "2026-07-25T13:00:05.860Z"
},
{
"model": "gemma3-12b",
@@ -24705,7 +25177,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.958Z"
+ "queued_at": "2026-07-25T13:00:05.883Z"
},
{
"model": "hermes3-8b",
@@ -24715,7 +25187,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.968Z"
+ "queued_at": "2026-07-25T13:00:05.893Z"
},
{
"model": "qwen25-7b",
@@ -24723,9 +25195,9 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:48:13.004Z",
+ "started_at": "2026-07-25T13:00:05.951Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.975Z"
+ "queued_at": "2026-07-25T13:00:05.902Z"
},
{
"model": "hf-qwen-coder-32b",
@@ -24735,7 +25207,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.980Z"
+ "queued_at": "2026-07-25T13:00:05.911Z"
},
{
"model": "claude-code",
@@ -24743,9 +25215,9 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:48:13.009Z",
+ "started_at": "2026-07-25T13:00:05.957Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.984Z"
+ "queued_at": "2026-07-25T13:00:05.917Z"
},
{
"model": "kimi",
@@ -24753,9 +25225,9 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:48:13.016Z",
+ "started_at": "2026-07-25T13:00:05.966Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.990Z"
+ "queued_at": "2026-07-25T13:00:05.930Z"
},
{
"model": "gpt",
@@ -24763,9 +25235,9 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:48:13.021Z",
+ "started_at": "2026-07-25T13:00:05.973Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.995Z"
+ "queued_at": "2026-07-25T13:00:05.938Z"
},
{
"model": "grok",
@@ -24773,19 +25245,19 @@
"error": null,
"seconds": null,
"cost": null,
- "started_at": "2026-07-25T12:48:13.026Z",
+ "started_at": "2026-07-25T13:00:06.011Z",
"finished_at": null,
- "queued_at": "2026-07-25T12:48:12.999Z"
+ "queued_at": "2026-07-25T13:00:05.943Z"
}
]
},
{
- "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.)",
+ "id": "0a809ac3ac48",
+ "title": "Designer Wallcoverings — Trending Color Reel",
+ "prompt": "Build a single self-contained HTML file: a vertical 9:16 Reel that reveals a \"Color of the Season\" for a wallcovering brand. Auto-advancing timed scenes: hook (\"This season it's all about...\"), the hue name filling the screen (e.g. Celadon), 3 CSS pattern swatches in that color, styling tip, CTA. Animated captions + progress bar, play/pause. 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:13.064Z",
+ "created_at": "2026-07-25T13:00:06.017Z",
"winner": null,
"runs": [
{
@@ -24796,7 +25268,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.071Z"
+ "queued_at": "2026-07-25T13:00:06.021Z"
},
{
"model": "gemma3-12b",
@@ -24806,7 +25278,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.074Z"
+ "queued_at": "2026-07-25T13:00:06.024Z"
},
{
"model": "hermes3-8b",
@@ -24816,7 +25288,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.078Z"
+ "queued_at": "2026-07-25T13:00:06.028Z"
},
{
"model": "qwen25-7b",
@@ -24826,7 +25298,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.082Z"
+ "queued_at": "2026-07-25T13:00:06.032Z"
},
{
"model": "hf-qwen-coder-32b",
@@ -24836,7 +25308,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.086Z"
+ "queued_at": "2026-07-25T13:00:06.036Z"
},
{
"model": "claude-code",
@@ -24846,7 +25318,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.093Z"
+ "queued_at": "2026-07-25T13:00:06.040Z"
},
{
"model": "kimi",
@@ -24856,7 +25328,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.097Z"
+ "queued_at": "2026-07-25T13:00:06.045Z"
},
{
"model": "gpt",
@@ -24866,7 +25338,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.101Z"
+ "queued_at": "2026-07-25T13:00:06.049Z"
},
{
"model": "grok",
@@ -24876,7 +25348,7 @@
"cost": null,
"started_at": null,
"finished_at": null,
- "queued_at": "2026-07-25T12:48:13.105Z"
+ "queued_at": "2026-07-25T13:00:06.052Z"
}
]
}
diff --git a/data/costlog.jsonl b/data/costlog.jsonl
index 52be456..70ed27f 100644
--- a/data/costlog.jsonl
+++ b/data/costlog.jsonl
@@ -339,3 +339,9 @@
{"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}
+{"ts":"2026-07-25T12:49:28.867Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3502,"output_tokens":12506,"cost_usd":0.181212}
+{"ts":"2026-07-25T12:50:27.502Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4320,"output_tokens":10920,"cost_usd":0.17676}
+{"ts":"2026-07-25T12:50:36.229Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":6614,"output_tokens":8707,"cost_usd":0.025736}
+{"ts":"2026-07-25T12:50:44.392Z","provider":"openai","model":"gpt-5.1","task":"model-arena-tools","input_tokens":3315,"output_tokens":12685,"cost_usd":0.183391}
+{"ts":"2026-07-25T12:52:06.616Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena-tools","input_tokens":6393,"output_tokens":6238,"cost_usd":0.019431}
+{"ts":"2026-07-25T12:53:34.418Z","provider":"xai","model":"grok-4.5","task":"model-arena-tools","input_tokens":4063,"output_tokens":13836,"cost_usd":0.219729}
diff --git a/idea-run/.dw-brand-style-color-pointer b/idea-run/.dw-brand-style-color-pointer
index 45a4fb7..f599e28 100644
--- a/idea-run/.dw-brand-style-color-pointer
+++ b/idea-run/.dw-brand-style-color-pointer
@@ -1 +1 @@
-8
+10
← bbe6f3e night-loop: cycle 05:48 — judged=ab0c520893e3 · fired 2 →; F
·
back to Model Arena
·
auto-save: 2026-07-25T06:04:08 (4 files) — data/challenges.j 1c3e449 →