// UR2D Final — DRIVERS.
//   · FDDriversLanding — #drivers: "Current grid" (this season's standings, league by league) | "All-time" (every driver in the
//     results DB, ranked by titles top league first; search + league filter). Every tile opens #driver/<key>.
//   · FDDriverPage — #driver/<key>: one driver's career. Hero (car + ghost number, title wreaths, season + league bands), then
//     Career (season journey + every team) · Trophy Cabinet · Garage (every car raced) · Stats (teammate head-to-head,
//     numbers, racecraft, season chart, circuits, records) · Results. Built from the team page's parts and classes
//     (ur2d-teampage.jsx / .css) so the two read as one family. Data: ur2d-final-driverdata.jsx.
// Load order: after ur2d-teampage.jsx + ur2d-final-driverdata.jsx, before ur2d-final.jsx.

const fddLandCss = `
.fdd-tiles{--cols:4;display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));border-top:1px dashed ${COLORS.hairline};overflow:hidden}
.fdd-tile{all:unset;box-sizing:border-box;cursor:pointer;position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;align-content:start;align-items:center;gap:14px 12px;padding:26px 22px 24px;min-width:0;box-shadow:-1px 0 0 ${COLORS.hairline},0 -1px 0 ${COLORS.hairline};transition:background .2s ease;content-visibility:auto;contain-intrinsic-size:auto 210px}
.fdd-tile::after{content:'';position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tc);transform:scaleX(0);transform-origin:left;transition:transform .25s ease}
.fdd-tile:hover,.fdd-tile:focus-visible{background:rgba(255,255,255,.035)}
.fdd-tile:hover::after,.fdd-tile:focus-visible::after{transform:scaleX(1)}
.fdd-tnum{font-family:'Archivo',sans-serif;font-stretch:62%;font-weight:900;font-size:clamp(24px,2vw,32px);line-height:.85;color:var(--tc);letter-spacing:-.01em}
.fdd-tnum.none{color:rgba(255,255,255,.14)}
.fdd-tpos{justify-self:end;font-family:'JetBrains Mono',monospace;font-size:13px;letter-spacing:.14em;color:${COLORS.textMute}}
.fdd-tpos.p1{color:#F0C53C}
.fdd-twr{justify-self:end;position:relative;display:grid;place-items:center;width:52px;height:52px}
.fdd-twr svg{position:absolute;inset:0;width:100%;height:100%}
.fdd-twr b{position:relative;font-family:'Archivo',sans-serif;font-stretch:64%;font-weight:800;font-size:19px;line-height:1;color:${COLORS.text}}
.fdd-tname{display:flex;align-items:center;gap:12px;min-width:0;font-family:'Archivo',sans-serif;font-weight:800;font-stretch:72%;font-size:clamp(20px,1.8vw,27px);line-height:1.05;text-transform:uppercase;color:${COLORS.text}}
.fdd-tname .no{font-style:normal;font-stretch:62%;font-weight:900;font-size:1.1em;line-height:1;color:var(--tc);flex-shrink:0;min-width:1.4em}
.fdd-tname .no.none{color:rgba(255,255,255,.18)}
.fdd-tname img{width:30px;height:20px;object-fit:cover;flex-shrink:0;box-shadow:0 0 0 1px rgba(255,255,255,.12)}
.fdd-tname span{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fdd-more{all:unset;box-sizing:border-box;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:16px;width:100%;margin-top:-1px;padding:22px 4px;border-top:1px solid ${COLORS.hairline};border-bottom:1px solid ${COLORS.hairline};font-family:'Archivo',sans-serif;font-weight:800;font-size:15px;letter-spacing:.08em;text-transform:uppercase;color:${COLORS.text};transition:color .2s}
.fdd-more:hover,.fdd-more:focus-visible{color:${COLORS.red}}
.fdd-more .fdt-mono{color:${COLORS.textDim}}
.fdd-tteam{grid-column:1/-1;display:flex;align-items:center;gap:8px;min-width:0;font-family:'JetBrains Mono',monospace;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:${COLORS.textMute}}
.fdd-tteam i{width:8px;height:8px;border-radius:50%;background:var(--tc);flex-shrink:0}
.fdd-tteam span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fdd-tmeta{grid-column:1/-1;font-family:'JetBrains Mono',monospace;font-size:12px;line-height:1.5;letter-spacing:.06em;text-transform:uppercase;color:${COLORS.textDim}}
.fdd-tmeta b{font-weight:500;color:${COLORS.text}}
.fdd-tttl{grid-column:1/-1;font-family:'JetBrains Mono',monospace;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:#F0C53C}
.fdd-tlgs{grid-column:1/-1;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin-top:4px}
.fdd-tlgs .lg{display:flex;flex-direction:column;align-items:center;gap:7px;min-width:0}
.fdd-tlgs .w{position:relative;display:grid;place-items:center;width:48px;height:48px}
.fdd-tlgs .w svg{position:absolute;inset:0;width:100%;height:100%}
.fdd-tlgs .w b{position:relative;font-family:'Archivo',sans-serif;font-stretch:64%;font-weight:800;font-size:18px;line-height:1;color:${COLORS.textDim}}
.fdd-tlgs .lg.won .w b{color:${COLORS.text}}
.fdd-tlgs img{height:18px;width:auto;max-width:100%;object-fit:contain}
.fdd-tlgs .lg.off{opacity:.25}
@media (max-width:1180px){.fdd-tiles{--cols:3}}@media (max-width:760px){.fdd-tiles{--cols:2}}@media (max-width:480px){.fdd-tiles{--cols:1}}
.fdd-tools{display:flex;flex-wrap:wrap;align-items:center;gap:12px 18px;padding:24px 0 22px}
.fdd-search{flex:1 1 260px;max-width:420px;display:flex;align-items:center;gap:12px;height:44px;padding:0 14px;border:1px solid ${COLORS.hairline};background:rgba(255,255,255,.03)}
.fdd-search:focus-within{border-color:${COLORS.red}}
.fdd-search input{all:unset;flex:1;min-width:0;font-family:'Archivo',sans-serif;font-size:15px;color:${COLORS.text}}
.fdd-search input::placeholder{color:${COLORS.textDim}}
.fdd-chips{display:flex;gap:6px;flex-wrap:wrap}
.fdd-chip{all:unset;cursor:pointer;height:34px;padding:0 14px;display:inline-flex;align-items:center;border:1px solid ${COLORS.hairline};border-radius:999px;font-family:'JetBrains Mono',monospace;font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:${COLORS.textMute};transition:color .15s,border-color .15s,background .15s}
.fdd-chip:hover,.fdd-chip:focus-visible{color:${COLORS.text}}
.fdd-chip[aria-pressed="true"]{color:#fff;border-color:${COLORS.red};background:color-mix(in oklab,${COLORS.red} 18%,transparent)}
.fdd-chip.lgo{height:40px;padding:0 16px}
.fdd-chip.lgo img{height:22px;width:auto;max-width:64px;object-fit:contain;display:block;opacity:.55;transition:opacity .15s}
.fdd-chip.lgo:hover img,.fdd-chip.lgo:focus-visible img,.fdd-chip.lgo[aria-pressed="true"] img{opacity:1}
.fdd-chips{align-items:center}
.fdd-count{margin-left:auto;color:${COLORS.textDim}}
`;

