chore: auto deploy 2026-01-20 20:09:56

This commit is contained in:
taimafanl
2026-01-20 20:09:56 +08:00
parent 619dd37464
commit f45680130b
3 changed files with 366 additions and 74 deletions

View File

@@ -16,8 +16,7 @@ data.languages.forEach(lang => {
// 语言链接 - 动态生成 // 语言链接 - 动态生成
const langLinksHtml = data.languages.map(l => { const langLinksHtml = data.languages.map(l => {
const lContent = data.content[l]; const lContent = data.content[l];
// 只有当不是当前语言时,才显示链接 if (l === lang) return `<span class="active-lang">${lContent.langName}</span>`;
if (l === lang) return `<span style="color:white; margin-left:15px; font-size:13px; font-weight:800">${lContent.langName}</span>`;
return `<a href="../${l}/index.html">${lContent.langName}</a>`; return `<a href="../${l}/index.html">${lContent.langName}</a>`;
}).join(''); }).join('');
html = html.replace(/{{languageLinks}}/g, langLinksHtml); html = html.replace(/{{languageLinks}}/g, langLinksHtml);
@@ -28,10 +27,12 @@ data.languages.forEach(lang => {
// 表格行 + 详情行 // 表格行 + 详情行
const rowsHtml = content.cities.map((city, idx) => ` const rowsHtml = content.cities.map((city, idx) => `
<tr class="city-row" onclick="toggleDetails(${idx})"> <tr id="row-${idx}" class="city-row" onclick="toggleDetails(${idx})">
<td> <td>
<strong>${city.name}</strong> <div class="city-name-cell">
<span class="tag-region">${city.region}</span> <strong>${city.name}</strong>
<span class="tag-region">${city.region}</span>
</div>
</td> </td>
<td>${city.matches}</td> <td>${city.matches}</td>
<td style="font-weight:600">${city.budget}</td> <td style="font-weight:600">${city.budget}</td>

62
data.js
View File

@@ -10,19 +10,16 @@ module.exports = {
ui_stadium: "球场详情", ui_stadium: "球场详情",
ui_logistics: "物流与避坑", ui_logistics: "物流与避坑",
cities: [ cities: [
// 西部赛区 (West)
{ name: "🇨🇦 温哥华 (Vancouver)", region: "西部", matches: "7 场", budget: "$250 - $350", visa: "需加签/eTA", vCls: "v-warn", tips: "气候最凉爽的夏季赛区", std: "卑诗体育馆 (BC Place): 位于市中心,步行可达,有伸缩顶棚。", log: "物价极高公共交通发达6月气候宜人适合旅游。" }, { name: "🇨🇦 温哥华 (Vancouver)", region: "西部", matches: "7 场", budget: "$250 - $350", visa: "需加签/eTA", vCls: "v-warn", tips: "气候最凉爽的夏季赛区", std: "卑诗体育馆 (BC Place): 位于市中心,步行可达,有伸缩顶棚。", log: "物价极高公共交通发达6月气候宜人适合旅游。" },
{ name: "🇺🇸 西雅图 (Seattle)", region: "西部", matches: "6 场", budget: "$220 - $320", visa: "需美签", vCls: "v-req", tips: "全美足球氛围最浓城市", std: "流明球场 (Lumen Field): 以全美最吵闹的观众席著称。", log: "坡道多,建议穿着运动鞋;海鲜非常出名。" }, { name: "🇺🇸 西雅图 (Seattle)", region: "西部", matches: "6 场", budget: "$220 - $320", visa: "需美签", vCls: "v-req", tips: "全美足球氛围最浓城市", std: "流明球场 (Lumen Field): 以全美最吵闹的观众席著称。", log: "坡道多,建议穿着运动鞋;海鲜非常出名。" },
{ name: "🇺🇸 旧金山 (San Francisco)", region: "西部", matches: "6 场", budget: "$300 - $450", visa: "需美签", vCls: "v-req", tips: "科技迷朝圣地", std: "李维斯体育场 (Levi's Stadium): 实际位于圣克拉拉。", log: "⚠️ 警告:球场离旧金山市区 1 小时车程,建议住圣何塞附近。" }, { name: "🇺🇸 旧金山 (San Francisco)", region: "西部", matches: "6 场", budget: "$300 - $450", visa: "需美签", vCls: "v-req", tips: "科技迷朝圣地", std: "李维斯体育场 (Levi's Stadium): 实际位于圣克拉拉。", log: "⚠️ 警告:球场离旧金山市区 1 小时车程,建议住圣何塞附近。" },
{ name: "🇺🇸 洛杉矶 (Los Angeles)", region: "西部", matches: "8 场", budget: "$300 - $500", visa: "需美签", vCls: "v-req", tips: "最奢华的视听球场", std: "SoFi 体育场: 全球造价最高,带环形巨屏,全室内空调。", log: "交通拥堵严重,公共交通差,必须租车。消费水平高。" }, { name: "🇺🇸 洛杉矶 (Los Angeles)", region: "西部", matches: "8 场", budget: "$300 - $500", visa: "需美签", vCls: "v-req", tips: "最奢华的视听球场", std: "SoFi 体育场: 全球造价最高,带环形巨屏,全室内空调。", log: "交通拥堵严重,公共交通差,必须租车。消费水平高。" },
// 中部赛区 (Central)
{ name: "🇲🇽 瓜达拉哈拉 (Guadalajara)", region: "中部", matches: "4 场", budget: "$70 - $110", visa: "免签 (有美签)", vCls: "v-free", tips: "最正宗的墨西哥风情", std: "阿克伦球场: 造型前卫。墨西哥国家队分主场。", log: "龙舌兰之乡;物价极低;需留意基本安全及卫生。" }, { name: "🇲🇽 瓜达拉哈拉 (Guadalajara)", region: "中部", matches: "4 场", budget: "$70 - $110", visa: "免签 (有美签)", vCls: "v-free", tips: "最正宗的墨西哥风情", std: "阿克伦球场: 造型前卫。墨西哥国家队分主场。", log: "龙舌兰之乡;物价极低;需留意基本安全及卫生。" },
{ name: "🇲🇽 墨西哥城 (Mexico City)", region: "中部", matches: "5 场 (揭幕战)", budget: "$80 - $130", visa: "免签 (有美签)", vCls: "v-free", tips: "世界杯“朝圣”第一站", std: "阿兹特克球场: 足球史上唯一的“三朝圣地”,海拔 2240m。", log: "⚠️ 警惕高原反应;开幕式地点;历史感最强,性价比极高。" }, { name: "🇲🇽 墨西哥城 (Mexico City)", region: "中部", matches: "5 场 (揭幕战)", budget: "$80 - $130", visa: "免签 (有美签)", vCls: "v-free", tips: "世界杯“朝圣”第一站", std: "阿兹特克球场: 足球史上唯一的“三朝圣地”,海拔 2240m。", log: "⚠️ 警惕高原反应;开幕式地点;历史感最强,性价比极高。" },
{ name: "🇲🇽 蒙特雷 (Monterrey)", region: "中部", matches: "4 场", budget: "$90 - $140", visa: "免签 (有美签)", vCls: "v-free", tips: "景观最美的“马鞍山”球场", std: "BBVA 体育场: 坐在看台能直视壮丽的山景。", log: "工业之都,生活便利;夏季极热,注意补水。" }, { name: "🇲🇽 蒙特雷 (Monterrey)", region: "中部", matches: "4 场", budget: "$90 - $140", visa: "免签 (有美签)", vCls: "v-free", tips: "景观最美的“马鞍山”球场", std: "BBVA 体育场: 坐在看台能直视壮丽的山景。", log: "工业之都,生活便利;夏季极热,注意补水。" },
{ name: "🇺🇸 休斯顿 (Houston)", region: "中部", matches: "7 场", budget: "$150 - $220", visa: "需美签", vCls: "v-req", tips: "完全无视天气的室内球场", std: "NRG 体育场: 巨大的室内空调球场,完全无视户外热浪。", log: "气候极度湿热;城市极其分散,完全依赖租车。" }, { name: "🇺🇸 休斯顿 (Houston)", region: "中部", matches: "7 场", budget: "$150 - $220", visa: "需美签", vCls: "v-req", tips: "完全无视天气的室内球场", std: "NRG 体育场: 巨大的室内空调球场,完全无视户外热浪。", log: "气候极度湿热;城市极其分散,完全依赖租车。" },
{ name: "🇺🇸 达拉斯 (Dallas)", region: "中部", matches: "9 场 (场次最多)", budget: "$180 - $260", visa: "需美签", vCls: "v-req", tips: "全美赛程大本营", std: "AT&T 体育场: 承办半决赛,拥有全球最大的吊顶屏幕。", log: "全美最核心中转站;夏天极热,但球场内有空调。" }, { name: "🇺🇸 达拉斯 (Dallas)", region: "中部", matches: "9 场 (场次最多)", budget: "$180 - $260", visa: "需美签", vCls: "v-req", tips: "全美赛程大本营", std: "AT&T 体育场: 承办半决赛,拥有全球最大的吊顶屏幕。", log: "全美最核心中转站;夏天极热,但球场内有空调。" },
{ name: "🇺🇸 堪萨斯城 (Kansas City)", region: "中部", matches: "6 场", budget: "$140 - $200", visa: "需美签", vCls: "v-req", tips: "烧烤与最狂热死忠", std: "箭头体育场: 曾创造全球最响亮体育场分贝记录。", log: "地理位置绝佳,适合作为东西部跨城中转站。" }, { name: "🇺🇸 堪萨斯城 (Kansas City)", region: "中部", matches: "6 场", budget: "$140 - $200", visa: "需美签", vCls: "v-req", tips: "烧烤与最狂热死忠", std: "箭头体育场: 曾创造全球最响亮体育场分贝记录。", log: "地理位置绝佳,适合作为东西部跨城中转站。" },
// 东部赛区 (East)
{ name: "🇨🇦 多伦多 (Toronto)", region: "东部", matches: "6 场", budget: "$220 - $320", visa: "需加签/eTA", vCls: "v-warn", tips: "华人社区最发达的赛区", std: "BMO 球场: 扩建后观感紧凑。加国家队主场。", log: "公共交通极其便利;多元文化饮食丰富,生活无障碍。" }, { name: "🇨🇦 多伦多 (Toronto)", region: "东部", matches: "6 场", budget: "$220 - $320", visa: "需加签/eTA", vCls: "v-warn", tips: "华人社区最发达的赛区", std: "BMO 球场: 扩建后观感紧凑。加国家队主场。", log: "公共交通极其便利;多元文化饮食丰富,生活无障碍。" },
{ name: "🇺🇸 波士顿 (Boston)", region: "东部", matches: "7 场", budget: "$280 - $400", visa: "需美签", vCls: "v-req", tips: "历史底蕴与学院风", std: "吉列体育场: 位于 Foxborough 郊区。", log: "⚠️ 警告:离波士顿市区很远,建议搭乘赛事特开火车。" }, { name: "🇺🇸 波士顿 (Boston)", region: "东部", matches: "7 场", budget: "$280 - $400", visa: "需美签", vCls: "v-req", tips: "历史底蕴与学院风", std: "吉列体育场: 位于 Foxborough 郊区。", log: "⚠️ 警告:离波士顿市区很远,建议搭乘赛事特开火车。" },
{ name: "🇺🇸 费城 (Philadelphia)", region: "东部", matches: "6 场", budget: "$200 - $300", visa: "需美签", vCls: "v-req", tips: "东部核心陆路枢纽", std: "林肯金融体育场: 位于费城综合体育中心。", log: "离纽约极近,可以作为纽约住宿太贵的替代选择。" }, { name: "🇺🇸 费城 (Philadelphia)", region: "东部", matches: "6 场", budget: "$200 - $300", visa: "需美签", vCls: "v-req", tips: "东部核心陆路枢纽", std: "林肯金融体育场: 位于费城综合体育中心。", log: "离纽约极近,可以作为纽约住宿太贵的替代选择。" },
@@ -33,29 +30,54 @@ module.exports = {
}, },
en: { en: {
langName: "English", langName: "English",
title: "2026 World Cup: 16 Host Cities Planner", title: "FIFA 2026: 16 Cities Comparison Tool",
metaDesc: "Detailed comparison of all 16 host cities for the 2026 World Cup. Visa, budget, and stadiums info.", metaDesc: "Comprehensive guide for the 2026 FIFA World Cup: Compare 16 host cities on matches, budget, visas, and stadium tips.",
headers: ["City & Region", "Matches", "Budget", "Visa", "Vibe"], headers: ["City & Region", "Matches", "Budget", "Visa Info", "Key Tips"],
ui_stadium: "Stadium Info", ui_stadium: "Stadium Details",
ui_logistics: "Logistics", ui_logistics: "Logistics & Advice",
cities: [ cities: [
{ name: "🇲🇽 Mexico City", region: "Central", matches: "5 (Opener)", budget: "$80-130", visa: "Visa Free*", vCls: "v-free", tips: "The Opening Ceremony", std: "Estadio Azteca: Historic temple.", log: "Altitude alert: 2,240m. Stay hydrated." }, { name: "🇨🇦 Vancouver", region: "West", matches: "7 Matches", budget: "$250 - $350", visa: "Visa/eTA Req.", vCls: "v-warn", tips: "Coolest summer climate", std: "BC Place: Downtown, retractable roof, walkable.", log: "High prices; great public transit; pleasant June weather." },
{ name: "🇺🇸 Dallas", region: "Central", matches: "9 (Most)", budget: "$180-260", visa: "Visa Req.", vCls: "v-req", tips: "Most Matches / Hub", std: "AT&T Stadium: Massive dome with giant screen.", log: "Texas heat is real; car rental is a must." }, { name: "🇺🇸 Seattle", region: "West", matches: "6 Matches", budget: "$220 - $320", visa: "US Visa Req.", vCls: "v-req", tips: "Best football atmosphere in USA", std: "Lumen Field: Known for the loudest crowd in the US.", log: "Hilly city, wear sneakers; famous for seafood." },
{ name: "🇺🇸 NY/NJ", region: "East", matches: "8 (Final)", budget: "$400-600", visa: "Visa Req.", vCls: "v-req", tips: "The Grand Finale", std: "MetLife Stadium: World stage for the Final.", log: "Hotels are extremely expensive. Book early." } { name: "🇺🇸 San Francisco", region: "West", matches: "6 Matches", budget: "$300 - $450", visa: "US Visa Req.", vCls: "v-req", tips: "Tech lover's pilgrimage", std: "Levi's Stadium: Located in Santa Clara, not SF city center.", log: "Warning: Stadium is 1 hour from SF; consider staying in San Jose." },
// ... (Other 13 cities simplified for briefness, same structure as above) { name: "🇺🇸 Los Angeles", region: "West", matches: "8 Matches", budget: "$300 - $500", visa: "US Visa Req.", vCls: "v-req", tips: "Ultimate luxury stadium experience", std: "SoFi Stadium: World's most expensive stadium with a giant ring screen.", log: "Heavy traffic, car rental mandatory; high living costs." },
{ name: "🇲🇽 Guadalajara", region: "Central", matches: "4 Matches", budget: "$70 - $110", visa: "Visa-Free (with US Visa)", vCls: "v-free", tips: "Authentic Mexican culture", std: "Estadio Akron: Modern design. Alternative home for Mexico.", log: "Birthplace of Tequila; very affordable; watch for basic safety." },
{ name: "🇲🇽 Mexico City", region: "Central", matches: "5 (Opening)", budget: "$80 - $130", visa: "Visa-Free (with US Visa)", vCls: "v-free", tips: "Football's holiest shrine", std: "Estadio Azteca: Only stadium to host 3 World Cups; 2240m altitude.", log: "Altitude warning; opening match site; historic and great value." },
{ name: "🇲🇽 Monterrey", region: "Central", matches: "4 Matches", budget: "$90 - $140", visa: "Visa-Free (with US Visa)", vCls: "v-free", tips: "Most scenic mountain view stadium", std: "Estadio BBVA: Incredible views of the 'Saddle Mountain'.", log: "Industrial hub; very convenient; extremely hot in summer." },
{ name: "🇺🇸 Houston", region: "Central", matches: "7 Matches", budget: "$150 - $220", visa: "US Visa Req.", vCls: "v-req", tips: "All-weather indoor stadium", std: "NRG Stadium: Massive air-conditioned dome ignoring outdoor heat.", log: "Very humid; city is sprawling; car rental is essential." },
{ name: "🇺🇸 Dallas", region: "Central", matches: "9 (Most)", budget: "$180 - $260", visa: "US Visa Req.", vCls: "v-req", tips: "Central hub for the tournament", std: "AT&T Stadium: Semi-final host, world's largest suspended screen.", log: "The true central hub; hot summer but indoor AC is great." },
{ name: "🇺🇸 Kansas City", region: "Central", matches: "6 Matches", budget: "$140 - $200", visa: "US Visa Req.", vCls: "v-req", tips: "BBQ and die-hard fans", std: "Arrowhead Stadium: Once held the Guinness record for loudest stadium.", log: "Perfect central location for cross-country travel." },
{ name: "🇨🇦 Toronto", region: "East", matches: "6 Matches", budget: "$220 - $320", visa: "Visa/eTA Req.", vCls: "v-warn", tips: "Diverse multicultural hub", std: "BMO Field: Compact atmosphere. Home for Canada.", log: "Excellent transit; amazing food diversity; zero-barrier living." },
{ name: "🇺🇸 Boston", region: "East", matches: "7 Matches", budget: "$280 - $400", visa: "US Visa Req.", vCls: "v-req", tips: "History and academic charm", std: "Gillette Stadium: Located in Foxborough, far from downtown.", log: "Warning: Far from Boston; use special tournament trains." },
{ name: "🇺🇸 Philadelphia", region: "East", matches: "6 Matches", budget: "$200 - $300", visa: "US Visa Req.", vCls: "v-req", tips: "The East Coast transit hub", std: "Lincoln Financial Field: Part of the city's sports complex.", log: "Close to NYC; a great budget alternative for accommodation." },
{ name: "🇺🇸 Miami", region: "East", matches: "7 Matches", budget: "$300 - $500", visa: "US Visa Req.", vCls: "v-req", tips: "Football, beach, and parties", std: "Hard Rock Stadium: 3rd place match host. Messi-land.", log: "Vibrant atmosphere; tropical summer rains; stay flexible." },
{ name: "🇺🇸 Atlanta", region: "East", matches: "8 Matches", budget: "$180 - $280", visa: "US Visa Req.", vCls: "v-req", tips: "World's busiest travel hub", std: "Mercedes-Benz Stadium: Semi-final host, unique shutter-style roof.", log: "Busiest airport in the world; stadium is transit-accessible." },
{ name: "🇺🇸 New York / NJ", region: "East", matches: "8 (Final)", budget: "$400 - $600", visa: "US Visa Req.", vCls: "v-req", tips: "Center of the world / Final venue", std: "MetLife Stadium: The venue for the Final on July 19, 2026.", log: "Highest costs; hotels are scarce; stay on NJ side for better rates." }
] ]
}, },
es: { es: {
langName: "Español", langName: "Español",
title: "Guía de las 16 Sedes del Mundial 2026", title: "Sedes Mundial 2026: Guía Comparativa",
metaDesc: "Comparativa detallada de las 16 sedes de la Copa Mundial 2026. Visa, presupuesto y estadios.", metaDesc: "Guía completa del Mundial 2026: Compara las 16 sedes, presupuestos, visas y consejos de estadios.",
headers: ["Ciudad", "Partidos", "Presupuesto", "Visa", "Consejo"], headers: ["Ciudad y Región", "Partidos", "Presupuesto", "Visa", "Claves"],
ui_stadium: "Estadio", ui_stadium: "Detalles del Estadio",
ui_logistics: "Logística", ui_logistics: "Logística y Consejos",
cities: [ cities: [
{ name: "🇲🇽 CDMX", region: "Central", matches: "5 (Apertura)", budget: "$80-130", visa: "Sin Visa", vCls: "v-free", tips: "La Inauguración", std: "Estadio Azteca: El coloso de Santa Úrsula.", log: "Cuidado con la altitud. Hidrátate bien." }, { name: "🇨🇦 Vancouver", region: "Oeste", matches: "7 Partidos", budget: "$250 - $350", visa: "Visa/eTA Req.", vCls: "v-warn", tips: "El clima más fresco del verano", std: "BC Place: En el centro, techo retráctil.", log: "Precios altos; buen transporte público; clima ideal en junio." },
{ name: "🇺🇸 Dallas", region: "Central", matches: "9 (Máximo)", budget: "$180-260", visa: "Visa Requerida", vCls: "v-req", tips: "Sede con más partidos", std: "AT&T Stadium: El domo más grande de Texas.", log: "El calor es extremo; transporte público limitado." } { name: "🇺🇸 Seattle", region: "Oeste", matches: "6 Partidos", budget: "$220 - $320", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Mejor ambiente futbolero de EEUU", std: "Lumen Field: Conocido por ser el estadio más ruidoso.", log: "Ciudad con muchas pendientes; prueba el marisco local." },
// ... (Other 13 cities follow same structure) { name: "🇺🇸 San Francisco", region: "Oeste", matches: "6 Partidos", budget: "$300 - $450", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Meca de la tecnología", std: "Levi's Stadium: Ubicado en Santa Clara, no en SF central.", log: "Aviso: El estadio está a 1 hora de SF; quédate en San José." },
{ name: "🇺🇸 Los Ángeles", region: "Oeste", matches: "8 Partidos", budget: "$300 - $500", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Estadio más lujoso del mundo", std: "SoFi Stadium: El más caro de la historia con pantalla gigante circular.", log: "Tráfico denso; alquiler de coche obligatorio; costes altos." },
{ name: "🇲🇽 Guadalajara", region: "Centro", matches: "4 Partidos", budget: "$70 - $110", visa: "Exento (con Visa EEUU)", vCls: "v-free", tips: "Auténtica cultura mexicana", std: "Estadio Akron: Diseño vanguardista. Casa de las Chivas.", log: "Tierra del Tequila; muy económico; precaución básica de seguridad." },
{ name: "🇲🇽 CDMX", region: "Centro", matches: "5 (Apertura)", budget: "$80 - $130", visa: "Exento (con Visa EEUU)", vCls: "v-free", tips: "Santuario mundial del fútbol", std: "Estadio Azteca: Único en tener 3 mundiales; 2240m altitud.", log: "Aviso de altitud; sede de la inauguración; gran valor histórico." },
{ name: "🇲🇽 Monterrey", region: "Centro", matches: "4 Partidos", budget: "$90 - $140", visa: "Exento (con Visa EEUU)", vCls: "v-free", tips: "Estadio con las mejores vistas", std: "Estadio BBVA: Vistas increíbles al Cerro de la Silla.", log: "Centro industrial; muy conveniente; calor intenso en verano." },
{ name: "🇺🇸 Houston", region: "Centro", matches: "7 Partidos", budget: "$150 - $220", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Estadio techado con aire", std: "NRG Stadium: Gran domo climatizado ideal para el calor.", log: "Extremadamente húmedo; ciudad dispersa; coche necesario." },
{ name: "🇺🇸 Dallas", region: "Centro", matches: "9 (Máximo)", budget: "$180 - $260", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Base central del torneo", std: "AT&T Stadium: Sede de semis, la pantalla colgante más grande.", log: "Centro neurálgico; verano caluroso pero estadio climatizado." },
{ name: "🇺🇸 Kansas City", region: "Centro", matches: "6 Partidos", budget: "$140 - $200", visa: "Visa EEUU Req.", vCls: "v-req", tips: "BBQ y fans apasionados", std: "Arrowhead Stadium: Récord Guinness de ruido en estadio.", log: "Ubicación ideal para viajar por el país." },
{ name: "🇨🇦 Toronto", region: "Este", matches: "6 Partidos", budget: "$220 - $320", visa: "Visa/eTA Req.", vCls: "v-warn", tips: "Hub multicultural", std: "BMO Field: Ambiente compacto. Casa de Canadá.", log: "Excelente transporte; comida diversa; vida cosmopolita." },
{ name: "🇺🇸 Boston", region: "Este", matches: "7 Partidos", budget: "$280 - $400", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Historia y encanto académico", std: "Gillette Stadium: En Foxborough, lejos del centro.", log: "Aviso: Lejos de Boston; usa los trenes del torneo." },
{ name: "🇺🇸 Filadelfia", region: "Este", matches: "6 Partidos", budget: "$200 - $300", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Eje de transporte de la costa este", std: "Lincoln Financial Field: Parte del complejo deportivo.", log: "Cerca de NY; alternativa barata para alojamiento." },
{ name: "🇺🇸 Miami", region: "Este", matches: "7 Partidos", budget: "$300 - $500", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Fútbol, playa y fiesta", std: "Hard Rock Stadium: Sede del 3er puesto. Tierra de Messi.", log: "Ambiente vibrante; lluvias tropicales; mantente flexible." },
{ name: "🇺🇸 Atlanta", region: "Este", matches: "8 Partidos", budget: "$180 - $280", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Hub aéreo más grande", std: "Mercedes-Benz Stadium: Sede de semis, techo único.", log: "Aeropuerto muy transitado; estadio accesible en metro." },
{ name: "🇺🇸 NY / NJ", region: "Este", matches: "8 (Final)", budget: "$400 - $600", visa: "Visa EEUU Req.", vCls: "v-req", tips: "Centro del mundo / Gran Final", std: "MetLife Stadium: Escenario de la Final el 19 de julio.", log: "Costes máximos; hoteles caros; busca en el lado de NJ." }
] ]
} }
} }

View File

@@ -1,63 +1,319 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{langCode}}"> <html lang="{{langCode}}">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title> <title>{{title}}</title>
<meta name="description" content="{{metaDesc}}"> <meta name="description" content="{{metaDesc}}">
<link rel="alternate" hreflang="zh" href="https://yoursite.com/zh/" /> <!-- Google Fonts -->
<link rel="alternate" hreflang="en" href="https://yoursite.com/en/" /> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="alternate" hreflang="es" href="https://yoursite.com/es/" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Outfit:wght@600;800&display=swap"
rel="stylesheet">
<style> <style>
:root { --primary: #003366; --accent: #d21034; --gold: #b8975a; --bg: #f8fafc; } :root {
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: var(--bg); color: #334155; margin: 0; line-height: 1.5; } --primary: #0f172a;
--accent: #d21034;
--secondary: #334155;
--success: #10b981;
--warning: #f59e0b;
--error: #ef4444;
--bg: #f8fafc;
--card-bg: #ffffff;
--border: #e2e8f0;
--text-main: #1e293b;
--text-muted: #64748b;
--radius: 12px;
--shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
}
/* 导航 */ * {
nav { background: #0f172a; padding: 12px 20px; display: flex; justify-content: space-between; align-items: center; color: white; position: sticky; top: 0; z-index: 1000; } box-sizing: border-box;
.nav-brand { font-weight: 800; letter-spacing: 1px; font-size: 18px; } }
.nav-langs a { color: #94a3b8; text-decoration: none; margin-left: 15px; font-size: 13px; font-weight: 600; transition: 0.3s; }
.nav-langs a:hover { color: white; }
.container { max-width: 1100px; margin: 30px auto; padding: 0 15px; } body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text-main);
margin: 0;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
header { text-align: center; margin-bottom: 40px; } /* Nav & Glassy Effect */
h1 { color: var(--primary); font-size: 32px; margin-bottom: 10px; } nav {
.subtitle { color: #64748b; font-size: 16px; } background: rgba(15, 23, 42, 0.9);
backdrop-filter: blur(8px);
padding: 16px 40px;
display: flex;
justify-content: space-between;
align-items: center;
color: white;
position: sticky;
top: 0;
z-index: 1000;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
}
/* 表格容器 */ .nav-brand {
.card-table { background: white; border-radius: 16px; box-shadow: 0 10px 25px -5px rgba(0,0,0,0.05); overflow: hidden; } font-family: 'Outfit', sans-serif;
.table-responsive { overflow-x: auto; } font-weight: 800;
table { width: 100%; border-collapse: collapse; min-width: 850px; } letter-spacing: -0.5px;
font-size: 22px;
background: linear-gradient(to right, #fff, #94a3b8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* 表头 */ .nav-langs {
th { background: #f1f5f9; padding: 16px; text-align: left; font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em; color: #475569; position: sticky; top: 0; } display: flex;
gap: 15px;
align-items: center;
}
/* 行样式 */ .nav-langs a,
.city-row { cursor: pointer; border-bottom: 1px solid #f1f5f9; transition: all 0.2s; } .nav-langs span {
.city-row:hover { background: #fdfeff; } text-decoration: none;
.city-row td { padding: 16px; font-size: 15px; } font-size: 13px;
font-weight: 600;
padding: 6px 12px;
border-radius: 20px;
transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 标签 */ .nav-langs a {
.tag-region { font-size: 11px; padding: 2px 6px; border-radius: 4px; background: #e2e8f0; margin-left: 8px; font-weight: normal; } color: #94a3b8;
.tag-visa { font-size: 12px; padding: 4px 8px; border-radius: 6px; font-weight: 700; } background: rgba(255, 255, 255, 0.05);
.v-free { background: #dcfce7; color: #166534; } }
.v-req { background: #fee2e2; color: #991b1b; }
.v-warn { background: #fef3c7; color: #92400e; }
/* 详情面板 */ .nav-langs a:hover {
.detail-pane { display: none; background: #fcfdfe; } color: white;
.detail-content { padding: 30px; display: grid; grid-template-columns: 1fr 1fr; gap: 30px; border-bottom: 2px solid #f1f5f9; } background: rgba(255, 255, 255, 0.15);
.info-box h4 { margin: 0 0 12px 0; font-size: 14px; color: var(--accent); display: flex; align-items: center; } transform: translateY(-1px);
.info-box h4::before { content: ''; display: inline-block; width: 4px; height: 14px; background: var(--accent); margin-right: 8px; } }
.info-text { font-size: 14px; line-height: 1.7; color: #475569; }
.nav-langs .active-lang {
color: white;
background: var(--accent);
box-shadow: 0 0 15px rgba(210, 16, 52, 0.4);
}
/* Hero Section */
.hero {
background: radial-gradient(circle at top right, #1e293b, #0f172a);
padding: 80px 20px;
text-align: center;
color: white;
margin-bottom: -60px;
}
.hero h1 {
font-family: 'Outfit', sans-serif;
font-size: 42px;
margin: 0 0 16px 0;
line-height: 1.1;
max-width: 800px;
margin-left: auto;
margin-right: auto;
}
.hero p {
color: #94a3b8;
font-size: 18px;
max-width: 600px;
margin: 0 auto;
}
/* Container */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px 60px;
position: relative;
}
/* Table Card Styles */
.card-table {
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow-lg);
overflow: hidden;
border: 1px solid var(--border);
animation: slideUp 0.6s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.table-responsive {
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
min-width: 900px;
}
th {
background: #f8fafc;
padding: 20px;
text-align: left;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--text-muted);
border-bottom: 2px solid var(--border);
}
.city-row {
cursor: pointer;
border-bottom: 1px solid var(--border);
transition: 0.2s;
}
.city-row:hover {
background: #f1f5f9;
}
.city-row td {
padding: 20px;
font-size: 15px;
}
.city-name-cell {
display: flex;
align-items: center;
gap: 12px;
}
.city-name-cell strong {
font-size: 16px;
color: var(--primary);
}
.tag-region {
font-size: 10px;
padding: 2px 8px;
border-radius: 100px;
background: #f1f5f9;
color: var(--secondary);
font-weight: 700;
text-transform: uppercase;
}
.tag-visa {
font-size: 12px;
padding: 6px 12px;
border-radius: 8px;
font-weight: 600;
display: inline-block;
}
.v-free {
background: #ecfdf5;
color: #065f46;
border: 1px solid #d1fae5;
}
.v-req {
background: #fff1f2;
color: #9f1239;
border: 1px solid #ffe4e6;
}
.v-warn {
background: #fffbeb;
color: #92400e;
border: 1px solid #fef3c7;
}
/* Detail Panel */
.detail-pane {
display: none;
background: #fdfdfd;
border-left: 4px solid var(--accent);
}
.detail-content {
padding: 30px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
background: linear-gradient(to bottom right, #ffffff, #f9fafb);
}
.info-box h4 {
margin: 0 0 15px 0;
font-size: 15px;
color: var(--primary);
display: flex;
align-items: center;
gap: 8px;
font-weight: 700;
}
.info-box h4::before {
content: '';
display: inline-block;
width: 12px;
height: 12px;
background: var(--accent);
border-radius: 3px;
}
.info-text {
font-size: 14px;
line-height: 1.8;
color: var(--secondary);
background: white;
padding: 15px;
border-radius: 8px;
border: 1px solid var(--border);
}
footer {
text-align: center;
padding: 40px;
color: var(--text-muted);
font-size: 14px;
}
@media (max-width: 768px) { @media (max-width: 768px) {
.detail-content { grid-template-columns: 1fr; } .hero h1 {
font-size: 32px;
}
.nav-brand {
font-size: 18px;
}
.detail-content {
grid-template-columns: 1fr;
gap: 20px;
}
nav {
padding: 16px 20px;
}
} }
</style> </style>
</head> </head>
<body> <body>
<nav> <nav>
@@ -65,12 +321,12 @@
<div class="nav-langs">{{languageLinks}}</div> <div class="nav-langs">{{languageLinks}}</div>
</nav> </nav>
<div class="container"> <div class="hero">
<header> <h1>{{title}}</h1>
<h1>{{title}}</h1> <p>{{metaDesc}}</p>
<div class="subtitle">{{metaDesc}}</div> </div>
</header>
<div class="container">
<div class="card-table"> <div class="card-table">
<div class="table-responsive"> <div class="table-responsive">
<table> <table>
@@ -83,15 +339,28 @@
</table> </table>
</div> </div>
</div> </div>
<footer>
<p>&copy; 2026 World Cup Planner - Unofficial Guide</p>
</footer>
</div> </div>
<script> <script>
function toggleDetails(idx) { function toggleDetails(idx) {
const pane = document.getElementById('details-' + idx); const pane = document.getElementById('details-' + idx);
const row = document.getElementById('row-' + idx);
const isVisible = pane.style.display === 'table-row'; const isVisible = pane.style.display === 'table-row';
// Close others
document.querySelectorAll('.detail-pane').forEach(p => p.style.display = 'none'); document.querySelectorAll('.detail-pane').forEach(p => p.style.display = 'none');
pane.style.display = isVisible ? 'none' : 'table-row'; document.querySelectorAll('.city-row').forEach(r => r.style.background = '');
if (!isVisible) {
pane.style.display = 'table-row';
row.style.background = '#f8fafc';
}
} }
</script> </script>
</body> </body>
</html> </html>