← back to Model Arena
data/artifacts/0a809ac3ac48/grok.html
681 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Color of the Season — Designer Wallcoverings</title>
<style>
:root {
--bg: #0d0d0f;
--surface: #17171c;
--ink: #1c1a17;
--text: #f5f2ea;
--muted: #8a8578;
--accent: #c9a961;
--accent-dim: #7d6a45;
--celadon: #7ba892;
--celadon-deep: #4a7a66;
--celadon-light: #a8cfc0;
--celadon-mist: #d4e8df;
--line: rgba(245, 242, 234, 0.12);
--shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
--ease: cubic-bezier(.22, .9, .24, 1);
--ease-scene: cubic-bezier(.77, 0, .18, 1);
--ease-hero: cubic-bezier(.22, 1, .36, 1);
--serif: 'Didot', 'Bodoni MT', 'Playfair Display', 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
--sans: 'Avenir Next', 'Century Gothic', Futura, 'Helvetica Neue', sans-serif;
--bar-h: 72px;
--reel-w: 360px;
--reel-h: 640px;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
height: 100%;
background: #050505;
display: flex;
align-items: center;
justify-content: center;
font-family: var(--sans);
color: var(--text);
-webkit-font-smoothing: antialiased;
}
/* ── Reel frame ── */
.reel {
position: relative;
width: min(100vw, var(--reel-w));
height: min(100vh, var(--reel-h));
background: var(--bg);
overflow: hidden;
box-shadow: var(--shadow), 0 0 0 1px var(--line);
display: flex;
flex-direction: column;
}
/* ── Header / wordmark ── */
.brand-bar {
position: absolute;
top: 0; left: 0; right: 0;
z-index: 50;
height: var(--bar-h);
padding: 14px 18px 10px;
display: flex;
align-items: flex-start;
background: linear-gradient(to bottom, rgba(13,13,15,0.92) 0%, rgba(13,13,15,0.55) 70%, transparent 100%);
pointer-events: none;
}
.wordmark {
font-family: var(--serif);
font-size: 15px;
font-weight: 400;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--text);
line-height: 1.35;
max-width: 220px;
}
/* ── Progress ── */
.progress-track {
position: absolute;
top: 0; left: 0; right: 0;
height: 2px;
background: rgba(245,242,234,0.08);
z-index: 60;
display: flex;
gap: 3px;
padding: 0 2px;
}
.progress-seg {
flex: 1;
height: 100%;
background: rgba(245,242,234,0.12);
overflow: hidden;
border-radius: 1px;
}
.progress-fill {
height: 100%;
width: 0%;
background: var(--accent);
transition: none;
}
.progress-fill.active {
transition: width linear;
}
.progress-fill.done {
width: 100%;
}
/* ── Scenes ── */
.scenes {
flex: 1;
position: relative;
}
.scene {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: calc(var(--bar-h) + 12px) 28px 80px;
opacity: 0;
visibility: hidden;
transition: opacity 0.7s var(--ease-scene), visibility 0.7s;
text-align: center;
}
.scene.active {
opacity: 1;
visibility: visible;
}
/* captions */
.caption {
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 18px;
opacity: 0;
transform: translateY(12px);
transition: opacity 0.6s var(--ease-hero) 0.15s, transform 0.6s var(--ease-hero) 0.15s;
}
.scene.active .caption {
opacity: 1;
transform: translateY(0);
}
.headline {
font-family: var(--serif);
font-weight: 400;
line-height: 1.1;
letter-spacing: -0.02em;
color: var(--text);
opacity: 0;
transform: translateY(20px);
transition: opacity 0.75s var(--ease-hero) 0.3s, transform 0.75s var(--ease-hero) 0.3s;
}
.scene.active .headline {
opacity: 1;
transform: translateY(0);
}
.sub {
font-family: var(--sans);
font-size: 14px;
line-height: 1.6;
color: var(--muted);
max-width: 280px;
margin-top: 16px;
opacity: 0;
transform: translateY(14px);
transition: opacity 0.7s var(--ease-hero) 0.5s, transform 0.7s var(--ease-hero) 0.5s;
}
.scene.active .sub {
opacity: 1;
transform: translateY(0);
}
/* Scene 1 — Hook */
.scene-hook .headline {
font-size: 32px;
max-width: 260px;
}
.scene-hook .ellipsis {
color: var(--accent);
}
/* Scene 2 — Hue name */
.scene-hue {
background:
radial-gradient(ellipse 80% 60% at 50% 55%, rgba(123,168,146,0.18) 0%, transparent 70%),
var(--bg);
}
.scene-hue .hue-name {
font-family: var(--serif);
font-size: 64px;
letter-spacing: -0.03em;
line-height: 1;
color: var(--celadon-light);
opacity: 0;
transform: scale(0.92) translateY(16px);
transition: opacity 0.9s var(--ease-hero) 0.25s, transform 0.9s var(--ease-hero) 0.25s;
}
.scene.active .hue-name {
opacity: 1;
transform: scale(1) translateY(0);
}
.hue-swatch-bar {
width: 64px;
height: 3px;
background: var(--celadon);
margin: 22px auto 0;
opacity: 0;
transform: scaleX(0);
transition: opacity 0.5s var(--ease) 0.7s, transform 0.6s var(--ease-hero) 0.7s;
}
.scene.active .hue-swatch-bar {
opacity: 1;
transform: scaleX(1);
}
.scene-hue .sub {
margin-top: 20px;
}
/* Scene 3 — Patterns */
.scene-patterns .headline {
font-size: 24px;
margin-bottom: 28px;
}
.swatches {
display: flex;
flex-direction: column;
gap: 14px;
width: 100%;
max-width: 260px;
opacity: 0;
transform: translateY(24px);
transition: opacity 0.8s var(--ease-hero) 0.35s, transform 0.8s var(--ease-hero) 0.35s;
}
.scene.active .swatches {
opacity: 1;
transform: translateY(0);
}
.swatch {
height: 88px;
border-radius: 2px;
border: 1px solid var(--line);
box-shadow: var(--shadow);
position: relative;
overflow: hidden;
}
/* Pattern 1 — Damask / botanical motif via radial dots */
.swatch-damask {
background-color: var(--celadon-deep);
background-image:
radial-gradient(circle at 25% 25%, var(--celadon-light) 1.5px, transparent 1.6px),
radial-gradient(circle at 75% 75%, var(--celadon-light) 1.5px, transparent 1.6px),
radial-gradient(circle at 50% 50%, rgba(168,207,192,0.35) 8px, transparent 8.5px),
radial-gradient(ellipse 40% 30% at 30% 70%, rgba(212,232,223,0.2) 0%, transparent 70%),
radial-gradient(ellipse 35% 40% at 70% 30%, rgba(212,232,223,0.15) 0%, transparent 70%);
background-size: 28px 28px, 28px 28px, 56px 56px, 100% 100%, 100% 100%;
}
/* Pattern 2 — Fine vertical pinstripe + silk sheen */
.swatch-stripe {
background-color: var(--celadon);
background-image:
repeating-linear-gradient(
90deg,
transparent 0px,
transparent 5px,
rgba(13,13,15,0.18) 5px,
rgba(13,13,15,0.18) 6px
),
linear-gradient(
180deg,
rgba(212,232,223,0.25) 0%,
transparent 40%,
transparent 60%,
rgba(74,122,102,0.3) 100%
);
}
/* Pattern 3 — Geometric lattice / trellis */
.swatch-trellis {
background-color: #3d6554;
background-image:
linear-gradient(45deg, var(--celadon-light) 1px, transparent 1.5px),
linear-gradient(-45deg, var(--celadon-light) 1px, transparent 1.5px),
linear-gradient(45deg, transparent 48%, rgba(168,207,192,0.4) 49%, rgba(168,207,192,0.4) 51%, transparent 52%),
linear-gradient(-45deg, transparent 48%, rgba(168,207,192,0.4) 49%, rgba(168,207,192,0.4) 51%, transparent 52%);
background-size: 20px 20px, 20px 20px, 40px 40px, 40px 40px;
background-position: 0 0, 0 0, 0 0, 0 0;
}
/* Scene 4 — Styling tip */
.scene-tip {
background:
radial-gradient(ellipse 70% 50% at 50% 80%, rgba(201,169,97,0.08) 0%, transparent 65%),
var(--bg);
}
.scene-tip .headline {
font-size: 28px;
max-width: 270px;
}
.tip-rule {
width: 40px;
height: 1px;
background: var(--accent);
margin: 20px auto;
opacity: 0;
transition: opacity 0.5s var(--ease) 0.55s;
}
.scene.active .tip-rule {
opacity: 1;
}
.tip-body {
font-family: var(--sans);
font-size: 15px;
line-height: 1.65;
color: var(--text);
max-width: 270px;
opacity: 0;
transform: translateY(14px);
transition: opacity 0.7s var(--ease-hero) 0.5s, transform 0.7s var(--ease-hero) 0.5s;
}
.scene.active .tip-body {
opacity: 1;
transform: translateY(0);
}
/* Scene 5 — CTA */
.scene-cta .headline {
font-size: 30px;
max-width: 260px;
}
.cta-btn {
display: inline-block;
margin-top: 28px;
padding: 14px 32px;
border: 1px solid var(--accent);
background: transparent;
color: var(--accent);
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
cursor: pointer;
opacity: 0;
transform: translateY(16px);
transition:
opacity 0.7s var(--ease-hero) 0.55s,
transform 0.7s var(--ease-hero) 0.55s,
background 0.3s var(--ease),
color 0.3s var(--ease);
}
.scene.active .cta-btn {
opacity: 1;
transform: translateY(0);
}
.cta-btn:hover {
background: var(--accent);
color: var(--ink);
}
.cta-note {
margin-top: 18px;
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
opacity: 0;
transition: opacity 0.6s var(--ease) 0.8s;
}
.scene.active .cta-note {
opacity: 1;
}
/* ── Controls ── */
.controls {
position: absolute;
bottom: 0; left: 0; right: 0;
z-index: 50;
padding: 16px 18px 20px;
display: flex;
align-items: center;
justify-content: space-between;
background: linear-gradient(to top, rgba(13,13,15,0.95) 0%, rgba(13,13,15,0.5) 70%, transparent 100%);
}
.ctrl-btn {
background: transparent;
border: 1px solid var(--line);
color: var(--muted);
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.16em;
text-transform: uppercase;
padding: 8px 14px;
cursor: pointer;
transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
display: flex;
align-items: center;
gap: 6px;
}
.ctrl-btn:hover {
color: var(--text);
border-color: var(--muted);
}
.ctrl-btn svg {
width: 10px;
height: 10px;
fill: currentColor;
}
.scene-dots {
display: flex;
gap: 6px;
}
.dot {
width: 5px;
height: 5px;
border-radius: 50%;
background: rgba(245,242,234,0.2);
transition: background 0.3s var(--ease), transform 0.3s var(--ease);
}
.dot.on {
background: var(--accent);
transform: scale(1.2);
}
.scene-label {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
min-width: 48px;
text-align: right;
}
/* Decorative corner lines */
.corner {
position: absolute;
width: 18px;
height: 18px;
z-index: 40;
pointer-events: none;
opacity: 0.35;
}
.corner-bl { bottom: 56px; left: 14px; border-left: 1px solid var(--accent); border-bottom: 1px solid var(--accent); }
.corner-br { bottom: 56px; right: 14px; border-right: 1px solid var(--accent); border-bottom: 1px solid var(--accent); }
</style>
</head>
<body>
<div class="reel" id="reel">
<!-- Progress -->
<div class="progress-track" id="progress"></div>
<!-- Brand bar -->
<header class="brand-bar">
<div class="wordmark">Designer<br>Wallcoverings</div>
</header>
<!-- Scenes -->
<div class="scenes">
<!-- 1 Hook -->
<section class="scene scene-hook active" data-dur="3200">
<p class="caption">Seasonal Edit · 2025</p>
<h1 class="headline">This season<br>it’s all about<span class="ellipsis">…</span></h1>
</section>
<!-- 2 Hue -->
<section class="scene scene-hue" data-dur="3800">
<p class="caption">Color of the Season</p>
<div class="hue-name">Celadon</div>
<div class="hue-swatch-bar"></div>
<p class="sub">A quiet jade — porcelain-born,<br>garden-soft, endlessly refined.</p>
</section>
<!-- 3 Patterns -->
<section class="scene scene-patterns" data-dur="4800">
<p class="caption">In the Collection</p>
<h2 class="headline">Three expressions</h2>
<div class="swatches">
<div class="swatch swatch-damask" title="Botanical damask"></div>
<div class="swatch swatch-stripe" title="Silk pinstripe"></div>
<div class="swatch swatch-trellis" title="Trellis lattice"></div>
</div>
</section>
<!-- 4 Tip -->
<section class="scene scene-tip" data-dur="4200">
<p class="caption">Styling Note</p>
<h2 class="headline">Pair with warm brass<br>& unbleached linen</h2>
<div class="tip-rule"></div>
<p class="tip-body">Let Celadon breathe on a single feature wall. Anchor with walnut, soft ivory plaster, and a single sculptural vessel — restraint is the luxury.</p>
</section>
<!-- 5 CTA -->
<section class="scene scene-cta" data-dur="5000">
<p class="caption">Designer Wallcoverings</p>
<h2 class="headline">Request the<br>Celadon folio</h2>
<button class="cta-btn" id="ctaBtn" type="button">Explore the Hue</button>
<p class="cta-note">Sample sets · Trade program</p>
</section>
</div>
<!-- Corners -->
<div class="corner corner-bl"></div>
<div class="corner corner-br"></div>
<!-- Controls -->
<div class="controls">
<button class="ctrl-btn" id="playBtn" type="button" aria-label="Pause">
<svg id="iconPause" viewBox="0 0 12 12"><rect x="2" y="1" width="3" height="10"/><rect x="7" y="1" width="3" height="10"/></svg>
<svg id="iconPlay" viewBox="0 0 12 12" style="display:none"><polygon points="2,1 11,6 2,11"/></svg>
<span id="playLabel">Pause</span>
</button>
<div class="scene-dots" id="dots"></div>
<span class="scene-label" id="sceneLabel">01 / 05</span>
</div>
</div>
<script>
(function () {
const scenes = Array.from(document.querySelectorAll('.scene'));
const progress = document.getElementById('progress');
const dots = document.getElementById('dots');
const playBtn = document.getElementById('playBtn');
const playLabel = document.getElementById('playLabel');
const iconPause = document.getElementById('iconPause');
const iconPlay = document.getElementById('iconPlay');
const sceneLabel = document.getElementById('sceneLabel');
const ctaBtn = document.getElementById('ctaBtn');
let idx = 0;
let playing = true;
let raf = null;
let startTs = 0;
let elapsed = 0;
let fills = [];
// Build progress segments + dots
scenes.forEach((_, i) => {
const seg = document.createElement('div');
seg.className = 'progress-seg';
const fill = document.createElement('div');
fill.className = 'progress-fill';
seg.appendChild(fill);
progress.appendChild(seg);
fills.push(fill);
const d = document.createElement('div');
d.className = 'dot' + (i === 0 ? ' on' : '');
dots.appendChild(d);
});
function pad(n) { return String(n).padStart(2, '0'); }
function showScene(n) {
scenes.forEach((s, i) => s.classList.toggle('active', i === n));
Array.from(dots.children).forEach((d, i) => d.classList.toggle('on', i === n));
sceneLabel.textContent = pad(n + 1) + ' / ' + pad(scenes.length);
fills.forEach((f, i) => {
f.classList.remove('active');
f.style.width = i < n ? '100%' : '0%';
f.style.transition = 'none';
if (i < n) f.classList.add('done');
else f.classList.remove('done');
});
elapsed = 0;
startTs = performance.now();
}
function tick(now) {
if (!playing) return;
const dur = parseInt(scenes[idx].dataset.dur, 10);
elapsed = now - startTs;
const p = Math.min(1, elapsed / dur);
const fill = fills[idx];
fill.style.transition = 'none';
fill.style.width = (p * 100) + '%';
fill.classList.add('active');
if (p >= 1) {
fill.classList.add('done');
idx = (idx + 1) % scenes.length;
if (idx === 0) fills.forEach(f => { f.style.width = '0%'; f.classList.remove('done', 'active'); });
showScene(idx);
}
raf = requestAnimationFrame(tick);
}
function play() {
playing = true;
startTs = performance.now() - elapsed;
playLabel.textContent = 'Pause';
iconPause.style.display = '';
iconPlay.style.display = 'none';
raf = requestAnimationFrame(tick);
}
function pause() {
playing = false;
if (raf) cancelAnimationFrame(raf);
playLabel.textContent = 'Play';
iconPause.style.display = 'none';
iconPlay.style.display = '';
}
playBtn.addEventListener('click', () => playing ? pause() : play());
// CTA — in-page overlay (no alert)
let overlay = null;
ctaBtn.addEventListener('click', () => {
if (overlay) return;
pause();
overlay = document.createElement('div');
overlay.setAttribute('style',
'position:absolute;inset:0;z-index:80;background:rgba(13,13,15,0.94);' +
'display:flex;flex-direction:column;align-items:center;justify-content:center;' +
'padding:40px 32px;text-align:center;'
);
overlay.innerHTML =
'<p style="font-family:var(--sans);font-size:11px;letter-spacing:0.2em;text-transform:uppercase;color:var(--muted);margin-bottom:18px;">Trade Desk</p>' +
'<h3 style="font-family:var(--serif);font-size:28px;color:var(--text);line-height:1.15;letter-spacing:-0.02em;margin-bottom:14px;">Celadon folio<br>requested</h3>' +
'<div style="width:40px;height:1px;background:var(--accent);margin:0 auto 18px;"></div>' +
'<p style="font-family:var(--sans);font-size:14px;line-height:1.6;color:var(--muted);max-width:240px;margin-bottom:28px;">Our atelier will prepare your sample set and trade pricing within two business days.</p>' +
'<button type="button" id="closeOv" style="font-family:var(--sans);font-size:10px;letter-spacing:0.18em;text-transform:uppercase;padding:12px 28px;border:1px solid var(--accent);background:transparent;color:var(--accent);cursor:pointer;">Continue</button>';
document.getElementById('reel').appendChild(overlay);
overlay.querySelector('#closeOv').addEventListener('click', () => {
overlay.remove();
overlay = null;
play();
});
});
// Kick off
showScene(0);
play();
})();
</script>
</body>
</html>