/* 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 (
{[
{ 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 (
);
}
function MobileConsensus() {
if (!ARENA.consensus || ARENA.consensus.length === 0) return null;
return (
TODAY'S CONSENSUS · {ARENA.models.length} MODELS
);
}
function MobileQuickNav() {
const links = [
{ href: 'odds.html', label: 'AI Odds' },
{ href: 'fixtures.html', label: 'Fixtures' },
{ href: 'methodology.html', label: 'Methodology' },
];
return (
);
}
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 });