/* Standings — season points grid. Drivers & Constructors, season selector. */ const { useState: useSt, useMemo: useStMemo, useEffect: useStEffect } = React; const CELL_MODE_KEY = "fd.standings.cellMode"; function loadCellMode() { try { return localStorage.getItem(CELL_MODE_KEY) === "position" ? "position" : "points"; } catch { return "points"; } } function Segmented({ value, options, onChange }) { return (
{options.map(o => { const on = o.value === value; return ( ); })}
); } function Legend() { const items = [["Win", "var(--accent)"], ["Podium", "color-mix(in srgb, var(--ink) 22%, transparent)"], ["Pole (P)", "var(--warn)"], ["Fastest Lap (F)", "#a855f7"], ["DNF", "transparent"]]; return (
{items.map(([lab, c]) => ( {lab} ))}
); } function cellStyle(o, mode) { // o = {pts, pos, dnf}; mode = "points" | "position" (controls displayed text only) let bg = "transparent", color = "var(--ink-2)", weight = 500; if (o.dnf) return { bg, color: "var(--ink-4)", weight, txt: "DNF", small: true }; if (o.pos === 1) { bg = "color-mix(in srgb, var(--accent) 26%, transparent)"; color = "var(--ink)"; weight = 800; } else if (o.pos <= 3) { bg = "color-mix(in srgb, var(--ink) 9%, transparent)"; color = "var(--ink)"; weight = 700; } else if (o.pts > 0) { color = "var(--ink)"; weight = 600; } const txt = mode === "position" ? (o.pos ? "P" + o.pos : "–") : (o.pts > 0 ? o.pts : "–"); return { bg, color, weight, txt, small: false }; } function DriversGrid({ sid, mode }) { const FD = window.FD; const sd = FD.seasonData[sid]; const rounds = sd.byRound; const grid = {}; rounds.forEach(rd => rd.order.forEach(o => { (grid[o.num] = grid[o.num] || {})[rd.rd] = { pts: o.pts, pos: o.pos, dnf: o.dnf, pole: rd.pole === o.num, fastest: !!o.fastest }; })); const isS6 = sid === FD.currentSid; return (
{rounds.map(rd => ( ))} {sd.ranked.map((row, i) => { const dr = FD.driverByNum[row.num]; const team = FD.teamById[FD.driverTeam(row.num, sid)]; return ( location.href = `driver.html?d=${row.num}`} onMouseEnter={e => e.currentTarget.style.background = "color-mix(in srgb, var(--ink) 4%, transparent)"} onMouseLeave={e => e.currentTarget.style.background = "transparent"}> {rounds.map(rd => { const o = grid[row.num][rd.rd]; if (!o) return ; const cs = cellStyle(o, mode); return ( ); })} ); })}
# Driver
{isS6 && } R{rd.rd}
Pts
{i + 1}
{dr.username}
{dr.code} · {team.code} · #{dr.num}
·
{cs.txt} {o.pole && P} {o.fastest && F}
); } function ConstructorsGrid({ sid }) { const FD = window.FD; const sd = FD.seasonData[sid]; const rounds = sd.byRound; const standings = FD.teamStandings(sid).filter(t => t.roster.length); // team points per round const teamRound = (teamId, rd) => rd.order.filter(o => FD.driverTeam(o.num, sid) === teamId).reduce((a, o) => a + o.pts, 0); const isS6 = sid === FD.currentSid; return (
{rounds.map(rd => ( ))} {standings.map((t, i) => ( location.href = `team.html?t=${t.id}`} onMouseEnter={e => e.currentTarget.style.background = "color-mix(in srgb, var(--ink) 4%, transparent)"} onMouseLeave={e => e.currentTarget.style.background = "transparent"}> {rounds.map(rd => { const pts = teamRound(t.id, rd); return ( ); })} ))}
# Constructor
{isS6 && }R{rd.rd}
Pts
{i + 1}
{t.name} {t.code}
0 ? "var(--ink)" : "var(--ink-4)", fontWeight: pts >= 25 ? 700 : 500 }}>{pts > 0 ? pts : "–"}
); } const thBase = { fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--ink-4)", fontWeight: 500, padding: "13px 8px" }; const tdBase = { padding: "9px 8px", verticalAlign: "middle" }; function StandingsPage() { const FD = window.FD; const [sid, setSid] = useSt(FD.currentSid); const [tab, setTab] = useSt("drivers"); const [cellMode, setCellMode] = useSt(loadCellMode); useStEffect(() => { try { localStorage.setItem(CELL_MODE_KEY, cellMode); } catch {} }, [cellMode]); const season = FD.seasons.find(s => s.id === sid); return (
({ value: s.id, label: s.label.replace("Season ", "S") }))} /> {tab === "drivers" && }
} />
{tab === "drivers" ? : }

Each cell shows {tab === "drivers" && cellMode === "position" ? "the finishing position" : "points scored"} that round. {season.status === "live" ? `${season.rounds - season.completed} rounds remain this season.` : "Season complete."} Click any row for the full profile.

); } ReactDOM.createRoot(document.getElementById("root")).render();