const fddCss = `
.tp-root.fdd .tp-cine .tp-name{font-size:calc(clamp(52px,7.4vw,132px) * var(--nfit,1));overflow-wrap:anywhere}
@media (max-width:1500px){.tp-root.fdd .tp-cine .tp-name{font-size:calc(clamp(46px,6.2vw,108px) * var(--nfit,1))}}
.tp-root.fdd .fdd-trow{grid-area:logo;display:flex;align-items:center;flex-wrap:wrap;gap:14px 20px;margin-bottom:clamp(16px,2vw,26px);min-width:0}
.tp-root.fdd .fdd-trow>.mk{width:clamp(54px,5vw,80px);height:clamp(54px,5vw,80px);object-fit:contain;flex-shrink:0;filter:drop-shadow(0 0 26px color-mix(in oklab,var(--tc) 50%,transparent))}
.tp-root.fdd .fdd-trow>.tx{display:grid;gap:8px;min-width:0}
.tp-root.fdd .fdd-trow>.tx b{font-stretch:64%;font-weight:800;font-size:clamp(24px,2.2vw,32px);line-height:.92;text-transform:uppercase}
.tp-root.fdd .fdd-trow>.tx i{font-style:normal;color:var(--mute)}
.tp-root.fdd .fdd-crowns{display:flex;flex-wrap:wrap;gap:12px 20px;padding-left:20px;border-left:1px solid var(--line2)}
.tp-root.fdd .fdd-crown{display:inline-flex;align-items:center;gap:10px}
.tp-root.fdd .fdd-crown .w,.tp-root.fdd .fdd-cm .w,.tp-root.fdd .fdd-plw .w{position:relative;display:grid;place-items:center;flex-shrink:0}
.tp-root.fdd .fdd-crown .w{width:60px;height:60px}
.tp-root.fdd .fdd-crown .w svg,.tp-root.fdd .fdd-cm .w svg,.tp-root.fdd .fdd-plw .w svg,.tp-root.fdd .fdd-twr svg{position:absolute;inset:0;width:100%;height:100%}
.tp-root.fdd .fdd-crown .w b{position:relative;font-stretch:64%;font-weight:800;font-size:22px;line-height:1;color:var(--ink)}
.tp-root.fdd .fdd-crown .tx{display:grid;gap:5px}
.tp-root.fdd .fdd-crown .tx b{font-family:'JetBrains Mono',monospace;font-size:12px;font-weight:500;letter-spacing:.16em;color:var(--gold)}
.tp-root.fdd .fdd-crown .tx i{font-style:normal;font-size:10px;color:var(--dim);white-space:nowrap}
.tp-root.fdd .tp-ccar{isolation:isolate}
.tp-root.fdd .tp-ccar>img,.tp-root.fdd .tp-ccar>.ghost{position:relative;z-index:1}
.tp-root.fdd .fdd-ghost{position:absolute;left:50%;top:50%;z-index:0;transform:translate(-50%,-50%);font-family:'Archivo',sans-serif;font-stretch:62%;font-weight:900;font-size:calc(min(28vw,480px) * var(--gfit,1));line-height:.8;letter-spacing:-.02em;color:transparent;-webkit-text-stroke:2px color-mix(in oklab,var(--tc) 80%,transparent);opacity:.42;white-space:nowrap;pointer-events:none;user-select:none}
.tp-root.fdd .fdd-bteam{display:flex;align-items:center;gap:10px;min-width:0}
.tp-root.fdd .fdd-bteam .mk{width:30px;height:30px;object-fit:contain;flex-shrink:0}
.tp-root.fdd .fdd-bteam b{font-stretch:64%;font-weight:800;font-size:22px;line-height:1;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.tp-root.fdd .tp-blu span{grid-template-columns:auto auto minmax(0,1fr) auto}
.tp-root.fdd .fdd-h2h *,.tp-root.fdd .tp-blu b *{display:inline}
.tp-root.fdd .fdd-h2h{font-style:normal;font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.06em;color:var(--mute);white-space:nowrap}
.tp-root.fdd .fdd-disp{display:inline-grid;place-items:center;margin-left:.25em;width:.6em;height:.6em;font-size:.48em;border-radius:50%;background:#d9a13b;color:#111;font-stretch:100%;font-weight:800;vertical-align:.4em;cursor:help}
.tp-root.fdd svg.ur-fmark{display:block}
.tp-root.fdd .fdd-xs{width:20px;height:20px;object-fit:contain;flex-shrink:0}
.tp-root.fdd .tp-jr .c{grid-template-rows:96px auto 46px auto auto}
.tp-root.fdd .fdd-jt{display:inline-block;max-width:100%;padding:3px 6px 2px;background:color-mix(in oklab,var(--tc) 26%,transparent);box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--tc) 60%,transparent);color:var(--ink);font-size:9px;letter-spacing:.1em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tp-root.fdd .fdd-trw{grid-template-columns:56px minmax(0,1.6fr) minmax(0,.7fr) 72px 84px 64px 84px}
.tp-root.fdd .fdd-trw.tp-row{padding:16px 0}
.tp-root.fdd .fdd-trw .mkc{display:grid;place-items:center}
.tp-root.fdd .fdd-trw .mk{width:44px;height:44px;object-fit:contain}
.tp-root.fdd .fdd-trw .nm{display:grid;gap:8px;min-width:0}
.tp-root.fdd .fdd-trw .nm b{font-stretch:64%;font-weight:800;font-size:clamp(24px,2.4vw,34px);line-height:.9;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tp-root.fdd .fdd-trw .nm i{font-style:normal;color:var(--dim);font-size:10px}
.tp-root.fdd .fdd-rrow{grid-template-columns:var(--gut) minmax(0,1.6fr) 72px minmax(0,.8fr) 76px 124px 60px 64px}
.tp-root.fdd .fdd-rrow.tp-row{min-height:78px;padding:12px 0}
.tp-root.fdd .fdd-rrow.focus{background:color-mix(in oklab,var(--tc) 10%,transparent)}
.tp-root.fdd .fdd-rtm{display:flex;align-items:center;gap:9px;min-width:0}
.tp-root.fdd .fdd-rtm span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--mute)}
.tp-root.fdd .fdd-q{display:grid;gap:5px;justify-items:start}
.tp-root.fdd .fdd-q b{font-stretch:64%;font-weight:800;font-size:clamp(20px,1.8vw,26px);line-height:1;color:var(--mute)}
.tp-root.fdd .fdd-q i{font-style:normal;font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.06em}
.tp-root.fdd .fdd-q i.up{color:#6cc287}.tp-root.fdd .fdd-q i.dn{color:#d66a63}
.tp-root.fdd .fdd-nomap{display:block;width:56px;height:36px}
.tp-root.fdd .fdd-craft{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:clamp(28px,4vw,72px);padding-top:clamp(28px,3vw,44px);align-items:start}
.tp-root.fdd .fdd-hist{padding-bottom:26px}
.tp-root.fdd .fdd-hist .bars{display:grid;grid-template-columns:repeat(var(--hn,21),minmax(0,1fr));gap:4px;height:220px;align-items:end;border-bottom:1px solid var(--line2)}
.tp-root.fdd .fdd-hist .bars>span{position:relative;height:100%;display:flex;flex-direction:column;justify-content:flex-end}
.tp-root.fdd .fdd-hist .bars i{display:block;position:relative;min-height:2px;background:color-mix(in oklab,var(--tc) 50%,#2a2a2a)}
.tp-root.fdd .fdd-hist .bars .p1 i{background:var(--mg)}.tp-root.fdd .fdd-hist .bars .p2 i{background:var(--ms)}.tp-root.fdd .fdd-hist .bars .p3 i{background:var(--mb)}
.tp-root.fdd .fdd-hist .bars em{position:absolute;left:50%;bottom:calc(100% + 4px);transform:translateX(-50%);font-style:normal;font-size:9px;color:var(--mute)}
.tp-root.fdd .fdd-hist .bars b{position:absolute;left:0;right:0;top:calc(100% + 8px);text-align:center;font-size:9px;font-weight:500;color:var(--dim)}
.tp-root.fdd .fdd-figs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border-top:1px solid var(--line)}
.tp-root.fdd .fdd-figs>div{display:grid;gap:7px;align-content:start;padding:16px 12px 16px 0;border-bottom:1px solid var(--line);min-width:0}
.tp-root.fdd .fdd-figs>div:not(:nth-child(3n+1)){padding-left:clamp(12px,1.4vw,20px);border-left:1px solid var(--line)}
.tp-root.fdd .fdd-figs .k{font-size:10px;color:var(--dim)}
.tp-root.fdd .fdd-figs b{font-stretch:64%;font-weight:800;font-size:clamp(28px,2.6vw,40px);line-height:.9}
.tp-root.fdd .fdd-figs .sub{font-size:12px;color:var(--mute);line-height:1.3}
.tp-root.fdd .fdd-climb{grid-column:1/-1;display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:6px 24px;align-items:center;width:100%;padding:20px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);text-align:left}
.tp-root.fdd .fdd-climb .k{color:var(--tc)}
.tp-root.fdd .fdd-climb b{white-space:nowrap;font-stretch:64%;font-weight:800;font-size:clamp(32px,3.2vw,48px);line-height:.9}
.tp-root.fdd .fdd-climb .sub{color:var(--mute);font-size:14px}
.tp-root.fdd .fdd-climb .tp-map{width:72px;height:48px;background:var(--mute)}
.tp-root.fdd .fdd-climb:hover .tp-map{background:var(--ink)}
.tp-root.fdd .fdd-circ{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 clamp(24px,3vw,48px);padding-top:8px}
.tp-root.fdd .fdd-cc{display:grid;grid-template-columns:64px minmax(0,1fr) 72px 56px 64px;gap:0 14px;align-items:center;padding:16px 0;border-bottom:1px solid var(--line)}
.tp-root.fdd .fdd-cmap{width:60px;height:40px;background:var(--mute)}
.tp-root.fdd .fdd-cc:hover .fdd-cmap{background:var(--ink)}
.tp-root.fdd .fdd-cc .nm{display:grid;gap:6px;min-width:0}
.tp-root.fdd .fdd-cc .nm b{font-stretch:64%;font-weight:800;font-size:clamp(20px,1.8vw,26px);line-height:.95;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tp-root.fdd .fdd-cc .nm i{display:flex;align-items:center;gap:8px;font-style:normal;color:var(--dim);font-size:10px;white-space:nowrap;overflow:hidden}
.tp-root.fdd .fdd-cc .nm .tp-flag{width:18px;height:12px}
.tp-root.fdd .fdd-cc .fg{display:grid;gap:5px;justify-items:end}
.tp-root.fdd .fdd-cc .fg b{font-stretch:64%;font-weight:800;font-size:22px;line-height:1}
.tp-root.fdd .fdd-cc .fg i{font-style:normal;font-size:9px;color:var(--dim)}
.tp-root.fdd .fdd-twr{position:relative;display:grid;place-items:center;width:clamp(120px,12vw,168px);aspect-ratio:1;margin:0 0 20px;filter:drop-shadow(0 0 26px rgba(226,184,87,.22))}
.tp-root.fdd .fdd-twr b{position:relative;font-stretch:62%;font-weight:800;font-size:clamp(30px,3vw,42px);line-height:1;color:var(--ink)}
.tp-root.fdd .fdd-twr .in{position:relative;width:44%;height:44%;object-fit:contain}
.tp-root.fdd .fdd-tsum{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px}
.tp-root.fdd .fdd-cm{display:inline-flex;align-items:center;gap:8px}
.tp-root.fdd .fdd-cm .w{width:34px;height:34px}
.tp-root.fdd .fdd-cm .w b{position:relative;font-size:14px;margin:0}
.tp-root.fdd .tp-shelf.fdd-shelf{margin-bottom:clamp(20px,2vw,32px)}
.tp-root.fdd .fdd-plw{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));border-bottom:1px solid var(--line);margin-bottom:clamp(20px,2vw,32px)}
.tp-root.fdd .fdd-plw>button,.tp-root.fdd .fdd-plw>div{display:grid;grid-template-columns:64px minmax(0,1fr);gap:16px;align-items:center;padding:20px 16px 20px 0;text-align:left}
.tp-root.fdd .fdd-plw .w{width:64px;height:64px}
.tp-root.fdd .fdd-plw .w b{position:relative;font-stretch:64%;font-weight:800;font-size:18px}
.tp-root.fdd .fdd-plw .w img,.tp-root.fdd .fdd-plw .w svg.in{position:relative!important;inset:auto!important;width:46%!important;height:46%!important;object-fit:contain}
.tp-root.fdd .fdd-plw .tx b{display:block;font-stretch:64%;font-weight:800;font-size:clamp(24px,2.2vw,30px);line-height:.9;text-transform:uppercase;margin-bottom:8px}
.tp-root.fdd .fdd-plw .tx i{font-style:normal;color:var(--dim);font-size:10px}
.tp-root.fdd .fdd-plw>button:hover .tx b{color:var(--tc)}
.tp-root .fdd-sss{max-height:min(60vh,420px);overflow-y:auto}
.tp-root .fdt-crumb .tp-popb{white-space:nowrap}.fdt-crumb .slot{flex-shrink:0}
.fdd-lnum{font-family:'Archivo',sans-serif;font-stretch:62%;font-weight:900;font-size:clamp(90px,10vw,150px);line-height:.8;color:transparent;-webkit-text-stroke:2px var(--tc)}
@media (max-width:1000px){.tp-root.fdd .fdd-craft,.tp-root.fdd .fdd-circ{grid-template-columns:1fr}}
@media (max-width:900px){
.tp-root.fdd .fdd-trw{grid-template-columns:44px minmax(0,1fr) 60px 64px}.tp-root.fdd .fdd-trw>.c-sn,.tp-root.fdd .fdd-trw>.c-st,.tp-root.fdd .fdd-trw>.c-pd{display:none}
.tp-root.fdd .fdd-rrow{grid-template-columns:var(--gut) minmax(0,1fr) 56px 84px 48px}.tp-root.fdd .fdd-rrow>.tp-date,.tp-root.fdd .fdd-rrow>.c-tm,.tp-root.fdd .fdd-rrow>.tp-map,.tp-root.fdd .fdd-rrow>.fdd-nomap,.tp-root.fdd .fdd-rrow>.tp-cmap{display:none}
.tp-root.fdd .fdd-crowns{padding-left:0;border-left:0}}
@media (max-width:640px){.tp-root.fdd .fdd-figs{grid-template-columns:repeat(2,minmax(0,1fr))}.tp-root.fdd .fdd-figs>div:not(:nth-child(3n+1)){padding-left:0;border-left:0}.tp-root.fdd .fdd-figs>div:nth-child(even){padding-left:12px;border-left:1px solid var(--line)}.tp-root.fdd .fdd-cc{grid-template-columns:48px minmax(0,1fr) 64px 56px}.tp-root.fdd .fdd-cc>.fg:last-child{display:none}.tp-root.fdd .fdd-climb{grid-template-columns:1fr}}
`;

