From 2f73828d4d311a46b766c1be4cbfaf2f0e1de390 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Wed, 6 May 2026 17:57:40 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=9F=8E=E5=B8=82=E5=86=B3?= =?UTF-8?q?=E7=AD=96=E5=8D=A1=20hero=20=E5=B8=83=E5=B1=80=EF=BC=9A?= =?UTF-8?q?=E5=8E=BB=E9=99=A4=20sticky=20=E5=9B=BA=E5=AE=9A=E6=95=88?= =?UTF-8?q?=E6=9E=9C=EF=BC=8C=E5=8F=B3=E4=BE=A7=E6=94=B9=E4=B8=BA=E4=B8=89?= =?UTF-8?q?=E6=8C=87=E6=A0=87=E5=B9=B6=E5=88=97=E5=AF=B9=E6=AF=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 scan-ai-city-hero 从"左重右轻"改为左右均衡布局,右侧从单一预计高温数字 替换为当前温度/预计最高温/峰值时间三列并排指标卡,中间列高亮为主指标。 移除冗余的 pills 行和隐藏的 mobile-priority div,新鲜度条改为水平单行。 同步更新亮色主题 CSS 新增 metrics 样式。修复 fallback 模块未使用变量。 Constraint: dark/light 双主题完整覆盖 Scope-risk: hero 高度缩减约 30%,需确认移动端 MobileDecisionCard 不受影响 --- .../dashboard/ScanTerminalCard.module.css | 92 +++++++++++++------ .../ScanTerminalLightTheme.module.css | 36 +++++++- .../dashboard/ScanTerminalList.module.css | 6 -- .../scan-terminal/CityCardHeader.tsx | 38 +++----- web/scan_city_ai_fallback.py | 10 -- 5 files changed, 112 insertions(+), 70 deletions(-) diff --git a/frontend/components/dashboard/ScanTerminalCard.module.css b/frontend/components/dashboard/ScanTerminalCard.module.css index fc8b667e..d6cb5614 100644 --- a/frontend/components/dashboard/ScanTerminalCard.module.css +++ b/frontend/components/dashboard/ScanTerminalCard.module.css @@ -399,14 +399,20 @@ .root :global(.scan-ai-city-hero) { display: flex; justify-content: space-between; - gap: 18px; - padding: 22px; + align-items: flex-start; + gap: 20px; + padding: 18px 22px; background: linear-gradient(135deg, rgba(77, 163, 255, 0.11), rgba(34, 197, 94, 0.03)), #111a2e; border-bottom: 1px solid rgba(159, 178, 199, 0.12); } +.root :global(.scan-ai-city-hero-left) { + min-width: 0; + flex: 1; +} + .root :global(.scan-ai-city-kicker) { color: #4da3ff; font-size: 12px; @@ -414,10 +420,10 @@ } .root :global(.scan-ai-city-hero h3) { - margin: 8px 0 12px; + margin: 4px 0 8px; color: #e6edf3; - font-size: 28px; - line-height: 1.1; + font-size: 22px; + line-height: 1.15; } .root :global(.scan-ai-city-mobile-priority) { @@ -487,32 +493,33 @@ } .root :global(.scan-ai-city-freshness) { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 6px; - max-width: 620px; - margin-top: 10px; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 4px 6px; + margin-top: 6px; color: #9fb2c7; font-size: 11px; font-weight: 760; } .root :global(.scan-ai-city-freshness strong) { - grid-column: 1 / -1; - color: #d8e7f8; - font-size: 11px; - font-weight: 900; + color: #7d92b2; + font-size: 10px; + font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; + margin-right: 2px; } .root :global(.scan-ai-city-freshness span) { display: inline-flex; align-items: center; gap: 2px; - border-radius: 8px; - background: rgba(148, 163, 184, 0.08); - padding: 4px 7px; + border-radius: 5px; + background: rgba(148, 163, 184, 0.06); + padding: 2px 6px; + font-size: 11px; } .root :global(.scan-ai-city-freshness b) { @@ -546,31 +553,58 @@ } .root :global(.scan-ai-city-hero-side) { - min-width: 180px; + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 10px; + flex-shrink: 0; +} + +.root :global(.scan-ai-city-metrics) { display: grid; - justify-items: end; - align-content: start; - gap: 6px; - text-align: right; + grid-template-columns: repeat(3, auto); + gap: 10px; } -.root :global(.scan-ai-city-hero-side > span) { - color: #9fb2c7; - font-size: 12px; +.root :global(.scan-ai-city-metrics > span) { + display: grid; + gap: 3px; + min-width: 88px; + text-align: center; + padding: 8px 14px; + border: 1px solid rgba(159, 178, 199, 0.12); + border-radius: 11px; + background: rgba(11, 18, 32, 0.42); +} + +.root :global(.scan-ai-city-metrics > span.primary) { + border-color: rgba(77, 163, 255, 0.28); + background: rgba(77, 163, 255, 0.09); +} + +.root :global(.scan-ai-city-metrics small) { + color: #6b7a90; + font-size: 10px; font-weight: 800; + letter-spacing: 0.02em; + text-transform: uppercase; } -.root :global(.scan-ai-city-hero-side > strong) { +.root :global(.scan-ai-city-metrics b) { color: #e6edf3; - font-size: 30px; - line-height: 1; + font-size: 20px; + font-weight: 900; + line-height: 1.1; +} + +.root :global(.scan-ai-city-metrics > span.primary b) { + color: #9ecbff; } .root :global(.scan-ai-city-actions) { display: inline-flex; justify-content: flex-end; gap: 8px; - margin-top: 4px; } .root :global(.scan-ai-city-icon-button), diff --git a/frontend/components/dashboard/ScanTerminalLightTheme.module.css b/frontend/components/dashboard/ScanTerminalLightTheme.module.css index 4939c662..1918eb85 100644 --- a/frontend/components/dashboard/ScanTerminalLightTheme.module.css +++ b/frontend/components/dashboard/ScanTerminalLightTheme.module.css @@ -446,14 +446,28 @@ .root :global(.scan-terminal.light .scan-ai-decision-metrics span), .root :global(.scan-terminal.light .scan-ai-market-bucket), .root :global(.scan-terminal.light .scan-ai-city-pills span), -.root :global(.scan-terminal.light .scan-ai-city-freshness span) { +.root :global(.scan-terminal.light .scan-ai-city-freshness span), +.root :global(.scan-terminal.light .scan-ai-city-metrics > span) { background: #eef2f7; border-color: #e2e8f0; } +.root :global(.scan-terminal.light .scan-ai-city-metrics > span.primary) { + background: #dbeafe; + border-color: rgba(59, 130, 246, 0.28); +} + +.root :global(.scan-terminal.light .scan-ai-city-metrics > span.primary b) { + color: #1d4ed8; +} + +.root :global(.scan-terminal.light .scan-ai-city-metrics small) { + color: #64748b; +} + .root :global(.scan-terminal.light .scan-ai-workspace-head strong), .root :global(.scan-terminal.light .scan-ai-city-hero h3), -.root :global(.scan-terminal.light .scan-ai-city-hero-side > strong), +.root :global(.scan-terminal.light .scan-ai-city-metrics b), .root :global(.scan-terminal.light .scan-ai-decision-band strong), .root :global(.scan-terminal.light .scan-ai-decision-metrics b), .root :global(.scan-terminal.light .scan-ai-market-bucket strong), @@ -770,12 +784,30 @@ .root:global(.light) :global(.scan-terminal.light .scan-ai-decision-metrics span), .root:global(.light) :global(.scan-terminal.light .scan-ai-city-pills span), .root:global(.light) :global(.scan-terminal.light .scan-ai-city-freshness span), +.root:global(.light) :global(.scan-terminal.light .scan-ai-city-metrics > span), .root:global(.light) :global(.scan-terminal.light .scan-mobile-decision-metrics span), .root:global(.light) :global(.scan-terminal.light .scan-mobile-decision-reason) { background: #eef7ff !important; border-color: rgba(37, 99, 235, 0.16) !important; } +.root:global(.light) :global(.scan-terminal.light .scan-ai-city-metrics > span.primary) { + background: #dbeafe !important; + border-color: rgba(59, 130, 246, 0.34) !important; +} + +.root:global(.light) :global(.scan-terminal.light .scan-ai-city-metrics b) { + color: #0f172a !important; +} + +.root:global(.light) :global(.scan-terminal.light .scan-ai-city-metrics > span.primary b) { + color: #1d4ed8 !important; +} + +.root:global(.light) :global(.scan-terminal.light .scan-ai-city-metrics small) { + color: #64748b !important; +} + .root:global(.light) :global(.scan-terminal.light .scan-ai-city-card p), .root:global(.light) :global(.scan-terminal.light .scan-ai-city-card li), .root:global(.light) :global(.scan-terminal.light .scan-ai-city-card small), diff --git a/frontend/components/dashboard/ScanTerminalList.module.css b/frontend/components/dashboard/ScanTerminalList.module.css index 16b2286d..b776ad98 100644 --- a/frontend/components/dashboard/ScanTerminalList.module.css +++ b/frontend/components/dashboard/ScanTerminalList.module.css @@ -591,9 +591,3 @@ overflow: visible; } -.root :global(.scan-ai-city-card:not(.collapsed) .scan-ai-city-hero) { - position: sticky; - top: 54px; - z-index: 6; - border-radius: 18px 18px 0 0; -} diff --git a/frontend/components/dashboard/scan-terminal/CityCardHeader.tsx b/frontend/components/dashboard/scan-terminal/CityCardHeader.tsx index fcc61732..6c20d35e 100644 --- a/frontend/components/dashboard/scan-terminal/CityCardHeader.tsx +++ b/frontend/components/dashboard/scan-terminal/CityCardHeader.tsx @@ -59,32 +59,12 @@ export function CityCardHeader({ }) { return (
-
+
{isEn ? "Deep analysis" : "城市深度分析"}

{displayName}

-
- - {isEn ? "Observed" : "当前温度"} - {currentTempText} - - - {isEn ? "Expected high" : "预测高点"} - {expectedHighText} - - - {isEn ? "Peak" : "峰值时间"} - {peakWindow} - -
-
- {detailLocalTime || rowLocalTime || "--"} - DEB {debText} - {isEn ? "Model" : "模型"} {modelRange} - {isEn ? "Peak" : "峰值"} {peakWindow} -
- {isEn ? "Expected high" : "预计最高温"} - {expectedHighText} +
+ + {isEn ? "Observed" : "当前温度"} + {currentTempText} + + + {isEn ? "Expected high" : "预计最高温"} + {expectedHighText} + + + {isEn ? "Peak" : "峰值时间"} + {peakWindow} + +