// UR2D — Home page sections (Nav, Hero, Ticker, Teams, Standings preview, Drivers preview, Calendar preview, Footer)

const URNav = ({ page, setPage, items: navItems }) => {
  const items = navItems || [
  { id: 'home', label: 'Home' },
  { id: 'standings', label: 'Standings' },
  { id: 'calres', label: 'Calendar & Results' },
  { id: 'teamdrv', label: 'Teams' },
  { id: 'champions', label: 'Hall of Champions' },
  { id: 'news', label: 'News' }];

  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 50,
      background: 'rgba(8,8,10,0.86)', backdropFilter: 'blur(14px)',
      borderBottom: `1px solid ${COLORS.hairline}`
    }}>
      <div aria-hidden style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 72, background: 'radial-gradient(130% 100% at 50% 100%, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.05) 40%, transparent 72%)', pointerEvents: 'none', zIndex: 0 }} />
      <div style={{ position: 'relative', zIndex: 1, display: 'flex', alignItems: 'center', padding: '0 28px', height: 88, gap: 20 }}>
        <button onClick={() => setPage(items[0].id)} style={{ all: 'unset', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 14, flexShrink: 0 }}>
          <img src="assets/ul-logo-cropped.png" alt="Ultimate League" style={{ height: 38, width: 'auto', display: 'block' }} />
          <span style={{ width: 1, height: 40, background: COLORS.hairline, display: 'block' }} />
          <span style={{ display: 'flex', flexDirection: 'column', lineHeight: 0.95 }}>
            <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 19, letterSpacing: '0.04em', color: COLORS.text, textTransform: 'uppercase' }}>Ultimate</span>
            <span style={{ fontFamily: 'Archivo', fontWeight: 800, fontSize: 12, letterSpacing: '0.42em', color: COLORS.red, textTransform: 'uppercase', marginTop: 2 }}>RACING</span>
          </span>
        </button>
        <nav style={{ display: 'flex', gap: 0, marginLeft: 10 }}>
          {items.map((it) => {
            const active = page === it.id;
            return (
              <button key={it.id} onClick={() => setPage(it.id)} style={{
                all: 'unset', cursor: 'pointer', padding: '10px 11px', whiteSpace: 'nowrap',
                fontFamily: 'Archivo', fontWeight: 700, fontSize: 12, letterSpacing: '0.12em',
                textTransform: 'uppercase',
                color: active ? COLORS.text : COLORS.textMute,
                position: 'relative'
              }}>
                {it.label}
                {active && <span style={{ position: 'absolute', left: 11, right: 11, bottom: -1, height: 2, background: COLORS.red }} />}
              </button>);

          })}
        </nav>
        <div style={{ flex: 1, minWidth: 8 }} />
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, color: COLORS.textMute, fontSize: 12, fontFamily: 'JetBrains Mono', flexShrink: 0 }}>
          <button onClick={() => setPage('teamdrv')} style={{
            all: 'unset', cursor: 'pointer',
            background: COLORS.red, color: '#fff',
            padding: '11px 20px', fontFamily: 'Archivo', fontWeight: 700, fontSize: 12, letterSpacing: '0.18em', textTransform: 'uppercase'
          }}>Race with us</button>
        </div>
      </div>
    </header>);

};

// ─────────────────────────────────────────────────────────────────────────────
// MARQUEE — news ticker just under the hero
const URTicker = ({ items, speed = 60 }) =>
<div style={{ overflow: 'hidden', borderTop: `1px solid ${COLORS.hairline}`, borderBottom: `1px solid ${COLORS.hairline}`, background: COLORS.base }}>
    <div style={{
    display: 'flex', whiteSpace: 'nowrap',
    animation: `ur-marquee ${speed}s linear infinite`,
    willChange: 'transform'
  }}>
      {[0, 1].map((k) =>
    <div key={k} style={{ display: 'flex', gap: 56, padding: '14px 28px' }}>
          {items.map((it, i) =>
      <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 14, fontFamily: 'Archivo', fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', fontSize: 12, color: COLORS.text }}>
              <span style={{ color: COLORS.red }}>◆</span>
              {it}
            </span>
      )}
        </div>
    )}
    </div>
    <style>{`@keyframes ur-marquee{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}`}</style>
  </div>;


// ─────────────────────────────────────────────────────────────────────────────
// Per-GP detailed track stats — supplement the calendar store (which has laps but not length/corners etc.)
// Add entries as data becomes available; unknowns show '—'.
const UR_HOME_TRACK_STATS = {
  'British Grand Prix': { length: '5.891 km', corners: 18, drsZones: '02', lapRecord: '1:21.043' }
};
const UR_HERO_STAT_DEFAULT = { length: '—', corners: '—', drsZones: '—', lapRecord: '—' };