const FDD_SECS = [['career', 'Career'], ['trophies', 'Trophy Cabinet'], ['garage', 'Garage'], ['stats', 'Stats'], ['results', 'Results']];
const fddPad = (n) => String(n).padStart(2, '0');
const fddOrd = (n) => (typeof n === 'number' ? n + window.TP.ord(n) : '—');
const fddLgName = (lg) => (window.TP && window.TP.LEAGUES[lg]) || lg;
const fddRowId = (k, n) => 'dr-' + String(k).replace(/[^a-z0-9]/gi, '-') + '-' + n;
const fddWr = (size, color) => (typeof URWreath === 'function' ? <URWreath size={size} color={color} /> : null);
const FDD_GOLD = '#e2b857', FDD_SILVER = '#c7cbd1', FDD_BRONZE = '#c0813e';
function fddScrollTo(id) {
  const el = document.getElementById(id), h = el && (el.querySelector('.tp-sh') || el);
  if (h) window.scrollTo({ top: h.getBoundingClientRect().top + window.scrollY - 96 - 72, behavior: 'smooth' });
}
function fddRuns(ns) { // [1,2,3,5,6] → "R1–3, R5–6"
  const a = [...ns].sort((x, y) => x - y), out = [];
  for (let i = 0; i < a.length; i++) { let j = i; while (j + 1 < a.length && a[j + 1] === a[j] + 1) j++; out.push(i === j ? 'R' + a[i] : 'R' + a[i] + '–' + a[j]); i = j; }
  return out.join(', ');
}

const FDDCtx = React.createContext(null);
const FDDMark = ({ t, cls = 'mk' }) => {
  const [bad, setBad] = React.useState(false);
  React.useEffect(() => setBad(false), [t && t.logo]);
  if (!t) return null;
  if (t.logo && !bad) return <img className={cls} src={t.logo} alt="" loading="lazy" onError={() => setBad(true)} />;
  return <URFranchiseMark className={cls} code={t.independent ? 'IND' : t.short} color={t.independent ? '#3A3F45' : t.color} title={t.name} />;
};
const FDDLink = ({ r, go, children }) => (r ? <a href={'#' + r} onClick={(e) => { if (e.metaKey || e.ctrlKey || e.shiftKey) return; e.preventDefault(); go(r); }}>{children}</a> : children);
const FDDCrown = ({ n, k, sub }) => (
  <span className="fdd-crown" title={`${n} ${k === 'WDC' ? "drivers'" : "constructors'"} title${n > 1 ? 's' : ''}`}>
    <span className="w">{fddWr(60, FDD_GOLD)}<b>{n}</b></span>
    <span className="tx"><b>{k}</b><i className="mono">{sub}</i></span>
  </span>);

// ─── LANDING ─────────────────────────────────────────────────────────────────
const FDD_TAB_KEY = 'ur2d-drivers-tab';
const fddGetTab = () => { try { return sessionStorage.getItem(FDD_TAB_KEY) === 'all' ? 'all' : 'current'; } catch (e) { return 'current'; } };
const fddSetTab = (v) => { try { sessionStorage.setItem(FDD_TAB_KEY, v); } catch (e) {} };

const FDDGridRow = ({ L, go }) => {
  const sid = fddCurLabel(L.id), data = useStandings(L.id, sid);
  useFddIndex(); // keys for drivers without a roster record resolve once the index lands
  const teamBased = !UR2D_ADAPTERS[L.id] || UR2D_ADAPTERS[L.id].teamBased !== false;
  const teams = {};
  (data.teams || []).forEach((t) => { teams[t.short] = t; });
  const rows = (data.drivers || []).filter((d) => d && d.name);
  const busy = data.status === 'loading' && !rows.length;
  const warm = (d) => { fddLoadProfile(fddKeyForName(d.name)); };
  return (
    <div className="fdt-wall" data-league={L.id}>
      <div className="fdt-lg">
        <img src={L.logo} alt="" />
        <div style={{ minWidth: 0 }}>
          <div className="fdt-lgn">{L.name}</div>
          <div className="fdt-mono" style={{ color: L.accent, marginTop: 7 }}>{rows.length ? rows.length + ' drivers' : busy ? 'Loading' : 'TBA'}{sid ? ' · ' + sid : ''}</div>
        </div>
      </div>
      {!rows.length ? <div className="fdt-solo fdt-mono">{busy ? 'Loading the standings…' : 'No results yet this season.'}</div> :
        <div className="fdd-tiles">{rows.map((d) => {
          const t = d.team && d.team !== 'IND' ? teams[d.team] : null, col = (t && t.color) || L.accent || '#8C9198';
          return (
            <button key={d.name + d.pos} className="fdd-tile" style={{ '--tc': col }} title={`${d.name} — open career page`}
              onClick={() => go(fddRoute(fddKeyForName(d.name)))} onMouseEnter={() => warm(d)} onFocus={() => warm(d)} onTouchStart={() => warm(d)}>
              <span className="fdd-tname"><em className={'no' + (d.carNumber == null ? ' none' : '')}>{d.carNumber != null ? d.carNumber : '—'}</em><img src={urFlagImg(d.country || getRosterCountry(d.name) || 'un')} alt="" /><span>{d.name}</span></span>
              <span className={'fdd-tpos' + (d.pos === 1 ? ' p1' : '')}>P{d.pos}</span>
              {teamBased && <span className="fdd-tteam"><i></i><span>{t ? t.name : 'Independent'}</span></span>}
              <span className="fdd-tmeta"><b>{d.pts}</b> pts{d.wins ? ` · ${d.wins} win${d.wins > 1 ? 's' : ''}` : ''}{d.podiums ? ` · ${d.podiums} pod.` : ''}</span>
            </button>);
        })}</div>}
    </div>);
};

const FDDAllTime = ({ go }) => {
  const { status, idx } = useFddIndex();
  const [q, setQ] = React.useState(''), [lg, setLg] = React.useState('all');
  const list = React.useMemo(() => {
    if (!idx) return [];
    const n = fddN(q);
    const out = idx.list.filter((g) => g.seasons.length && (lg === 'all' || g.leagues.includes(lg)) &&
      (!n || fddN(g.name).includes(n) || g.names.some((x) => fddN(x).includes(n)) || (g.person && fddN(g.person.display).includes(n))));
    // One league picked → that league's titles, then its points, then its wins (user 2026-10-09)
    if (lg !== 'all') out.sort((a, b) => (b.titlesBy[lg] || 0) - (a.titlesBy[lg] || 0) || (b.ptsBy[lg] || 0) - (a.ptsBy[lg] || 0) || (b.winsBy[lg] || 0) - (a.winsBy[lg] || 0) || a.name.localeCompare(b.name));
    return out;
  }, [idx, q, lg]);
  const [shown, setShown] = React.useState(24);
  React.useEffect(() => setShown(24), [q, lg]);
  if (status !== 'ready') return <div className="fdt-solo fdt-mono" style={{ paddingTop: 24 }}>{status === 'error' ? 'The results archive is unreachable right now.' : 'Loading the archive…'}</div>;
  const accent = (g) => { const top = ['UL', 'CL', 'JL', 'AL'].find((l) => g.leagues.includes(l)); const L = LEAGUES.find((x) => x.short === top); return (L && L.accent) || COLORS.red; };
  const span = (g) => (g.first ? `${fddLgS(g.first.lg)} ${g.first.label}${g.seasons.length > 1 ? ` → ${g.last.lg === g.first.lg ? '' : fddLgS(g.last.lg) + ' '}${g.last.label}` : ''}` : '');
  const titleLine = (g) => ['UL', 'CL', 'JL', 'AL'].filter((l) => g.titlesBy[l]).map((l) => `${g.titlesBy[l] > 1 ? g.titlesBy[l] + '× ' : ''}${l} champion`).join(' · ');
  return (
    <div className="fdt-walls"><div className="fdt-wall">
      <div className="fdd-tools">
        <label className="fdd-search"><span className="fdt-mono" style={{ color: COLORS.textDim }}>Find</span><input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Driver name" aria-label="Search drivers" /></label>
        <div className="fdd-chips">{[['all', 'All', null], ...LEAGUES.map((L) => [L.short, L.name, L.logo])].map(([k, l, logo]) =>
          <button key={k} className={'fdd-chip' + (logo ? ' lgo' : '')} aria-pressed={lg === k ? 'true' : 'false'} onClick={() => setLg(k)} title={logo ? l : 'All leagues'}>{logo ? <img src={logo} alt={k} /> : l}</button>)}</div>
        <span className="fdt-mono fdd-count">{list.length} drivers · {lg === 'all' ? 'by titles, top league first' : `by ${lg} titles, then points, then wins`}</span>
      </div>
      {list.length ?
        <div className="fdd-tiles">{list.slice(0, shown).map((g) =>
          <button key={g.key} className="fdd-tile" style={{ '--tc': accent(g) }} title={`${g.name} — ${g.seasons.length} season${g.seasons.length > 1 ? 's' : ''}${g.titles.length ? ' · champion ' + g.titles.join(', ') : ''} — open career page`}
            onClick={() => go(fddRoute(g.key))} onMouseEnter={() => fddLoadProfile(g.key)} onFocus={() => fddLoadProfile(g.key)} onTouchStart={() => fddLoadProfile(g.key)}>
            <span className="fdd-tname" style={{ gridColumn: '1 / -1' }}><em className={'no' + (g.num == null ? ' none' : '')}>{g.num != null ? g.num : '—'}</em><img src={urFlagImg(g.cc || 'un')} alt="" loading="lazy" /><span>{g.name}</span></span>
            <span className="fdd-tlgs">{LEAGUES.map((L) => { const n = g.titlesBy[L.short] || 0, raced = g.leagues.includes(L.short); return (
              <span key={L.id} className={'lg' + (raced ? '' : ' off') + (n ? ' won' : '')} title={`${L.name} · ${raced ? n + ' title' + (n === 1 ? '' : 's') : 'never raced'}`}>
                <span className="w">{fddWr(48, n ? FDD_GOLD : 'rgba(243,241,236,.22)')}<b>{n}</b></span><img src={L.logo} alt={L.short} loading="lazy" />
              </span>); })}</span>
          </button>)}</div> :
        <div className="fdt-solo fdt-mono">No driver matches “{q}”.</div>}
      {list.length > shown && <button className="fdd-more" onClick={() => setShown((n) => n + 24)}><span>Show more drivers</span><span className="fdt-mono">{shown} of {list.length}</span></button>}
    </div></div>);
};

