← back to Model Arena
data/artifacts/131728b7aeb6/kimi.html
673 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 {
/* Color Palette - Luxury Noir with Celadon Accent */
--bg: #0d0d0f;
--surface: #17171c;
--ink: #f5f2ea;
--muted: #8a8578;
--accent: #c9a961;
--line: rgba(245, 242, 234, 0.15);
--shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
/* Color of the Season */
--celadon: #b8c4b8;
--celadon-deep: #9aab9a;
--celadon-light: #d5ddd5;
/* Typography */
--font-display: 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
--font-body: 'Avenir Next', 'Century Gothic', Futura, 'Segoe UI', sans-serif;
--font-mono: 'SF Mono', 'Cascadia Code', Consolas, Menlo, monospace;
/* Type Scale */
--text-caption: 12px;
--text-body: 16px;
--text-lead: 21px;
--text-h3: 28px;
--text-h2: 38px;
--text-h1: 50px;
--text-display: clamp(60px, 15vw, 120px);
/* Spacing */
--space-xs: 8px;
--space-sm: 16px;
--space-md: 24px;
--space-lg: 40px;
--space-xl: 64px;
/* Easings */
--ease-swift: cubic-bezier(.22,.9,.24,1);
--ease-power: cubic-bezier(.77,0,.18,1);
--ease-overshoot: cubic-bezier(.34,1.56,.64,1);
--ease-out-quint: cubic-bezier(.22,1,.36,1);
/* Timing */
--scene-duration: 3000ms;
--stagger-delay: 150ms;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-body);
background: var(--bg);
color: var(--ink);
overflow: hidden;
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
}
/* Fixed Header */
.brand-header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
background: var(--bg);
border-bottom: 1px solid var(--line);
display: flex;
align-items: center;
padding: 0 var(--space-md);
z-index: 1000;
box-shadow: var(--shadow);
}
.wordmark {
font-family: var(--font-display);
font-size: 14px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink);
font-weight: 400;
line-height: 1;
white-space: nowrap;
}
/* 9:16 Reel Container */
.reel-container {
position: relative;
width: 100%;
max-width: 450px;
aspect-ratio: 9/16;
background: var(--bg);
overflow: hidden;
box-shadow: var(--shadow);
}
@media (max-width: 500px) {
.reel-container {
max-width: none;
height: 100vh;
}
}
/* Progress Bar */
.progress-bar {
position: absolute;
top: 0;
left: 0;
height: 2px;
background: var(--accent);
width: 0%;
z-index: 100;
transition: width 100ms linear;
}
/* Play/Pause Control */
.controls {
position: absolute;
bottom: var(--space-lg);
right: var(--space-md);
z-index: 100;
}
.control-btn {
width: 44px;
height: 44px;
border: 1px solid var(--line);
background: rgba(13, 13, 15, 0.8);
backdrop-filter: blur(8px);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 300ms var(--ease-swift);
}
.control-btn:hover {
border-color: var(--accent);
transform: scale(1.05);
}
.control-btn svg {
width: 16px;
height: 16px;
fill: var(--ink);
}
.control-btn.paused .pause-icon,
.control-btn:not(.paused) .play-icon {
display: none;
}
/* Scene Container */
.scenes {
position: relative;
width: 100%;
height: 100%;
}
.scene {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--space-lg) var(--space-md);
opacity: 0;
visibility: hidden;
transition: opacity 600ms var(--ease-power), visibility 600ms;
}
.scene.active {
opacity: 1;
visibility: visible;
}
/* Scene 1: Hook */
.hook-text {
font-family: var(--font-display);
font-size: var(--text-h2);
color: var(--ink);
text-align: center;
line-height: 1.2;
letter-spacing: -0.02em;
opacity: 0;
transform: translateY(30px);
transition: all 800ms var(--ease-out-quint);
}
.scene.active .hook-text {
opacity: 1;
transform: translateY(0);
}
/* Scene 2: Color Name */
.color-hero {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--celadon);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
opacity: 0;
transform: scale(0.95);
transition: all 900ms var(--ease-power);
}
.scene.active .color-hero {
opacity: 1;
transform: scale(1);
}
.color-name {
font-family: var(--font-display);
font-size: var(--text-display);
color: var(--bg);
text-transform: uppercase;
letter-spacing: 0.05em;
line-height: 0.9;
text-align: center;
opacity: 0;
transform: translateY(40px);
transition: all 700ms var(--ease-out-quint) 200ms;
}
.color-subtitle {
font-family: var(--font-body);
font-size: var(--text-caption);
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--bg);
margin-top: var(--space-md);
opacity: 0;
transition: opacity 500ms var(--ease-swift) 500ms;
}
.scene.active .color-name,
.scene.active .color-subtitle {
opacity: 1;
transform: translateY(0);
}
/* Scene 3: Pattern Swatches */
.swatches-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: var(--space-sm);
padding: var(--space-xl) 0;
}
.swatch {
flex: 1;
width: 100%;
background: var(--celadon);
position: relative;
overflow: hidden;
opacity: 0;
transform: translateX(-30px);
transition: all 600ms var(--ease-out-quint);
}
.scene.active .swatch {
opacity: 1;
transform: translateX(0);
}
.scene.active .swatch:nth-child(1) { transition-delay: calc(var(--stagger-delay) * 1); }
.scene.active .swatch:nth-child(2) { transition-delay: calc(var(--stagger-delay) * 2); }
.scene.active .swatch:nth-child(3) { transition-delay: calc(var(--stagger-delay) * 3); }
/* Pattern 1: Geometric Lattice */
.pattern-lattice {
background-color: var(--celadon);
background-image:
linear-gradient(45deg, transparent 48%, var(--celadon-deep) 49%, var(--celadon-deep) 51%, transparent 52%),
linear-gradient(-45deg, transparent 48%, var(--celadon-deep) 49%, var(--celadon-deep) 51%, transparent 52%);
background-size: 40px 40px;
opacity: 0.6;
}
/* Pattern 2: Organic Floral (SVG pattern) */
.pattern-floral {
background-color: var(--celadon);
background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M30 5c5 0 10 5 10 10s-5 8-10 8-10-3-10-8 5-10 10-10zm0 30c5 0 10 5 10 10s-5 8-10 8-10-3-10-8 5-10 10-10z' fill='%239aab9a' fill-opacity='0.4'/%3E%3C/svg%3E");
}
/* Pattern 3: Horizontal Stripes with Texture */
.pattern-stripes {
background: repeating-linear-gradient(
0deg,
var(--celadon),
var(--celadon) 10px,
var(--celadon-deep) 10px,
var(--celadon-deep) 12px
);
}
/* Scene 4: Styling Tip */
.tip-container {
text-align: center;
max-width: 320px;
}
.tip-label {
font-size: var(--text-caption);
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--accent);
margin-bottom: var(--space-md);
opacity: 0;
transform: translateY(20px);
transition: all 500ms var(--ease-swift);
}
.tip-text {
font-family: var(--font-display);
font-size: var(--text-h2);
color: var(--ink);
line-height: 1.3;
letter-spacing: -0.01em;
opacity: 0;
transform: translateY(20px);
transition: all 500ms var(--ease-swift) 150ms;
}
.tip-detail {
font-size: var(--text-body);
color: var(--muted);
margin-top: var(--space-md);
line-height: 1.6;
opacity: 0;
transition: opacity 500ms var(--ease-swift) 300ms;
}
.scene.active .tip-label,
.scene.active .tip-text,
.scene.active .tip-detail {
opacity: 1;
transform: translateY(0);
}
/* Scene 5: CTA */
.cta-container {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-lg);
}
.cta-headline {
font-family: var(--font-display);
font-size: var(--text-h1);
color: var(--ink);
line-height: 1.1;
letter-spacing: -0.02em;
opacity: 0;
transform: scale(0.9);
transition: all 600ms var(--ease-overshoot);
}
.cta-button {
font-family: var(--font-body);
font-size: var(--text-caption);
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--bg);
background: var(--celadon);
padding: var(--space-md) var(--space-xl);
border: none;
cursor: pointer;
position: relative;
overflow: hidden;
opacity: 0;
transform: translateY(20px);
transition: all 400ms var(--ease-swift) 200ms;
}
.cta-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: var(--accent);
transition: left 400ms var(--ease-swift);
z-index: -1;
}
.cta-button:hover::before {
left: 0;
}
.cta-button:hover {
color: var(--bg);
}
.cta-subline {
font-size: var(--text-caption);
color: var(--muted);
letter-spacing: 0.1em;
text-transform: uppercase;
opacity: 0;
transition: opacity 400ms var(--ease-swift) 400ms;
}
.scene.active .cta-headline,
.scene.active .cta-button,
.scene.active .cta-subline {
opacity: 1;
transform: translateY(0) scale(1);
}
/* Caption overlay for accessibility */
.caption-overlay {
position: absolute;
bottom: 80px;
left: var(--space-md);
right: var(--space-md);
text-align: center;
pointer-events: none;
}
.caption-text {
font-size: var(--text-caption);
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--muted);
background: rgba(13, 13, 15, 0.8);
padding: var(--space-xs) var(--space-sm);
display: inline-block;
opacity: 0;
transform: translateY(10px);
transition: all 300ms var(--ease-swift);
}
.scene.active .caption-text {
opacity: 1;
transform: translateY(0);
}
/* Hairline decorative elements */
.hairline {
position: absolute;
background: var(--line);
}
.hairline-top {
top: 60px;
left: var(--space-md);
right: var(--space-md);
height: 1px;
}
</style>
</head>
<body>
<!-- Fixed Brand Header -->
<header class="brand-header">
<div class="wordmark">Designer Wallcoverings</div>
</header>
<!-- 9:16 Reel Container -->
<div class="reel-container" id="reel">
<!-- Progress Bar -->
<div class="progress-bar" id="progressBar"></div>
<!-- Decorative Hairline -->
<div class="hairline hairline-top"></div>
<!-- Scenes -->
<div class="scenes">
<!-- Scene 1: Hook -->
<div class="scene active" data-scene="0">
<h1 class="hook-text">This season<br>it's all about…</h1>
<div class="caption-overlay">
<span class="caption-text">Color of the Season</span>
</div>
</div>
<!-- Scene 2: Color Name -->
<div class="scene" data-scene="1">
<div class="color-hero">
<h2 class="color-name">Celadon</h2>
<p class="color-subtitle">The New Neutral</p>
</div>
<div class="caption-overlay">
<span class="caption-text">Introducing Celadon</span>
</div>
</div>
<!-- Scene 3: Pattern Swatches -->
<div class="scene" data-scene="2">
<div class="swatches-container">
<div class="swatch pattern-lattice"></div>
<div class="swatch pattern-floral"></div>
<div class="swatch pattern-stripes"></div>
</div>
<div class="caption-overlay">
<span class="caption-text">Three Signature Patterns</span>
</div>
</div>
<!-- Scene 4: Styling Tip -->
<div class="scene" data-scene="3">
<div class="tip-container">
<p class="tip-label">Styling Tip</p>
<h3 class="tip-text">Pair with warm brass and raw linen for effortless sophistication</h3>
<p class="tip-detail">Celadon brings quiet energy to both modern minimal and classic interiors.</p>
</div>
<div class="caption-overlay">
<span class="caption-text">How to Style</span>
</div>
</div>
<!-- Scene 5: CTA -->
<div class="scene" data-scene="4">
<div class="cta-container">
<h3 class="cta-headline">Transform<br>Your Space</h3>
<button class="cta-button">Shop the Collection</button>
<p class="cta-subline">Exclusive to Designer Wallcoverings</p>
</div>
<div class="caption-overlay">
<span class="caption-text">Shop Now</span>
</div>
</div>
</div>
<!-- Controls -->
<div class="controls">
<button class="control-btn" id="playPauseBtn" aria-label="Pause">
<svg class="pause-icon" 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 class="play-icon" viewBox="0 0 24 24">
<path d="M8 5v14l11-7z"/>
</svg>
</button>
</div>
</div>
<script>
// Reel Controller
class ReelController {
constructor() {
this.scenes = document.querySelectorAll('.scene');
this.progressBar = document.getElementById('progressBar');
this.playPauseBtn = document.getElementById('playPauseBtn');
this.reel = document.getElementById('reel');
this.currentScene = 0;
this.isPlaying = true;
this.sceneDuration = 3000; // 3 seconds per scene
this.lastFrameTime = 0;
this.elapsedTime = 0;
this.animationId = null;
this.init();
}
init() {
this.playPauseBtn.addEventListener('click', () => this.togglePlay());
this.start();
}
start() {
this.lastFrameTime = performance.now();
this.animationId = requestAnimationFrame((t) => this.loop(t));
}
loop(currentTime) {
if (!this.isPlaying) return;
const deltaTime = currentTime - this.lastFrameTime;
this.lastFrameTime = currentTime;
this.elapsedTime += deltaTime;
// Calculate progress within current scene
const progress = Math.min(this.elapsedTime / this.sceneDuration, 1);
this.updateProgressBar(progress);
// Check if scene should advance
if (this.elapsedTime >= this.sceneDuration) {
this.nextScene();
}
this.animationId = requestAnimationFrame((t) => this.loop(t));
}
updateProgressBar(progress) {
const totalProgress = ((this.currentScene + progress) / this.scenes.length) * 100;
this.progressBar.style.width = `${totalProgress}%`;
}
nextScene() {
// Remove active class from current scene
this.scenes[this.currentScene].classList.remove('active');
// Advance to next scene
this.currentScene = (this.currentScene + 1) % this.scenes.length;
// Add active class to new scene
this.scenes[this.currentScene].classList.add('active');
// Reset elapsed time
this.elapsedTime = 0;
}
togglePlay() {
this.isPlaying = !this.isPlaying;
if (this.isPlaying) {
this.playPauseBtn.classList.remove('paused');
this.lastFrameTime = performance.now();
this.animationId = requestAnimationFrame((t) => this.loop(t));
} else {
this.playPauseBtn.classList.add('paused');
cancelAnimationFrame(this.animationId);
}
}
}
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
new ReelController();
});
// Handle visibility change to pause when tab is hidden
document.addEventListener('visibilitychange', () => {
const btn = document.getElementById('playPauseBtn');
if (document.hidden) {
btn.classList.add('paused');
} else {
btn.classList.remove('paused');
}
});
</script>
</body>
</html>