// ════════════════════════════════════════════════════════════════════════════
// UR2D STANDINGS — BROADCAST OVERHAUL (F1-TV-graphic inspired)
// Same data architecture as before: useStandings(league, seasonId) + getSeasons.
// Loads AFTER ur2d-pages.jsx (uses UR_TEAM_LOGO, getDriverFlag, FlagSvg) and
// BEFORE ur2d-app.jsx (which renders URStandingsBroadcast).
// ════════════════════════════════════════════════════════════════════════════

const URSB_SLATE = COLORS.slate;

// Broadcast title with thick red rule underneath.
const URSBTitle = ({ children, action }) =>
<div>
    <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 20, minHeight: 40 }}>
      <h2 style={{ margin: 0, minWidth: 0, fontFamily: 'Archivo', fontWeight: 900, fontSize: 'clamp(24px, 2.4vw, 42px)', letterSpacing: '-0.02em', textTransform: 'uppercase', color: COLORS.text, lineHeight: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{children}</h2>
      {action}
    </div>
    <div style={{ height: 4, background: COLORS.red, marginTop: 14 }}></div>
  </div>;

const URSBMatrixButton = () =>
<a href="#matrix" onClick={(e) => { if (window.fdGo) { e.preventDefault(); window.fdGo('matrix'); } }} style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '10px 16px', border: `1px solid ${COLORS.red}`, color: COLORS.text, background: 'rgba(225,6,0,0.1)', fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase', textDecoration: 'none', whiteSpace: 'nowrap', flexShrink: 0 }}>
    Full Race Matrix <span aria-hidden style={{ color: COLORS.red }}>→</span>
  </a>;


// Disputed value: the league's Mega Table and the results database disagree (ur2d-megacheck.jsx). Hover for both numbers.
const urFmtPts = (v) => (v == null ? 'no entry' : String(Math.round(v * 100) / 100));
const URSBDisputed = ({ v, onPlate }) => {
  const c = onPlate ? '#8A5A00' : '#F2B83A';
  const label = v ? `Disputed: Mega Table ${urFmtPts(v.mt)} · results database ${urFmtPts(v.db)}` : undefined;
  return <span title={label} aria-label={label} aria-hidden={label ? undefined : 'true'} style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 18, height: 18, borderRadius: 999, border: `1.5px solid ${c}`, color: c, fontFamily: 'JetBrains Mono', fontSize: 11, fontWeight: 700, lineHeight: 1, flexShrink: 0, cursor: label ? 'help' : 'default' }}>≠</span>;
};
const URSBDisputedNote = ({ rows }) => {
  const list = (rows || []).filter((r) => r.disputed);
  if (!list.length) return null;
  const dbShown = list.some((r) => r.disputed.shown === 'db' && r.disputed.mt != null);
  return (
    <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10, padding: '14px 18px 0', fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.04em', lineHeight: 1.6, color: COLORS.textMute }}>
      <URSBDisputed v={null} />
      <span>{list.length} disputed value{list.length > 1 ? 's' : ''}: the league's Mega Table and the results database disagree. Hover a ≠ for both numbers. {dbShown ? 'The Mega Table isn’t finished for this season, so database values are shown.' : 'Mega Table values are shown.'}</span>
    </div>);
};