const FDDriversLanding = ({ go }) => {
  const cur = getCalendarSeasons().find((s) => s.isCurrent);
  const [tab, setTabS] = React.useState(fddGetTab);
  const setTab = (k) => { setTabS(k); fddSetTab(k); };
  React.useEffect(() => { const ric = window.requestIdleCallback || ((f) => setTimeout(f, 300)); ric(() => { fddIndex().catch(() => {}); }); }, []);
  return (
    <section className="fdt-page" data-screen-label="Final — Drivers">
      <style>{window.fdtCss || ''}</style>
      <style>{fddLandCss}</style>
      <UR2SectionHead
        kicker={`Drivers${cur && cur.period ? ' · ' + cur.period : ''}`}
        title={<span>Pick a <span style={{ color: COLORS.red }}>driver.</span></span>}
        right={<div style={{ maxWidth: 360, color: COLORS.textMute, fontSize: 15, lineHeight: 1.55 }}>{tab === 'current' ? 'Everyone racing this season, league by league, in championship order. Open one for their whole career.' : 'Every driver who has raced in UR2D, all leagues together, ranked by championships in the top leagues.'}</div>} />
      <div className="fdt-tabs" role="tablist">
        {[['current', 'Current grid'], ['all', 'All-time']].map(([k, label]) =>
          <button key={k} className="fdt-tab" role="tab" aria-selected={tab === k ? 'true' : 'false'} onClick={() => setTab(k)}>{label}</button>)}
      </div>
      {tab === 'current' ? <div className="fdt-walls">{LEAGUES.map((L) => <FDDGridRow key={L.id} L={L} go={go} />)}</div> : <FDDAllTime go={go} />}
    </section>);
};

// ─── DRIVER PAGE ─────────────────────────────────────────────────────────────
function useFddSpy() {
  const [a, setA] = React.useState('overview');
  React.useEffect(() => {
    const f = () => {
      let cur = 'overview';
      FDD_SECS.forEach(([id]) => { const el = document.getElementById('fdd-' + id), h = el && (el.querySelector('.tp-sh') || el); if (h && h.getBoundingClientRect().top < 272) cur = id; });
      setA(cur);
    };
    f();
    window.addEventListener('scroll', f, { passive: true });
    return () => window.removeEventListener('scroll', f);
  }, []);
  return a;
}
function FDDSNav({ P, active }) {
  const top = (e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); };
  return (
    <div className="tp-snav"><div className="tp-wrap">
      <a className="id" href="#" onClick={top}>{P.id.num != null && <em className="tp-dno">#{P.id.num}</em>}<span>{P.id.name}</span></a>
      <nav>
        <a href="#" className={active === 'overview' ? 'on' : ''} onClick={top}><i>00</i>Overview</a>
        {FDD_SECS.map(([id, l], k) => <a key={id} href="#" className={active === id ? 'on' : ''} onClick={(e) => { e.preventDefault(); fddScrollTo('fdd-' + id); }}><i>{fddPad(k + 1)}</i>{l}</a>)}
      </nav>
    </div></div>);
}
function fddRole(P, s) {
  const now = s.live ? P.now.find((x) => x.site === s.site) : null, t = s.team;
  const role = now ? (now.role === 'main' ? 'Race driver' : now.role === 'reserve' ? 'Reserve driver' : 'Independent')
    : t && !t.independent ? (s.starts * 2 >= s.rounds.length ? 'Race driver' : 'Stand-in') : 'Independent';
  return role + ' · ' + fddSn(s) + (s.erTeams ? ' · ER for ' + s.erTeams.join(', ') : '');
}

