The Ember Journal catalog
Choose your next pour.
Browse focused candle-making courses with honest difficulty levels, practical outcomes, and a clear list of materials.
Loading the studio shelf…
`;
async function loadHeaderFooter() {
$("site-header").innerHTML = headerHTML;
$("site-footer").innerHTML = footerHTML;
// Mobile menu
const mt = $("menu-toggle");
const mn = $("mobile-nav");
if(mt && mn){ mt.onclick=()=>mn.classList.toggle("hidden"); }
// Theme toggle
const themeBtn = $("theme-toggle");
if(themeBtn){
const applyTheme = (t)=>{
if(t==="dark"){ document.documentElement.style.setProperty("--tw-bg-opacity","1"); document.body.classList.add("bg-[#3E291F]"); document.body.classList.remove("bg-[#F7F0E6]"); }
else{ document.body.classList.remove("bg-[#3E291F]"); document.body.classList.add("bg-[#F7F0E6]"); }
};
let saved = localStorage.getItem("tendertrail-theme")||"light";
applyTheme(saved);
themeBtn.onclick=()=>{
saved = saved==="light"?"dark":"light";
localStorage.setItem("tendertrail-theme",saved);
applyTheme(saved);
};
}
// Login/Register modals
const loginBtn = $("login-open");
const regBtn = $("register-open");
if(loginBtn){ loginBtn.onclick=()=>showAuthModal("login"); }
if(regBtn){ regBtn.onclick=()=>showAuthModal("register"); }
// Cookie banner
const banner = $("cookie-banner");
if(banner && localStorage.getItem("tendertrail-cookie-consent")==="yes"){ banner.classList.add("hidden"); }
const cookieClose = $("cookie-close");
if(cookieClose){ cookieClose.onclick=()=>{ localStorage.setItem("tendertrail-cookie-consent","yes"); banner.classList.add("hidden"); }; }
}
function showAuthModal(type){
const modal = document.createElement("div");
modal.className = "fixed inset-0 z-50 flex items-center justify-center bg-[#3E291F]/70 p-5";
modal.innerHTML = `
${type==="login"?"Sign in to your journal":"Create your studio account"}
`;
document.body.appendChild(modal);
modal.querySelector("#auth-close").onclick=()=>modal.remove();
modal.querySelector("#auth-form").onsubmit=(e)=>{e.preventDefault(); modal.remove(); alert(type==="login"?"Welcome back to Tendertrail Candle Studio.":"Account created. Welcome to the studio.");};
}
const sampleProducts = [
{"id":"c01","title":"Foundation Wax Pour","category":"Foundations","level":"Beginner","duration":"4 weeks","hours":18,"price":185,"currency":"USD","shortDescription":"Master the fundamentals of soy and beeswax blends.","description":"Learn temperature control, wick selection, and safe pouring technique for clean burns. Includes three finished 8oz candles.","materials":["Soy wax flakes","Cotton wicks","Thermometer","Pouring pitcher"],"featured":true},
{"id":"c02","title":"Scent Ledger: Citrus & Herb","category":"Scent Design","level":"Intermediate","duration":"5 weeks","hours":22,"price":245,"currency":"USD","shortDescription":"Build layered fragrance profiles with natural essential oils.","description":"Create four signature blends using bergamot, rosemary, lavender, and vetiver. Final project is a 12oz custom candle.","materials":["Essential oils set","Beeswax","Fragrance tester strips","Label kit"],"featured":false},
{"id":"c03","title":"Wick & Flame Mastery","category":"Advanced Studio","level":"Advanced","duration":"6 weeks","hours":28,"price":310,"currency":"USD","shortDescription":"Design and test custom wick systems for larger vessels.","description":"Study burn dynamics across container sizes. Produce three 16oz candles with verified 50+ hour burn times.","materials":["Wooden wicks","Metal containers","Digital scale","Burn test journal"],"featured":true},
{"id":"c04","title":"Botanical Wax Journal","category":"Foundations","level":"Beginner","duration":"3 weeks","hours":14,"price":165,"currency":"USD","shortDescription":"Incorporate dried botanicals into wax for visual texture.","description":"Create pressed flower and herb candles with safe embedding techniques and color theory basics.","materials":["Dried botanicals","Colored wax chips","Silicone molds","Drying rack"],"featured":false},
{"id":"c05","title":"Amber & Resin Atelier","category":"Scent Design","level":"Intermediate","duration":"4 weeks","hours":20,"price":235,"currency":"USD","shortDescription":"Work with resinous and woody notes for deep, warm profiles.","description":"Develop two 10oz candles featuring frankincense, myrrh, and sandalwood. Focus on slow-release scent.","materials":["Resin chips","Wooden wick assortment","Amber glass jars","Scent strips"],"featured":true},
{"id":"c06","title":"Studio Planning & Batch Production","category":"Advanced Studio","level":"Advanced","duration":"8 weeks","hours":36,"price":395,"currency":"USD","shortDescription":"Scale your practice into repeatable small-batch production.","description":"Build a full production calendar, cost sheets, and quality control checklist. Deliver six finished candles.","materials":["Production logbook","Label printer access","Bulk wax","Safety kit"],"featured":false},
{"id":"c07","title":"Clean Burn Foundations","category":"Foundations","level":"Beginner","duration":"4 weeks","hours":16,"price":175,"currency":"USD","shortDescription":"Achieve soot-free, even burns from the first pour.","description":"Master wick trimming, centering, and first-burn protocols across three classic vessel shapes.","materials":["Cotton wick assortment","Glass tumblers","Wick centering tools","Burn journal"],"featured":false},
{"id":"c08","title":"Floral Harmony","category":"Scent Design","level":"Intermediate","duration":"5 weeks","hours":24,"price":255,"currency":"USD","shortDescription":"Balance delicate floral notes into stable, long-lasting candles.","description":"Create rose, jasmine, and neroli blends. Includes testing for scent throw in different wax bases.","materials":["Floral essential oils","Wax base samples","Testing vessels","Perfume blotters"],"featured":true},
{"id":"c09","title":"Large Vessel & Multi-Wick Systems","category":"Advanced Studio","level":"Advanced","duration":"7 weeks","hours":32,"price":355,"currency":"USD","shortDescription":"Design stable multi-wick configurations for 20oz+ candles.","description":"Calculate wick spacing, produce four large-format candles, and document burn performance.","materials":["Large glass cylinders","Wood & cotton wicks","Digital thermometer","Test stand"],"featured":false},
{"id":"c10","title":"Seasonal Ember Collection","category":"Foundations","level":"Beginner","duration":"3 weeks","hours":15,"price":155,"currency":"USD","shortDescription":"Design limited-edition seasonal candles with warm spices.","description":"Create autumn and winter blends using cinnamon, clove, and orange. Package two finished candles.","materials":["Spice oils","Seasonal labels","Kraft boxes","Ribbon"],"featured":false},
{"id":"c11","title":"Minimalist Scent Architecture","category":"Scent Design","level":"Intermediate","duration":"4 weeks","hours":19,"price":225,"currency":"USD","shortDescription":"Craft single-note and minimalist compositions.","description":"Focus on purity of scent with cedar, vetiver, and palo santo. Produce three refined 9oz candles.","materials":["Single-note oils","Matte black jars","Wick trimmer","Journal cards"],"featured":true},
{"id":"c12","title":"Professional Studio Setup","category":"Advanced Studio","level":"Advanced","duration":"6 weeks","hours":30,"price":375,"currency":"USD","shortDescription":"Establish a safe, efficient home candle studio workflow.","description":"Plan layout, ventilation, storage, and batch tracking systems. Deliver a complete production-ready setup plan.","materials":["Studio planning templates","Safety signage","Storage bins","Scale & thermometer"],"featured":false},
{"id":"c13","title":"Heritage Beeswax Techniques","category":"Foundations","level":"Beginner","duration":"4 weeks","hours":17,"price":195,"currency":"USD","shortDescription":"Work exclusively with 100% beeswax for natural luminosity.","description":"Learn rolling, dipping, and poured beeswax methods. Finish with four handcrafted candles.","materials":["Beeswax sheets","Wick spools","Dipping tank","Polish cloth"],"featured":false},
{"id":"c14","title":"Spiced & Smoked Profiles","category":"Scent Design","level":"Intermediate","duration":"5 weeks","hours":23,"price":265,"currency":"USD","shortDescription":"Develop warm, smoky, and spiced fragrance stories.","description":"Create tobacco, smoked vanilla, and cardamom candles with complex dry-down notes.","materials":["Smoky fragrance oils","Vanilla bean","Test tubes","Label stock"],"featured":true},
{"id":"c15","title":"Custom Mold & Shape Design","category":"Advanced Studio","level":"Advanced","duration":"6 weeks","hours":29,"price":335,"currency":"USD","shortDescription":"Create original candle shapes using silicone molds and carving.","description":"Design and produce four unique sculptural candles with custom molds and surface texture techniques.","materials":["Silicone mold kit","Carving tools","Color pigments","Finishing wax"],"featured":false},
{"id":"c16","title":"Intro to Candle Safety & Testing","category":"Foundations","level":"Beginner","duration":"2 weeks","hours":10,"price":125,"currency":"USD","shortDescription":"Understand burn safety, testing protocols, and labeling requirements.","description":"Complete safety certification and produce two test candles with documented burn data.","materials":["Safety manual","Test vessels","Timer","Label templates"],"featured":false},
{"id":"c17","title":"Night Garden Collection","category":"Scent Design","level":"Intermediate","duration":"4 weeks","hours":21,"price":240,"currency":"USD","shortDescription":"Explore nocturnal florals and cool night air accords.","description":"Develop jasmine, tuberose, and night-blooming cereus blends in cool-toned vessels.","materials":["Cool floral oils","Matte navy jars","Wick assortment","Scent diary"],"featured":true},
{"id":"c18","title":"Batch Scaling & Quality Control","category":"Advanced Studio","level":"Advanced","duration":"7 weeks","hours":34,"price":385,"currency":"USD","shortDescription":"Move from single pours to consistent, repeatable batches.","description":"Build SOPs, track variance, and deliver eight identical candles with full QC documentation.","materials":["Batch log sheets","Digital scale","Color matching kit","Storage crates"],"featured":false},
{"id":"c19","title":"Travel Candle Workshop","category":"Foundations","level":"Beginner","duration":"3 weeks","hours":13,"price":145,"currency":"USD","shortDescription":"Design compact, leak-proof candles for travel and gifting.","description":"Create four 4oz travel tins with secure lids and custom labels.","materials":["Travel tins","Leak-proof seals","Mini wicks","Gift tags"],"featured":false},
{"id":"c20","title":"Ember & Ash Signature Series","category":"Scent Design","level":"Intermediate","duration":"5 weeks","hours":25,"price":275,"currency":"USD","shortDescription":"Craft the studio’s signature warm, smoky, woody collection.","description":"Develop the final signature line with three 12oz candles ready for limited release.","materials":["Signature oil blend kit","Matte terracotta jars","Premium wicks","Edition cards"],"featured":true}
];
async function loadProducts() {
const status = $("status");
try {
// Using embedded data for self-contained file
products = sampleProducts;
const categories = [...new Set(products.map(p=>p.category))];
const catSelect = $("category");
categories.forEach(cat=>{
const opt = document.createElement("option");
opt.value = cat;
opt.textContent = cat;
catSelect.appendChild(opt);
});
filtered = [...products];
status.textContent = `${products.length} courses in the Ember Journal`;
renderGrid();
attachFilters();
} catch(e){
status.textContent = "Unable to load catalog. Please refresh.";
}
}
function attachFilters(){
$("search").oninput = filterAndRender;
$("category").onchange = filterAndRender;
$("pageSize").onchange = ()=>{page=1; renderGrid();};
}
function filterAndRender(){
const q = $("search").value.toLowerCase().trim();
const cat = $("category").value;
filtered = products.filter(p=>{
const matchQ = !q || p.title.toLowerCase().includes(q) || p.shortDescription.toLowerCase().includes(q);
const matchCat = cat==="all" || p.category===cat;
return matchQ && matchCat;
});
page=1;
renderGrid();
}
function renderGrid(){
const grid = $("course-grid");
grid.innerHTML = "";
const perPage = parseInt($("pageSize").value);
const start = (page-1)*perPage;
const pageItems = filtered.slice(start, start+perPage);
if(pageItems.length===0){
grid.innerHTML = `No courses match your filters.
`;
renderPagination(0);
return;
}
pageItems.forEach(p=>{
const favs = read(F,[]);
const isFav = favs.includes(p.id);
const card = document.createElement("div");
card.className = `dd23l xk9h7 p2aql border border-[#D9C4AE] bg-[#FFF9F0] rounded-2xl p-6 flex flex-col`;
card.innerHTML = `
${p.category}
${p.title}
${p.shortDescription}
${p.level} • ${p.duration}
$${p.price}
`;
grid.appendChild(card);
});
// Attach events
grid.querySelectorAll(".fav-btn").forEach(btn=>{
btn.onclick=()=>{ toggleFavorite(btn.dataset.id, btn); };
});
grid.querySelectorAll(".detail-btn").forEach(btn=>{
btn.onclick=()=>showDetail(btn.dataset.id);
});
grid.querySelectorAll(".cart-btn").forEach(btn=>{
btn.onclick=()=>addToCart(btn.dataset.id, btn);
});
renderPagination(Math.ceil(filtered.length / perPage));
}
function renderPagination(totalPages){
const nav = $("pagination");
nav.innerHTML = "";
if(totalPages<=1) return;
for(let i=1; i<=totalPages; i++){
const a = document.createElement("a");
a.href = "#";
a.className = `px-4 py-2 rounded-full border text-sm ${i===page ? "bg-[#6B4632] text-[#FFF9F0] border-[#6B4632]" : "border-[#D9C4AE] hover:bg-[#EAD8C7]"}`;
a.textContent = i;
a.onclick = (e)=>{ e.preventDefault(); page=i; renderGrid(); };
nav.appendChild(a);
}
}
function toggleFavorite(id, btn){
let favs = read(F,[]);
if(favs.includes(id)){
favs = favs.filter(x=>x!==id);
btn.classList.remove("text-[#C98F65]");
btn.classList.add("text-[#D9C4AE]");
} else {
favs.push(id);
btn.classList.add("text-[#C98F65]");
btn.classList.remove("text-[#D9C4AE]");
}
write(F,favs);
}
function addToCart(id, btn){
let cart = read(C,{});
cart[id] = (cart[id]||0) + 1;
write(C,cart);
const orig = btn.textContent;
btn.textContent = "Added ✓";
setTimeout(()=>{ btn.textContent = orig; }, 1200);
}
function showDetail(id){
const p = products.find(x=>x.id===id);
if(!p) return;
const modal = $("detail-modal");
const content = $("detail-content");
content.innerHTML = `
${p.category} • ${p.level}
${p.title}
${p.duration} • ${p.hours} studio hours • $${p.price}
${p.description}
Materials included
${p.materials.map(m=>`- ${m}
`).join("")}
`;
modal.classList.remove("hidden");
modal.classList.add("flex");
$("close-detail").onclick = ()=>{ modal.classList.remove("flex"); modal.classList.add("hidden"); };
$("modal-cart").onclick = ()=>{ addToCart(id, $("modal-cart")); };
}
async function init(){
await loadHeaderFooter();
await loadProducts();
}
init();