Xevora

Log in to Xevora

Account access is a demonstration feature on this education website.

Create a Xevora profile

Registration is not connected to a live account service in this demonstration.

Your learning plan

Cart

Total: $0.00

Checkout inquiry
Continue browsing

Inquiry noted

This demonstration has no live payment processing. Contact Xevora to discuss access and next steps.

`; const footerHTML = ` `; document.getElementById('site-header').innerHTML = headerHTML; document.getElementById('site-footer').innerHTML = footerHTML; const key = 'xevora-cart'; const read = () => JSON.parse(localStorage.getItem(key) || '[]'); let products = []; function draw() { const cart = read(); const rows = cart.map(x => ({...x, p: products.find(p => p.id === x.id)})).filter(x => x.p); const container = document.querySelector('#cart-list'); if (rows.length === 0) { container.innerHTML = '

Your cart is empty. Choose a learning resource to create a focused study plan.

'; document.querySelector('#total').textContent = '$0.00'; return; } container.innerHTML = rows.map(x => `

${x.p.title}

${x.p.category} · $${x.p.price.toFixed(2)} each

`).join(''); const total = rows.reduce((sum, x) => sum + x.p.price * x.quantity, 0); document.querySelector('#total').textContent = '$' + total.toFixed(2); } function attachListeners() { document.addEventListener('change', e => { if (e.target.dataset.qty) { let c = read(); const item = c.find(v => v.id === e.target.dataset.qty); if (item) { item.quantity = Math.max(1, Math.min(20, Number(e.target.value) || 1)); localStorage.setItem(key, JSON.stringify(c)); draw(); } } }); document.addEventListener('click', e => { if (e.target.dataset.remove) { let c = read(); c = c.filter(v => v.id !== e.target.dataset.remove); localStorage.setItem(key, JSON.stringify(c)); draw(); } }); const checkoutLink = document.getElementById('checkout-link'); if (checkoutLink) { checkoutLink.addEventListener('click', e => { e.preventDefault(); const modal = document.getElementById('checkout-modal'); if (modal) modal.showModal(); }); } } fetch('./catalog.json') .then(r => r.json()) .then(x => { products = x; draw(); attachListeners(); }) .catch(() => { const container = document.querySelector('#cart-list'); container.innerHTML = '

Unable to load catalog. Please try again later.

'; }); // Header & footer scripts (function(){ const mobileBtn = document.getElementById('mobile-menu-toggle'); const mobileNav = document.getElementById('mobile-nav'); if(mobileBtn && mobileNav){ mobileBtn.addEventListener('click', () => { mobileNav.classList.toggle('hidden'); }); } const themeBtn = document.getElementById('theme-toggle'); const htmlEl = document.documentElement; const savedTheme = localStorage.getItem('xevora-theme'); if(savedTheme === 'dark'){ htmlEl.classList.add('dark'); if(themeBtn) themeBtn.textContent = '☀︎'; } if(themeBtn){ themeBtn.addEventListener('click', () => { if(htmlEl.classList.contains('dark')){ htmlEl.classList.remove('dark'); localStorage.setItem('xevora-theme', 'light'); themeBtn.textContent = '◐'; } else { htmlEl.classList.add('dark'); localStorage.setItem('xevora-theme', 'dark'); themeBtn.textContent = '☀︎'; } }); } document.querySelectorAll('[data-open-modal]').forEach(btn => { btn.addEventListener('click', () => { const modalId = btn.getAttribute('data-open-modal'); const modal = document.getElementById(modalId); if(modal) modal.showModal(); }); }); })(); (function(){ const banner = document.getElementById('cookie-banner'); const acceptBtn = document.getElementById('accept-cookies'); const consentKey = 'xevora-cookie-consent'; if(banner){ if(!localStorage.getItem(consentKey)){ banner.classList.remove('hidden'); banner.classList.add('flex'); } } if(acceptBtn && banner){ acceptBtn.addEventListener('click', () => { localStorage.setItem(consentKey, 'accepted'); banner.classList.remove('flex'); banner.classList.add('hidden'); }); } })();