[object Object]

← back to Model Arena

Agent-driven editorial: DW The Lookbook (frontend-developer) — 6 swipeable style spreads, SVG heroes, inert TOC. Registered.

ef2e59b2eb6e5ddfc658cf25cacf7839e501430e · 2026-07-25 11:44:01 -0700 · Steve Abrams

Files touched

Diff

commit ef2e59b2eb6e5ddfc658cf25cacf7839e501430e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sat Jul 25 11:44:01 2026 -0700

    Agent-driven editorial: DW The Lookbook (frontend-developer) — 6 swipeable style spreads, SVG heroes, inert TOC. Registered.
---
 data/arcade-games.json        |    6 +
 public/games/dw-lookbook.html | 1020 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1026 insertions(+)

diff --git a/data/arcade-games.json b/data/arcade-games.json
index 730ca7d..28c8f76 100644
--- a/data/arcade-games.json
+++ b/data/arcade-games.json
@@ -65,6 +65,12 @@
       "title": "DW Pattern Match",
       "credit": "frontend-developer",
       "note": "Agent-built match-3 game \u2014 swap luxury swatch tiles, cascading combos, 6 textures"
+    },
+    {
+      "slug": "dw-lookbook",
+      "title": "DW The Lookbook",
+      "credit": "frontend-developer",
+      "note": "Agent-built editorial \u2014 6 swipeable style spreads (Grandmillennial\u2192Modern Minimal), each with SVG hero + palette"
     }
   ]
 }