// HERO — Next round splash. Track image background + gradient + stat bar.
const URHero = () => {
  const calRace = getCalendar('ul').races.find((cr) => cr.status === 'next');
  const r = URL_LEAGUE.nextRound; // fallback
  const trackBg = calRace?.trackImage || 'assets/tenbridge-map.jpg';

  const trackShort = calRace ?
  calRace.track.startsWith('Circuit of') ? calRace.track.split(' ').pop() : calRace.track.split(' ')[0] :
  r.trackShort;
  const roundNum = calRace ? String(calRace.round).padStart(2, '0') : r.r.replace(/[^0-9]/g, '');
  const gpName = calRace ? calRace.grandPrix : r.name;
  const laps = calRace ? (calRace.laps ?? '—') : r.laps;
  const flagKind = typeof UR_GP_FLAG !== 'undefined' && UR_GP_FLAG[gpName] || r.flag;
  const loc3 = typeof UR_GP_LOC3 !== 'undefined' && UR_GP_LOC3[gpName] || r.countryShort;
  const stats = UR_HOME_TRACK_STATS[gpName] || UR_HERO_STAT_DEFAULT;
  // Next-race bar (moved down from the welcome splash so the track preview backs it).
  const nextFlag = flagKind;
  const nextName = gpName;
  const nextLaps = laps;
  const nextLength = stats.length;
  const alCal = typeof getCalendar !== 'undefined' ? getCalendar('al') : null;
  const alRace = alCal ? alCal.races.find((cr) => cr.status === 'next') : null;
  const alTime = typeof UR2D_CALENDAR !== 'undefined' ? UR2D_CALENDAR.times.al : '14:30';
  const alHasDate = !!(alRace && alRace.date);
  const alStartIso = alHasDate ? `${alRace.date}T${(alRace.utcHHMM || alTime).padStart(5, '0')}:00Z` : null;
  const nextLightsOut = alTime + ' UTC';
  const [, setHeroTick] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setHeroTick((t) => t + 1), 1000);
    return () => clearInterval(id);
  }, []);
  const c = alHasDate ? getCountdown(alStartIso) : null;
  // Raceday itself reads "Current race"; the rest of the week reads "Next race".
  const isRaceDay = (() => {
    if (!calRace?.date) return false;
    const [y, m, d] = calRace.date.split('-').map(Number);
    const n = new Date();
    return n.getFullYear() === y && n.getMonth() === m - 1 && n.getDate() === d;
  })();
  return (
    <section style={{ position: 'relative', minHeight: 560, background: '#000', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
      {/* BACKGROUND — circuit map */}
      <div aria-hidden style={{ position: 'absolute', inset: 0, backgroundImage: `url(${trackBg})`, backgroundSize: 'cover', backgroundPosition: 'center', filter: 'saturate(0.9) contrast(1.02)' }} />
      {/* readability scrims */}
      <div aria-hidden style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(0,0,0,0.90) 0%, rgba(0,0,0,0.45) 24%, rgba(0,0,0,0.30) 48%, rgba(5,5,7,0.86) 82%, #050507 100%)', pointerEvents: 'none' }} />
      <div aria-hidden style={{ position: 'absolute', inset: 0, background: 'linear-gradient(90deg, rgba(0,0,0,0.62) 0%, rgba(0,0,0,0.12) 34%, transparent 58%)', pointerEvents: 'none' }} />

      {/* Next-race countdown bar — sits over the track preview */}
      <div style={{ position: 'relative', borderBottom: `1px solid ${COLORS.hairline}`, zIndex: 3, padding: '30px 48px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 32, flexWrap: 'wrap', background: 'transparent' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 28 }}>
          <FlagSvg kind={nextFlag} w={78} h={52} radius={3} />
          <div>
            <div style={{ fontFamily: 'JetBrains Mono', fontSize: 14, letterSpacing: '0.3em', color: COLORS.red, textTransform: 'uppercase' }}>Next on the calendar</div>
            <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 48, color: COLORS.text, letterSpacing: '-0.025em', lineHeight: 1, marginTop: 9 }}>{nextName}</div>
            <div style={{ fontFamily: 'JetBrains Mono', fontSize: 17, color: COLORS.textMute, letterSpacing: '0.06em', marginTop: 11 }}>{nextLaps != null ? `${nextLaps} laps · ` : ''}{nextLength && nextLength !== '—' ? `${nextLength} · ` : ''}Lights out {nextLightsOut}</div>
          </div>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 16 }}>
          <div style={{ fontFamily: 'JetBrains Mono', fontSize: 14, letterSpacing: '0.3em', color: COLORS.red, textTransform: 'uppercase' }}>{alHasDate ? `Until Apprentice League · ${nextLightsOut}` : 'Apprentice League · Schedule TBA'}</div>
          {alHasDate ?
          <div style={{ display: 'flex', gap: 12, transform: 'scale(1.28)', transformOrigin: 'right center' }}>
            {[['D', c.d], ['H', c.h], ['M', c.m]].map(([k, v]) =>
              <URFlipCard key={k} value={String(v).padStart(2, '0')} label={k} />
              )}
          </div> :
          <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 60, color: COLORS.text, letterSpacing: '-0.02em', lineHeight: 1 }}>TBA</div>
          }
        </div>
      </div>
      {/* spacer that lets the map breathe */}
      <div style={{ flex: 1, minHeight: 90 }} />

      {/* SECTOR PINS removed */}

      <style>{`@keyframes ur-pulse{0%,100%{opacity:.45;transform:scale(.82)}50%{opacity:1;transform:scale(1.12)}}`}</style>
    </section>);

};

// ─────────────────────────────────────────────────────────────────────────────
// HOME — per-league standings + recent results, both sourced from the store.
// Top-5 drivers for a league's default (current, data-bearing) season.
function useHomeStandingsRows(league) {
  const seasonId = defaultDataSeasonId(league);
  const s = useStandings(league, seasonId);
  return (s.drivers || []).slice(0, 5).map((d) => {
    const t = (s.teams || []).find((t) => t.short === d.team);
    return { name: d.name, team: d.team, color: (t && t.color) || COLORS.textMute, country: getRosterCountry(d.name), pts: d.pts };
  });
}

// Podium (top 3) of the most recently-completed round for a league, from the
// Data-gatherer race-results feed.
function useHomeRecentResult(league) {
  const seasonId = defaultDataSeasonId(league);
  const byRound = useRaceResults(league, seasonId);
  const standings = useStandings(league, seasonId);
  const rounds = Object.keys(byRound).map(Number).sort((a, b) => a - b);
  const last = rounds[rounds.length - 1];
  if (!last) return null;
  return {
    race: `R${String(last).padStart(2, '0')}`,
    podium: (byRound[last] || []).slice(0, 3).map((r) => {
      const std = standings.drivers.find((d) => rosterNorm(d.name) === rosterNorm(r.name));
      const t = std && (standings.teams || []).find((t) => t.short === std.team);
      return { name: r.name, team: (std && std.team) || '—', color: (t && t.color) || COLORS.textMute, country: getRosterCountry(r.name) };
    })
  };
}

// Compact league button row
function URLeaguePills({ league, setLeague }) {
  return (
    <div style={{ display: 'inline-flex', border: `1px solid ${COLORS.hairline}`, background: COLORS.panel }}>
      {LEAGUES.map((L, i) => {
        const on = league === L.id;
        return (
          <button key={L.id} onClick={() => setLeague(L.id)} style={{
            all: 'unset', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 9,
            padding: '11px 18px', position: 'relative',
            borderRight: i < LEAGUES.length - 1 ? `1px solid ${COLORS.hairline}` : 'none',
            background: on ? COLORS.surface : 'transparent'
          }}>
            {on && <span style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 2, background: L.accent }} />}
            <span style={{ display: 'inline-flex', width: 24, height: 24, background: COLORS.ink, padding: 3 }}>
              <img src={L.logo} alt={L.short} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain', opacity: on ? 1 : 0.5 }} />
            </span>
            <span style={{ fontFamily: 'Archivo', fontWeight: 800, fontSize: 12, letterSpacing: '0.18em', textTransform: 'uppercase', color: on ? COLORS.text : COLORS.textMute }}>{L.short}</span>
          </button>);

      })}
    </div>);

}

