← back to Model Arena
data/artifacts/145b5d1ed01f/grok.html
856 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Grandmillennial — Designer Wallcoverings</title>
<style>
:root {
--bg: #0d0d0f;
--surface: #17171c;
--text: #f5f2ea;
--muted: #8a8578;
--accent: #c9a961;
--accent2: #7d6a45;
--hairline: rgba(245,242,234,0.12);
--shadow: 0 12px 40px rgba(0,0,0,0.45);
--ease: cubic-bezier(.22,.9,.24,1);
--ease-hero: cubic-bezier(.22,1,.36,1);
--display: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, 'Times New Roman', serif;
--sans: 'Avenir Next', 'Century Gothic', 'Helvetica Neue', sans-serif;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
height: 100%;
background: var(--bg);
color: var(--text);
font-family: var(--sans);
font-size: 16px;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
overflow: hidden;
}
/* Fixed top bar */
.topbar {
position: fixed;
top: 0; left: 0; right: 0;
z-index: 100;
height: 56px;
display: flex;
align-items: center;
padding: 0 28px;
background: rgba(13,13,15,0.92);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--hairline);
}
.wordmark {
font-family: var(--display);
font-size: 13px;
font-weight: 400;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--text);
}
/* Stage */
.stage {
position: absolute;
inset: 56px 0 0 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 32px 20px 28px;
}
.carousel-shell {
width: min(420px, 100%);
display: flex;
flex-direction: column;
gap: 20px;
}
/* Phone frame */
.phone {
position: relative;
width: 100%;
aspect-ratio: 9 / 16;
max-height: calc(100vh - 160px);
background: var(--surface);
border: 1px solid var(--hairline);
border-radius: 4px;
box-shadow: var(--shadow);
overflow: hidden;
}
.track {
display: flex;
height: 100%;
transition: transform 0.7s var(--ease-hero);
will-change: transform;
}
.slide {
flex: 0 0 100%;
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
/* —— COVER —— */
.slide-cover {
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 36px 32px 48px;
background:
radial-gradient(ellipse 80% 60% at 70% 20%, rgba(201,169,97,0.14), transparent 60%),
linear-gradient(165deg, #1a1814 0%, #0d0d0f 55%, #12100e 100%);
}
.cover-ornament {
position: absolute;
inset: 0;
opacity: 0.07;
background-image:
repeating-linear-gradient(0deg, transparent, transparent 39px, var(--accent) 39px, var(--accent) 40px),
repeating-linear-gradient(90deg, transparent, transparent 39px, var(--accent) 39px, var(--accent) 40px);
pointer-events: none;
}
.cover-kicker {
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 18px;
font-weight: 500;
}
.cover-title {
font-family: var(--display);
font-size: clamp(42px, 11vw, 56px);
font-weight: 400;
line-height: 1.05;
letter-spacing: -0.03em;
color: var(--text);
margin-bottom: 16px;
}
.cover-title[contenteditable]:focus {
outline: 1px solid var(--accent);
outline-offset: 6px;
}
.cover-rule {
width: 48px;
height: 1px;
background: var(--accent);
margin-bottom: 18px;
}
.cover-sub {
font-size: 14px;
color: var(--muted);
max-width: 28ch;
line-height: 1.65;
}
.cover-palette {
position: absolute;
top: 36px;
right: 28px;
display: flex;
flex-direction: column;
gap: 8px;
align-items: flex-end;
}
.cover-palette label {
font-size: 10px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
}
.swatches {
display: flex;
gap: 6px;
}
.swatch-dot {
width: 18px;
height: 18px;
border-radius: 50%;
border: 1px solid var(--hairline);
cursor: pointer;
transition: transform 0.3s var(--ease);
}
.swatch-dot:hover { transform: scale(1.15); }
.swatch-dot.active { box-shadow: 0 0 0 1.5px var(--bg), 0 0 0 2.5px var(--accent); }
/* —— LOOK SLIDES —— */
.slide-look {
display: grid;
grid-template-rows: 1fr 1fr auto;
height: 100%;
background: var(--bg);
}
.pattern-panel {
position: relative;
overflow: hidden;
border-bottom: 1px solid var(--hairline);
}
.pattern-label {
position: absolute;
top: 16px;
left: 20px;
z-index: 2;
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--text);
background: rgba(13,13,15,0.55);
padding: 6px 10px;
border: 1px solid var(--hairline);
backdrop-filter: blur(6px);
}
/* CSS patterns */
.pat-chintz {
background-color: #1c1814;
background-image:
radial-gradient(circle at 20% 30%, rgba(201,169,97,0.35) 0 3px, transparent 4px),
radial-gradient(circle at 60% 55%, rgba(201,169,97,0.25) 0 2px, transparent 3px),
radial-gradient(circle at 80% 20%, rgba(245,242,234,0.12) 0 5px, transparent 6px),
radial-gradient(circle at 35% 75%, rgba(201,169,97,0.2) 0 4px, transparent 5px),
radial-gradient(ellipse 18px 28px at 50% 40%, transparent 40%, rgba(125,106,69,0.35) 42%, transparent 48%),
radial-gradient(ellipse 14px 22px at 25% 60%, transparent 40%, rgba(201,169,97,0.2) 42%, transparent 50%),
radial-gradient(ellipse 16px 24px at 75% 70%, transparent 40%, rgba(125,106,69,0.28) 42%, transparent 50%);
background-size: 80px 90px;
}
.pat-toile {
background-color: #141210;
background-image:
linear-gradient(30deg, transparent 48%, rgba(201,169,97,0.15) 49%, rgba(201,169,97,0.15) 51%, transparent 52%),
linear-gradient(-30deg, transparent 48%, rgba(201,169,97,0.1) 49%, rgba(201,169,97,0.1) 51%, transparent 52%),
radial-gradient(circle at 30% 40%, rgba(245,242,234,0.06) 0 12px, transparent 13px),
radial-gradient(circle at 70% 65%, rgba(201,169,97,0.1) 0 18px, transparent 19px);
background-size: 60px 60px, 60px 60px, 100px 100px, 120px 120px;
}
.pat-damask {
background-color: #12100e;
background-image:
radial-gradient(ellipse 40% 50% at 50% 50%, rgba(201,169,97,0.18) 0%, transparent 70%),
repeating-conic-gradient(from 0deg at 50% 50%, transparent 0deg 20deg, rgba(125,106,69,0.12) 20deg 22deg, transparent 22deg 40deg),
radial-gradient(circle at 50% 20%, rgba(201,169,97,0.2) 0 2px, transparent 3px),
radial-gradient(circle at 50% 80%, rgba(201,169,97,0.2) 0 2px, transparent 3px),
radial-gradient(circle at 20% 50%, rgba(201,169,97,0.15) 0 2px, transparent 3px),
radial-gradient(circle at 80% 50%, rgba(201,169,97,0.15) 0 2px, transparent 3px);
background-size: 100% 100%, 70px 70px, 70px 70px, 70px 70px, 70px 70px, 70px 70px;
}
/* Room vignettes */
.room-panel {
position: relative;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
background: linear-gradient(180deg, #141210 0%, #0d0d0f 100%);
overflow: hidden;
}
.room {
width: 100%;
height: 100%;
position: relative;
border: 1px solid var(--hairline);
background: #1a1714;
overflow: hidden;
}
/* Room 1 — parlor with chintz wall */
.room-parlor .wall {
position: absolute; inset: 0 0 28% 0;
background:
radial-gradient(circle at 18% 35%, rgba(201,169,97,0.3) 0 2px, transparent 3px),
radial-gradient(circle at 55% 50%, rgba(201,169,97,0.22) 0 1.5px, transparent 2.5px),
radial-gradient(circle at 78% 28%, rgba(245,242,234,0.1) 0 3px, transparent 4px),
radial-gradient(ellipse 10px 16px at 40% 45%, transparent 40%, rgba(125,106,69,0.3) 42%, transparent 50%),
#1e1a16;
background-size: 36px 42px;
}
.room-parlor .wainscot {
position: absolute; left: 0; right: 0; bottom: 28%; height: 18%;
background: linear-gradient(180deg, #2a2420 0%, #1f1b18 100%);
border-top: 2px solid var(--accent2);
}
.room-parlor .floor {
position: absolute; left: 0; right: 0; bottom: 0; height: 28%;
background:
repeating-linear-gradient(90deg, #1a1612 0 14px, #221e19 14px 15px);
}
.room-parlor .sofa {
position: absolute;
bottom: 22%;
left: 18%;
right: 18%;
height: 22%;
background: #2c2824;
border-radius: 6px 6px 2px 2px;
border: 1px solid rgba(201,169,97,0.2);
box-shadow: 0 4px 12px rgba(0,0,0,0.35);
}
.room-parlor .sofa::before {
content: '';
position: absolute;
top: -28%;
left: 4%;
right: 4%;
height: 40%;
background: #34302b;
border-radius: 4px 4px 0 0;
border: 1px solid rgba(201,169,97,0.15);
}
.room-parlor .pillow {
position: absolute;
width: 18%;
height: 45%;
top: 18%;
border-radius: 3px;
border: 1px solid rgba(201,169,97,0.25);
}
.room-parlor .pillow.p1 { left: 12%; background: #c9a961; opacity: 0.7; }
.room-parlor .pillow.p2 { right: 12%; background: #8a7a55; opacity: 0.6; }
.room-parlor .frame {
position: absolute;
top: 12%;
left: 50%;
transform: translateX(-50%);
width: 22%;
height: 28%;
border: 2px solid var(--accent2);
background: #0d0d0f;
box-shadow: inset 0 0 0 3px #1a1714;
}
.room-parlor .lamp {
position: absolute;
bottom: 40%;
right: 10%;
width: 8%;
height: 30%;
}
.room-parlor .lamp::before {
content: '';
position: absolute;
bottom: 0; left: 40%;
width: 20%; height: 55%;
background: var(--accent2);
}
.room-parlor .lamp::after {
content: '';
position: absolute;
bottom: 50%; left: 0;
width: 100%; height: 45%;
background: rgba(201,169,97,0.35);
clip-path: polygon(15% 100%, 85% 100%, 100% 0, 0 0);
}
/* Room 2 — powder room toile */
.room-powder .wall {
position: absolute; inset: 0 0 20% 0;
background-color: #161310;
background-image:
linear-gradient(28deg, transparent 48%, rgba(201,169,97,0.12) 49%, rgba(201,169,97,0.12) 51%, transparent 52%),
linear-gradient(-28deg, transparent 48%, rgba(201,169,97,0.08) 49%, rgba(201,169,97,0.08) 51%, transparent 52%),
radial-gradient(circle at 40% 35%, rgba(245,242,234,0.05) 0 8px, transparent 9px);
background-size: 28px 28px, 28px 28px, 50px 50px;
}
.room-powder .vanity {
position: absolute;
bottom: 18%;
left: 15%;
right: 15%;
height: 16%;
background: linear-gradient(180deg, #2e2924, #24201c);
border-top: 1px solid var(--accent);
}
.room-powder .mirror {
position: absolute;
top: 10%;
left: 50%;
transform: translateX(-50%);
width: 36%;
height: 38%;
border: 3px solid var(--accent2);
border-radius: 50% 50% 45% 45%;
background: linear-gradient(145deg, #1a2228, #0e1216);
box-shadow: 0 0 0 1px rgba(201,169,97,0.2), inset 0 0 20px rgba(201,169,97,0.05);
}
.room-powder .sconce {
position: absolute;
top: 28%;
width: 6%;
height: 14%;
background: var(--accent);
opacity: 0.5;
border-radius: 2px 2px 50% 50%;
}
.room-powder .sconce.l { left: 18%; }
.room-powder .sconce.r { right: 18%; }
.room-powder .floor {
position: absolute; left: 0; right: 0; bottom: 0; height: 20%;
background:
repeating-linear-gradient(45deg, #1a1612 0 8px, #221c18 8px 16px);
}
.room-powder .basin {
position: absolute;
bottom: 28%;
left: 50%;
transform: translateX(-50%);
width: 22%;
height: 8%;
background: #f5f2ea;
opacity: 0.85;
border-radius: 0 0 40% 40%;
}
/* Room 3 — library damask */
.room-library .wall {
position: absolute; inset: 0 0 24% 0;
background:
radial-gradient(ellipse 30% 40% at 50% 40%, rgba(201,169,97,0.12) 0%, transparent 70%),
repeating-conic-gradient(from 0deg at 50% 50%, transparent 0deg 18deg, rgba(125,106,69,0.1) 18deg 20deg, transparent 20deg 36deg),
#181512;
background-size: 100% 100%, 48px 48px;
}
.room-library .shelves {
position: absolute;
top: 8%;
left: 8%;
bottom: 30%;
width: 28%;
display: flex;
flex-direction: column;
gap: 4px;
padding: 6px;
border: 1px solid rgba(201,169,97,0.2);
background: rgba(0,0,0,0.25);
}
.room-library .book {
flex: 1;
background: var(--accent2);
opacity: 0.55;
border-radius: 1px;
}
.room-library .book:nth-child(2n) { opacity: 0.35; background: #5a4a32; }
.room-library .book:nth-child(3n) { opacity: 0.7; background: #c9a961; }
.room-library .chair {
position: absolute;
bottom: 20%;
right: 18%;
width: 32%;
height: 32%;
}
.room-library .chair-back {
position: absolute;
top: 0; left: 10%; right: 10%;
height: 55%;
background: #2a2420;
border: 1px solid rgba(201,169,97,0.25);
border-radius: 40% 40% 2px 2px;
}
.room-library .chair-seat {
position: absolute;
bottom: 15%; left: 0; right: 0;
height: 30%;
background: #322c26;
border: 1px solid rgba(201,169,97,0.2);
border-radius: 3px;
}
.room-library .chair-leg {
position: absolute;
bottom: 0;
width: 6%;
height: 18%;
background: var(--accent2);
}
.room-library .chair-leg.l { left: 12%; }
.room-library .chair-leg.r { right: 12%; }
.room-library .floor {
position: absolute; left: 0; right: 0; bottom: 0; height: 24%;
background: repeating-linear-gradient(90deg, #1c1814 0 18px, #241f1a 18px 19px);
}
.room-library .rug {
position: absolute;
bottom: 8%;
left: 20%;
right: 12%;
height: 14%;
background:
repeating-linear-gradient(90deg, transparent 0 6px, rgba(201,169,97,0.15) 6px 7px),
repeating-linear-gradient(0deg, transparent 0 6px, rgba(201,169,97,0.1) 6px 7px),
#2a2218;
border: 1px solid rgba(201,169,97,0.2);
}
/* Note strip */
.note-strip {
padding: 18px 24px 22px;
border-top: 1px solid var(--hairline);
background: var(--surface);
}
.note-num {
font-size: 10px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 6px;
}
.note-text {
font-family: var(--display);
font-size: 17px;
line-height: 1.35;
letter-spacing: -0.01em;
color: var(--text);
font-weight: 400;
}
/* —— CTA —— */
.slide-cta {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 40px 36px;
background:
radial-gradient(ellipse 70% 50% at 50% 40%, rgba(201,169,97,0.1), transparent 65%),
var(--bg);
}
.cta-ornament {
width: 40px;
height: 1px;
background: var(--accent);
margin-bottom: 28px;
}
.cta-kicker {
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 16px;
}
.cta-title {
font-family: var(--display);
font-size: clamp(28px, 7vw, 36px);
line-height: 1.15;
letter-spacing: -0.02em;
margin-bottom: 16px;
max-width: 14ch;
}
.cta-body {
font-size: 14px;
color: var(--muted);
max-width: 28ch;
margin-bottom: 32px;
line-height: 1.65;
}
.cta-btn {
display: inline-block;
padding: 14px 32px;
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--bg);
background: var(--accent);
border: none;
cursor: pointer;
transition: background 0.35s var(--ease), transform 0.35s var(--ease);
}
.cta-btn:hover {
background: #d4b86e;
transform: translateY(-1px);
}
.cta-fine {
margin-top: 28px;
font-size: 11px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--muted);
}
/* Dots + nav */
.controls {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
}
.nav-btn {
width: 36px;
height: 36px;
border-radius: 50%;
border: 1px solid var(--hairline);
background: transparent;
color: var(--text);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.nav-btn:hover {
border-color: var(--accent);
background: rgba(201,169,97,0.08);
}
.nav-btn svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.5; }
.dots {
display: flex;
gap: 8px;
align-items: center;
}
.dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--muted);
opacity: 0.4;
border: none;
cursor: pointer;
padding: 0;
transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), background 0.35s var(--ease);
}
.dot.active {
opacity: 1;
background: var(--accent);
transform: scale(1.35);
}
.hint {
text-align: center;
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
opacity: 0.7;
}
/* Entrance */
.phone { animation: rise 0.9s var(--ease-hero) both; }
@keyframes rise {
from { opacity: 0; transform: translateY(18px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
<header class="topbar">
<div class="wordmark">Designer Wallcoverings</div>
</header>
<main class="stage">
<div class="carousel-shell">
<div class="phone" id="phone">
<div class="track" id="track">
<!-- COVER -->
<section class="slide slide-cover">
<div class="cover-ornament"></div>
<div class="cover-palette">
<label>Palette</label>
<div class="swatches" id="paletteSwatches">
<button class="swatch-dot active" data-p="luxe" style="background:#c9a961" title="Gilt"></button>
<button class="swatch-dot" data-p="ivory" style="background:#f5f2ea" title="Ivory"></button>
<button class="swatch-dot" data-p="sage" style="background:#8a9a7b" title="Sage"></button>
<button class="swatch-dot" data-p="blush" style="background:#c4a4a0" title="Blush"></button>
</div>
</div>
<div class="cover-kicker">Lookbook No. 07</div>
<h1 class="cover-title" contenteditable="true" spellcheck="false">Grand­millennial</h1>
<div class="cover-rule"></div>
<p class="cover-sub">Heirloom florals, layered pattern, and collected charm — reimagined for the modern home.</p>
</section>
<!-- SLIDE 1 -->
<section class="slide slide-look">
<div class="pattern-panel pat-chintz">
<span class="pattern-label">Chintz · No. 14</span>
</div>
<div class="room-panel">
<div class="room room-parlor">
<div class="wall"></div>
<div class="wainscot"></div>
<div class="floor"></div>
<div class="frame"></div>
<div class="sofa">
<div class="pillow p1"></div>
<div class="pillow p2"></div>
</div>
<div class="lamp"></div>
</div>
</div>
<div class="note-strip">
<div class="note-num">01 — Parlor</div>
<p class="note-text">Pair a dense chintz wall with solid velvet seating so the print can breathe.</p>
</div>
</section>
<!-- SLIDE 2 -->
<section class="slide slide-look">
<div class="pattern-panel pat-toile">
<span class="pattern-label">Toile · No. 22</span>
</div>
<div class="room-panel">
<div class="room room-powder">
<div class="wall"></div>
<div class="floor"></div>
<div class="mirror"></div>
<div class="sconce l"></div>
<div class="sconce r"></div>
<div class="vanity"></div>
<div class="basin"></div>
</div>
</div>
<div class="note-strip">
<div class="note-num">02 — Powder</div>
<p class="note-text">A monochrome toile envelops small rooms in narrative without visual noise.</p>
</div>
</section>
<!-- SLIDE 3 -->
<section class="slide slide-look">
<div class="pattern-panel pat-damask">
<span class="pattern-label">Damask · No. 09</span>
</div>
<div class="room-panel">
<div class="room room-library">
<div class="wall"></div>
<div class="floor"></div>
<div class="shelves">
<div class="book"></div><div class="book"></div><div class="book"></div>
<div class="book"></div><div class="book"></div><div class="book"></div>
</div>
<div class="chair">
<div class="chair-back"></div>
<div class="chair-seat"></div>
<div class="chair-leg l"></div>
<div class="chair-leg r"></div>
</div>
<div class="rug"></div>
</div>
</div>
<div class="note-strip">
<div class="note-num">03 — Library</div>
<p class="note-text">Tone-on-tone damask lends quiet grandeur behind dark wood and leather.</p>
</div>
</section>
<!-- CTA -->
<section class="slide slide-cta">
<div class="cta-ornament"></div>
<div class="cta-kicker">Request the collection</div>
<h2 class="cta-title">Wallpaper, made to be lived with.</h2>
<p class="cta-body">Explore Grandmillennial papers, borders, and coordinating textiles — sampled to your door.</p>
<button class="cta-btn" type="button">Order Samples</button>
<p class="cta-fine">Designer Wallcoverings · Est. 1987</p>
</section>
</div>
</div>
<div class="controls">
<button class="nav-btn" id="prev" aria-label="Previous">
<svg viewBox="0 0 24 24"><path d="M15 18l-6-6 6-6"/></svg>
</button>
<div class="dots" id="dots"></div>
<button class="nav-btn" id="next" aria-label="Next">
<svg viewBox="0 0 24 24"><path d="M9 18l6-6-6-6"/></svg>
</button>
</div>
<p class="hint">Swipe · Edit the style name</p>
</div>
</main>
<script>
(function () {
const track = document.getElementById('track');
const phone = document.getElementById('phone');
const dotsWrap = document.getElementById('dots');
const slides = track.querySelectorAll('.slide');
const total = slides.length;
let index = 0;
let startX = 0, deltaX = 0, dragging = false;
for (let i = 0; i < total; i++) {
const b = document.createElement('button');
b.className = 'dot' + (i === 0 ? ' active' : '');
b.setAttribute('aria-label', 'Slide ' + (i + 1));
b.addEventListener('click', () => go(i));
dotsWrap.appendChild(b);
}
const dots = dotsWrap.querySelectorAll('.dot');
function go(i) {
index = Math.max(0, Math.min(total - 1, i));
track.style.transform = 'translateX(' + (-index * 100) + '%)';
dots.forEach((d, n) => d.classList.toggle('active', n === index));
}
document.getElementById('prev').addEventListener('click', () => go(index - 1));
document.getElementById('next').addEventListener('click', () => go(index + 1));
// Touch / pointer swipe
phone.addEventListener('pointerdown', (e) => {
if (e.target.closest('button, [contenteditable]')) return;
dragging = true;
startX = e.clientX;
deltaX = 0;
phone.setPointerCapture(e.pointerId);
track.style.transition = 'none';
});
phone.addEventListener('pointermove', (e) => {
if (!dragging) return;
deltaX = e.clientX - startX;
const pct = (deltaX / phone.offsetWidth) * 100;
track.style.transform = 'translateX(calc(' + (-index * 100) + '% + ' + pct + '%))';
});
phone.addEventListener('pointerup', () => {
if (!dragging) return;
dragging = false;
track.style.transition = '';
if (Math.abs(deltaX) > phone.offsetWidth * 0.2) {
go(index + (deltaX < 0 ? 1 : -1));
} else {
go(index);
}
});
phone.addEventListener('pointercancel', () => {
dragging = false;
track.style.transition = '';
go(index);
});
// Keyboard
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowRight') go(index + 1);
if (e.key === 'ArrowLeft') go(index - 1);
});
// Editable palette
const roots = {
luxe: { accent: '#c9a961', accent2: '#7d6a45' },
ivory: { accent: '#d4cfc0', accent2: '#9a9484' },
sage: { accent: '#8a9a7b', accent2: '#5c6b52' },
blush: { accent: '#c4a4a0', accent2: '#8a6e6a' }
};
document.getElementById('paletteSwatches').addEventListener('click', (e) => {
const btn = e.target.closest('.swatch-dot');
if (!btn) return;
document.querySelectorAll('.swatch-dot').forEach(s => s.classList.remove('active'));
btn.classList.add('active');
const p = roots[btn.dataset.p];
if (!p) return;
document.documentElement.style.setProperty('--accent', p.accent);
document.documentElement.style.setProperty('--accent2', p.accent2);
});
})();
</script>
</body>
</html>