FIFA World Cup 2026 Complete Schedule — All 104 Matches, Dates & Venues

Sports LiveJun 13, 2026
FIFA World Cup 2026 Complete Schedule — All 104 Matches, Dates & Venues
<!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>