(function() { const $ = (sel) => document.querySelector(sel); const qs = new URLSearchParams(location.search); const targetISO = qs.get("target") || ($("#countdown")?.dataset.target || ""); const showMillis = (qs.get("millis") ?? ($("#countdown")?.dataset.showMillis || "0")) === "1"; const roundedUnit = qs.get("rounded_unit") || ($("#countdown")?.dataset.roundedUnit || "none"); const targetDate = targetISO ? new Date(targetISO) : null; const targetText = $("#targetText"); const statusEl = $("#status"); const msWrap = $("#millisWrap"); // Reflect chosen colors into CSS variables if passed via query const root = document.documentElement; const setVar = (k, v) => { if (v) root.style.setProperty(k, v); }; setVar("--accent", qs.get("accent")); setVar("--radius", (qs.get("radius") || "16") + "px"); setVar("--bg", qs.get("bg")); setVar("--fg", qs.get("fg")); const scheme = qs.get("scheme"); if (scheme) root.setAttribute("data-scheme", scheme); const font = qs.get("font"); if (font) root.style.setProperty("--font", font.includes(" ") ? `"${font}"` : font); if (!targetDate || isNaN(targetDate.valueOf())) { statusEl.textContent = "Invalid or missing target date. Use the Edit link to set one."; return; } targetText.textContent = targetDate.toString(); msWrap.hidden = !showMillis; if (!showMillis && msWrap.parentNode) { msWrap.parentNode.removeChild(msWrap); } function roundToUnit(ms, unit) { if (unit === "none") return ms; const map = { minutes: 60_000, hours: 3_600_000, days: 86_400_000, }; const size = map[unit] || 1; return Math.round(ms / size) * size; } function tick() { const now = new Date(); let diff = targetDate - now; if (roundedUnit !== "none") { diff = roundToUnit(diff, roundedUnit); } if (diff <= 0) { $("#d").textContent = "0"; $("#h").textContent = "0"; $("#m").textContent = "0"; $("#s").textContent = "0"; if (showMillis) $("#ms").textContent = "000"; statusEl.textContent = "🎉 It's time!"; return; } const totalSeconds = Math.floor(diff / 1000); const days = Math.floor(totalSeconds / (3600*24)); const hours = Math.floor((totalSeconds % (3600*24)) / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; const millis = diff % 1000; $("#d").textContent = String(days); $("#h").textContent = String(hours).padStart(2, "0"); $("#m").textContent = String(minutes).padStart(2, "0"); $("#s").textContent = String(seconds).padStart(2, "0"); if (showMillis) $("#ms").textContent = String(millis).padStart(3, "0"); requestAnimationFrame(tick); } // Shareable link const copyBtn = $("#copyLink"); if (copyBtn) { copyBtn.addEventListener("click", async () => { try { await navigator.clipboard.writeText(location.href); copyBtn.textContent = "Link copied!"; setTimeout(() => copyBtn.textContent = "Copy sharable link", 1500); } catch (e) { alert("Copy failed: " + e); } }); } // Start requestAnimationFrame(tick); })();