/* soccerarena.ai — mobile: collapsed single-column card stack. */ const { useState: useSt, useEffect: useEf } = React; function preLabel(startDate) { const days = Math.ceil((new Date(startDate + 'T00:00:00Z') - Date.now()) / 86400000); return days > 0 ? `T-${days}` : 'PRE-TOURNAMENT'; } function useMobileSecondsUntil(isoTarget) { const target = isoTarget ? new Date(isoTarget).getTime() : 0; const secs = () => (target ? Math.max(0, Math.round((target - Date.now()) / 1000)) : 0); const [s, setS] = useSt(secs); useEf(() => { if (!target) return; const id = setInterval(() => setS(secs), 1000); return () => clearInterval(id); }, [target]); return s; } function MobilePreTournamentOverlay({ kickoffAt, startDate }) { const s = useMobileSecondsUntil(kickoffAt); const days = Math.floor(s / 86400); const hrs = Math.floor((s % 86400) / 3600); const mins = Math.floor((s % 3600) / 60); const sec = s % 60; const pad = (n) => String(n).padStart(2, '0'); const dateLabel = startDate ? new Date(startDate + 'T00:00:00Z').toLocaleDateString('en-US', { month: 'short', day: 'numeric', timeZone: 'UTC' }) : ''; return (
SCORING OPENS IN
{[ { n: pad(days), label: 'DAYS' }, { n: pad(hrs), label: 'HRS' }, { n: pad(mins), label: 'MIN' }, { n: pad(sec), label: 'SEC' }, ].map(({ n, label }, i) => ( {i > 0 && ( : )}
{n} {label}
))}
First match · {dateLabel}
); } function MobileHeader({ countdown }) { const t = ARENA.tournament; const pct = t.dayTotal > 0 ? Math.min(100, (t.dayCurrent / t.dayTotal) * 100) : 0; const phaseShort = t.dayCurrent > 0 ? `D${t.dayCurrent}/${t.dayTotal}` : preLabel(t.startDate); return (
footballarena .ai
{phaseShort}
{t.phase.toUpperCase()} Next in {countdown}
); } function MobileModelCard({ m, rank }) { const isLeader = rank === 1; const cardStyle = { background: isLeader ? SA.surface : SA.turf2, border: `1px solid ${SA.line2}`, borderLeftWidth: 2, borderLeftColor: isLeader ? SA.lime : SA.line2, }; return (
{rank}
{m.name} {m.origin}
{m.provider}
{m.total}
TOTAL
PICK {m.pick.flag} {m.pick.name} {m.flipped && }
= 0 ? SA.lime : SA.orange} />
); } function MobileConsensus() { if (!ARENA.consensus || ARENA.consensus.length === 0) return null; return (
TODAY'S CONSENSUS · {ARENA.models.length} MODELS
{ARENA.consensus.map((c, i) => (
{c.emoji} {c.label.toUpperCase()}
{c.flag && {c.flag}} {c.value}
{c.share}
))}
); } function MobileQuickNav() { const links = [ { href: 'odds.html', label: 'AI Odds' }, { href: 'fixtures.html', label: 'Fixtures' }, { href: 'methodology.html', label: 'Methodology' }, ]; return (
{links.map(l => ( {l.label} ))}
); } function MobileApp({ countdown }) { const models = ARENA.models || []; const rows = [...models].sort((a, b) => b.total - a.total); const t = ARENA.tournament; const isPreTournament = t.dayCurrent === 0; const visibleRows = isPreTournament ? rows.slice(0, 4) : rows; return (

Leaderboard

{models.length} MODELS
{visibleRows.length === 0 ? (
Predictions will appear once the tournament begins.
) : (
{visibleRows.map((m, i) => )}
)}
{isPreTournament && ( )}
); } Object.assign(window, { MobileApp });