ClearScene Atelier

The atelier library

Choose the next piece of your practice.

Study the decisions behind distinctive marks, then apply them to a brief of your own.

Loading the studio library...
`; const footerHTML = ``; document.getElementById('site-header').innerHTML = headerHTML; document.getElementById('site-footer').innerHTML = footerHTML; // Theme toggle function initTheme() { const themeBtn = document.getElementById('theme-toggle'); const savedTheme = localStorage.getItem('clearSceneTheme'); if (savedTheme === 'light') { document.documentElement.classList.add('bg-white', 'text-slate-950'); document.documentElement.classList.remove('bg-slate-950', 'text-slate-100'); } if (themeBtn) { themeBtn.addEventListener('click', () => { if (document.documentElement.classList.contains('bg-white')) { document.documentElement.classList.remove('bg-white', 'text-slate-950'); document.documentElement.classList.add('bg-slate-950', 'text-slate-100'); localStorage.setItem('clearSceneTheme', 'dark'); } else { document.documentElement.classList.add('bg-white', 'text-slate-950'); document.documentElement.classList.remove('bg-slate-950', 'text-slate-100'); localStorage.setItem('clearSceneTheme', 'light'); } }); } } // Mobile nav function initMobileNav() { const toggle = document.getElementById('mobile-menu-toggle'); const mobile = document.getElementById('mobile-navigation'); if (toggle && mobile) { toggle.addEventListener('click', () => mobile.classList.toggle('hidden')); } } // Modals function initModals() { document.querySelectorAll('[data-modal-open]').forEach(btn => { btn.addEventListener('click', () => { const modal = document.getElementById(btn.dataset.modalOpen); if (modal) modal.classList.replace('hidden', 'flex'); }); }); document.querySelectorAll('[data-modal-close]').forEach(btn => { btn.addEventListener('click', () => { const modal = document.getElementById(btn.dataset.modalClose); if (modal) modal.classList.replace('flex', 'hidden'); }); }); } // Catalog logic let products = []; let filtered = []; let page = 1; const size = 6; const follows = () => JSON.parse(localStorage.getItem('clearSceneFollows') || '[]'); const cartData = () => JSON.parse(localStorage.getItem('clearSceneCart') || '{}'); const grid = document.getElementById('product-grid'); const statusEl = document.getElementById('catalog-status'); function getStudioSignal(p) { return `${p.category.toUpperCase().slice(0,3)}-${p.level.slice(0,1)}${p.duration.split(' ')[0]}`; } function render() { const start = (page - 1) * size; const slice = filtered.slice(start, start + size); grid.innerHTML = slice.map(p => `

${p.category} · ${p.level}

${getStudioSignal(p)}

${p.title}

${p.shortDescription}

${p.format} · ${p.duration} · $${p.price}

`).join(''); statusEl.textContent = filtered.length ? `${filtered.length} studio pieces found.` : 'No pieces match this search.'; const totalPages = Math.ceil(filtered.length / size); document.getElementById('pagination').innerHTML = Array.from({ length: totalPages }, (_, i) => ` `).join(''); } function refresh() { const q = document.getElementById('search').value.toLowerCase(); const c = document.getElementById('category').value; filtered = products.filter(p => (c === 'all' || p.category === c) && `${p.title} ${p.shortDescription} ${p.category}`.toLowerCase().includes(q) ); page = 1; render(); } fetch('./catalog.json') .then(r => r.json()) .then(data => { products = data; const catSelect = document.getElementById('category'); [...new Set(data.map(p => p.category))].forEach(c => { catSelect.insertAdjacentHTML('beforeend', ``); }); filtered = [...products]; render(); }); document.getElementById('search').addEventListener('input', refresh); document.getElementById('category').addEventListener('change', refresh); document.addEventListener('click', e => { const followId = e.target.dataset.follow; if (followId) { let arr = follows(); arr = arr.includes(followId) ? arr.filter(x => x !== followId) : [...arr, followId]; localStorage.setItem('clearSceneFollows', JSON.stringify(arr)); render(); } const cartId = e.target.dataset.cart; if (cartId) { let c = cartData(); c[cartId] = (c[cartId] || 0) + 1; localStorage.setItem('clearSceneCart', JSON.stringify(c)); e.target.textContent = 'Added'; setTimeout(() => { if (e.target) e.target.textContent = 'Add to cart'; }, 1200); } const detailId = e.target.dataset.detail; if (detailId) { const p = products.find(x => x.id === detailId); const modalContent = document.getElementById('product-detail'); modalContent.innerHTML = `

${p.category} · ${p.level}

${p.title}

${p.description}

You will practice

Open cart
`; document.getElementById('product-modal').classList.replace('hidden', 'flex'); document.getElementById('close-detail').addEventListener('click', () => { document.getElementById('product-modal').classList.replace('flex', 'hidden'); }); } const pageBtn = e.target.dataset.page; if (pageBtn) { page = parseInt(pageBtn); render(); } }); // Cookie banner function initCookie() { const banner = document.getElementById('cookie-banner'); if (localStorage.getItem('clearSceneCookies') === 'accepted' && banner) banner.remove(); const closeBtn = document.getElementById('cookie-close'); if (closeBtn) { closeBtn.addEventListener('click', () => { localStorage.setItem('clearSceneCookies', 'accepted'); if (banner) banner.remove(); }); } } // Boot everything function boot() { initTheme(); initMobileNav(); initModals(); initCookie(); } boot();