⚽ FIFA WORLD CUP 2026     NJ-LIS-LON

SWEEPSTAKE • 11 JUN – 19 JUL 2026
CAN MEX USA
€60 pot
Network error: Failed to fetch ⚽ Live scores
⚽ YOUR TEAMS PLAYING TODAY
🇶🇦 QAT vs 🇨🇭 SUI 20:00 BST / 3:00pm ET • San Francisco
🇧🇷 BRA vs 🇲🇦 MAR 23:00 BST / 6:00pm ET • New York/NJ
🇭🇹 HAI vs SCO SCO 02:00† BST / 9:00pm ET • Boston
🇦🇺 AUS vs 🇹🇷 TUR 05:00† BST / 12:00am ET • Vancouver
🔓Owner mode active

👤 Players

Add everyone taking part. You need at least 2 players to run the draw.

Nina
Aarav
Suhani
Pooja
Maya
Paarth_siuu
Radhi
Aryan
D K Kotecha
Chandulal Batuk
Anit
CR7

🅾 Pin Top-12 Teams

Optionally assign one top-12 team to a specific player. Pinned teams are locked in before the draw runs — max one pin per player.

Nina
Aarav
Suhani
Pooja
Maya
Paarth_siuu
Radhi
Aryan
D K Kotecha
Chandulal Batuk
Anit
CR7

💰 Pot (optional)

12 players × €5 = €60 total pot

📶 Live Results API

Enter your football-data.org API key to auto-sync results every time you refresh.

Connected ✔

🏆 All 48 Qualified Teams

Draw is seeded — every player gets 1 top-12 + 1 ranked 13–20. Official codes & flags shown.

🇫🇷 FRA #1🇪🇸 ESP #2🇦🇷 ARG #3ENG #4🇵🇹 POR #5🇧🇷 BRA #6🇳🇱 NED #7🇲🇦 MAR #8🇧🇪 BEL #9🇩🇪 GER #10🇭🇷 CRO #11🇨🇴 COL #13🇸🇳 SEN #14🇲🇽 MEX #15🇺🇸 USA #16🇺🇾 URU #17🇯🇵 JPN #18🇨🇭 SUI #19🇰🇷 KOR #22🇦🇹 AUT #25🇦🇺 AUS #26🇪🇨 ECU #28🇹🇷 TUR #29🇩🇿 ALG #30🇳🇴 NOR #31🇸🇪 SWE #33🇮🇷 IRN #35SCO #36🇵🇾 PAR #37🇨🇿 CZE #38🇬🇭 GHA #40🇪🇬 EGY #41🇸🇦 KSA #56🇵🇦 PAN #57🇹🇳 TUN #58🇨🇦 CAN #59🇨🇮 CIV #60🇳🇿 NZL #63🇶🇦 QAT #65🇧🇦 BIH #66🇮🇶 IRQ #68🇯🇴 JOR #70🇨🇩 COD #74🇿🇦 RSA #76🇭🇹 HAI #83🇺🇿 UZB #87🇨🇻 CPV #90🇨🇼 CUW #104

🎲 The Draw

Seeded draw — everyone gets at least 1 top-12 team and 1 ranked 13–20. Hit the button when everyone’s ready!

Draw complete — 12 players, all 48 teams assigned.

N
Nina
0 pts
🇧🇷
BRA
Brazil
★ #6
🇨🇦
CAN
Canada
#59
🇿🇦
RSA
South Africa
#76
🇰🇷
KOR
South Korea
#22
A
Aarav
0 pts
🇩🇪
GER
Germany
★ #10
🇬🇭
GHA
Ghana
#40
🇸🇪
SWE
Sweden
#33
🇨🇭
SUI
Switzerland
#19
S
Suhani
0 pts
🇳🇱
NED
Netherlands
★ #7
🇨🇿
CZE
Czechia
#38
🇸🇦
KSA
Saudi Arabia
#56
🇨🇮
CIV
Ivory Coast
#60
P
Pooja
0 pts
🇧🇪
BEL
Belgium
★ #9
🇮🇶
IRQ
Iraq
#68
🇯🇴
JOR
Jordan
#70
🇹🇳
TUN
Tunisia
#58
M
Maya
0 pts
🇪🇸
ESP
Spain
★ #2
🇺🇸
USA
USA
#16
🇸🇳
SEN
Senegal
#14
🇶🇦
QAT
Qatar
#65
P
Paarth_siuu
0 pts
🇵🇹
POR
Portugal
★ #5
🇦🇹
AUT
Austria
#25
🇵🇦
PAN
Panama
#57
🇨🇼
CUW
Curacao
#104
R
Radhi
0 pts
🇦🇷
ARG
Argentina
★ #3
🇪🇬
EGY
Egypt
#41
🇹🇷
TUR
Turkey
#29
🏁
SCO
Scotland
#36
A
Aryan
0 pts
🏁
ENG
England
★ #4
🇨🇩
COD
DR Congo
#74
🇪🇨
ECU
Ecuador
#28
🇨🇻
CPV
Cape Verde
#90
DK
D K Kotecha
0 pts
🇫🇷
FRA
France
★ #1
🇲🇽
MEX
Mexico
#15
🇧🇦
BIH
Bosnia-Herz
#66
🇵🇾
PAR
Paraguay
#37
CB
Chandulal Batuk
0 pts
🇨🇴
COL
Colombia
#13
🇺🇾
URU
Uruguay
#17
🇭🇹
HAI
Haiti
#83
🇦🇺
AUS
Australia
#26
A
Anit
0 pts
🇲🇦
MAR
Morocco
★ #8
🇳🇿
NZL
New Zealand
#63
🇯🇵
JPN
Japan
#18
🇳🇴
NOR
Norway
#31
C
CR7
0 pts
🇭🇷
CRO
Croatia
#11
🇩🇿
ALG
Algeria
#30
🇺🇿
UZB
Uzbekistan
#87
🇮🇷
IRN
Iran
#35
12
Players
€60
Total pot
48
Teams still in

