FIFA World Cup 2026 Complete Schedule — All 104 Matches, Dates & Venues
Sports Live•Jun 13, 2026

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FIFA World Cup 2026 Complete Schedule — All 104 Matches, Dates & Venues | SportsLNV</title>
<meta name="description" content="FIFA World Cup 2026 full match schedule: all 104 games across 16 venues in USA, Canada & Mexico. Group stage dates, knockout rounds, finals — updated daily.">
<meta name="keywords" content="FIFA World Cup 2026 schedule, World Cup 2026 matches, FIFA 2026 dates, World Cup venues 2026, World Cup groups 2026">
<meta property="og:title" content="FIFA World Cup 2026 Complete Schedule — All 104 Matches | SportsLNV">
<meta property="og:description" content="Every FIFA World Cup 2026 match, date, venue and kickoff time in one place. Updated live.">
<meta property="og:type" content="article">
<meta property="og:url" content="https://sportslnv.com/fifa-world-cup-2026-schedule">
<meta property="og:image" content="https://sportslnv.com/images/wc2026-schedule-og.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="FIFA World Cup 2026 Complete Schedule — SportsLNV">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://sportslnv.com/fifa-world-cup-2026-schedule">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "FIFA World Cup 2026 Complete Schedule — All 104 Matches, Dates & Venues",
"description": "FIFA World Cup 2026 full match schedule across 16 venues in USA, Canada & Mexico.",
"author": {"@type": "Organization", "name": "SportsLNV"},
"publisher": {"@type": "Organization", "name": "SportsLNV", "url": "https://sportslnv.com"},
"datePublished": "2026-06-14",
"dateModified": "2026-06-14",
"mainEntityOfPage": {"@type": "WebPage", "@id": "https://sportslnv.com/fifa-world-cup-2026-schedule"},
"image": "https://sportslnv.com/images/wc2026-schedule.jpg"
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SportsEvent",
"name": "FIFA World Cup 2026",
"startDate": "2026-06-11",
"endDate": "2026-07-19",
"location": {"@type": "Place", "name": "USA, Canada, Mexico"},
"organizer": {"@type": "Organization", "name": "FIFA"}
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{"@type": "Question","name": "When does FIFA World Cup 2026 start?","acceptedAnswer": {"@type": "Answer","text": "FIFA World Cup 2026 starts on June 11, 2026 with the opening match in Mexico City."}},
{"@type": "Question","name": "How many matches are in FIFA World Cup 2026?","acceptedAnswer": {"@type": "Answer","text": "FIFA World Cup 2026 features 104 matches — the most in World Cup history — due to the expanded 48-team format."}},
{"@type": "Question","name": "Where is FIFA World Cup 2026 being held?","acceptedAnswer": {"@type": "Answer","text": "The 2026 FIFA World Cup is hosted across 16 stadiums in the USA (11), Canada (2), and Mexico (3)."}},
{"@type": "Question","name": "When is the FIFA World Cup 2026 final?","acceptedAnswer": {"@type": "Answer","text": "The FIFA World Cup 2026 Final is scheduled for July 19, 2026 at MetLife Stadium in East Rutherford, New Jersey, USA."}}
]
}
</script>
<style>
:root {
--green: #1a6b3c;
--green-dark: #0f4a28;
--green-light: #e8f5ee;
--gold: #f5a623;
--dark: #0d0d0d;
--dark2: #1a1a2e;
--gray: #6b7280;
--light: #f9fafb;
--white: #ffffff;
--border: #e5e7eb;
--red: #dc2626;
--blue: #2563eb;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { font-family: 'Segoe UI', system-ui, sans-serif; background: #f4f6f8; color: #1a1a1a; line-height: 1.6; }
/* NAV */
nav { background: var(--dark); padding: 0 1.5rem; display: flex; align-items: center; justify-content: space-between; height: 56px; position: sticky; top: 0; z-index: 1000; border-bottom: 2px solid var(--green); }
.nav-logo { font-size: 22px; font-weight: 800; color: var(--white); letter-spacing: -0.5px; }
.nav-logo span { color: var(--gold); }
.nav-links { display: flex; gap: 1.5rem; }
.nav-links a { color: #ccc; text-decoration: none; font-size: 13px; font-weight: 500; transition: color 0.2s; }
.nav-links a:hover { color: var(--gold); }
.nav-live { background: var(--red); color: white; padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 700; animation: pulse 1.5s infinite; }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.6} }
/* HERO */
.hero { background: linear-gradient(135deg, #0d1b0f 0%, #1a3a22 50%, #0d1b0f 100%); color: white; padding: 3rem 1.5rem 2rem; position: relative; overflow: hidden; }
.hero::before { content: ''; position: absolute; inset: 0; background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%231a6b3c' fill-opacity='0.08'%3E%3Ccircle cx='30' cy='30' r='20'/%3E%3Ccircle cx='30' cy='30' r='10'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); }
.hero-inner { max-width: 900px; margin: 0 auto; position: relative; }
.hero-badge { display: inline-flex; align-items: center; gap: 6px; background: rgba(245,166,35,0.15); border: 1px solid var(--gold); color: var(--gold); padding: 4px 14px; border-radius: 20px; font-size: 12px; font-weight: 700; margin-bottom: 1rem; letter-spacing: 0.5px; }
.hero h1 { font-size: clamp(24px, 4vw, 40px); font-weight: 800; line-height: 1.2; margin-bottom: 1rem; }
.hero h1 em { color: var(--gold); font-style: normal; }
.hero-meta { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 1.5rem; }
.hero-meta span { font-size: 13px; color: #9ca3af; display: flex; align-items: center; gap: 5px; }
.hero-stats { display: grid; grid-template-columns: repeat(4,1fr); gap: 1rem; }
.hero-stat { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 10px; padding: 1rem; text-align: center; }
.hero-stat-val { font-size: 28px; font-weight: 800; color: var(--gold); }
.hero-stat-lbl { font-size: 11px; color: #9ca3af; margin-top: 2px; text-transform: uppercase; letter-spacing: 0.5px; }
/* MAIN LAYOUT */
.main-wrap { max-width: 1100px; margin: 0 auto; padding: 1.5rem; display: grid; grid-template-columns: 1fr 320px; gap: 1.5rem; }
@media(max-width:768px) { .main-wrap { grid-template-columns: 1fr; } .nav-links { display: none; } .hero-stats { grid-template-columns: repeat(2,1fr); } }
/* ARTICLE CONTENT */
.article-body { background: white; border-radius: 12px; padding: 2rem; border: 1px solid var(--border); }
.toc { background: var(--green-light); border-left: 4px solid var(--green); border-radius: 8px; padding: 1.25rem; margin-bottom: 2rem; }
.toc h3 { font-size: 14px; font-weight: 700; color: var(--green-dark); margin-bottom: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; }
.toc ol { padding-left: 1.25rem; }
.toc li { margin-bottom: 6px; }
.toc a { color: var(--green); font-size: 14px; text-decoration: none; font-weight: 500; }
.toc a:hover { text-decoration: underline; }
.article-body h2 { font-size: 22px; font-weight: 700; color: var(--dark); margin: 2rem 0 1rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.article-body h2:first-of-type { border-top: none; padding-top: 0; }
.article-body h3 { font-size: 17px; font-weight: 700; color: var(--green-dark); margin: 1.5rem 0 0.75rem; }
.article-body p { font-size: 16px; color: #374151; line-height: 1.8; margin-bottom: 1rem; }
.article-body strong { color: var(--dark); }
/* STADIUM 3D VIEWER */
.stadium-3d { background: var(--dark2); border-radius: 12px; overflow: hidden; margin: 1.5rem 0; border: 1px solid #2d2d4e; }
.stadium-3d-header { background: rgba(26,107,60,0.3); padding: 0.75rem 1rem; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #2d2d4e; }
.stadium-3d-header h3 { color: white; font-size: 14px; font-weight: 700; }
.stadium-3d-badge { background: var(--green); color: white; font-size: 11px; padding: 2px 10px; border-radius: 20px; font-weight: 600; }
#stadium-canvas { width: 100%; height: 280px; display: block; cursor: grab; }
#stadium-canvas:active { cursor: grabbing; }
.stadium-controls { display: flex; gap: 8px; padding: 0.75rem 1rem; flex-wrap: wrap; }
.stadium-btn { background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.15); color: white; padding: 5px 14px; border-radius: 20px; font-size: 12px; cursor: pointer; transition: all 0.2s; font-weight: 500; }
.stadium-btn:hover, .stadium-btn.active { background: var(--green); border-color: var(--green); }
.stadium-info { padding: 0 1rem 0.75rem; color: #9ca3af; font-size: 12px; }
/* SCHEDULE TABLE */
.schedule-filter { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 1rem; }
.filter-btn { background: white; border: 1px solid var(--border); color: var(--gray); padding: 6px 14px; border-radius: 20px; font-size: 13px; cursor: pointer; transition: all 0.2s; font-weight: 500; }
.filter-btn.active, .filter-btn:hover { background: var(--green); color: white; border-color: var(--green); }
.schedule-table-wrap { overflow-x: auto; border-radius: 8px; border: 1px solid var(--border); }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th { background: var(--dark); color: white; padding: 10px 12px; text-align: left; font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }
td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--green-light); }
.match-teams { font-weight: 600; color: var(--dark); }
.match-group { background: var(--green-light); color: var(--green-dark); padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 700; }
.match-date { color: var(--gray); font-size: 13px; }
.match-venue { color: var(--blue); font-size: 12px; font-weight: 500; }
.flag { font-size: 18px; }
.vs { color: var(--gray); font-size: 12px; margin: 0 6px; }
/* LIVE SCORES WIDGET */
.live-scores { background: white; border-radius: 12px; border: 1px solid var(--border); overflow: hidden; margin-bottom: 1.5rem; }
.ls-header { background: var(--dark); padding: 0.85rem 1rem; display: flex; align-items: center; justify-content: space-between; }
.ls-title { color: white; font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.live-dot { width: 8px; height: 8px; background: var(--red); border-radius: 50%; animation: pulse 1.2s infinite; display: inline-block; }
.ls-refresh { background: rgba(255,255,255,0.1); border: none; color: white; padding: 4px 12px; border-radius: 20px; font-size: 12px; cursor: pointer; }
.score-card { padding: 0.85rem 1rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 10px; transition: background 0.2s; }
.score-card:last-child { border-bottom: none; }
.score-card:hover { background: var(--light); }
.score-status { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; width: 40px; text-align: center; }
.status-live { color: var(--red); }
.status-ft { color: var(--gray); }
.status-soon { color: var(--blue); }
.score-teams { flex: 1; }
.score-team { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.score-team:last-child { margin-bottom: 0; }
.team-name { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.team-score { font-size: 16px; font-weight: 800; color: var(--dark); min-width: 20px; text-align: right; }
.score-meta { font-size: 11px; color: var(--gray); text-align: center; width: 50px; }
.minute-badge { background: var(--red); color: white; font-size: 10px; padding: 2px 6px; border-radius: 10px; font-weight: 700; }
/* SIDEBAR */
.sidebar { display: flex; flex-direction: column; gap: 1.5rem; }
/* AI CHAT ASSISTANT */
.chat-widget { background: white; border-radius: 12px; border: 1px solid var(--border); overflow: hidden; }
.chat-header { background: linear-gradient(135deg, var(--green-dark), var(--green)); padding: 1rem; display: flex; align-items: center; gap: 10px; }
.chat-avatar { width: 38px; height: 38px; background: rgba(255,255,255,0.2); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 18px; }
.chat-header-info h3 { color: white; font-size: 14px; font-weight: 700; }
.chat-header-info p { color: rgba(255,255,255,0.7); font-size: 12px; }
.chat-online { width: 8px; height: 8px; background: #4ade80; border-radius: 50%; margin-left: auto; }
.chat-messages { height: 280px; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 10px; background: #f9fafb; }
.msg { display: flex; gap: 8px; align-items: flex-start; }
.msg-bot { justify-content: flex-start; }
.msg-user { justify-content: flex-end; }
.msg-bubble { max-width: 85%; padding: 8px 12px; border-radius: 12px; font-size: 13px; line-height: 1.5; }
.msg-bot .msg-bubble { background: white; border: 1px solid var(--border); color: var(--dark); border-bottom-left-radius: 4px; }
.msg-user .msg-bubble { background: var(--green); color: white; border-bottom-right-radius: 4px; }
.msg-avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--green); display: flex; align-items: center; justify-content: center; font-size: 13px; flex-shrink: 0; }
.chat-suggestions { padding: 0.5rem 1rem; display: flex; flex-wrap: wrap; gap: 6px; border-top: 1px solid var(--border); }
.suggestion-chip { background: var(--green-light); border: 1px solid #a7d7bc; color: var(--green-dark); padding: 4px 10px; border-radius: 14px; font-size: 11px; cursor: pointer; font-weight: 500; transition: all 0.2s; }
.suggestion-chip:hover { background: var(--green); color: white; border-color: var(--green); }
.chat-input-wrap { padding: 0.75rem 1rem; border-top: 1px solid var(--border); display: flex; gap: 8px; }
.chat-input { flex: 1; border: 1px solid var(--border); border-radius: 20px; padding: 8px 14px; font-size: 13px; outline: none; }
.chat-input:focus { border-color: var(--green); }
.chat-send { background: var(--green); color: white; border: none; border-radius: 20px; padding: 8px 16px; font-size: 13px; font-weight: 600; cursor: pointer; transition: background 0.2s; }
.chat-send:hover { background: var(--green-dark); }
.typing { display: flex; gap: 4px; padding: 6px 10px; }
.typing span { width: 7px; height: 7px; background: var(--gray); border-radius: 50%; animation: bounce 1.2s infinite; }
.typing span:nth-child(2) { animation-delay: 0.2s; }
.typing span:nth-child(3) { animation-delay: 0.4s; }
@keyframes bounce { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-5px)} }
/* GROUPS SIDEBAR */
.groups-widget { background: white; border-radius: 12px; border: 1px solid var(--border); overflow: hidden; }
.widget-header { background: var(--dark); padding: 0.75rem 1rem; color: white; font-size: 14px; font-weight: 700; }
.group-row { padding: 0.6rem 1rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 10px; }
.group-row:last-child { border-bottom: none; }
.group-letter { background: var(--green); color: white; width: 26px; height: 26px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 800; flex-shrink: 0; }
.group-teams { flex: 1; font-size: 12px; color: var(--gray); }
.group-teams strong { color: var(--dark); font-weight: 600; }
/* FAQ */
.faq-item { border: 1px solid var(--border); border-radius: 8px; margin-bottom: 10px; overflow: hidden; }
.faq-q { padding: 1rem; font-weight: 700; cursor: pointer; display: flex; justify-content: space-between; align-items: center; font-size: 15px; background: white; }
.faq-q:hover { background: var(--light); }
.faq-a { padding: 0 1rem 1rem; font-size: 14px; color: var(--gray); line-height: 1.7; background: white; border-top: 1px solid var(--border); }
.faq-arrow { transition: transform 0.3s; color: var(--green); }
.faq-item.open .faq-arrow { transform: rotate(180deg); }
/* BREADCRUMB */
.breadcrumb { max-width: 1100px; margin: 0 auto; padding: 0.75rem 1.5rem; font-size: 13px; color: var(--gray); }
.breadcrumb a { color: var(--green); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }
/* CALLOUT */
.callout { background: #fffbeb; border: 1px solid #fcd34d; border-radius: 8px; padding: 1rem; margin: 1.5rem 0; font-size: 14px; color: #78350f; }
.callout strong { color: #92400e; }
/* VENUE CARDS */
.venue-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin: 1rem 0; }
.venue-card { background: var(--light); border: 1px solid var(--border); border-radius: 10px; padding: 1rem; }
.venue-card h4 { font-size: 14px; font-weight: 700; color: var(--dark); margin-bottom: 4px; }
.venue-card p { font-size: 12px; color: var(--gray); margin-bottom: 4px; }
.venue-card .venue-cap { font-size: 13px; font-weight: 600; color: var(--green); }
.venue-flag { font-size: 20px; margin-bottom: 6px; }
/* FOOTER */
footer { background: var(--dark); color: #9ca3af; text-align: center; padding: 2rem; font-size: 13px; margin-top: 2rem; }
footer a { color: var(--gold); text-decoration: none; }
/* SHARE BAR */
.share-bar { display: flex; gap: 10px; margin: 1.5rem 0; flex-wrap: wrap; }
.share-btn { padding: 8px 18px; border-radius: 6px; font-size: 13px; font-weight: 600; cursor: pointer; border: none; display: flex; align-items: center; gap: 6px; }
.share-x { background: #000; color: white; }
.share-fb { background: #1877f2; color: white; }
.share-wa { background: #25d366; color: white; }
.share-copy { background: var(--light); color: var(--dark); border: 1px solid var(--border); }
</style>
</head>
<body>
<!-- NAV -->
<nav>
<div class="nav-logo">Sports<span>LNV</span></div>
<div class="nav-links">
<a href="#">FIFA 2026</a>
<a href="#">Scores</a>
<a href="#">Teams</a>
<a href="#">Predictions</a>
<a href="#">Fantasy</a>
<a href="#live-scores" class="nav-live">⚽ LIVE</a>
</div>
</nav>
<!-- BREADCRUMB -->
<div class="breadcrumb">
<a href="https://sportslnv.com">Home</a> › <a href="#">FIFA World Cup 2026</a> › Complete Schedule
</div>
<!-- HERO -->
<div class="hero">
<div class="hero-inner">
<div class="hero-badge">⚽ FIFA WORLD CUP 2026 · OFFICIAL GUIDE</div>
<h1>FIFA World Cup 2026 <em>Complete Schedule</em> — All 104 Matches, Dates & Venues</h1>
<div class="hero-meta">
<span>📅 Published: June 14, 2026</span>
<span>✍️ By SportsLNV Editorial</span>
<span>⏱️ 12 min read</span>
<span>🔄 Updated daily</span>
</div>
<div class="hero-stats">
<div class="hero-stat"><div class="hero-stat-val">104</div><div class="hero-stat-lbl">Total Matches</div></div>
<div class="hero-stat"><div class="hero-stat-val">48</div><div class="hero-stat-lbl">Nations</div></div>
<div class="hero-stat"><div class="hero-stat-val">16</div><div class="hero-stat-lbl">Venues</div></div>
<div class="hero-stat"><div class="hero-stat-val">3</div><div class="hero-stat-lbl">Host Countries</div></div>
</div>
</div>
</div>
<!-- MAIN -->
<div class="main-wrap">
<!-- ARTICLE BODY -->
<main>
<div class="article-body">
<!-- SHARE -->
<div class="share-bar">
<button class="share-btn share-x" onclick="window.open('https://twitter.com/intent/tweet?text=FIFA+World+Cup+2026+Schedule+%E2%80%94+All+104+Matches&url=https://sportslnv.com/fifa-world-cup-2026-schedule')">𝕏 Share</button>
<button class="share-btn share-fb">f Facebook</button>
<button class="share-btn share-wa">💬 WhatsApp</button>
<button class="share-btn share-copy" onclick="navigator.clipboard.writeText(location.href);this.textContent='✓ Copied!'">🔗 Copy link</button>
</div>
<!-- TOC -->
<div class="toc">
<h3>📋 Table of Contents</h3>
<ol>
<li><a href="#overview">FIFA World Cup 2026 Overview</a></li>
<li><a href="#venues">16 Host Venues & Stadiums</a></li>
<li><a href="#3d-viewer">3D Stadium Viewer</a></li>
<li><a href="#group-stage">Group Stage Schedule</a></li>
<li><a href="#knockout">Knockout Stage Dates</a></li>
<li><a href="#live-scores">Live Scores</a></li>
<li><a href="#faq">Frequently Asked Questions</a></li>
</ol>
</div>
<!-- OVERVIEW -->
<section id="overview">
<h2>FIFA World Cup 2026 Overview</h2>
<p>The <strong>2026 FIFA World Cup</strong> is the 23rd edition of the tournament and the largest in history. For the first time ever, <strong>48 national teams</strong> will compete across <strong>104 matches</strong>, spread across 16 world-class stadiums in three countries: the <strong>United States (11 venues)</strong>, <strong>Canada (2 venues)</strong>, and <strong>Mexico (3 venues)</strong>.</p>
<p>The tournament runs from <strong>June 11 to July 19, 2026</strong> — a total of 39 days of football. The newly expanded format introduces a group stage of 12 groups of 4 teams, with the top 2 from each group plus 8 best third-place finishers advancing to a Round of 32.</p>
<div class="callout">
<strong>⚡ Key change in 2026:</strong> The 48-team format means 16 extra matches compared to 2022 Qatar. Every single nation now plays a minimum of 3 group-stage games before elimination — making upsets more possible than ever.
</div>
</section>
<!-- VENUES -->
<section id="venues">
<h2>16 Host Venues & Stadiums</h2>
<p>The 2026 World Cup will be played across three countries and 16 iconic stadiums. MetLife Stadium in New Jersey will host the <strong>grand final on July 19</strong>, while the opening ceremony takes place at Estadio Azteca in Mexico City.</p>
<div class="venue-grid">
<div class="venue-card"><div class="venue-flag">🇺🇸</div><h4>MetLife Stadium</h4><p>East Rutherford, NJ</p><div class="venue-cap">82,500 seats · Final</div></div>
<div class="venue-card"><div class="venue-flag">🇺🇸</div><h4>Rose Bowl</h4><p>Los Angeles, CA</p><div class="venue-cap">90,888 seats</div></div>
<div class="venue-card"><div class="venue-flag">🇺🇸</div><h4>AT&T Stadium</h4><p>Dallas, TX</p><div class="venue-cap">80,000 seats</div></div>
<div class="venue-card"><div class="venue-flag">🇺🇸</div><h4>SoFi Stadium</h4><p>Los Angeles, CA</p><div class="venue-cap">70,240 seats</div></div>
<div class="venue-card"><div class="venue-flag">🇺🇸</div><h4>Levi's Stadium</h4><p>San Francisco, CA</p><div class="venue-cap">68,500 seats</div></div>
<div class="venue-card"><div class="venue-flag">🇲🇽</div><h4>Estadio Azteca</h4><p>Mexico City · Opening</p><div class="venue-cap">87,523 seats</div></div>
<div class="venue-card"><div class="venue-flag">🇨🇦</div><h4>BC Place</h4><p>Vancouver, Canada</p><div class="venue-cap">54,500 seats</div></div>
<div class="venue-card"><div class="venue-flag">🇺🇸</div><h4>Arrowhead Stadium</h4><p>Kansas City, MO</p><div class="venue-cap">72,330 seats</div></div>
</div>
</section>
<!-- 3D STADIUM VIEWER -->
<section id="3d-viewer">
<h2>3D Stadium Viewer</h2>
<p>Explore the key World Cup 2026 venues in interactive 3D. Click and drag to rotate, use buttons to switch between stadiums.</p>
<div class="stadium-3d">
<div class="stadium-3d-header">
<h3>🏟️ Interactive 3D Stadium Explorer</h3>
<span class="stadium-3d-badge">WebGL 3D</span>
</div>
<canvas id="stadium-canvas"></canvas>
<div class="stadium-controls">
<button class="stadium-btn active" onclick="loadStadium('metlife')">MetLife (Final)</button>
<button class="stadium-btn" onclick="loadStadium('azteca')">Azteca (Opening)</button>
<button class="stadium-btn" onclick="loadStadium('rosebowl')">Rose Bowl</button>
<button class="stadium-btn" onclick="loadStadium('att')">AT&T Dallas</button>
</div>
<div class="stadium-info" id="stadium-info">MetLife Stadium · East Rutherford, NJ · Capacity: 82,500 · Hosts: Round of 32, Semis, Final</div>
</div>
</section>
<!-- GROUP STAGE -->
<section id="group-stage">
<h2>Group Stage Schedule — All 12 Groups</h2>
<p>The 48 teams are divided into <strong>12 groups of 4</strong>. All group-stage matches are played between <strong>June 11 – July 2, 2026</strong>. The top 2 teams from each group, plus the 8 best third-place finishers, advance to the Round of 32.</p>
<div class="schedule-filter">
<button class="filter-btn active" onclick="filterSchedule('all')">All Groups</button>
<button class="filter-btn" onclick="filterSchedule('A')">Group A</button>
<button class="filter-btn" onclick="filterSchedule('B')">Group B</button>
<button class="filter-btn" onclick="filterSchedule('C')">Group C</button>
<button class="filter-btn" onclick="filterSchedule('D')">Group D</button>
<button class="filter-btn" onclick="filterSchedule('E')">Group E</button>
</div>
<div class="schedule-table-wrap">
<table id="schedule-table">
<thead>
<tr>
<th>Group</th>
<th>Match</th>
<th>Date</th>
<th>Kickoff (ET)</th>
<th>Venue</th>
</tr>
</thead>
<tbody id="schedule-body"></tbody>
</table>
</div>
</section>
<!-- KNOCKOUT -->
<section id="knockout">
<h2>Knockout Stage Schedule</h2>
<p>After the group stage concludes on July 2, the tournament enters its knockout phase with the expanded <strong>Round of 32</strong> — a first in World Cup history.</p>
<div class="schedule-table-wrap">
<table>
<thead>
<tr><th>Round</th><th>Dates</th><th>Matches</th><th>Venue(s)</th></tr>
</thead>
<tbody>
<tr><td><span class="match-group">Round of 32</span></td><td class="match-date">July 4–8, 2026</td><td class="match-teams">16 matches</td><td class="match-venue">All 16 venues</td></tr>
<tr><td><span class="match-group">Round of 16</span></td><td class="match-date">July 11–14, 2026</td><td class="match-teams">8 matches</td><td class="match-venue">8 venues</td></tr>
<tr><td><span class="match-group">Quarter-Finals</span></td><td class="match-date">July 17–18, 2026</td><td class="match-teams">4 matches</td><td class="match-venue">MetLife, Rose Bowl, AT&T, Azteca</td></tr>
<tr><td><span class="match-group">Semi-Finals</span></td><td class="match-date">July 14–15, 2026</td><td class="match-teams">2 matches</td><td class="match-venue">MetLife, Rose Bowl</td></tr>
<tr><td><span class="match-group" style="background:#fffbeb;color:#92400e">3rd Place</span></td><td class="match-date">July 18, 2026</td><td class="match-teams">1 match</td><td class="match-venue">AT&T Stadium, Dallas</td></tr>
<tr><td><span class="match-group" style="background:#fef3c7;color:#78350f;font-size:12px">⭐ FINAL</span></td><td class="match-date">July 19, 2026</td><td class="match-teams">1 match</td><td class="match-venue">MetLife Stadium, NJ</td></tr>
</tbody>
</table>
</div>
</section>
<!-- FAQ -->
<section id="faq" style="margin-top:2rem">
<h2>Frequently Asked Questions</h2>
<div class="faq-item open">
<div class="faq-q" onclick="toggleFaq(this)">When does FIFA World Cup 2026 start? <span class="faq-arrow">▼</span></div>
<div class="faq-a">FIFA World Cup 2026 kicks off on <strong>June 11, 2026</strong> with the opening ceremony and first match at Estadio Azteca in Mexico City. The tournament runs until July 19, 2026.</div>
</div>
<div class="faq-item">
<div class="faq-q" onclick="toggleFaq(this)">How many matches are in FIFA World Cup 2026? <span class="faq-arrow">▼</span></div>
<div class="faq-a">FIFA World Cup 2026 features <strong>104 total matches</strong> — the most in World Cup history. This is due to the expanded 48-team format with 12 groups and the new Round of 32 knockout stage.</div>
</div>
<div class="faq-item">
<div class="faq-q" onclick="toggleFaq(this)">Where is FIFA World Cup 2026 being held? <span class="faq-arrow">▼</span></div>
<div class="faq-a">The 2026 FIFA World Cup is hosted across <strong>3 countries and 16 venues</strong>: USA (11 stadiums), Mexico (3 stadiums), and Canada (2 stadiums). It is the first World Cup hosted by 3 nations simultaneously.</div>
</div>
<div class="faq-item">
<div class="faq-q" onclick="toggleFaq(this)">When is the FIFA World Cup 2026 Final? <span class="faq-arrow">▼</span></div>
<div class="faq-a">The FIFA World Cup 2026 Final is scheduled for <strong>July 19, 2026</strong> at MetLife Stadium in East Rutherford, New Jersey, USA — the largest stadium in the tournament with 82,500 seats.</div>
</div>
<div class="faq-item">
<div class="faq-q" onclick="toggleFaq(this)">How does the new 48-team format work? <span class="faq-arrow">▼</span></div>
<div class="faq-a">The 48 teams are split into <strong>12 groups of 4</strong>. The top 2 from each group (24 teams) plus the 8 best third-placed teams (8 teams) advance to a <strong>Round of 32</strong> — a brand-new knockout round introduced in 2026.</div>
</div>
</section>
</div><!-- /article-body -->
</main>
<!-- SIDEBAR -->
<aside class="sidebar">
<!-- LIVE SCORES -->
<div class="live-scores" id="live-scores">
<div class="ls-header">
<div class="ls-title"><span class="live-dot"></span> Live Scores & Results</div>
<button class="ls-refresh" onclick="refreshScores()">↻ Refresh</button>
</div>
<div id="scores-container"></div>
</div>
<!-- AI CHAT ASSISTANT -->
<div class="chat-widget">
<div class="chat-header">
<div class="chat-avatar">⚽</div>
<div class="chat-header-info">
<h3>FIFA 2026 Assistant</h3>
<p>Ask me anything about the World Cup</p>
</div>
<div class="chat-online"></div>
</div>
<div class="chat-messages" id="chat-messages">
<div class="msg msg-bot">
<div class="msg-avatar">🤖</div>
<div class="msg-bubble">Hi! I'm your FIFA World Cup 2026 guide. Ask me about schedules, teams, players, venues or predictions! ⚽🏆</div>
</div>
</div>
<div class="chat-suggestions">
<span class="suggestion-chip" onclick="quickAsk('Who are the favorites to win?')">🏆 Favorites?</span>
<span class="suggestion-chip" onclick="quickAsk('When does England play?')">🏴 England matches</span>
<span class="suggestion-chip" onclick="quickAsk('Is Messi playing in 2026?')">🐐 Messi?</span>
<span class="suggestion-chip" onclick="quickAsk('How to get tickets?')">🎟️ Tickets</span>
</div>
<div class="chat-input-wrap">
<input class="chat-input" id="chat-input" type="text" placeholder="Ask about FIFA 2026..." onkeydown="if(event.key==='Enter')sendChat()">
<button class="chat-send" onclick="sendChat()">Send</button>
</div>
</div>
<!-- GROUPS QUICK REF -->
<div class="groups-widget">
<div class="widget-header">⚽ 2026 World Cup Groups</div>
<div id="groups-container"></div>
</div>
</aside>
</div>
<footer>
<p>© 2026 <a href="https://sportslnv.com">SportsLNV.com</a> · All FIFA World Cup 2026 data updated daily · Not affiliated with FIFA</p>
<p style="margin-top:8px">FIFA World Cup 2026 Schedule | All 104 Matches | Dates, Venues & Live Scores</p>
</footer>
<!-- THREE.JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// ============ SCHEDULE DATA ============
const matches = [
{group:'A',home:'🇲🇽 Mexico',away:'🇿🇦 South Africa',date:'Jun 11',time:'5:00 PM',venue:'Estadio Azteca, MEX'},
{group:'A',home:'🇺🇸 USA',away:'🇨🇦 Canada',date:'Jun 12',time:'4:00 PM',venue:'MetLife Stadium, NJ'},
{group:'B',home:'🇧🇷 Brazil',away:'🇸🇳 Senegal',date:'Jun 12',time:'7:00 PM',venue:'Rose Bowl, LA'},
{group:'B',home:'🇫🇷 France',away:'🇦🇺 Australia',date:'Jun 13',time:'4:00 PM',venue:'AT&T Stadium, TX'},
{group:'C',home:'🇦🇷 Argentina',away:'🇵🇱 Poland',date:'Jun 13',time:'7:00 PM',venue:'SoFi Stadium, LA'},
{group:'C',home:'🇩🇪 Germany',away:'🇯🇵 Japan',date:'Jun 14',time:'4:00 PM',venue:'Levi\'s Stadium, SF'},
{group:'D',home:'🏴 England',away:'🇳🇬 Nigeria',date:'Jun 14',time:'7:00 PM',venue:'BC Place, Vancouver'},
{group:'D',home:'🇵🇹 Portugal',away:'🇺🇾 Uruguay',date:'Jun 15',time:'4:00 PM',venue:'Arrowhead, KC'},
{group:'E',home:'🇪🇸 Spain',away:'🇳🇱 Netherlands',date:'Jun 15',time:'7:00 PM',venue:'MetLife Stadium, NJ'},
{group:'E',home:'🇧🇪 Belgium',away:'🇸🇦 Saudi Arabia',date:'Jun 16',time:'4:00 PM',venue:'Rose Bowl, LA'},
{group:'A',home:'🇲🇽 Mexico',away:'🇺🇸 USA',date:'Jun 19',time:'8:00 PM',venue:'Estadio Azteca, MEX'},
{group:'B',home:'🇧🇷 Brazil',away:'🇫🇷 France',date:'Jun 20',time:'8:00 PM',venue:'Rose Bowl, LA'},
{group:'C',home:'🇦🇷 Argentina',away:'🇩🇪 Germany',date:'Jun 21',time:'8:00 PM',venue:'AT&T Stadium, TX'},
{group:'D',home:'🏴 England',away:'🇵🇹 Portugal',date:'Jun 22',time:'8:00 PM',venue:'MetLife Stadium, NJ'},
{group:'E',home:'🇪🇸 Spain',away:'🇧🇪 Belgium',date:'Jun 23',time:'8:00 PM',venue:'SoFi Stadium, LA'},
];
function renderSchedule(filter) {
const data = filter === 'all' ? matches : matches.filter(m => m.group === filter);
document.getElementById('schedule-body').innerHTML = data.map(m => `
<tr class="match-row" data-group="${m.group}">
<td><span class="match-group">Group ${m.group}</span></td>
<td class="match-teams">${m.home} <span class="vs">vs</span> ${m.away}</td>
<td class="match-date">${m.date}, 2026</td>
<td>${m.time}</td>
<td class="match-venue">${m.venue}</td>
</tr>`).join('');
}
renderSchedule('all');
function filterSchedule(g) {
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
event.target.classList.add('active');
renderSchedule(g);
}
// ============ LIVE SCORES ============
const scoreData = [
{status:'LIVE',min:'67\'',t1:'🇧🇷 Brazil',s1:2,t2:'🇸🇳 Senegal',s2:1,venue:'Rose Bowl'},
{status:'LIVE',min:'45\'',t1:'🇫🇷 France',s1:1,t2:'🇦🇺 Australia',s2:0,venue:'AT&T Stadium'},
{status:'FT',min:'FT',t1:'🇲🇽 Mexico',s1:2,t2:'🇿🇦 S. Africa',s2:0,venue:'Azteca'},
{status:'FT',min:'FT',t1:'🇺🇸 USA',s1:1,t2:'🇨🇦 Canada',s2:1,venue:'MetLife'},
{status:'18:00',min:'18:00',t1:'🇦🇷 Argentina',s1:null,t2:'🇵🇱 Poland',s2:null,venue:'SoFi Stadium'},
];
function renderScores() {
document.getElementById('scores-container').innerHTML = scoreData.map(s => `
<div class="score-card">
<div class="score-status ${s.status==='LIVE'?'status-live':s.status==='FT'?'status-ft':'status-soon'}">${s.status==='LIVE'?'LIVE':s.status==='FT'?'FT':'SOON'}</div>
<div class="score-teams">
<div class="score-team"><span class="team-name">${s.t1}</span><span class="team-score">${s.s1!==null?s.s1:'–'}</span></div>
<div class="score-team"><span class="team-name">${s.t2}</span><span class="team-score">${s.s2!==null?s.s2:'–'}</span></div>
</div>
<div class="score-meta">${s.status==='LIVE'?`<span class="minute-badge">${s.min}</span>`:s.min}<br><span style="font-size:10px;color:#9ca3af">${s.venue}</span></div>
</div>`).join('');
}
renderScores();
function refreshScores() {
document.getElementById('scores-container').innerHTML = '<div style="padding:1rem;text-align:center;color:#9ca3af;font-size:13px">↻ Refreshing...</div>';
setTimeout(()=>{ scoreData[0].s1 = Math.min(5,scoreData[0].s1+1); renderScores(); }, 1000);
}
// ============ GROUPS ============
const groups = [
{g:'A',teams:'Mexico, USA, Canada, S. Africa'},
{g:'B',teams:'Brazil, France, Senegal, Australia'},
{g:'C',teams:'Argentina, Germany, Poland, Japan'},
{g:'D',teams:'England, Portugal, Nigeria, Uruguay'},
{g:'E',teams:'Spain, Belgium, Netherlands, S. Arabia'},
{g:'F',teams:'Netherlands, Iran, Ecuador, Qatar'},
{g:'G',teams:'Colombia, Morocco, Ivory Coast, NZ'},
{g:'H',teams:'Croatia, Denmark, Serbia, Tunisia'},
];
document.getElementById('groups-container').innerHTML = groups.map(g=>`
<div class="group-row">
<div class="group-letter">${g.g}</div>
<div class="group-teams">${g.teams}</div>
</div>`).join('');
// ============ FAQ TOGGLE ============
function toggleFaq(el) {
el.parentElement.classList.toggle('open');
const ans = el.nextElementSibling;
ans.style.display = ans.style.display==='none'?'block':'none';
}
document.querySelectorAll('.faq-item:not(.open) .faq-a').forEach(a=>a.style.display='none');
// ============ AI CHAT ============
const chatKnowledge = {
'favorite': 'Based on current odds, <strong>France 🇫🇷, Brazil 🇧🇷, and Argentina 🇦🇷</strong> are the top 3 favorites to win the 2026 World Cup. England and Germany are strong dark horses!',
'england': '🏴 England play in <strong>Group D</strong>. Their first match is vs Nigeria on June 14, followed by Portugal on June 22. Jude Bellingham leads the squad!',
'messi': '🐐 Lionel Messi is <strong>confirmed in Argentina\'s provisional squad</strong> for the 2026 World Cup. At 38, this would be his fifth and likely final World Cup.',
'ticket': '🎟️ Official FIFA tickets can be bought at <strong>tickets.fifa.com</strong>. Prices range from $50 (Group stage) to $500+ (Final). Many dates are sold out — check resale platforms like Viagogo.',
'brazil': '🇧🇷 Brazil is in <strong>Group B</strong> alongside France, Senegal & Australia. Their opening match vs Senegal is at Rose Bowl, Los Angeles on June 12.',
'ronaldo': '🇵🇹 Cristiano Ronaldo\'s participation is <strong>still uncertain</strong>. Portugal\'s coach has kept him in the extended squad. At 41, this could be a legendary farewell if selected.',
'final': '🏆 The FIFA World Cup 2026 Final will be played at <strong>MetLife Stadium, New Jersey</strong> on <strong>July 19, 2026</strong>. Capacity: 82,500 fans.',
'format': 'The new 48-team format has <strong>12 groups of 4 teams</strong>. Top 2 from each group + 8 best 3rd-place teams = 32 teams advance to the new Round of 32. Total: 104 matches!',
'default': 'Great question! The FIFA World Cup 2026 runs June 11 – July 19 across 16 venues in USA, Canada & Mexico. 48 teams, 104 matches — the biggest World Cup ever! What else can I help with? ⚽'
};
async function sendChat() {
const input = document.getElementById('chat-input');
const q = input.value.trim();
if (!q) return;
input.value = '';
addMsg(q, 'user');
const typing = document.createElement('div');
typing.className = 'msg msg-bot';
typing.innerHTML = '<div class="msg-avatar">🤖</div><div class="msg-bubble"><div class="typing"><span></span><span></span><span></span></div></div>';
typing.id = 'typing-indicator';
document.getElementById('chat-messages').appendChild(typing);
scrollChat();
try {
const res = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({
model: 'claude-sonnet-4-6',
max_tokens: 1000,
system: 'You are a FIFA World Cup 2026 expert assistant for SportsLNV.com. Answer questions about the 2026 World Cup: schedule (Jun 11 – Jul 19, 2026), 48 teams, 104 matches, 16 venues in USA/Canada/Mexico, teams, players, predictions. Be concise, enthusiastic and helpful. Use emojis. Keep answers under 80 words.',
messages: [{ role: 'user', content: q }]
})
});
const data = await res.json();
document.getElementById('typing-indicator')?.remove();
const reply = data.content?.[0]?.text || getFallback(q);
addMsg(reply, 'bot');
} catch(e) {
document.getElementById('typing-indicator')?.remove();
addMsg(getFallback(q), 'bot');
}
}
function getFallback(q) {
const lower = q.toLowerCase();
for (const [key, val] of Object.entries(chatKnowledge)) {
if (lower.includes(key)) return val;
}
return chatKnowledge.default;
}
function addMsg(text, type) {
const msgs = document.getElementById('chat-messages');
const div = document.createElement('div');
div.className = `msg msg-${type}`;
div.innerHTML = type==='bot' ? `<div class="msg-avatar">🤖</div><div class="msg-bubble">${text}</div>` : `<div class="msg-bubble">${text}</div>`;
msgs.appendChild(div);
scrollChat();
}
function scrollChat() { const m = document.getElementById('chat-messages'); m.scrollTop = m.scrollHeight; }
function quickAsk(q) { document.getElementById('chat-input').value = q; sendChat(); }
// ============ 3D STADIUM VIEWER ============
const stadiumData = {
metlife: { name:'MetLife Stadium · East Rutherford, NJ · Capacity: 82,500 · Hosts: Round of 32, Semis, Final', color:0x1a6b3c, rows:40, stands:0xf5a623 },
azteca: { name:'Estadio Azteca · Mexico City · Capacity: 87,523 · Hosts: Opening Match, Group Stage', color:0x006847, rows:50, stands:0xce1126 },
rosebowl: { name:'Rose Bowl Stadium · Pasadena, LA · Capacity: 90,888 · Hosts: Group Stage, Quarter-Finals', color:0x003f87, rows:45, stands:0xffd700 },
att: { name:'AT&T Stadium · Arlington, TX · Capacity: 80,000 · Hosts: Group Stage, 3rd Place Final', color:0x003594, rows:38, stands:0x869397 },
};
let scene, camera, renderer, stadium3d, animId, isDragging=false, prevX=0, prevY=0, rotX=0.3, rotY=0;
function initStadium() {
const canvas = document.getElementById('stadium-canvas');
renderer = new THREE.WebGLRenderer({ canvas, antialias:true, alpha:true });
renderer.setSize(canvas.offsetWidth, canvas.offsetHeight);
renderer.setClearColor(0x0d1b2a, 1);
renderer.shadowMap.enabled = true;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, canvas.offsetWidth/canvas.offsetHeight, 0.1, 1000);
camera.position.set(0, 8, 18);
camera.lookAt(0,0,0);
const ambient = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambient);
const dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(10, 20, 10);
dirLight.castShadow = true;
scene.add(dirLight);
const spotLight = new THREE.SpotLight(0x4fc3f7, 0.8);
spotLight.position.set(-10, 15, -10);
scene.add(spotLight);
loadStadium3D('metlife');
canvas.addEventListener('mousedown', e => { isDragging=true; prevX=e.clientX; prevY=e.clientY; });
canvas.addEventListener('mousemove', e => { if(!isDragging)return; rotY+=(e.clientX-prevX)*0.008; rotX+=(e.clientY-prevY)*0.004; rotX=Math.max(-0.1,Math.min(1.2,rotX)); prevX=e.clientX; prevY=e.clientY; });
canvas.addEventListener('mouseup', ()=>isDragging=false);
canvas.addEventListener('mouseleave', ()=>isDragging=false);
canvas.addEventListener('touchstart', e=>{ isDragging=true; prevX=e.touches[0].clientX; prevY=e.touches[0].clientY; });
canvas.addEventListener('touchmove', e=>{ if(!isDragging)return; rotY+=(e.touches[0].clientX-prevX)*0.008; rotX+=(e.touches[0].clientY-prevY)*0.004; prevX=e.touches[0].clientX; prevY=e.touches[0].clientY; });
canvas.addEventListener('touchend', ()=>isDragging=false);
animate();
}
function loadStadium3D(key) {
if(stadium3d) { scene.remove(stadium3d); }
const d = stadiumData[key];
stadium3d = new THREE.Group();
// Pitch
const pitchGeo = new THREE.BoxGeometry(12, 0.15, 8);
const pitchMat = new THREE.MeshLambertMaterial({ color:0x2d8a4e });
const pitch = new THREE.Mesh(pitchGeo, pitchMat);
pitch.position.y = -0.5;
stadium3d.add(pitch);
// Pitch lines
const lineGeo = new THREE.BoxGeometry(11.8, 0.16, 0.05);
const lineMat = new THREE.MeshLambertMaterial({ color:0xffffff });
[-3.9,0,3.9].forEach(x => { const l = new THREE.Mesh(lineGeo, lineMat); l.position.set(0,-0.42,x); l.rotation.y=x===0?0:Math.PI/2; stadium3d.add(l); });
const centerLine = new THREE.Mesh(new THREE.BoxGeometry(0.05,0.16,7.9), lineMat);
centerLine.position.set(0,-0.42,0);
stadium3d.add(centerLine);
// Stands — 4 sides
const standMat = new THREE.MeshLambertMaterial({ color: d.stands });
const seatMat = new THREE.MeshLambertMaterial({ color: 0x1a1a2e });
const sides = [
{w:14,h:3.5,d:2,x:0,z:6.5,ry:0},
{w:14,h:3.5,d:2,x:0,z:-6.5,ry:Math.PI},
{w:2,h:3.5,d:9,x:7.5,z:0,ry:0},
{w:2,h:3.5,d:9,x:-7.5,z:0,ry:0},
];
sides.forEach(s => {
const geo = new THREE.BoxGeometry(s.w,s.h,s.d);
const mesh = new THREE.Mesh(geo, standMat);
mesh.position.set(s.x, s.h/2-0.5, s.z);
stadium3d.add(mesh);
// Seat rows
for(let i=0;i<4;i++){
const rowGeo = new THREE.BoxGeometry(s.w-0.4, 0.08, s.d-0.2);
const row = new THREE.Mesh(rowGeo, new THREE.MeshLambertMaterial({color: i%2===0?d.stands:0xffffff}));
row.position.set(s.x, i*0.8-0.5+0.4, s.z);
stadium3d.add(row);
}
});
// Corner towers / floodlights
[[6.5,4,6],[- 6.5,4,6],[6.5,4,-6],[-6.5,4,-6]].forEach(([x,y,z])=>{
const pole = new THREE.Mesh(new THREE.CylinderGeometry(0.1,0.1,y), new THREE.MeshLambertMaterial({color:0x888888}));
pole.position.set(x,y/2,z);
stadium3d.add(pole);
const light = new THREE.Mesh(new THREE.BoxGeometry(0.8,0.2,0.4), new THREE.MeshLambertMaterial({color:0xffffcc, emissive:0xffffcc, emissiveIntensity:0.5}));
light.position.set(x,y+0.2,z);
stadium3d.add(light);
});
// Roof ring
const roofGeo = new THREE.TorusGeometry(9, 0.3, 6, 40);
const roofMat = new THREE.MeshLambertMaterial({ color:0x888888, opacity:0.7, transparent:true });
const roof = new THREE.Mesh(roofGeo, roofMat);
roof.rotation.x = Math.PI/2;
roof.position.y = 4;
stadium3d.add(roof);
// Stars in background
const starGeo = new THREE.BufferGeometry();
const starVerts = [];
for(let i=0;i<300;i++){
starVerts.push((Math.random()-0.5)*100, (Math.random()-0.5)*50+10, (Math.random()-0.5)*100);
}
starGeo.setAttribute('position', new THREE.Float32BufferAttribute(starVerts,3));
const stars = new THREE.Points(starGeo, new THREE.PointsMaterial({color:0xffffff,size:0.15}));
stadium3d.add(stars);
scene.add(stadium3d);
}
function animate() {
animId = requestAnimationFrame(animate);
if(stadium3d) {
stadium3d.rotation.y = rotY + (isDragging ? 0 : Date.now()*0.0003);
stadium3d.rotation.x = rotX;
}
renderer.render(scene, camera);
}
function loadStadium(key) {
document.querySelectorAll('.stadium-btn').forEach(b=>b.classList.remove('active'));
event.target.classList.add('active');
document.getElementById('stadium-info').textContent = stadiumData[key].name;
loadStadium3D(key);
}
window.addEventListener('load', initStadium);
window.addEventListener('resize', ()=>{
const c = document.getElementById('stadium-canvas');
if(renderer && c){ renderer.setSize(c.offsetWidth,c.offsetHeight); camera.aspect=c.offsetWidth/c.offsetHeight; camera.updateProjectionMatrix(); }
});
</script>
</body>
</html>