// ─────────────────────────────────────────────────────────────────────────────
// HOME — CURRENT STANDINGS (top 5 per league + switch + full standings link)
const URHomeStandings = ({ setPage }) => {
  const [league, setLeague] = React.useState('ul');
  const L = LEAGUE_BY_ID[league];
  const rows = useHomeStandingsRows(league);

  const thStyle = { textAlign: 'left', padding: '14px 22px', fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.22em', color: COLORS.textDim, textTransform: 'uppercase', borderBottom: `1px solid ${COLORS.hairline}`, background: COLORS.ink, fontWeight: 600 };
  const tdStyle = { padding: '18px 22px', borderBottom: `1px solid ${COLORS.hairline}`, verticalAlign: 'middle' };

  return (
    <section style={{ background: '#000', padding: '100px 40px 60px', position: 'relative', overflow: 'hidden' }}>
      <div aria-hidden style={{ position: 'absolute', top: 50, right: -40, fontFamily: 'Archivo', fontWeight: 900, fontSize: 320, color: 'transparent', WebkitTextStroke: `1px ${L.accent}2e`, letterSpacing: '-0.04em', lineHeight: 0.8, pointerEvents: 'none' }}>{L.short}</div>

      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 32, marginBottom: 32, position: 'relative', flexWrap: 'wrap' }}>
        <div>
          <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.3em', color: L.accent, textTransform: 'uppercase', marginBottom: 16 }}>◆ {L.name}</div>
          <h2 style={{ margin: 0, fontFamily: 'Archivo', fontWeight: 900, fontSize: 72, color: COLORS.text, letterSpacing: '-0.03em', lineHeight: 0.95 }}>
            Current <span style={{ color: L.accent }}>standings.</span>
          </h2>
        </div>
        <URLeaguePills league={league} setLeague={setLeague} />
      </div>

      <div style={{ background: COLORS.surface, border: `1px solid ${COLORS.hairline}`, position: 'relative' }}>
        <table style={{ width: '100%', borderCollapse: 'collapse', fontFamily: 'Archivo' }}>
          <thead>
            <tr>
              <th style={{ ...thStyle, width: 64 }}>Pos</th>
              <th style={{ ...thStyle, width: 36 }}></th>
              <th style={thStyle}>Driver</th>
              <th style={thStyle}>Team</th>
              <th style={{ ...thStyle, width: 110, textAlign: 'right' }}>Pts</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((r, i) =>
            <tr key={r.name} style={{ background: `linear-gradient(90deg, ${r.color}3a 0%, ${r.color}12 30%, transparent 68%)` }}>
                <td style={{ ...tdStyle, position: 'relative' }}>
                  <span style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, background: r.color }} />
                  <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 24, color: i === 0 ? L.accent : COLORS.textDim, letterSpacing: '-0.02em' }}>{i + 1}</span>
                </td>
                <td style={tdStyle}><FlagSvg kind={r.country} w={24} h={15} /></td>
                <td style={{ ...tdStyle, fontFamily: 'Archivo', fontWeight: 800, fontSize: 22, color: COLORS.text, letterSpacing: '-0.01em' }}>{r.name}</td>
                <td style={{ ...tdStyle, fontFamily: 'Archivo', fontWeight: 600, fontSize: 14, color: r.color, letterSpacing: '0.04em' }}>{r.team}</td>
                <td style={{ ...tdStyle, textAlign: 'right', fontFamily: 'Archivo', fontWeight: 800, fontSize: 24, color: COLORS.text, fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.02em' }}>{r.pts}</td>
              </tr>
            )}
          </tbody>
        </table>
        <div style={{ display: 'flex', justifyContent: 'flex-end', padding: '18px 22px', borderTop: `1px solid ${COLORS.hairline}` }}>
          <button onClick={() => setPage('standings')} style={{
            all: 'unset', cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 10,
            background: L.accent, color: '#fff', padding: '13px 24px',
            fontFamily: 'Archivo', fontWeight: 800, fontSize: 13, letterSpacing: '0.2em', textTransform: 'uppercase'
          }}>Full Standings →</button>
        </div>
      </div>
    </section>);

};

// ─────────────────────────────────────────────────────────────────────────────
// HOME — RECENT RESULTS (one podium card per league)
const UR_MEDAL = ['#FFD24A', '#C9CDD4', '#CD7F32'];

// One podium slot — metal numeral, driver, team. P1 gets the emphasis.
const URResultSlot = ({ p, i }) => {
  const metal = UR_MEDAL[i];
  const lead = i === 0;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '14px 18px', background: lead ? 'rgba(255,255,255,0.04)' : 'transparent', borderLeft: `2px solid ${metal}`, minWidth: 0 }}>
      <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: lead ? 34 : 26, color: metal, lineHeight: 1, letterSpacing: '-0.04em', fontVariantNumeric: 'tabular-nums' }}>{i + 1}</span>
      <FlagSvg kind={p.country} w={24} h={15} />
      <div style={{ minWidth: 0 }}>
        <div style={{ fontFamily: 'Archivo', fontWeight: 800, fontSize: lead ? 20 : 17, color: COLORS.text, letterSpacing: '-0.01em', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.name}</div>
        <div style={{ fontFamily: 'JetBrains Mono', fontSize: 9, fontWeight: 700, color: p.color, letterSpacing: '0.18em', textTransform: 'uppercase', marginTop: 4 }}>{p.team}</div>
      </div>
    </div>);
};

// HOME — RECENT RESULTS. One full-width ribbon per league: league mark + round on the
// left, the three podium slots laid out across the right.
const URRecentResults = () => {
  const results = { ul: useHomeRecentResult('ul'), hl: useHomeRecentResult('hl'), jl: useHomeRecentResult('jl'), al: useHomeRecentResult('al') };
  return (
    <section style={{ background: '#000', padding: '40px 40px 130px', position: 'relative' }}>
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 32, flexWrap: 'wrap', marginBottom: 44 }}>
        <div>
          <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.3em', color: COLORS.red, textTransform: 'uppercase', marginBottom: 16 }}>◆ Latest Results · Across All Leagues</div>
          <h2 style={{ margin: 0, fontFamily: 'Archivo', fontWeight: 900, fontSize: 72, color: COLORS.text, letterSpacing: '-0.03em', lineHeight: 0.95 }}>
            Recent <span style={{ color: COLORS.red }}>results.</span>
          </h2>
        </div>
        <div style={{ display: 'flex', gap: 18, alignItems: 'center', paddingBottom: 6 }}>
          {UR_MEDAL.map((m, i) =>
          <div key={m} style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
            <span style={{ width: 8, height: 8, background: m, display: 'inline-block' }} />
            <span style={{ fontFamily: 'JetBrains Mono', fontSize: 9, letterSpacing: '0.2em', color: COLORS.textDim, textTransform: 'uppercase' }}>P{i + 1}</span>
          </div>
          )}
        </div>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        {LEAGUES.map((L) => {
          const res = results[L.id];
          if (!res) return null;
          return (
            <article key={L.id} style={{ position: 'relative', overflow: 'hidden', background: COLORS.surface, border: `1px solid ${COLORS.hairline}`, display: 'grid', gridTemplateColumns: 'minmax(240px, 300px) 1fr', alignItems: 'stretch' }}>
              <span style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, background: L.accent, zIndex: 2 }} />
              <div aria-hidden style={{ position: 'absolute', left: 210, top: '50%', transform: 'translateY(-50%)', fontFamily: 'Archivo', fontWeight: 900, fontSize: 150, color: 'transparent', WebkitTextStroke: `1px ${L.accent}26`, letterSpacing: '-0.05em', lineHeight: 0.8, pointerEvents: 'none' }}>{L.short}</div>
              <div style={{ position: 'relative', display: 'flex', alignItems: 'center', gap: 14, padding: '22px 26px', borderRight: `1px solid ${COLORS.hairline}`, background: 'rgba(0,0,0,0.35)' }}>
                <span style={{ display: 'inline-flex', width: 44, height: 44, background: COLORS.ink, padding: 6, flexShrink: 0 }}>
                  <img src={L.logo} alt={L.short} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }} />
                </span>
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 17, color: COLORS.text, letterSpacing: '-0.01em', textTransform: 'uppercase' }}>{L.name}</div>
                  <div style={{ fontFamily: 'JetBrains Mono', fontSize: 9, letterSpacing: '0.22em', color: L.accent, textTransform: 'uppercase', marginTop: 5 }}>Round {res.race.replace('R', '')} · Podium</div>
                </div>
              </div>
              <div style={{ position: 'relative', display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: 1, background: COLORS.hairline }}>
                {res.podium.map((p, i) =>
                <div key={p.name} style={{ background: COLORS.surface }}>
                  <URResultSlot p={p} i={i} />
                </div>
                )}
              </div>
            </article>);
        })}
      </div>
    </section>);
};