🏆 Leaderboard

🥇
N
Nina
🇧🇷 BRA🇨🇦 CAN🇿🇦 RSA🇰🇷 KOR
0pts
🥈
A
Aarav
🇩🇪 GER🇬🇭 GHA🇸🇪 SWE🇨🇭 SUI
0pts
🥉
S
Suhani
🇳🇱 NED🇨🇿 CZE🇸🇦 KSA🇨🇮 CIV
0pts
4
P
Pooja
🇧🇪 BEL🇮🇶 IRQ🇯🇴 JOR🇹🇳 TUN
0pts
5
M
Maya
🇪🇸 ESP🇺🇸 USA🇸🇳 SEN🇶🇦 QAT
0pts
6
P
Paarth_siuu
🇵🇹 POR🇦🇹 AUT🇵🇦 PAN🇨🇼 CUW
0pts
7
R
Radhi
🇦🇷 ARG🇪🇬 EGY🇹🇷 TUR SCO
0pts
8
A
Aryan
ENG🇨🇩 COD🇪🇨 ECU🇨🇻 CPV
0pts
9
DK
D K Kotecha
🇫🇷 FRA🇲🇽 MEX🇧🇦 BIH🇵🇾 PAR
0pts
10
CB
Chandulal Batuk
🇨🇴 COL🇺🇾 URU🇭🇹 HAI🇦🇺 AUS
0pts
11
A
Anit
🇲🇦 MAR🇳🇿 NZL🇯🇵 JPN🇳🇴 NOR
0pts
12
C
CR7
🇭🇷 CRO🇩🇿 ALG🇺🇿 UZB🇮🇷 IRN
0pts
💰 PRIZE BREAKDOWN
🥇
Nina
1st place
€35
🥈
Aarav
2nd place
€15
🥉
Suhani
3rd place
€10

⛳ Update Results

If auto-sync is on, this updates automatically. You can also mark results manually.
Points: Group=1 • R32=2 • R16=4 • QF=6 • SF=9 • Runner-up=12 • Winner=20

🇫🇷 FRA France D K Kotecha
🇪🇸 ESP Spain Maya
🇦🇷 ARG Argentina Radhi
ENG England Aryan
🇵🇹 POR Portugal Paarth_siuu
🇧🇷 BRA Brazil Nina
🇳🇱 NED Netherlands Suhani
🇲🇦 MAR Morocco Anit
🇧🇪 BEL Belgium Pooja
🇩🇪 GER Germany Aarav
🇭🇷 CRO Croatia CR7
🇨🇴 COL Colombia Chandulal Batuk
🇸🇳 SEN Senegal Maya
🇲🇽 MEX Mexico D K Kotecha
🇺🇸 USA USA Maya
🇺🇾 URU Uruguay Chandulal Batuk
🇯🇵 JPN Japan Anit
🇨🇭 SUI Switzerland Aarav
🇰🇷 KOR South Korea Nina
🇦🇹 AUT Austria Paarth_siuu
🇦🇺 AUS Australia Chandulal Batuk
🇪🇨 ECU Ecuador Aryan
🇹🇷 TUR Turkey Radhi
🇩🇿 ALG Algeria CR7
🇳🇴 NOR Norway Anit
🇸🇪 SWE Sweden Aarav
🇮🇷 IRN Iran CR7
SCO Scotland Radhi
🇵🇾 PAR Paraguay D K Kotecha
🇨🇿 CZE Czechia Suhani
🇬🇭 GHA Ghana Aarav
🇪🇬 EGY Egypt Radhi
🇸🇦 KSA Saudi Arabia Suhani
🇵🇦 PAN Panama Paarth_siuu
🇹🇳 TUN Tunisia Pooja
🇨🇦 CAN Canada Nina
🇨🇮 CIV Ivory Coast Suhani
🇳🇿 NZL New Zealand Anit
🇶🇦 QAT Qatar Maya
🇧🇦 BIH Bosnia-Herz D K Kotecha
🇮🇶 IRQ Iraq Pooja
🇯🇴 JOR Jordan Pooja
🇨🇩 COD DR Congo Aryan
🇿🇦 RSA South Africa Nina
🇭🇹 HAI Haiti Chandulal Batuk
🇺🇿 UZB Uzbekistan CR7
🇨🇻 CPV Cape Verde Aryan
🇨🇼 CUW Curacao Paarth_siuu

