Blushroute Candle Studio

Log in

Account access is prepared for future studio enrollment tools. This demonstration does not collect credentials.

Ask the studio instead

The studio shelf

Courses for curious candle makers.

Choose a focused learning experience with practical outcomes, transparent pricing, and a pace that respects your creative process.

Loading the studio catalog…
`; const footerHTML = ``; document.querySelector('header').innerHTML = headerHTML; document.querySelector('footer').innerHTML = footerHTML; let products = [], page = 1; const size = 6; const favKey = "blushrouteFavorites", cartKey = "blushrouteCart"; const $ = s => document.querySelector(s); function getFavorites() { return JSON.parse(localStorage.getItem(favKey) || "[]"); } function getCart() { return JSON.parse(localStorage.getItem(cartKey) || "[]"); } function saveFavorites(favs) { localStorage.setItem(favKey, JSON.stringify(favs)); } function saveCart(cart) { localStorage.setItem(cartKey, JSON.stringify(cart)); } function updateStatus(msg) { $("#status").textContent = msg; } function renderGrid(filtered) { const grid = $("#grid"); grid.innerHTML = ""; if (!filtered.length) { grid.innerHTML = `

No courses match your search.

`; return; } const start = (page - 1) * size; const slice = filtered.slice(start, start + size); slice.forEach(item => { const favs = getFavorites(); const isFav = favs.includes(item.id); const card = document.createElement("div"); card.className = `course-card rounded-3xl border border-rose-200 bg-white p-6 flex flex-col`; card.innerHTML = `
${item.level}

${item.title}

${item.description}

${item.duration}
$${item.price} ${item.currency}
`; grid.appendChild(card); }); renderPagination(filtered.length); attachCardListeners(); } function renderPagination(total) { const nav = $("#pagination"); nav.innerHTML = ""; const pages = Math.ceil(total / size); if (pages <= 1) return; for (let i = 1; i <= pages; i++) { const btn = document.createElement("button"); btn.textContent = i; btn.className = `rounded-full border px-4 py-2 text-sm font-semibold ${i === page ? "bg-fuchsia-700 text-white border-fuchsia-700" : "border-rose-200"}`; btn.onclick = () => { page = i; applyFilters(); }; nav.appendChild(btn); } } function attachCardListeners() { document.querySelectorAll("[data-fav]").forEach(btn => { btn.onclick = () => { const id = btn.dataset.fav; let favs = getFavorites(); if (favs.includes(id)) favs = favs.filter(x => x !== id); else favs.push(id); saveFavorites(favs); applyFilters(); }; }); document.querySelectorAll("[data-details]").forEach(btn => { btn.onclick = () => showDetails(btn.dataset.details); }); document.querySelectorAll("[data-cart]").forEach(btn => { btn.onclick = () => addToCart(btn.dataset.cart); }); } function applyFilters() { const term = $("#search").value.toLowerCase().trim(); const level = $("#filter").value; let filtered = products; if (level !== "All") filtered = filtered.filter(p => p.level === level); if (term) filtered = filtered.filter(p => p.title.toLowerCase().includes(term) || p.description.toLowerCase().includes(term) || p.outcomes.join(" ").toLowerCase().includes(term) ); $("#status").textContent = `${filtered.length} courses found`; renderGrid(filtered); } function showDetails(id) { const item = products.find(p => p.id === id); if (!item) return; const modal = $("#details"); const content = $("#detailContent"); const favs = getFavorites(); const isFav = favs.includes(id); content.innerHTML = `
${item.level}

${item.title}

${item.duration} • $${item.price} ${item.currency}

${item.description}

Learning outcomes

Materials provided

`; modal.showModal(); content.querySelector("[data-fav-modal]").onclick = () => { let favs = getFavorites(); if (favs.includes(id)) favs = favs.filter(x => x !== id); else favs.push(id); saveFavorites(favs); modal.close(); applyFilters(); }; } function addToCart(id) { let cart = getCart(); const existing = cart.findIndex(x => x.id === id); if (existing > -1) cart[existing].quantity++; else cart.push({id, quantity: 1}); saveCart(cart); const btns = document.querySelectorAll(`[data-cart="${id}"]`); btns.forEach(b => { b.textContent = "Added ✓"; setTimeout(() => { b.textContent = "Add to cart"; }, 1200); }); } function attachGlobalListeners() { $("#search").addEventListener("input", () => { page = 1; applyFilters(); }); $("#filter").addEventListener("change", () => { page = 1; applyFilters(); }); const menuToggle = document.querySelector("#menuToggle"); const mainNav = document.querySelector("#mainNav"); menuToggle?.addEventListener("click", () => mainNav.classList.toggle("hidden")); document.querySelectorAll("[data-auth]").forEach(x => x.addEventListener("click", () => { const authTitle = document.querySelector("#authTitle"); authTitle.textContent = x.dataset.auth === "login" ? "Log in" : "Create an account"; document.querySelector("#authModal").showModal(); })); const themeToggle = document.querySelector("#themeToggle"); themeToggle?.addEventListener("click", () => { document.documentElement.classList.toggle("dark"); localStorage.setItem("blushrouteTheme", document.documentElement.classList.contains("dark") ? "dark" : "light"); }); if (localStorage.getItem("blushrouteTheme") === "dark") document.documentElement.classList.add("dark"); const cb = document.querySelector("#cookieBanner"); if (localStorage.getItem("blushrouteCookies") === "yes") cb?.remove(); document.querySelector("#acceptCookies")?.addEventListener("click", () => { localStorage.setItem("blushrouteCookies", "yes"); cb?.remove(); }); } async function init() { try { const r = await fetch("./catalog.json"); products = await r.json(); updateStatus(`${products.length} courses available`); attachGlobalListeners(); applyFilters(); } catch (e) { updateStatus("The catalog could not be loaded. Please try again or contact the studio."); $("#grid").innerHTML = `
Unable to load courses right now.
`; } } init();