// ─────────────────────────────────────────────────────────────────────────────
// FLIP CLOCK — split-flap countdown digit panel
// Each half renders the FULL digit but clips to its top/bottom via overflow:hidden,
// so the top and bottom leaves line up on the center seam.
const URFlipHalf = ({ digit, half, cardH }) =>
<div style={{ position: 'relative', width: '100%', height: cardH / 2, overflow: 'hidden', background: half === 'top' ? '#141418' : COLORS.ink }}>
    <span style={{
    position: 'absolute', left: 0, right: 0, [half === 'top' ? 'top' : 'bottom']: 0,
    height: cardH, lineHeight: `${cardH}px`, textAlign: 'center',
    fontFamily: 'Archivo', fontWeight: 900, fontSize: 54, color: COLORS.text,
    fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.03em'
  }}>{digit}</span>
  </div>;


// On value change: keep the old value's bottom half static while the old top leaf
// flips down (revealing the new top), then the new bottom leaf flips down into place.
// Leaves are keyed by an incrementing id so each tick re-triggers the animation; they
// hold their end-state between ticks (matching the static layer beneath — no glitch).
const URFlipCard = ({ value, label }) => {
  const w = 92,cardH = 96;
  const [st, setSt] = React.useState({ cur: value, prev: value, id: 0 });
  React.useEffect(() => {
    setSt((s) => s.cur === value ? s : { cur: value, prev: s.cur, id: s.id + 1 });
  }, [value]);
  const flipping = st.cur !== st.prev;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10 }}>
      <div style={{ position: 'relative', width: w, height: cardH, perspective: 320, border: `1px solid ${COLORS.hairline}`, borderRadius: 6, boxShadow: '0 10px 24px -12px rgba(0,0,0,0.85)' }}>
        {/* Static layer — top shows new value, bottom shows old value until the leaf covers it */}
        <div style={{ position: 'absolute', top: 0, left: 0, right: 0 }}><URFlipHalf digit={st.cur} half="top" cardH={cardH} /></div>
        <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0 }}><URFlipHalf digit={st.prev} half="bottom" cardH={cardH} /></div>
        {/* Flipping leaves */}
        {flipping &&
        <React.Fragment key={st.id}>
            <div style={{ position: 'absolute', top: 0, left: 0, right: 0, transformOrigin: 'bottom', backfaceVisibility: 'hidden', zIndex: 4, animation: 'ur-flip-top 0.3s ease-in forwards' }}>
              <URFlipHalf digit={st.prev} half="top" cardH={cardH} />
            </div>
            <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, transformOrigin: 'top', backfaceVisibility: 'hidden', zIndex: 4, transform: 'rotateX(90deg)', animation: 'ur-flip-bottom 0.3s ease-out 0.3s forwards' }}>
              <URFlipHalf digit={st.cur} half="bottom" cardH={cardH} />
            </div>
          </React.Fragment>}
        {/* Center seam */}
        <div style={{ position: 'absolute', top: '50%', left: 0, right: 0, height: 2, marginTop: -1, background: 'rgba(0,0,0,0.55)', zIndex: 6, pointerEvents: 'none' }} />
      </div>
      <div style={{ fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.3em', color: COLORS.red, textTransform: 'uppercase' }}>{label}</div>
    </div>);

};