function FDDNowBand() {
  const { P, s, go } = React.useContext(FDDCtx);
  return (
    <div className="tp-band now">
      <span className="bl"><span className="tp-chip">{fddSn(s)}</span><i className="mono">{s.live ? 'Live' : s.period || 'Final'}</i></span>
      <div className="bc"><span className="mono k">This season</span>
        <div className="tp-nstat two">
          <span><b>{s.pos ? <TPOrd n={s.pos} /> : '—'}</b><i className="mono">{s.wdc ? 'Champion' : 'Position'}</i></span>
          <span><b>{s.pts}{s.disputed && <span className="fdd-disp" title={`Disputed · Mega Table ${s.disputed.mt} · database ${s.disputed.db}`}>≠</span>}</b><i className="mono">Points</i></span>
        </div>
      </div>
      <div className="bc wide"><span className="mono k" aria-hidden="true">&nbsp;</span>
        <div className="tp-nstat">{[['Wins', s.wins], ['Pods', s.podiums], ['Poles', s.poles], ['FLs', s.fl]].map(([l, v]) => <span key={l}><b>{v != null ? v : '—'}</b><i className="mono">{l}</i></span>)}</div>
      </div>
      <div className="bc"><span className="mono k">Teammate</span>
        {s.mates.length ?
          <div className="tp-blu">{s.mates.slice(0, 2).map((m) => <span key={m.key} title={`Teammate · ${m.n} races together · race head-to-head ${m.r[0]}–${m.r[1]}`}><em className="tp-dno">{m.num != null ? '#' + m.num : '—'}</em><TPFlag cc={m.cc} /><b><FDDLink r={fddRoute(m.key)} go={go}>{m.name}</FDDLink></b><em className="fdd-h2h">{`H2H ${m.r[0]}–${m.r[1]}`}</em></span>)}</div> :
          <span className="mono tp-mute">{s.site === 'al' ? 'Solo league' : s.team && s.team.independent ? 'Independent' : 'No teammate on record'}</span>}
      </div>
    </div>);
}
function FDDLeagueBand({ x }) {
  const { go, former } = React.useContext(FDDCtx);
  const h = x.home, lgName = fddLgName(x.lg).replace(/ League$/, '');
  const crowns = [['WDC', x.wdc, "drivers' titles"], ...(x.lg === 'AL' ? [] : [['WCC', x.wcc, "constructors' titles with the team"]])];
  return (
    <div className="tp-band hist">
      <span className="bl"><span className="tp-chip">{fddLgS(x.lg)}</span><i className="mono">Since {x.since}</i></span>
      <div className="bc"><span className="mono k" style={{ whiteSpace: 'nowrap' }}>All time in {lgName} League</span>
        <div className="tp-nstat two"><span><b>{x.seasons}</b><i className="mono">{x.seasons === 1 ? 'Season' : 'Seasons'}</i></span><span><b>{x.best ? 'P' + x.best : '—'}</b><i className="mono">Best finish</i></span></div>
      </div>
      <div className="bc wide"><span className="mono k" aria-hidden="true">&nbsp;</span>
        <div className="tp-nstat" style={{ gridTemplateColumns: 'repeat(5, minmax(0,1fr))' }}>{[['Starts', x.starts], ['Wins', x.wins], ['Pods', x.podiums], ['Poles', x.poles], ['FLs', x.fl]].map(([l, v]) => <span key={l}><b>{v}</b><i className="mono">{l}</i></span>)}</div>
      </div>
      <div className="bc"><span className="mono k">{x.lg === 'AL' ? 'Most raced car' : 'Most raced for'}</span>
        {h ? <div className="tp-lgbox">
          <div className="tp-lgmain">
            <div className="fdd-bteam" style={{ '--tc': h.t.color }}><FDDMark t={h.t} cls="mk" /><b><FDDLink r={fddTeamRoute(h.t, former)} go={go}>{h.t.name}</FDDLink></b></div>
            <div className="tp-lgd">{[['Seasons', h.seasons], ['Starts', h.starts], ['Wins', h.wins]].map(([l, v]) => <span key={l}><b>{v}</b><i className="mono">{l}</i></span>)}</div>
          </div>
          <div className="tp-lgt">{crowns.map(([l, v, full]) =>
            <span key={l} className={'tw' + (v ? '' : ' z')} title={`${v} ${full} · ${lgName} League`}><span className="w">{fddWr(44, v ? FDD_GOLD : 'rgba(243,241,236,.28)')}<b>{v}</b></span><i className="mono">{l}</i></span>)}</div>
        </div> : null}
      </div>
    </div>);
}
function FDDHero() {
  const { P, s, go, former } = React.useContext(FDDCtx);
  const id = P.id, A = P.all, t = s.team, L = LEAGUE_BY_ID[s.site];
  const car = (s.cars.find((c) => !c.special && c.file) || s.cars.find((c) => c.file) || {}).file || (t && t.livery) || null;
  const lastDone = P.seasons.find((x) => !x.live && x.starts > 0);
  const reign = lastDone && lastDone.wdc ? lastDone : null;
  const longest = Math.max(1, ...id.lines.map((x) => String(x || '').length));
  const nfit = longest > 9 ? Math.max(0.46, 9 / longest) : 1;
  const gfit = String(id.num != null ? id.num : '').length >= 3 ? 0.66 : 1;
  return (
    <section className="tp-cine" data-screen-label="Driver hero">
      <div className="tp-cbg" aria-hidden="true"></div>
      <div className="tp-wrap tp-ctop">
        <div className="fdd-trow">
          {t && <FDDMark t={t} cls="mk" />}
          <span className="tx"><b><FDDLink r={fddTeamRoute(t, former)} go={go}>{t ? t.name : 'Independent'}</FDDLink></b><i className="mono">{fddRole(P, s)}</i></span>
          {(A.titles.length > 0 || A.wccs.length > 0) && <span className="fdd-crowns">
            {A.titles.length > 0 && <FDDCrown n={A.titles.length} k="WDC" sub={reign ? 'Reigning · ' + fddSn(reign) : "Drivers' titles"} />}
            {A.wccs.length > 0 && <FDDCrown n={A.wccs.length} k="WCC" sub="Constructors' titles" />}
          </span>}
        </div>
        <span className="mono tp-ckick">{L ? L.name : ''} · Season {s.num}{id.num != null && <React.Fragment> · <b>#{id.num}</b></React.Fragment>}{id.display && <React.Fragment> · aka {id.display}</React.Fragment>}</span>
        <h1 className="tp-name" style={{ '--nfit': nfit }}><span>{id.lines[0]}<TPFlag cc={id.cc} cls="tp-flag-xl" /></span>{id.lines[1] && <span>{id.lines[1]}</span>}</h1>
        <div className="tp-ccar" style={{ '--gfit': gfit }}>
          {id.num != null && <span className="fdd-ghost" aria-hidden="true">{id.num}</span>}
          {car ? <img src={car} alt={`${id.name} · ${t ? t.name : 'Independent'} · ${fddSn(s)}`} /> : <span className="ghost"></span>}
        </div>
      </div>
      <div className="tp-wrap tp-bands" ref={tpBandsGutter}>
        <FDDNowBand />
        {A.leagues.map((x) => <FDDLeagueBand key={x.lg} x={x} />)}
      </div>
    </section>);
}

// 01 · CAREER — one column per season (oldest → newest) + every team raced for
function FDDJourney() {
  const { P, jump } = React.useContext(FDDCtx);
  const A = P.all, L = P.seasons.filter((s) => s.starts > 0).slice().reverse(), n = L.length;
  const ref = React.useRef(null);
  React.useLayoutEffect(() => { const el = ref.current; if (el && el.scrollWidth > el.clientWidth) el.scrollLeft = el.scrollWidth; }, [n, P.key]);
  const bands = [];
  L.forEach((s, k) => { const b = bands[bands.length - 1]; if (b && b.lg === s.lg) b.to = k; else bands.push({ lg: s.lg, from: k, to: k }); });
  const promo = {}; A.promos.forEach((p) => { promo[p.k] = p; });
  return (
    <div className="tp-jr" ref={ref} style={{ '--n': n }}>
      <p className="tp-jsum mono"><span className="lg"><TPCup kind="wdc" /><b>{A.titles.length}</b> WDC</span>{A.wccs.length > 0 && <span className="lg"><TPCup kind="wcc" /><b>{A.wccs.length}</b> WCC</span>} · <b>{A.wins}</b> wins · <b>{A.podiums}</b> podiums · <b>{A.poles}</b> poles · <b>{A.teams.length}</b> {A.teams.length === 1 ? 'team' : 'teams'} · <b>{n}</b> seasons</p>
      <div className="cols">{L.map((s) => {
        const pods = s.podList.slice().sort((a, b) => a.pos - b.pos), last = s.rounds[s.rounds.length - 1], pl = !s.live && s.pos && s.pos <= 3, pr = promo[s.k];
        return (
          <div key={s.k} className={'c' + (s.wdc ? ' t' : pl ? ' pl' : '')} style={{ '--tc': s.team ? s.team.color : undefined, alignContent: 'end', gridTemplateRows: s.wdc ? 'auto 96px auto 46px auto auto' : undefined }}>
            {pr && <span className="promo mono" title={`First season in the ${fddLgName(pr.to)}`}>↑ {fddLgS(pr.to)}</span>}
            {s.wdc && <span className="lab mono"><span className="tk wdc">WDC</span></span>}
            <button className="tro" onClick={() => jump(s.k, last ? last.n : 1)} title={`${fddSn(s)} · ${s.pos ? fddOrd(s.pos) + ' in the drivers\'' : 'unranked'} · ${s.pts} pts${s.team ? ' · ' + s.team.name : ''}`}>
              {s.wdc ? <TPCup kind="wdc" /> : pl ? <TPCup kind="place" cls={'p' + s.pos} /> : s.pos ?
                <span className="posc" style={{ display: 'grid', placeItems: 'center', width: 58, height: 58, marginBottom: 8, borderRadius: '50%', border: '2px solid var(--tc)', background: 'color-mix(in oklab, var(--tc) 22%, transparent)', color: 'var(--ink)', fontFamily: "'Archivo', sans-serif", fontStretch: '64%', fontWeight: 800, fontSize: s.pos >= 10 ? 21 : 24, lineHeight: 1 }}>{'P' + s.pos}</span> : <span className="slot"></span>}
            </button>
            <span className="lab mono" aria-hidden={s.wdc || !pl ? 'true' : undefined} style={s.wdc || !pl ? { visibility: 'hidden' } : undefined}>{fddOrd(s.pos)}</span>
            <div className="pips">{pods.map((g, i) => <button key={i} className={'p' + g.pos} onClick={() => jump(s.k, g.n)} title={`P${g.pos} · R${g.n} ${g.gp}`}></button>)}</div>
            <span className="sid"><b>{s.label}</b></span>
            <span className="fdd-jt mono" title={s.team ? s.team.name : ''}>{s.team ? s.team.short : '—'}</span>
          </div>);
      })}</div>
      <div className="lgs">{bands.map((b) => <span key={b.from} style={{ gridColumn: `${b.from + 1} / ${b.to + 2}` }} className="mono">{fddLgName(b.lg)}</span>)}</div>
    </div>);
}
function FDDTeamsTable() {
  const { P, go, former } = React.useContext(FDDCtx);
  return (
    <div className="fdd-teams">
      <div className="tp-lh fdd-trw"><span></span><span>Team</span><span className="c-sn">Seasons</span><span className="r c-st">Starts</span><span className="r">Pts</span><span className="r">Wins</span><span className="r c-pd">Podiums</span></div>
      {P.all.teams.map((x) =>
        <div className="tp-row fdd-trw" key={x.key} style={{ '--tc': x.t.color }}>
          <span className="mkc"><FDDMark t={x.t} cls="mk" /></span>
          <span className="nm"><b><FDDLink r={fddTeamRoute(x.t, former)} go={go}>{x.t.name}</FDDLink></b><i className="mono">{x.current ? 'Current team · ' : ''}{x.span}</i></span>
          <span className="mono tp-mute c-sn">{x.n} {x.n === 1 ? 'season' : 'seasons'}</span>
          <span className="tp-v r c-st">{x.starts}</span><span className="tp-v r">{x.pts}</span><span className="tp-v r">{x.wins}</span><span className="tp-v r c-pd">{x.podiums}</span>
        </div>)}
    </div>);
}
function FDDCareerSec() {
  const { P } = React.useContext(FDDCtx);
  const A = P.all;
  return (
    <TPSection id="fdd-career" i="01" title="Career" desc="">
      <FDDJourney />
      <TPSub i="A" title="Teams" meta={`${A.teams.length} ${A.teams.length === 1 ? 'team' : 'teams'} · ${A.starts} starts`} />
      <FDDTeamsTable />
    </TPSection>);
}

// 02 · TROPHY CABINET — titles as wreaths, championship podiums, then every race podium as its circuit
function FDDPodWall() {
  const { P, jump } = React.useContext(FDDCtx);
  const A = P.all, [by, setBy] = React.useState('season');
  if (!A.podList.length) return null;
  const cup = (g, k) => <button key={k} className={'cup p' + g.pos} onClick={() => jump(g.k, g.n)} title={`P${g.pos} · ${g.sn} R${g.n} ${g.gp}`}>{g.map ? <TPMap k={g.map} cls="g" /> : <span className="gm">{g.pos}</span>}</button>;
  const wp = (p) => <i className="mono">{p.filter((g) => g.pos === 1).length}W · {p.length}P</i>;
  const seasons = P.seasons.map((s) => ({ s, p: s.podList.slice().sort((a, b) => a.n - b.n) })).filter((x) => x.p.length);
  const teams = A.teams.map((x) => ({ x, p: A.podList.filter((g) => g.team && g.team.key === x.key).slice().reverse() })).filter((o) => o.p.length);
  return (
    <div className="tp-twall">
      <div className="hd"><span className="mono">Race podiums · {A.podList.length}</span>
        <div className="seg">{[['season', 'By season'], ['team', 'By team']].map(([k, l]) => <button key={k} className={by === k ? 'on' : ''} onClick={() => setBy(k)}>{l}</button>)}</div>
      </div>
      <div className="rows">{by === 'season' ?
        seasons.map(({ s, p }) => <div key={s.k} className="row"><span className="who"><b>{s.label}</b><span className="mono lgt">{fddLgS(s.lg)}</span>{wp(p)}</span><div className="cups">{p.map(cup)}</div></div>) :
        teams.map(({ x, p }) => <div key={x.key} className="row"><span className="who" style={{ '--tc': x.t.color }}><FDDMark t={x.t} cls="fdd-xs" /><b>{x.t.short}</b>{wp(p)}</span><div className="cups">{p.map(cup)}</div></div>)}</div>
    </div>);
}
function FDDTrophies() {
  const { P, jump } = React.useContext(FDDCtx);
  const A = P.all, last = (s) => s.rounds[s.rounds.length - 1] || { n: 1, track: {} };
  const empty = !A.titles.length && !A.wccs.length && !A.champPods.length && !A.podList.length;
  const cm = (n, k) => <span className="fdd-cm"><span className="w">{fddWr(34, n ? FDD_GOLD : 'rgba(243,241,236,.28)')}<b>{n}</b></span>{k}</span>;
  return (
    <TPSection id="fdd-trophies" i="02" title="Trophy Cabinet" desc="">
      {!empty && <p className="tp-jsum mono fdd-tsum">{cm(A.titles.length, 'WDC')}{cm(A.wccs.length, 'WCC')}<span>· <b>{A.champPods.length}</b> championship podiums · <b>{A.wins}</b> wins · <b>{A.podList.length}</b> race podiums</span></p>}
      {empty && <div className="tp-void" aria-label="No honours yet">
        <div className="plinths">{[0, 1, 2].map((k) => <span key={k}><i></i></span>)}</div>
        <span className="shelf"></span>
        <p className="mono">The cabinet is waiting · best championship finish {A.bestPos ? fddOrd(A.bestPos.pos) + ' in ' + fddSn(A.bestPos) : '—'}</p>
      </div>}
      {A.titles.length > 0 && <React.Fragment>
        <div className="tp-cap mono tp-tcap"><span>Drivers' championships · {A.titles.length}</span><span>Click one for the deciding race</span></div>
        <div className="tp-shelf fdd-shelf">{A.titles.map((s) => { const r = last(s); return (
          <button className="tp-tro p1" key={s.k} onClick={() => jump(s.k, r.n)}>
            <span className="mono k">WDC · {fddSn(s)}</span>
            <span className="fdd-twr">{fddWr(168, FDD_GOLD)}<b>{s.label}</b></span>
            <h3>Drivers' champion</h3>
            <p className="mono">{s.team ? s.team.name + ' · ' : ''}{s.pts} pts · {s.wins} wins →</p>
          </button>); })}</div>
      </React.Fragment>}
      {A.wccs.length > 0 && <React.Fragment>
        <div className="tp-cap mono tp-tcap"><span>Constructors' championships · {A.wccs.length}</span><span>Won as a team driver</span></div>
        <div className="fdd-plw">{A.wccs.map((s) => <button key={s.k} style={{ '--tc': s.team.color }} onClick={() => jump(s.k, last(s).n)}>
          <span className="w">{fddWr(64, FDD_GOLD)}<FDDMark t={s.team} cls="in" /></span>
          <span className="tx"><b>{s.team.name}</b><i className="mono">WCC · {fddSn(s)}</i></span>
        </button>)}</div>
      </React.Fragment>}
      {A.champPods.length > 0 && <React.Fragment>
        <div className="tp-cap mono tp-tcap"><span>Championship podiums · {A.champPods.length}</span><span>Seasons finished 2nd or 3rd</span></div>
        <div className="fdd-plw">{A.champPods.map((s) => <button key={s.k} style={{ '--tc': s.team ? s.team.color : undefined }} onClick={() => jump(s.k, last(s).n)}>
          <span className="w">{fddWr(64, s.pos === 2 ? FDD_SILVER : FDD_BRONZE)}<b>P{s.pos}</b></span>
          <span className="tx"><b>{fddOrd(s.pos)} · {fddSn(s)}</b><i className="mono">{s.team ? s.team.name + ' · ' : ''}{s.pts} pts</i></span>
        </button>)}</div>
      </React.Fragment>}
      <FDDPodWall />
    </TPSection>);
}

// 03 · GARAGE — every car raced, newest first (round specials before that season's car)
function FDDGarage() {
  const { P, sel } = React.useContext(FDDCtx);
  const cars = P.all.cars;
  const [i, setI] = React.useState(() => Math.max(0, cars.findIndex((c) => c.s.k === sel)));
  React.useEffect(() => { const k = cars.findIndex((c) => c.s.k === sel); if (k >= 0) setI(k); }, [sel]);
  const filmRef = React.useRef(null), [bar, setBar] = React.useState(null);
  React.useLayoutEffect(() => {
    const f = filmRef.current, b = f && f.querySelector('button.on');
    setBar(b ? { left: b.offsetLeft, width: b.offsetWidth } : null);
    if (f && b && (b.offsetLeft < f.scrollLeft || b.offsetLeft + b.offsetWidth > f.scrollLeft + f.clientWidth)) f.scrollTo({ left: Math.max(0, b.offsetLeft - 40), behavior: 'smooth' });
  }, [i, cars.length]);
  if (!cars.length) return null;
  const c = cars[Math.min(i, cars.length - 1)], s = c.s, t = c.t;
  const step = (d) => setI((k) => (k + d + cars.length) % cars.length);
  const spec = [['Races', c.races, 'hi'], ['Points', c.pts, 'hi'], ['Wins', c.wins], ['Podiums', c.podiums], ['Poles', c.poles]];
  return (
    <TPSection id="fdd-garage" i="03" title="Garage" desc="">
      <div className="tp-bleed tp-poster v-poster bg-logo" style={{ '--tc': t.color }}>
        {t.logo && <img className="tp-pbglogo" src={t.logo} alt="" aria-hidden="true" />}
        <div className="tp-wrap tp-pgrid">
          <div className="tp-pspec2">
            <div className="lv"><span className="mono">Livery</span><b>{c.name}</b></div>
            <div className="hd sm"><b>{fddSn(s)}</b><span className="mono">{fddLgName(s.lg)}{s.period ? ' · ' + s.period : ''}</span></div>
            <dl>{spec.map(([k, v, cl]) => <div key={k} className={cl || ''}><dd>{v}</dd><dt className="mono">{k}</dt></div>)}</dl>
            <div className="dr"><span className="mono">Team · {fddRuns(c.ns)}</span><b>{t.name}</b></div>
          </div>
          <div className="tp-part" key={c.key}>
            {c.file ? <img className="tp-pcar" src={c.file} alt={`${c.name} · ${t.name} · ${fddSn(s)}`} /> : <span className="tp-pcar ghost"></span>}
            {!c.file && <span className="tp-pna mono">Livery not archived yet</span>}
            <span className="tp-pcap"><b>{c.name}</b><i className="mono">{t.name} · {fddSn(s)}{c.special ? ' · ' + (c.rl ? 'Round ' + c.rl : 'Special') : ''}</i></span>
          </div>
          <div className="tp-pside">
            <span className="tp-pvert mono">{P.id.name} · {fddSn(s)}</span>
            {s.wdc && !c.special && <span className="tp-pchamp mono">◆ Title car</span>}
            {c.special && <span className="tp-pchamp mono">◆ {c.rl ? 'Round ' + c.rl + ' special' : 'Special livery'}</span>}
            <div className="tp-ctl"><button onClick={() => step(-1)}>← Prev</button><span className="mono">{fddPad(i + 1)} / {fddPad(cars.length)}</span><button onClick={() => step(1)}>Next →</button></div>
          </div>
        </div>
      </div>
      <div className="tp-film" ref={filmRef}>{bar && <i className="tp-filmbar" aria-hidden="true" style={{ left: bar.left, width: bar.width }}></i>}
        {cars.map((x, k) => <button key={x.key} className={(x.special ? 'sp' : '') + (k === i ? ' on' : '')} onClick={() => setI(k)}>
          {x.file ? <img src={x.file} alt="" loading="lazy" /> : <span className="ghost"></span>}
          <b>{x.special ? x.name : x.t.independent ? 'IND' : x.t.short + '-' + x.s.num}</b>
          <span className="mono">{fddSn(x.s)} · {x.special ? (x.rl ? 'R' + x.rl : 'Special') : x.s.wdc ? 'Champion' : x.races + ' races'}</span>
        </button>)}
      </div>
    </TPSection>);
}

// 04 · STATS
function fddPair(s, meW, m) { // one season as a two-driver "team" for TPTimeline (me vs my main teammate)
  const mw = 'd:' + m.key;
  return { drivers: [meW, mw], rounds: s.rounds.map((r) => ({ n: r.n, track: r.track, cells: [{ who: meW, f: r.f, pts: r.pts, dns: r.dns }, r.mate && r.mate.key === m.key ? { who: mw, f: r.mate.f, pts: r.mate.pts || 0, dns: false } : { who: mw, f: 0, pts: 0, dns: true }] })) };
}
function FDDRacecraft() {
  const { P, jump } = React.useContext(FDDCtx);
  const A = P.all, max = Math.max(1, ...A.hist.map((h) => h.n)), c = A.climb, pc = (a, b) => (b ? Math.round(a / b * 100) + '%' : '—');
  const figs = [
    ['Average grid', A.avgQ != null ? 'P' + A.avgQ : '—', 'qualifying position'],
    ['Average finish', A.avgF != null ? 'P' + A.avgF : '—', A.sd != null ? '±' + A.sd + ' places spread' : ''],
    ['Places gained', A.gainAvg != null ? (A.gainAvg > 0 ? '+' : '') + A.gainAvg : '—', 'per race, grid to flag'],
    ['Points finishes', A.ptsRate + '%', `of ${A.starts} starts`],
    ['Finish rate', A.finRate + '%', 'no DNF or DSQ'],
    ['Points per start', A.ppS, A.pts + ' career points'],
    ['Front-row starts', A.frontRows, A.frontRows ? `${A.frontPods} turned into a podium` : 'grid 1st or 2nd'],
    ['Pole → win', A.poleConv.poles ? `${A.poleConv.wins}/${A.poleConv.poles}` : '—', A.poleConv.poles ? pc(A.poleConv.wins, A.poleConv.poles) + ' converted' : 'no poles yet'],
    ['Wins from P4+', A.winsFromBehind, 'started 4th or lower'],
    ['Races ahead of teammate', pc(A.beat.r[0], A.beat.r[1]), A.beat.r[1] ? `${A.beat.r[0]} of ${A.beat.r[1]} shared races` : 'no teammate on record'],
    ['Out-qualified teammate', pc(A.beat.q[0], A.beat.q[1]), A.beat.q[1] ? `${A.beat.q[0]} of ${A.beat.q[1]} sessions` : ''],
    ['Seasons out-scoring', A.beat.seasons[1] ? `${A.beat.seasons[0]}/${A.beat.seasons[1]}` : '—', 'vs main teammate'],
  ];
  if (A.sprint) figs.push(['Sprint races', A.sprint.wins + 'W', `${A.sprint.n} sprints · ${A.sprint.podiums} podiums · avg P${A.sprint.avg}`]);
  return (
    <div className="fdd-craft">
      <div className="fdd-hist">
        <div className="tp-cap mono"><span>Finishing positions · {A.starts} starts</span><span>{A.dnfs} DNF</span></div>
        <div className="bars" style={{ '--hn': A.hist.length }}>{A.hist.map((h) =>
          <span key={h.p} className={h.p <= 3 ? 'p' + h.p : ''} title={`${h.over ? 'P21 or lower' : 'P' + h.p} · ${h.n}×`}><i style={{ height: (h.n / max * 100) + '%' }}>{h.n > 0 && <em className="mono">{h.n}</em>}</i><b className="mono">{h.over ? '21+' : h.p}</b></span>)}</div>
      </div>
      <div className="fdd-figs">{figs.map(([k, v, sub]) => <div key={k}><span className="mono k">{k}</span><b>{v}</b>{sub && <span className="sub">{sub}</span>}</div>)}</div>
      {c && c.g > 0 && <button className="fdd-climb" onClick={() => jump(c.x.s.k, c.x.r.n)} title="Open the race">
        <span><span className="mono k">Best climb</span><br /><b>P{c.x.r.q} → P{c.x.r.f}</b></span>
        <span className="sub">+{c.g} places from the grid · {c.x.r.track.circuit} · {fddSn(c.x.s)} R{c.x.r.n}{c.x.r.team && !c.x.r.team.independent ? ' · ' + c.x.r.team.name : ''} →</span>
        {c.x.r.track.map ? <TPMap k={c.x.r.track.map} /> : <span></span>}
      </button>}
    </div>);
}
function FDDSeasonChart() {
  const { P } = React.useContext(FDDCtx);
  const L = P.seasons.filter((s) => s.starts > 0 && s.pos).slice().reverse(), n = L.length;
  if (!n) return null;
  const maxP = Math.max(10, ...L.map((s) => s.pos)), maxPts = Math.max(1, ...L.map((s) => s.pts));
  const X = (k) => (k + 0.5) / n * 100, Y = (p) => 6 + (p - 1) / (maxP - 1) * 50;
  const bands = [];
  L.forEach((s, k) => { const b = bands[bands.length - 1]; if (b && b.lg === s.lg) b.to = k; else bands.push({ lg: s.lg, from: k, to: k }); });
  return (
    <div className="tp-mx" style={{ '--n': n, marginTop: 28 }}>
      <div className="plot">
        <div className="bars">{L.map((s) => <span key={s.k} className={s.wdc ? 't' : ''} style={{ '--tc': s.team ? s.team.color : undefined }}><i style={{ height: `${s.pts / maxPts * 62}%` }}><em className="mono">{s.pts}</em></i></span>)}</div>
        <svg viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true"><polyline points={L.map((s, k) => `${X(k)},${Y(s.pos)}`).join(' ')} /></svg>
        {L.map((s, k) => <span key={s.k} className={'d' + (s.wdc ? ' t' : '')} style={{ left: X(k) + '%', top: Y(s.pos) + '%' }} title={`${fddSn(s)} · ${fddOrd(s.pos)} · ${s.pts} pts${s.team ? ' · ' + s.team.name : ''}`}><i className="mono">P{s.pos}</i></span>)}
      </div>
      <div className="x">{L.map((s) => <span key={s.k} className="mono">{s.label}</span>)}</div>
      <div className="lgs">{bands.map((b) => <span key={b.from} style={{ gridColumn: `${b.from + 1} / ${b.to + 2}` }} className="mono">{fddLgName(b.lg)}</span>)}</div>
    </div>);
}
function FDDCircuits() {
  const { P } = React.useContext(FDDCtx);
  const B = P.all.bestTracks;
  if (!B.length) return <p className="tp-zero" style={{ marginTop: 20 }}>No circuit raced twice yet — this fills in with repeat visits.</p>;
  return (
    <div className="fdd-circ">{B.map((c) =>
      <div key={c.k} className="fdd-cc">
        {c.track.map ? <TPMap k={c.track.map} cls="tp-map fdd-cmap" /> : <span className="fdd-nomap"></span>}
        <span className="nm"><b>{c.track.circuit}</b><i className="mono"><TPFlag cc={c.track.cc} />{c.track.gp}</i></span>
        <span className="fg"><b>P{c.avg}</b><i className="mono">Avg finish</i></span>
        <span className="fg"><b>{c.n}</b><i className="mono">Starts</i></span>
        <span className="fg"><b>{c.wins ? c.wins : c.podiums ? c.podiums : 'P' + c.best}</b><i className="mono">{c.wins ? 'Wins' : c.podiums ? 'Podiums' : 'Best'}</i></span>
      </div>)}</div>);
}
function FDDRecords() {
  const { P } = React.useContext(FDDCtx);
  const A = P.all, at = (x) => (x ? `${fddSn(x.s)} R${x.r.n} · ${x.r.track.gp}` : '');
  const tiles = [
    ['Best finish', A.best ? 'P' + A.best.f + (A.best.count > 1 ? ' ×' + A.best.count : '') : '—', A.best ? 'latest · ' + at(A.best.last) : '', A.best && A.best.last.r.track.map],
    ['First win', A.firstWin ? fddSn(A.firstWin.s) + ' R' + A.firstWin.r.n : '—', A.firstWin ? A.firstWin.r.track.gp + (A.firstWin.r.team && !A.firstWin.r.team.independent ? ' · ' + A.firstWin.r.team.name : '') : 'still to come', A.firstWin && A.firstWin.r.track.map],
    ['First podium', A.firstPod ? fddSn(A.firstPod.s) + ' R' + A.firstPod.r.n : '—', A.firstPod ? 'P' + A.firstPod.r.f + ' · ' + A.firstPod.r.track.gp : 'still to come', A.firstPod && A.firstPod.r.track.map],
    ['Win streak', A.winStreak.n || '—', A.winStreak.n > 1 ? 'in a row · to ' + at(A.winStreak.end) : A.winStreak.n === 1 ? 'no back-to-back wins yet' : ''],
    ['Podium streak', A.podStreak.n || '—', A.podStreak.n ? 'races in a row · to ' + at(A.podStreak.end) : ''],
    ['Points streak', A.ptsStreak.n || '—', A.ptsStreak.n ? 'races in a row · to ' + at(A.ptsStreak.end) : ''],
    ['Best circuit', A.bestCircuit ? A.bestCircuit.podiums : '—', A.bestCircuit ? `podiums at ${A.bestCircuit.track.circuit}` : '', A.bestCircuit && A.bestCircuit.track.map],
    ['Best season', A.bestSeason ? fddSn(A.bestSeason) : '—', A.bestSeason ? `${fddOrd(A.bestSeason.pos)} · ${A.bestSeason.pts} pts · ${A.bestSeason.wins} wins` : ''],
    ['Most wins in a season', A.mostWins && A.mostWins.wins ? A.mostWins.wins : '—', A.mostWins && A.mostWins.wins ? fddSn(A.mostWins) + (A.mostWins.team && !A.mostWins.team.independent ? ' · ' + A.mostWins.team.name : '') : ''],
  ];
  return (
    <div className="tp-recs">{tiles.map(([k, v, sub, map]) =>
      <div key={k} className="tp-rec"><span className="mono k" style={{ fontSize: 14 }}>{k}</span><b>{v}</b><span className="sub">{sub}</span>{map && <TPMap k={map} cls="tp-map rmap" />}</div>)}</div>);
}
function FDDStats() {
  const { P, sel } = React.useContext(FDDCtx);
  const A = P.all, withMate = P.seasons.filter((x) => x.mate);
  const [ls, setLs] = React.useState(() => (withMate.some((x) => x.k === sel) ? sel : 'all'));
  React.useEffect(() => { if (withMate.some((x) => x.k === sel)) setLs(sel); }, [sel]);
  const s = ls !== 'all' ? withMate.find((x) => x.k === ls) || null : null, all = !s;
  const [hl, setHl] = React.useState(null), [pk, setPk] = React.useState(0);
  const pr = A.pairs[Math.min(pk, Math.max(0, A.pairs.length - 1))];
  const pair = React.useMemo(() => (s && s.mate ? fddPair(s, 'd:' + P.key, s.mate) : null), [s && s.k, P.key]);
  const pc = (v) => (A.starts ? Math.round(v / A.starts * 100) + '%' : '');
  return (
    <TPSection id="fdd-stats" i="04" title="Stats" desc="">
      <TPSub i="A" title="Teammate Head-to-Head" meta={all ? `${A.pairs.length} teammates · ${A.beat.r[1]} shared races` : `${fddSn(s)} · ${s.mate.n} races together`} />
      {A.pairs.length ? <React.Fragment>
        <div className="tp-lsel" role="tablist" aria-label="Head-to-head season">
          <button className={all ? 'on' : ''} onClick={() => setLs('all')}>All-time</button>
          <span className="sep"></span>
          {withMate.map((x) => <button key={x.k} className={!all && ls === x.k ? 'on' : ''} onClick={() => setLs(x.k)}>{x.label}<i>{fddLgS(x.lg)}</i></button>)}
        </div>
        {all ?
          <div className="tp-duo">
            <div className="tp-pairs">
              <div className="tp-cap mono"><span>Every teammate</span><span>Pick one</span></div>
              {A.pairs.map((p, k) => <button key={p.key} className={p === pr ? 'on' : ''} onClick={() => setPk(k)}>
                <b>{P.id.name} <em>v</em> {p.name}</b>
                <span className="mono">{p.ks.length} season{p.ks.length > 1 ? 's' : ''} · {p.n} races together</span>
                <span className="mono rec">Q {p.q[0]}–{p.q[1]} · R {p.r[0]}–{p.r[1]}</span>
              </button>)}
            </div>
            <TPH2HBars names={[P.id.name, pr.name]} tag={`${pr.n} races together`} rows={[['Qualifying', pr.q], ['Race', pr.r], ['Points', pr.pts], ['Podiums', pr.podiums], ['Wins', pr.wins]]} />
          </div> :
          <div className="tp-duo">
            <div><div className="tp-cap mono"><span>Driver v teammate · points through the season</span><span>Hover a driver</span></div><TPTimeline s={pair} hl={hl} setHl={setHl} /></div>
            <TPH2HBars names={[P.id.name, s.mate.name]} tag={fddSn(s)} rows={[['Qualifying', s.mate.q], ['Race', s.mate.r], ['Points', s.mate.pts], ['Podiums', s.mate.podiums], ['Wins', s.mate.wins]]} hl={hl} setHl={setHl} />
          </div>}
      </React.Fragment> : <p className="tp-zero" style={{ marginTop: 20 }}>No teammate on record — independent or solo-league seasons only.</p>}
      <TPSub i="B" title="Career numbers" meta={`${A.seasons} seasons · ${A.starts} starts${A.first ? ' · since ' + fddSn(A.first.s) : ''}`} />
      <div className="tp-nstat tp-allstats">{[['Starts', A.starts], ['Wins', A.wins, pc(A.wins)], ['Podiums', A.podiums, pc(A.podiums)], ['Top 5s', A.top5, pc(A.top5)], ['Top 10s', A.top10, pc(A.top10)], ['Poles', A.poles, pc(A.poles)], ['Fastest laps', A.fl], ['DNFs', A.dnfs, pc(A.dnfs)]].map(([l, v, p]) =>
        <span key={l}><b>{v}{p && <em>{p}</em>}</b><i className="mono">{l}</i></span>)}</div>
      <TPSub i="C" title="Racecraft" meta="Qualifying, race pace, consistency" />
      <FDDRacecraft />
      <TPSub i="D" title="Season by season" meta="Championship position · points" />
      <FDDSeasonChart />
      <TPSub i="E" title="Circuits" meta="Best average finish · two starts or more" />
      <FDDCircuits />
      <TPSub i="F" title="Records" meta={`Since ${A.first ? fddSn(A.first.s) : '—'}`} />
      <FDDRecords />
    </TPSection>);
}

// 05 · RESULTS
const FDDFin = ({ r }) => {
  const tags = [r.pole && 'Pole', r.fl && 'FL', r.dnf && 'DNF', r.sprint != null && 'Sprint P' + r.sprint].filter(Boolean);
  const lab = r.absent ? '—' : r.dsq ? 'DSQ' : r.f == null ? 'DNS' : 'P' + r.f;
  return <span className={'tp-fin' + (r.f == null || r.dsq ? ' out' : r.f <= 3 ? ' pod' : '')}><b>{lab}</b>{tags.length > 0 && <i className="mono">{tags.join(' · ')}</i>}</span>;
};
function FDDRoundRows({ s, focus }) {
  return (
    <React.Fragment>
      <div className="tp-lh fdd-rrow"><span>Rnd</span><span>Location</span><span className="tp-date">Date</span><span className="c-tm">Team</span><span>Grid</span><span>Result</span><span className="tp-cmap">Circuit</span><span className="r">Pts</span></div>
      {s.rounds.map((r) => {
        const d = r.q != null && r.f != null ? r.q - r.f : 0;
        return (
          <div className={'tp-row fdd-rrow' + (focus && focus.k === s.k && focus.n === r.n ? ' focus' : '')} key={r.n} id={fddRowId(s.k, r.n)}>
            <span className="tp-num">{fddPad(r.n)}</span>
            <span className="tp-loc"><TPFlag cc={r.track.cc} /><span><b>{r.track.gp}</b><i className="mono">{r.track.circuit}</i></span>{r.track.img && <img className="tp-peek" src={`assets/tracks/sm/${r.track.img}.jpg`} alt="" loading="lazy" />}</span>
            <span className="tp-date mono">{r.date ? window.TP.fmtDay(r.date) : '—'}</span>
            <span className="c-tm fdd-rtm">{r.team && <React.Fragment><FDDMark t={r.team} cls="fdd-xs" /><span className="mono">{r.team.short}</span></React.Fragment>}</span>
            <span className="fdd-q"><b>{r.q != null ? 'P' + r.q : '—'}</b>{d !== 0 && <i className={d > 0 ? 'up' : 'dn'}>{d > 0 ? '▲' + d : '▼' + -d}</i>}</span>
            <FDDFin r={r} />
            {r.track.map ? <TPMap k={r.track.map} /> : <span className="fdd-nomap"></span>}
            <span className="tp-v r">{r.dns ? '—' : r.pts}</span>
          </div>);
      })}
    </React.Fragment>);
}
function FDDResults() {
  const { P, s, focus } = React.useContext(FDDCtx);
  const others = P.seasons.filter((x) => x.k !== s.k && x.rounds.length);
  const [open, setOpen] = React.useState(() => new Set()), [more, setMore] = React.useState(false);
  const tog = (k) => setOpen((o) => { const n = new Set(o); if (n.has(k)) n.delete(k); else n.add(k); return n; });
  const shown = more ? others : others.slice(0, 4);
  return (
    <TPSection id="fdd-results" i="05" title="Results" desc="">
      <div className="tp-cap mono tp-tcap"><span>{fddSn(s)} · {s.team ? s.team.name : 'Independent'}</span><span>{s.starts} starts · {s.pts} pts{s.pos ? ' · ' + fddOrd(s.pos) : ''}</span></div>
      <FDDRoundRows s={s} focus={focus} />
      {others.length > 0 && <div className="tp-cap mono tp-tcap"><span>Other seasons · {others.length}</span><span>Open a season to see every round</span></div>}
      {shown.map((x) => (
        <TPAcc key={x.k} open={open.has(x.k)} onToggle={() => tog(x.k)} head={<React.Fragment>
          <span className="yr">{x.label}</span>
          <span className="lg"><b>{fddLgName(x.lg)}</b><span className="mono">{x.team ? x.team.name : 'Independent'} · {x.starts} starts{x.wins ? ` · ${x.wins} wins` : ''}</span></span>
          <span className={'fig' + (x.wdc ? ' gold' : '')}><b>{x.pos ? <TPOrd n={x.pos} /> : '—'}</b><span className="mono">{x.wdc ? 'Champion' : 'Drivers'}</span></span>
          <span className="fig tp-hide-s"><b>{x.pts}</b><span className="mono">Points</span></span>
        </React.Fragment>}>
          <FDDRoundRows s={x} focus={focus} />
        </TPAcc>))}
      {others.length > 4 && <button className="tp-more" onClick={() => setMore(!more)}><span>{more ? 'Show fewer seasons' : `Show ${others.length - 4} more seasons`}</span><span className="mono">back to {fddSn(P.seasons[P.seasons.length - 1])}</span></button>}
    </TPSection>);
}

// No race on record yet (new signing): identity, contract, car.
function FDDFresh() {
  const { P } = React.useContext(FDDCtx);
  const now = P.now[0] || null, L = now ? LEAGUE_BY_ID[now.site] : null;
  const team = now && now.code && typeof fdtIdentity === 'function' ? fdtIdentity(now.site, now.code) : null;
  return (
    <section className="fdt-fresh" data-screen-label={`Driver ${P.id.name} — no races yet`} style={team ? { '--tc': team.color } : undefined}>
      <div className="tp-wrap fdt-fgrid">
        <div>
          {P.id.num != null && <div className="fdd-lnum">{P.id.num}</div>}
          <span className="mono fdt-fkick">{L ? L.name + ' · ' + now.label : 'UR2D'} · <b>No races yet</b></span>
          <h1 className="fdt-fname"><span>{P.id.lines[0]}</span>{P.id.lines[1] && <span>{P.id.lines[1]}</span>}</h1>
        </div>
        <div className="fdt-fcar">{team && team.livery && <img src={team.livery} alt={`${team.name} livery`} />}</div>
      </div>
      <div className="tp-wrap">
        <div className="fdt-fband">
          {team && <div><span className="mono k">{now.role === 'reserve' ? 'Reserve for' : 'Racing for'}</span><b>{team.name}</b></div>}
          {now && now.role === 'independent' && <div><span className="mono k">Entry</span><b>Independent</b></div>}
          <div><span className="mono k">Country</span><b style={{ display: 'flex', alignItems: 'center', gap: 10 }}><TPFlag cc={P.id.cc} />{String(P.id.cc || '').toUpperCase()}</b></div>
        </div>
        <p className="mono fdt-fnote">Results, trophies and stats fill in here after the first race.</p>
      </div>
    </section>);
}

function FDDCareer({ P, sel, setSel, go, peek, color }) {
  const [focus, setFocus] = React.useState(null);
  const active = useFddSpy();
  const fm = useFdtFormer();
  const former = React.useMemo(() => new Set((fm.teams || []).map((t) => t.id)), [fm.teams]);
  const s = P.seasons.find((x) => x.k === sel) || P.seasons[0];
  const jump = (k, n) => {
    setSel(k); setFocus({ k, n });
    setTimeout(() => { const el = document.getElementById(fddRowId(k, n)); if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 180 - 72, behavior: 'smooth' }); }, 80);
  };
  return (
    <FDDCtx.Provider value={{ P, s, sel, setSel, go, jump, focus, former }}>
      <div className={'tp-root embed fdd' + (peek === 'always' ? ' tp-peek-on' : '')} style={{ '--tc': color }}>
        {P.fresh || !s ? <FDDFresh /> : <React.Fragment>
          <FDDSNav P={P} active={active} />
          <FDDHero />
          <main><FDDCareerSec /><FDDTrophies /><FDDGarage /><FDDStats /><FDDResults /></main>
        </React.Fragment>}
      </div>
    </FDDCtx.Provider>);
}

