← back to Prestige Car Wash
public/services.html
119 lines
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Services & Pricing — Prestige Car Wash</title>
<meta name="description" content="Full service menu and flat pricing: express wash, hand wash, full detail, ceramic coating, headlight restoration — San Fernando Valley.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/assets/pcw.css">
</head>
<body>
<nav class="nav"><div class="wrap row">
<div class="brand"><span class="mk">🚗</span><div>Prestige<br><small>Car Wash · SFV</small></div></div>
<button class="hamb" aria-label="Menu" aria-expanded="false" onclick="var o=document.getElementById('lnk').classList.toggle('open');this.setAttribute('aria-expanded',o)">☰</button>
<div class="links" id="lnk">
<a href="/">Home</a><a href="/services" class="on">Services</a><a href="/contact">Book / Contact</a>
<a class="btn" href="/contact">Book a Wash</a>
</div>
</div></nav>
<section class="section"><div class="wrap">
<h2>Services & pricing</h2>
<p class="sub">Flat, all-in pricing. Filter, sort, and set the density that suits you.</p>
<div class="controls">
<button class="btn ghost filters-toggle" onclick="toggleDrawer(true)">☰ Filters</button>
<input type="search" id="q" placeholder="Search services…">
<label>Sort
<select id="sort">
<option value="featured">Featured</option>
<option value="price-asc">Price ↑</option>
<option value="price-desc">Price ↓</option>
<option value="duration">Quickest</option>
<option value="title">A–Z</option>
</select>
</label>
<label>Density
<input type="range" id="density" min="2" max="6" step="1">
</label>
<span id="count" style="color:var(--mut);font-size:13px;font-weight:600"></span>
</div>
<div class="drawer-backdrop" id="backdrop" onclick="toggleDrawer(false)"></div>
<div class="layout">
<aside class="filters" id="filters">
<h4>Filters</h4>
<details class="facet" open><summary>Category</summary><div id="f-category"></div></details>
<details class="facet" open><summary>Price</summary><div id="f-band"></div></details>
<button class="btn ghost" style="margin-top:12px;width:100%" onclick="clearFilters()">Clear filters</button>
</aside>
<main><div class="grid" id="grid"></div></main>
</div>
</div></section>
<footer class="foot"><div class="wrap">© 2026 Prestige Car Wash · San Fernando Valley, CA · Instagram @prestigecwash</div></footer>
<script>
const $=s=>document.querySelector(s);
const FIL={category:'',band:''};
const KEY='pcw';
let SORT=localStorage.getItem(KEY+'.sort')||'featured';
let DENS=localStorage.getItem(KEY+'.density')||'4';
$('#sort').value=SORT; $('#density').value=DENS; setDensity(DENS);
function setDensity(v){v=Number(v);
const fs=Math.max(.85,Math.min(1.25, 1+(4-v)*0.06));
document.documentElement.style.setProperty('--cols',v);
document.documentElement.style.setProperty('--fs',fs.toFixed(3));
}
$('#density').oninput=e=>{setDensity(e.target.value);localStorage.setItem(KEY+'.density',e.target.value)};
$('#sort').onchange=e=>{SORT=e.target.value;localStorage.setItem(KEY+'.sort',SORT);load()};
let t; $('#q').oninput=()=>{clearTimeout(t);t=setTimeout(load,250)};
function qs(){const p=new URLSearchParams();p.set('sort',SORT);
if(FIL.category)p.set('category',FIL.category); if(FIL.band)p.set('band',FIL.band);
if($('#q').value.trim())p.set('q',$('#q').value.trim()); return p.toString();}
function facetBox(id,counts,field){
const el=$('#'+id);
el.innerHTML=Object.entries(counts).sort((a,b)=>b[1]-a[1]).map(([k,n])=>`
<div class="opt ${FIL[field]===k?'on':''}" onclick="pick('${field}','${k.replace(/'/g,"\\'")}')">
<span>${k}</span><span class="n">${n}</span></div>`).join('') || '<div class="opt">—</div>';
}
window.pick=(field,val)=>{FIL[field]=FIL[field]===val?'':val;load()};
window.clearFilters=()=>{FIL.category='';FIL.band='';$('#q').value='';load()};
window.toggleDrawer=(open)=>{$('#filters').classList.toggle('open',open);$('#backdrop').classList.toggle('open',open)};
function load(){
Promise.all([
fetch('/api/services?'+qs()).then(r=>r.json()),
fetch('/api/facets?'+qs()).then(r=>r.json())
]).then(([list,facets])=>{
$('#count').textContent=list.length+' service'+(list.length!==1?'s':'');
facetBox('f-category',facets.category,'category');
facetBox('f-band',facets.band,'band');
$('#grid').innerHTML=list.map(card).join('')||'<p style="color:var(--mut)">No services match those filters.</p>';
});
}
function card(s){
return `<div class="card">
<div class="media">
<video src="/${s.media_clip}" muted loop autoplay playsinline
onerror="this.replaceWith(Object.assign(document.createElement('div'),{className:'ph',innerHTML:'🚿 ${s.name}'}))"></video>
</div>
<div class="body">
<div class="cat">${s.category} · ${s.duration_min} min</div>
<div class="ttl">${s.name}</div>
<div class="blurb">${s.blurb}</div>
<div class="tags">${(s.highlights||[]).map(h=>`<span class="tag">${h}</span>`).join('')}</div>
<div class="row" style="margin-top:10px"><span class="price">${s.price_display||('$'+s.price)}</span><a class="btn" href="/contact?service=${encodeURIComponent(s.name)}">Book</a></div>
</div>
</div>`;
}
load();
</script>
</body>
</html>