← back to Model Arena
data/artifacts/18bd2744dce2/claude-code.html
435 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Color Story — Designer Wallcoverings</title>
<style>
/* ============ DESIGN TOKENS ============ */
:root{
--bg:#f4ede2; /* warm ivory ground */
--surface:#fbf6ee;
--ink:#241c15; /* deep near-black warm */
--ink-soft:#463a2c;
--muted:#9c8d78; /* muted stone */
--accent:#a8642f; /* single metallic-bronze accent */
--accent-2:#c79a5a; /* soft gilt */
--line:rgba(36,28,21,.16);
--line-soft:rgba(36,28,21,.08);
--shadow:0 24px 60px rgba(36,28,21,.16);
--shadow-soft:0 10px 34px rgba(36,28,21,.10);
--ease:cubic-bezier(.22,1,.36,1);
--serif:'Didot','Bodoni MT','Playfair Display','Cormorant Garamond',Georgia,serif;
--sans:-apple-system,'Segoe UI','Helvetica Neue',Arial,sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
background:#e9e0d2;
font-family:var(--sans);
color:var(--ink);
display:flex;
align-items:center;
justify-content:center;
min-height:100vh;
padding:16px;
}
/* ============ STAGE (1080x1080 scaled) ============ */
.stage-wrap{
width:min(1080px,calc(100vh - 32px),calc(100vw - 32px));
aspect-ratio:1/1;
}
.stage{
position:relative;
width:1080px;height:1080px;
transform-origin:top left;
background:var(--bg);
overflow:hidden;
box-shadow:var(--shadow);
border-radius:10px;
}
/* ambient drifting ground */
.stage::before{
content:"";
position:absolute;inset:0;
background:
radial-gradient(120% 90% at 15% 8%, rgba(199,154,90,.16), transparent 55%),
radial-gradient(120% 90% at 88% 96%, rgba(168,100,47,.12), transparent 55%);
animation:drift 22s ease-in-out infinite alternate;
pointer-events:none;
}
@keyframes drift{from{transform:translate3d(-1.5%,-1%,0) scale(1.04)}to{transform:translate3d(1.5%,1.5%,0) scale(1.10)}}
/* ============ TOP BAR / WORDMARK LOCKUP ============ */
.topbar{
position:absolute;top:0;left:0;right:0;
height:96px;
display:flex;align-items:center;justify-content:space-between;
padding:0 48px;
z-index:40;
pointer-events:none;
}
.lockup{max-width:230px;line-height:1.06}
.wordmark{
font-family:var(--serif);
font-weight:600;
font-size:23px;
letter-spacing:.18em;
text-transform:uppercase;
color:var(--ink);
}
.wordmark .amp{color:var(--accent)}
.sub{
font-family:var(--sans);
font-size:10px;
letter-spacing:.34em;
text-transform:uppercase;
color:var(--muted);
margin-top:6px;
}
.season-chip{
font-family:var(--sans);
font-size:11px;
letter-spacing:.22em;
text-transform:uppercase;
color:var(--accent);
border:1px solid var(--line);
padding:8px 14px;
border-radius:40px;
background:rgba(251,246,238,.6);
}
/* ============ CAROUSEL ============ */
.track{
position:absolute;inset:0;
display:flex;
transition:transform .7s var(--ease);
will-change:transform;
cursor:grab;
}
.track.dragging{transition:none;cursor:grabbing}
.slide{
position:relative;
flex:0 0 1080px;
height:1080px;
padding:150px 96px 128px;
display:flex;
flex-direction:column;
}
.kicker{
font-size:12px;letter-spacing:.32em;text-transform:uppercase;
color:var(--muted);
}
/* ---- COVER ---- */
.cover{justify-content:center;align-items:flex-start}
.cover .kicker{color:var(--accent)}
.cover h1{
font-family:var(--serif);
font-weight:500;
font-size:96px;
line-height:.98;
letter-spacing:-.5px;
margin:26px 0 8px;
color:var(--ink);
}
.cover h1 em{font-style:italic;color:var(--accent)}
.cover .lede{
font-size:20px;line-height:1.6;color:var(--ink-soft);
max-width:560px;margin-top:22px;
}
.cover .rule{
width:120px;height:1px;background:var(--line);margin:40px 0 30px;
}
.cover .chip-row{display:flex;gap:14px;flex-wrap:wrap}
.swatch-mini{
width:96px;height:96px;border-radius:8px;
border:1px solid var(--line-soft);
box-shadow:var(--shadow-soft);
}
/* ---- HUE SLIDES ---- */
.hue{justify-content:flex-start}
.hue .index{
font-family:var(--serif);font-style:italic;
font-size:22px;color:var(--muted);
}
.swatch-hero{
margin-top:34px;
height:420px;width:100%;
border-radius:14px;
border:1px solid var(--line-soft);
box-shadow:var(--shadow);
position:relative;
overflow:hidden;
}
/* woven tonal texture over the swatch, color-carried, no letters */
.swatch-hero::after{
content:"";position:absolute;inset:0;
background:
repeating-linear-gradient(135deg, rgba(255,255,255,.05) 0 3px, transparent 3px 7px),
repeating-linear-gradient(45deg, rgba(0,0,0,.045) 0 3px, transparent 3px 7px);
mix-blend-mode:soft-light;
}
.hue-name{
font-family:var(--serif);
font-weight:500;
font-size:60px;
line-height:1;
margin-top:40px;
color:var(--ink);
}
.hue-meta{
display:flex;align-items:baseline;gap:16px;margin-top:14px;
}
.hue-hex{
font-family:var(--sans);font-size:12px;letter-spacing:.22em;
text-transform:uppercase;color:var(--accent);
}
.hue-dot{width:8px;height:8px;border-radius:50%;background:var(--muted);display:inline-block}
.hue-family{font-size:12px;letter-spacing:.22em;text-transform:uppercase;color:var(--muted)}
.tip{
margin-top:26px;
padding-left:22px;
border-left:2px solid var(--accent);
max-width:640px;
}
.tip .tip-label{
font-size:11px;letter-spacing:.3em;text-transform:uppercase;
color:var(--muted);display:block;margin-bottom:8px;
}
.tip p{font-size:20px;line-height:1.62;color:var(--ink-soft)}
/* ---- CTA ---- */
.cta{justify-content:center;align-items:center;text-align:center}
.cta .palette-strip{
display:flex;width:520px;height:140px;border-radius:12px;overflow:hidden;
box-shadow:var(--shadow);border:1px solid var(--line-soft);margin-bottom:44px;
}
.cta .palette-strip > div{flex:1}
.cta h2{
font-family:var(--serif);font-weight:500;font-size:66px;line-height:1.02;
color:var(--ink);
}
.cta h2 em{font-style:italic;color:var(--accent)}
.cta p{font-size:20px;line-height:1.6;color:var(--ink-soft);max-width:560px;margin:24px 0 40px}
.cta .btn{
font-family:var(--sans);font-size:13px;letter-spacing:.24em;text-transform:uppercase;
color:var(--surface);background:var(--accent);
padding:20px 46px;border-radius:44px;border:none;
box-shadow:var(--shadow-soft);cursor:pointer;
transition:transform .2s var(--ease),background .2s var(--ease);
}
.cta .btn:hover{transform:translateY(-2px);background:#8e5325}
.cta .handle{margin-top:30px;font-size:12px;letter-spacing:.28em;text-transform:uppercase;color:var(--muted)}
/* entrance stagger */
.slide.active .anim{animation:fadeUp .7s var(--ease) both}
.slide.active .anim:nth-child(2){animation-delay:.09s}
.slide.active .anim:nth-child(3){animation-delay:.18s}
.slide.active .anim:nth-child(4){animation-delay:.27s}
.slide.active .anim:nth-child(5){animation-delay:.36s}
.slide.active .anim:nth-child(6){animation-delay:.45s}
@keyframes fadeUp{from{opacity:0;transform:translateY(28px)}to{opacity:1;transform:none}}
/* ============ NAV: dots + arrows ============ */
.dots{
position:absolute;bottom:52px;left:50%;transform:translateX(-50%);
display:flex;gap:12px;z-index:40;
}
.dots button{
width:9px;height:9px;border-radius:50%;border:1px solid var(--accent);
background:transparent;padding:0;cursor:pointer;
transition:all .3s var(--ease);
}
.dots button.on{background:var(--accent);width:26px;border-radius:6px}
.arrow{
position:absolute;top:50%;transform:translateY(-50%);
width:60px;height:60px;border-radius:50%;
background:rgba(251,246,238,.82);border:1px solid var(--line);
color:var(--ink);font-size:22px;cursor:pointer;z-index:40;
display:flex;align-items:center;justify-content:center;
box-shadow:var(--shadow-soft);
transition:transform .2s var(--ease),opacity .2s var(--ease);
}
.arrow:hover{transform:translateY(-50%) scale(1.06)}
.arrow.prev{left:32px}
.arrow.next{right:32px}
.arrow[disabled]{opacity:.28;cursor:default}
.pageno{
position:absolute;bottom:52px;right:52px;z-index:40;
font-family:var(--serif);font-style:italic;font-size:18px;color:var(--muted);
}
</style>
</head>
<body>
<div class="stage-wrap">
<div class="stage" id="stage">
<!-- TOP BAR -->
<header class="topbar">
<div class="lockup">
<div class="wordmark">Designer<br>Wallcoverings</div>
<div class="sub">Est. Interiors</div>
</div>
<div class="season-chip" id="seasonChip">Autumn 2026</div>
</header>
<!-- SLIDES injected here -->
<div class="track" id="track"></div>
<button class="arrow prev" id="prev" aria-label="Previous">‹</button>
<button class="arrow next" id="next" aria-label="Next">›</button>
<nav class="dots" id="dots"></nav>
<div class="pageno" id="pageno">01 / 05</div>
</div>
</div>
<script>
/* ============================================================
EDITABLE PALETTE — change these and the whole story rebuilds
============================================================ */
const STORY = {
season: "Autumn 2026",
paletteName: ["Terracotta", "Sage"], // rendered as "Terracotta & Sage"
lede: "A grounded, sun-warmed trio for rooms that feel collected, not decorated — earthen clay meets soft botanical calm.",
handle: "@designerwallcoverings",
hues: [
{
name: "Oatmeal",
hex: "#d9ccb4",
family: "Warm Neutral",
tip: "Wrap an entire study or hallway to build a quiet, tonal envelope — it flatters oak, brass, and low evening light."
},
{
name: "Celadon",
hex: "#9fb094",
family: "Muted Botanical",
tip: "Ideal on a single feature wall behind linen upholstery; its greyed green cools a south-facing bedroom without going cold."
},
{
name: "Terracotta",
hex: "#b56a44",
family: "Earthen Clay",
tip: "Use in a dining room or powder room where candlelight can deepen it — pair with unlacquered brass and cream millwork."
}
]
};
/* ---------- build slides ---------- */
const track = document.getElementById('track');
document.getElementById('seasonChip').textContent = STORY.season;
function coverSlide(){
const mini = STORY.hues.map(h=>`<div class="swatch-mini" style="background:${h.hex}"></div>`).join('');
return `<section class="slide cover active" data-i="0">
<div class="kicker anim">${STORY.season} · Color Story</div>
<h1 class="anim">${STORY.paletteName[0]}<br><em>&</em> ${STORY.paletteName[1]}</h1>
<p class="lede anim">${STORY.lede}</p>
<div class="rule anim"></div>
<div class="chip-row anim">${mini}</div>
</section>`;
}
function hueSlide(h,i){
return `<section class="slide hue" data-i="${i+1}">
<div class="index anim">No. 0${i+1} of three</div>
<div class="swatch-hero anim" style="background:${h.hex}"></div>
<div class="hue-name anim">${h.name}</div>
<div class="hue-meta anim">
<span class="hue-hex">${h.hex}</span>
<span class="hue-dot"></span>
<span class="hue-family">${h.family}</span>
</div>
<div class="tip anim">
<span class="tip-label">Room Use</span>
<p>${h.tip}</p>
</div>
</section>`;
}
function ctaSlide(){
const strip = STORY.hues.map(h=>`<div style="background:${h.hex}"></div>`).join('');
return `<section class="slide cta" data-i="4">
<div class="palette-strip anim">${strip}</div>
<div class="kicker anim">${STORY.paletteName[0]} & ${STORY.paletteName[1]}</div>
<h2 class="anim">Bring the story<br><em>home</em></h2>
<p class="anim">Order hand-cut samples of all three hues and see how the light in your own rooms shapes the palette.</p>
<button class="btn anim">Request Samples</button>
<div class="handle anim">${STORY.handle}</div>
</section>`;
}
track.innerHTML = coverSlide()
+ STORY.hues.map(hueSlide).join('')
+ ctaSlide();
const slides = [...track.children];
const N = slides.length;
/* ---------- dots ---------- */
const dotsWrap = document.getElementById('dots');
slides.forEach((_,i)=>{
const b=document.createElement('button');
if(i===0)b.classList.add('on');
b.addEventListener('click',()=>go(i));
dotsWrap.appendChild(b);
});
const dots=[...dotsWrap.children];
const pageno=document.getElementById('pageno');
const prev=document.getElementById('prev');
const next=document.getElementById('next');
let idx=0;
function render(){
track.style.transform = `translateX(${-idx*1080}px)`;
slides.forEach((s,i)=>s.classList.toggle('active',i===idx));
dots.forEach((d,i)=>d.classList.toggle('on',i===idx));
pageno.textContent = `0${idx+1} / 0${N}`;
prev.disabled = idx===0;
next.disabled = idx===N-1;
}
function go(i){ idx=Math.max(0,Math.min(N-1,i)); render(); }
prev.addEventListener('click',()=>go(idx-1));
next.addEventListener('click',()=>go(idx+1));
document.addEventListener('keydown',e=>{
if(e.key==='ArrowRight')go(idx+1);
if(e.key==='ArrowLeft')go(idx-1);
});
/* ---------- drag / swipe ---------- */
let startX=0,dx=0,dragging=false;
function down(x){dragging=true;startX=x;dx=0;track.classList.add('dragging');}
function move(x){ if(!dragging)return; dx=x-startX; track.style.transform=`translateX(${-idx*1080+dx}px)`; }
function up(){
if(!dragging)return;
dragging=false;track.classList.remove('dragging');
if(Math.abs(dx)>110){ go(idx + (dx<0?1:-1)); } else { render(); }
}
const stage=document.getElementById('stage');
stage.addEventListener('mousedown',e=>{e.preventDefault();down(e.clientX);});
window.addEventListener('mousemove',e=>move(e.clientX));
window.addEventListener('mouseup',up);
stage.addEventListener('touchstart',e=>down(e.touches[0].clientX),{passive:true});
stage.addEventListener('touchmove',e=>move(e.touches[0].clientX),{passive:true});
stage.addEventListener('touchend',up);
/* ---------- scale 1080 stage to fit container ---------- */
function fit(){
const wrap=document.querySelector('.stage-wrap');
const s=wrap.clientWidth/1080;
stage.style.transform=`scale(${s})`;
wrap.style.height=wrap.clientWidth+'px';
}
window.addEventListener('resize',fit);
fit();
render();
</script>
</body>
</html>