// ─────────────────────────────────────────────────────────────────────────────
// WELCOME SPLASH — full-viewport intro above the hero (home page only)
const URWelcome = ({ setPage }) => {
  const r = URL_LEAGUE.nextRound;
  const calRace = getCalendar('ul').races.find((cr) => cr.status === 'next');
  const nextFlag = typeof UR_GP_FLAG !== 'undefined' && calRace ? UR_GP_FLAG[calRace.grandPrix] || r.flag : r.flag;
  const nextName = calRace ? calRace.grandPrix : r.name;
  const nextLaps = calRace ? calRace.laps : r.laps;
  const nextStats = typeof UR_HOME_TRACK_STATS !== 'undefined' && calRace ? UR_HOME_TRACK_STATS[calRace.grandPrix] : null;
  const nextLength = nextStats ? nextStats.length : r.length;
  // Countdown to the next Apprentice League lights-out, ticking against the REAL clock.
  const alCal = typeof getCalendar !== 'undefined' ? getCalendar('al') : null;
  const alRace = alCal ? alCal.races.find((cr) => cr.status === 'next') : null;
  const alTime = typeof UR2D_CALENDAR !== 'undefined' ? UR2D_CALENDAR.times.al : '14:30';
  const alHasDate = !!(alRace && alRace.date);
  const alStartIso = alHasDate ? `${alRace.date}T${(alRace.utcHHMM || alTime).padStart(5, '0')}:00Z` : null;
  const nextLightsOut = alTime + ' UTC';
  const [, setTick] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setTick((t) => t + 1), 1000);
    return () => clearInterval(id);
  }, []);
  const c = alHasDate ? getCountdown(alStartIso) : null;
  return (
    <section style={{ position: 'relative', minHeight: 'calc(100vh - 96px)', background: COLORS.base, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
    {/* Topographic contour background */}
    <div aria-hidden style={{
        position: 'absolute', inset: 0, opacity: 0.05, pointerEvents: 'none',
        backgroundImage: `repeating-radial-gradient(ellipse 1200px 900px at 60% 45%, transparent 0, transparent 46px, ${COLORS.text} 47px, transparent 49px)`
      }} />
    {/* Red glow */}
    <div aria-hidden style={{ position: 'absolute', left: '50%', top: '52%', transform: 'translate(-50%,-50%)', width: 820, height: 820, borderRadius: '50%', background: `radial-gradient(circle, ${COLORS.red}26 0%, transparent 62%)`, filter: 'blur(50px)', pointerEvents: 'none' }} />

    {/* Top row: stacked title (left) · Race with us (right) */}
    <div style={{ position: 'relative', display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 32, padding: '52px 48px 0' }}>
      <h1 style={{ margin: 0, fontFamily: 'Archivo', fontWeight: 900, fontSize: 76, lineHeight: 0.86, letterSpacing: '-0.04em', color: COLORS.text, textTransform: 'uppercase' }}>
        Ultimate<br />Racing 2D<br />
        <span style={{ color: COLORS.red, textTransform: 'none', letterSpacing: '-0.01em' }}>esports.</span>
      </h1>
      <button onClick={() => setPage('teamdrv')} style={{
          all: 'unset', cursor: 'pointer', flexShrink: 0,
          background: COLORS.red, color: '#fff',
          padding: '15px 26px', fontFamily: 'Archivo', fontWeight: 800, fontSize: 13, letterSpacing: '0.22em', textTransform: 'uppercase'
        }}>JOIN THE GRID→</button>
    </div>

    {/* Center: UR2D eSports logo */}
    <div style={{ position: 'relative', flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '40px 0' }}>
      <img src="assets/ur2d-logo.png" alt="UR2D eSports" style={{ width: 320, height: 'auto', maxWidth: '70vw', display: 'block', mixBlendMode: 'screen', WebkitMaskImage: 'radial-gradient(ellipse 62% 62% at 50% 50%, #000 55%, transparent 100%)', maskImage: 'radial-gradient(ellipse 62% 62% at 50% 50%, #000 55%, transparent 100%)' }} />
    </div>

    <style>{`
      @keyframes ur-flip-top { 0%{transform:rotateX(0deg)} 100%{transform:rotateX(-90deg)} }
      @keyframes ur-flip-bottom { 0%{transform:rotateX(90deg)} 100%{transform:rotateX(0deg)} }
    `}</style>
  </section>);

};

// ─────────────────────────────────────────────────────────────────────────────
// TEAMS GRID — replaces MZM's car showcase. 8 teams.
const URTeams = () => {
  return (
    <section style={{ background: '#000', padding: '110px 40px 130px', position: 'relative', overflow: 'hidden' }}>
      <div aria-hidden style={{ position: 'absolute', top: 60, right: -40, fontFamily: 'Archivo', fontWeight: 900, fontSize: 360, color: 'transparent', WebkitTextStroke: `1px ${COLORS.red}33`, letterSpacing: '-0.04em', lineHeight: 0.8, pointerEvents: 'none' }}>UR2D·26</div>

      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 48, position: 'relative' }}>
        <div>
          <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.3em', color: COLORS.red, textTransform: 'uppercase', marginBottom: 18 }}>◆ The Grid · 08 Teams</div>
          <h2 style={{ margin: 0, fontFamily: 'Archivo', fontWeight: 900, fontSize: 76, color: COLORS.text, letterSpacing: '-0.03em', lineHeight: 0.95 }}>
            Eight teams,<br /><span style={{ color: COLORS.red }}>one championship.</span>
          </h2>
        </div>
        <div style={{ maxWidth: 380, color: COLORS.textMute, fontSize: 15, lineHeight: 1.6 }}>
          Every team runs two starters. Sixteen drivers fight for the constructors' title and the individual crown across a sixteen-round season.
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16, position: 'relative' }}>
        {URL_LEAGUE.teams.map((t, i) => {
          const teamDrivers = URL_LEAGUE.drivers.filter((d) => d.team === t.id);
          const standingPos = i + 1;
          return (
            <article key={t.id} style={{
              background: COLORS.surface, border: `1px solid ${COLORS.hairline}`,
              padding: '24px 22px 20px', position: 'relative', overflow: 'hidden',
              minHeight: 280
            }}>
              {/* Team color accent bar */}
              <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 4, background: t.color }} />
              {/* Background mark */}
              <div aria-hidden style={{
                position: 'absolute', right: -16, bottom: -36,
                fontFamily: 'Archivo', fontWeight: 900, fontSize: 180,
                color: 'transparent', WebkitTextStroke: `1px ${t.color}55`,
                letterSpacing: '-0.04em', lineHeight: 0.8, pointerEvents: 'none'
              }}>{t.short}</div>
              {/* Top row */}
              <div style={{ position: 'relative', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 24 }}>
                <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 26, color: COLORS.textDim, letterSpacing: '-0.02em' }}>P{standingPos}</span>
                <div style={{
                  background: t.color, color: '#fff', fontFamily: 'JetBrains Mono', fontWeight: 700,
                  fontSize: 11, letterSpacing: '0.22em', padding: '5px 10px'
                }}>{t.short}</div>
              </div>
              {/* Team name */}
              <h3 style={{ margin: 0, position: 'relative', fontFamily: 'Archivo', fontWeight: 900, fontSize: 28, color: COLORS.text, letterSpacing: '-0.01em', lineHeight: 1.05, textTransform: 'uppercase' }}>{t.name}</h3>
              {/* Drivers */}
              <div style={{ marginTop: 22, position: 'relative' }}>
                {teamDrivers.map((d) =>
                <div key={d.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '6px 0', fontFamily: 'Archivo', fontSize: 14 }}>
                    <FlagSvg kind={d.country} w={20} h={13} />
                    <span style={{ fontWeight: 700, color: COLORS.text, flex: 1 }}>{d.name}</span>
                    <span style={{ fontFamily: 'JetBrains Mono', color: t.color, fontSize: 12, fontWeight: 700 }}>#{d.number}</span>
                  </div>
                )}
              </div>
              {/* Points line */}
              <div style={{ marginTop: 22, position: 'relative', display: 'flex', alignItems: 'baseline', gap: 8, borderTop: `1px solid ${COLORS.hairline}`, paddingTop: 14 }}>
                <span style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 36, color: COLORS.text, fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.02em', lineHeight: 1 }}>{t.pts}</span>
                <span style={{ fontFamily: 'JetBrains Mono', fontSize: 10, color: t.color, letterSpacing: '0.22em' }}>PTS</span>
              </div>
            </article>);

        })}
      </div>
    </section>);

};

