← back to Model Arena
data/artifacts/193230252710/gpt.html
1138 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Designer Wallcoverings – Mood Board Generator</title>
<style>
:root {
/* Design tokens */
--bg: #0d0d0f;
--surface: #17171c;
--surface-soft: #141419;
--text: #f5f2ea;
--muted: #8a8578;
--accent: #c9a961; /* metallic gold */
--accent-soft: #7d6a45;
--line: rgba(201,169,97,0.35);
--line-soft: rgba(245,242,234,0.06);
--shadow-soft: 0 18px 45px rgba(0,0,0,0.66);
--shadow-subtle: 0 8px 20px rgba(0,0,0,0.55);
--radius-card: 18px;
--radius-chip: 999px;
--radius-tile: 16px;
--ease-hero: cubic-bezier(.22,1,.36,1);
--ease-ui: cubic-bezier(.22,.9,.24,1);
--canvas-width: 1080px;
--canvas-height: 1350px;
--font-display: "Playfair Display", "Didot", "Bodoni MT", Georgia, "Times New Roman", serif;
--font-sans: "Avenir Next", "Century Gothic", -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
--fs-display: 67px;
--fs-h1: 50px;
--fs-h2: 38px;
--fs-h3: 28px;
--fs-body: 16px;
--fs-label: 12px;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
background: radial-gradient(circle at top, #191922 0, #050509 60%);
color: var(--text);
font-family: var(--font-sans);
-webkit-font-smoothing: antialiased;
}
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Header / wordmark */
.app-shell {
max-width: 1280px;
margin: 0 auto;
padding: 24px 24px 40px;
}
header.app-header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 20;
backdrop-filter: blur(20px);
background: linear-gradient(to bottom, rgba(5,5,9,0.9), rgba(5,5,9,0.7), rgba(5,5,9,0));
border-bottom: 1px solid var(--line-soft);
}
.header-inner {
max-width: 1280px;
margin: 0 auto;
padding: 18px 24px 14px;
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 24px;
}
.brand-lockup {
display: inline-flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
}
.brand-wordmark {
font-family: var(--font-display);
font-size: 44px;
line-height: 1.05;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--text);
white-space: normal;
max-width: 280px;
}
.brand-subtitle {
margin-top: 6px;
font-size: 12px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
}
.header-controls {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 8px;
}
.theme-label {
font-size: var(--fs-label);
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
}
.theme-pill {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
border-radius: 999px;
border: 1px solid var(--line-soft);
background: radial-gradient(circle at top left, rgba(201,169,97,0.24), rgba(15,15,19,0.95));
box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
}
.theme-chip {
width: 10px;
height: 10px;
border-radius: 999px;
background: var(--accent);
box-shadow: 0 0 0 1px rgba(0,0,0,0.9);
}
.theme-name {
font-size: 11px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--text);
}
/* Main layout */
.main {
padding-top: 96px;
}
.board-shell {
display: flex;
justify-content: center;
padding: 24px;
}
.board-frame {
width: min(100%, var(--canvas-width));
aspect-ratio: 1080 / 1350;
border-radius: 28px;
border: 1px solid var(--line-soft);
background: radial-gradient(circle at top, #1c1c24 0, #101016 42%, #050509 100%);
box-shadow: var(--shadow-soft);
padding: 32px 32px 28px;
position: relative;
overflow: hidden;
}
/* Board header row */
.board-top-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24px;
}
.board-meta {
display: flex;
flex-direction: column;
gap: 8px;
}
.board-title {
font-family: var(--font-display);
font-size: 28px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--text);
}
.board-subtitle {
font-size: 13px;
color: var(--muted);
max-width: 320px;
}
.board-meta-row {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
.meta-pill {
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
padding: 4px 10px;
border-radius: 999px;
border: 1px solid var(--line-soft);
background: linear-gradient(to bottom right, rgba(241,234,215,0.02), rgba(0,0,0,0.65));
}
/* Regenerate button */
button {
font-family: var(--font-sans);
}
.regen-button {
position: relative;
padding: 10px 20px;
border-radius: 999px;
border: 1px solid rgba(201,169,97,0.7);
background: radial-gradient(circle at top left, rgba(201,169,97,0.35), rgba(5,5,9,0.9));
color: var(--text);
font-size: 11px;
letter-spacing: 0.22em;
text-transform: uppercase;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 8px;
overflow: hidden;
box-shadow: 0 10px 25px rgba(0,0,0,0.7);
transition:
transform 220ms var(--ease-ui),
box-shadow 220ms var(--ease-ui),
background 260ms var(--ease-ui),
border-color 260ms var(--ease-ui);
}
.regen-button::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(120deg,
rgba(255,255,255,0) 0%,
rgba(255,255,255,0.35) 40%,
rgba(255,255,255,0) 70%);
transform: translateX(-120%);
transition: transform 500ms var(--ease-hero);
pointer-events: none;
}
.regen-button:hover::before {
transform: translateX(0%);
}
.regen-button:hover {
transform: translateY(-1px);
box-shadow: 0 12px 30px rgba(0,0,0,0.82);
border-color: rgba(201,169,97,0.95);
}
.regen-button:active {
transform: translateY(1px) scale(0.99);
box-shadow: 0 6px 16px rgba(0,0,0,0.7);
}
.regen-icon {
width: 10px;
height: 10px;
border-radius: 999px;
border: 1px solid rgba(201,169,97,0.65);
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
}
.regen-icon::after {
content: "";
width: 6px;
height: 6px;
border-radius: 999px;
background: var(--accent);
box-shadow: 0 0 12px rgba(201,169,97,0.9);
}
/* Canvas grid */
.board-canvas {
position: relative;
width: 100%;
height: calc(100% - 72px);
border-radius: 20px;
padding: 18px 18px 20px;
background:
linear-gradient(to bottom right, rgba(255,255,255,0.02), rgba(0,0,0,0.8)),
radial-gradient(circle at top left, rgba(201,169,97,0.12), transparent 55%);
border: 1px solid var(--line-soft);
overflow: hidden;
}
/* Layout slots */
.canvas-grid {
position: relative;
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 1.2fr 0.9fr;
grid-template-rows: 1.1fr 0.9fr 0.9fr;
gap: 16px;
}
/* Cards */
.card {
position: relative;
border-radius: var(--radius-card);
background: var(--surface);
border: 1px solid var(--line-soft);
box-shadow: var(--shadow-subtle);
overflow: hidden;
display: flex;
flex-direction: column;
}
.card-header {
padding: 12px 14px 4px;
display: flex;
justify-content: space-between;
align-items: baseline;
}
.card-label {
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
}
.card-tag {
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
border-radius: 999px;
border: 1px solid var(--line-soft);
padding: 2px 9px;
}
.card-body {
flex: 1;
padding: 10px 14px 14px;
display: flex;
}
/* Hero pattern card */
.hero-card {
grid-column: 1 / 2;
grid-row: 1 / 3;
}
.hero-pattern-frame {
position: relative;
width: 100%;
height: 100%;
border-radius: 16px;
overflow: hidden;
border: 1px solid rgba(245,242,234,0.06);
background: radial-gradient(circle at top, #f7f2e5 0, #d2c7ae 35%, #7d6a45 100%);
}
.hero-overlay {
position: absolute;
inset: 0;
mix-blend-mode: multiply;
opacity: 0.75;
}
/* Pattern variants */
.pattern-classic {
background:
radial-gradient(circle at 0 0, rgba(0,0,0,0.16) 0 18%, transparent 19% 100%),
repeating-linear-gradient(45deg, rgba(201,169,97,0.8) 0 2px, rgba(201,169,97,0.25) 3px 4px, rgba(255,255,255,0) 5px 16px);
}
.pattern-coastal {
background:
radial-gradient(circle at 20% 0, rgba(255,255,255,0.5) 0 22%, transparent 23% 100%),
repeating-radial-gradient(circle at 0 120%, rgba(201,169,97,0.25) 0 6px, rgba(3,34,49,0.9) 7px 18px),
linear-gradient(180deg, #f7f2ea 0, #e3ddd0 30%, #143146 100%);
}
.pattern-moody {
background:
radial-gradient(circle at 0 0, rgba(255,255,255,0.3) 0 14%, transparent 15% 100%),
radial-gradient(circle at 100% 100%, rgba(0,0,0,0.75) 0 45%, transparent 46% 100%),
repeating-linear-gradient(135deg, rgba(0,0,0,0.9) 0 3px, rgba(0,0,0,0.3) 4px 7px, rgba(201,169,97,0.3) 8px 10px);
}
.pattern-botanical {
background:
radial-gradient(circle at 10% 0, rgba(255,255,255,0.7) 0 16%, transparent 17% 100%),
radial-gradient(circle at 80% 120%, rgba(74,96,58,0.75) 0 40%, transparent 41% 100%),
repeating-radial-gradient(circle at 20% 80%, rgba(25,46,32,0.7) 0 5px, rgba(25,46,32,0.15) 6px 12px),
linear-gradient(145deg, #f4efe2 0, #d9d0b6 28%, #2c3d2b 80%);
}
.hero-gild-lines {
position: absolute;
inset: 0;
background-image:
repeating-linear-gradient(90deg,
rgba(255,255,255,0.2) 0 1px,
rgba(201,169,97,0.7) 2px 2px,
transparent 3px 24px);
mix-blend-mode: soft-light;
opacity: 0.8;
}
.hero-caption {
position: absolute;
left: 18px;
bottom: 16px;
right: 18px;
display: flex;
justify-content: space-between;
align-items: baseline;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.16em;
color: #2f2715;
}
.hero-caption span.pattern-name {
font-family: var(--font-display);
letter-spacing: 0.14em;
}
/* Color chips card */
.chips-card {
grid-column: 2 / 3;
grid-row: 1 / 2;
}
.chips-row {
display: flex;
gap: 12px;
width: 100%;
}
.color-chip {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
}
.chip-swatch {
width: 100%;
border-radius: var(--radius-chip);
height: 46px;
border: 1px solid rgba(255,255,255,0.14);
box-shadow: 0 4px 12px rgba(0,0,0,0.7);
}
.chip-meta {
display: flex;
flex-direction: column;
gap: 2px;
}
.chip-name {
font-size: 12px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text);
}
.chip-code {
font-size: 11px;
color: var(--muted);
}
/* Type pairing card */
.type-card {
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.type-sample {
width: 100%;
border-radius: 14px;
padding: 14px 14px 12px;
background: radial-gradient(circle at top, rgba(245,242,234,0.12), rgba(5,5,9,0.9));
border: 1px solid var(--line-soft);
}
.type-heading {
font-family: var(--font-display);
font-size: 24px;
letter-spacing: 0.04em;
text-transform: uppercase;
margin-bottom: 4px;
}
.type-sub {
font-size: 12px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 10px;
}
.type-body {
font-size: 13px;
line-height: 1.6;
max-width: 100%;
}
/* Texture tile card */
.texture-card {
grid-column: 1 / 2;
grid-row: 3 / 4;
}
.texture-body {
flex: 1;
display: flex;
gap: 16px;
}
.texture-tile {
flex: 0 0 52%;
border-radius: var(--radius-tile);
border: 1px solid rgba(245,242,234,0.08);
overflow: hidden;
position: relative;
background: #222326;
box-shadow: 0 8px 18px rgba(0,0,0,0.7);
}
.texture-layer {
position: absolute;
inset: 0;
mix-blend-mode: soft-light;
}
/* Texture variants */
.texture-weave {
background-image:
linear-gradient(90deg, rgba(255,255,255,0.06) 1px, transparent 1px),
linear-gradient(180deg, rgba(255,255,255,0.06) 1px, transparent 1px);
background-size: 6px 6px, 6px 6px;
}
.texture-linen {
background-image:
linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px),
linear-gradient(180deg, rgba(255,255,255,0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(0,0,0,0.45) 50%, transparent 51%);
background-size: 3px 1px, 1px 3px, 8px 100%;
opacity: 0.75;
}
.texture-velvet {
background-image:
linear-gradient(180deg, rgba(255,255,255,0.16), rgba(0,0,0,0.95)),
radial-gradient(circle at 0 0, rgba(255,255,255,0.2) 0 18%, transparent 20% 100%);
opacity: 0.9;
}
.texture-grasscloth {
background-image:
linear-gradient(180deg, rgba(255,255,255,0.08) 1px, transparent 1px),
linear-gradient(180deg, rgba(0,0,0,0.7), rgba(0,0,0,0.95));
background-size: 4px 12px, 100% 100%;
opacity: 0.85;
}
.texture-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.texture-name {
font-size: 13px;
letter-spacing: 0.12em;
text-transform: uppercase;
margin-bottom: 6px;
}
.texture-notes {
font-size: 12px;
line-height: 1.6;
color: var(--muted);
}
/* Small meta list */
.meta-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 6px;
}
.meta-item {
font-size: 10px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
}
/* Ambient animation hook */
.board-canvas.animating .hero-pattern-frame,
.board-canvas.animating .chips-row,
.board-canvas.animating .type-sample,
.board-canvas.animating .texture-tile,
.board-canvas.animating .texture-info {
animation-duration: 520ms;
animation-timing-function: var(--ease-hero);
animation-fill-mode: both;
}
.board-canvas.animating .hero-pattern-frame {
animation-name: slideUpSoft;
}
.board-canvas.animating .chips-row {
animation-name: slideRightSoft;
}
.board-canvas.animating .type-sample {
animation-name: slideLeftSoft;
}
.board-canvas.animating .texture-tile {
animation-name: popInSoft;
}
.board-canvas.animating .texture-info {
animation-name: fadeRiseSoft;
}
/* Keyframes */
@keyframes slideUpSoft {
from { transform: translateY(14px) scale(0.98); opacity: 0; }
to { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes slideRightSoft {
from { transform: translateX(-16px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideLeftSoft {
from { transform: translateX(16px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes popInSoft {
from { transform: translateY(10px) scale(0.96); opacity: 0; }
to { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes fadeRiseSoft {
from { transform: translateY(10px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
/* Responsive tweaks */
@media (max-width: 900px) {
.header-inner {
align-items: flex-start;
}
.brand-wordmark {
font-size: 40px;
max-width: 240px;
}
.board-frame {
padding: 24px 20px 20px;
}
.board-top-row {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
}
@media (max-width: 720px) {
.board-frame {
border-radius: 22px;
}
.board-canvas {
padding: 14px;
}
.canvas-grid {
grid-template-columns: 1fr;
grid-template-rows: 1.1fr 0.7fr 0.7fr 0.7fr;
}
.hero-card {
grid-column: 1 / 2;
grid-row: 1 / 2;
}
.chips-card {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.type-card {
grid-row: 3 / 4;
}
.texture-card {
grid-row: 4 / 5;
}
}
</style>
</head>
<body>
<header class="app-header">
<div class="header-inner">
<div class="brand-lockup">
<div class="brand-wordmark">DESIGNER<br>WALLCOVERINGS</div>
<div class="brand-subtitle">Luxury wallcovering mood-board generator</div>
</div>
<div class="header-controls">
<div class="theme-label">Current style</div>
<div class="theme-pill">
<div class="theme-chip" id="themeChip"></div>
<div class="theme-name" id="themeName">Classic Salon</div>
</div>
</div>
</div>
</header>
<main class="main">
<div class="app-shell">
<section class="board-shell">
<div class="board-frame">
<div class="board-top-row">
<div class="board-meta">
<div class="board-title" id="boardTitle">Classic Salon Mood Board</div>
<div class="board-subtitle">
A shareable 1080×1350 canvas capturing palette, pattern, and texture for the next signature wall.
</div>
<div class="board-meta-row">
<div class="meta-pill" id="metaPalette">Palette · Gilded Noir</div>
<div class="meta-pill" id="metaFinish">Finish · Textured Silk</div>
</div>
</div>
<button class="regen-button" id="regenButton" type="button">
<span class="regen-icon" aria-hidden="true"></span>
<span>Regenerate</span>
</button>
</div>
<div class="board-canvas" id="boardCanvas">
<div class="canvas-grid">
<!-- Hero pattern -->
<article class="card hero-card">
<div class="card-header">
<div class="card-label">Hero wall pattern</div>
<div class="card-tag" id="heroTag">Classic · Panelled</div>
</div>
<div class="card-body">
<div class="hero-pattern-frame" id="heroPattern">
<div class="hero-overlay" id="heroOverlay"></div>
<div class="hero-gild-lines"></div>
<div class="hero-caption">
<span class="pattern-name" id="patternName">Salon Filigree</span>
<span id="patternCode">Edition No. 04 · DW Studio</span>
</div>
</div>
</div>
</article>
<!-- Color chips -->
<article class="card chips-card">
<div class="card-header">
<div class="card-label">Color study</div>
<div class="card-tag" id="chipTag">Trim · Brass</div>
</div>
<div class="card-body">
<div class="chips-row" id="chipsRow">
<div class="color-chip">
<div class="chip-swatch" id="chip1"></div>
<div class="chip-meta">
<div class="chip-name" id="chip1Name">Gallery Ivory</div>
<div class="chip-code" id="chip1Code">DW 01-11</div>
</div>
</div>
<div class="color-chip">
<div class="chip-swatch" id="chip2"></div>
<div class="chip-meta">
<div class="chip-name" id="chip2Name">Molten Brass</div>
<div class="chip-code" id="chip2Code">DW 27-24</div>
</div>
</div>
<div class="color-chip">
<div class="chip-swatch" id="chip3"></div>
<div class="chip-meta">
<div class="chip-name" id="chip3Name">Midnight Lacquer</div>
<div class="chip-code" id="chip3Code">DW 90-02</div>
</div>
</div>
</div>
</div>
</article>
<!-- Type pairing -->
<article class="card type-card">
<div class="card-header">
<div class="card-label">Type pairing</div>
<div class="card-tag" id="typeTag">Playfair & Avenir</div>
</div>
<div class="card-body">
<div class="type-sample" id="typeSample">
<div class="type-heading" id="typeHeading">Salon • Evening</div>
<div class="type-sub" id="typeSub">Luxury wallcovering headline</div>
<div class="type-body" id="typeBody">
Delicate serif letterforms float over a calm sans body, echoing panel mouldings against a shadowed wall.
Use for feature introductions, collection titles, and invitation motifs.
</div>
</div>
</div>
</article>
<!-- Texture tile -->
<article class="card texture-card">
<div class="card-header">
<div class="card-label">Surface texture</div>
<div class="card-tag" id="textureTag">Vertical Weave</div>
</div>
<div class="card-body texture-body">
<div class="texture-tile" id="textureTile">
<div class="texture-layer texture-weave"></div>
<div class="texture-layer texture-linen"></div>
</div>
<div class="texture-info">
<div>
<div class="texture-name" id="textureName">Hand-Loomed Silk Weave</div>
<div class="texture-notes" id="textureNotes">
Soft sheen catches side light, with a subtle horizontal slub. Works beautifully on long corridor walls
and inset panels where movement is desired without visual noise.
</div>
</div>
<div class="meta-list">
<div class="meta-item" id="textureMeta1">Install · Wrap corners</div>
<div class="meta-item" id="textureMeta2">Sheen · Pearl</div>
</div>
</div>
</div>
</article>
</div>
</div>
</div>
</section>
</div>
</main>
<script>
(function() {
const styles = [
{
id: 'classic',
label: 'Classic',
themeName: 'Classic Salon',
boardTitle: 'Classic Salon Mood Board',
metaPalette: 'Palette · Gilded Noir',
metaFinish: 'Finish · Panelled Silk',
accentColor: '#c9a961',
heroPatternClass: 'pattern-classic',
heroTag: 'Classic · Panelled',
patternName: 'Salon Filigree',
patternCode: 'Edition No. 04 · DW Studio',
heroOverlay:
'linear-gradient(135deg, rgba(12,10,8,0.65), rgba(0,0,0,0.75))',
chips: [
{ color: '#f5f0e2', name: 'Gallery Ivory', code: 'DW 01-11' },
{ color: '#c9a961', name: 'Molten Brass', code: 'DW 27-24' },
{ color: '#151419', name: 'Midnight Lacquer', code: 'DW 90-02' }
],
chipTag: 'Trim · Brass',
typeTag: 'Playfair & Avenir',
typeHeading: 'Salon • Evening',
typeSub: 'Luxury wallcovering headline',
typeBody:
'A poised serif headline over a quiet geometric sans sets a gallery-like rhythm. Ideal for invitation suites and collection covers.',
textureClassCombo: ['texture-weave', 'texture-linen'],
textureTag: 'Hand-Woven',
textureName: 'Hand-Loomed Silk Weave',
textureNotes:
'Soft sheen catches side light, with a subtle horizontal slub. Best on tall walls where the texture can breathe.',
textureMeta1: 'Install · Full height',
textureMeta2: 'Sheen · Pearl'
},
{
id: 'coastal',
label: 'Coastal',
themeName: 'Coastal Atelier',
boardTitle: 'Coastal Atelier Mood Board',
metaPalette: 'Palette · Salt & Brass',
metaFinish: 'Finish · Sun-Washed Grasscloth',
accentColor: '#c9a961',
heroPatternClass: 'pattern-coastal',
heroTag: 'Coastal · Ripple',
patternName: 'Tideline Panel',
patternCode: 'Edition No. 07 · DW Studio',
heroOverlay:
'linear-gradient(160deg, rgba(3,26,39,0.8), rgba(0,0,0,0.7))',
chips: [
{ color: '#f7f2ea', name: 'Sea Salt Wash', code: 'DW 10-03' },
{ color: '#18384f', name: 'Deep Atlantic', code: 'DW 65-18' },
{ color: '#c9a961', name: 'Sunlit Brass', code: 'DW 27-19' }
],
chipTag: 'Detail · Antique brass',
typeTag: 'Playfair & Avenir',
typeHeading: 'Tide • Horizon',
typeSub: 'Relaxed shoreline heading',
typeBody:
'Open letterspacing and generous line-height echo the breath between waves. Use for breezy, light-filled spaces and veranda walls.',
textureClassCombo: ['texture-grasscloth', 'texture-linen'],
textureTag: 'Fine Grasscloth',
textureName: 'Salt-Brushed Grasscloth',
textureNotes:
'Tight vertical fibres catch highlights like dune grasses in low light. Perfect behind woven seating and light oak joinery.',
textureMeta1: 'Install · Wrapped panels',
textureMeta2: 'Sheen · Matte'
},
{
id: 'moody',
label: 'Moody',
themeName: 'Moody Atelier',
boardTitle: 'Moody Atelier Mood Board',
metaPalette: 'Palette · Obsidian Gold',
metaFinish: 'Finish · Velvet Flock',
accentColor: '#c9a961',
heroPatternClass: 'pattern-moody',
heroTag: 'Moody · Deco',
patternName: 'Nocturne Panel',
patternCode: 'Edition No. 12 · DW Studio',
heroOverlay:
'linear-gradient(145deg, rgba(0,0,0,0.9), rgba(0,0,0,0.4))',
chips: [
{ color: '#111015', name: 'Obsidian Ink', code: 'DW 98-01' },
{ color: '#c9a961', name: 'Deco Gold', code: 'DW 31-09' },
{ color: '#4b4140', name: 'Smoked Umber', code: 'DW 55-22' }
],
chipTag: 'Metal · Smoked brass',
typeTag: 'Playfair & Avenir',
typeHeading: 'Nocturne • Suite',
typeSub: 'After-dark statement header',
typeBody:
'Condensed caps and rich tracking feel like a monogram on lacquer. Reserve for hero copy where drama is desired.',
textureClassCombo: ['texture-velvet', 'texture-weave'],
textureTag: 'Cut Velvet',
textureName: 'Shadowed Velvet Flock',
textureNotes:
'High-contrast pile catches the light with theatre-curtain depth. Use on feature walls behind sculptural lighting.',
textureMeta1: 'Install · Feature wall',
textureMeta2: 'Sheen · Low gloss'
},
{
id: 'botanical',
label: 'Botanical',
themeName: 'Botanical Conservatory',
boardTitle: 'Botanical Conservatory Mood Board',
metaPalette: 'Palette · Verdant Brass',
metaFinish: 'Finish · Layered Linen',
accentColor: '#c9a961',
heroPatternClass: 'pattern-botanical',
heroTag: 'Botanical · Canopy',
patternName: 'Conservatory Canopy',
patternCode: 'Edition No. 19 · DW Studio',
heroOverlay:
'linear-gradient(135deg, rgba(20,42,30,0.9), rgba(0,0,0,0.5))',
chips: [
{ color: '#e8e1cf', name: 'Greenhouse Light', code: 'DW 06-08' },
{ color: '#314733', name: 'Canopy Green', code: 'DW 48-32' },
{ color: '#c9a961', name: 'Bronzed Stem', code: 'DW 29-18' }
],
chipTag: 'Hardware · Brushed brass',
typeTag: 'Playfair & Avenir',
typeHeading: 'Conservatory • Wall',
typeSub: 'Leafy collection header',
typeBody:
'Rounded capitals with subtle tracking echo botanical labels. Use for garden rooms, dining nooks, and winter gardens.',
textureClassCombo: ['texture-grasscloth', 'texture-velvet'],
textureTag: 'Linen Blend',
textureName: 'Layered Botanical Linen',
textureNotes:
'Fine vertical threads with soft tonal shifts create a greenhouse haze. Ideal behind foliage and warm timber.',
textureMeta1: 'Install · Picture frame',
textureMeta2: 'Sheen · Soft matte'
}
];
const boardCanvas = document.getElementById('boardCanvas');
const heroPattern = document.getElementById('heroPattern');
const heroOverlay = document.getElementById('heroOverlay');
const patternNameEl = document.getElementById('patternName');
const patternCodeEl = document.getElementById('patternCode');
const heroTagEl = document.getElementById('heroTag');
const chipEls = [
{
swatch: document.getElementById('chip1'),
name: document.getElementById('chip1Name'),
code: document.getElementById('chip1Code')
},
{
swatch: document.getElementById('chip2'),
name: document.getElementById('chip2Name'),
code: document.getElementById('chip2Code')
},
{
swatch: document.getElementById('chip3'),
name: document.getElementById('chip3Name'),
code: document.getElementById('chip3Code')
}
];
const chipTagEl = document.getElementById('chipTag');
const typeTagEl = document.getElementById('typeTag');
const typeHeadingEl = document.getElementById('typeHeading');
const typeSubEl = document.getElementById('typeSub');
const typeBodyEl = document.getElementById('typeBody');
const textureTile = document.getElementById('textureTile');
const textureTagEl = document.getElementById('textureTag');
const textureNameEl = document.getElementById('textureName');
const textureNotesEl = document.getElementById('textureNotes');
const textureMeta1El = document.getElementById('textureMeta1');
const textureMeta2El = document.getElementById('textureMeta2');
const boardTitleEl = document.getElementById('boardTitle');
const metaPaletteEl = document.getElementById('metaPalette');
const metaFinishEl = document.getElementById('metaFinish');
const themeNameEl = document.getElementById('themeName');
const themeChipEl = document.getElementById('themeChip');
const regenButton = document.getElementById('regenButton');
let lastStyleId = null;
const overlayClassNames = ['pattern-classic', 'pattern-coastal', 'pattern-moody', 'pattern-botanical'];
function pickNextStyle() {
const available = styles.filter(s => s.id !== lastStyleId);
const choice = available[Math.floor(Math.random() * available.length)];
lastStyleId = choice.id;
return choice;
}
function clearPatternClasses() {
overlayClassNames.forEach(cls => heroPattern.classList.remove(cls));
}
function clearTextureClasses() {
const layers = textureTile.querySelectorAll('.texture-layer');
layers.forEach(layer => {
layer.classList.remove('texture-weave', 'texture-linen', 'texture-velvet', 'texture-grasscloth');
});
}
function applyStyle(style) {
boardCanvas.classList.remove('animating'); // reset animation
void boardCanvas.offsetWidth; // force reflow
boardTitleEl.textContent = style.boardTitle;
metaPaletteEl.textContent = style.metaPalette;
metaFinishEl.textContent = style.metaFinish;
themeNameEl.textContent = style.themeName;
themeChipEl.style.background = style.accentColor;
themeChipEl.style.boxShadow = '0 0 14px ' + style.accentColor;
// Hero pattern
clearPatternClasses();
heroPattern.classList.add(style.heroPatternClass);
heroOverlay.style.backgroundImage = style.heroOverlay;
patternNameEl.textContent = style.patternName;
patternCodeEl.textContent = style.patternCode;
heroTagEl.textContent = style.heroTag;
// Chips
style.chips.forEach((chip, i) => {
const el = chipEls[i];
el.swatch.style.background = chip.color;
el.name.textContent = chip.name;
el.code.textContent = chip.code;
el.swatch.style.boxShadow = '0 4px 18px rgba(0,0,0,0.8)';
el.swatch.style.borderColor = i === 1 ? 'rgba(0,0,0,0.2)' : 'rgba(255,255,255,0.18)';
});
chipTagEl.textContent = style.chipTag;
// Type section
typeTagEl.textContent = style.typeTag;
typeHeadingEl.textContent = style.typeHeading;
typeSubEl.textContent = style.typeSub;
typeBodyEl.textContent = style.typeBody;
// Texture
clearTextureClasses();
const layers = textureTile.querySelectorAll('.texture-layer');
if (layers[0]) layers[0].classList.add(style.textureClassCombo[0]);
if (layers[1]) layers[1].classList.add(style.textureClassCombo[1]);
textureTagEl.textContent = style.textureTag;
textureNameEl.textContent = style.textureName;
textureNotesEl.textContent = style.textureNotes;
textureMeta1El.textContent = style.textureMeta1;
textureMeta2El.textContent = style.textureMeta2;
// Trigger entrance animation
requestAnimationFrame(() => {
boardCanvas.classList.add('animating');
});
}
regenButton.addEventListener('click', () => {
const style = pickNextStyle();
applyStyle(style);
});
// Initial board
applyStyle(styles[0]);
})();
</script>
</body>
</html>