statsEsc = window.statsEsc
lbToday = { const d = new Date(); return d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0") }
viewof lbSport = Inputs.radio([["Football", "football"], ["AFL", "afl"]], { label: "Sport", format: x => x[0], value: ["Football", "football"] })
viewof lbBoard = Inputs.radio([["Today", "today"], ["All-time", "alltime"], ["Streak", "streak"]], { label: "Board", format: x => x[0], value: ["Today", "today"] })
lbData = {
const base = (window.WORKER_BASE_URL || "").replace(/\/$/, "")
if (!base) return null
const board = lbBoard[1], sport = lbSport[1]
const qs = board === "today" ? `sport=${sport}&day=${lbToday}&board=today` : `sport=${sport}&board=${board}`
try {
const r = await fetch(`${base}/api/run-score?${qs}`)
if (!r.ok) { console.warn("[run-score] HTTP " + r.status, await r.text().catch(() => "")); return null }
return (await r.json()).scores || []
}
catch (e) { console.warn("[leaderboard] fetch failed:", e); return null }
}
{
const scores = lbData
if (scores == null) return html`<p class="text-muted">Leaderboard is offline right now — try again shortly.</p>`
if (!scores.length) return html`<p class="text-muted">No runs yet${lbBoard[1] === "today" ? " today" : ""} — <a href="games.html">play the Daily Run</a> and you'll top the board.</p>`
const isStreak = lbBoard[1] === "streak"
const rows = scores.map((s, i) => {
const val = isStreak ? `${s.streak} day${s.streak === 1 ? "" : "s"}` : `${s.depth}/8`
const days = (s.days != null && !isStreak) ? `<span class="lb-days">${s.days} day${s.days === 1 ? "" : "s"}</span>` : (isStreak ? `<span class="lb-days">${s.days} total</span>` : "")
const medal = i < 3 ? ` lb-medal-${i + 1}` : ""
return `<div class="lb-row${medal}"><span class="lb-rank">${i + 1}</span><span class="lb-name">${statsEsc(s.name)}</span>${days}<span class="lb-val">${val}</span></div>`
}).join("")
const div = document.createElement("div"); div.className = "lb-table"; div.innerHTML = rows
return div
}