← 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>