Welcome back
Sign-in is presented as a private preview for this static learning studio.
Create your studio profile
Save your learning trail and return to your selected modules.
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
${p.outcomes.map(x => `- ${x}
`).join('')}
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();