📅 Match Schedule

All 104 matches • UK / BST times • 11 Jun – 19 Jul 2026 • = England or Scotland match

Thu 11 Jun Played
🇲🇽MEX vs RSA🇿🇦
20:00 BST Mexico City Group A
🇰🇷KOR vs CZE🇨🇿
03:00† BST Guadalajara Group A
Fri 12 Jun Played
🇨🇦CAN vs BIH🇧🇦
20:00 BST Toronto Group B
🇺🇸USA vs PAR🇵🇾
02:00† BST Los Angeles Group D
Sat 13 Jun Today
🇶🇦QAT vs SUI🇨🇭
20:00 BST San Francisco Group B
🇧🇷BRA vs MAR🇲🇦
23:00 BST New York/NJ Group C
🇭🇹HAI vs SCO
02:00† BST Boston Group C
🇦🇺AUS vs TUR🇹🇷
05:00† BST Vancouver Group D
Sun 14 Jun Tomorrow
🇩🇪GER vs CUW🇨🇼
19:00 BST Houston Group E
🇳🇱NED vs JPN🇯🇵
22:00 BST Dallas Group F
🇨🇮CIV vs ECU🇪🇨
01:00† BST Philadelphia Group E
🇸🇪SWE vs TUN🇹🇳
04:00† BST Monterrey Group F
Mon 15 Jun In 2 days
🇪🇸ESP vs CPV🇨🇻
18:00 BST Atlanta Group H
🇧🇪BEL vs EGY🇪🇬
21:00 BST Vancouver Group G
🇸🇦KSA vs URU🇺🇾
00:00† BST Miami Group H
🇮🇷IRN vs NZL🇳🇿
05:00† BST Los Angeles Group G
Tue 16 Jun In 3 days
🇫🇷FRA vs SEN🇸🇳
21:00 BST New York/NJ Group I
🇮🇶IRQ vs NOR🇳🇴
00:00† BST Boston Group I
🇦🇷ARG vs ALG🇩🇿
03:00† BST Kansas City Group J
🇦🇹AUT vs JOR🇯🇴
08:00† BST San Francisco Group J
Wed 17 Jun In 4 days
🇵🇹POR vs COD🇨🇩
19:00 BST Houston Group K
ENG vs CRO🇭🇷
22:00 BST Dallas Group L
🇬🇭GHA vs PAN🇵🇦
01:00† BST Toronto Group L
🇺🇿UZB vs COL🇨🇴
04:00† BST Mexico City Group K
Thu 18 Jun In 5 days
🇨🇿CZE vs RSA🇿🇦
18:00 BST Atlanta Group A
🇨🇭SUI vs BIH🇧🇦
21:00 BST Los Angeles Group B
🇨🇦CAN vs QAT🇶🇦
02:00† BST Vancouver Group B
🇲🇽MEX vs KOR🇰🇷
04:00† BST Guadalajara Group A
Fri 19 Jun In 6 days
🇿🇦RSA vs MAR🇲🇦
21:00 BST Boston Group C
🇺🇸USA vs AUS🇦🇺
22:00 BST Seattle Group D
🇧🇷BRA vs HAI🇭🇹
02:00† BST Philadelphia Group C
🇹🇷TUR vs PAR🇵🇾
04:00† BST San Francisco Group D
Sat 20 Jun In 7 days
🇳🇱NED vs SWE🇸🇪
19:00 BST Houston Group F
🇩🇪GER vs CIV🇨🇮
22:00 BST Toronto Group E
🇪🇨ECU vs CUW🇨🇼
02:00† BST Kansas City Group E
🇹🇳TUN vs JPN🇯🇵
06:00† BST Monterrey Group F
Sun 21 Jun
🇪🇸ESP vs KSA🇸🇦
18:00 BST Atlanta Group H
🇧🇪BEL vs IRN🇮🇷
21:00 BST Los Angeles Group G
🇺🇾URU vs CPV🇨🇻
00:00† BST Miami Group H
🇳🇿NZL vs EGY🇪🇬
05:00† BST Vancouver Group G
Mon 22 Jun
🇦🇷ARG vs AUT🇦🇹
19:00 BST Dallas Group J
🇫🇷FRA vs IRQ🇮🇶
23:00 BST Philadelphia Group I
🇳🇴NOR vs SEN🇸🇳
02:00† BST New York/NJ Group I
🇯🇴JOR vs ALG🇩🇿
07:00† BST San Francisco Group J
Tue 23 Jun
🇵🇹POR vs UZB🇺🇿
19:00 BST Houston Group K
ENG vs GHA🇬🇭
22:00 BST Seattle Group L
🇭🇷CRO vs PAN🇵🇦
01:00† BST Toronto Group L
🇨🇴COL vs COD🇨🇩
05:00† BST Kansas City Group K
Wed 24 Jun
🇲🇽MEX vs CZE🇨🇿
20:00 BST Mexico City Group A
🇰🇷KOR vs RSA🇿🇦
20:00 BST Guadalajara Group A
🇧🇦BIH vs QAT🇶🇦
23:00 BST Toronto Group B
🇨🇭SUI vs CAN🇨🇦
23:00 BST Vancouver Group B
Thu 25 Jun
SCO vs BRA🇧🇷
20:00 BST Philadelphia Group C
🇲🇦MAR vs HAI🇭🇹
20:00 BST New York/NJ Group C
🇵🇾PAR vs AUS🇦🇺
23:00 BST Los Angeles Group D
🇹🇷TUR vs USA🇺🇸
23:00 BST Seattle Group D
Fri 26 Jun
🇨🇼CUW vs GER🇩🇪
20:00 BST Kansas City Group E
🇪🇨ECU vs CIV🇨🇮
20:00 BST Philadelphia Group E
🇯🇵JPN vs NED🇳🇱
23:00 BST Dallas Group F
🇹🇳TUN vs SWE🇸🇪
23:00 BST Monterrey Group F
Sat 27 Jun
🇪🇬EGY vs BEL🇧🇪
20:00 BST Vancouver Group G
🇳🇿NZL vs IRN🇮🇷
20:00 BST Los Angeles Group G
🇨🇻CPV vs ESP🇪🇸
23:00 BST Miami Group H
🇺🇾URU vs KSA🇸🇦
23:00 BST Atlanta Group H
Sun 28 Jun
🇸🇳SEN vs FRA🇫🇷
20:00 BST New York/NJ Group I
🇳🇴NOR vs IRQ🇮🇶
20:00 BST Boston Group I
🇩🇿ALG vs ARG🇦🇷
23:00 BST Kansas City Group J
🇯🇴JOR vs AUT🇦🇹
23:00 BST San Francisco Group J
Mon 29 Jun
🇨🇩COD vs POR🇵🇹
20:00 BST Houston Group K
🇨🇴COL vs UZB🇺🇿
20:00 BST Mexico City Group K
🇵🇦PAN vs ENG
23:00 BST Toronto Group L
🇬🇭GHA vs CRO🇭🇷
23:00 BST Dallas Group L
Fri 3 Jul – Mon 7 Jul
Round of 32 (8 matches)
KNOCKOUT
Sat 5 Jul – Tue 8 Jul
Round of 16 (8 matches)
KNOCKOUT
Fri 10 Jul – Sun 12 Jul
Quarter-finals (4 matches)
KNOCKOUT
Wed 15 – Thu 16 Jul
Semi-finals
KNOCKOUT
Sun 18 Jul
3rd place play-off — Miami
23:00 BSTKNOCKOUT
Sun 19 Jul
🏆 FINAL — New York / New Jersey
20:00 BSTKNOCKOUT