// One drivers-table row, broadcast style: P1 = white plate w/ dark text.
const URSBDriverRow = ({ d, team, showTeam, independentTeams }) => {
  const isP1 = d.pos === 1;
  const top3 = d.pos <= 3;
  const fg = isP1 ? COLORS.plateInk : COLORS.text;
  const isIndependent = !team && independentTeams && independentTeams.length > 0;
  const cols = showTeam ? '46px 44px minmax(110px, 1.2fr) 106px minmax(90px, 1fr)' : '46px 44px minmax(110px, 1fr) 110px';
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: cols, gap: 10, alignItems: 'center',
      padding: '0 18px', height: isP1 ? 62 : 54,
      background: isP1 ? COLORS.plate : top3 ? 'rgba(255,255,255,0.075)' : 'rgba(255,255,255,0.028)',
      borderBottom: '1px solid rgba(255,255,255,0.05)',
      marginBottom: isP1 ? 6 : 0
    }}>
      <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: isP1 ? 26 : 22, color: fg, fontVariantNumeric: 'tabular-nums', textAlign: 'center' }}>{d.pos}</span>
      <span style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <FlagSvg kind={(d.country || getDriverFlag(d.name)) || null} w={30} h={20} radius={2} />
      </span>
      <span style={{ display: 'flex', alignItems: 'baseline', gap: 8, overflow: 'hidden' }}>
        <span style={{ fontFamily: 'Archivo', fontWeight: 800, fontSize: isP1 ? 22 : 19, letterSpacing: '0.01em', textTransform: 'uppercase', color: fg, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.name}</span>
        {d.carNumber != null && <span style={{ fontFamily: 'JetBrains Mono', fontWeight: 700, fontSize: isP1 ? 13 : 11, color: isP1 ? 'rgba(11,11,13,0.40)' : 'rgba(255,255,255,0.28)', fontVariantNumeric: 'tabular-nums', flexShrink: 0, letterSpacing: '0.04em' }}>{d.carNumber}</span>}
      </span>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: 'Archivo', fontWeight: 900, fontSize: isP1 ? 24 : 20, color: fg, fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap' }}>{d.pts}{d.disputed && <URSBDisputed v={d.disputed} onPlate={isP1} />}</span>
      {showTeam &&
      <span style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
          {isIndependent ?
        <React.Fragment>
              <span style={{ display: 'flex', alignItems: 'center', gap: 6, flexShrink: 0 }}>
                {independentTeams.map((short, i) => UR_TEAM_LOGO[short] &&
              <React.Fragment key={short}>
                    {i > 0 && <span style={{ fontFamily: 'Archivo', fontSize: 13, color: isP1 ? 'rgba(11,11,13,0.28)' : 'rgba(255,255,255,0.22)', fontWeight: 400 }}>/</span>}
                    <img src={urTeamLogo(short, isP1)} alt={short} style={{ height: 26, width: 'auto', maxWidth: 34, objectFit: 'contain', filter: UR_TEAM_LOGO_DARK.has(short) ? 'brightness(0.4)' : 'none', opacity: 0.85 }} />
                  </React.Fragment>
              )}
              </span>
              <span style={{ fontFamily: 'Archivo', fontWeight: 800, fontSize: 15, letterSpacing: '0.04em', textTransform: 'uppercase', color: isP1 ? COLORS.plateMute : '#D6D6D6', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>Independent</span>
            </React.Fragment> :

        <React.Fragment>
              {team && UR_TEAM_LOGO[team.short] &&
          <img src={urTeamLogo(team.short, isP1)} alt={team.short} style={{ height: 36, width: 'auto', maxWidth: 54, objectFit: 'contain', filter: UR_TEAM_LOGO_DARK.has(team.short) ? 'brightness(0.4)' : 'none' }} />
          }
              <span style={{ fontFamily: 'Archivo', fontWeight: 800, fontSize: 15, letterSpacing: '0.04em', textTransform: 'uppercase', color: team ? isP1 ? COLORS.plateInk : team.color : isP1 ? COLORS.plateMute : COLORS.textDim, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{team ? team.name : '—'}</span>
            </React.Fragment>
        }
        </span>
      }
    </div>);

};

// One constructors-table row.
const URSBTeamRow = ({ t }) => {
  const isP1 = t.pos === 1;
  const top3 = t.pos <= 3;
  const fg = isP1 ? COLORS.plateInk : COLORS.text;
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: '56px 44px minmax(0, 1fr) 110px', gap: 12, alignItems: 'center',
      padding: '0 18px', height: isP1 ? 62 : 54,
      background: isP1 ? COLORS.plate : top3 ? 'rgba(255,255,255,0.075)' : 'rgba(255,255,255,0.028)',
      borderBottom: '1px solid rgba(255,255,255,0.05)',
      marginBottom: isP1 ? 6 : 0
    }}>
      <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: isP1 ? 26 : 22, color: fg, fontVariantNumeric: 'tabular-nums', textAlign: 'center' }}>{t.pos}</span>
      <span style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: "44px" }}>
        {UR_TEAM_LOGO[t.short] &&
        <span style={{ borderRadius: 5, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 3, height: "44px", width: "44px", opacity: "1", color: "rgb(250, 250, 250)", background: isP1 ? "rgba(11,11,13,0.9)" : "rgba(255, 255, 255, 0)" }}>
            <img src={UR_TEAM_LOGO[t.short]} alt={t.short} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain', filter: UR_TEAM_LOGO_DARK.has(t.short) ? 'brightness(0.4)' : 'none', width: "44px", height: "44px" }} />
          </span>
        }
      </span>
      <span style={{ display: 'flex', alignItems: 'baseline', gap: 12, minWidth: 0 }}>
        <span style={{ fontFamily: 'Archivo', fontWeight: 800, fontSize: isP1 ? 22 : 19, textTransform: 'uppercase', color: fg, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{t.name}</span>
        <span style={{ fontFamily: 'JetBrains Mono', fontSize: 11, fontWeight: 700, letterSpacing: '0.18em', color: isP1 ? COLORS.plateMute : t.color }}>{t.short}</span>
      </span>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: 'Archivo', fontWeight: 900, fontSize: isP1 ? 24 : 20, color: fg, fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap' }}>{t.pts}{t.disputed && <URSBDisputed v={t.disputed} onPlate={isP1} />}</span>
    </div>);

};

