365-Day Plan

Search, filter by topic, and click a day to view its verse, challenge, and reflection.

Showing 0 / 0 Selected: —

Pick a day

Challenge

Select a day on the right to view details.

Reflection

—

Your last selected day is saved in this browser.
    Tip: use Search + Topic filter to narrow, then click a day.
    \n" + "OR\n" + "2) Add plan.json next to index.html (same folder)\n\n" + "Details: " + e.message ); } } function initUI(){ $("countTotal").textContent = allDays.length; renderTopicOptions(allDays); renderDayJump(allDays); applyFilters(); renderList(allDays); // restore last selected day let last = null; try { last = parseInt(localStorage.getItem(LOCAL_KEY), 10); } catch {} if (last && allDays.some(d => d.day === last)) selectDay(last, false); // events $("search").addEventListener("input", applyFilters); $("topicFilter").addEventListener("change", applyFilters); $("dayJump").addEventListener("change", () => { const val = parseInt($("dayJump").value, 10); if (val) selectDay(val, true); }); $("prevBtn").addEventListener("click", () => move(-1)); $("nextBtn").addEventListener("click", () => move(1)); $("randomBtn").addEventListener("click", pickRandom); $("todayBtn").addEventListener("click", selectToday); $("clearBtn").addEventListener("click", clearFilters); // keyboard nav window.addEventListener("keydown", (e) => { if (e.key === "ArrowLeft") move(-1); if (e.key === "ArrowRight") move(1); if (e.key === "/" && document.activeElement !== $("search")) { e.preventDefault(); $("search").focus(); } }); } (async function boot(){ try{ const data = await loadPlan(); // sanitize and sort allDays = data .map(d => ({ day: Number(d.day), reference: d.reference, topic: d.topic, challenge: d.challenge, reflection: d.reflection })) .filter(d => Number.isFinite(d.day)) .sort((a,b)=>a.day-b.day); initUI(); } catch (e){ showError(e.message || String(e)); } })();