// ─────────────────────────────────────────────────────────────────────────────
// DRIVERS PREVIEW — top 4 driver cards
const URDriverCard = ({ d, pos, pts, big = false, league = 'ul' }) => {
  const team = TEAM_BY_ID[d.team];
  const L = LEAGUE_BY_ID[league];
  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
    <article style={{ position: 'relative', height: big ? 720 : 560, background: COLORS.surface, overflow: 'hidden', border: `1px solid ${COLORS.hairline}`, boxShadow: `0 24px 60px -20px ${L.accent}80, 0 0 0 1px ${L.accent}1f` }}>
      {/* Big number watermark */}
      <div style={{
          position: 'absolute', right: -30, top: -40,
          fontFamily: 'Archivo', fontWeight: 900, fontSize: big ? 380 : 280, color: team.color,
          lineHeight: 0.8, letterSpacing: '-0.06em', opacity: 0.22, pointerEvents: 'none', zIndex: 1
        }}>{d.number}</div>

      {/* Portrait slot */}
      <div style={{ position: 'absolute', inset: 0, zIndex: 2 }}>
        <URImageSlot
            id={`ur-driver-${d.id}`}
            placeholder={`${d.name} portrait`}
            shape="rect"
            style={{ width: '100%', height: '100%' }} />
      </div>
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, transparent 35%, rgba(0,0,0,.92) 95%)', zIndex: 3, pointerEvents: 'none' }} />

      {/* Top label */}
      <div style={{ position: 'absolute', top: 20, left: 20, zIndex: 4, display: 'flex', alignItems: 'center', gap: 10 }}>
        <FlagSvg kind={d.country} w={28} h={18} />
        <span style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.22em', color: COLORS.text, textTransform: 'uppercase' }}>
          P{pos} · {pts} pts
        </span>
      </div>

      {/* Team chip — top right */}
      <div style={{ position: 'absolute', top: 20, right: 20, zIndex: 4, background: team.color, color: '#fff', padding: '5px 10px', fontFamily: 'JetBrains Mono', fontSize: 11, fontWeight: 700, letterSpacing: '0.22em' }}>
        {team.short}
      </div>

      {/* Bottom name block */}
      <div style={{ position: 'absolute', bottom: 24, left: 24, right: 24, zIndex: 4 }}>
        <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: big ? 56 : 48, color: COLORS.text, letterSpacing: '-0.02em', lineHeight: 0.95, textTransform: 'uppercase' }}>{d.name}</div>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 14, marginTop: 14, fontFamily: 'JetBrains Mono', fontSize: 12, color: COLORS.textMute, letterSpacing: '0.16em', textTransform: 'uppercase' }}>
          <span>#{d.number}</span>
          <span style={{ color: team.color }}>·</span>
          <span>{team.name}</span>
        </div>
      </div>
    </article>
    {/* League logo strip below the card */}
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 14, padding: '0 2px' }}>
      <span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 30, height: 30, background: COLORS.ink, border: `1px solid ${COLORS.hairline}`, padding: 4, flexShrink: 0 }}>
        <img src={L.logo} alt={L.short} style={{ maxHeight: '100%', maxWidth: '100%', objectFit: 'contain', display: 'block' }} />
      </span>
      <span style={{ fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.24em', color: COLORS.textMute, textTransform: 'uppercase' }}>
        {L.short} · <span style={{ color: L.accent }}>{L.name}</span>
      </span>
    </div>
    </div>);

};

// Store-driven leader card — one league's P1, rendered from the canonical
// Standings shape (driver name + team short + pts/wins/podiums). The original
// URDriverCard requires the placeholder URL_LEAGUE.drivers graph (driver #,
// country, portrait id) which the store doesn't carry yet.
const URLeagueLeaderCard = ({ league }) => {
  const L = LEAGUE_BY_ID[league];
  const data = useStandings(league);
  const leader = data.drivers && data.drivers[0];
  const team = leader && data.teams ? data.teams.find((t) => t.short === leader.team) : null;
  const accent = team && team.color || L.accent;
  // Placeholder until per-team liveries land in the adapter's teamLiveries map.
  const livery = team && team.livery || 'assets/mazzar-livery.png';
  const logoSrc = typeof UR_TEAM_LOGO !== 'undefined' && team ? UR_TEAM_LOGO[team.short] : null;
  const logoDark = typeof UR_TEAM_LOGO_DARK !== 'undefined' && team ? UR_TEAM_LOGO_DARK.has(team.short) : false;

  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <article style={{ position: 'relative', height: 560, background: COLORS.surface, overflow: 'hidden', border: `1px solid ${COLORS.hairline}`, boxShadow: `0 24px 60px -20px ${L.accent}80, 0 0 0 1px ${L.accent}1f` }}>
        {/* Backsplash: large semi-transparent team logo, centered behind the car */}
        {logoSrc &&
        <img aria-hidden src={logoSrc} alt="" style={{
          position: 'absolute', left: '50%', top: '50%',
          transform: 'translate(-50%, -50%)',
          width: 380, height: 380, objectFit: 'contain',
          opacity: 0.16, pointerEvents: 'none', zIndex: 1,
          filter: logoDark ? 'brightness(0.6)' : 'none'
        }} />
        }

        {/* Livery — rotated -90° so the car runs vertically, filling the card from the
                         top down to the name block. team.livery comes from the adapter's
                         teamLiveries map; falls back to the mazzar placeholder when not yet set.
                         Width pre-rotation = visual height after rotation. */}
        <div style={{ position: 'absolute', top: 24, bottom: 130, left: 0, right: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 2, pointerEvents: 'none' }}>
          <img src={livery} alt="" style={{ width: 400, height: 'auto', transform: 'rotate(-90deg)', filter: 'drop-shadow(0 18px 30px rgba(0,0,0,0.55))', imageRendering: 'auto' }} />
        </div>

        {/* Bottom gradient — readability for the name block */}
        <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, transparent 35%, rgba(0,0,0,.92) 95%)', zIndex: 3, pointerEvents: 'none' }} />

        {/* Top label — P1 · pts */}
        <div style={{ position: 'absolute', top: 20, left: 20, zIndex: 4, display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.22em', color: COLORS.text, textTransform: 'uppercase' }}>
            {leader ? `P1 · ${leader.pts} pts` : 'Season pending'}
          </span>
        </div>

        {/* Team logo — top right, only if league is team-based and we matched a team */}
        {team && logoSrc &&
        <div style={{ position: 'absolute', top: 16, right: 16, zIndex: 4, width: 48, height: 48, display: 'flex', alignItems: 'center', justifyContent: 'center', background: COLORS.ink, border: `1px solid ${COLORS.hairline}`, padding: 8 }}>
            <img src={logoSrc} alt={team.short} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain', display: 'block' }} />
          </div>
        }

        {/* Bottom name block */}
        <div style={{ position: 'absolute', bottom: 24, left: 24, right: 24, zIndex: 4 }}>
          <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 48, color: COLORS.text, letterSpacing: '-0.02em', lineHeight: 0.95, textTransform: 'uppercase' }}>{leader ? leader.name : '—'}</div>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 14, marginTop: 14, fontFamily: 'JetBrains Mono', fontSize: 12, color: COLORS.textMute, letterSpacing: '0.16em', textTransform: 'uppercase' }}>
            <span>{leader ? `${leader.wins}W · ${leader.podiums}P` : 'No data'}</span>
            {team && <span style={{ color: team.color }}>·</span>}
            {team && <span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{team.name}</span>}
          </div>
        </div>
      </article>

      {/* League logo strip below the card */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 14, padding: '0 2px' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 30, height: 30, background: COLORS.ink, border: `1px solid ${COLORS.hairline}`, padding: 4, flexShrink: 0 }}>
          <img src={L.logo} alt={L.short} style={{ maxHeight: '100%', maxWidth: '100%', objectFit: 'contain', display: 'block' }} />
        </span>
        <span style={{ fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.24em', color: COLORS.textMute, textTransform: 'uppercase' }}>
          {L.short} · <span style={{ color: L.accent }}>{L.name}</span>
          {data.season ? <span style={{ color: COLORS.textDim }}> · {data.season.label}</span> : null}
        </span>
      </div>
    </div>);

};