// RIGHT PANEL — trophy cabinet glyphs (P1/P2/P3 breakdown)
const URSBTrophyCabinet = ({ podiums = [], league, seasonLabel }) => {
  if (!podiums.length) return null;
  const byPos = { 1: [], 2: [], 3: [] };
  podiums.forEach(p => { if (byPos[p.pos]) byPos[p.pos].push(p); });
  const labels = { 1: '1ST', 2: '2ND', 3: '3RD' };
  return (
    <div style={{ marginTop: 14, padding: '10px 14px', background: 'rgba(255,255,255,0.04)', borderRadius: 8, display: 'flex', flexDirection: 'column', gap: 10 }}>
      {[1, 2, 3].map(pos => {
        const entries = byPos[pos];
        if (!entries.length) return null;
        return (
          <div key={pos} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ fontFamily: 'JetBrains Mono', fontWeight: 700, fontSize: 9, letterSpacing: '0.1em', color: 'rgba(255,255,255,0.35)', width: 26, flexShrink: 0 }}>{labels[pos]}</span>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
              {entries.map((p, i) => typeof URPodiumGlyph !== 'undefined' ? <URPodiumGlyph key={i} round={p.round} pos={pos} league={league} seasonLabel={seasonLabel} /> : null)}
            </div>
          </div>
        );
      })}
    </div>
  );
};

// RIGHT PANEL — season-stats strip (wins / podiums / FL / poles / +/-), same chrome as the trophy cabinet.
const URSBSeasonStats = ({ stats }) => {
  if (!stats) return null;
  const fmt = (v) => {
    if (v == null) return '—';
    if (v > 0) return `+${v}`;
    return `${v}`;
  };
  const items = [
    { label: 'WINS', value: stats.wins != null ? stats.wins : 0 },
    { label: 'PODS', value: stats.podiums != null ? stats.podiums : 0 },
    { label: 'FL', value: stats.fastestLaps != null ? stats.fastestLaps : 0 },
    { label: 'POLES', value: stats.poles != null ? stats.poles : 0 },
    { label: '+/-', value: fmt(stats.posGained) }
  ];
  return (
    <div style={{ marginTop: 14, padding: '10px 14px', background: 'rgba(255,255,255,0.04)', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 4 }}>
      {items.map((it, i) =>
      <div key={i} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3, flex: 1 }}>
          <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 17, color: COLORS.text, fontVariantNumeric: 'tabular-nums' }}>{it.value}</span>
          <span style={{ fontFamily: 'JetBrains Mono', fontWeight: 700, fontSize: 8, letterSpacing: '0.08em', color: 'rgba(255,255,255,0.35)', textAlign: 'center' }}>{it.label}</span>
        </div>
      )}
    </div>);

};

