← back to Hollywood Wallcoverings
customcreator/gallery.html
152 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Creator — Made-to-Measure Murals | Hollywood Wallcoverings</title>
<style>
:root{
--ink:#1a1a1a; --muted:#6b6b6b; --line:#e6e2db; --bg:#fbfaf7; --paper:#fff;
--accent:#c9a865; --accent-ink:#a98b50; --radius:4px; --card:230px;
--serif:'Cormorant Garamond',Georgia,'Times New Roman',serif;
--sans:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:var(--sans);color:var(--ink);background:var(--bg);line-height:1.55;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
.top{display:flex;align-items:center;justify-content:space-between;padding:20px 30px;border-bottom:1px solid var(--line)}
.brand{font-family:var(--serif);font-size:20px;letter-spacing:.02em}
.top nav a{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-left:22px}
.hero{position:relative;min-height:76vh;display:flex;align-items:center;overflow:hidden;background:#1a140d}
.hero-bg{position:absolute;inset:0;background:url('/CustomCreator/rooms/hero.jpg') center 38%/cover no-repeat;transform:scale(1.03)}
.hero-scrim{position:absolute;inset:0;background:linear-gradient(96deg,rgba(18,13,7,.70) 0%,rgba(18,13,7,.40) 38%,rgba(18,13,7,.05) 66%,rgba(18,13,7,0) 100%)}
.hero-content{position:relative;z-index:2;max-width:1340px;width:100%;margin:0 auto;padding:0 40px}
.hero-inner{max-width:580px;color:#fff}
.hero .eyebrow{font-size:12px;letter-spacing:.24em;text-transform:uppercase;color:#ecdcb6;font-weight:600}
.hero h1{font-family:var(--serif);font-weight:500;font-size:76px;line-height:1;margin:14px 0 18px;color:#fff;text-shadow:0 2px 30px rgba(0,0,0,.35)}
@media(max-width:640px){.hero h1{font-size:46px} .hero-inner{max-width:100%}}
.hero p{font-size:18px;color:rgba(255,255,255,.93);line-height:1.62;max-width:490px;margin:0 0 28px}
.hero .cta{display:inline-block;background:var(--accent);color:#fff;font-weight:600;font-size:14px;letter-spacing:.04em;padding:16px 36px;border-radius:3px}
.hero .cta:hover{background:var(--accent-ink)}
.steps{display:flex;gap:24px;margin-top:32px;flex-wrap:wrap;color:rgba(255,255,255,.82);font-size:12.5px;letter-spacing:.04em}
.steps b{color:#fff;font-weight:700}
.wrap{max-width:1340px;margin:0 auto;padding:0 28px 90px}
.bar{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:16px 2px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--bg);z-index:5;flex-wrap:wrap}
.bar .count{font-size:13px;color:var(--muted)}
.ctrls{display:flex;align-items:center;gap:22px;flex-wrap:wrap}
.ctrl{display:flex;align-items:center;gap:9px}
.ctrl label{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.ctrl select{font-family:var(--sans);font-size:13px;border:1px solid var(--line);border-radius:3px;padding:7px 26px 7px 10px;background:#fff;cursor:pointer}
.ctrl input[type=range]{-webkit-appearance:none;appearance:none;width:120px;height:4px;border-radius:3px;background:var(--line);outline:none;cursor:pointer}
.ctrl input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:17px;height:17px;border-radius:50%;background:var(--accent);border:2px solid #fff;box-shadow:0 1px 3px rgba(0,0,0,.25);cursor:pointer}
.ctrl input[type=range]::-moz-range-thumb{width:17px;height:17px;border-radius:50%;background:var(--accent);border:2px solid #fff;cursor:pointer}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--card),1fr));gap:22px;margin-top:26px}
.card{display:block;cursor:pointer}
.card-img{width:100%;aspect-ratio:4/5;background:#eee var(--bgimg) center/cover no-repeat;border-radius:var(--radius);overflow:hidden;position:relative;transition:box-shadow .18s}
.card:hover .card-img{box-shadow:0 8px 26px rgba(0,0,0,.16)}
.card-img:after{content:"Customize →";position:absolute;left:0;right:0;bottom:0;padding:12px;font-size:12px;letter-spacing:.06em;color:#fff;background:linear-gradient(transparent,rgba(0,0,0,.5));opacity:0;transition:opacity .18s;text-align:center}
.card:hover .card-img:after{opacity:1}
.card-name{font-family:var(--serif);font-size:18px;margin:11px 2px 2px;line-height:1.2}
.card-sub{font-size:12px;color:var(--muted);margin:0 2px}
.empty{padding:60px;text-align:center;color:var(--muted)}
</style>
</head>
<body>
<div class="top">
<div class="brand">Hollywood Wallcoverings</div>
<nav><a href="https://hollywoodwallcoverings.com">Shop</a><a href="#grid">Patterns</a><a href="/CustomCreator/configure">Start Creating</a></nav>
</div>
<section class="hero">
<div class="hero-bg"></div><div class="hero-scrim"></div>
<div class="hero-content"><div class="hero-inner">
<div class="eyebrow">Hollywood Wallcoverings · Made to Measure</div>
<h1>Custom Creator</h1>
<p>Design your own mural, printed to the exact size of your wall. Choose a pattern, size it with live pricing, and preview it in a real room.</p>
<a class="cta" id="startBtn" href="/CustomCreator/configure">Start Creating →</a>
<div class="steps"><span><b>1.</b> Pick a pattern</span><span><b>2.</b> Size your wall</span><span><b>3.</b> Preview in a room</span><span><b>4.</b> Order made-to-measure</span></div>
</div></div>
</section>
<div class="wrap">
<div class="bar" id="grid">
<div class="count" id="count">Loading patterns…</div>
<div class="ctrls">
<div class="ctrl"><input id="q" type="search" placeholder="Search designs…" style="font-family:var(--sans);font-size:13px;border:1px solid var(--line);border-radius:3px;padding:7px 12px;min-width:170px"></div>
<div class="ctrl"><label for="cat">Category</label>
<select id="cat"><option value="">All</option></select>
</div>
<div class="ctrl"><label for="sort">Sort</label>
<select id="sort">
<option value="newest">Newest</option>
<option value="color">Color</option>
<option value="style">Style</option>
<option value="sku">SKU A→Z</option>
<option value="title">Title A→Z</option>
</select>
</div>
<div class="ctrl"><label for="density">Density</label><input id="density" type="range" min="160" max="340" step="10" value="230"></div>
</div>
</div>
<div class="grid" id="cards"></div>
<div style="text-align:center;margin-top:34px">
<button id="more" style="display:none;font-family:var(--sans);font-size:13px;letter-spacing:.06em;border:1px solid var(--ink);background:var(--paper);color:var(--ink);padding:13px 34px;border-radius:3px;cursor:pointer">Load more</button>
</div>
</div>
<script>
const $=id=>document.getElementById(id);
const esc=s=>String(s||'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
const PAGE=120;
let offset=0,total=0,loading=false,first=true;
function cardHtml(p){return `
<a class="card" href="/CustomCreator/configure?handle=${encodeURIComponent(p.handle)}">
<div class="card-img" style="--bgimg:url('${esc(p.image)}')"></div>
<div class="card-name">${esc(p.title)}</div>
<div class="card-sub">${esc(p.style||'Original')}${p.colorName?' · '+esc(p.colorName):''}</div>
</a>`;}
function query(reset){
if(loading) return; loading=true;
if(reset){offset=0;$('cards').innerHTML='';}
const u=new URLSearchParams({q:$('q').value.trim(),category:$('cat').value,sort:$('sort').value,offset,limit:PAGE});
$('count').textContent='Loading…';
fetch('/CustomCreator/api/collection?'+u).then(r=>r.json()).then(d=>{
total=d.total; const items=d.items||[];
$('cards').insertAdjacentHTML('beforeend',items.map(cardHtml).join(''));
offset+=items.length;
$('count').textContent=total? (offset+' of '+total.toLocaleString()+' designs') : 'No designs match.';
$('more').style.display=offset<total?'inline-block':'none';
if(first&&items[0]){$('startBtn').href='/CustomCreator/configure?handle='+encodeURIComponent(items[0].handle);first=false;}
loading=false;
}).catch(()=>{$('count').textContent='Could not load designs.';loading=false;});
}
function loadCategories(){
fetch('/CustomCreator/api/categories').then(r=>r.json()).then(d=>{
const cap=s=>String(s||'').replace(/\b\w/g,c=>c.toUpperCase());
(d.categories||[]).forEach(c=>{const o=document.createElement('option');o.value=c.category;o.textContent=cap(c.category.replace(/-/g,' '))+' ('+c.count.toLocaleString()+')';$('cat').appendChild(o);});
}).catch(()=>{});
}
function init(){
const sv=localStorage.getItem('cc-sort'); if(sv)$('sort').value=sv;
const cv=localStorage.getItem('cc-cat'); // applied after categories load
const dv=localStorage.getItem('cc-density'); if(dv){$('density').value=dv;document.documentElement.style.setProperty('--card',dv+'px');}
let t; $('q').oninput=()=>{clearTimeout(t);t=setTimeout(()=>query(true),280);};
$('cat').onchange=()=>{localStorage.setItem('cc-cat',$('cat').value);query(true);};
$('sort').onchange=()=>{localStorage.setItem('cc-sort',$('sort').value);query(true);};
$('density').oninput=()=>{document.documentElement.style.setProperty('--card',$('density').value+'px');localStorage.setItem('cc-density',$('density').value);};
$('more').onclick=()=>query(false);
loadCategories();
query(true);
}
init();
</script>
</body>
</html>