const URDriversPreview = () =>
<section style={{ background: COLORS.base, padding: '80px 40px 110px', marginTop: -1 }}>
    <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 48 }}>
      <div>
        <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.3em', color: COLORS.red, textTransform: 'uppercase', marginBottom: 18 }}>◆ Championship leaders</div>
        <h2 style={{ margin: 0, fontFamily: 'Archivo', fontWeight: 900, fontSize: 76, color: COLORS.text, letterSpacing: '-0.03em', lineHeight: 0.95 }}>
          The drivers<br /><span style={{ color: COLORS.red }}>at the front.</span>
        </h2>
      </div>
      <div style={{ maxWidth: 360, color: COLORS.textMute, fontSize: 15, lineHeight: 1.55 }}>
        Four leagues. Four championships in flight. Here's whose name sits at the top of each table right now.
      </div>
    </div>
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 20 }}>
      {LEAGUES.map((Lg) => <URLeagueLeaderCard key={Lg.id} league={Lg.id} />)}
    </div>
  </section>;

// ─────────────────────────────────────────────────────────────────────────────
// CALENDAR PREVIEW (compact rows, used on home)
// Real-race flags by Grand Prix name (store has no flag field)
const UR_GP_FLAG = {
  'Qatar Grand Prix': 'qatar',
  'South African Grand Prix': 'southafrica',
  'Spanish Grand Prix': 'spain',
  'Ukrainian Grand Prix': 'ukraine',
  'German Grand Prix': 'germany',
  'Indonesian Grand Prix': 'indonesia',
  'Slovakian Grand Prix': 'slovakia',
  'British Grand Prix': 'uk',
  'Malaysian Grand Prix': 'malaysia',
  'Welsh Grand Prix': 'wales',
  'Japanese Grand Prix': 'japan',
  'Belgian Grand Prix': 'belgium',
  'Swedish Grand Prix': 'sweden',
  'Dutch Grand Prix': 'netherlands',
  'Italian Grand Prix': 'italy',
  'Gold Coast Grand Prix': 'australia',
  'Sapporo International Grand Prix': 'japan',
  'Canadian Grand Prix': 'canada',
  'Australian Grand Prix': 'australia',
  'Arcana East Flanders Grand Prix': 'belgium',
  'French Grand Prix': 'fr',
  'Russian Grand Prix': 'russia',
  'United States Grand Prix': 'usa', // Niagara Falls (US/CA border) — GP is billed as United States
  'Romanian Grand Prix': 'romania',
  'Canarian Grand Prix': 'canary',   // Spain, but Canary Islands flag (user call)
  'Monaco Grand Prix': 'monaco',
};

// Adapt a store race (from getCalendar) to the calendar-row shape
function mapCalRaceToRow(race) {
  return {
    r: 'R' + String(race.round).padStart(2, '0'),
    flag: UR_GP_FLAG[race.grandPrix] || 'pacific',
    name: race.grandPrix,
    track: race.track,
    status: race.status,
    detail: race.localDate + ' · ' + race.utcTime,
    trackUrl: race.trackUrl
  };
}

const URCalendarRow = ({ e, i }) => {
  const isDone = e.status === 'done';
  const isNext = e.status === 'next';
  const winTeam = e.winTeam ? TEAM_BY_ID[e.winTeam] : null;
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: '70px 50px 1fr 1.2fr 100px 140px', gap: 24,
      alignItems: 'center', padding: '22px 28px',
      background: isNext ? `linear-gradient(90deg, ${COLORS.red}1a, transparent 70%)` : 'transparent',
      borderBottom: `1px solid ${COLORS.hairline}`,
      position: 'relative'
    }}>
      {isNext && <span style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, background: COLORS.red }} />}
      <span style={{ fontFamily: 'JetBrains Mono', fontWeight: 700, fontSize: 14, color: isDone ? COLORS.textDim : COLORS.red, letterSpacing: '0.14em' }}>{e.r}</span>
      <FlagSvg kind={e.flag} w={36} h={24} />
      <div>
        <div style={{ fontFamily: 'Archivo', fontWeight: 800, fontSize: 22, color: isDone ? COLORS.textMute : COLORS.text, letterSpacing: '-0.005em' }}>{e.name}</div>
        <div style={{ fontFamily: 'Archivo', fontSize: 13, color: COLORS.textDim, marginTop: 2 }}>{e.track}</div>
      </div>
      <div style={{ fontFamily: 'Archivo', fontWeight: 600, fontSize: 14, color: COLORS.textMute }}>
        {e.winner ?
        <span>Winner · <span style={{ color: winTeam ? winTeam.color : COLORS.text, fontWeight: 800 }}>{e.winner}</span></span> :
        e.detail || (isNext ? 'May 31 · 19:00 UTC' : '—')}
      </div>
      <div>
        <span style={{
          fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase',
          padding: '4px 8px',
          background: isNext ? COLORS.red : isDone ? '#1a1a1d' : 'transparent',
          color: isNext ? '#fff' : isDone ? COLORS.textMute : COLORS.textDim,
          border: !isDone && !isNext ? `1px solid ${COLORS.hairline}` : 'none'
        }}>{isNext ? 'Next' : isDone ? 'Complete' : 'Upcoming'}</span>
      </div>
      <div style={{ textAlign: 'right' }}>
        <a href={e.trackUrl || undefined} target={e.trackUrl ? '_blank' : undefined} rel="noopener" style={{ fontFamily: 'Archivo', fontWeight: 700, fontSize: 12, color: COLORS.text, letterSpacing: '0.2em', textTransform: 'uppercase', borderBottom: `1px solid ${isNext ? COLORS.red : COLORS.hairline}`, paddingBottom: 4, textDecoration: 'none' }}>{e.trackUrl ? 'Track' : isDone ? 'Race report' : 'Preview'} →</a>
      </div>
    </div>);

};

