TerraLance

Your quiet shortlist

Fallows

Keep the courses you want to revisit close at hand. Saved items remain in this browser until you remove them.

Loading saved courses.

Find more courses Open cart
`; const footerHTML = ` `; document.getElementById('site-header').innerHTML = headerHTML; document.getElementById('site-footer').innerHTML = footerHTML; const toggle = document.getElementById('mobile-menu-toggle'); const nav = document.getElementById('main-navigation'); toggle.addEventListener('click', () => { const expanded = toggle.getAttribute('aria-expanded') === 'true'; toggle.setAttribute('aria-expanded', !expanded); nav.classList.toggle('hidden'); nav.classList.toggle('flex'); nav.classList.toggle('flex-col'); nav.classList.toggle('w-full'); nav.classList.toggle('mt-4'); nav.classList.toggle('lg:flex'); }); const themeBtn = document.getElementById('theme-toggle'); function applyTheme(isDark) { if (isDark) { document.documentElement.style.setProperty('--page-bg', '#24332C'); document.body.style.background = '#24332C'; document.body.style.color = '#F7F1E8'; themeBtn.textContent = '☽'; } else { document.documentElement.style.setProperty('--page-bg', '#F7F1E8'); document.body.style.background = '#F7F1E8'; document.body.style.color = '#24332C'; themeBtn.textContent = '☀︎'; } localStorage.setItem('tl-theme', isDark ? 'dark' : 'light'); } themeBtn.addEventListener('click', () => { const current = localStorage.getItem('tl-theme') === 'dark'; applyTheme(!current); }); const savedTheme = localStorage.getItem('tl-theme'); applyTheme(savedTheme === 'dark'); const modal = document.getElementById('auth-modal'); const authTitle = document.getElementById('auth-title'); const authContent = document.getElementById('auth-content'); const closeAuth = document.getElementById('close-auth'); document.getElementById('login-trigger').addEventListener('click', () => showAuth('login')); document.getElementById('register-trigger').addEventListener('click', () => showAuth('register')); closeAuth.addEventListener('click', () => { modal.classList.remove('grid'); modal.classList.add('hidden'); }); function showAuth(type) { modal.classList.remove('hidden'); modal.classList.add('grid'); if (type === 'login') { authTitle.textContent = 'Log in to TerraLance'; authContent.innerHTML = `
`; } else { authTitle.textContent = 'Create your account'; authContent.innerHTML = `
`; } } (function() { const banner = document.getElementById('cookie-banner'); const acceptBtn = document.getElementById('accept-cookies'); const consentKey = 'terralance-cookie-consent'; if (!localStorage.getItem(consentKey)) { banner.classList.remove('hidden'); } acceptBtn.addEventListener('click', () => { localStorage.setItem(consentKey, 'true'); banner.classList.add('hidden'); }); })(); async function loadFallows() { const status = document.getElementById('fallows-status'); const grid = document.getElementById('fallows-grid'); const ids = JSON.parse(localStorage.getItem('terralance-fallows') || '[]'); if (ids.length === 0) { status.textContent = 'No saved courses yet.'; grid.innerHTML = ''; return; } try { const res = await fetch('./catalog.json'); const catalog = await res.json(); const saved = catalog.filter(item => ids.includes(item.id)); if (saved.length === 0) { status.textContent = 'Saved items not found in current catalog.'; grid.innerHTML = ''; return; } status.textContent = `${saved.length} saved course${saved.length > 1 ? 's' : ''}`; grid.innerHTML = ''; saved.forEach(course => { const card = document.createElement('div'); card.className = 'rounded-3xl border border-[#D8C7B5] bg-white p-6'; card.innerHTML = `

${course.title}

${course.description}

${course.duration}
`; const removeBtn = card.querySelector('button'); removeBtn.addEventListener('click', () => { const newIds = JSON.parse(localStorage.getItem('terralance-fallows') || '[]').filter(id => id !== course.id); localStorage.setItem('terralance-fallows', JSON.stringify(newIds)); loadFallows(); }); grid.appendChild(card); }); } catch (e) { status.textContent = 'Unable to load saved courses.'; grid.innerHTML = ''; } } loadFallows();