// RIGHT PANEL — championship leader spotlight.
const URSBLeaderPanel = ({ view, leader, leaderTeam, league, trophies, seasonStats, calSeasonLabel }) => {
  if (!leader) return null;
  const isDrivers = view === 'drivers';
  const person = isDrivers && typeof resolvePerson !== 'undefined' ? resolvePerson(leader.name) : null;
  const ghost = isDrivers
    ? (leader.carNumber != null ? leader.carNumber
      : person && person.carNumber != null ? person.carNumber
      : leader.pos)
    : leader.pts;
  const leagueAccent = (typeof LEAGUE_BY_ID !== 'undefined' && LEAGUE_BY_ID[league]) ? LEAGUE_BY_ID[league].accent : COLORS.red;
  const accent = leaderTeam ? leaderTeam.color : (!isDrivers && leader && leader.color) ? leader.color : leagueAccent;
  const slotId = isDrivers ? `ur-drv-${leader.name.toLowerCase().replace(/[^a-z0-9]/g, '-')}` : null;
  return (
    <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', minHeight: isDrivers ? 520 : 0 }}>
      <URSBTitle>Leader</URSBTitle>
      <div style={{ position: 'relative', flex: isDrivers ? 1 : '0 0 auto', marginTop: 18, overflow: 'hidden', minHeight: isDrivers ? 460 : 0 }}>

        {isDrivers ?
        <React.Fragment>
            {/* LAYER 1 — giant number watermark: dark, desaturated, behind everything */}
            <div aria-hidden style={{
            position: 'absolute', left: '50%', top: -8, transform: 'translateX(-50%)',
            fontFamily: 'Archivo', fontWeight: 900, fontSize: 'clamp(200px, 19vw, 340px)', lineHeight: 0.82,
            letterSpacing: '-0.06em', color: accent, opacity: 0.38, pointerEvents: 'none',
            fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap', zIndex: 1
          }}>{ghost}</div>

            {/* LAYER 2 — dark vignette scrim, separates car from number by brightness */}
            <div aria-hidden style={{
            position: 'absolute', inset: 0, zIndex: 2, pointerEvents: 'none',
            background: 'radial-gradient(ellipse 72% 58% at 50% 54%, rgba(6,6,10,0.78) 0%, rgba(6,6,10,0.28) 62%, transparent 84%)'
          }}></div>

            {/* LAYER 3 — livery / portrait, above the scrim */}
            <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 3, pointerEvents: 'none' }}>
              {(() => {
              // Season-specific only (user 2026-10-05): the driver's / team's livery for THIS season — never another season's car
              // and no generic default car. Nothing → the portrait slot.
              const fallbackSrc = leader.livery || leaderTeam && leaderTeam.livery || null;
              return fallbackSrc ?
              <img src={fallbackSrc} alt={leaderTeam ? leaderTeam.short + ' livery' : league.toUpperCase() + ' car'} style={{ width: 'clamp(260px, 42vh, 420px)', height: 'auto', transform: 'rotate(270deg)', transformOrigin: 'center', filter: 'drop-shadow(0 4px 28px rgba(0,0,0,0.85))', imageRendering: 'auto' }} /> :
              <URImageSlot id={slotId} placeholder={`${leader.name} portrait`} shape="rect" style={{ width: '100%', height: '100%' }} />;
            })()}
            </div>

            {/* LAYER 4 — name + team at the bottom; accent color lives here only */}
            <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 4, textAlign: 'center', paddingBottom: 14, paddingTop: 60, background: `linear-gradient(to top, ${COLORS.bg || 'rgba(8,8,10,0.97)'} 18%, rgba(8,8,10,0.82) 46%, transparent)` }}>
              <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 'clamp(30px, 3vw, 46px)', letterSpacing: '-0.02em', textTransform: 'uppercase', color: accent, lineHeight: 1 }}>{leader.name}</div>
              <div style={{ marginTop: 10, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10 }}>
                {leaderTeam && UR_TEAM_LOGO[leaderTeam.short] &&
              <span style={{ width: 24, height: 24, borderRadius: 5, background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 3 }}>
                    <img src={urTeamLogo(leaderTeam.short, true)} alt={leaderTeam.short} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain', filter: UR_TEAM_LOGO_DARK.has(leaderTeam.short) ? 'brightness(0.4)' : 'none' }} />
                  </span>
              }
                <span style={{ fontFamily: 'JetBrains Mono', fontSize: 12, letterSpacing: '0.3em', textTransform: 'uppercase', color: COLORS.textMute }}>{leaderTeam ? leaderTeam.name : `${leader.pts} pts`}</span>
              </div>
              </div>
          </React.Fragment> :

        <div style={{ position: 'relative', zIndex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-end', paddingBottom: 4 }}>
            {UR_TEAM_LOGO[leader.short] &&
          <div style={{ width: 190, height: 190, borderRadius: 22, background: `radial-gradient(circle at center, rgba(255,255,255,0.18) 0%, ${accent}44 100%)`, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 26, boxShadow: `0 0 0 1.5px ${accent}88, 0 0 40px ${accent}55, 0 14px 60px rgba(0,0,0,0.5)` }}>
                <img src={UR_TEAM_LOGO[leader.short]} alt={leader.name} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }} />
              </div>
          }
            <div style={{ textAlign: 'center', paddingTop: 24 }}>
              <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 'clamp(28px, 2.6vw, 40px)', letterSpacing: '-0.02em', textTransform: 'uppercase', color: accent, lineHeight: 1 }}>{leader.name}</div>
              <div style={{ marginTop: 10, fontFamily: 'JetBrains Mono', fontSize: 12, letterSpacing: '0.3em', textTransform: 'uppercase', color: COLORS.textMute }}>{leader.pts} points</div>
            </div>
          </div>
        }
      </div>
      <URSBSeasonStats stats={seasonStats} />
      {trophies && trophies.length > 0 && <URSBTrophyCabinet podiums={trophies} league={league} seasonLabel={calSeasonLabel} />}
    </div>);

};