function FDDSeasonPop({ P, sel, setSel }) {
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => { if (!open) return; const f = () => setOpen(false); window.addEventListener('click', f); return () => window.removeEventListener('click', f); }, [open]);
  const cur = P.seasons.find((x) => x.k === sel);
  return (
    <div className="tp-ctx inl" onClick={(e) => e.stopPropagation()}>
      <div className="tp-pop">
        <button className="tp-popb" onClick={() => setOpen(!open)} aria-expanded={open} title="Change season"><span>{cur ? fddSn(cur) : 'Season'}</span><i>▾</i></button>
        {open && <div className="tp-popm sss fdd-sss">{P.seasons.map((x) =>
          <button key={x.k} className={sel === x.k ? 'on' : ''} onClick={() => { setSel(x.k); setOpen(false); }} title={`${fddSn(x)}${x.team ? ' · ' + x.team.name : ''}`}><b>{x.label}</b><span className="mono">{fddLgS(x.lg)}</span></button>)}</div>}
      </div>
    </div>);
}

const FDDLoading = ({ id }) =>
  <div className="fdt-load" aria-live="polite">
    {id && id.num != null && <div className="fdd-lnum">{id.num}</div>}
    {id && <div className="nm">{id.name}</div>}
    <span className="bar"><i></i></span>
    <span className="mono" style={{ color: 'var(--mute)' }}>Loading the career from the archive</span>
  </div>;

