Choose theme
Tip: press "t" to toggle theme quickly.
Sign in to VividStream Oratory
Your cart
Adjust quantities and review totals. Prices shown are in USD and include all online materials.
Your cart is empty.
Browse catalog.
Subtotal
$0.00
No medical or financial guarantees are implied. Enrollment policies apply.
Order received
Thank you. This is a confirmation that your selection was recorded locally for demo purposes. No payment was processed.
`;
const footerHTML = `
`;
document.querySelector('header').innerHTML = headerHTML;
document.querySelector('footer').innerHTML = footerHTML;
bindShared();
}
function bindShared(){
const tb=document.getElementById('openTheme');
const menuBtn=document.getElementById('openMenu');
const mob=document.getElementById('mobileMenu');
if(menuBtn&&mob){menuBtn.onclick=()=>mob.classList.toggle('hidden');}
const loginBtns=document.querySelectorAll('#openLogin,#openRegisterMobile');
loginBtns.forEach(b=>{if(b){b.addEventListener('click',()=>{window.location.href='./contact.html';});}});
const consent=localStorage.getItem('cookieConsent');
const banner=document.getElementById('cookieBanner');
if(!consent&&banner){setTimeout(()=>{banner.classList.remove('hidden');banner.classList.add('flex');},800);}
const ca=document.getElementById('cookieAccept');
const cr=document.getElementById('cookieReject');
const cc=document.getElementById('cookieClose');
if(ca)ca.onclick=()=>{localStorage.setItem('cookieConsent','accepted');banner&&banner.classList.add('hidden');};
if(cr)cr.onclick=()=>{localStorage.setItem('cookieConsent','rejected');banner&&banner.classList.add('hidden');};
if(cc)cc.onclick=()=>{banner&&banner.classList.add('hidden');};
}
function getCart(){ try{return JSON.parse(localStorage.getItem('cart'))||[];}catch(e){return[];} }
function setCart(v){ localStorage.setItem('cart', JSON.stringify(v)); }
async function loadCart(){
const data = await fetch('./catalog.json').then(r=>r.json());
const items = getCart();
const enriched = items.map(it => {
const d = data.find(x=>x.id===it.id);
return d ? { ...d, qty: it.qty } : null;
}).filter(Boolean);
const list = document.getElementById('cartList');
const empty = document.getElementById('cartEmpty');
const summary = document.getElementById('summary');
if (!enriched.length) {
list.innerHTML = '';
empty.classList.remove('hidden');
summary.classList.add('hidden');
return;
}
empty.classList.add('hidden');
summary.classList.remove('hidden');
list.innerHTML = enriched.map(it => `
${it.title}
${it.category} • ${it.level} • ${it.durationHours}h
${it.qty}
$${(it.price * it.qty).toFixed(2)}
`).join('');
list.querySelectorAll('[data-remove]').forEach(b=>b.addEventListener('click',()=>{ updateQty(b.getAttribute('data-remove'), 0); }));
list.querySelectorAll('[data-inc]').forEach(b=>b.addEventListener('click',()=>{ updateQty(b.getAttribute('data-inc'), +1); }));
list.querySelectorAll('[data-dec]').forEach(b=>b.addEventListener('click',()=>{ updateQty(b.getAttribute('data-dec'), -1); }));
updateSubtotal(enriched);
}
function updateQty(id, delta){
const cart = getCart();
const item = cart.find(x=>x.id===id);
if (!item) return;
item.qty += delta;
if (item.qty <= 0) {
const i = cart.findIndex(x=>x.id===id);
cart.splice(i,1);
}
setCart(cart);
loadCart();
}
function updateSubtotal(items){
const sum = items.reduce((a,b)=>a + b.price * b.qty, 0);
document.getElementById('subtotal').textContent = '$' + sum.toFixed(2);
}
document.addEventListener('DOMContentLoaded', ()=>{
injectLayout().then(loadCart);
const place = document.getElementById('placeOrder');
const modal = document.getElementById('orderModal');
const close = document.getElementById('closeOrder');
place.addEventListener('click', ()=>{ modal.classList.remove('hidden'); modal.classList.add('flex'); });
close.addEventListener('click', ()=>{ modal.classList.add('hidden'); modal.classList.remove('flex'); });
});