// ─────────────────────────────────────────────────────────────────────────────
// PAGE
const URStandingsBroadcast = ({ league, setLeague }) => {
  const L = LEAGUE_BY_ID[league];
  const seasons = getSeasons(league);
  const [seasonId, setSeasonId] = useSharedSeason(league);
  // Default = the CURRENT season even before its workbook exists (S26) → shows the loading state.
  const activeId = seasons.some((s) => s.id === seasonId) ? seasonId : ((seasons.find((s) => s.isCurrent) || {}).id || defaultDataSeasonId(seasons));
  const _activeSeason = seasons.find((s) => s.id === activeId);
  const awaitingData = !!(_activeSeason && _activeSeason.isCurrent && !_activeSeason.hasData);
  // Calendar season for round→track resolution. Map by INDEX into the (UL-centric)
  // calendar list, NOT by label — HL/JL/AL labels (S21, S22A…) never match the
  // UL-labelled calendar array and would fall back to the current schedule.
  const calSeasons = typeof getCalendarSeasons !== 'undefined' ? getCalendarSeasons() : [];
  const _seasonIdx = seasons.filter((s) => !s.dbOnly).findIndex((s) => s.id === activeId); // dbOnly archive seasons aren't calendar-aligned
  const calSeasonLabel = (_seasonIdx >= 0 && calSeasons[_seasonIdx]) ? calSeasons[_seasonIdx].id : activeId;
  const data = useStandings(league, activeId);
  const [view, setView] = React.useState('drivers');
  const teamBased = !!(data.teams && data.teams.length);
  const activeView = teamBased && view === 'teams' ? 'teams' : 'drivers';

  const teamByShort = {};
  (data.teams || []).forEach((t) => {teamByShort[t.short] = t;});
  // Independent drivers (not signed to a team) carry team 'IND' — synthesize a
  // display entry so their row is labelled "Independent" instead of a blank dash.
  if (!teamByShort.IND) teamByShort.IND = { short: 'IND', name: 'Independent', color: COLORS.textDim };

  // Emergency-reserve drivers this season: show "Independent" + minilogos of the
  // most recent teams they've raced for (from the roster's stint ledger), instead
  // of a blank team cell — the sheet's lineup section doesn't list ER call-ups.
  const seasonRoster = typeof getRoster !== 'undefined' ? getRoster(league, activeId) : null;
  const erNames = {};
  if (seasonRoster) {
    (seasonRoster.stints || []).filter((s) => s.role === 'emergency-reserve').forEach((s) => {
      const person = seasonRoster.people[s.driver];
      const key = rosterNorm(person ? person.sheetName || person.display || s.driver : s.driver);
      if (key) erNames[key] = true;
    });
  }
  const recentTeamsFor = (name) => {
    if (!seasonRoster) return [];
    const who = typeof resolvePerson !== 'undefined' ? resolvePerson(name) : null;
    const handle = who ? who.handle : null;
    const stints = (seasonRoster.stints || []).filter((s) => s.driver === handle || rosterNorm(s.driver) === rosterNorm(name));
    const seen = [];
    for (let i = stints.length - 1; i >= 0; i--) {
      if (!seen.includes(stints[i].team)) seen.push(stints[i].team);
      if (seen.length >= 2) break;
    }
    return seen;
  };

  // controls — season dropdown + league switcher (compact, broadcast chrome)
  const ctrlH = 40;
  const seasonSel =
  <div style={{ position: 'relative' }}>
      <select value={activeId || ''} onChange={(e) => setSeasonId(e.target.value)} style={{
      appearance: 'none', WebkitAppearance: 'none', height: ctrlH, boxSizing: 'border-box',
      background: 'rgba(255,255,255,0.05)', color: COLORS.text, border: '1px solid rgba(255,255,255,0.12)',
      borderRadius: 0, padding: '0 34px 0 14px', cursor: 'pointer',
      fontFamily: 'Archivo', fontWeight: 800, fontSize: 13, letterSpacing: '0.04em'
    }}>
        {seasons.map((s) => <option key={s.id} value={s.id} style={{ background: COLORS.ink, color: COLORS.text }}>{s.label}{s.hasData ? '' : ' · soon'}</option>)}
      </select>
      <span aria-hidden style={{ position: 'absolute', right: 11, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none', color: COLORS.red, fontSize: 8 }}>▼</span>
    </div>;

  const leagueSwitch =
  <div style={{ display: 'inline-flex', border: '1px solid rgba(255,255,255,0.12)', background: 'rgba(0,0,0,0.4)' }}>
      {LEAGUES.map((Lg, i) => {
      const active = league === Lg.id;
      return (
        <button key={Lg.id} onClick={() => setLeague(Lg.id)} style={{
          all: 'unset', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
          width: 48, height: ctrlH, boxSizing: 'border-box',
          background: active ? 'rgba(255,255,255,0.08)' : 'transparent',
          borderRight: i < LEAGUES.length - 1 ? '1px solid rgba(255,255,255,0.1)' : 'none',
          position: 'relative', transition: 'background .12s ease'
        }}>
            {active && <span style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 2, background: Lg.accent }} />}
            <img src={Lg.logo} alt={Lg.short} style={{ height: 24, width: 24, objectFit: 'contain', display: 'block', opacity: active ? 1 : 0.4, filter: active ? 'none' : 'grayscale(.6)' }} />
          </button>);

    })}
    </div>;

  const viewToggle = teamBased ?
  <div style={{ display: 'inline-flex', border: '1px solid rgba(255,255,255,0.12)' }}>
      {[['drivers', 'Drivers'], ['teams', 'Constructors']].map(([id, label], i) =>
    <button key={id} onClick={() => setView(id)} style={{
      all: 'unset', cursor: 'pointer', padding: '0 18px', height: ctrlH, boxSizing: 'border-box',
      display: 'flex', alignItems: 'center',
      fontFamily: 'JetBrains Mono', fontSize: 11, fontWeight: 700, letterSpacing: '0.22em', textTransform: 'uppercase',
      color: activeView === id ? COLORS.plateInk : COLORS.textMute,
      background: activeView === id ? COLORS.plate : 'transparent',
      borderRight: i === 0 ? '1px solid rgba(255,255,255,0.1)' : 'none'
    }}>{label}</button>
    )}
    </div> :
  null;

  const leader = activeView === 'drivers' ? data.drivers && data.drivers[0] : data.teams && data.teams[0];
  const leaderTeam = activeView === 'drivers' && leader ? teamByShort[leader.team] || null : null;

  // Podium map for trophy cabinet (real P1/P2/P3 breakdown per driver)
  const podiumMap = usePodiumMap(league, data.season && data.season.label);
  const trophies = React.useMemo(() => {
    if (!leader) return null;
    if (activeView === 'drivers') {
      const ps = podiumMap[leader.name] || [];
      if (ps.length) return ps; // [{round, pos}]
      // fallback: synthetic entries from standings aggregates
      const out = [];
      for (let i = 0; i < (leader.wins || 0); i++) out.push({ round: i + 1, pos: 1 });
      const p2p3 = Math.max(0, (leader.podiums || 0) - (leader.wins || 0));
      for (let i = 0; i < p2p3; i++) out.push({ round: (leader.wins || 0) + i + 1, pos: 2 });
      return out;
    }
    // Constructors — aggregate across all team drivers
    const teamDrivers = (data.drivers || []).filter(d => d.team === leader.short);
    let out = [];
    teamDrivers.forEach(d => {
      const ps = podiumMap[d.name] || [];
      if (ps.length) { out = out.concat(ps); }
      else {
        for (let i = 0; i < (d.wins || 0); i++) out.push({ round: i + 1, pos: 1 });
        const p2p3 = Math.max(0, (d.podiums || 0) - (d.wins || 0));
        for (let i = 0; i < p2p3; i++) out.push({ round: (d.wins || 0) + i + 1, pos: 2 });
      }
    });
    return out;
  }, [leader, activeView, podiumMap, data.drivers]);

  // Season-stats strip: raw aggregates already on the standings row (drivers), or
  // summed across a team's drivers (constructors). posGained isn't wired from the
  // live sheets yet — shows '—' until the store carries it.
  const seasonStats = React.useMemo(() => {
    if (!leader) return null;
    if (activeView === 'drivers') {
      return { wins: leader.wins, podiums: leader.podiums, fastestLaps: leader.fastestLaps, poles: leader.poles, posGained: leader.posGained ?? null };
    }
    const teamDrivers = (data.drivers || []).filter((d) => d.team === leader.short);
    if (!teamDrivers.length) return null;
    const sum = (key) => teamDrivers.reduce((acc, d) => acc + (d[key] || 0), 0);
    return { wins: sum('wins'), podiums: sum('podiums'), fastestLaps: sum('fastestLaps'), poles: sum('poles'), posGained: null };
  }, [leader, activeView, data.drivers]);

  return (
    <section data-screen-label="Standings" style={{
      position: 'relative', minHeight: '100vh', overflow: 'hidden',
      background: `${URSB_SLATE} repeating-linear-gradient(115deg, rgba(255,255,255,0.016) 0 90px, transparent 90px 200px)`
    }}>
      {/* faint red glow top-left */}
      <div aria-hidden style={{ position: 'absolute', left: -220, top: -220, width: 640, height: 640, borderRadius: '50%', background: `radial-gradient(circle, ${COLORS.red}22 0%, transparent 62%)`, filter: 'blur(40px)', pointerEvents: 'none' }}></div>

      <div style={{ position: 'relative', padding: '34px 44px 90px' }}>
        {/* Broadcast top strip */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 18, marginBottom: 34, flexWrap: 'wrap' }}>
          <LeagueBadge league={league} height={46} showName={false} />
          <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 19, letterSpacing: '0.06em', textTransform: 'uppercase', color: COLORS.text }}>
            UR2D {L.name} <span style={{ color: COLORS.red }}>· {activeId || ''}</span>
          </span>
          <span style={{ flex: 1 }}></span>
          {viewToggle}
          {seasonSel}
          {leagueSwitch}
        </div>

        {(data.status === 'loading' && !awaitingData) ?
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 20, padding: '120px 0' }}>
            <div style={{ display: 'flex', gap: 8 }}>
              {[0, 1, 2].map((i) => <span key={i} style={{ width: 10, height: 10, background: L.accent, borderRadius: '50%', animation: `ur-pulse 1.2s ease-in-out ${i * 0.2}s infinite` }} />)}
            </div>
            <span style={{ fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.28em', color: COLORS.textMute, textTransform: 'uppercase' }}>Loading live data…</span>
          </div> :
        (awaitingData || !data.drivers.length) ?
        <div style={{ display: 'flex', justifyContent: 'center', padding: '100px 0' }}>
            <div style={{ maxWidth: 560, textAlign: 'center', background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.1)', padding: '64px 48px' }}>
              <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.3em', color: L.accent, textTransform: 'uppercase' }}>◆ {L.short}</div>
              <h3 style={{ margin: '18px 0 0', fontFamily: 'Archivo', fontWeight: 900, fontSize: 40, color: COLORS.text, letterSpacing: '-0.02em' }}>No data yet</h3>
            </div>
          </div> :

        <div className="ursb-grid">
            <style>{`
              .ursb-grid { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 56px; align-items: start; }
              @media (max-width: 1240px) { .ursb-grid { grid-template-columns: minmax(0, 1fr); } }
            `}</style>
            {/* LEFT — championship table */}
            <div>
              <URSBTitle action={<URSBMatrixButton />}>{activeView === 'drivers' ? "Drivers' Championship" : "Constructors' Championship"}</URSBTitle>
              {/* column headers */}
              <div style={{ display: 'grid', gridTemplateColumns: activeView === 'drivers' ? teamBased ? '56px 44px minmax(110px, 1.2fr) 106px minmax(90px, 1fr)' : '56px 44px minmax(110px, 1fr) 110px' : '56px 44px minmax(0, 1fr) 110px', gap: 12, padding: '16px 18px 10px' }}>
                <span style={{ fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.2em', color: COLORS.textMute, textTransform: 'uppercase', textAlign: 'center' }}>Position</span>
                <span></span>
                <span style={{ fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.2em', color: COLORS.textMute, textTransform: 'uppercase' }}>{activeView === 'drivers' ? 'Driver' : 'Constructor'}</span>
                <span style={{ fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.2em', color: COLORS.textMute, textTransform: 'uppercase' }}>Points</span>
                {activeView === 'drivers' && teamBased && <span style={{ fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.2em', color: COLORS.textMute, textTransform: 'uppercase' }}>Team</span>}
              </div>
              {activeView === 'drivers' ?
            data.drivers.map((d) => d.erTeams && d.erTeams.length ?
            <URSBDriverRow key={d.name + d.pos} d={d} team={null} showTeam={teamBased} independentTeams={d.erTeams.slice(0, 2)} /> : // ER-only starts → "Independent" + the teams they drove for
            <URSBDriverRow key={d.name + d.pos} d={d} team={teamByShort[d.team] || null} showTeam={teamBased} independentTeams={!teamByShort[d.team] && erNames[rosterNorm(d.name)] ? recentTeamsFor(d.name) : null} />) :
            data.teams.map((t) => <URSBTeamRow key={t.short} t={t} />)
            }
              <URSBDisputedNote rows={activeView === 'drivers' ? data.drivers : data.teams} />
            </div>

            {/* RIGHT — leader spotlight */}
            <URSBLeaderPanel view={activeView} leader={leader} leaderTeam={leaderTeam} league={league} trophies={trophies} seasonStats={seasonStats} calSeasonLabel={calSeasonLabel} />
          </div>
        }
      </div>
    </section>);

};

Object.assign(window, { URStandingsBroadcast, URSBTitle });