// Route #driver/<key>
const FDDriverPage = ({ dkey, go, tp }) => {
  const [prof, setProf] = React.useState(() => fddProfileReady[dkey] || null);
  const [tick, setTick] = React.useState(0);
  React.useEffect(() => {
    if (fddProfileReady[dkey]) { setProf(fddProfileReady[dkey]); return; }
    let alive = true;
    setProf(null);
    fddLoadProfile(dkey).then((p) => { if (alive) setProf(p); });
    return () => { alive = false; };
  }, [dkey, tick]);
  const ok = !!(prof && !prof.missing && !prof.failed);
  const first = (p) => ((p.seasons.find((x) => x.starts > 0) || p.seasons[0] || {}).k || null);
  const [sel, setSel] = React.useState(() => (ok ? first(prof) : null));
  React.useEffect(() => { if (ok) setSel(first(prof)); }, [prof]);
  React.useEffect(() => { if (ok && prof.key !== dkey && /^n-/.test(dkey)) history.replaceState(null, '', '#' + fddRoute(prof.key)); }, [prof]);
  const s = ok ? prof.seasons.find((x) => x.k === sel) || prof.seasons.find((x) => x.k === first(prof)) || prof.seasons[0] : null;
  const pre = fddQuick(dkey);
  const color = (s && s.team && !s.team.independent && s.team.color) || (ok && prof.color) || COLORS.red;
  const tex = tp && tp.texture, L = s ? LEAGUE_BY_ID[s.site] : null, back = () => go('drivers');
  return (
    <div data-screen-label={`Final — Driver ${(ok && prof.id.name) || (pre && pre.name) || ''}`} className={'fdt-page' + (tex ? ' tex' : '')} style={{ background: '#070707', minHeight: '60vh', '--tc': color }}>
      <style>{window.fdtPageCss || ''}</style>
      <style>{fddCss}</style>
      {tex && <div className="fdt-tex" aria-hidden="true" style={{ opacity: tp.texOpacity != null ? tp.texOpacity : 0.05 }}></div>}
      <div className="fdt-texc">
        <div className="tp-root embed fdt-crumbw" style={{ '--tc': color }}>
          <div className="tp-wrap fdt-crumb">
            <button onClick={back}>← All drivers</button>
            {L && <React.Fragment><span className="sep">/</span><span>{L.name}</span></React.Fragment>}
            {(ok || pre) && <React.Fragment><span className="sep">/</span><b>{ok ? prof.id.name : pre.name}</b></React.Fragment>}
            <span className="slot">{ok && prof.seasons.length > 0 && !prof.fresh && <FDDSeasonPop P={prof} sel={sel} setSel={setSel} />}</span>
          </div>
        </div>
        {!prof ? <div className="tp-root embed"><FDDLoading id={pre} /></div> :
          !ok ? <div className="tp-root embed"><div className="fdt-load">
            <div className="nm">{prof.failed ? 'Archive unreachable' : 'Driver not found'}</div>
            {prof.failed && <button className="mono" onClick={() => setTick((x) => x + 1)} style={{ color: 'var(--ink)' }}>Try again</button>}
            <button className="mono" onClick={back} style={{ color: 'var(--ink)' }}>← All drivers</button>
          </div></div> :
          <FDDCareer P={prof} sel={s ? s.k : null} setSel={setSel} go={go} peek={tp && tp.peek} color={color} />}
      </div>
    </div>);
};

Object.assign(window, { FDDriversLanding, FDDriverPage });