const URCalendarPreview = ({ compact = true }) => {
  const cal = getCalendar('ul');
  const calRows = cal.races.map(mapCalRaceToRow);
  const roundsDone = cal.races.filter((r) => r.status === 'done').length;
  const totalRounds = cal.races.length;
  return (
    <section style={{ background: COLORS.base, padding: '110px 40px' }}>
    <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 48 }}>
      <div>
        <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.3em', color: COLORS.red, textTransform: 'uppercase', marginBottom: 18 }}>◆ Season 2026</div>
        <h2 style={{ margin: 0, fontFamily: 'Archivo', fontWeight: 900, fontSize: 76, color: COLORS.text, letterSpacing: '-0.03em', lineHeight: 0.95 }}>
          The road to<br /><span style={{ color: COLORS.red }}>the season finale.</span>
        </h2>
      </div>
      <div style={{ display: 'flex', gap: 28, alignItems: 'flex-end' }}>
        <div>
          <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.24em', color: COLORS.textMute, textTransform: 'uppercase' }}>Rounds Done</div>
          <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 56, color: COLORS.text, lineHeight: 1 }}>{roundsDone}<span style={{ color: COLORS.textDim, fontSize: 28 }}>/{totalRounds}</span></div>
        </div>
        <div>
          <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.24em', color: COLORS.textMute, textTransform: 'uppercase' }}>Leader</div>
          <div style={{ fontFamily: 'Archivo', fontWeight: 900, fontSize: 56, color: COLORS.red, lineHeight: 1 }}>{roundsDone > 0 ? 'RIVEN' : 'TBA'}</div>
        </div>
      </div>
    </div>
    <div style={{ border: `1px solid ${COLORS.hairline}`, background: COLORS.ink }}>
      <div style={{ display: 'grid', gridTemplateColumns: '70px 50px 1fr 1.2fr 100px 140px', gap: 24, padding: '14px 28px', borderBottom: `1px solid ${COLORS.hairline}`, fontFamily: 'JetBrains Mono', fontSize: 10, letterSpacing: '0.22em', color: COLORS.textDim, textTransform: 'uppercase' }}>
        <span>Round</span><span>Flag</span><span>Race</span><span>Detail</span><span>Status</span><span style={{ textAlign: 'right' }}>Link</span>
      </div>
      {(compact ? calRows.slice(0, 8) : calRows).map((e, i) => <URCalendarRow key={i} e={e} i={i} />)}
    </div>
  </section>);

};


// ─────────────────────────────────────────────────────────────────────────────
// VIDEO CARD — YouTube thumbnail + title, links to the video
const URVideoCard = ({ v, big }) =>
<a href={`https://www.youtube.com/watch?v=${v.id}`} target="_blank" rel="noopener noreferrer"
  style={{ display: 'block', background: COLORS.surface, border: `1px solid ${COLORS.hairline}`, textDecoration: 'none', color: 'inherit' }}>
    <div style={{ position: 'relative', aspectRatio: '16 / 9', overflow: 'hidden', background: '#000' }}>
      <img src={`https://i.ytimg.com/vi/${v.id}/hqdefault.jpg`} alt={v.title} loading="lazy"
      style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, transparent 55%, rgba(0,0,0,.55) 100%)' }} />
      <span style={{ position: 'absolute', top: 12, left: 12, background: COLORS.red, color: '#fff', padding: '4px 9px', fontFamily: 'JetBrains Mono', fontSize: 9, letterSpacing: '0.2em', textTransform: 'uppercase' }}>▶ Watch</span>
      <span style={{ position: 'absolute', bottom: 12, right: 12, background: 'rgba(0,0,0,.6)', backdropFilter: 'blur(4px)', color: COLORS.text, padding: '4px 9px', fontFamily: 'JetBrains Mono', fontSize: 9, letterSpacing: '0.16em', textTransform: 'uppercase' }}>{v.date}</span>
    </div>
    <div style={{ padding: big ? '22px 24px 26px' : '16px 18px 20px' }}>
      <h3 style={{ margin: 0, fontFamily: 'Archivo', fontWeight: 700, fontSize: big ? 26 : 16, color: COLORS.text, lineHeight: 1.2, letterSpacing: '-0.01em' }}>{v.title}</h3>
    </div>
  </a>;

// NEWS GRID (used on home and Discord page) — latest videos from the channel
const URNews = () =>
<section style={{ background: '#000', padding: '110px 40px 90px' }}>
    <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 48, flexWrap: 'wrap', gap: 20 }}>
      <div>
        <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.3em', color: COLORS.red, textTransform: 'uppercase', marginBottom: 18 }}>◆ Watch</div>
        <h2 style={{ margin: 0, fontFamily: 'Archivo', fontWeight: 900, fontSize: 76, color: COLORS.text, letterSpacing: '-0.03em', lineHeight: 0.95 }}>
          Latest from <span style={{ color: COLORS.red }}>the channel.</span>
        </h2>
      </div>
      <a href={URL_LEAGUE.youtubeChannel} target="_blank" rel="noopener noreferrer" style={{ color: COLORS.text, fontFamily: 'Archivo', fontWeight: 700, fontSize: 13, letterSpacing: '0.22em', textTransform: 'uppercase', borderBottom: `1px solid ${COLORS.red}`, paddingBottom: 6, textDecoration: 'none' }}>All videos ↗</a>
    </div>
    <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 28 }}>
      <URVideoCard v={URL_LEAGUE.videos[0]} big />
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gridAutoRows: 'min-content', gap: 20 }}>
        {URL_LEAGUE.videos.slice(1, 5).map((v) => <URVideoCard key={v.id} v={v} />)}
      </div>
    </div>
  </section>;


// ─────────────────────────────────────────────────────────────────────────────
// FOOTER
const URFooter = ({ setPage }) =>
<footer style={{ background: '#000', borderTop: `1px solid ${COLORS.hairline}`, padding: '70px 40px 40px' }}>
    <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr 1fr 1fr', gap: 60, marginBottom: 60 }}>
      <div>
        <LogoLockup size={40} />
        <p style={{ marginTop: 22, color: COLORS.textMute, fontSize: 14, lineHeight: 1.6, maxWidth: 380 }}>
          Ultimate Racing Esports is an arcade racing league founded in {URL_LEAGUE.brand.estab}. Eight teams, sixteen drivers, one championship — every Sunday.
        </p>
        <div style={{ display: 'flex', gap: 10, marginTop: 22 }}>
          {['Tw', 'Ig', 'Yt', 'Dc'].map((s, i) =>
        <span key={i} style={{ width: 36, height: 36, border: `1px solid ${COLORS.hairline}`, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: COLORS.text, fontFamily: 'JetBrains Mono', fontSize: 11 }}>{s}</span>
        )}
        </div>
      </div>
      {[
    ['League', ['Calendar', 'Results', 'Standings', 'Rules']],
    ['Compete', ['Teams', 'Drivers', 'How to join', 'Code of conduct']],
    ['Garage', ['News', 'Broadcast', 'Discord', 'Contact']]].
    map(([h, items]) =>
    <div key={h}>
          <div style={{ fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.24em', color: COLORS.red, textTransform: 'uppercase', marginBottom: 18 }}>{h}</div>
          {items.map((it) => <div key={it} style={{ color: COLORS.textMute, fontFamily: 'Archivo', fontWeight: 500, fontSize: 14, padding: '7px 0' }}>{it}</div>)}
        </div>
    )}
    </div>
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderTop: `1px solid ${COLORS.hairline}`, paddingTop: 24, color: COLORS.textDim, fontFamily: 'JetBrains Mono', fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase' }}>
      <span>© 2026 Ultimate Racing Esports · All rights reserved</span>
      <span>Privacy · Terms · Cookies</span>
    </div>
  </footer>;


Object.assign(window, { URResultSlot, URNav, URWelcome, URTicker, URHero, URTeams, URHomeStandings, URRecentResults, URDriversPreview, URCalendarPreview, URCalendarRow, URNews, URVideoCard, URFooter, URDriverCard, mapCalRaceToRow, UR_GP_FLAG });