Files
PolyWeather/index.html
T

488 lines
36 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PolyWeather - 天气衍生品智能分析平台</title>
<meta name="description" content="PolyWeather 天气衍生品智能分析平台,提供全球天气数据、市场分析与交易信号">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=Noto+Sans+SC:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
:root{
--bg-base:#0a0e1a;--bg-card:#111827;--bg-card-hover:#1a2235;--bg-surface:#0f1525;
--border:#1e2a3a;--border-hover:#2a3a50;
--text-primary:#e8ecf4;--text-secondary:#8899aa;--text-muted:#556677;
--accent:#00bcd4;--accent-glow:rgba(0,188,212,.15);--accent-dim:#0097a7;
--red:#ef4444;--red-bg:rgba(239,68,68,.12);--red-border:rgba(239,68,68,.3);
--orange:#f59e0b;--orange-bg:rgba(245,158,11,.12);--orange-border:rgba(245,158,11,.3);
--green:#22c55e;--green-bg:rgba(34,197,94,.12);--green-border:rgba(34,197,94,.3);
--blue:#3b82f6;
--radius:10px;--radius-lg:14px;--radius-sm:6px;
--font-sans:'Inter','Noto Sans SC',system-ui,sans-serif;
}
html{font-size:13px}
body{font-family:var(--font-sans);background:var(--bg-base);color:var(--text-primary);overflow:hidden;height:100vh;display:flex;flex-direction:column}
::-webkit-scrollbar{width:4px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#2a3a50;border-radius:4px}
/* === HEADER === */
.header{display:flex;align-items:center;height:46px;padding:0 16px;background:linear-gradient(180deg,#111827 0%,#0f1420 100%);border-bottom:1px solid var(--border);flex-shrink:0;gap:8px;z-index:100}
.logo{display:flex;align-items:center;gap:8px;margin-right:12px}
.logo-icon{width:28px;height:28px;background:linear-gradient(135deg,#00bcd4,#0288d1);border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:800;color:#fff}
.logo-text{font-size:16px;font-weight:700;color:#fff;letter-spacing:-.5px}
.logo-sub{font-size:11px;color:var(--text-muted);margin-left:4px;white-space:nowrap}
.nav{display:flex;gap:2px;margin:0 auto}
.nav-item{padding:6px 14px;border-radius:var(--radius-sm);font-size:12px;color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;gap:5px;transition:.2s}
.nav-item:hover{color:var(--text-primary);background:rgba(255,255,255,.05)}
.nav-item.active{color:var(--accent);background:var(--accent-glow)}
.header-right{display:flex;align-items:center;gap:6px;margin-left:auto}
.live-badge{display:flex;align-items:center;gap:5px;padding:4px 10px;border-radius:20px;border:1px solid var(--green-border);background:var(--green-bg);font-size:11px;color:var(--green);font-weight:600}
.live-dot{width:6px;height:6px;border-radius:50%;background:var(--green);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}
.hdr-btn{width:32px;height:32px;border-radius:var(--radius-sm);border:1px solid var(--border);background:transparent;color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;transition:.2s}
.hdr-btn:hover{border-color:var(--border-hover);color:var(--text-primary);background:rgba(255,255,255,.04)}
/* === MAIN LAYOUT === */
.main{display:grid;grid-template-columns:220px 1fr 280px;flex:1;overflow:hidden;min-height:0}
/* === SIDEBAR === */
.sidebar{background:var(--bg-surface);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden}
.sidebar-header{padding:10px 12px 6px}
.search-box{display:flex;align-items:center;gap:6px;padding:6px 10px;border-radius:var(--radius-sm);border:1px solid var(--border);background:rgba(255,255,255,.03);color:var(--text-secondary);font-size:12px}
.search-box input{background:none;border:none;color:var(--text-primary);font-size:12px;outline:none;width:100%;font-family:inherit}
.sidebar-title{display:flex;align-items:center;justify-content:space-between;padding:8px 12px 4px;font-size:11px;font-weight:600;color:var(--text-secondary)}
.sidebar-title .count{background:rgba(255,255,255,.08);padding:1px 7px;border-radius:10px;font-size:10px}
.city-list{flex:1;overflow-y:auto;padding:0 6px 8px}
.risk-group{margin-bottom:4px}
.risk-label{display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;font-weight:600;cursor:pointer;color:var(--text-secondary)}
.risk-label .arrow{font-size:8px;transition:.2s}
.risk-label .dot{width:6px;height:6px;border-radius:50%}
.risk-label .r-count{margin-left:auto;font-size:10px;color:var(--text-muted)}
.city-item{display:flex;align-items:center;padding:5px 8px 5px 22px;border-radius:var(--radius-sm);cursor:pointer;transition:.15s;gap:6px;font-size:12px}
.city-item:hover{background:rgba(255,255,255,.04)}
.city-item.active{background:var(--accent-glow);border:1px solid rgba(0,188,212,.25)}
.city-item .name{flex:1;white-space:nowrap}
.city-item .temp{font-weight:600;font-size:12px;min-width:36px;text-align:right}
.city-item .trend{font-size:10px;margin-left:2px}
.city-item .time{font-size:10px;color:var(--text-muted);min-width:34px;text-align:right}
.sidebar-footer{padding:8px 12px;border-top:1px solid var(--border);font-size:10px;color:var(--text-muted);line-height:1.5}
/* === CENTER === */
.center{display:flex;flex-direction:column;overflow:hidden;min-width:0}
.map-panel{flex:1;position:relative;background:var(--bg-base);overflow:hidden;min-height:0}
.map-header{position:absolute;top:12px;left:16px;right:16px;display:flex;align-items:center;justify-content:space-between;z-index:10}
.map-title{font-size:14px;font-weight:600;display:flex;align-items:center;gap:8px}
.map-title .sub{font-size:11px;color:var(--text-muted);font-weight:400}
.map-tabs{display:flex;gap:2px;background:rgba(17,24,39,.8);border:1px solid var(--border);border-radius:var(--radius-sm);padding:2px}
.map-tab{padding:4px 14px;border-radius:4px;font-size:11px;color:var(--text-secondary);cursor:pointer;transition:.2s}
.map-tab.active{background:var(--accent);color:#fff}
.map-tab:hover:not(.active){color:var(--text-primary)}
.map-expand{width:28px;height:28px;border-radius:var(--radius-sm);border:1px solid var(--border);background:rgba(17,24,39,.8);color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:12px}
/* Map Canvas */
.map-canvas{width:100%;height:100%;position:relative}
.map-bg{position:absolute;inset:0;background:radial-gradient(ellipse at 50% 50%,#0d1a2f 0%,#080e1a 70%);overflow:hidden}
.map-bg::before{content:'';position:absolute;inset:-20%;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='400'%3E%3Cdefs%3E%3CradialGradient id='a'%3E%3Cstop offset='0' stop-color='%23112240'/%3E%3Cstop offset='1' stop-color='transparent'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect fill='%230a0e18' width='800' height='400'/%3E%3Ccircle cx='400' cy='200' r='250' fill='url(%23a)' opacity='.3'/%3E%3C/svg%3E") center/cover;opacity:.5}
.map-grid{position:absolute;inset:0;background-image:linear-gradient(rgba(0,188,212,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(0,188,212,.03) 1px,transparent 1px);background-size:60px 60px}
.continent{position:absolute;border-radius:40%;opacity:.12;filter:blur(15px)}
.c-na{width:280px;height:180px;background:#1a5276;top:18%;left:12%}
.c-sa{width:140px;height:200px;background:#1a5276;top:48%;left:22%}
.c-eu{width:200px;height:120px;background:#1a5276;top:14%;left:42%}
.c-af{width:160px;height:200px;background:#1a5276;top:32%;left:42%}
.c-as{width:280px;height:180px;background:#1a5276;top:16%;left:55%}
.heat-spot{position:absolute;border-radius:50%;filter:blur(25px);animation:heatPulse 4s ease-in-out infinite alternate}
@keyframes heatPulse{0%{opacity:.4;transform:scale(1)}100%{opacity:.7;transform:scale(1.1)}}
.city-pin{position:absolute;z-index:5;cursor:pointer;transition:.2s}
.city-pin:hover{z-index:10;transform:scale(1.15)}
.pin-dot{width:8px;height:8px;border-radius:50%;border:2px solid;position:relative}
.pin-dot::after{content:'';position:absolute;inset:-4px;border-radius:50%;border:1px solid;opacity:.3;animation:ripple 2.5s infinite}
@keyframes ripple{0%{transform:scale(1);opacity:.4}100%{transform:scale(2.2);opacity:0}}
.pin-label{position:absolute;top:-22px;left:50%;transform:translateX(-50%);white-space:nowrap;font-size:10px;padding:2px 6px;border-radius:4px;background:rgba(10,14,26,.85);border:1px solid var(--border);backdrop-filter:blur(4px);display:flex;align-items:center;gap:4px}
.pin-label .pin-temp{font-weight:600;color:var(--accent)}
.pin-highlight{position:absolute;z-index:4}
.pin-highlight .ring{width:60px;height:60px;border-radius:50%;border:2px solid var(--red);opacity:.4;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);animation:ringPulse 2s infinite}
.pin-highlight .ring2{width:90px;height:90px;border-radius:50%;border:1px solid var(--red);opacity:.2;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);animation:ringPulse 2s .5s infinite}
@keyframes ringPulse{0%{opacity:.4;transform:translate(-50%,-50%) scale(1)}100%{opacity:0;transform:translate(-50%,-50%) scale(1.5)}}
.pin-highlight .glow{width:40px;height:40px;border-radius:50%;background:radial-gradient(var(--red),transparent 70%);opacity:.25;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}
/* Map controls */
.map-zoom{position:absolute;right:16px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:2px;z-index:10}
.map-zoom button{width:30px;height:30px;border-radius:var(--radius-sm);border:1px solid var(--border);background:rgba(17,24,39,.85);color:var(--text-secondary);cursor:pointer;font-size:14px;display:flex;align-items:center;justify-content:center;transition:.2s;backdrop-filter:blur(4px)}
.map-zoom button:hover{border-color:var(--accent);color:var(--accent)}
.map-legend{position:absolute;bottom:12px;left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:8px;padding:6px 14px;border-radius:var(--radius);background:rgba(17,24,39,.85);border:1px solid var(--border);z-index:10;backdrop-filter:blur(4px)}
.map-legend .label{font-size:10px;color:var(--text-secondary)}
.legend-bar{width:200px;height:8px;border-radius:4px;background:linear-gradient(90deg,#2563eb,#06b6d4,#22c55e,#eab308,#ef4444);margin:0 4px}
.legend-vals{display:flex;justify-content:space-between;width:200px;font-size:9px;color:var(--text-muted)}
/* === Bottom Summary === */
.bottom-section{border-top:1px solid var(--border);flex-shrink:0}
.summary-row{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;padding:10px 16px;grid-column:1/-1}
.summary-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:12px 14px;transition:.2s}
.summary-card:hover{border-color:var(--border-hover);background:var(--bg-card-hover)}
.sc-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.sc-title{font-size:12px;font-weight:600}
.sc-link{font-size:10px;color:var(--accent);cursor:pointer}
.sc-body{display:flex;align-items:flex-end;gap:16px}
.sc-stat{text-align:center}
.sc-stat .num{font-size:22px;font-weight:700;line-height:1}
.sc-stat .lbl{font-size:10px;color:var(--text-muted);margin-top:3px}
.sc-divider{width:1px;height:30px;background:var(--border)}
.sc-bar-row{display:flex;align-items:center;gap:6px;flex:1}
.sc-bar{height:6px;border-radius:3px;flex:1}
.sc-bar-label{font-size:11px;font-weight:700;min-width:30px}
/* === Opportunity Cards === */
.opp-section{padding:8px 16px 12px;border-top:1px solid var(--border);grid-column:1/-1}
.opp-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.opp-title{font-size:13px;font-weight:600;display:flex;align-items:center;gap:6px}
.opp-title .badge{font-size:10px;color:var(--text-muted);background:rgba(255,255,255,.06);padding:2px 8px;border-radius:10px}
.opp-nav{display:flex;gap:4px}
.opp-nav button{width:26px;height:26px;border-radius:50%;border:1px solid var(--border);background:transparent;color:var(--text-secondary);cursor:pointer;font-size:11px;transition:.2s}
.opp-nav button:hover{border-color:var(--accent);color:var(--accent)}
.opp-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px}
.opp-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:12px;transition:.2s;cursor:pointer}
.opp-card:hover{border-color:var(--accent);background:var(--bg-card-hover);transform:translateY(-1px);box-shadow:0 4px 20px rgba(0,188,212,.08)}
.opp-card-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.opp-rank{font-size:12px;font-weight:700;color:var(--accent);margin-right:6px}
.opp-city{font-size:12px;font-weight:600}
.risk-tag{font-size:9px;padding:2px 6px;border-radius:4px;font-weight:600}
.risk-tag.high{color:var(--red);background:var(--red-bg);border:1px solid var(--red-border)}
.risk-tag.mid{color:var(--orange);background:var(--orange-bg);border:1px solid var(--orange-border)}
.risk-tag.low{color:var(--green);background:var(--green-bg);border:1px solid var(--green-border)}
.opp-question{font-size:10px;color:var(--text-muted);margin-bottom:6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.opp-prices{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.opp-yes,.opp-no{font-size:11px;font-weight:600}
.opp-yes{color:var(--green)}.opp-no{color:var(--red)}
.opp-edge{font-size:11px;color:var(--accent);font-weight:600}
.opp-chart{height:28px;margin-top:4px;position:relative}
.opp-chart svg{width:100%;height:100%}
/* === RIGHT PANEL === */
.right-panel{background:var(--bg-surface);border-left:1px solid var(--border);overflow-y:auto;display:flex;flex-direction:column}
.rp-header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid var(--border)}
.rp-title{font-size:12px;font-weight:600;display:flex;align-items:center;gap:5px}
.rp-link{font-size:10px;color:var(--accent);cursor:pointer}
.rp-city{padding:12px 14px}
.rp-city-name{font-size:22px;font-weight:700;display:flex;align-items:center;gap:6px}
.rp-city-name .star{color:var(--orange);font-size:14px}
.rp-meta{font-size:10px;color:var(--text-muted);margin-top:4px;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.rp-meta .code{color:var(--text-secondary);font-weight:500}
.rp-time{display:flex;gap:12px;font-size:10px;color:var(--text-muted);margin-top:6px}
.rp-time .live-dot-sm{width:5px;height:5px;border-radius:50%;background:var(--green);display:inline-block;margin-right:3px}
.rp-temp-block{padding:8px 14px;display:flex;align-items:center;justify-content:space-between}
.rp-temp-main{display:flex;align-items:flex-start}
.rp-temp-num{font-size:52px;font-weight:800;line-height:1;letter-spacing:-2px}
.rp-temp-unit{font-size:18px;font-weight:300;margin-top:4px}
.rp-temp-sub{font-size:11px;color:var(--text-muted);margin-top:4px}
.rp-temp-right{text-align:right}
.rp-weather-icon{font-size:36px;opacity:.7}
.rp-forecast{font-size:10px;color:var(--text-muted);margin-top:4px}
.rp-forecast .val{color:var(--text-primary);font-weight:600}
.rp-card{margin:4px 14px;padding:10px 12px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius)}
.rp-card-title{font-size:11px;font-weight:600;margin-bottom:6px;display:flex;align-items:center;gap:5px}
.rp-card-title .tag{font-size:9px;padding:1px 5px;border-radius:3px;background:var(--accent-glow);color:var(--accent)}
.rp-deb{display:flex;align-items:center;justify-content:space-between}
.rp-deb-temp{font-size:26px;font-weight:700}
.rp-deb-delta{font-size:13px;color:var(--red);font-weight:600;margin-left:6px}
.rp-mini-chart{width:140px;height:32px}
.rp-market{margin-top:2px}
.rp-market-q{font-size:11px;color:var(--text-secondary);margin-bottom:6px}
.rp-market-prices{display:flex;gap:8px;margin-bottom:8px}
.rp-price-box{flex:1;padding:6px;border-radius:var(--radius-sm);text-align:center;font-weight:700;font-size:13px}
.rp-price-yes{background:var(--green-bg);border:1px solid var(--green-border);color:var(--green)}
.rp-price-no{background:var(--red-bg);border:1px solid var(--red-border);color:var(--red)}
.rp-market-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;text-align:center}
.rp-market-stats .stat-label{font-size:9px;color:var(--text-muted)}
.rp-market-stats .stat-val{font-size:12px;font-weight:600;margin-top:1px}
.rp-signals{margin:4px 14px;padding:10px 12px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius)}
.rp-signals .title{font-size:11px;font-weight:600;margin-bottom:6px}
.signal-item{display:flex;align-items:center;gap:6px;padding:4px 0;font-size:11px}
.signal-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}
.rp-cta{margin:8px 14px;padding:10px;text-align:center;background:linear-gradient(135deg,rgba(0,188,212,.15),rgba(0,188,212,.05));border:1px solid rgba(0,188,212,.25);border-radius:var(--radius);color:var(--accent);font-size:12px;font-weight:600;cursor:pointer;transition:.2s}
.rp-cta:hover{background:linear-gradient(135deg,rgba(0,188,212,.25),rgba(0,188,212,.1));transform:translateY(-1px)}
</style>
</head>
<body>
<!-- HEADER -->
<header class="header">
<div class="logo">
<div class="logo-icon">P</div>
<span class="logo-text">PolyWeather</span>
<span class="logo-sub">天气衍生品智能分析</span>
</div>
<nav class="nav">
<div class="nav-item active">🏠 首页</div>
<div class="nav-item">🗺️ 地图</div>
<div class="nav-item">📊 市场</div>
<div class="nav-item">📈 分析</div>
<div class="nav-item">📅 历史</div>
<div class="nav-item">⚠️ 预警</div>
</nav>
<div class="header-right">
<div class="live-badge"><span class="live-dot"></span>LIVE</div>
<button class="hdr-btn" title="刷新">🔄</button>
<button class="hdr-btn" title="文档">📄</button>
<button class="hdr-btn" title="通知">🔔</button>
<button class="hdr-btn" title="账户">👤</button>
</div>
</header>
<!-- MAIN -->
<div class="main">
<!-- SIDEBAR -->
<aside class="sidebar">
<div class="sidebar-header">
<div class="search-box">🔍 <input type="text" placeholder="搜索城市..."></div>
</div>
<div class="sidebar-title">监控城市 <span class="count">52</span></div>
<div class="city-list">
<!-- High Risk -->
<div class="risk-group">
<div class="risk-label"><span class="arrow"></span><span class="dot" style="background:var(--red)"></span> 高风险城市 <span class="r-count">6</span></div>
<div class="city-item active"><span class="name">芝加哥</span><span class="temp" style="color:var(--red)">72°F</span><span class="trend">📈</span><span class="time"></span></div>
<div class="city-item"><span class="name">达拉斯</span><span class="temp">63°F</span><span class="time">09:18</span></div>
<div class="city-item"><span class="name">休斯顿</span><span class="temp">69°F</span><span class="time">09:25</span></div>
<div class="city-item"><span class="name">马尼拉</span><span class="temp">84°F</span><span class="time">08:59</span></div>
<div class="city-item"><span class="name">曼谷</span><span class="temp">83°F</span><span class="time">09:47</span></div>
<div class="city-item"><span class="name">迈阿密</span><span class="temp">82°F</span><span class="time">09:02</span></div>
</div>
<!-- Mid Risk -->
<div class="risk-group">
<div class="risk-label"><span class="arrow"></span><span class="dot" style="background:var(--orange)"></span> 中等风险城市 <span class="r-count">18</span></div>
<div class="city-item"><span class="name">纽约</span><span class="temp">66°F</span><span class="time">09:10</span></div>
<div class="city-item"><span class="name">洛杉矶</span><span class="temp">68°F</span><span class="time">09:10</span></div>
<div class="city-item"><span class="name">墨西哥城</span><span class="temp">64°F</span><span class="time">08:50</span></div>
<div class="city-item"><span class="name">伦敦</span><span class="temp">57°F</span><span class="time">09:35</span></div>
<div class="city-item"><span class="name">巴黎</span><span class="temp">59°F</span><span class="time">08:33</span></div>
</div>
<!-- Low Risk -->
<div class="risk-group">
<div class="risk-label"><span class="arrow"></span><span class="dot" style="background:var(--green)"></span> 低风险城市 <span class="r-count">28</span></div>
<div class="city-item"><span class="name">旧金山</span><span class="temp">61°F</span><span class="time">09:11</span></div>
<div class="city-item"><span class="name">西雅图</span><span class="temp">58°F</span><span class="time">09:07</span></div>
<div class="city-item"><span class="name">温哥华</span><span class="temp">56°F</span><span class="time">09:12</span></div>
<div class="city-item"><span class="name">多伦多</span><span class="temp">60°F</span><span class="time">09:08</span></div>
<div class="city-item"><span class="name">柏林</span><span class="temp">55°F</span><span class="time">09:30</span></div>
</div>
</div>
<div class="sidebar-footer">📊 数据更新 09:41:12 (北京)<br>数据来源:METAR · ECMWF · DEB · 市场</div>
</aside>
<!-- CENTER -->
<main class="center">
<div class="map-panel">
<div class="map-header">
<div class="map-title">全球天气态势 <span class="sub">更新时间:09:41 北京</span></div>
<div style="display:flex;gap:8px;align-items:center">
<div class="map-tabs">
<div class="map-tab active">温度</div>
<div class="map-tab">降水</div>
<div class="map-tab">风场</div>
</div>
<button class="map-expand"></button>
</div>
</div>
<div class="map-canvas">
<div class="map-bg"></div>
<div class="map-grid"></div>
<!-- Continents -->
<div class="continent c-na"></div>
<div class="continent c-sa"></div>
<div class="continent c-eu"></div>
<div class="continent c-af"></div>
<div class="continent c-as"></div>
<!-- Heat spots -->
<div class="heat-spot" style="width:120px;height:120px;background:radial-gradient(var(--red),transparent 70%);top:22%;left:22%;opacity:.3"></div>
<div class="heat-spot" style="width:80px;height:80px;background:radial-gradient(var(--orange),transparent 70%);top:35%;left:27%;opacity:.25;animation-delay:1s"></div>
<div class="heat-spot" style="width:60px;height:60px;background:radial-gradient(#22c55e,transparent 70%);top:20%;left:50%;opacity:.2;animation-delay:2s"></div>
<div class="heat-spot" style="width:100px;height:100px;background:radial-gradient(var(--red),transparent 70%);top:30%;left:70%;opacity:.25;animation-delay:.5s"></div>
<!-- City pins -->
<div class="city-pin pin-highlight" style="left:24%;top:28%"><div class="ring"></div><div class="ring2"></div><div class="glow"></div><div class="pin-dot" style="border-color:var(--red);background:var(--red)"></div><div class="pin-label">芝加哥 <span class="pin-temp">72°F</span></div></div>
<div class="city-pin" style="left:20%;top:22%"><div class="pin-dot" style="border-color:var(--green);background:transparent"></div><div class="pin-label">温哥华 <span class="pin-temp">56°F</span></div></div>
<div class="city-pin" style="left:22%;top:36%"><div class="pin-dot" style="border-color:var(--red);background:transparent"></div><div class="pin-label">达拉斯 <span class="pin-temp">63°F</span></div></div>
<div class="city-pin" style="left:19%;top:26%"><div class="pin-dot" style="border-color:var(--green);background:transparent"></div><div class="pin-label">旧金山 <span class="pin-temp">61°F</span></div></div>
<div class="city-pin" style="left:27%;top:30%"><div class="pin-dot" style="border-color:var(--orange);background:transparent"></div><div class="pin-label">纽约 <span class="pin-temp">66°F</span></div></div>
<div class="city-pin" style="left:22%;top:44%"><div class="pin-dot" style="border-color:var(--orange);background:transparent"></div><div class="pin-label">墨西哥城 <span class="pin-temp">64°F</span></div></div>
<div class="city-pin" style="left:46%;top:22%"><div class="pin-dot" style="border-color:var(--orange);background:transparent"></div><div class="pin-label">伦敦 <span class="pin-temp">57°F</span></div></div>
<div class="city-pin" style="left:48%;top:24%"><div class="pin-dot" style="border-color:var(--orange);background:transparent"></div><div class="pin-label">巴黎 <span class="pin-temp">59°F</span></div></div>
<div class="city-pin" style="left:44%;top:22%"><div class="pin-dot" style="border-color:var(--orange);background:transparent"></div><div class="pin-label">西雅图 <span class="pin-temp">58°F</span></div></div>
<div class="city-pin" style="left:30%;top:38%"><div class="pin-dot" style="border-color:var(--red);background:transparent"></div><div class="pin-label">迈阿密 <span class="pin-temp">82°F</span></div></div>
<div class="city-pin" style="left:70%;top:30%"><div class="pin-dot" style="border-color:var(--orange);background:transparent"></div><div class="pin-label">北京 <span class="pin-temp">61°F</span></div></div>
<div class="city-pin" style="left:72%;top:42%"><div class="pin-dot" style="border-color:var(--red);background:transparent"></div><div class="pin-label">马尼拉 <span class="pin-temp">84°F</span></div></div>
<div class="city-pin" style="left:68%;top:38%"><div class="pin-dot" style="border-color:var(--red);background:transparent"></div><div class="pin-label">曼谷 <span class="pin-temp">83°F</span></div></div>
<div class="city-pin" style="left:65%;top:44%"><div class="pin-dot" style="border-color:var(--orange);background:transparent"></div><div class="pin-label">圣保罗 <span class="pin-temp">70°F</span></div></div>
</div>
<div class="map-zoom"><button>+</button><button></button><button></button></div>
<div class="map-legend">
<span class="label">温度 (°F)</span>
<div>
<div class="legend-bar"></div>
<div class="legend-vals"><span>-4</span><span>14</span><span>32</span><span>50</span><span>68</span><span>86</span><span>104</span></div>
</div>
</div>
</div>
<!-- Bottom area -->
<div class="bottom-section">
<div class="summary-row">
<div class="summary-card">
<div class="sc-header"><span class="sc-title">今日机会概览</span><span class="sc-link">查看全部</span></div>
<div class="sc-body">
<div class="sc-stat"><div class="num" style="color:var(--red)">6</div><div class="lbl">高风险</div></div>
<div class="sc-stat"><div class="num" style="color:var(--orange)">14</div><div class="lbl">中等风险</div></div>
<div class="sc-stat"><div class="num" style="color:var(--green)">28</div><div class="lbl">低风险</div></div>
</div>
</div>
<div class="summary-card">
<div class="sc-header"><span class="sc-title">市场总览</span><span class="sc-link">查看全部</span></div>
<div class="sc-body" style="flex-direction:column;gap:4px">
<div style="display:flex;justify-content:space-between;font-size:11px"><span>交易市场数</span><span style="font-weight:700">1,248</span></div>
<div style="display:flex;justify-content:space-between;font-size:11px"><span>活跃合约数</span><span style="font-weight:700">892</span></div>
<div style="display:flex;justify-content:space-between;font-size:11px"><span>24h 成交量</span><span style="font-weight:700">$2.34M</span></div>
<div style="display:flex;justify-content:space-between;font-size:11px"><span>平均 Edge</span><span style="font-weight:700;color:var(--green)">+6.7%</span></div>
</div>
</div>
<div class="summary-card">
<div class="sc-header"><span class="sc-title">模型一致性</span><span class="sc-link">查看全部</span></div>
<div class="sc-body">
<div class="sc-stat"><div class="sc-bar-label" style="color:var(--green)">48%</div><div class="lbl"></div></div>
<div class="sc-stat"><div class="sc-bar-label" style="color:var(--orange)">32%</div><div class="lbl"></div></div>
<div class="sc-stat"><div class="sc-bar-label" style="color:var(--red)">20%</div><div class="lbl"></div></div>
</div>
<div style="display:flex;height:6px;border-radius:3px;overflow:hidden;margin-top:8px">
<div style="width:48%;background:var(--green)"></div>
<div style="width:32%;background:var(--orange)"></div>
<div style="width:20%;background:var(--red)"></div>
</div>
</div>
<div class="summary-card">
<div class="sc-header"><span class="sc-title">高影响窗口 (未来6小时)</span></div>
<div class="sc-body" style="flex-direction:column;gap:4px">
<div style="display:flex;justify-content:space-between;font-size:11px"><span>影响市场数</span><span style="font-weight:700">12</span></div>
<div style="display:flex;justify-content:space-between;font-size:11px"><span>预计成交量</span><span style="font-weight:700">$1.26M</span></div>
</div>
</div>
</div>
<!-- Opportunity Cards -->
<div class="opp-section">
<div class="opp-header">
<div class="opp-title">今日最佳机会 <span class="badge">Top 机会</span></div>
<div class="opp-nav"><button></button><button></button></div>
</div>
<div class="opp-grid">
<div class="opp-card">
<div class="opp-card-head"><span><span class="opp-rank">1</span><span class="opp-city">芝加哥</span></span><span class="risk-tag high">高风险</span></div>
<div class="opp-question">> 76°F 出现时间 5月22日</div>
<div class="opp-prices"><span class="opp-yes">YES 62¢</span><span style="color:var(--text-muted);font-size:10px">·</span><span class="opp-edge">Edge +12.4%</span></div>
<div class="opp-chart"><svg viewBox="0 0 160 28"><polyline points="5,22 20,18 40,20 60,14 80,16 100,10 120,12 140,6 155,8" fill="none" stroke="#22c55e" stroke-width="1.5"/></svg></div>
</div>
<div class="opp-card">
<div class="opp-card-head"><span><span class="opp-rank">2</span><span class="opp-city">达拉斯</span></span><span class="risk-tag high">高风险</span></div>
<div class="opp-question">> 76°F 出现时间 5月22日</div>
<div class="opp-prices"><span class="opp-yes">YES 58¢</span><span style="color:var(--text-muted);font-size:10px">·</span><span class="opp-edge">Edge +10.1%</span></div>
<div class="opp-chart"><svg viewBox="0 0 160 28"><polyline points="5,20 25,22 45,18 65,20 85,14 105,16 125,10 145,8 155,12" fill="none" stroke="#f59e0b" stroke-width="1.5"/></svg></div>
</div>
<div class="opp-card">
<div class="opp-card-head"><span><span class="opp-rank">3</span><span class="opp-city">伦敦</span></span><span class="risk-tag mid">中等风险</span></div>
<div class="opp-question">> 76°F 出现时间 5月22日</div>
<div class="opp-prices"><span class="opp-yes">YES 54¢</span><span style="color:var(--text-muted);font-size:10px">·</span><span class="opp-edge">Edge +6.8%</span></div>
<div class="opp-chart"><svg viewBox="0 0 160 28"><polyline points="5,16 25,18 45,14 65,16 85,12 105,14 125,10 145,12 155,8" fill="none" stroke="#3b82f6" stroke-width="1.5"/></svg></div>
</div>
<div class="opp-card">
<div class="opp-card-head"><span><span class="opp-rank">4</span><span class="opp-city">墨西哥城</span></span><span class="risk-tag low">低风险</span></div>
<div class="opp-question">> 76°F 出现时间 5月22日</div>
<div class="opp-prices"><span class="opp-yes">YES 53¢</span><span style="color:var(--text-muted);font-size:10px">·</span><span class="opp-edge">Edge +6.8%</span></div>
<div class="opp-chart"><svg viewBox="0 0 160 28"><polyline points="5,14 25,16 45,12 65,18 85,16 105,20 125,14 145,10 155,12" fill="none" stroke="#22c55e" stroke-width="1.5"/></svg></div>
</div>
<div class="opp-card">
<div class="opp-card-head"><span><span class="opp-rank">5</span><span class="opp-city">马尼拉</span></span><span class="risk-tag high">高风险</span></div>
<div class="opp-question">> 76°F 出现时间 5月22日</div>
<div class="opp-prices"><span class="opp-yes">YES 51¢</span><span style="color:var(--text-muted);font-size:10px">·</span><span class="opp-edge">Edge +4.7%</span></div>
<div class="opp-chart"><svg viewBox="0 0 160 28"><polyline points="5,20 25,16 45,18 65,12 85,14 105,10 125,16 145,14 155,10" fill="none" stroke="#ef4444" stroke-width="1.5"/></svg></div>
</div>
</div>
</div>
</div>
</main>
<!-- RIGHT PANEL -->
<aside class="right-panel">
<div class="rp-header"><span class="rp-title">焦点城市 </span><span class="rp-link">为什么是它?</span></div>
<div class="rp-city">
<div class="rp-city-name">芝加哥 <span class="star"></span></div>
<div class="rp-meta"><span class="code">KORD</span> · 芝加哥奥黑尔国际机场 <span class="risk-tag high" style="margin-left:4px">高风险</span></div>
<div class="rp-time"><span>本地时间 09:41</span><span><span class="live-dot-sm"></span>1 分钟前更新</span></div>
</div>
<div class="rp-temp-block">
<div>
<div class="rp-temp-main"><span class="rp-temp-num">72</span><span class="rp-temp-unit">°F</span></div>
<div class="rp-temp-sub">体感 70°F</div>
</div>
<div class="rp-temp-right">
<div class="rp-weather-icon">🌧️</div>
<div class="rp-forecast">最大预计<br><span class="val">76°F</span> 14:33</div>
</div>
</div>
<div class="rp-card">
<div class="rp-card-title"><span class="tag">DEB 预测</span> (24小时最高)</div>
<div class="rp-deb">
<div><span class="rp-deb-temp">76°F</span><span class="rp-deb-delta">+2°F</span></div>
<div class="rp-mini-chart">
<svg viewBox="0 0 140 32" width="140" height="32">
<polyline points="0,28 15,24 30,22 45,18 60,14 75,10 90,8 105,10 120,12 135,14" fill="none" stroke="var(--accent)" stroke-width="1.5"/>
<circle cx="90" cy="8" r="3" fill="var(--accent)"/>
<text x="85" y="6" font-size="7" fill="var(--accent)">76°F</text>
</svg>
</div>
</div>
</div>
<div class="rp-card rp-market" style="margin-top:6px">
<div class="rp-card-title">市场问题</div>
<div class="rp-market-q">> 76°F 出现时间 5月22日</div>
<div class="rp-market-prices">
<div class="rp-price-box rp-price-yes">YES 62¢</div>
<div class="rp-price-box rp-price-no">NO 38¢</div>
</div>
<div class="rp-market-stats">
<div><div class="stat-label">Edge</div><div class="stat-val" style="color:var(--green)">+12.4%</div></div>
<div><div class="stat-label">隐含概率</div><div class="stat-val">62%</div></div>
<div><div class="stat-label">模型概率</div><div class="stat-val">74%</div></div>
</div>
</div>
<div class="rp-signals">
<div class="title">关键信号</div>
<div class="signal-item"><span class="signal-dot" style="background:var(--accent)"></span> DEB > 市场隐含值</div>
<div class="signal-item"><span class="signal-dot" style="background:var(--orange)"></span> 气温上升趋势</div>
<div class="signal-item"><span class="signal-dot" style="background:var(--red)"></span> 高影响窗口 11:00-17:00 (北京)</div>
</div>
<div class="rp-cta">查看完整分析 →</div>
</aside>
</div>
<script>
// Hover effects for city items
document.querySelectorAll('.city-item').forEach(item=>{
item.addEventListener('click',()=>{
document.querySelectorAll('.city-item').forEach(i=>i.classList.remove('active'));
item.classList.add('active');
});
});
// Map tab switching
document.querySelectorAll('.map-tab').forEach(tab=>{
tab.addEventListener('click',()=>{
document.querySelectorAll('.map-tab').forEach(t=>t.classList.remove('active'));
tab.classList.add('active');
});
});
// Nav switching
document.querySelectorAll('.nav-item').forEach(n=>{
n.addEventListener('click',()=>{
document.querySelectorAll('.nav-item').forEach(i=>i.classList.remove('active'));
n.classList.add('active');
});
});
</script>
</body>
</html>