[object Object]

← back to Dw Style Quiz

Designer Wallcoverings style quiz: fixed GPT-5.1 layout bug, rebranded, added result/share/restart flow

78a0a7414cd2697d0211dc93762f6a49c1f1327f · 2026-07-25 01:04:19 -0700 · Steve Abrams

Files touched

Diff

commit 78a0a7414cd2697d0211dc93762f6a49c1f1327f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sat Jul 25 01:04:19 2026 -0700

    Designer Wallcoverings style quiz: fixed GPT-5.1 layout bug, rebranded, added result/share/restart flow
---
 .gitignore |   8 +
 index.html | 955 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 963 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1924158
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..e1d4005
--- /dev/null
+++ b/index.html
@@ -0,0 +1,955 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>What's Your Wallcovering Style? — Designer Wallcoverings</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1" />
+  <meta name="description" content="A five-tap editorial quiz to discover your wallcovering style — Traditional Damask, Modern Minimalist, Bohemian Maximalist, or Art Deco Glam. By Designer Wallcoverings." />
+  <meta property="og:title" content="What's Your Wallcovering Style?" />
+  <meta property="og:description" content="Five taps to your signature wall. A quiz by Designer Wallcoverings." />
+  <style>
+    :root {
+      --bg: #0d0d0f;
+      --text: #f5f2ea;
+      --muted: #8a8578;
+      --accent: #c9a961;
+
+      --radius-lg: 26px;
+      --radius-md: 18px;
+
+      --font-display: "Didot", "Bodoni MT", "Playfair Display", Georgia, serif;
+      --font-body: -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
+
+      --ease-out: cubic-bezier(.22, 1, .36, 1);
+    }
+
+    @keyframes fadeUp {
+      from { opacity: 0; transform: translateY(24px); }
+      to { opacity: 1; transform: none; }
+    }
+    @keyframes clipReveal {
+      from { opacity: 0; transform: scale(.965); filter: blur(6px); }
+      to { opacity: 1; transform: none; filter: blur(0); }
+    }
+    @keyframes shimmer {
+      from { background-position: 200% 0; }
+      to { background-position: -200% 0; }
+    }
+
+    * { box-sizing: border-box; }
+
+    html, body {
+      margin: 0;
+      padding: 0;
+      background: radial-gradient(circle at top, #1d1d23 0, #050507 55%, #000 100%);
+      color: var(--text);
+      font-family: var(--font-body);
+      -webkit-font-smoothing: antialiased;
+      min-height: 100%;
+    }
+
+    body {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      min-height: 100vh;
+      padding: 24px;
+    }
+
+    /* The 1080x1080 shareable canvas */
+    .frame {
+      position: relative;
+      width: min(92vmin, 1080px);
+      height: min(92vmin, 1080px);
+      background: radial-gradient(circle at 10% 0, #252531 0, #0b0b0d 40%, #050507 100%);
+      border-radius: 40px;
+      box-shadow: 0 26px 80px rgba(0, 0, 0, 0.65);
+      border: 1px solid rgba(255, 255, 255, 0.06);
+      overflow: hidden;
+      display: flex;
+      flex-direction: column;
+      padding: clamp(20px, 3.4vmin, 40px);
+    }
+
+    @media (max-width: 620px) {
+      body { padding: 0; }
+      .frame {
+        width: 100vw;
+        height: 100vh;
+        height: 100dvh;
+        border-radius: 0;
+        box-shadow: none;
+        border: none;
+      }
+    }
+
+    /* Chrome: brand + progress */
+    .chrome {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      gap: 16px;
+      flex: 0 0 auto;
+    }
+
+    .brand-lockup {
+      display: flex;
+      align-items: center;
+      gap: 10px;
+      letter-spacing: 0.16em;
+      text-transform: uppercase;
+      font-size: clamp(9px, 1.5vmin, 12px);
+      color: var(--muted);
+    }
+
+    .brand-mark {
+      width: clamp(16px, 2.4vmin, 22px);
+      height: clamp(16px, 2.4vmin, 22px);
+      border-radius: 999px;
+      border: 1px solid rgba(201, 169, 97, 0.6);
+      background: conic-gradient(from 210deg, rgba(255,255,255,0.12), rgba(201,169,97,0.65), rgba(125,106,69,0.4), rgba(0,0,0,0.85), rgba(255,255,255,0.12));
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      flex: 0 0 auto;
+    }
+
+    .brand-mark::after {
+      content: "";
+      width: 38%;
+      height: 38%;
+      border-radius: 999px;
+      background: radial-gradient(circle at 30% 0, #f5f2ea 0, #e4d4ae 40%, #8d6a2b 100%);
+    }
+
+    .brand-name b { color: var(--text); font-weight: 600; }
+
+    .steps {
+      display: inline-flex;
+      align-items: center;
+      gap: 5px;
+    }
+
+    .steps-dot {
+      width: 4px;
+      height: clamp(10px, 1.8vmin, 14px);
+      border-radius: 999px;
+      background: rgba(255, 255, 255, 0.1);
+      overflow: hidden;
+      position: relative;
+    }
+
+    .steps-dot::after {
+      content: "";
+      position: absolute;
+      inset: 0;
+      transform-origin: bottom;
+      transform: scaleY(0);
+      background: linear-gradient(to top, #c9a961, #f5e3b7);
+      transition: transform 320ms var(--ease-out);
+    }
+
+    .steps-dot.on::after { transform: scaleY(1); }
+
+    /* Stage: the part that swaps screens. flex:1 gives it real height. */
+    .stage {
+      position: relative;
+      flex: 1 1 auto;
+      min-height: 0;
+      margin: clamp(14px, 2.4vmin, 26px) 0;
+    }
+
+    .screen {
+      position: absolute;
+      inset: 0;
+      display: flex;
+      flex-direction: column;
+      opacity: 0;
+      pointer-events: none;
+      transform: translateY(16px);
+      transition: opacity 340ms var(--ease-out), transform 340ms var(--ease-out);
+    }
+
+    .screen.active {
+      opacity: 1;
+      pointer-events: auto;
+      transform: none;
+    }
+
+    /* ---- Intro screen ---- */
+    .intro {
+      justify-content: center;
+      text-align: center;
+      gap: clamp(14px, 2.4vmin, 26px);
+      align-items: center;
+    }
+
+    .eyebrow {
+      font-size: clamp(10px, 1.6vmin, 13px);
+      text-transform: uppercase;
+      letter-spacing: 0.26em;
+      color: var(--accent);
+    }
+
+    .intro-title {
+      font-family: var(--font-display);
+      font-size: clamp(38px, 8.6vmin, 92px);
+      line-height: 0.98;
+      letter-spacing: -0.03em;
+      text-transform: uppercase;
+      margin: 0;
+    }
+    .intro-title .em { color: var(--accent); font-style: italic; }
+
+    .intro-sub {
+      font-size: clamp(13px, 2.1vmin, 18px);
+      color: rgba(245, 242, 234, 0.72);
+      max-width: 30ch;
+      line-height: 1.55;
+      margin: 0;
+    }
+
+    .intro-swatches {
+      display: flex;
+      gap: clamp(8px, 1.4vmin, 14px);
+      margin-top: 4px;
+    }
+    .intro-swatches .chip {
+      width: clamp(44px, 8vmin, 92px);
+      height: clamp(44px, 8vmin, 92px);
+      border-radius: 14px;
+      overflow: hidden;
+      border: 1px solid rgba(255,255,255,0.1);
+      box-shadow: 0 10px 30px rgba(0,0,0,0.5);
+    }
+    .intro-swatches .chip > div { width: 100%; height: 100%; }
+
+    /* ---- Question screens ---- */
+    .q-head {
+      display: flex;
+      align-items: center;
+      gap: 10px;
+      font-size: clamp(9px, 1.5vmin, 12px);
+      text-transform: uppercase;
+      letter-spacing: 0.18em;
+      color: var(--muted);
+      margin-bottom: clamp(6px, 1vmin, 10px);
+      flex: 0 0 auto;
+    }
+    .q-head .rule { flex: 1; height: 1px; background: linear-gradient(to right, rgba(201,169,97,0.7), transparent); }
+
+    .q-title {
+      font-family: var(--font-display);
+      font-size: clamp(22px, 4.2vmin, 44px);
+      line-height: 1.06;
+      letter-spacing: -0.02em;
+      margin: 0 0 clamp(12px, 2vmin, 24px);
+      flex: 0 0 auto;
+    }
+
+    .answers {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: clamp(8px, 1.5vmin, 16px);
+      flex: 1 1 auto;
+      min-height: 0;
+    }
+
+    .answer {
+      position: relative;
+      border-radius: var(--radius-md);
+      padding: clamp(10px, 1.6vmin, 16px);
+      background: radial-gradient(circle at 0 0, rgba(255,255,255,0.07), transparent 55%), linear-gradient(145deg, #15151b, #101016);
+      border: 1px solid rgba(255, 255, 255, 0.08);
+      color: inherit;
+      font: inherit;
+      text-align: left;
+      cursor: pointer;
+      overflow: hidden;
+      display: flex;
+      flex-direction: column;
+      gap: clamp(6px, 1vmin, 10px);
+      transition: transform 200ms var(--ease-out), box-shadow 200ms var(--ease-out), border-color 200ms var(--ease-out);
+    }
+    .answer:hover, .answer:focus-visible {
+      transform: translateY(-3px);
+      box-shadow: 0 14px 40px rgba(0, 0, 0, 0.7);
+      border-color: rgba(201, 169, 97, 0.7);
+      outline: none;
+    }
+    .answer:active { transform: translateY(-1px) scale(0.99); }
+
+    .answer .swatch {
+      position: relative;
+      border-radius: 12px;
+      overflow: hidden;
+      flex: 1 1 auto;
+      min-height: clamp(52px, 9vmin, 120px);
+      border: 1px solid rgba(255, 255, 255, 0.08);
+    }
+    .answer .swatch > div { position: absolute; inset: 0; }
+
+    .answer .swatch-tag {
+      position: absolute;
+      right: 7px;
+      bottom: 7px;
+      font-size: clamp(8px, 1.3vmin, 10px);
+      text-transform: uppercase;
+      letter-spacing: 0.16em;
+      padding: 3px 7px;
+      border-radius: 999px;
+      background: rgba(10, 10, 14, 0.78);
+      border: 1px solid rgba(255, 255, 255, 0.22);
+    }
+
+    .answer .a-label {
+      font-size: clamp(12px, 1.9vmin, 16px);
+      letter-spacing: 0.02em;
+      color: rgba(245, 242, 234, 0.92);
+      font-weight: 500;
+    }
+    .answer .a-meta {
+      font-size: clamp(10px, 1.5vmin, 12.5px);
+      color: var(--muted);
+      line-height: 1.4;
+    }
+
+    @media (max-width: 620px) {
+      .answer .a-meta { display: none; }
+    }
+
+    /* ---- Result screen ---- */
+    .result {
+      animation: clipReveal 0.7s var(--ease-out) both;
+    }
+    .result-inner {
+      flex: 1 1 auto;
+      display: grid;
+      grid-template-rows: auto 1fr auto;
+      gap: clamp(12px, 2vmin, 22px);
+      min-height: 0;
+    }
+
+    .result-top {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      font-size: clamp(9px, 1.5vmin, 12px);
+      text-transform: uppercase;
+      letter-spacing: 0.18em;
+      color: var(--muted);
+    }
+    .result-top .tag {
+      display: inline-flex;
+      align-items: center;
+      gap: 7px;
+      padding: 4px 10px;
+      border-radius: 999px;
+      border: 1px solid rgba(255, 255, 255, 0.16);
+      background: linear-gradient(135deg, rgba(10,10,14,0.9), rgba(0,0,0,1));
+    }
+    .result-top .tag .dot {
+      width: 8px; height: 8px; border-radius: 50%;
+      background: conic-gradient(from 160deg, #c9a961, #f7e5bd, #7d6a45, #c9a961);
+    }
+
+    .result-body {
+      display: grid;
+      grid-template-columns: 1.05fr 1fr;
+      gap: clamp(14px, 2.4vmin, 26px);
+      min-height: 0;
+    }
+    @media (max-width: 620px) {
+      .result-body { grid-template-columns: 1fr; grid-template-rows: minmax(120px, 1fr) auto; }
+    }
+
+    .result-pattern {
+      position: relative;
+      border-radius: var(--radius-md);
+      overflow: hidden;
+      border: 1px solid rgba(255, 255, 255, 0.08);
+      min-height: 0;
+    }
+    .result-pattern > div { position: absolute; inset: 0; }
+    .result-pattern .p-tag {
+      position: absolute;
+      left: 10px; top: 10px;
+      z-index: 2;
+      font-size: clamp(8px, 1.3vmin, 10px);
+      text-transform: uppercase;
+      letter-spacing: 0.16em;
+      padding: 3px 8px;
+      border-radius: 999px;
+      background: rgba(10, 10, 14, 0.78);
+      border: 1px solid rgba(255, 255, 255, 0.2);
+    }
+
+    .result-info {
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      min-height: 0;
+    }
+    .result-cat {
+      font-size: clamp(10px, 1.6vmin, 13px);
+      text-transform: uppercase;
+      letter-spacing: 0.2em;
+      color: var(--accent);
+      margin-bottom: 6px;
+    }
+    .result-title {
+      font-family: var(--font-display);
+      font-size: clamp(26px, 5vmin, 54px);
+      line-height: 1.02;
+      letter-spacing: -0.02em;
+      text-transform: uppercase;
+      margin: 0 0 clamp(8px, 1.4vmin, 14px);
+    }
+    .result-rule {
+      width: 40px; height: 2px;
+      background: linear-gradient(to right, var(--accent), transparent);
+      margin-bottom: clamp(8px, 1.4vmin, 14px);
+    }
+    .result-desc {
+      font-size: clamp(12px, 1.9vmin, 16px);
+      color: rgba(245, 242, 234, 0.82);
+      line-height: 1.55;
+      margin: 0 0 clamp(10px, 1.8vmin, 18px);
+    }
+    .result-tags { display: flex; flex-wrap: wrap; gap: 6px; }
+    .result-tags .t {
+      font-size: clamp(9px, 1.4vmin, 11px);
+      text-transform: uppercase;
+      letter-spacing: 0.14em;
+      padding: 4px 9px;
+      border-radius: 999px;
+      border: 1px solid rgba(255, 255, 255, 0.16);
+      background: linear-gradient(135deg, #15151b, #0f0f14);
+      color: rgba(245, 242, 234, 0.9);
+    }
+
+    /* Buttons */
+    .actions {
+      display: flex;
+      align-items: center;
+      gap: 10px;
+      flex-wrap: wrap;
+    }
+    .btn {
+      border-radius: 999px;
+      border: 1px solid rgba(255,255,255,0.14);
+      padding: clamp(9px, 1.5vmin, 14px) clamp(16px, 2.4vmin, 26px);
+      font-size: clamp(10px, 1.6vmin, 13px);
+      text-transform: uppercase;
+      letter-spacing: 0.2em;
+      background: transparent;
+      color: var(--text);
+      cursor: pointer;
+      font-family: var(--font-body);
+      transition: transform 180ms var(--ease-out), background 180ms var(--ease-out), border-color 180ms var(--ease-out);
+      white-space: nowrap;
+    }
+    .btn:hover { transform: translateY(-1px); border-color: rgba(255,255,255,0.35); }
+    .btn:active { transform: translateY(0); }
+    .btn-primary {
+      border: none;
+      color: #111015;
+      font-weight: 600;
+      background-image: linear-gradient(120deg, #c9a961, #f9e8bd, #7d6a45);
+      background-size: 180% 100%;
+      box-shadow: 0 12px 30px rgba(0, 0, 0, 0.55);
+    }
+    .btn-primary:hover { background-position: 100% 0; }
+    .btn-ghost { color: var(--muted); }
+    .btn-ghost:hover { color: var(--text); }
+
+    .begin-btn { margin-top: clamp(6px, 1.2vmin, 12px); }
+
+    /* Footer */
+    .footer {
+      display: flex;
+      align-items: center;
+      gap: 12px;
+      flex: 0 0 auto;
+      font-size: clamp(9px, 1.4vmin, 11px);
+      text-transform: uppercase;
+      letter-spacing: 0.18em;
+      color: var(--muted);
+    }
+    .progress-rail {
+      flex: 1;
+      height: 2px;
+      background: rgba(255, 255, 255, 0.1);
+      border-radius: 999px;
+      overflow: hidden;
+    }
+    .progress-bar {
+      height: 100%;
+      background: linear-gradient(to right, #c9a961, #f5e3b7);
+      transform-origin: left;
+      transform: scaleX(0);
+      transition: transform 340ms var(--ease-out);
+    }
+    .footer-logo { font-family: var(--font-display); letter-spacing: 0.28em; }
+    .footer-logo b { color: var(--accent); font-weight: 400; }
+
+    .hint {
+      font-size: clamp(9px, 1.4vmin, 12px);
+      color: var(--muted);
+      display: flex; align-items: center; gap: 8px;
+      margin-top: clamp(8px, 1.4vmin, 14px);
+      flex: 0 0 auto;
+    }
+    .hint .rule { width: 24px; height: 1px; background: linear-gradient(to right, rgba(201,169,97,0.7), transparent); }
+
+    /* Toast for share fallback */
+    .toast {
+      position: absolute;
+      left: 50%;
+      bottom: clamp(70px, 12vmin, 120px);
+      transform: translate(-50%, 12px);
+      background: rgba(15,15,19,0.96);
+      border: 1px solid rgba(201,169,97,0.4);
+      color: var(--text);
+      padding: 10px 18px;
+      border-radius: 999px;
+      font-size: clamp(10px, 1.5vmin, 13px);
+      letter-spacing: 0.04em;
+      opacity: 0;
+      pointer-events: none;
+      transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out);
+      z-index: 20;
+      box-shadow: 0 16px 40px rgba(0,0,0,0.6);
+    }
+    .toast.show { opacity: 1; transform: translate(-50%, 0); }
+
+    /* ============ CSS PATTERN SWATCHES ============ */
+    .pat { width: 100%; height: 100%; }
+
+    /* Traditional Damask */
+    .pat-damask {
+      background:
+        radial-gradient(circle at 50% 18%, rgba(201,169,97,0.9) 0 2px, transparent 2px 13px),
+        repeating-radial-gradient(circle at 50% 40%, rgba(201,169,97,0.55) 0 1px, transparent 1px 11px),
+        repeating-conic-gradient(from 0deg, #17141d 0 15deg, #241f2c 15deg 30deg);
+    }
+    .pat-damask::before, .pat-damask::after {
+      content: ""; position: absolute; border-radius: 50%;
+      border: 1.5px solid rgba(201,169,97,0.7);
+    }
+    .pat-damask { position: relative; }
+    .pat-damask::before { inset: 14% 24%; }
+    .pat-damask::after { inset: 30% 38%; border-color: rgba(245,242,234,0.6); box-shadow: 0 0 22px rgba(201,169,97,0.6); }
+
+    /* Modern Minimalist */
+    .pat-minimal {
+      background:
+        linear-gradient(135deg, #14141b, #0a0a0e);
+      background-image:
+        linear-gradient(to right, rgba(245,242,234,0.09) 1px, transparent 1px),
+        linear-gradient(to bottom, rgba(245,242,234,0.05) 1px, transparent 1px),
+        linear-gradient(135deg, rgba(245,242,234,0.06) 25%, transparent 25% 50%, rgba(245,242,234,0.06) 50% 75%, transparent 75%);
+      background-size: 26px 26px, 26px 26px, 52px 52px;
+    }
+    .pat-minimal { position: relative; }
+    .pat-minimal::before {
+      content: ""; position: absolute; inset: 22% 20%;
+      border: 1px solid rgba(245,242,234,0.35);
+      border-radius: 4px;
+    }
+
+    /* Bohemian Maximalist */
+    .pat-maximal {
+      background:
+        radial-gradient(circle at 22% 26%, #f6d9a8 0 6%, transparent 6% 16%, #f6d9a8 16% 22%, transparent 22%),
+        radial-gradient(circle at 74% 30%, #d98168 0 6%, transparent 6% 15%, #d98168 15% 21%, transparent 21%),
+        radial-gradient(circle at 40% 78%, #6fae90 0 6%, transparent 6% 16%, #6fae90 16% 22%, transparent 22%),
+        radial-gradient(circle at 82% 80%, #b58bc4 0 5%, transparent 5% 14%, #b58bc4 14% 20%, transparent 20%),
+        conic-gradient(from 45deg, #2a1120, #1d1020, #131322, #182329, #2a1120);
+      background-size: 74px 74px, 74px 74px, 74px 74px, 74px 74px, 100% 100%;
+    }
+
+    /* Art Deco Glam */
+    .pat-deco {
+      background: linear-gradient(135deg, #16131d, #08060c);
+    }
+    .pat-deco { position: relative; }
+    .pat-deco::before {
+      content: ""; position: absolute; inset: 0;
+      background:
+        repeating-linear-gradient(90deg, transparent 0 18px, rgba(201,169,97,0.16) 18px 19px),
+        repeating-conic-gradient(from 0deg at 50% 100%, rgba(201,169,97,0.5) 0 6deg, transparent 6deg 18deg);
+      -webkit-mask-image: radial-gradient(circle at 50% 100%, black 0 62%, transparent 62%);
+      mask-image: radial-gradient(circle at 50% 100%, black 0 62%, transparent 62%);
+    }
+    .pat-deco::after {
+      content: ""; position: absolute; left: 26%; right: 26%; bottom: 8%; height: 46%;
+      border: 2px solid rgba(201,169,97,0.85);
+      border-bottom: none;
+      border-radius: 50% 50% 0 0;
+    }
+  </style>
+</head>
+<body>
+  <div class="frame" id="frame">
+    <!-- Chrome -->
+    <div class="chrome">
+      <div class="brand-lockup">
+        <span class="brand-mark"></span>
+        <span class="brand-name"><b>Designer</b> Wallcoverings</span>
+      </div>
+      <div class="steps" id="steps" aria-hidden="true"></div>
+    </div>
+
+    <!-- Stage -->
+    <div class="stage" id="stage" aria-live="polite">
+
+      <!-- Intro -->
+      <section class="screen intro active" data-screen="intro">
+        <div class="eyebrow">The Style Quiz</div>
+        <h1 class="intro-title">What's Your<br /><span class="em">Wallcovering</span><br />Style?</h1>
+        <p class="intro-sub">Five quick taps to discover the pattern that feels like home. Answer instinctively — your walls will thank you.</p>
+        <div class="intro-swatches" aria-hidden="true">
+          <div class="chip"><div class="pat pat-damask"></div></div>
+          <div class="chip"><div class="pat pat-minimal"></div></div>
+          <div class="chip"><div class="pat pat-maximal"></div></div>
+          <div class="chip"><div class="pat pat-deco"></div></div>
+        </div>
+        <button class="btn btn-primary begin-btn" id="beginBtn">Begin the Quiz</button>
+      </section>
+
+      <!-- Questions render here -->
+      <div id="questions"></div>
+
+      <!-- Result -->
+      <section class="screen result" data-screen="result">
+        <div class="result-inner">
+          <div class="result-top">
+            <span>1080 × 1080 &nbsp;·&nbsp; Screenshot &amp; Share</span>
+            <span class="tag"><span class="dot"></span><span id="resShort">Your Wallcovering DNA</span></span>
+          </div>
+          <div class="result-body">
+            <div class="result-pattern">
+              <span class="p-tag">Pattern Match</span>
+              <div class="pat" id="resPattern"></div>
+            </div>
+            <div class="result-info">
+              <div class="result-cat" id="resCat">Modern Minimalist</div>
+              <h2 class="result-title" id="resTitle">Gallery-Quiet Walls</h2>
+              <div class="result-rule"></div>
+              <p class="result-desc" id="resDesc"></p>
+              <div class="result-tags" id="resTags"></div>
+            </div>
+          </div>
+          <div class="actions">
+            <a class="btn btn-primary" id="shopBtn" href="#" target="_blank" rel="noopener noreferrer">Shop this Style</a>
+            <button class="btn" id="shareBtn" type="button">Share</button>
+            <button class="btn btn-ghost" id="retakeBtn" type="button">Retake</button>
+          </div>
+        </div>
+      </section>
+    </div>
+
+    <!-- Footer -->
+    <div class="footer">
+      <div class="progress-rail"><div class="progress-bar" id="progressBar"></div></div>
+      <div class="footer-logo"><b>Designer</b> Wallcoverings</div>
+    </div>
+
+    <div class="toast" id="toast">Link copied — paste it anywhere.</div>
+  </div>
+
+  <script>
+  (function () {
+    "use strict";
+
+    // ---------- Data ----------
+    var QUESTIONS = [
+      {
+        kicker: "Q1 — Mood",
+        title: "How do you want your space to feel?",
+        options: [
+          { score: "damask",  pat: "pat-damask",  tag: "Opulent Calm",   label: "Timeless & grand",     meta: "Candlelit dinners, heirloom silver, soft strings." },
+          { score: "minimal", pat: "pat-minimal", tag: "Quiet Clarity",  label: "Clean & composed",     meta: "Sunlight, negative space, one perfect chair." },
+          { score: "maximal", pat: "pat-maximal", tag: "Eclectic Joy",   label: "Playful & collected",  meta: "Layered textiles, travel finds, a story everywhere." },
+          { score: "deco",    pat: "pat-deco",    tag: "Evening Glam",    label: "Dramatic & polished",  meta: "Velvet banquettes, champagne, city lights." }
+        ]
+      },
+      {
+        kicker: "Q2 — Architecture",
+        title: "Which backdrop feels most like “home”?",
+        options: [
+          { score: "minimal", pat: "pat-minimal", tag: "Gallery Loft",   label: "Airy loft",            meta: "Crisp lines, pale oak, soft architectural light." },
+          { score: "damask",  pat: "pat-damask",  tag: "Townhouse",      label: "Historic brownstone",  meta: "Crown mouldings, marble mantels, library greens." },
+          { score: "deco",    pat: "pat-deco",    tag: "Skyline Suite",  label: "City penthouse",       meta: "Metallic accents, skyline views, a bar cart." },
+          { score: "maximal", pat: "pat-maximal", tag: "Artist Studio",  label: "Sun-drenched studio",  meta: "Plants, vintage rugs, a curated chaos." }
+        ]
+      },
+      {
+        kicker: "Q3 — Pattern",
+        title: "Choose the pattern energy that draws you in.",
+        options: [
+          { score: "damask",  pat: "pat-damask",  tag: "Heritage",      label: "Ornate motifs",        meta: "Scrolling florals, medallions, old-world romance." },
+          { score: "minimal", pat: "pat-minimal", tag: "Precision",     label: "Linear & graphic",     meta: "Architectural stripes, grids, tonal shifts." },
+          { score: "maximal", pat: "pat-maximal", tag: "Botanical",     label: "Botanical & wild",     meta: "Overscale florals, palms, a lush jungle vibe." },
+          { score: "deco",    pat: "pat-deco",    tag: "Geometry",      label: "Geometric glamour",    meta: "Fans, arches, sharp metallic repeats." }
+        ]
+      },
+      {
+        kicker: "Q4 — Palette",
+        title: "Which palette would you wake up to?",
+        options: [
+          { score: "minimal", pat: "pat-minimal", tag: "Bone & Ink",    label: "Soft neutrals",        meta: "Ivories, warm greys, a hint of charcoal." },
+          { score: "deco",    pat: "pat-deco",    tag: "Champagne",     label: "Noir & metallic",      meta: "Inky blacks, molten metals, candlelit warmth." },
+          { score: "damask",  pat: "pat-damask",  tag: "Antique Gold",  label: "Rich jewel tones",     meta: "Sapphire, garnet, deep velvety neutrals." },
+          { score: "maximal", pat: "pat-maximal", tag: "Sunset",       label: "Sun-soaked brights",   meta: "Terracotta, olive, ochre, saturated color." }
+        ]
+      },
+      {
+        kicker: "Q5 — Lifestyle",
+        title: "Your Friday night at home looks like…",
+        options: [
+          { score: "damask",  pat: "pat-damask",  tag: "Salon",        label: "Slow dinner party",    meta: "Linen tablecloths, candles, an endless playlist." },
+          { score: "minimal", pat: "pat-minimal", tag: "Reset",        label: "Solo reset",           meta: "Fresh sheets, a face mask, a plumped pillow." },
+          { score: "maximal", pat: "pat-maximal", tag: "Gather",       label: "Friends & laughter",   meta: "Board games, bold drinks, shuffle on." },
+          { score: "deco",    pat: "pat-deco",    tag: "After Dark",   label: "Cocktail hour",        meta: "Shaken not stirred, a late-night movie." }
+        ]
+      }
+    ];
+
+    var RESULTS = {
+      damask: {
+        cat: "Traditional Damask", title: "Gilded Heritage Walls", pat: "pat-damask", short: "Old World, New Mood",
+        desc: "You gravitate toward rooms with history and a hint of ceremony. Ornate damask motifs, antique-gold inks, and tactile embossing turn your walls into a modern-day manor — romantic, refined, and endlessly photogenic.",
+        tags: ["Chandelier-ready", "Silk-inspired sheen", "Heirloom details"],
+        shop: "https://designerwallcoverings.com/search?q=damask"
+      },
+      minimal: {
+        cat: "Modern Minimalist", title: "Gallery-Quiet Walls", pat: "pat-minimal", short: "Quiet Luxury",
+        desc: "You breathe easiest in spaces that feel edited and intentional. Understated patterning, tonal shifts, and architectural lines create a soft backdrop that makes everything else in the room shine.",
+        tags: ["Soft contrast", "Architectural lines", "Museum-grade calm"],
+        shop: "https://designerwallcoverings.com/search?q=grasscloth"
+      },
+      maximal: {
+        cat: "Bohemian Maximalist", title: "Collected Story Walls", pat: "pat-maximal", short: "More Is More",
+        desc: "You curate spaces like you collect memories — boldly, joyfully, and without apology. Lush botanicals, layered prints, and rich, sun-warmed color turn every wall into a passport stamp.",
+        tags: ["Pattern-on-pattern", "Lush botanicals", "Global eclectic"],
+        shop: "https://designerwallcoverings.com/search?q=floral"
+      },
+      deco: {
+        cat: "Art Deco Glam", title: "Midnight Deco Walls", pat: "pat-deco", short: "Iconic Glamour",
+        desc: "You live for a little drama. Fan motifs, sharp geometrics, and metallic inks that catch the light just so. Your walls feel like the lobby of a grand hotel — always ready for the next cocktail hour.",
+        tags: ["Metallic accents", "Geometric glamour", "After-dark glow"],
+        shop: "https://designerwallcoverings.com/search?q=art+deco"
+      }
+    };
+
+    var TOTAL = QUESTIONS.length;
+
+    // ---------- State ----------
+    var scores = { damask: 0, minimal: 0, maximal: 0, deco: 0 };
+    var firstPick = null;   // tie-breaker: honor the very first answer
+    var answered = 0;
+
+    // ---------- Elements ----------
+    var stage = document.getElementById("stage");
+    var questionsHost = document.getElementById("questions");
+    var stepsHost = document.getElementById("steps");
+    var progressBar = document.getElementById("progressBar");
+    var toast = document.getElementById("toast");
+
+    // Build step dots
+    for (var s = 0; s < TOTAL; s++) {
+      var d = document.createElement("div");
+      d.className = "steps-dot";
+      stepsHost.appendChild(d);
+    }
+    var stepDots = Array.prototype.slice.call(stepsHost.children);
+
+    // ---------- Build question screens ----------
+    QUESTIONS.forEach(function (q, qi) {
+      var sec = document.createElement("section");
+      sec.className = "screen";
+      sec.setAttribute("data-screen", "q" + qi);
+
+      var head = document.createElement("div");
+      head.className = "q-head";
+      head.innerHTML = escapeText(q.kicker) + '<span class="rule"></span>';
+      sec.appendChild(head);
+
+      var title = document.createElement("h2");
+      title.className = "q-title";
+      title.textContent = q.title;
+      sec.appendChild(title);
+
+      var grid = document.createElement("div");
+      grid.className = "answers";
+
+      q.options.forEach(function (opt) {
+        var btn = document.createElement("button");
+        btn.className = "answer";
+        btn.type = "button";
+        btn.setAttribute("data-score", opt.score);
+        btn.innerHTML =
+          '<div class="swatch"><div class="pat ' + opt.pat + '"></div>' +
+          '<span class="swatch-tag">' + escapeText(opt.tag) + '</span></div>' +
+          '<div class="a-label">' + escapeText(opt.label) + '</div>' +
+          '<div class="a-meta">' + escapeText(opt.meta) + '</div>';
+        btn.addEventListener("click", function () { onAnswer(opt.score, qi); });
+        grid.appendChild(btn);
+      });
+
+      sec.appendChild(grid);
+
+      var hint = document.createElement("div");
+      hint.className = "hint";
+      hint.innerHTML = '<span class="rule"></span><span>' +
+        (qi === TOTAL - 1 ? "Last one — tap to reveal your style" : "Tap a tile to continue") +
+        '</span>';
+      sec.appendChild(hint);
+
+      questionsHost.appendChild(sec);
+    });
+
+    // Cache screens after building
+    var screens = {};
+    Array.prototype.slice.call(stage.querySelectorAll(".screen")).forEach(function (el) {
+      screens[el.getAttribute("data-screen")] = el;
+    });
+
+    // ---------- Flow ----------
+    function showScreen(id) {
+      Object.keys(screens).forEach(function (k) { screens[k].classList.remove("active"); });
+      if (screens[id]) screens[id].classList.add("active");
+    }
+
+    function updateProgress(count) {
+      var ratio = count / TOTAL;
+      progressBar.style.transform = "scaleX(" + ratio + ")";
+      stepDots.forEach(function (dot, i) {
+        if (i < count) dot.classList.add("on"); else dot.classList.remove("on");
+      });
+    }
+
+    function onAnswer(score, qIndex) {
+      if (scores[score] != null) scores[score] += 1;
+      if (firstPick === null) firstPick = score;
+      answered = qIndex + 1;
+      updateProgress(answered);
+
+      if (qIndex < TOTAL - 1) {
+        showScreen("q" + (qIndex + 1));
+      } else {
+        renderResult();
+        showScreen("result");
+      }
+    }
+
+    function computeResult() {
+      var best = null, bestVal = -1;
+      // Iterate in a stable order; tie-break to firstPick, else keep earliest max.
+      ["damask", "minimal", "maximal", "deco"].forEach(function (k) {
+        if (scores[k] > bestVal) { bestVal = scores[k]; best = k; }
+      });
+      // If the first pick is tied for the top, honor it (feels more personal).
+      if (firstPick && scores[firstPick] === bestVal) best = firstPick;
+      return best || "minimal";
+    }
+
+    var currentShop = "#";
+
+    function renderResult() {
+      var key = computeResult();
+      var r = RESULTS[key];
+
+      document.getElementById("resPattern").className = "pat " + r.pat;
+      document.getElementById("resCat").textContent = r.cat;
+      document.getElementById("resTitle").textContent = r.title;
+      document.getElementById("resDesc").textContent = r.desc;
+      document.getElementById("resShort").textContent = r.short;
+
+      var tagsHost = document.getElementById("resTags");
+      tagsHost.innerHTML = "";
+      r.tags.forEach(function (t) {
+        var span = document.createElement("span");
+        span.className = "t";
+        span.textContent = t;
+        tagsHost.appendChild(span);
+      });
+
+      var shopBtn = document.getElementById("shopBtn");
+      shopBtn.setAttribute("href", r.shop);
+      currentShop = r.shop;
+
+      // Reflect result in the URL hash so a shared link re-opens the same result.
+      try { history.replaceState(null, "", "#result-" + key); } catch (e) {}
+      window.__result = { key: key, r: r };
+    }
+
+    // ---------- Share ----------
+    function showToast(msg) {
+      toast.textContent = msg;
+      toast.classList.add("show");
+      setTimeout(function () { toast.classList.remove("show"); }, 2200);
+    }
+
+    document.getElementById("shareBtn").addEventListener("click", function () {
+      var res = window.__result;
+      var cat = res ? res.r.cat : "Wallcovering Style";
+      var shareText = "My wallcovering style is " + cat + " — what's yours?";
+      var shareUrl = location.href;
+
+      if (navigator.share) {
+        navigator.share({ title: "What's Your Wallcovering Style?", text: shareText, url: shareUrl })
+          .catch(function () { /* user cancelled — no-op */ });
+      } else if (navigator.clipboard && navigator.clipboard.writeText) {
+        navigator.clipboard.writeText(shareText + " " + shareUrl)
+          .then(function () { showToast("Copied — paste it anywhere."); })
+          .catch(function () { showToast("Screenshot this card to share."); });
+      } else {
+        showToast("Screenshot this card to share — it's sized for the feed.");
+      }
+    });
+
+    // ---------- Restart ----------
+    document.getElementById("retakeBtn").addEventListener("click", resetQuiz);
+
+    function resetQuiz() {
+      scores = { damask: 0, minimal: 0, maximal: 0, deco: 0 };
+      firstPick = null;
+      answered = 0;
+      updateProgress(0);
+      try { history.replaceState(null, "", location.pathname + location.search); } catch (e) {}
+      showScreen("intro");
+    }
+
+    // ---------- Begin ----------
+    document.getElementById("beginBtn").addEventListener("click", function () {
+      showScreen("q0");
+    });
+
+    // ---------- Utils ----------
+    function escapeText(str) {
+      return String(str).replace(/[&<>"']/g, function (c) {
+        return { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c];
+      });
+    }
+
+    // ---------- Deep link: open straight to a result if hash present ----------
+    (function initFromHash() {
+      var m = /^#result-(damask|minimal|maximal|deco)$/.exec(location.hash || "");
+      if (m) {
+        // Seed a minimal score so computeResult returns this key, then show it.
+        scores[m[1]] = 1;
+        firstPick = m[1];
+        updateProgress(TOTAL);
+        renderResult();
+        showScreen("result");
+      }
+    })();
+
+    updateProgress(0);
+  })();
+  </script>
+</body>
+</html>

(oldest)  ·  back to Dw Style Quiz  ·  Fix result screen bleeding onto intro (gate clipReveal anima d1aaa32 →