💬 Share to WhatsApp

💾 Download

Save the app as a single HTML file. Share it with family — they open it in any browser.

🗣 Banter Board Live

Family chat — trash talk welcome. Messages are shared live across all devices.

1
111 Jun 12:47
test
1
111 Jun 12:31
hello
1
1211 Jun 12:02
hello
1
1210 Jun 23:35
hello
1
1210 Jun 18:27
13
1
1210 Jun 16:12
1-2-3
N
Nina10 Jun 14:48
testing
1
1210 Jun 14:46
hello
N
Nina10 Jun 14:44
test
TU
Test User10 Jun 12:54
Hello from console
TU
Test User10 Jun 12:48
Hello from console
TU
Test User10 Jun 12:48
Hello from console
1
110 Jun 12:36
test
1
110 Jun 12:36
test
1
110 Jun 12:35
test
1
110 Jun 12:32
hi
1
110 Jun 12:31
hi
1
110 Jun 12:31
hi
N
Nina10 Jun 12:09
test
N
Nina10 Jun 10:36
test
N
Nina10 Jun 10:16
test

🏆 Route to the Final

Predict the knockout bracket — in R32 use the dropdowns to pick which team from each group advances, then tap a team to pick the match winner. They advance automatically all the way to the final.

Round of 32
🇲🇽
🇨🇦
🇧🇷
🇺🇸
🇩🇪
🇳🇱
🇧🇪
🇪🇸
🇫🇷
🇦🇷
🇵🇹
🇨🇦
🇲🇽
🇺🇸
🇧🇷
🇳🇱
🇩🇪
🇪🇸
🇧🇪
🇦🇷
🇫🇷
🇵🇹
🇲🇽
🇧🇷
🇩🇪
🇧🇪
🇫🇷
🇵🇹
🇲🇽
🇨🇦
Round of 16
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
Quarter-finals
TBD
TBD
TBD
TBD
TBD
TBD
TBD
TBD
Semi-finals
TBD
TBD
TBD
TBD
Final
TBD
TBD
',stateInject+''); var blob=new Blob([html],{type:'text/html'}); var a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='wc2026-sweepstake.html';a.click(); } /* -- BOOT -- */ /* -- TODAY'S MATCHES BAR -- */ /* -- TIME HELPERS -- */ function bstToET(bstStr){ // bstStr like "20:00" or "02:00" (dagger already stripped by caller) var parts=bstStr.split(':'); if(parts.length<2)return ''; var h=parseInt(parts[0],10); var m=parts[1]; // NJ/NY is EDT = UTC-4, BST = UTC+1, so ET = BST - 5 var eth=((h-5)+24)%24; var ampm=eth<12?'am':'pm'; var h12=eth%12||12; return h12+':'+m+ampm+' ET'; } function renderTodayBar(){ var bar=document.getElementById('today-bar'); var label=document.getElementById('today-bar-label'); var feed=document.getElementById('today-matches'); if(!bar||!feed)return; var now=new Date(); var days=['Sun','Mon','Tue','Wed','Thu','Fri','Sat']; var months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; var todayStr=days[now.getDay()]+' '+now.getDate()+' '+months[now.getMonth()]; var myTeamCodes=[]; if(state.drawn){ Object.values(state.assignments).forEach(function(teams){ teams.forEach(function(tn){ var t=TEAMS.find(function(x){return x.name===tn}); if(t)myTeamCodes.push(t.code); }); }); } // Find today's matches involving drawn teams var todayMatches=SCHEDULE.filter(function(m){ return m.d===todayStr&&m.t.length===2&&myTeamCodes.length&&m.t.some(function(c){return myTeamCodes.indexOf(c)>=0}); }); // Find next 2 upcoming matches (any) if no matches today for my teams var nextMatches=[]; if(!todayMatches.length){ // walk schedule to find first 2 future group matches var found=0; for(var i=0;i=0; var mine2=myTeamCodes.indexOf(m.t[1])>=0; var f1=flagCache[m.t[0]]?'':(t1.emoji||m.t[0]); var f2=flagCache[m.t[1]]?'':(t2.emoji||m.t[1]); var bstClean=m.uk.replace('\u2020',''); var etStr=bstToET(bstClean); return '
' +f1+' '+m.t[0]+'' +' vs ' +f2+' '+m.t[1]+'' +' '+m.uk+' BST / '+etStr+' • '+m.v+'' +'
'; }).join(''); } else { // Show "no matches today, next up" if(label)label.innerHTML='📅 NEXT UPCOMING MATCHES'; bar.style.background='linear-gradient(135deg,rgba(42,57,141,.15),rgba(2,15,42,.3))'; bar.style.borderBottomColor='rgba(42,57,141,.4)'; feed.innerHTML=nextMatches.map(function(m){ var t1=TEAMS.find(function(x){return x.code===m.t[0]})||{emoji:'',code:m.t[0]}; var t2=TEAMS.find(function(x){return x.code===m.t[1]})||{emoji:'',code:m.t[1]}; var f1=flagCache[m.t[0]]?'':(t1.emoji||m.t[0]); var f2=flagCache[m.t[1]]?'':(t2.emoji||m.t[1]); var bstClean=m.uk.replace('\u2020',''); var etStr=bstToET(bstClean); return '
' +''+m.d+' ' +f1+' '+m.t[0]+'' +' vs ' +f2+' '+m.t[1]+'' +' '+m.uk+' BST / '+etStr+' • '+m.v+'' +'
'; }).join(''); } } /* -- TEAM MODAL -- */ function openTeamModal(teamName){ var t=TEAMS.find(function(x){return x.name===teamName}); if(!t)return; var modal=document.getElementById('team-modal'); var inner=document.getElementById('team-modal-content'); if(!modal||!inner)return; // Find next matches for this team var upcoming=SCHEDULE.filter(function(m){ return m.t.indexOf(t.code)>=0&&m.uk; }).slice(0,3); var stage=state.teamStages[teamName]||'tbd'; var stageInfo=STAGES[stage]||{label:'Not played yet',pts:0}; // Find who owns this team var owner=Object.entries(state.assignments).find(function(e){return e[1].indexOf(teamName)>=0}); var flagHtml=flagCache[t.code] ?'' :(t.emoji?''+t.emoji+'':''); var matchRows=upcoming.length ?upcoming.map(function(m){ var opp=m.t[0]===t.code?m.t[1]:m.t[0]; var oppT=TEAMS.find(function(x){return x.code===opp})||{emoji:'',code:opp}; var oppFlag=flagCache[opp]?'':(oppT.emoji||opp); return '
' +''+m.uk+' BST / '+bstToET(m.uk.replace("\u2020",""))+'' +''+m.d+'' +'vs '+oppFlag+' '+opp+'' +''+m.v+'' +'
'; }).join('') :'

No upcoming group fixtures

'; inner.innerHTML= '
' +flagHtml +'
' +'
'+t.name+'
' +'
FIFA Rank #'+t.rank+(t.rank<=10?' • ★ Top 10':t.rank<=20?' • Top 20':'')+'
' +(owner?'
Drawn by '+owner[0]+'
':'') +'
' +'
' +'
' +'Current stage' +''+stageInfo.label+'' +'
' +'
UPCOMING FIXTURES
' +matchRows; modal.style.display='flex'; } function closeTeamModal(){ var modal=document.getElementById('team-modal'); if(modal)modal.style.display='none'; } /* -- LIVE MATCH INDICATOR -- */ function getLiveTeams(){ var now=new Date(); var days=['Sun','Mon','Tue','Wed','Thu','Fri','Sat']; var months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; var todayStr=days[now.getDay()]+' '+now.getDate()+' '+months[now.getMonth()]; var liveSet={}; SCHEDULE.forEach(function(m){ if(m.d!==todayStr||!m.uk||!m.t.length)return; var timeStr=m.uk.replace('\u2020',''); var parts=timeStr.split(':'); if(parts.length<2)return; var h=parseInt(parts[0],10),mi=parseInt(parts[1],10); var kickoff=new Date(now); kickoff.setUTCHours(h-1,mi,0,0); var diff=(now-kickoff)/60000; if(diff>=0&&diff<=105)m.t.forEach(function(c){liveSet[c]=true;}); }); return liveSet; } /* -- BANTER BOARD (Firebase realtime) -- */ var replyToId=null; var _fbApp=null; var _fbDb=null; var _fbRef=null; var _fbMessages=[]; function initFirebase(){ if(_fbApp)return; // Dynamically load Firebase SDKs then connect function loadScript(src,cb){ var s=document.createElement('script'); s.src=src; s.onload=cb; s.onerror=function(){ document.getElementById('banter-status').textContent='Offline (CDN blocked)'; document.getElementById('banter-status').style.color='var(--gray)'; }; document.head.appendChild(s); } var appUrl='https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js'; var dbUrl='https://www.gstatic.com/firebasejs/9.23.0/firebase-database-compat.js'; loadScript(appUrl,function(){ loadScript(dbUrl,function(){ try{ var firebaseConfig={ apiKey:'AIzaSyBU6vWqHUbHSnIPdjcGpC3BlwzlwhL24jg', authDomain:'wc2026-sweepstake-dbd56.firebaseapp.com', databaseURL:'https://wc2026-sweepstake-dbd56-default-rtdb.europe-west1.firebasedatabase.app', projectId:'wc2026-sweepstake-dbd56', storageBucket:'wc2026-sweepstake-dbd56.firebasestorage.app', messagingSenderId:'11571340466', appId:'1:11571340466:web:ebfbf6f935ce22ea98d5ab' }; _fbApp=firebase.initializeApp(firebaseConfig); _fbDb=firebase.database(); _fbRef=_fbDb.ref('banter'); _fbRef.on('value',function(snapshot){ var data=snapshot.val(); _fbMessages=[]; if(data){ Object.keys(data).forEach(function(k){_fbMessages.push(data[k]);}); _fbMessages.sort(function(a,b){return a.id-b.id;}); } renderBanter(); updateBanterDot(); }); document.getElementById('banter-status').textContent='Live'; document.getElementById('banter-status').style.color='var(--wc-green)'; }catch(e){ console.warn('Firebase init failed:',e); document.getElementById('banter-status').textContent='Offline'; document.getElementById('banter-status').style.color='var(--gray)'; } }); }); } function updateBanterDot(){ var lastSeen=parseInt(localStorage.getItem('banter-last-seen')||'0',10); var hasNew=_fbMessages.some(function(m){return m.id>lastSeen;}); var dot=document.getElementById('banter-dot'); if(dot)dot.style.display=hasNew?'inline-block':'none'; } function setReply(id){ var msg=_fbMessages.find(function(m){return m.id===id;}); if(!msg)return; replyToId=id; var preview=document.getElementById('banter-reply-preview'); var previewText=document.getElementById('banter-reply-text'); if(preview&&previewText){ previewText.innerHTML=''+msg.name+': '+msg.text.slice(0,60)+(msg.text.length>60?'...':''); preview.style.display='flex'; } var ta=document.getElementById('banter-msg'); if(ta)ta.focus(); } function clearReply(){ replyToId=null; var preview=document.getElementById('banter-reply-preview'); if(preview)preview.style.display='none'; } function renderBanter(){ var sel=document.getElementById('banter-name'); if(sel){ var cur=sel.value; sel.innerHTML=state.players.length ?state.players.map(function(p){return '';}).join('') :''; } var lastSeen=parseInt(localStorage.getItem('banter-last-seen')||'0',10); var msgs=_fbMessages; var feed=document.getElementById('banter-feed'); if(!feed)return; if(!msgs.length){ feed.innerHTML='
No messages yet. Start the banter! 🗣
'; return; } feed.innerHTML=msgs.slice().reverse().map(function(m,i){ var pi=state.players.indexOf(m.name); var col=pi>=0?pc(pi):{bg:'#444'}; var initials=m.name.split(' ').map(function(w){return w[0];}).join('').toUpperCase().slice(0,2); var ts=new Date(m.ts).toLocaleTimeString('en-GB',{hour:'2-digit',minute:'2-digit'}); var dateStr=new Date(m.ts).toLocaleDateString('en-GB',{day:'numeric',month:'short'}); var isNew=m.id>lastSeen; var replyHtml=''; if(m.replyTo){ var orig=_fbMessages.find(function(x){return x.id===m.replyTo;}); if(orig){ var origPi=state.players.indexOf(orig.name); var origCol=origPi>=0?pc(origPi):{bg:'#444'}; replyHtml='
' +''+orig.name+' ' +''+orig.text.slice(0,60)+(orig.text.length>60?'...':'')+'' +'
'; } } return '
' +'
'+initials+'
' +'
' +replyHtml +'
' +''+m.name+'' +(isNew?'':'') +''+dateStr+' '+ts+'' +'' +'' +'
' +'
'+m.text+'
' +'
' +'
'; }).join(''); } function scrollToBanter(id){ var el=document.getElementById('banter-msg-'+id); if(el){el.scrollIntoView({behavior:'smooth',block:'center'});el.style.background='rgba(240,180,41,.1)';setTimeout(function(){el.style.background='';},1200);} } function markBanterRead(){ if(!_fbMessages.length)return; var maxId=Math.max.apply(null,_fbMessages.map(function(m){return m.id;})); localStorage.setItem('banter-last-seen',maxId); var dot=document.getElementById('banter-dot'); if(dot)dot.style.display='none'; } function postBanter(){ var name=document.getElementById('banter-name').value; var msg=document.getElementById('banter-msg').value.trim(); if(!name||!msg)return; if(!_fbRef){alert('Not connected to Firebase yet. Please wait a moment and try again.');return;} var entry={id:Date.now(),name:name,text:msg,ts:new Date().toISOString()}; if(replyToId)entry.replyTo=replyToId; _fbRef.push(entry); document.getElementById('banter-msg').value=''; clearReply(); markBanterRead(); } function deleteBanter(id){ if(!_fbRef)return; // Find the Firebase key for this message _fbRef.once('value',function(snapshot){ snapshot.forEach(function(child){ if(child.val().id===id){ child.ref.remove(); } }); }); } /* -- BRACKET PREDICTOR -- */ /* Bracket structure: 32 teams -> R32 (16 matches) -> R16 (8) -> QF (4) -> SF (2) -> Final (1) state.bracket = { rounds: [ [matchObj,...], ... ] // 5 rounds: r32, r16, qf, sf, final } matchObj = { t: [teamNameOrNull, teamNameOrNull], winner: teamNameOrNull } */ var BRACKET_ROUND_NAMES=['Round of 32','Round of 16','Quarter-finals','Semi-finals','Final']; function initBracket(){ if(!state.drawn)return; // WC 2026 official R32 matchup slots by group position // Format: [slot description, group codes for team options] // Each match: {label, groups} where groups are the pool of teams to pick from // Based on official FIFA WC2026 bracket: 12 group winners + 12 runners-up + 8 best 3rds // We simplify: show all teams from the relevant groups as options, user taps to pick var R32_SLOTS=[ // Match 1-16 based on official WC2026 bracket structure // Group winners vs best 3rds / runners-up {a:['A'],b:['B']}, // 1A v 2B {a:['C'],b:['D']}, // 1C v 2D {a:['E'],b:['F']}, // 1E v 2F {a:['G'],b:['H']}, // 1G v 2H {a:['I'],b:['J']}, // 1I v 2J {a:['K'],b:['L']}, // 1K v 2L {a:['B'],b:['A']}, // 1B v 2A {a:['D'],b:['C']}, // 1D v 2C {a:['F'],b:['E']}, // 1F v 2E {a:['H'],b:['G']}, // 1H v 2G {a:['J'],b:['I']}, // 1J v 2I {a:['L'],b:['K']}, // 1L v 2K // Last 4 matches involve 3rd-place qualifiers - use cross-group pools {a:['A','B'],b:['C','D']}, {a:['E','F'],b:['G','H']}, {a:['I','J'],b:['K','L']}, {a:['A','C','E'],b:['B','D','F']} ]; // Build a lookup: group letter -> drawn teams in that group var groupMap={}; var SCHEDULE_GROUPS={ A:['MEX','RSA','KOR','CZE'],B:['CAN','BIH','QAT','SUI'], C:['BRA','MAR','HAI','SCO'],D:['USA','PAR','AUS','TUR'], E:['GER','CUW','CIV','ECU'],F:['NED','JPN','SWE','TUN'], G:['BEL','EGY','IRN','NZL'],H:['ESP','CPV','KSA','URU'], I:['FRA','SEN','IRQ','NOR'],J:['ARG','ALG','AUT','JOR'], K:['POR','COD','UZB','COL'],L:['ENG','CRO','GHA','PAN'] }; var drawnCodes={}; Object.values(state.assignments).forEach(function(ts){ ts.forEach(function(tn){ var t=TEAMS.find(function(x){return x.name===tn;}); if(t)drawnCodes[t.code]=tn; }); }); Object.keys(SCHEDULE_GROUPS).forEach(function(g){ groupMap[g]=SCHEDULE_GROUPS[g].filter(function(c){return drawnCodes[c];}).map(function(c){return drawnCodes[c];}); }); var matches=R32_SLOTS.map(function(slot){ // pool for side a: all drawn teams from those groups var poolA=[],poolB=[]; slot.a.forEach(function(g){poolA=poolA.concat(groupMap[g]||[]);}); slot.b.forEach(function(g){poolB=poolB.concat(groupMap[g]||[]);}); // pick first from each pool as default slot (user can change by tapping) return {t:[poolA[0]||null,poolB[0]||null],poolA:poolA,poolB:poolB,winner:null}; }); var rounds=[matches]; for(var r=0;r<4;r++){ var prev=rounds[r]; var next=[]; for(var j=0;j=4)return; var m=state.bracket.rounds[round][match]; if(!m)return; // if the old team (being replaced) was the winner, clear their downstream too var oldTeam=m.t[slot]; if(oldTeam&&m.winner===oldTeam){ m.winner=null; var nextMatch=Math.floor(match/2); var nextSlot=match%2; clearDownstream(round+1,nextMatch,oldTeam,nextSlot); if(state.bracket.rounds[round+1][nextMatch]){ state.bracket.rounds[round+1][nextMatch].t[nextSlot]=null; } } } function resetBracket(){ if(!confirm('Reset bracket prediction?'))return; state.bracket=null; save(); renderBracket(); } function renderBracket(){ var el=document.getElementById('bracket-content'); var champCard=document.getElementById('bracket-champion-card'); if(!el)return; if(!state.drawn){el.innerHTML='
Do the draw first to unlock the bracket predictor.
';if(champCard)champCard.style.display='none';return;} if(!state.bracket||!state.bracket.rounds||!state.bracket.rounds[0]||!state.bracket.rounds[0].length){ el.innerHTML='

Uses the 12 official WC 2026 groups

'; if(champCard)champCard.style.display='none'; return; } var rounds=state.bracket.rounds; var html='
'; for(var r=0;r'; html+='
'; for(var m=0;m=0;}); var flagHtml=flagCache[ct.code]?'':(ct.emoji?''+ct.emoji+'':''); document.getElementById('bracket-champion-display').innerHTML= '
' +'
\uD83C\uDFC6
' +'
'+flagHtml+'
' +'
'+champ+'
' +(owner?'
Drawn by '+owner[0]+'
':'') +'
'; } else if(champCard){ champCard.style.display='none'; } } function renderBracketMatch(round,matchIdx,m){ var t0=m.t[0]; var t1=m.t[1]; var w=m.winner; function teamHtml(tn,slot){ var pool=slot===0?(m.poolA||[]):(m.poolB||[]); if(!tn&&!pool.length){ return '
TBD
'; } // If round 0 and pool has multiple options, show a mini-select if(round===0&&pool.length>1){ var selOpts=pool.map(function(ptn){ var pt=TEAMS.find(function(x){return x.name===ptn;})||{code:'???'}; return ''; }).join(''); var curT=tn?TEAMS.find(function(x){return x.name===tn;})||{code:'???',emoji:'',rank:99}:{code:'?',emoji:'',rank:99}; var flagHtml=tn&&flagCache[curT.code]?'': (tn&&curT.emoji?''+curT.emoji+'':''); return '
' +flagHtml +'' +(w===tn?'\u2714':'') +(tn?'':'') +'
'; } if(!tn){ return '
TBD
'; } var t=TEAMS.find(function(x){return x.name===tn;})||{code:'???',emoji:'',rank:99}; var isW=w===tn; var isL=w&&w!==tn; var flagHtml2=flagCache[t.code]?'':(t.emoji?''+t.emoji+'':''); var owner=Object.entries(state.assignments).find(function(e){return e[1].indexOf(tn)>=0;}); var ownerInitials=owner?owner[0].split(' ').map(function(w2){return w2[0];}).join('').toUpperCase().slice(0,2):''; var pi=owner?state.players.indexOf(owner[0]):-1; var ownerCol=pi>=0?pc(pi).bg:'#666'; return '
' +flagHtml2 +''+t.code+'' +(ownerInitials?''+ownerInitials+'':'') +(isW?'\u2714':'') +'
'; } return '
'+teamHtml(t0,0)+teamHtml(t1,1)+'
'; } function swapBracketSlot(round,match,slot,teamName){ if(!state.bracket)return; var m=state.bracket.rounds[round][match]; if(!m)return; m.t[slot]=teamName; if(m.winner&&m.winner!==m.t[0]&&m.winner!==m.t[1])m.winner=null; save();renderBracket(); } function shareBracket(){ if(!state.bracket)return; var rounds=state.bracket.rounds; var rnames=['R32','R16','QF','SF','Final']; var txt='\u26BD WC 2026 BRACKET PREDICTION \u26BD\n'; for(var r=0;rfetchResults()); } else { setSyncStatus('','No API key set \u2014 add one in Setup for live results'); }