← back to Model Arena
data/artifacts/18bd2744dce2/grok.html
697 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Terracotta & Sage — Color Story</title>
<style>
:root {
--bg: #faf8f4;
--surface: #ffffff;
--ink: #1c1a17;
--muted: #9b948a;
--accent: #b0472e;
--accent-soft: #c65f38;
--jewel: #2f4c39;
--line: rgba(28, 26, 23, 0.12);
--shadow: 0 12px 40px rgba(28, 26, 23, 0.08);
--shadow-soft: 0 4px 16px rgba(28, 26, 23, 0.06);
--ease: cubic-bezier(.22, .9, .24, 1);
--ease-hero: cubic-bezier(.22, 1, .36, 1);
--serif: 'Didot', 'Bodoni MT', 'Playfair Display', 'EB Garamond', Georgia, 'Times New Roman', serif;
--sans: 'Avenir Next', 'Century Gothic', Futura, 'Helvetica Neue', sans-serif;
--hue-oatmeal: #d4c4a8;
--hue-celadon: #8fa890;
--hue-terracotta: #c45c3e;
--frame: 1080px;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
height: 100%;
background: #e8e4dc;
color: var(--ink);
font-family: var(--sans);
font-size: 16px;
line-height: 1.55;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Compact wordmark lockup */
.topbar {
position: fixed;
top: 0;
left: 0;
z-index: 100;
padding: 18px 24px;
pointer-events: none;
}
.wordmark {
font-family: var(--serif);
font-size: 11px;
font-weight: 400;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink);
max-width: 220px;
line-height: 1.3;
opacity: 0.85;
}
.app {
min-height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 56px 24px 40px;
gap: 28px;
}
/* Stage */
.stage-wrap {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.carousel {
width: min(92vw, 540px);
aspect-ratio: 1 / 1;
position: relative;
background: var(--bg);
border: 1px solid var(--line);
box-shadow: var(--shadow);
overflow: hidden;
touch-action: pan-y;
user-select: none;
cursor: grab;
}
.carousel:active { cursor: grabbing; }
.track {
display: flex;
height: 100%;
width: 100%;
transition: transform 0.65s var(--ease-hero);
will-change: transform;
}
.slide {
flex: 0 0 100%;
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* —— Slide 1: Cover —— */
.slide-cover {
background: var(--bg);
justify-content: center;
align-items: center;
text-align: center;
padding: 8%;
}
.cover-ornament {
width: 48px;
height: 1px;
background: var(--accent);
margin: 0 auto 28px;
}
.cover-kicker {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 18px;
}
.cover-title {
font-family: var(--serif);
font-size: clamp(36px, 8vw, 52px);
font-weight: 400;
line-height: 1.08;
letter-spacing: -0.02em;
color: var(--ink);
margin-bottom: 14px;
}
.cover-title em {
font-style: italic;
color: var(--accent);
}
.cover-sub {
font-family: var(--sans);
font-size: 13px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 36px;
}
.cover-swatches {
display: flex;
gap: 10px;
justify-content: center;
align-items: center;
}
.cover-swatch {
width: 44px;
height: 44px;
border-radius: 50%;
border: 1px solid var(--line);
box-shadow: var(--shadow-soft);
}
.cover-season {
position: absolute;
bottom: 7%;
left: 0;
right: 0;
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--muted);
text-align: center;
}
/* —— Hue slides 2–4 —— */
.slide-hue {
background: var(--bg);
padding: 0;
}
.hue-panel {
flex: 1;
display: grid;
grid-template-rows: 1.15fr 1fr;
height: 100%;
}
.swatch-field {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
/* CSS-drawn luxury swatch — layered planes, no letter labels */
.swatch-field::before {
content: '';
position: absolute;
inset: 0;
background: var(--swatch);
}
.swatch-field::after {
content: '';
position: absolute;
right: -8%;
bottom: -18%;
width: 58%;
height: 70%;
background: var(--swatch-deep);
opacity: 0.55;
border-radius: 60% 40% 30% 70% / 50% 30% 70% 50%;
filter: blur(0.5px);
}
.swatch-sheen {
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.18) 0%, transparent 42%, transparent 100%);
pointer-events: none;
z-index: 1;
}
.swatch-edge {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 1px;
background: var(--line);
z-index: 2;
}
.hue-copy {
display: flex;
flex-direction: column;
justify-content: center;
padding: 9% 10% 10%;
background: var(--bg);
gap: 14px;
}
.hue-label {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--muted);
}
.hue-name {
font-family: var(--serif);
font-size: clamp(32px, 7vw, 44px);
font-weight: 400;
letter-spacing: -0.02em;
line-height: 1.1;
color: var(--ink);
}
.hue-rule {
width: 32px;
height: 1px;
background: var(--accent);
margin: 2px 0 4px;
}
.hue-tip {
font-family: var(--sans);
font-size: clamp(13px, 2.4vw, 15px);
line-height: 1.6;
color: var(--ink);
opacity: 0.78;
max-width: 34ch;
}
.hue-tip strong {
font-weight: 500;
color: var(--ink);
opacity: 1;
}
/* Per-hue tokens */
.slide-oatmeal { --swatch: var(--hue-oatmeal); --swatch-deep: #b8a68a; }
.slide-celadon { --swatch: var(--hue-celadon); --swatch-deep: #6f8a72; }
.slide-terracotta { --swatch: var(--hue-terracotta); --swatch-deep: #9a3f28; }
/* —— Slide 5: CTA —— */
.slide-cta {
background: var(--ink);
color: var(--bg);
justify-content: center;
align-items: center;
text-align: center;
padding: 10%;
}
.cta-kicker {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--accent-soft);
margin-bottom: 22px;
}
.cta-title {
font-family: var(--serif);
font-size: clamp(28px, 6.5vw, 40px);
font-weight: 400;
line-height: 1.15;
letter-spacing: -0.02em;
color: #f5f2ea;
margin-bottom: 18px;
max-width: 16ch;
}
.cta-body {
font-family: var(--sans);
font-size: 14px;
line-height: 1.65;
color: rgba(245, 242, 234, 0.62);
max-width: 28ch;
margin: 0 auto 32px;
}
.cta-btn {
display: inline-block;
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink);
background: #f5f2ea;
border: 1px solid #f5f2ea;
padding: 14px 28px;
cursor: pointer;
transition: background 0.35s var(--ease), color 0.35s var(--ease), border-color 0.35s var(--ease);
text-decoration: none;
}
.cta-btn:hover {
background: transparent;
color: #f5f2ea;
border-color: rgba(245, 242, 234, 0.45);
}
.cta-palette-row {
display: flex;
gap: 8px;
justify-content: center;
margin-top: 36px;
}
.cta-dot {
width: 18px;
height: 18px;
border-radius: 50%;
border: 1px solid rgba(245, 242, 234, 0.15);
}
/* Dots */
.dots {
display: flex;
gap: 10px;
align-items: center;
justify-content: center;
}
.dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--muted);
opacity: 0.35;
border: none;
padding: 0;
cursor: pointer;
transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), background 0.35s var(--ease);
}
.dot[aria-current="true"] {
opacity: 1;
background: var(--accent);
transform: scale(1.35);
}
/* Editable palette strip */
.editor {
width: min(92vw, 540px);
background: var(--surface);
border: 1px solid var(--line);
box-shadow: var(--shadow-soft);
padding: 18px 20px 16px;
}
.editor-head {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 14px;
}
.editor-title {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
}
.editor-note {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.06em;
color: var(--muted);
opacity: 0.7;
}
.swatch-controls {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
}
.control {
display: flex;
flex-direction: column;
gap: 8px;
align-items: flex-start;
}
.control label {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink);
opacity: 0.7;
}
.control input[type="color"] {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 36px;
border: 1px solid var(--line);
background: transparent;
cursor: pointer;
padding: 0;
border-radius: 2px;
}
.control input[type="color"]::-webkit-color-swatch-wrapper { padding: 3px; }
.control input[type="color"]::-webkit-color-swatch {
border: none;
border-radius: 1px;
}
.control input[type="color"]::-moz-color-swatch {
border: none;
border-radius: 1px;
}
.hint {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--muted);
text-align: center;
opacity: 0.65;
}
@media (max-width: 480px) {
.topbar { padding: 14px 16px; }
.app { padding: 48px 12px 28px; }
.hue-copy { padding: 8% 8% 9%; }
}
</style>
</head>
<body>
<header class="topbar" aria-label="Brand">
<div class="wordmark">Designer Wallcoverings</div>
</header>
<main class="app">
<div class="stage-wrap">
<div class="carousel" id="carousel" role="region" aria-roledescription="carousel" aria-label="Terracotta and Sage color story">
<div class="track" id="track">
<!-- 1 Cover -->
<section class="slide slide-cover" aria-label="Cover">
<div class="cover-ornament"></div>
<p class="cover-kicker">Seasonal Color Story</p>
<h1 class="cover-title">Terracotta<br>& <em>Sage</em></h1>
<p class="cover-sub">Autumn Atelier · Vol. IV</p>
<div class="cover-swatches" aria-hidden="true">
<span class="cover-swatch" id="cs-oat" style="background: var(--hue-oatmeal)"></span>
<span class="cover-swatch" id="cs-cel" style="background: var(--hue-celadon)"></span>
<span class="cover-swatch" id="cs-ter" style="background: var(--hue-terracotta)"></span>
</div>
<p class="cover-season">Three hues · Infinite rooms</p>
</section>
<!-- 2 Oatmeal -->
<section class="slide slide-hue slide-oatmeal" aria-label="Oatmeal">
<div class="hue-panel">
<div class="swatch-field">
<div class="swatch-sheen"></div>
<div class="swatch-edge"></div>
</div>
<div class="hue-copy">
<p class="hue-label">Hue 01 · Ground</p>
<h2 class="hue-name">Oatmeal</h2>
<div class="hue-rule"></div>
<p class="hue-tip"><strong>Room tip:</strong> Anchor a sunlit dining alcove — pair with raw linen drapery and unlacquered brass to let the grain of the paper breathe.</p>
</div>
</div>
</section>
<!-- 3 Celadon -->
<section class="slide slide-hue slide-celadon" aria-label="Celadon">
<div class="hue-panel">
<div class="swatch-field">
<div class="swatch-sheen"></div>
<div class="swatch-edge"></div>
</div>
<div class="hue-copy">
<p class="hue-label">Hue 02 · Breath</p>
<h2 class="hue-name">Celadon</h2>
<div class="hue-rule"></div>
<p class="hue-tip"><strong>Room tip:</strong> Soften a powder room or study — the mineral green steadies terracotta accents and cools warm oak floors.</p>
</div>
</div>
</section>
<!-- 4 Terracotta -->
<section class="slide slide-hue slide-terracotta" aria-label="Terracotta">
<div class="hue-panel">
<div class="swatch-field">
<div class="swatch-sheen"></div>
<div class="swatch-edge"></div>
</div>
<div class="hue-copy">
<p class="hue-label">Hue 03 · Ember</p>
<h2 class="hue-name">Terracotta</h2>
<div class="hue-rule"></div>
<p class="hue-tip"><strong>Room tip:</strong> Commit to a full feature wall behind a bed or banquette — the clay warmth holds candlelight and deepens after dusk.</p>
</div>
</div>
</section>
<!-- 5 CTA -->
<section class="slide slide-cta" aria-label="Call to action">
<p class="cta-kicker">Request the story</p>
<h2 class="cta-title">Bring the atelier home</h2>
<p class="cta-body">Sample the Terracotta & Sage collection — hand-finished wallcoverings, cut to order.</p>
<button type="button" class="cta-btn" id="ctaBtn">Order Samples</button>
<div class="cta-palette-row" aria-hidden="true">
<span class="cta-dot" id="cd-oat" style="background: var(--hue-oatmeal)"></span>
<span class="cta-dot" id="cd-cel" style="background: var(--hue-celadon)"></span>
<span class="cta-dot" id="cd-ter" style="background: var(--hue-terracotta)"></span>
</div>
</section>
</div>
</div>
<div class="dots" id="dots" role="tablist" aria-label="Slides"></div>
<p class="hint">Swipe or drag · Tap dots</p>
</div>
<aside class="editor" aria-label="Editable palette">
<div class="editor-head">
<span class="editor-title">Editable Palette</span>
<span class="editor-note">Live · updates swatches</span>
</div>
<div class="swatch-controls">
<div class="control">
<label for="c-oatmeal">Oatmeal</label>
<input type="color" id="c-oatmeal" value="#d4c4a8">
</div>
<div class="control">
<label for="c-celadon">Celadon</label>
<input type="color" id="c-celadon" value="#8fa890">
</div>
<div class="control">
<label for="c-terracotta">Terracotta</label>
<input type="color" id="c-terracotta" value="#c45c3e">
</div>
</div>
</aside>
</main>
<script>
(function () {
const root = document.documentElement;
const track = document.getElementById('track');
const carousel = document.getElementById('carousel');
const dotsWrap = document.getElementById('dots');
const slides = Array.from(track.children);
const total = slides.length;
let index = 0;
let dragging = false;
let startX = 0;
let deltaX = 0;
let width = 0;
// Dots
slides.forEach((_, i) => {
const b = document.createElement('button');
b.className = 'dot';
b.type = 'button';
b.setAttribute('role', 'tab');
b.setAttribute('aria-label', 'Slide ' + (i + 1));
b.addEventListener('click', () => go(i));
dotsWrap.appendChild(b);
});
const dots = Array.from(dotsWrap.children);
function measure() {
width = carousel.getBoundingClientRect().width;
}
function go(i, animate) {
index = Math.max(0, Math.min(total - 1, i));
if (animate === false) track.style.transition = 'none';
else track.style.transition = '';
track.style.transform = 'translate3d(' + (-index * 100) + '%, 0, 0)';
dots.forEach((d, di) => d.setAttribute('aria-current', di === index ? 'true' : 'false'));
if (animate === false) {
void track.offsetHeight;
track.style.transition = '';
}
}
// Pointer / touch
function onDown(clientX) {
dragging = true;
startX = clientX;
deltaX = 0;
measure();
track.style.transition = 'none';
}
function onMove(clientX) {
if (!dragging) return;
deltaX = clientX - startX;
const pct = (deltaX / width) * 100;
track.style.transform = 'translate3d(' + (-index * 100 + pct) + '%, 0, 0)';
}
function onUp() {
if (!dragging) return;
dragging = false;
track.style.transition = '';
const threshold = width * 0.18;
if (deltaX < -threshold) go(index + 1);
else if (deltaX > threshold) go(index - 1);
else go(index);
deltaX = 0;
}
carousel.addEventListener('pointerdown', (e) => {
if (e.button !== 0) return;
carousel.setPointerCapture(e.pointerId);
onDown(e.clientX);
});
carousel.addEventListener('pointermove', (e) => onMove(e.clientX));
carousel.addEventListener('pointerup', onUp);
carousel.addEventListener('pointercancel', onUp);
carousel.addEventListener('lostpointercapture', onUp);
// Keyboard
carousel.tabIndex = 0;
carousel.addEventListener('keydown', (e) => {
if (e.key === 'ArrowRight') go(index + 1);
if (e.key === 'ArrowLeft') go(index - 1);
});
window.addEventListener('resize', () => { measure(); go(index, false); });
// Editable palette
function hexToDeep(hex, factor) {
const h = hex.replace('#', '');
const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16);
let r = (n >> 16) & 255, g = (n >> 8) & 255, b = n & 255;
r = Math.max(0, Math.round(r * factor));
g = Math.max(0, Math.round(g * factor));
b = Math.max(0, Math.round(b * factor));
return '#' + [r, g, b].map(v => v.toString(16).padStart(2, '0')).join('');
}
function bindColor(inputId, cssVar, deepSelector) {
const input = document.getElementById(inputId);
const apply = () => {
const v = input.value;
root.style.setProperty(cssVar, v);
if (deepSelector) {
const el = document.querySelector(deepSelector);
if (el) el.style.setProperty('--swatch-deep', hexToDeep(v, 0.78));
}
};
input.addEventListener('input', apply);
apply();
}
bindColor('c-oatmeal', '--hue-oatmeal', '.slide-oatmeal');
bindColor('c-celadon', '--hue-celadon', '.slide-celadon');
bindColor('c-terracotta', '--hue-terracotta', '.slide-terracotta');
document.getElementById('ctaBtn').addEventListener('click', function () {
this.textContent = 'Samples Requested';
this.style.opacity = '0.7';
});
measure();
go(0, false);
})();
</script>
</body>
</html>