← back to Model Arena
data/artifacts/0a809ac3ac48/kimi.html
506 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>
/* DESIGN TOKENS */
:root {
/* Palette: luxe-noir */
--bg: #0d0d0f;
--surface: #17171c;
--text: #f5f2ea;
--muted: #8a8578;
--accent: #c9a961;
--accent2: #7d6a45;
--line: rgba(245, 242, 234, 0.12);
--shadow: 0 12px 48px rgba(0, 0, 0, 0.4);
/* Typography */
--font-display: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
--font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
/* Motion */
--ease: cubic-bezier(0.22, 1, 0.36, 1);
/* Season Color: Celadon */
--celadon: #b4c4a3;
--celadon-dark: #8a9a7a;
--celadon-light: #d4e4c3;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: var(--bg);
color: var(--text);
font-family: var(--font-body);
line-height: 1.6;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* HEADER */
header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
padding: 24px 32px;
display: flex;
align-items: center;
background: linear-gradient(to bottom, var(--bg) 60%, transparent);
}
.wordmark {
font-family: var(--font-display);
font-size: 42px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--text);
font-weight: 400;
line-height: 1.1;
}
/* REEL CONTAINER - 9:16 Aspect Ratio */
.reel-container {
width: 100%;
max-width: 450px;
aspect-ratio: 9/16;
background: var(--surface);
position: relative;
overflow: hidden;
box-shadow: var(--shadow);
}
/* SCENES */
.scene {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 80px 32px 120px;
opacity: 0;
pointer-events: none;
transition: opacity 0.6s var(--ease);
}
.scene.active {
opacity: 1;
pointer-events: all;
}
/* SCENE 1: HOOK */
.scene-hook .hook-label {
font-size: 13px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 24px;
animation: fadeUp 0.8s var(--ease) both;
}
.scene-hook .hook-title {
font-family: var(--font-display);
font-size: 38px;
line-height: 1.2;
text-align: center;
animation: fadeUp 0.8s var(--ease) 0.2s both;
}
/* SCENE 2: COLOR NAME */
.scene-color {
background: var(--celadon);
}
.scene-color .color-name {
font-family: var(--font-display);
font-size: 72px;
letter-spacing: -0.02em;
color: var(--bg);
animation: scaleIn 1s var(--ease) both;
}
.scene-color .color-year {
font-size: 12px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: rgba(13, 13, 15, 0.6);
margin-top: 16px;
animation: fadeUp 0.8s var(--ease) 0.4s both;
}
/* SCENE 3: SWATCHES */
.scene-swatches .swatch-label {
font-size: 12px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 48px;
animation: fadeUp 0.8s var(--ease) both;
}
.swatches-grid {
display: flex;
flex-direction: column;
gap: 20px;
width: 100%;
max-width: 280px;
}
.swatch {
height: 120px;
background: var(--celadon);
position: relative;
overflow: hidden;
animation: scaleIn 0.8s var(--ease) both;
animation-delay: calc(var(--i) * 150ms);
box-shadow: 0 4px 24px rgba(180, 196, 163, 0.15);
}
.swatch:nth-child(1) {
/* Geometric Lattice */
background-image:
linear-gradient(45deg, transparent 48%, var(--celadon-dark) 49%, var(--celadon-dark) 51%, transparent 52%),
linear-gradient(-45deg, transparent 48%, var(--celadon-dark) 49%, var(--celadon-dark) 51%, transparent 52%);
background-size: 24px 24px;
}
.swatch:nth-child(2) {
/* Organic Botanical - SVG Pattern */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60' viewBox='0 0 60 60'%3E%3Cpath d='M30 10 Q40 20 30 30 Q20 40 30 50 Q40 40 30 30 Q20 20 30 10' fill='none' stroke='%238a9a7a' stroke-width='1' opacity='0.5'/%3E%3Ccircle cx='30' cy='30' r='3' fill='%238a9a7a' opacity='0.3'/%3E%3C/svg%3E");
background-size: 30px 30px;
}
.swatch:nth-child(3) {
/* Classic Pinstripe */
background-image: repeating-linear-gradient(
90deg,
var(--celadon),
var(--celadon) 2px,
var(--celadon-dark) 2px,
var(--celadon-dark) 4px
);
}
/* SCENE 4: STYLING TIP */
.scene-tip .tip-label {
font-size: 12px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 32px;
animation: fadeUp 0.8s var(--ease) both;
}
.scene-tip .tip-text {
font-family: var(--font-display);
font-size: 32px;
line-height: 1.3;
text-align: center;
color: var(--text);
animation: fadeUp 0.8s var(--ease) 0.2s both;
}
.scene-tip .tip-detail {
font-size: 15px;
color: var(--muted);
margin-top: 32px;
max-width: 260px;
text-align: center;
line-height: 1.7;
animation: fadeUp 0.8s var(--ease) 0.4s both;
}
/* SCENE 5: CTA */
.scene-cta .cta-headline {
font-family: var(--font-display);
font-size: 36px;
text-align: center;
margin-bottom: 40px;
animation: fadeUp 0.8s var(--ease) both;
}
.cta-button {
padding: 20px 48px;
border: 1px solid var(--celadon);
background: transparent;
color: var(--celadon);
font-size: 12px;
letter-spacing: 0.2em;
text-transform: uppercase;
cursor: pointer;
transition: all 0.4s var(--ease);
animation: scaleIn 0.8s var(--ease) 0.3s both;
}
.cta-button:hover {
background: var(--celadon);
color: var(--bg);
}
.cta-subtext {
font-size: 12px;
color: var(--muted);
margin-top: 32px;
letter-spacing: 0.1em;
animation: fadeUp 0.8s var(--ease) 0.5s both;
}
/* CONTROLS */
.controls {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 24px 32px 32px;
display: flex;
align-items: center;
gap: 16px;
z-index: 50;
background: linear-gradient(to top, var(--surface) 40%, transparent);
}
.play-pause {
width: 44px;
height: 44px;
border: 1px solid var(--line);
border-radius: 50%;
background: transparent;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s var(--ease);
}
.play-pause:hover {
border-color: var(--accent);
}
.play-pause svg {
width: 16px;
height: 16px;
fill: var(--text);
}
.progress-container {
flex: 1;
height: 2px;
background: var(--line);
position: relative;
}
.progress-bar {
height: 100%;
background: var(--accent);
width: 0%;
transition: width 0.1s linear;
}
.scene-indicator {
font-size: 11px;
letter-spacing: 0.15em;
color: var(--muted);
min-width: 40px;
text-align: right;
}
/* KEYFRAMES */
@keyframes fadeUp {
from {
opacity: 0;
transform: translateY(28px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.92);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes clipReveal {
from {
clip-path: inset(0 100% 0 0);
}
to {
clip-path: inset(0);
}
}
/* Letter animation utility */
.letter-reveal span {
display: inline-block;
opacity: 0;
transform: translateY(0.6em);
animation: fadeUp 0.5s var(--ease) forwards;
}
</style>
</head>
<body>
<!-- HEADER -->
<header>
<div class="wordmark">DESIGNER WALLCOVERINGS</div>
</header>
<!-- REEL -->
<div class="reel-container" id="reel">
<!-- SCENE 1: HOOK -->
<div class="scene scene-hook active" data-duration="3500">
<div class="hook-label">This Season It's All About</div>
<h1 class="hook-title">A Return to<br>Quiet Luxury</h1>
</div>
<!-- SCENE 2: COLOR NAME -->
<div class="scene scene-color" data-duration="3000">
<h2 class="color-name letter-reveal" id="colorName">Celadon</h2>
<div class="color-year">Color of the Season 2024</div>
</div>
<!-- SCENE 3: SWATCHES -->
<div class="scene scene-swatches" data-duration="4500">
<div class="swatch-label">Three Ways to Wear It</div>
<div class="swatches-grid">
<div class="swatch" style="--i:0" aria-label="Geometric lattice pattern"></div>
<div class="swatch" style="--i:1" aria-label="Botanical motif pattern"></div>
<div class="swatch" style="--i:2" aria-label="Classic pinstripe pattern"></div>
</div>
</div>
<!-- SCENE 4: STYLING TIP -->
<div class="scene scene-tip" data-duration="3500">
<div class="tip-label">Designer Tip</div>
<p class="tip-text">"Pair with warm brass<br>and ivory linen"</p>
<p class="tip-detail">Celadon's grey-green undertone creates an instant sense of calm in bedrooms and reading nooks.</p>
</div>
<!-- SCENE 5: CTA -->
<div class="scene scene-cta" data-duration="3500">
<h2 class="cta-headline">Transform<br>Your Space</h2>
<button class="cta-button" onclick="window.location.reload()">Request Samples</button>
<p class="cta-subtext">Complimentary for interior designers</p>
</div>
<!-- CONTROLS -->
<div class="controls">
<button class="play-pause" id="playPause" aria-label="Pause">
<svg id="pauseIcon" viewBox="0 0 24 24">
<rect x="6" y="4" width="4" height="16"/>
<rect x="14" y="4" width="4" height="16"/>
</svg>
<svg id="playIcon" viewBox="0 0 24 24" style="display:none; margin-left:2px;">
<polygon points="5,3 19,12 5,21"/>
</svg>
</button>
<div class="progress-container">
<div class="progress-bar" id="progressBar"></div>
</div>
<div class="scene-indicator"><span id="currentScene">1</span>/5</div>
</div>
</div>
<script>
// State
let currentSceneIndex = 0;
let isPlaying = true;
let sceneStartTime = Date.now();
let pausedTime = 0;
let animationFrame;
const scenes = document.querySelectorAll('.scene');
const totalScenes = scenes.length;
const playPauseBtn = document.getElementById('playPause');
const pauseIcon = document.getElementById('pauseIcon');
const playIcon = document.getElementById('playIcon');
const progressBar = document.getElementById('progressBar');
const currentSceneEl = document.getElementById('currentScene');
const colorNameEl = document.getElementById('colorName');
// Letter-by-letter reveal for color name
function splitReveal(el) {
const text = el.textContent;
el.textContent = '';
[...text].forEach((char, i) => {
const span = document.createElement('span');
span.textContent = char === ' ' ? '\u00A0' : char;
span.style.animationDelay = `${i * 80}ms`;
el.appendChild(span);
});
}
// Initialize letter reveal
splitReveal(colorNameEl);
// Scene management
function showScene(index) {
scenes.forEach((scene, i) => {
scene.classList.toggle('active', i === index);
});
currentSceneIndex = index;
sceneStartTime = Date.now();
currentSceneEl.textContent = index + 1;
}
function nextScene() {
const next = (currentSceneIndex + 1) % totalScenes;
showScene(next);
}
// Progress bar and auto-advance
function update() {
if (isPlaying) {
const currentScene = scenes[currentSceneIndex];
const duration = parseInt(currentScene.dataset.duration);
const elapsed = Date.now() - sceneStartTime;
const progress = Math.min((elapsed / duration) * 100, 100);
progressBar.style.width = `${progress}%`;
if (elapsed >= duration) {
nextScene();
}
}
animationFrame = requestAnimationFrame(update);
}
// Play/Pause toggle
playPauseBtn.addEventListener('click', () => {
isPlaying = !isPlaying;
if (isPlaying) {
sceneStartTime = Date.now() - pausedTime;
pauseIcon.style.display = 'block';
playIcon.style.display = 'none';
} else {
pausedTime = Date.now() - sceneStartTime;
pauseIcon.style.display = 'none';
playIcon.style.display = 'block';
}
});
// Start
update();
</script>
</body>
</html>