← 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>&amp;</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]} &amp; ${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>