\ No newline at end of file
diff --git a/public/games/dw-lookbook.html b/public/games/dw-lookbook.html
new file mode 100644
index 0000000..b2168bd
--- /dev/null
+++ b/public/games/dw-lookbook.html
@@ -0,0 +1,1020 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<title>Designer Wallcoverings — The Lookbook</title>
+<style>
+/* ── TOKENS ── */
+:root {
+  --bg: #0d0b09;
+  --ink: #1c1a17;
+  --cream: #f4f1ea;
+  --mid: #8a8070;
+  --accent: #c9a961;
+  --accent-dim: #9a7d42;
+  --serif: 'Cormorant Garamond','Playfair Display','EB Garamond',Georgia,serif;
+  --sans: 'Optima','Gill Sans','Trebuchet MS',sans-serif;
+  --ease: cubic-bezier(.4,0,.2,1);
+  --ease-out: cubic-bezier(0,0,.2,1);
+  --ease-spring: cubic-bezier(.34,1.56,.64,1);
+  --r: 2px;
+}
+
+/* ── RESET ── */
+*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
+html,body{width:100%;height:100%;overflow:hidden;background:var(--bg)}
+body{font-family:var(--sans);color:var(--cream);-webkit-font-smoothing:antialiased}
+
+/* ── HEADER ── */
+header{
+  position:fixed;top:0;left:0;right:0;z-index:100;
+  display:flex;align-items:center;justify-content:space-between;
+  padding:18px 36px 16px;
+  background:linear-gradient(180deg,rgba(13,11,9,.92) 0%,rgba(13,11,9,0) 100%);
+  pointer-events:none;
+}
+.wordmark{
+  font-family:var(--serif);font-size:clamp(15px,1.6vw,22px);
+  font-weight:400;letter-spacing:.18em;text-transform:uppercase;
+  color:var(--ink); /* darkest ink, never white-on-cream */
+  color:var(--cream); /* on dark bg: lightest token */
+  line-height:1;pointer-events:auto;
+}
+.wordmark span{color:var(--accent);letter-spacing:.22em}
+.hdr-right{display:flex;align-items:center;gap:20px;pointer-events:auto}
+.toc-btn{
+  font-family:var(--sans);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
+  color:var(--cream);opacity:.7;background:none;border:none;cursor:pointer;
+  transition:opacity .2s var(--ease);
+}
+.toc-btn:hover{opacity:1}
+
+/* ── PROGRESS BAR ── */
+.progress-bar{
+  position:fixed;top:0;left:0;height:2px;z-index:200;
+  background:var(--accent);width:0%;transition:width .5s var(--ease-out);
+}
+
+/* ── SLIDES VIEWPORT ── */
+.viewport{
+  width:100%;height:100vh;position:relative;overflow:hidden;
+}
+.slides-track{
+  display:flex;width:600%;height:100%;
+  transition:transform .75s var(--ease-out);
+  will-change:transform;
+}
+.slide{
+  width:calc(100%/6);flex-shrink:0;height:100%;
+  position:relative;overflow:hidden;
+}
+
+/* ── DOT NAV ── */
+.dots{
+  position:fixed;bottom:32px;left:50%;transform:translateX(-50%);
+  display:flex;gap:10px;z-index:100;
+}
+.dot{
+  width:6px;height:6px;border-radius:50%;
+  background:rgba(249,241,234,.3);border:1px solid rgba(249,241,234,.4);
+  cursor:pointer;transition:all .3s var(--ease);
+}
+.dot.active{
+  background:var(--accent);border-color:var(--accent);
+  transform:scale(1.4);
+}
+
+/* ── ARROW NAV ── */
+.arrow{
+  position:fixed;top:50%;transform:translateY(-50%);z-index:100;
+  background:none;border:1px solid rgba(201,169,97,.3);
+  color:var(--accent);font-size:18px;width:44px;height:44px;
+  border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;
+  transition:all .25s var(--ease);opacity:.6;
+}
+.arrow:hover{opacity:1;background:rgba(201,169,97,.12);border-color:var(--accent)}
+.arrow-prev{left:24px}
+.arrow-next{right:24px}
+
+/* ── SPREAD LABEL ── */
+.spread-num{
+  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
+  font-family:var(--serif);font-size:clamp(100px,18vw,240px);
+  font-weight:300;letter-spacing:-.02em;color:rgba(255,255,255,.03);
+  pointer-events:none;user-select:none;z-index:1;line-height:1;
+}
+
+/* ── PALETTE STRIP ── */
+.palette-strip{
+  display:flex;gap:0;overflow:hidden;border-radius:var(--r);
+}
+.swatch{
+  height:28px;flex:1;cursor:pointer;position:relative;
+  transition:flex .3s var(--ease);
+}
+.swatch:hover{flex:2.4}
+.swatch::after{
+  content:attr(data-name);
+  position:absolute;bottom:calc(100% + 6px);left:50%;transform:translateX(-50%);
+  font-family:var(--sans);font-size:9px;letter-spacing:.12em;text-transform:uppercase;
+  color:var(--cream);opacity:0;white-space:nowrap;
+  transition:opacity .2s var(--ease);pointer-events:none;
+}
+.swatch:hover::after{opacity:.8}
+
+/* ── PATTERN SWATCH ── */
+.pattern-frame{
+  position:relative;overflow:hidden;border-radius:var(--r);
+}
+.pattern-label{
+  margin-top:10px;font-family:var(--sans);font-size:10px;
+  letter-spacing:.15em;text-transform:uppercase;color:var(--accent);
+  opacity:.85;
+}
+
+/* ── EDITORIAL TEXT ── */
+.headline{
+  font-family:var(--serif);font-weight:300;line-height:1.08;
+  letter-spacing:-.01em;
+}
+.tagline{
+  font-family:var(--sans);font-size:10.5px;letter-spacing:.22em;
+  text-transform:uppercase;color:var(--accent);margin-bottom:14px;
+}
+.body-copy{
+  font-family:var(--serif);font-size:clamp(14px,1.2vw,17px);
+  line-height:1.72;font-weight:300;opacity:.82;
+  font-style:italic;
+}
+.rule{
+  display:block;width:48px;height:1px;
+  background:var(--accent);margin:20px 0;opacity:.6;
+}
+
+/* ── REVEAL ANIMATION ── */
+.reveal{
+  opacity:0;transform:translateY(22px);
+  transition:opacity .7s var(--ease-out),transform .7s var(--ease-out);
+}
+.reveal.in{opacity:1;transform:none}
+.reveal.d1{transition-delay:.1s}
+.reveal.d2{transition-delay:.25s}
+.reveal.d3{transition-delay:.42s}
+.reveal.d4{transition-delay:.58s}
+.reveal.d5{transition-delay:.72s}
+
+/* ── PARALLAX HERO ── */
+.parallax-hero{
+  position:absolute;inset:0;will-change:transform;
+  transition:transform .05s linear;
+}
+
+/* ── TOC OVERLAY ── */
+.toc-overlay{
+  position:fixed;inset:0;z-index:500;
+  background:rgba(13,11,9,.96);
+  display:flex;align-items:center;justify-content:center;
+  visibility:hidden;opacity:0;
+  transition:opacity .35s var(--ease),visibility 0s .35s;
+}
+.toc-overlay.open{visibility:visible;opacity:1;transition:opacity .35s var(--ease)}
+.toc-inner{text-align:center;max-width:520px;width:90%}
+.toc-title{
+  font-family:var(--serif);font-size:clamp(11px,1vw,13px);
+  letter-spacing:.28em;text-transform:uppercase;color:var(--accent);
+  margin-bottom:44px;
+}
+.toc-list{list-style:none;display:flex;flex-direction:column;gap:0}
+.toc-item{
+  padding:18px 0;border-bottom:1px solid rgba(201,169,97,.15);
+  cursor:pointer;display:flex;align-items:baseline;gap:18px;
+  transition:opacity .2s var(--ease);
+}
+.toc-item:first-child{border-top:1px solid rgba(201,169,97,.15)}
+.toc-item:hover .toc-item-title{color:var(--accent)}
+.toc-n{
+  font-family:var(--serif);font-size:12px;color:var(--accent);
+  opacity:.6;min-width:24px;
+}
+.toc-item-title{
+  font-family:var(--serif);font-size:clamp(22px,2.8vw,34px);
+  font-weight:300;letter-spacing:.04em;color:var(--cream);
+  transition:color .2s var(--ease);
+}
+.toc-sub{
+  font-family:var(--sans);font-size:10px;letter-spacing:.14em;
+  text-transform:uppercase;color:var(--mid);margin-left:auto;
+}
+.toc-close{
+  margin-top:40px;font-family:var(--sans);font-size:10px;
+  letter-spacing:.2em;text-transform:uppercase;color:var(--mid);
+  background:none;border:none;cursor:pointer;
+  transition:color .2s var(--ease);
+}
+.toc-close:hover{color:var(--cream)}
+
+/* ═══════════════════════════════════════
+   SPREAD 1 — GRANDMILLENNIAL
+═══════════════════════════════════════ */
+.s1{background:#f0ece4}
+.s1 .headline,.s1 .tagline,.s1 .body-copy,.s1 .pattern-label{
+  /* override for light spread */
+}
+.s1-layout{
+  display:grid;grid-template-columns:1fr 1fr;height:100%;
+}
+.s1-hero{position:relative;overflow:hidden}
+.s1-content{
+  display:flex;flex-direction:column;justify-content:center;
+  padding:clamp(36px,6vw,80px) clamp(36px,5vw,72px);
+  background:#f0ece4;
+  color:var(--ink);
+}
+.s1-content .headline{font-size:clamp(38px,5.5vw,80px);color:#1c1a17}
+.s1-content .tagline{color:#8a6d3a}
+.s1-content .body-copy{color:#3a3630}
+.s1-content .rule{background:#8a6d3a}
+.s1-content .pattern-label{color:#8a6d3a}
+
+/* ═══════════════════════════════════════
+   SPREAD 2 — COASTAL
+═══════════════════════════════════════ */
+.s2{background:#e8eff5}
+.s2-layout{
+  display:grid;grid-template-rows:1fr auto;height:100%;
+}
+.s2-hero{flex:1;position:relative;overflow:hidden}
+.s2-content{
+  padding:clamp(28px,4vw,52px) clamp(48px,7vw,120px);
+  background:rgba(20,36,52,.88);
+  color:#e8f0f7;
+}
+.s2-content .headline{font-size:clamp(32px,5vw,70px);color:#e8f0f7;line-height:1.04}
+.s2-content .tagline{color:#7fb5d5}
+.s2-content .body-copy{color:rgba(232,240,247,.75)}
+.s2-content .rule{background:#7fb5d5}
+.s2-content .pattern-label{color:#7fb5d5}
+.s2-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(32px,5vw,80px);align-items:end}
+
+/* ═══════════════════════════════════════
+   SPREAD 3 — MOODY MAXIMALIST
+═══════════════════════════════════════ */
+.s3{background:#1a1210}
+.s3-layout{
+  display:grid;grid-template-columns:1.1fr .9fr;height:100%;
+}
+.s3-hero{position:relative;overflow:hidden}
+.s3-content{
+  display:flex;flex-direction:column;justify-content:center;
+  padding:clamp(36px,5vw,72px);background:#1a1210;
+  color:#e8dccf;
+}
+.s3-content .headline{font-size:clamp(36px,5vw,76px);color:#e8dccf}
+.s3-content .tagline{color:#c9a961}
+.s3-content .body-copy{color:rgba(232,220,207,.65)}
+.s3-content .rule{background:#c9a961}
+.s3-content .pattern-label{color:#c9a961}
+
+/* ═══════════════════════════════════════
+   SPREAD 4 — ART DECO
+═══════════════════════════════════════ */
+.s4{background:#0e0c08}
+.s4-layout{
+  display:flex;flex-direction:column;align-items:center;
+  justify-content:center;height:100%;
+  padding:clamp(60px,8vh,110px) clamp(36px,8vw,160px);
+  text-align:center;position:relative;
+}
+.s4 .headline{font-size:clamp(40px,6vw,96px);color:#e8dfc8;letter-spacing:.06em}
+.s4 .tagline{color:#c9a961;justify-content:center;display:flex}
+.s4 .body-copy{color:rgba(232,223,200,.7);max-width:480px;margin:0 auto;font-style:normal;font-size:clamp(13px,1.1vw,16px);letter-spacing:.04em;line-height:1.8}
+.s4 .rule{margin:20px auto}
+.s4 .pattern-label{color:#c9a961;text-align:center}
+.s4-frame{
+  position:absolute;inset:30px;border:1px solid rgba(201,169,97,.15);
+  pointer-events:none;
+}
+.s4-frame::before,.s4-frame::after{
+  content:'';position:absolute;width:24px;height:24px;
+  border-color:var(--accent);border-style:solid;opacity:.5;
+}
+.s4-frame::before{top:-1px;left:-1px;border-width:1px 0 0 1px}
+.s4-frame::after{bottom:-1px;right:-1px;border-width:0 1px 1px 0}
+
+/* ═══════════════════════════════════════
+   SPREAD 5 — CHINOISERIE
+═══════════════════════════════════════ */
+.s5{background:#f7f3eb}
+.s5-layout{
+  display:grid;grid-template-columns:.9fr 1.1fr;height:100%;
+}
+.s5-content{
+  display:flex;flex-direction:column;justify-content:center;
+  padding:clamp(36px,5vw,72px);background:#f7f3eb;color:#1c2218;
+}
+.s5-content .headline{font-size:clamp(34px,5vw,72px);color:#1c2218;line-height:1.06}
+.s5-content .tagline{color:#5c7a4a}
+.s5-content .body-copy{color:rgba(28,34,24,.72)}
+.s5-content .rule{background:#5c7a4a}
+.s5-content .pattern-label{color:#5c7a4a}
+.s5-hero{position:relative;overflow:hidden}
+
+/* ═══════════════════════════════════════
+   SPREAD 6 — MODERN MINIMAL
+═══════════════════════════════════════ */
+.s6{background:#f9f8f6}
+.s6-layout{
+  display:grid;grid-template-columns:1fr 1fr;height:100%;
+}
+.s6-content{
+  display:flex;flex-direction:column;justify-content:flex-end;
+  padding:clamp(48px,6vw,90px);background:#f9f8f6;color:#1c1a17;
+}
+.s6-content .headline{font-size:clamp(34px,4.8vw,72px);color:#1c1a17}
+.s6-content .tagline{color:#636058}
+.s6-content .body-copy{color:rgba(28,26,23,.68)}
+.s6-content .rule{background:#1c1a17;opacity:.25}
+.s6-content .pattern-label{color:#636058}
+.s6-hero{position:relative;overflow:hidden;background:#e8e5e0}
+.s6-accent-line{
+  position:absolute;left:0;top:50%;width:100%;height:1px;
+  background:rgba(28,26,23,.12);transform:translateY(-50%);
+}
+
+/* ── RESPONSIVE ── */
+@media(max-width:680px){
+  .s1-layout,.s3-layout,.s5-layout,.s6-layout{grid-template-columns:1fr}
+  .s1-hero,.s5-hero,.s6-hero,.s3-hero{display:none}
+  .s2-grid{grid-template-columns:1fr}
+  .s4-layout{padding:40px 24px}
+  header{padding:14px 20px}
+  .wordmark{font-size:13px}
+  .arrow{display:none}
+}
+</style>
+</head>
+<body>
+
+<!-- PROGRESS -->
+<div class="progress-bar" id="progressBar"></div>
+
+<!-- HEADER -->
+<header>
+  <div class="wordmark">Designer&nbsp;<span>Wallcoverings</span></div>
+  <div class="hdr-right">
+    <button class="toc-btn" onclick="openToc()">Contents</button>
+  </div>
+</header>
+
+<!-- ARROW NAV -->
+<button class="arrow arrow-prev" id="arrowPrev" aria-label="Previous spread" onclick="goTo(current-1)">&#8592;</button>
+<button class="arrow arrow-next" id="arrowNext" aria-label="Next spread" onclick="goTo(current+1)">&#8594;</button>
+
+<!-- DOT NAV -->
+<div class="dots" id="dots"></div>
+
+<!-- TOC OVERLAY -->
+<div class="toc-overlay" id="tocOverlay" role="dialog" aria-modal="true" aria-label="Table of Contents">
+  <div class="toc-inner">
+    <div class="toc-title">The Lookbook — 2026</div>
+    <ul class="toc-list" id="tocList"></ul>
+    <button class="toc-close" onclick="closeToc()">Close &nbsp;&#215;</button>
+  </div>
+</div>
+
+<!-- SLIDES -->
+<div class="viewport">
+  <div class="slides-track" id="track">
+
+    <!-- ══ SPREAD 1: GRANDMILLENNIAL ══ -->
+    <div class="slide s1" data-index="0">
+      <div class="spread-num">01</div>
+      <div class="s1-layout" style="height:100%">
+        <div class="s1-hero parallax-hero" data-speed=".04">
+          <svg viewBox="0 0 600 900" preserveAspectRatio="xMidYMid slice" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" style="position:absolute;inset:0">
+            <rect width="600" height="900" fill="#e6e0d5"/>
+            <!-- toile-style botanical background wash -->
+            <rect width="600" height="900" fill="url(#toileWash)" opacity=".18"/>
+            <!-- trellis grid -->
+            <defs>
+              <pattern id="toileWash" x="0" y="0" width="60" height="60" patternUnits="userSpaceOnUse">
+                <circle cx="30" cy="30" r="26" fill="none" stroke="#8a6d3a" stroke-width=".5"/>
+                <circle cx="0" cy="0" r="26" fill="none" stroke="#8a6d3a" stroke-width=".5"/>
+                <circle cx="60" cy="0" r="26" fill="none" stroke="#8a6d3a" stroke-width=".5"/>
+                <circle cx="0" cy="60" r="26" fill="none" stroke="#8a6d3a" stroke-width=".5"/>
+                <circle cx="60" cy="60" r="26" fill="none" stroke="#8a6d3a" stroke-width=".5"/>
+              </pattern>
+              <pattern id="toileFloral" x="0" y="0" width="120" height="160" patternUnits="userSpaceOnUse">
+                <!-- stem -->
+                <path d="M60 150 Q58 110 55 90 Q50 65 60 40" fill="none" stroke="#7a6040" stroke-width="1.2"/>
+                <!-- leaves -->
+                <ellipse cx="46" cy="100" rx="14" ry="7" fill="#8a7050" opacity=".55" transform="rotate(-30,46,100)"/>
+                <ellipse cx="74" cy="80" rx="14" ry="7" fill="#8a7050" opacity=".55" transform="rotate(30,74,80)"/>
+                <!-- bloom -->
+                <circle cx="60" cy="36" r="18" fill="none" stroke="#7a6040" stroke-width="1"/>
+                <circle cx="60" cy="36" r="10" fill="#c0a878" opacity=".4"/>
+                <circle cx="60" cy="36" r="4" fill="#8a6d3a" opacity=".6"/>
+                <!-- petals -->
+                <ellipse cx="60" cy="20" rx="5" ry="9" fill="#b09060" opacity=".45"/>
+                <ellipse cx="60" cy="52" rx="5" ry="9" fill="#b09060" opacity=".45"/>
+                <ellipse cx="44" cy="36" rx="9" ry="5" fill="#b09060" opacity=".45"/>
+                <ellipse cx="76" cy="36" rx="9" ry="5" fill="#b09060" opacity=".45"/>
+                <ellipse cx="48" cy="24" rx="5" ry="9" fill="#b09060" opacity=".35" transform="rotate(-45,48,24)"/>
+                <ellipse cx="72" cy="24" rx="5" ry="9" fill="#b09060" opacity=".35" transform="rotate(45,72,24)"/>
+                <ellipse cx="48" cy="48" rx="5" ry="9" fill="#b09060" opacity=".35" transform="rotate(45,48,48)"/>
+                <ellipse cx="72" cy="48" rx="5" ry="9" fill="#b09060" opacity=".35" transform="rotate(-45,72,48)"/>
+              </pattern>
+            </defs>
+            <rect width="600" height="900" fill="url(#toileFloral)" opacity=".55"/>
+            <!-- aged paper overlay -->
+            <rect width="600" height="900" fill="#f0e8d0" opacity=".28"/>
+            <!-- vignette -->
+            <radialGradient id="vigS1" cx="50%" cy="50%" r="70%">
+              <stop offset="0%" stop-color="transparent"/>
+              <stop offset="100%" stop-color="#a89060" stop-opacity=".35"/>
+            </radialGradient>
+            <rect width="600" height="900" fill="url(#vigS1)"/>
+          </svg>
+        </div>
+        <div class="s1-content">
+          <div class="tagline reveal d1">Story One</div>
+          <h2 class="headline reveal d2">Grand&shy;millennial</h2>
+          <span class="rule reveal d3"></span>
+          <p class="body-copy reveal d4">Heirloom florals reborn for the contemporary interior. English toile, blush moiré, and gilded chintz converge in rooms that honour ancestry without apology — spaces that feel inherited, not merely decorated.</p>
+          <span class="rule reveal d4" style="opacity:.2"></span>
+          <div class="palette-strip reveal d4" style="margin-top:8px;border-radius:2px;overflow:hidden">
+            <div class="swatch" style="background:#d4c4a8" data-name="Parchment"></div>
+            <div class="swatch" style="background:#b09060" data-name="Old Gold"></div>
+            <div class="swatch" style="background:#8a6d3a" data-name="Tobacco"></div>
+            <div class="swatch" style="background:#c8b4a0" data-name="Blush Moiré"></div>
+            <div class="swatch" style="background:#6a5840" data-name="Walnut"></div>
+          </div>
+          <div class="pattern-frame reveal d5" style="margin-top:18px;width:88px;height:88px">
+            <svg viewBox="0 0 88 88" width="88" height="88" xmlns="http://www.w3.org/2000/svg">
+              <rect width="88" height="88" fill="#e6e0d5"/>
+              <rect width="88" height="88" fill="url(#toileFloral)" opacity=".7"/>
+              <rect width="88" height="88" fill="none" stroke="#8a6d3a" stroke-width=".5" opacity=".5"/>
+            </svg>
+          </div>
+          <div class="pattern-label reveal d5">Heirloom Botanical — No. 12</div>
+        </div>
+      </div>
+    </div>
+
+    <!-- ══ SPREAD 2: COASTAL ══ -->
+    <div class="slide s2" data-index="1">
+      <div class="spread-num">02</div>
+      <div class="s2-layout" style="height:100%">
+        <div class="s2-hero" style="position:relative;overflow:hidden;flex:1">
+          <svg viewBox="0 0 1400 700" preserveAspectRatio="xMidYMid slice" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" style="position:absolute;inset:0">
+            <defs>
+              <linearGradient id="coastSky" x1="0" y1="0" x2="0" y2="1">
+                <stop offset="0%" stop-color="#c8dff0"/>
+                <stop offset="55%" stop-color="#e8f0f7"/>
+                <stop offset="100%" stop-color="#d0e5f0"/>
+              </linearGradient>
+              <pattern id="wavePattern" x="0" y="0" width="200" height="40" patternUnits="userSpaceOnUse">
+                <path d="M0 20 Q25 5 50 20 Q75 35 100 20 Q125 5 150 20 Q175 35 200 20" fill="none" stroke="#7fb5d5" stroke-width="1.5" opacity=".4"/>
+                <path d="M0 28 Q25 13 50 28 Q75 43 100 28 Q125 13 150 28 Q175 43 200 28" fill="none" stroke="#5c9abd" stroke-width=".8" opacity=".3"/>
+              </pattern>
+              <pattern id="seagrassWeave" x="0" y="0" width="16" height="16" patternUnits="userSpaceOnUse">
+                <rect width="16" height="16" fill="#c8d8b8"/>
+                <line x1="0" y1="0" x2="16" y2="0" stroke="#a8b898" stroke-width="2"/>
+                <line x1="0" y1="4" x2="16" y2="4" stroke="#b8c8a8" stroke-width="1.5"/>
+                <line x1="0" y1="8" x2="16" y2="8" stroke="#a8b898" stroke-width="2"/>
+                <line x1="0" y1="12" x2="16" y2="12" stroke="#b8c8a8" stroke-width="1.5"/>
+                <line x1="0" y1="0" x2="0" y2="16" stroke="#98a888" stroke-width="1.5"/>
+                <line x1="4" y1="0" x2="4" y2="16" stroke="#a8b898" stroke-width="1"/>
+                <line x1="8" y1="0" x2="8" y2="16" stroke="#98a888" stroke-width="1.5"/>
+                <line x1="12" y1="0" x2="12" y2="16" stroke="#a8b898" stroke-width="1"/>
+              </pattern>
+            </defs>
+            <!-- sky -->
+            <rect width="1400" height="700" fill="url(#coastSky)"/>
+            <!-- horizon water -->
+            <rect x="0" y="460" width="1400" height="240" fill="#b8d8ec"/>
+            <!-- wave texture -->
+            <rect x="0" y="470" width="1400" height="220" fill="url(#wavePattern)"/>
+            <!-- beach / sand band -->
+            <ellipse cx="700" cy="520" rx="900" ry="80" fill="#ddd0a8" opacity=".6"/>
+            <!-- dunes / seagrass suggestion -->
+            <ellipse cx="200" cy="580" rx="260" ry="100" fill="#c8c0a0" opacity=".4"/>
+            <ellipse cx="1200" cy="570" rx="240" ry="90" fill="#c8c0a0" opacity=".35"/>
+            <!-- seagrass texture patch -->
+            <rect x="0" y="540" width="400" height="160" fill="url(#seagrassWeave)" opacity=".35"/>
+            <rect x="1000" y="530" width="400" height="170" fill="url(#seagrassWeave)" opacity=".3"/>
+            <!-- light overlay -->
+            <rect width="1400" height="700" fill="#e8f4f8" opacity=".18"/>
+            <!-- vignette top -->
+            <linearGradient id="coastVig" x1="0" y1="0" x2="0" y2="1">
+              <stop offset="0%" stop-color="#c0d8e8" stop-opacity=".5"/>
+              <stop offset="40%" stop-color="transparent"/>
+            </linearGradient>
+            <rect width="1400" height="700" fill="url(#coastVig)"/>
+          </svg>
+        </div>
+        <div class="s2-content">
+          <div class="s2-grid">
+            <div>
+              <div class="tagline reveal d1">Story Two</div>
+              <h2 class="headline reveal d2">Coastal</h2>
+              <span class="rule reveal d3"></span>
+              <p class="body-copy reveal d4">Sea-bleached linens, seagrass weaves, and the unhurried blue of open water. Coastal living reimagined as quiet sophistication — salt air rendered in texture, light, and the gentle rhythm of natural fibre.</p>
+            </div>
+            <div>
+              <div class="palette-strip reveal d4" style="border-radius:2px;overflow:hidden;margin-bottom:16px">
+                <div class="swatch" style="background:#7fb5d5" data-name="Horizon"></div>
+                <div class="swatch" style="background:#c8d8b8" data-name="Seagrass"></div>
+                <div class="swatch" style="background:#ddd0a8" data-name="Driftwood"></div>
+                <div class="swatch" style="background:#5c9abd" data-name="Tidal"></div>
+                <div class="swatch" style="background:#e8f0f7" data-name="Sea Mist"></div>
+              </div>
+              <div class="pattern-frame reveal d5" style="width:72px;height:72px">
+                <svg viewBox="0 0 72 72" width="72" height="72" xmlns="http://www.w3.org/2000/svg">
+                  <rect width="72" height="72" fill="url(#seagrassWeave)"/>
+                  <rect width="72" height="72" fill="none" stroke="#5c9abd" stroke-width=".5" opacity=".6"/>
+                </svg>
+              </div>
+              <div class="pattern-label reveal d5">Coastal Seagrass — No. 07</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- ══ SPREAD 3: MOODY MAXIMALIST ══ -->
+    <div class="slide s3" data-index="2">
+      <div class="spread-num">03</div>
+      <div class="s3-layout" style="height:100%">
+        <div class="s3-hero">
+          <svg viewBox="0 0 700 900" preserveAspectRatio="xMidYMid slice" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" style="position:absolute;inset:0">
+            <defs>
+              <pattern id="damaskUnit" x="0" y="0" width="120" height="160" patternUnits="userSpaceOnUse">
+                <!-- large medallion -->
+                <ellipse cx="60" cy="80" rx="44" ry="58" fill="none" stroke="#6a3020" stroke-width="1.2"/>
+                <ellipse cx="60" cy="80" rx="34" ry="46" fill="#3a1810" opacity=".6"/>
+                <ellipse cx="60" cy="80" rx="24" ry="32" fill="none" stroke="#8a4030" stroke-width=".8"/>
+                <!-- central motif -->
+                <path d="M60 48 L66 68 L84 68 L70 80 L76 100 L60 88 L44 100 L50 80 L36 68 L54 68 Z" fill="#6a3020" opacity=".7"/>
+                <!-- diamond corners -->
+                <rect x="52" y="10" width="16" height="16" fill="#4a2018" transform="rotate(45,60,18)" opacity=".5"/>
+                <rect x="52" y="134" width="16" height="16" fill="#4a2018" transform="rotate(45,60,142)" opacity=".5"/>
+                <rect x="-8" y="72" width="16" height="16" fill="#4a2018" transform="rotate(45,0,80)" opacity=".5"/>
+                <rect x="112" y="72" width="16" height="16" fill="#4a2018" transform="rotate(45,120,80)" opacity=".5"/>
+                <!-- acanthus leaves suggestion -->
+                <path d="M60 26 Q68 40 60 54 Q52 40 60 26" fill="#6a3020" opacity=".45"/>
+                <path d="M60 106 Q68 120 60 134 Q52 120 60 106" fill="#6a3020" opacity=".45"/>
+                <path d="M16 80 Q30 72 44 80 Q30 88 16 80" fill="#6a3020" opacity=".45"/>
+                <path d="M76 80 Q90 72 104 80 Q90 88 76 80" fill="#6a3020" opacity=".45"/>
+              </pattern>
+              <linearGradient id="moodVig" x1="0" y1="0" x2="1" y2="1">
+                <stop offset="0%" stop-color="#2a1208" stop-opacity=".9"/>
+                <stop offset="100%" stop-color="#1a0c06" stop-opacity=".5"/>
+              </linearGradient>
+            </defs>
+            <rect width="700" height="900" fill="#1e0e08"/>
+            <rect width="700" height="900" fill="url(#damaskUnit)" opacity=".8"/>
+            <!-- deep jewel overlay -->
+            <rect width="700" height="900" fill="#3a1a10" opacity=".3"/>
+            <!-- gold shimmer glaze -->
+            <rect width="700" height="900" fill="#c9a961" opacity=".06"/>
+            <!-- edge vignette -->
+            <radialGradient id="moodRadial" cx="50%" cy="50%" r="60%">
+              <stop offset="0%" stop-color="transparent"/>
+              <stop offset="100%" stop-color="#0a0604" stop-opacity=".75"/>
+            </radialGradient>
+            <rect width="700" height="900" fill="url(#moodRadial)"/>
+          </svg>
+        </div>
+        <div class="s3-content">
+          <div class="tagline reveal d1">Story Three</div>
+          <h2 class="headline reveal d2">Moody<br>Maximalist</h2>
+          <span class="rule reveal d3"></span>
+          <p class="body-copy reveal d4">In darkness, pattern reveals its full power. Oxblood damask, smoked jewel velvets, and gilded acanthus scrollwork — for rooms that command absolute attention and refuse to whisper.</p>
+          <span class="rule reveal d4" style="opacity:.15"></span>
+          <div class="palette-strip reveal d4" style="margin-top:8px;border-radius:2px;overflow:hidden">
+            <div class="swatch" style="background:#6a1a10" data-name="Oxblood"></div>
+            <div class="swatch" style="background:#1e0e08" data-name="Ebony"></div>
+            <div class="swatch" style="background:#c9a961" data-name="Gilt"></div>
+            <div class="swatch" style="background:#3a2040" data-name="Aubergine"></div>
+            <div class="swatch" style="background:#4a2818" data-name="Tobacco"></div>
+          </div>
+          <div class="pattern-frame reveal d5" style="margin-top:18px;width:88px;height:88px">
+            <svg viewBox="0 0 88 88" width="88" height="88" xmlns="http://www.w3.org/2000/svg">
+              <rect width="88" height="88" fill="#1e0e08"/>
+              <rect width="88" height="88" fill="url(#damaskUnit)" opacity=".9"/>
+              <rect width="88" height="88" fill="none" stroke="#c9a961" stroke-width=".5" opacity=".5"/>
+            </svg>
+          </div>
+          <div class="pattern-label reveal d5">Midnight Damask — No. 33</div>
+        </div>
+      </div>
+    </div>
+
+    <!-- ══ SPREAD 4: ART DECO ══ -->
+    <div class="slide s4" data-index="3">
+      <div class="spread-num">04</div>
+      <div class="s4-frame"></div>
+      <!-- Full-bleed deco geometry bg -->
+      <svg viewBox="0 0 1400 900" preserveAspectRatio="xMidYMid slice" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" style="position:absolute;inset:0;z-index:0">
+        <defs>
+          <pattern id="decoGrid" x="0" y="0" width="100" height="100" patternUnits="userSpaceOnUse">
+            <!-- radiating fan lines -->
+            <line x1="50" y1="50" x2="0" y2="0" stroke="#c9a961" stroke-width=".4" opacity=".3"/>
+            <line x1="50" y1="50" x2="100" y2="0" stroke="#c9a961" stroke-width=".4" opacity=".3"/>
+            <line x1="50" y1="50" x2="0" y2="100" stroke="#c9a961" stroke-width=".4" opacity=".2"/>
+            <line x1="50" y1="50" x2="100" y2="100" stroke="#c9a961" stroke-width=".4" opacity=".2"/>
+            <circle cx="50" cy="50" r="30" fill="none" stroke="#c9a961" stroke-width=".3" opacity=".2"/>
+            <circle cx="50" cy="50" r="18" fill="none" stroke="#c9a961" stroke-width=".25" opacity=".18"/>
+            <rect x="35" y="35" width="30" height="30" fill="none" stroke="#c9a961" stroke-width=".25" opacity=".15" transform="rotate(45,50,50)"/>
+          </pattern>
+          <linearGradient id="decoFade" x1="0" y1="0" x2="0" y2="1">
+            <stop offset="0%" stop-color="#0e0c08"/>
+            <stop offset="50%" stop-color="#1a1408"/>
+            <stop offset="100%" stop-color="#0e0c08"/>
+          </linearGradient>
+        </defs>
+        <rect width="1400" height="900" fill="url(#decoFade)"/>
+        <rect width="1400" height="900" fill="url(#decoGrid)"/>
+        <!-- sunburst at center -->
+        <g transform="translate(700,450)" opacity=".12">
+          <line x1="0" y1="-320" x2="0" y2="320" stroke="#c9a961" stroke-width="1"/>
+          <line x1="-320" y1="0" x2="320" y2="0" stroke="#c9a961" stroke-width="1"/>
+          <line x1="-226" y1="-226" x2="226" y2="226" stroke="#c9a961" stroke-width=".7"/>
+          <line x1="226" y1="-226" x2="-226" y2="226" stroke="#c9a961" stroke-width=".7"/>
+          <circle r="120" fill="none" stroke="#c9a961" stroke-width="1.5"/>
+          <circle r="180" fill="none" stroke="#c9a961" stroke-width=".8"/>
+          <circle r="260" fill="none" stroke="#c9a961" stroke-width=".5"/>
+        </g>
+        <!-- stepped arch at top/bottom -->
+        <rect x="0" y="0" width="1400" height="3" fill="#c9a961" opacity=".4"/>
+        <rect x="0" y="897" width="1400" height="3" fill="#c9a961" opacity=".4"/>
+        <rect x="0" y="8" width="1400" height="1" fill="#c9a961" opacity=".2"/>
+        <rect x="0" y="890" width="1400" height="1" fill="#c9a961" opacity=".2"/>
+      </svg>
+      <!-- Editorial content on top -->
+      <div class="s4-layout" style="position:relative;z-index:2">
+        <div class="tagline reveal d1">Story Four</div>
+        <h2 class="headline reveal d2">Art&nbsp;Deco</h2>
+        <span class="rule reveal d3"></span>
+        <p class="body-copy reveal d4">The geometry of ambition. Sunburst veneers, lacquered chevrons, and the cool authority of gilded exactitude — a style that enshrines the machine age in beauty, and refuses to age itself.</p>
+        <div class="palette-strip reveal d4" style="margin-top:24px;border-radius:2px;overflow:hidden;max-width:360px;margin-left:auto;margin-right:auto">
+          <div class="swatch" style="background:#c9a961" data-name="Gilt"></div>
+          <div class="swatch" style="background:#0e0c08" data-name="Lacquer"></div>
+          <div class="swatch" style="background:#e8dfc8" data-name="Ivory"></div>
+          <div class="swatch" style="background:#2a2010" data-name="Ebonised"></div>
+          <div class="swatch" style="background:#8a7840" data-name="Bronze"></div>
+        </div>
+        <div style="display:flex;flex-direction:column;align-items:center;margin-top:22px">
+          <div class="pattern-frame reveal d5" style="width:80px;height:80px">
+            <svg viewBox="0 0 80 80" width="80" height="80" xmlns="http://www.w3.org/2000/svg">
+              <rect width="80" height="80" fill="#12100a"/>
+              <rect width="80" height="80" fill="url(#decoGrid)"/>
+              <!-- central small motif -->
+              <rect x="28" y="28" width="24" height="24" fill="none" stroke="#c9a961" stroke-width="1" transform="rotate(45,40,40)" opacity=".7"/>
+              <circle cx="40" cy="40" r="8" fill="none" stroke="#c9a961" stroke-width=".8" opacity=".6"/>
+              <rect width="80" height="80" fill="none" stroke="#c9a961" stroke-width=".5" opacity=".4"/>
+            </svg>
+          </div>
+          <div class="pattern-label reveal d5">Sunburst Geo — No. 44</div>
+        </div>
+      </div>
+    </div>
+
+    <!-- ══ SPREAD 5: CHINOISERIE ══ -->
+    <div class="slide s5" data-index="4">
+      <div class="spread-num">05</div>
+      <div class="s5-layout" style="height:100%">
+        <div class="s5-content">
+          <div class="tagline reveal d1">Story Five</div>
+          <h2 class="headline reveal d2">Chin&shy;oiserie</h2>
+          <span class="rule reveal d3"></span>
+          <p class="body-copy reveal d4">Hand-painted reverie — the imagined Orient of European romanticism. Jade pagodas in willow mist, silk-thin branches bearing blossom, and mandarin birds frozen mid-flight on rice-paper grounds.</p>
+          <span class="rule reveal d4" style="opacity:.2"></span>
+          <div class="palette-strip reveal d4" style="margin-top:8px;border-radius:2px;overflow:hidden">
+            <div class="swatch" style="background:#f0ebe0" data-name="Rice Paper"></div>
+            <div class="swatch" style="background:#5c7a4a" data-name="Jade"></div>
+            <div class="swatch" style="background:#8a4830" data-name="Cinnabar"></div>
+            <div class="swatch" style="background:#7a9098" data-name="Celadon"></div>
+            <div class="swatch" style="background:#c8a040" data-name="Saffron"></div>
+          </div>
+          <div class="pattern-frame reveal d5" style="margin-top:18px;width:88px;height:88px">
+            <svg viewBox="0 0 88 88" width="88" height="88" xmlns="http://www.w3.org/2000/svg">
+              <rect width="88" height="88" fill="#f0ebe0"/>
+              <!-- branch -->
+              <path d="M10 80 Q30 60 44 40 Q55 24 60 10" fill="none" stroke="#5c7a4a" stroke-width="1.8"/>
+              <path d="M44 40 Q55 38 65 30" fill="none" stroke="#5c7a4a" stroke-width="1.2"/>
+              <path d="M30 60 Q20 55 12 48" fill="none" stroke="#5c7a4a" stroke-width="1.2"/>
+              <!-- blossoms -->
+              <circle cx="62" cy="10" r="5" fill="#e88878" opacity=".8"/>
+              <circle cx="60" cy="10" r="3" fill="none" stroke="#8a4830" stroke-width=".8"/>
+              <circle cx="68" cy="28" r="4" fill="#e88878" opacity=".7"/>
+              <circle cx="58" cy="22" r="3" fill="#f0c0b0" opacity=".6"/>
+              <!-- bird suggestion -->
+              <ellipse cx="22" cy="44" rx="10" ry="5" fill="#5c7a4a" opacity=".5" transform="rotate(-15,22,44)"/>
+              <ellipse cx="30" cy="42" rx="4" ry="2.5" fill="#c8a040" opacity=".6" transform="rotate(-15,30,42)"/>
+              <!-- pagoda distant -->
+              <rect x="70" y="55" width="14" height="20" fill="#7a9098" opacity=".25"/>
+              <polygon points="70,55 84,55 77,48" fill="#7a9098" opacity=".25"/>
+              <rect width="88" height="88" fill="none" stroke="#5c7a4a" stroke-width=".5" opacity=".3"/>
+            </svg>
+          </div>
+          <div class="pattern-label reveal d5">Willow Mist — No. 21</div>
+        </div>
+        <div class="s5-hero">
+          <svg viewBox="0 0 700 900" preserveAspectRatio="xMidYMid slice" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" style="position:absolute;inset:0">
+            <defs>
+              <linearGradient id="chinoGrad" x1="0" y1="0" x2="0" y2="1">
+                <stop offset="0%" stop-color="#e8f0e8"/>
+                <stop offset="100%" stop-color="#f0ebe0"/>
+              </linearGradient>
+            </defs>
+            <rect width="700" height="900" fill="url(#chinoGrad)"/>
+            <!-- large repeating branches -->
+            <path d="M80 900 Q160 700 220 500 Q260 360 300 200 Q330 80 350 0" fill="none" stroke="#5c7a4a" stroke-width="2.5" opacity=".55"/>
+            <path d="M220 500 Q280 480 340 440" fill="none" stroke="#5c7a4a" stroke-width="1.8" opacity=".5"/>
+            <path d="M160 700 Q110 680 70 640" fill="none" stroke="#5c7a4a" stroke-width="1.5" opacity=".45"/>
+            <path d="M300 200 Q360 190 420 160" fill="none" stroke="#5c7a4a" stroke-width="1.5" opacity=".45"/>
+            <!-- second branch tree -->
+            <path d="M550 900 Q530 750 510 580 Q490 420 520 260 Q540 140 560 0" fill="none" stroke="#5c7a4a" stroke-width="2" opacity=".4"/>
+            <path d="M510 580 Q450 560 400 540" fill="none" stroke="#5c7a4a" stroke-width="1.3" opacity=".35"/>
+            <!-- blossoms scattered -->
+            <circle cx="220" cy="500" r="9" fill="#e88878" opacity=".7"/>
+            <circle cx="218" cy="500" r="5" fill="none" stroke="#8a4830" stroke-width=".8"/>
+            <circle cx="340" cy="440" r="7" fill="#f0c0b0" opacity=".65"/>
+            <circle cx="300" cy="200" r="10" fill="#e88878" opacity=".75"/>
+            <circle cx="298" cy="200" r="6" fill="none" stroke="#8a4830" stroke-width=".8"/>
+            <circle cx="420" cy="160" r="7" fill="#f0c0b0" opacity=".6"/>
+            <circle cx="510" cy="580" r="8" fill="#e88878" opacity=".6"/>
+            <circle cx="520" cy="260" r="9" fill="#e88878" opacity=".65"/>
+            <!-- birds in flight -->
+            <g opacity=".6" transform="translate(380,320)">
+              <ellipse cx="0" cy="0" rx="16" ry="7" fill="#5c7a4a" transform="rotate(-20)"/>
+              <ellipse cx="20" cy="-2" rx="6" ry="3" fill="#c8a040" transform="rotate(-20)"/>
+              <path d="M-16,0 Q-26,-10 -34,-6" fill="none" stroke="#5c7a4a" stroke-width="1.5"/>
+              <path d="M-16,0 Q-20,10 -12,14" fill="none" stroke="#5c7a4a" stroke-width="1.5"/>
+            </g>
+            <g opacity=".4" transform="translate(460,420)">
+              <ellipse cx="0" cy="0" rx="12" ry="5" fill="#5c7a4a" transform="rotate(-15)"/>
+              <ellipse cx="14" cy="-1" rx="4" ry="2" fill="#8a4830" transform="rotate(-15)"/>
+            </g>
+            <!-- pagoda distant -->
+            <g opacity=".25" transform="translate(580,600)">
+              <rect x="-24" y="-60" width="48" height="60" fill="#7a9098"/>
+              <rect x="-30" y="-70" width="60" height="12" fill="#5c7a4a"/>
+              <rect x="-36" y="-80" width="72" height="12" fill="#7a9098"/>
+              <polygon points="-20,-80 20,-80 0,-100" fill="#5c7a4a"/>
+            </g>
+            <!-- rice-paper texture overlay -->
+            <rect width="700" height="900" fill="#f4ede0" opacity=".12"/>
+          </svg>
+        </div>
+      </div>
+    </div>
+
+    <!-- ══ SPREAD 6: MODERN MINIMAL ══ -->
+    <div class="slide s6" data-index="5">
+      <div class="spread-num">06</div>
+      <div class="s6-layout" style="height:100%">
+        <div class="s6-content">
+          <div style="flex:1"></div>
+          <div>
+            <div class="tagline reveal d1">Story Six</div>
+            <h2 class="headline reveal d2">Modern<br>Minimal</h2>
+            <span class="rule reveal d3"></span>
+            <p class="body-copy reveal d4">Restraint as the highest form of luxury. Textured linen grounds, micro-stripe grasscloths, and the precise breath of negative space — interiors that speak in whispers and are heard across any room.</p>
+          </div>
+          <div style="padding-bottom:clamp(48px,6vh,88px)">
+            <div class="palette-strip reveal d4" style="margin-top:28px;border-radius:2px;overflow:hidden">
+              <div class="swatch" style="background:#f9f8f6" data-name="Chalk"></div>
+              <div class="swatch" style="background:#d8d4cc" data-name="Linen"></div>
+              <div class="swatch" style="background:#a8a098" data-name="Stone"></div>
+              <div class="swatch" style="background:#636058" data-name="Graphite"></div>
+              <div class="swatch" style="background:#1c1a17" data-name="Onyx"></div>
+            </div>
+            <div class="pattern-frame reveal d5" style="margin-top:16px;width:88px;height:88px">
+              <svg viewBox="0 0 88 88" width="88" height="88" xmlns="http://www.w3.org/2000/svg">
+                <defs>
+                  <pattern id="linenWeave" x="0" y="0" width="8" height="8" patternUnits="userSpaceOnUse">
+                    <rect width="8" height="8" fill="#e8e4de"/>
+                    <line x1="0" y1="0" x2="8" y2="0" stroke="#d0ccc4" stroke-width="1.2"/>
+                    <line x1="0" y1="4" x2="8" y2="4" stroke="#dedad4" stroke-width=".8"/>
+                    <line x1="0" y1="0" x2="0" y2="8" stroke="#ccc8c0" stroke-width="1"/>
+                    <line x1="4" y1="0" x2="4" y2="8" stroke="#d8d4cc" stroke-width=".6"/>
+                  </pattern>
+                </defs>
+                <rect width="88" height="88" fill="url(#linenWeave)"/>
+                <rect width="88" height="88" fill="none" stroke="#a8a098" stroke-width=".5" opacity=".5"/>
+              </svg>
+            </div>
+            <div class="pattern-label reveal d5">Natural Linen — No. 02</div>
+          </div>
+        </div>
+        <div class="s6-hero">
+          <svg viewBox="0 0 700 900" preserveAspectRatio="xMidYMid slice" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" style="position:absolute;inset:0">
+            <defs>
+              <pattern id="minStripe" x="0" y="0" width="1" height="20" patternUnits="userSpaceOnUse">
+                <rect width="1" height="20" fill="#e0dcd4"/>
+                <rect width="1" height="1" y="10" fill="#ccc8c0"/>
+              </pattern>
+              <pattern id="minGrid" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
+                <rect width="40" height="40" fill="#ebebea" />
+                <line x1="0" y1="0" x2="40" y2="0" stroke="#d8d4cc" stroke-width=".5"/>
+                <line x1="0" y1="0" x2="0" y2="40" stroke="#d8d4cc" stroke-width=".5"/>
+              </pattern>
+            </defs>
+            <rect width="700" height="900" fill="#e8e5e0"/>
+            <!-- vertical micro-stripe texture -->
+            <rect width="700" height="900" fill="url(#minStripe)" opacity=".5"/>
+            <!-- horizontal bands — architectural rhythm -->
+            <rect x="0" y="200" width="700" height="1" fill="#ccc8c0" opacity=".6"/>
+            <rect x="0" y="400" width="700" height="1" fill="#ccc8c0" opacity=".5"/>
+            <rect x="0" y="600" width="700" height="1" fill="#ccc8c0" opacity=".4"/>
+            <rect x="0" y="240" width="700" height=".5" fill="#d8d4cc" opacity=".35"/>
+            <rect x="0" y="440" width="700" height=".5" fill="#d8d4cc" opacity=".3"/>
+            <!-- floating rectangular forms -->
+            <rect x="80" y="180" width="180" height="260" fill="#f0ede8" opacity=".5"/>
+            <rect x="420" y="340" width="200" height="300" fill="#dedad4" opacity=".45"/>
+            <rect x="160" y="580" width="280" height="160" fill="#e8e4de" opacity=".4"/>
+            <!-- accent line -->
+            <rect x="0" y="450" width="700" height="2" fill="#c9a961" opacity=".18"/>
+            <!-- grid overlay subtle -->
+            <rect width="700" height="900" fill="url(#minGrid)" opacity=".12"/>
+            <!-- light gradient top -->
+            <linearGradient id="minLight" x1="0" y1="0" x2="0" y2="1">
+              <stop offset="0%" stop-color="#fff" stop-opacity=".25"/>
+              <stop offset="50%" stop-color="transparent"/>
+            </linearGradient>
+            <rect width="700" height="900" fill="url(#minLight)"/>
+          </svg>
+          <div class="s6-accent-line"></div>
+        </div>
+      </div>
+    </div>
+
+  </div><!-- /slides-track -->
+</div><!-- /viewport -->
+
+<script>
+(function(){
+  'use strict';
+
+  const TOTAL = 6;
+  const STORIES = [
+    {title:'Grandmillennial', sub:'Story One'},
+    {title:'Coastal',         sub:'Story Two'},
+    {title:'Moody Maximalist',sub:'Story Three'},
+    {title:'Art Deco',        sub:'Story Four'},
+    {title:'Chinoiserie',     sub:'Story Five'},
+    {title:'Modern Minimal',  sub:'Story Six'},
+  ];
+
+  let current = 0;
+  let isAnimating = false;
+  let touchStartX = 0, touchStartY = 0;
+
+  const track    = document.getElementById('track');
+  const dotsEl   = document.getElementById('dots');
+  const bar      = document.getElementById('progressBar');
+  const tocOverlay = document.getElementById('tocOverlay');
+  const tocList    = document.getElementById('tocList');
+  const prevBtn  = document.getElementById('arrowPrev');
+  const nextBtn  = document.getElementById('arrowNext');
+
+  // ── BUILD DOTS ──
+  for(let i=0;i<TOTAL;i++){
+    const d=document.createElement('div');
+    d.className='dot'+(i===0?' active':'');
+    d.setAttribute('aria-label','Go to spread '+(i+1));
+    d.setAttribute('role','button');
+    d.setAttribute('tabindex','0');
+    d.onclick=()=>goTo(i);
+    d.onkeydown=e=>{if(e.key==='Enter'||e.key===' ')goTo(i)};
+    dotsEl.appendChild(d);
+  }
+
+  // ── BUILD TOC ──
+  STORIES.forEach((s,i)=>{
+    const li=document.createElement('li');
+    li.className='toc-item';
+    li.innerHTML=`<span class="toc-n">0${i+1}</span><span class="toc-item-title">${s.title}</span><span class="toc-sub">${s.sub}</span>`;
+    li.onclick=()=>{goTo(i);closeToc()};
+    li.setAttribute('tabindex','0');
+    li.onkeydown=e=>{if(e.key==='Enter')li.click()};
+    tocList.appendChild(li);
+  });
+
+  // ── GO TO SLIDE ──
+  window.goTo=function(idx){
+    if(isAnimating) return;
+    if(idx<0||idx>=TOTAL) return;
+    isAnimating=true;
+    clearReveals(current);
+    current=idx;
+    track.style.transform=`translateX(-${(100/6)*current}%)`;
+    updateUI();
+    // Trigger reveals after transition starts
+    setTimeout(()=>{triggerReveals(current)},120);
+    setTimeout(()=>{isAnimating=false},820);
+  };
+
+  function updateUI(){
+    // dots
+    dotsEl.querySelectorAll('.dot').forEach((d,i)=>d.classList.toggle('active',i===current));
+    // progress bar
+    bar.style.width=((current+1)/TOTAL*100)+'%';
+    // arrows
+    prevBtn.style.opacity=current===0?'0.2':'0.6';
+    nextBtn.style.opacity=current===TOTAL-1?'0.2':'0.6';
+    prevBtn.style.pointerEvents=current===0?'none':'auto';
+    nextBtn.style.pointerEvents=current===TOTAL-1?'none':'auto';
+  }
+
+  function clearReveals(idx){
+    const slide=track.children[idx];
+    slide.querySelectorAll('.reveal').forEach(el=>{
+      el.classList.remove('in');
+    });
+  }
+
+  function triggerReveals(idx){
+    const slide=track.children[idx];
+    slide.querySelectorAll('.reveal').forEach(el=>{
+      // force reflow
+      void el.offsetWidth;
+      el.classList.add('in');
+    });
+  }
+
+  // ── PARALLAX ──
+  function applyParallax(e){
+    const slide=track.children[current];
+    const hero=slide.querySelector('.parallax-hero');
+    if(!hero) return;
+    const speed=parseFloat(hero.dataset.speed||'.03');
+    const cx=window.innerWidth/2, cy=window.innerHeight/2;
+    const dx=(e.clientX-cx)*speed*60;
+    const dy=(e.clientY-cy)*speed*40;
+    hero.style.transform=`translate(${dx}px,${dy}px) scale(1.06)`;
+  }
+  document.addEventListener('mousemove',applyParallax,{passive:true});
+
+  // ── KEYBOARD ──
+  document.addEventListener('keydown',e=>{
+    if(tocOverlay.classList.contains('open')){
+      if(e.key==='Escape') closeToc();
+      return;
+    }
+    if(e.key==='ArrowRight'||e.key==='ArrowDown') goTo(current+1);
+    else if(e.key==='ArrowLeft'||e.key==='ArrowUp') goTo(current-1);
+    else if(e.key==='Home') goTo(0);
+    else if(e.key==='End') goTo(TOTAL-1);
+  });
+
+  // ── TOUCH ──
+  document.addEventListener('touchstart',e=>{
+    touchStartX=e.touches[0].clientX;
+    touchStartY=e.touches[0].clientY;
+  },{passive:true});
+  document.addEventListener('touchend',e=>{
+    const dx=e.changedTouches[0].clientX-touchStartX;
+    const dy=e.changedTouches[0].clientY-touchStartY;
+    if(Math.abs(dx)>Math.abs(dy)&&Math.abs(dx)>40){
+      goTo(dx<0?current+1:current-1);
+    }
+  },{passive:true});
+
+  // ── TOC ──
+  window.openToc=function(){
+    tocOverlay.classList.add('open');
+    tocOverlay.querySelector('.toc-close').focus();
+  };
+  window.closeToc=function(){
+    tocOverlay.classList.remove('open');
+  };
+  tocOverlay.addEventListener('click',e=>{
+    if(e.target===tocOverlay) closeToc();
+  });
+
+  // ── WHEEL ──
+  let wheelCooldown=false;
+  document.addEventListener('wheel',e=>{
+    if(wheelCooldown||tocOverlay.classList.contains('open')) return;
+    if(Math.abs(e.deltaX)>Math.abs(e.deltaY)){
+      goTo(e.deltaX>30?current+1:e.deltaX<-30?current-1:current);
+    } else if(Math.abs(e.deltaY)>40){
+      goTo(e.deltaY>0?current+1:current-1);
+    }
+    wheelCooldown=true;
+    setTimeout(()=>{wheelCooldown=false},900);
+  },{passive:true});
+
+  // ── INIT ──
+  updateUI();
+  setTimeout(()=>triggerReveals(0),200);
+
+})();
+</script>
+</body>
+</html>

← a0f576c Agent-driven game: DW Pattern Match (frontend-developer) — 8  ·  back to Model Arena  ·  Agent-driven art toy: DW Damask Kaleidoscope (frontend-devel 71faf27 →