← 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=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[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>