全面修复前端 UI 设计审查问题:消除工程债务、统一 token 体系、提升可维护性
- 消除 !important 滥用:134 → 49(仅保留 Leaflet/图表所必需项),浅色主题使用 html.light 选择器获得更高优先级 - 修复 font-weight:13 个文件中所有 760/850/860/880/950 等非标准值已映射为 Inter 支持的 300–800 - 移除未加载的 Geist 字体声明,替换为 Inter - 添加全局 :focus-visible 轮廓环、跳过链接、Tab ARIA 属性(role/aria-selected) - 统一断点体系:18 → 10(480/640/768/960/1024/1200/1280/1360/1440/1680) - 创建 scan-root-styles.ts 桶文件,将 22 个 CSS Module 导入合并为 1 个 - Token 迁移:10 个文件中数百处硬编码颜色(#4DA3FF/#E6EDF3/#9FB2C7/#6B7A90)已替换为 CSS 变量 - 去重 @keyframes:spin 4→1、loading-spin 2→0、pulse-pending 已移至 globals.css - 添加统一的 empty/error/retry 状态组件 - 添加全局 prefers-reduced-motion 支持 - 修复 accent-primary 与 accent-secondary 相同值的问题 - 修复 accent-green 类错误渲染为蓝色 - 添加 CSS 渐变品牌 Logo - 移除死代码(1,697 行):public/static/style.css + public/legacy/index.html - Dashboard.module.css 本地变量已桥接至全局 token - 提升文字对比度:#6B7A90 → #7D8FA3 Fixed: !important-134-to-49, font-weight-13-files, Geist-removal, focus-visible, breakpoints-18-to-10, CSS-module-barrel, token-migration-10-files, keyframe-dedup, dead-code-removal, accent-color-fix, contrast-improvement Scope: frontend CSS architecture, design tokens, accessibility, responsive breakpoints Tested: npx tsc --noEmit
This commit is contained in:
@@ -302,8 +302,8 @@
|
||||
|
||||
.mono {
|
||||
font-family: "Consolas", "SFMono-Regular", "Menlo", monospace;
|
||||
font-size: 12px !important;
|
||||
color: #c7d2fe !important;
|
||||
font-size: 12px;
|
||||
color: #c7d2fe;
|
||||
}
|
||||
|
||||
.hint {
|
||||
@@ -361,13 +361,7 @@
|
||||
animation: spin 0.9s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
@media (max-width: 960px) {
|
||||
.topBar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
@@ -396,7 +390,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
@media (max-width: 640px) {
|
||||
.page {
|
||||
padding: 18px 12px 20px;
|
||||
}
|
||||
|
||||
@@ -4,26 +4,26 @@
|
||||
|
||||
.root {
|
||||
/* ── Palette (bridged from globals.css unified tokens) ── */
|
||||
--bg-primary: #0B1220;
|
||||
--bg-secondary: #16213A;
|
||||
--bg-card: #111A2E;
|
||||
--bg-primary: var(--color-bg-base);
|
||||
--bg-secondary: var(--color-bg-raised);
|
||||
--bg-card: var(--color-bg-card);
|
||||
--bg-glass: rgba(17, 26, 46, 0.82);
|
||||
--border-glass: rgba(159, 178, 199, 0.16);
|
||||
--border-subtle: rgba(159, 178, 199, 0.08);
|
||||
--border-glass: var(--color-border-default);
|
||||
--border-subtle: var(--color-border-subtle);
|
||||
|
||||
/* Text */
|
||||
--text-primary: var(--color-text-primary);
|
||||
--text-secondary: var(--color-text-secondary);
|
||||
--text-muted: var(--color-text-muted);
|
||||
|
||||
/* Accents — Fintech 3-Color Model */
|
||||
--accent-cyan: #4DA3FF;
|
||||
--accent-blue: #4DA3FF;
|
||||
/* Accent Colors */
|
||||
--accent-cyan: var(--color-accent-primary);
|
||||
--accent-blue: var(--color-accent-secondary);
|
||||
--accent-green: #22C55E;
|
||||
--accent-orange: #F59E0B;
|
||||
--accent-red: #EF4444;
|
||||
--accent-yellow: #F59E0B;
|
||||
--accent-purple: #4DA3FF;
|
||||
--accent-purple: var(--color-accent-tertiary);
|
||||
|
||||
/* Risk colors */
|
||||
--risk-high: var(--color-risk-high);
|
||||
|
||||
@@ -383,7 +383,7 @@
|
||||
border: 1px solid rgba(34, 211, 238, 0.18);
|
||||
border-radius: 999px;
|
||||
background: rgba(8, 145, 178, 0.1);
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 10px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.12em;
|
||||
@@ -418,7 +418,7 @@
|
||||
.root :global(.home-card-meta-row) {
|
||||
color: rgba(148, 163, 184, 0.88);
|
||||
font-size: 12px;
|
||||
font-weight: 650;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.root :global(.home-card-titlebar p) {
|
||||
@@ -476,7 +476,7 @@
|
||||
|
||||
.root :global(.home-weather-label) {
|
||||
margin-bottom: 8px;
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 10px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.14em;
|
||||
@@ -567,7 +567,7 @@
|
||||
width: 4px;
|
||||
height: 13px;
|
||||
border-radius: 999px;
|
||||
background: #4DA3FF;
|
||||
background: var(--color-accent-primary);
|
||||
transform: rotate(18deg);
|
||||
}
|
||||
|
||||
@@ -760,9 +760,9 @@
|
||||
|
||||
.root :global(.home-deb-card span),
|
||||
.root :global(.home-card-section h3) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.home-deb-card small),
|
||||
@@ -785,7 +785,7 @@
|
||||
color: #f87171;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.home-market-metrics svg) {
|
||||
@@ -882,7 +882,7 @@
|
||||
}
|
||||
|
||||
.root :global(.home-intraday-chart circle) {
|
||||
fill: #4DA3FF;
|
||||
fill: var(--color-accent-primary);
|
||||
stroke: rgba(15, 23, 42, 0.92);
|
||||
stroke-width: 1.6;
|
||||
filter: drop-shadow(0 0 10px rgba(56, 189, 248, 0.28));
|
||||
@@ -1007,7 +1007,7 @@
|
||||
gap: 9px;
|
||||
color: rgba(226, 232, 240, 0.95);
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.home-probability-row div),
|
||||
@@ -1077,7 +1077,7 @@
|
||||
.root :global(.home-market-header span) {
|
||||
color: rgba(148, 163, 184, 0.88);
|
||||
font-size: 11px;
|
||||
font-weight: 750;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.root :global(.home-market-ticket) {
|
||||
@@ -1109,7 +1109,7 @@
|
||||
}
|
||||
|
||||
.root :global(.home-market-prices .yes) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
background: rgba(8, 145, 178, 0.2);
|
||||
}
|
||||
|
||||
@@ -1142,7 +1142,7 @@
|
||||
margin-top: 10px;
|
||||
color: #fde68a;
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -1244,7 +1244,7 @@
|
||||
.root :global(.opportunity-strip-copy strong) {
|
||||
color: #f8fafc;
|
||||
font-size: 19px;
|
||||
font-weight: 860;
|
||||
font-weight: 800;
|
||||
line-height: 1.25;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
@@ -1279,7 +1279,7 @@
|
||||
.root :global(.opportunity-tape-pill span) {
|
||||
color: rgba(148, 163, 184, 0.82);
|
||||
font-size: 10px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -1287,12 +1287,12 @@
|
||||
.root :global(.opportunity-tape-pill strong) {
|
||||
color: #f8fafc;
|
||||
font-size: 16px;
|
||||
font-weight: 860;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.root :global(.opportunity-tape-pill.accent-cyan strong) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
}
|
||||
|
||||
.root :global(.opportunity-tape-pill.accent-green strong) {
|
||||
@@ -1383,7 +1383,7 @@
|
||||
}
|
||||
|
||||
.root :global(.opportunity-hero-kicker) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.08em;
|
||||
@@ -1401,7 +1401,7 @@
|
||||
overflow: hidden;
|
||||
color: #f8fafc;
|
||||
font-size: 28px;
|
||||
font-weight: 880;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.04em;
|
||||
text-overflow: ellipsis;
|
||||
@@ -1411,7 +1411,7 @@
|
||||
.root :global(.opportunity-hero-date) {
|
||||
color: rgba(186, 230, 253, 0.76);
|
||||
font-size: 12px;
|
||||
font-weight: 720;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.root :global(.opportunity-hero-copy p) {
|
||||
@@ -1439,13 +1439,13 @@
|
||||
background: rgba(7, 13, 25, 0.58);
|
||||
color: rgba(226, 232, 240, 0.92);
|
||||
font-size: 11px;
|
||||
font-weight: 820;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.root :global(.opportunity-hero-tag.engine) {
|
||||
border-color: rgba(34, 211, 238, 0.24);
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
}
|
||||
|
||||
.root :global(.opportunity-hero-tag.signal-yes) {
|
||||
@@ -1499,7 +1499,7 @@
|
||||
.root :global(.opportunity-hero-edgeblock span) {
|
||||
color: rgba(148, 163, 184, 0.8);
|
||||
font-size: 11px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -1539,7 +1539,7 @@
|
||||
.root :global(.opportunity-hero-metric span) {
|
||||
color: rgba(148, 163, 184, 0.8);
|
||||
font-size: 10px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -1548,7 +1548,7 @@
|
||||
overflow: hidden;
|
||||
color: #f8fafc;
|
||||
font-size: 20px;
|
||||
font-weight: 860;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.03em;
|
||||
text-overflow: ellipsis;
|
||||
@@ -1575,14 +1575,14 @@
|
||||
|
||||
.root :global(.opportunity-book-side span) {
|
||||
font-size: 11px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.root :global(.opportunity-book-side strong) {
|
||||
font-size: 26px;
|
||||
font-weight: 880;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.03em;
|
||||
}
|
||||
@@ -1624,7 +1624,7 @@
|
||||
.root :global(.opportunity-hero-sparkline-wrap span) {
|
||||
color: rgba(148, 163, 184, 0.8);
|
||||
font-size: 10px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -1680,7 +1680,7 @@
|
||||
.root :global(.opportunity-side-tile-head span) {
|
||||
color: rgba(241, 245, 249, 0.92);
|
||||
font-size: 13px;
|
||||
font-weight: 790;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.root :global(.opportunity-side-tile-body) {
|
||||
@@ -1700,7 +1700,7 @@
|
||||
overflow: hidden;
|
||||
color: #f8fafc;
|
||||
font-size: 24px;
|
||||
font-weight: 880;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.04em;
|
||||
text-overflow: ellipsis;
|
||||
@@ -1710,7 +1710,7 @@
|
||||
.root :global(.opportunity-side-stat span) {
|
||||
color: rgba(148, 163, 184, 0.82);
|
||||
font-size: 10px;
|
||||
font-weight: 680;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.root :global(.opportunity-side-stat b.accent-red) {
|
||||
@@ -1762,7 +1762,7 @@
|
||||
.root :global(.opportunity-empty-copy strong) {
|
||||
color: rgba(241, 245, 249, 0.94);
|
||||
font-size: 15px;
|
||||
font-weight: 840;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.opportunity-empty-copy span) {
|
||||
@@ -1828,7 +1828,7 @@
|
||||
justify-content: center;
|
||||
color: #f8fafc;
|
||||
font-size: 13px;
|
||||
font-weight: 840;
|
||||
font-weight: 800;
|
||||
flex-shrink: 0;
|
||||
background: rgba(6, 11, 23, 0.46);
|
||||
}
|
||||
@@ -1870,7 +1870,7 @@
|
||||
overflow: hidden;
|
||||
color: #f8fafc;
|
||||
font-size: 15px;
|
||||
font-weight: 860;
|
||||
font-weight: 800;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -2188,7 +2188,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1240px) {
|
||||
@media (max-width: 1280px) {
|
||||
.root :global(.opportunity-strip-topline) {
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -2215,7 +2215,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1020px) {
|
||||
@media (max-width: 1024px) {
|
||||
.root :global(.map) {
|
||||
left: 18px;
|
||||
bottom: 188px;
|
||||
@@ -2234,7 +2234,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
@media (max-width: 768px) {
|
||||
.root :global(.map) {
|
||||
inset: var(--header-height) 0 0;
|
||||
border-radius: 0;
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
0 0 22px rgba(251, 113, 133, 0.18);
|
||||
}
|
||||
.root :global(.marker-bubble.risk-high::after) {
|
||||
border-top-color: #ef4444;
|
||||
border-top-color: var(--color-signal-danger);
|
||||
}
|
||||
|
||||
.root :global(.marker-bubble.risk-medium) {
|
||||
@@ -168,7 +168,7 @@
|
||||
0 0 22px rgba(245, 158, 11, 0.16);
|
||||
}
|
||||
.root :global(.marker-bubble.risk-medium::after) {
|
||||
border-top-color: #f59e0b;
|
||||
border-top-color: var(--color-signal-warning);
|
||||
}
|
||||
|
||||
.root :global(.marker-bubble.risk-low) {
|
||||
@@ -179,7 +179,7 @@
|
||||
0 0 22px rgba(74, 222, 128, 0.14);
|
||||
}
|
||||
.root :global(.marker-bubble.risk-low::after) {
|
||||
border-top-color: #22C55E;
|
||||
border-top-color: var(--color-signal-success);
|
||||
}
|
||||
|
||||
.root :global(.marker-name) {
|
||||
@@ -380,7 +380,7 @@
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, #6FB7FF 0%, #0891b2 100%);
|
||||
background: radial-gradient(circle, var(--color-accent-secondary) 0%, #0891b2 100%);
|
||||
transform: translate(-50%, -50%);
|
||||
box-shadow:
|
||||
0 0 12px rgba(34, 211, 238, 0.65),
|
||||
@@ -544,18 +544,10 @@
|
||||
border: 2px solid rgba(34, 211, 238, 0.1);
|
||||
border-top-color: var(--accent-cyan);
|
||||
border-radius: 50%;
|
||||
animation: loading-spin 0.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
||||
animation: spin 0.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
||||
box-shadow: 0 0 15px rgba(34, 211, 238, 0.1);
|
||||
}
|
||||
|
||||
@keyframes loading-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes city-loading-pulse {
|
||||
0% {
|
||||
@@ -767,7 +759,7 @@
|
||||
}
|
||||
|
||||
.root :global(.nearby-time.is-stale) {
|
||||
color: #fbbf24;
|
||||
color: var(--color-signal-warning);
|
||||
}
|
||||
|
||||
.root :global(.nearby-wind) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.root :global(.scan-select) {
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(135deg, #4DA3FF, #00b383);
|
||||
background: linear-gradient(135deg, var(--color-accent-primary), #00b383);
|
||||
color: #000;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
@@ -90,12 +90,6 @@
|
||||
color: var(--accent-cyan);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.root :global(.modal-close) {
|
||||
background: none;
|
||||
border: none;
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
color: rgba(203, 213, 225, 0.82);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-weight: 550;
|
||||
font-weight: 500;
|
||||
transition: var(--transition);
|
||||
position: relative;
|
||||
}
|
||||
@@ -223,7 +223,7 @@
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
font-size: 11px;
|
||||
font-weight: 750;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
}
|
||||
@@ -262,7 +262,7 @@
|
||||
gap: 6px;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
font-weight: 650;
|
||||
font-weight: 600;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
@@ -281,14 +281,6 @@
|
||||
padding: 0;
|
||||
width: 32px;
|
||||
}
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── City List Sidebar ── */
|
||||
.root :global(.city-list) {
|
||||
@@ -545,11 +537,11 @@
|
||||
}
|
||||
|
||||
.root :global(.city-item .city-deviation-cold) {
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.city-item .city-deviation-hot) {
|
||||
color: #f59e0b;
|
||||
color: var(--color-signal-warning);
|
||||
}
|
||||
|
||||
.root :global(.city-item .city-deviation-normal) {
|
||||
@@ -604,7 +596,7 @@
|
||||
}
|
||||
|
||||
/* ── Responsive ── */
|
||||
@media (max-width: 1100px) {
|
||||
@media (max-width: 1024px) {
|
||||
.root {
|
||||
--panel-width: 460px;
|
||||
}
|
||||
@@ -707,7 +699,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
@media (max-width: 640px) {
|
||||
.root :global(.header) {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
.root :global(.panel-action-button-primary) {
|
||||
color: #FFFFFF;
|
||||
background: linear-gradient(135deg, #4DA3FF, #3B82F6);
|
||||
background: linear-gradient(135deg, var(--color-accent-primary), #3B82F6);
|
||||
border-color: rgba(77, 163, 255, 0.34);
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
border-radius: 999px;
|
||||
border: 2px solid rgba(34, 211, 238, 0.22);
|
||||
border-top-color: rgba(34, 211, 238, 0.92);
|
||||
animation: loading-spin 0.8s linear infinite;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
.root :global(.panel-meta) {
|
||||
@@ -232,7 +232,7 @@
|
||||
box-shadow: 0 14px 34px rgba(2, 6, 23, 0.38);
|
||||
backdrop-filter: blur(18px);
|
||||
font-size: 12px;
|
||||
font-weight: 650;
|
||||
font-weight: 600;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@
|
||||
/* ── Hero Section ── */
|
||||
.root :global(.hero-section) {
|
||||
text-align: center;
|
||||
padding-top: 12px !important;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.root :global(.hero-weather) {
|
||||
@@ -429,7 +429,7 @@
|
||||
padding: 3px 8px;
|
||||
border: 1px solid rgba(34, 211, 238, 0.28);
|
||||
border-radius: 8px;
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
background: rgba(34, 211, 238, 0.08);
|
||||
font-size: 11px;
|
||||
font-weight: 900;
|
||||
@@ -904,7 +904,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
@media (max-width: 768px) {
|
||||
.root :global(.forecast-table) {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
@@ -1058,8 +1058,3 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
border: 1px solid rgba(34, 211, 238, 0.28);
|
||||
border-radius: 8px;
|
||||
background: rgba(8, 47, 73, 0.36);
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
line-height: 1.25;
|
||||
@@ -195,7 +195,7 @@
|
||||
.root :global(.future-v2-decision-anchor small) {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
@@ -219,7 +219,7 @@
|
||||
.root :global(.future-v2-decision-grid strong) {
|
||||
display: block;
|
||||
margin-top: 7px;
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
@@ -250,7 +250,7 @@
|
||||
.root :global(.future-v2-meteorology-paths strong) {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
@@ -595,7 +595,7 @@
|
||||
}
|
||||
|
||||
.root :global(.future-v2-signal-tag.cyan) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
border-color: rgba(34, 211, 238, 0.22);
|
||||
background: rgba(34, 211, 238, 0.08);
|
||||
}
|
||||
@@ -684,7 +684,7 @@
|
||||
}
|
||||
|
||||
.root :global(.future-v2-pace-delta.cold) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
}
|
||||
|
||||
.root :global(.future-v2-pace-delta.neutral) {
|
||||
@@ -759,7 +759,7 @@
|
||||
}
|
||||
|
||||
.root :global(.future-v2-pace-meter-fill.cold) {
|
||||
background: linear-gradient(90deg, #0f766e 0%, #6FB7FF 100%);
|
||||
background: linear-gradient(90deg, #0f766e 0%, var(--color-accent-secondary) 100%);
|
||||
}
|
||||
|
||||
.root :global(.future-v2-pace-meter-fill.neutral) {
|
||||
@@ -1322,7 +1322,7 @@
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
border-radius: inherit;
|
||||
background: linear-gradient(90deg, #334155 0%, #9FB2C7 100%);
|
||||
background: linear-gradient(90deg, #334155 0%, var(--color-text-secondary) 100%);
|
||||
}
|
||||
|
||||
.root :global(.future-trend-meter-fill.warm) {
|
||||
@@ -1609,7 +1609,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
@media (max-width: 480px) {
|
||||
.root :global(.future-forward-stats) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -438,7 +438,7 @@
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
@media (max-width: 980px) {
|
||||
@media (max-width: 960px) {
|
||||
.root :global(.history-modal .modal-body) {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ export function ScanFilterPanel({
|
||||
<span>{isEn ? "Scan Mode" : "扫描模式"}</span>
|
||||
<Info size={14} />
|
||||
</div>
|
||||
<div className="scan-mode-tabs">
|
||||
<div className="scan-mode-tabs" role="tablist" aria-label={isEn ? "Scan mode" : "扫描模式"}>
|
||||
{SCAN_MODES.map((mode) => {
|
||||
const Icon = mode.icon;
|
||||
const isActive = value.scan_mode === mode.key;
|
||||
@@ -89,6 +89,8 @@ export function ScanFilterPanel({
|
||||
<button
|
||||
key={mode.key}
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={isActive}
|
||||
className={`scan-mode-tab ${isActive ? "active" : ""}`}
|
||||
onClick={() => updateFilter("scan_mode", mode.key)}
|
||||
>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
.root :global(.scan-mode-tab.active) {
|
||||
background: rgba(0, 224, 164, 0.08);
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
top: 25%;
|
||||
height: 50%;
|
||||
width: 3px;
|
||||
background: #4DA3FF;
|
||||
background: var(--color-accent-primary);
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
appearance: none;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background: #4DA3FF;
|
||||
background: var(--color-accent-primary);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
border: 2px solid var(--bg-secondary);
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
.root :global(.scan-toggle.active) {
|
||||
background: rgba(0, 224, 164, 0.3);
|
||||
border-color: #4DA3FF;
|
||||
border-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.scan-toggle-knob) {
|
||||
@@ -162,7 +162,7 @@
|
||||
|
||||
.root :global(.scan-toggle.active .scan-toggle-knob) {
|
||||
left: 18px;
|
||||
background: #4DA3FF;
|
||||
background: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
/* Select */
|
||||
@@ -179,7 +179,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-select:focus) {
|
||||
border-color: #4DA3FF;
|
||||
border-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
/* Scan CTA */
|
||||
@@ -192,7 +192,7 @@
|
||||
padding: 12px 16px;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(135deg, #4DA3FF, #00c48f);
|
||||
background: linear-gradient(135deg, var(--color-accent-primary), #00c48f);
|
||||
color: #030711;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
@@ -271,7 +271,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-view-tab.active) {
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: #4DA3FF;
|
||||
background: var(--color-accent-primary);
|
||||
border-radius: 4px;
|
||||
opacity: 0.8;
|
||||
transition: all 0.3s ease;
|
||||
@@ -392,7 +392,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-condition-value.accent-green) {
|
||||
color: #4DA3FF;
|
||||
color: #22C55E;
|
||||
}
|
||||
|
||||
.root :global(.scan-condition-value.accent-red) {
|
||||
@@ -417,7 +417,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-trade-card.yes) {
|
||||
border-top: 2px solid #4DA3FF;
|
||||
border-top: 2px solid var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.scan-trade-card.no) {
|
||||
@@ -441,7 +441,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-trade-card-edge.positive) {
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.scan-trade-card-edge.negative) {
|
||||
@@ -494,7 +494,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-confidence-dot.filled) {
|
||||
background: #4DA3FF;
|
||||
background: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.scan-confidence-dot.filled.amber) {
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-upgrade-announcement-copy span) {
|
||||
color: #4da3ff;
|
||||
color: var(--color-accent-primary);
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
@@ -56,13 +56,13 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-upgrade-announcement-copy strong) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 18px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.root :global(.scan-upgrade-announcement-copy p) {
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
margin: 10px 0 0;
|
||||
color: #d6e4f5;
|
||||
font-size: 13px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,17 +31,17 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-kicker) {
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
font-size: 11px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-city-title strong) {
|
||||
color: #E6EDF3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
@@ -57,9 +57,9 @@
|
||||
border: 1px solid rgba(159, 178, 199, 0.14);
|
||||
border-radius: 9px;
|
||||
background: rgba(22, 33, 58, 0.56);
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
@@ -68,28 +68,28 @@
|
||||
justify-items: end;
|
||||
gap: 5px;
|
||||
min-width: 0;
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-city-read small) {
|
||||
color: #6B7A90;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 11px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-city-read > b:not(.scan-phase-badge)) {
|
||||
color: #E6EDF3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 30px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-city-read span) {
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-row) {
|
||||
@@ -137,21 +137,21 @@
|
||||
.root :global(.scan-forecast-bucket small),
|
||||
.root :global(.scan-forecast-signals small),
|
||||
.root :global(.scan-ai-temperature-line small) {
|
||||
color: #6B7A90;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 11px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-bucket strong) {
|
||||
color: #E6EDF3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 18px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
line-height: 1.22;
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-bucket small) {
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
.root :global(.scan-forecast-signals b) {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
color: #E6EDF3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
line-height: 1.25;
|
||||
@@ -196,9 +196,9 @@
|
||||
border: 1px solid rgba(96, 165, 250, 0.28);
|
||||
border-radius: 999px;
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -231,20 +231,20 @@
|
||||
gap: 10px;
|
||||
align-items: baseline;
|
||||
padding: 0 16px 14px;
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-ai-line b) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.scan-forecast-ai-line small) {
|
||||
min-width: 0;
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 750;
|
||||
font-weight: 700;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@@ -272,26 +272,26 @@
|
||||
|
||||
.root :global(.scan-ai-analysis-head strong),
|
||||
.root :global(.scan-ai-brief-grid strong) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-analysis-head p) {
|
||||
margin: 0;
|
||||
color: #E6EDF3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 20px;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-analysis-head small) {
|
||||
max-width: 880px;
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 14px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
@@ -305,9 +305,9 @@
|
||||
border: 1px solid rgba(96, 165, 250, 0.28);
|
||||
border-radius: 999px;
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -328,9 +328,9 @@
|
||||
|
||||
.root :global(.scan-ai-temperature-line b) {
|
||||
overflow: hidden;
|
||||
color: #E6EDF3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 17px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -352,7 +352,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-evidence-line small) {
|
||||
color: #6B7A90;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 11px;
|
||||
font-weight: 900;
|
||||
}
|
||||
@@ -360,7 +360,7 @@
|
||||
.root :global(.scan-ai-evidence-line b) {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
color: #E6EDF3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 13px;
|
||||
font-weight: 900;
|
||||
line-height: 1.3;
|
||||
@@ -379,7 +379,7 @@
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(77, 163, 255, 0.35);
|
||||
border-radius: 18px;
|
||||
background: #111a2e;
|
||||
background: var(--color-bg-raised);
|
||||
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.24);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
@@ -414,14 +414,14 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-city-kicker) {
|
||||
color: #4da3ff;
|
||||
color: var(--color-accent-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-city-hero h3) {
|
||||
margin: 4px 0 8px;
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 22px;
|
||||
line-height: 1.15;
|
||||
}
|
||||
@@ -498,9 +498,9 @@
|
||||
align-items: center;
|
||||
gap: 4px 6px;
|
||||
margin-top: 6px;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 11px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-city-freshness strong) {
|
||||
@@ -529,7 +529,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-city-freshness em) {
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@@ -583,7 +583,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-city-metrics small) {
|
||||
color: #6b7a90;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 10px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.02em;
|
||||
@@ -591,7 +591,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-city-metrics b) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 20px;
|
||||
font-weight: 900;
|
||||
line-height: 1.1;
|
||||
@@ -699,7 +699,7 @@
|
||||
align-items: center;
|
||||
border: 1px solid rgba(77, 163, 255, 0.18);
|
||||
border-radius: 16px;
|
||||
background: #16213a;
|
||||
background: var(--color-bg-overlay);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
@@ -720,7 +720,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-decision-band span) {
|
||||
color: #4da3ff;
|
||||
color: var(--color-accent-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
}
|
||||
@@ -728,14 +728,14 @@
|
||||
.root :global(.scan-ai-decision-band strong) {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 24px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-decision-band p) {
|
||||
margin: 8px 0 0;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
@@ -745,7 +745,7 @@
|
||||
border: 1px solid rgba(77, 163, 255, 0.24);
|
||||
border-radius: 12px;
|
||||
background: rgba(77, 163, 255, 0.1);
|
||||
color: #d8e7f8 !important;
|
||||
color: var(--color-text-primary);
|
||||
font-weight: 900;
|
||||
padding: 9px 11px;
|
||||
}
|
||||
@@ -779,14 +779,14 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-market-decision span) {
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 11px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-market-decision strong) {
|
||||
margin-top: 3px;
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
@@ -806,14 +806,14 @@
|
||||
gap: 3px;
|
||||
border-radius: 10px;
|
||||
background: rgba(17, 26, 46, 0.82);
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-market-decision-stats b) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
@@ -840,14 +840,14 @@
|
||||
border: 1px solid rgba(159, 178, 199, 0.14);
|
||||
border-radius: 12px;
|
||||
background: rgba(11, 18, 32, 0.5);
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-decision-metrics b) {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
@@ -869,7 +869,7 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #4da3ff;
|
||||
color: var(--color-accent-primary);
|
||||
font-size: 13px;
|
||||
font-weight: 900;
|
||||
margin-bottom: 12px;
|
||||
@@ -908,7 +908,7 @@
|
||||
|
||||
.root :global(.scan-ai-city-section p) {
|
||||
margin: 0 0 10px;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
@@ -1006,14 +1006,10 @@
|
||||
animation: pulse-pending 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse-pending {
|
||||
0%, 100% { opacity: 0.3; }
|
||||
50% { opacity: 0.6; }
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-weather-summary) {
|
||||
color: #e6edf3;
|
||||
font-weight: 850;
|
||||
color: var(--color-text-primary);
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-weather-bullets) {
|
||||
@@ -1021,21 +1017,21 @@
|
||||
gap: 8px;
|
||||
margin: 10px 0 0;
|
||||
padding-left: 18px;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-weather-bullets li::marker) {
|
||||
color: #4da3ff;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-raw-metar) {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid rgba(77, 163, 255, 0.12);
|
||||
color: #6b7a90;
|
||||
color: var(--color-text-muted);
|
||||
font-family:
|
||||
ui-monospace,
|
||||
SFMono-Regular,
|
||||
@@ -1073,7 +1069,7 @@
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
margin-top: 10px;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
@@ -1147,14 +1143,14 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-market-bucket strong) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-market-bucket span),
|
||||
.root :global(.scan-ai-city-muted),
|
||||
.root :global(.scan-ai-city-loading) {
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -1180,9 +1176,9 @@
|
||||
.root :global(.scan-ai-brief-grid li) {
|
||||
position: relative;
|
||||
padding-left: 16px;
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 760;
|
||||
font-weight: 700;
|
||||
line-height: 1.48;
|
||||
}
|
||||
|
||||
@@ -1193,7 +1189,7 @@
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 999px;
|
||||
background: #4DA3FF;
|
||||
background: var(--color-accent-primary);
|
||||
box-shadow: 0 0 10px rgba(77, 163, 255, 0.34);
|
||||
content: "";
|
||||
}
|
||||
@@ -1212,7 +1208,7 @@
|
||||
|
||||
.root :global(.scan-ai-airport-read p) {
|
||||
margin: 0;
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
line-height: 1.5;
|
||||
|
||||
@@ -18,28 +18,7 @@ import {
|
||||
useState,
|
||||
} from "react";
|
||||
import styles from "./Dashboard.module.css";
|
||||
import dashboardHomeStyles from "./DashboardHomeIntelligence.module.css";
|
||||
import dashboardMapStyles from "./DashboardMap.module.css";
|
||||
import dashboardModalGuideStyles from "./DashboardModalGuide.module.css";
|
||||
import dashboardShellStyles from "./DashboardShell.module.css";
|
||||
import detailChromeStyles from "./DetailPanelChrome.module.css";
|
||||
import detailContentStyles from "./DetailPanelContent.module.css";
|
||||
import detailSectionsStyles from "./DetailPanelSections.module.css";
|
||||
import futureForecastModalStyles from "./FutureForecastModal.module.css";
|
||||
import historyModalStyles from "./HistoryModal.module.css";
|
||||
import modalChromeStyles from "./ModalChrome.module.css";
|
||||
import scanTerminalCalendarStyles from "./ScanTerminalCalendar.module.css";
|
||||
import scanTerminalCardStyles from "./ScanTerminalCard.module.css";
|
||||
import scanTerminalLightThemeStyles from "./ScanTerminalLightTheme.module.css";
|
||||
import scanTerminalOpportunityStyles from "./ScanTerminalOpportunity.module.css";
|
||||
import scanTerminalStyles from "./ScanTerminal.module.css";
|
||||
import scanTerminalBoardStyles from "./ScanTerminalBoard.module.css";
|
||||
import scanTerminalDetailStyles from "./ScanTerminalDetail.module.css";
|
||||
import scanTerminalFiltersStyles from "./ScanTerminalFilters.module.css";
|
||||
import scanTerminalListStyles from "./ScanTerminalList.module.css";
|
||||
import scanTerminalShellStyles from "./ScanTerminalShell.module.css";
|
||||
import scanTerminalStateStyles from "./ScanTerminalState.module.css";
|
||||
import scanTerminalMobileStyles from "./ScanTerminalMobile.module.css";
|
||||
import { scanRootClass } from "./scan-root-styles";
|
||||
import { ProFeaturePaywall } from "@/components/dashboard/ProFeaturePaywall";
|
||||
import {
|
||||
DashboardStoreProvider,
|
||||
@@ -133,28 +112,7 @@ function ScanTerminalScreen() {
|
||||
const lastMapSelectedCityRef = useRef<string>("");
|
||||
const scanTerminalRootClassName = clsx(
|
||||
styles.root,
|
||||
dashboardHomeStyles.root,
|
||||
dashboardMapStyles.root,
|
||||
dashboardShellStyles.root,
|
||||
dashboardModalGuideStyles.root,
|
||||
scanTerminalStyles.root,
|
||||
scanTerminalShellStyles.root,
|
||||
scanTerminalFiltersStyles.root,
|
||||
scanTerminalListStyles.root,
|
||||
scanTerminalBoardStyles.root,
|
||||
scanTerminalDetailStyles.root,
|
||||
scanTerminalStateStyles.root,
|
||||
scanTerminalOpportunityStyles.root,
|
||||
scanTerminalCardStyles.root,
|
||||
scanTerminalCalendarStyles.root,
|
||||
scanTerminalMobileStyles.root,
|
||||
scanTerminalLightThemeStyles.root,
|
||||
detailChromeStyles.root,
|
||||
detailContentStyles.root,
|
||||
detailSectionsStyles.root,
|
||||
modalChromeStyles.root,
|
||||
futureForecastModalStyles.root,
|
||||
historyModalStyles.root,
|
||||
scanRootClass,
|
||||
themeMode === "light" && "light",
|
||||
);
|
||||
|
||||
@@ -441,14 +399,17 @@ function ScanTerminalScreen() {
|
||||
>
|
||||
<main className="scan-data-grid">
|
||||
<div className="scan-topbar">
|
||||
<div className="scan-topbar-title">
|
||||
<strong>{isEn ? "AI Weather Decision Terminal" : "AI 天气交易决策台"}</strong>
|
||||
<div className="scan-topbar-brand">
|
||||
<div className="scan-topbar-logo" aria-hidden="true" />
|
||||
<div className="scan-topbar-title">
|
||||
<strong>{isEn ? "AI Weather Decision Terminal" : "AI 天气交易决策台"}</strong>
|
||||
<span>
|
||||
{isEn
|
||||
? "Start from the map, then open city cards to verify weather evidence"
|
||||
: "从地图选城市,再打开决策卡验证天气证据"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="scan-topbar-actions">
|
||||
<button
|
||||
type="button"
|
||||
@@ -525,9 +486,11 @@ function ScanTerminalScreen() {
|
||||
|
||||
<section className="scan-list-section">
|
||||
<div className="scan-list-header">
|
||||
<div className="scan-list-tabs">
|
||||
<div className="scan-list-tabs" role="tablist" aria-label={isEn ? "Content view" : "内容视图"}>
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={resolvedView === "map"}
|
||||
className={resolvedView === "map" ? "active" : ""}
|
||||
onClick={() => {
|
||||
lastMapSelectedCityRef.current = normalizeCityKey(store.selectedCity);
|
||||
@@ -538,6 +501,8 @@ function ScanTerminalScreen() {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={resolvedView === "analysis"}
|
||||
className={resolvedView === "analysis" ? "active" : ""}
|
||||
onClick={() => {
|
||||
setActiveView("analysis");
|
||||
@@ -547,6 +512,8 @@ function ScanTerminalScreen() {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={resolvedView === "calendar"}
|
||||
className={resolvedView === "calendar" ? "active" : ""}
|
||||
title={!isPro ? (isEn ? "Pro forecast calendar required" : "日历预测需 Pro") : undefined}
|
||||
onClick={() => {
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
color: #0F172A;
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-topbar-logo) {
|
||||
background: linear-gradient(135deg, #2563EB, #059669);
|
||||
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.18);
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-filter-panel),
|
||||
.root :global(.scan-terminal.light .scan-data-grid),
|
||||
.root :global(.scan-terminal.light .scan-detail-panel),
|
||||
@@ -80,6 +85,28 @@
|
||||
rgba(255, 255, 255, 0.78);
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-empty-icon),
|
||||
.root :global(.scan-terminal.light .scan-error-icon) {
|
||||
background: rgba(37, 99, 235, 0.08);
|
||||
border-color: rgba(37, 99, 235, 0.16);
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-error-icon) {
|
||||
background: rgba(239, 68, 68, 0.06);
|
||||
border-color: rgba(239, 68, 68, 0.14);
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-retry-button) {
|
||||
background: rgba(37, 99, 235, 0.08);
|
||||
border-color: rgba(37, 99, 235, 0.22);
|
||||
color: #2563EB;
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-retry-button:hover) {
|
||||
background: rgba(37, 99, 235, 0.14);
|
||||
border-color: rgba(37, 99, 235, 0.38);
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-loading-node) {
|
||||
background: #ffffff;
|
||||
border-color: rgba(148, 163, 184, 0.22);
|
||||
@@ -317,11 +344,11 @@
|
||||
.root :global(.scan-terminal.light .scan-v4-analysis p),
|
||||
.root :global(.scan-terminal.light .scan-v4-analysis ul),
|
||||
.root :global(.scan-terminal.light .scan-v4-evidence > div > span) {
|
||||
color: #6B7A90;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-v4-model-sources em) {
|
||||
color: #6B7A90;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-v4-model-sources b) {
|
||||
@@ -567,7 +594,7 @@
|
||||
.root :global(.scan-terminal.light .scan-ai-city-head p),
|
||||
.root :global(.scan-terminal.light .scan-ai-contract p),
|
||||
.root :global(.scan-terminal.light .scan-ai-contract small) {
|
||||
color: #6B7A90;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.root :global(.scan-terminal.light .scan-ai-city-head) {
|
||||
@@ -667,6 +694,8 @@
|
||||
|
||||
/* Light-mode hard overrides for the scan terminal. Keep this block last so the
|
||||
decision workspace cannot inherit the dark map/card palette from base rules. */
|
||||
|
||||
/* ── CSS Variable bridge (from globals.css token overrides) ── */
|
||||
.root:global(.light) {
|
||||
--bg-primary: #eef7ff;
|
||||
--bg-secondary: #e0f2fe;
|
||||
@@ -679,281 +708,313 @@
|
||||
--text-muted: #475569;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light) {
|
||||
/* ── Scan terminal shell light background ── */
|
||||
html.light .root :global(.scan-terminal.light) {
|
||||
background:
|
||||
radial-gradient(circle at 18% 12%, rgba(59, 130, 246, 0.12), transparent 30%),
|
||||
linear-gradient(180deg, #eef7ff 0%, #e8f4ff 48%, #f8fbff 100%) !important;
|
||||
color: #0f172a !important;
|
||||
linear-gradient(180deg, #eef7ff 0%, #e8f4ff 48%, #f8fbff 100%);
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
:global(html.light) .root :global(.map),
|
||||
.root:global(.light) :global(.map),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-map-shell .map),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-map-shell .leaflet-container),
|
||||
.root:global(.light) :global(.leaflet-container),
|
||||
.root:global(.light) :global(.leaflet-pane),
|
||||
.root:global(.light) :global(.leaflet-map-pane),
|
||||
.root:global(.light) :global(.leaflet-tile-pane) {
|
||||
/* ── Leaflet map light overrides (needs !important to beat Leaflet inline styles) ── */
|
||||
html.light .root :global(.map),
|
||||
html.light .root :global(.scan-terminal.light .scan-map-shell .map),
|
||||
html.light .root :global(.scan-terminal.light .scan-map-shell .leaflet-container),
|
||||
html.light .root :global(.leaflet-container),
|
||||
html.light .root :global(.leaflet-pane),
|
||||
html.light .root :global(.leaflet-map-pane),
|
||||
html.light .root :global(.leaflet-tile-pane) {
|
||||
background: #eef7ff !important;
|
||||
}
|
||||
|
||||
:global(html.light) .root :global(.map),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-map-shell) {
|
||||
border-color: rgba(37, 99, 235, 0.18) !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-map-shell),
|
||||
html.light .root :global(.map) {
|
||||
border-color: rgba(37, 99, 235, 0.18);
|
||||
box-shadow:
|
||||
0 18px 40px rgba(61, 100, 145, 0.14),
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.72) !important;
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.72);
|
||||
}
|
||||
|
||||
:global(html.light) .root :global(.map .leaflet-tile),
|
||||
.root:global(.light) :global(.map .leaflet-tile),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-map-shell .leaflet-tile) {
|
||||
html.light .root :global(.map .leaflet-tile),
|
||||
html.light .root :global(.scan-terminal.light .scan-map-shell .leaflet-tile) {
|
||||
filter: none !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-city-detail-rail),
|
||||
.root:global(.light) :global(.scan-terminal.light > .detail-panel.scan-city-detail-rail) {
|
||||
background:
|
||||
linear-gradient(180deg, rgba(238, 247, 255, 0.98), rgba(255, 255, 255, 0.96)) !important;
|
||||
border-color: rgba(37, 99, 235, 0.16) !important;
|
||||
color: #0f172a !important;
|
||||
/* ── City detail rail light overrides ── */
|
||||
html.light .root :global(.scan-city-detail-rail),
|
||||
html.light .root :global(.scan-terminal.light > .detail-panel.scan-city-detail-rail) {
|
||||
background: linear-gradient(180deg, rgba(238, 247, 255, 0.98), rgba(255, 255, 255, 0.96));
|
||||
border-color: rgba(37, 99, 235, 0.16);
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-header),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-structured-section),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-summary-shell),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-card) {
|
||||
background: rgba(255, 255, 255, 0.74) !important;
|
||||
border-color: rgba(125, 171, 214, 0.28) !important;
|
||||
html.light .root :global(.scan-city-detail-rail .panel-header),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-structured-section),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-summary-shell),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-card) {
|
||||
background: rgba(255, 255, 255, 0.74);
|
||||
border-color: rgba(125, 171, 214, 0.28);
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-city-detail-rail h2),
|
||||
.root:global(.light) :global(.scan-city-detail-rail h3),
|
||||
.root:global(.light) :global(.scan-city-detail-rail strong),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-value),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-summary-temp),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-section-head h3),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-title-area h2) {
|
||||
color: #0f172a !important;
|
||||
html.light .root :global(.scan-city-detail-rail h2),
|
||||
html.light .root :global(.scan-city-detail-rail h3),
|
||||
html.light .root :global(.scan-city-detail-rail strong),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-value),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-summary-temp),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-section-head h3),
|
||||
html.light .root :global(.scan-city-detail-rail .panel-title-area h2) {
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-city-detail-rail p),
|
||||
.root:global(.light) :global(.scan-city-detail-rail li),
|
||||
.root:global(.light) :global(.scan-city-detail-rail small),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-overline),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-loading-hint),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-meta-chip),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-section-kicker),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-label),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-value-muted),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-source-note),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-source-kind),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-mini-meta),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-summary-supporting),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .scan-detail-city-sub),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .scan-detail-volume-caption),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .scan-detail-score-label),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .scan-detail-empty) {
|
||||
color: #334155 !important;
|
||||
html.light .root :global(.scan-city-detail-rail p),
|
||||
html.light .root :global(.scan-city-detail-rail li),
|
||||
html.light .root :global(.scan-city-detail-rail small),
|
||||
html.light .root :global(.scan-city-detail-rail .panel-overline),
|
||||
html.light .root :global(.scan-city-detail-rail .panel-loading-hint),
|
||||
html.light .root :global(.scan-city-detail-rail .panel-meta-chip),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-section-kicker),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-label),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-value-muted),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-source-note),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-source-kind),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-mini-meta),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-summary-supporting),
|
||||
html.light .root :global(.scan-city-detail-rail .scan-detail-city-sub),
|
||||
html.light .root :global(.scan-city-detail-rail .scan-detail-volume-caption),
|
||||
html.light .root :global(.scan-city-detail-rail .scan-detail-score-label),
|
||||
html.light .root :global(.scan-city-detail-rail .scan-detail-empty) {
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-meta-chip),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-weather-chip),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .detail-source-link),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-action-button-secondary),
|
||||
.root:global(.light) :global(.scan-city-detail-rail .panel-action-button-ghost) {
|
||||
background: #eef7ff !important;
|
||||
border-color: rgba(37, 99, 235, 0.18) !important;
|
||||
color: #1f3654 !important;
|
||||
html.light .root :global(.scan-city-detail-rail .panel-meta-chip),
|
||||
html.light .root :global(.scan-city-detail-rail .panel-weather-chip),
|
||||
html.light .root :global(.scan-city-detail-rail .detail-source-link),
|
||||
html.light .root :global(.scan-city-detail-rail .panel-action-button-secondary),
|
||||
html.light .root :global(.scan-city-detail-rail .panel-action-button-ghost) {
|
||||
background: #eef7ff;
|
||||
border-color: rgba(37, 99, 235, 0.18);
|
||||
color: #1f3654;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-card),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-section),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-decision-band),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-market-decision),
|
||||
.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;
|
||||
/* ── AI city card light overrides ── */
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-card),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-section),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-decision-band),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-market-decision),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-decision-metrics span),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-pills span),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-freshness span),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-metrics > span),
|
||||
html.light .root :global(.scan-terminal.light .scan-mobile-decision-metrics span),
|
||||
html.light .root :global(.scan-terminal.light .scan-mobile-decision-reason) {
|
||||
background: #eef7ff;
|
||||
border-color: rgba(37, 99, 235, 0.16);
|
||||
}
|
||||
|
||||
.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;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-metrics > span.primary) {
|
||||
background: #dbeafe;
|
||||
border-color: rgba(59, 130, 246, 0.34);
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-metrics b) {
|
||||
color: #0f172a !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-metrics b) {
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-metrics > span.primary b) {
|
||||
color: #1d4ed8 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-metrics > span.primary b) {
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-metrics small) {
|
||||
color: #64748b !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-metrics small) {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.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),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-card span:not(.scan-ai-city-kicker)) {
|
||||
color: #334155 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-card p),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-card li),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-card small),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-card span:not(.scan-ai-city-kicker)) {
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-status-tag.green) {
|
||||
color: #047857 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-status-tag.green) {
|
||||
color: #047857;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-status-tag.blue) {
|
||||
color: #1d4ed8 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-status-tag.blue) {
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-status-tag.amber) {
|
||||
color: #b45309 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-status-tag.amber) {
|
||||
color: #b45309;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-status-tag.red) {
|
||||
color: #b91c1c !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-status-tag.red) {
|
||||
color: #b91c1c;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-upgrade-announcement) {
|
||||
/* ── Upgrade announcement light overrides ── */
|
||||
html.light .root :global(.scan-terminal.light .scan-upgrade-announcement) {
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(37, 99, 235, 0.12), transparent 36%),
|
||||
#ffffff !important;
|
||||
border-color: rgba(37, 99, 235, 0.16) !important;
|
||||
box-shadow: 0 16px 36px rgba(61, 100, 145, 0.12) !important;
|
||||
#ffffff;
|
||||
border-color: rgba(37, 99, 235, 0.16);
|
||||
box-shadow: 0 16px 36px rgba(61, 100, 145, 0.12);
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-upgrade-announcement-copy strong),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-mobile-priority b),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-mobile-decision-metrics b),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-mobile-decision-reason),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-mobile-decision-head h3),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-market-mobile-line b) {
|
||||
color: #0f172a !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-upgrade-announcement-copy strong),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-mobile-priority b),
|
||||
html.light .root :global(.scan-terminal.light .scan-mobile-decision-metrics b),
|
||||
html.light .root :global(.scan-terminal.light .scan-mobile-decision-reason),
|
||||
html.light .root :global(.scan-terminal.light .scan-mobile-decision-head h3),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-market-mobile-line b) {
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-upgrade-announcement-copy p),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-upgrade-announcement li),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-mobile-priority small),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-mobile-decision-metrics small),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-market-mobile-line span) {
|
||||
color: #334155 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-upgrade-announcement-copy p),
|
||||
html.light .root :global(.scan-terminal.light .scan-upgrade-announcement li),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-mobile-priority small),
|
||||
html.light .root :global(.scan-terminal.light .scan-mobile-decision-metrics small),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-market-mobile-line span) {
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-upgrade-announcement-copy span) {
|
||||
color: #047857 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-upgrade-announcement-copy span) {
|
||||
color: #047857;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-upgrade-announcement li),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-mobile-priority span),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-decision-why),
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-market-mobile-line) {
|
||||
background: #eef7ff !important;
|
||||
border-color: rgba(37, 99, 235, 0.16) !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-upgrade-announcement li),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-mobile-priority span),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-decision-why),
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-market-mobile-line) {
|
||||
background: #eef7ff;
|
||||
border-color: rgba(37, 99, 235, 0.16);
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-decision-why) {
|
||||
color: #1d4ed8 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-decision-why) {
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
/* ── Section titles (Evidence, Model, etc.) ── */
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-section-title) {
|
||||
color: #1d4ed8 !important;
|
||||
/* ── Section titles ── */
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-section-title) {
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-decision-band span) {
|
||||
color: #1d4ed8 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-decision-band span) {
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-decision-band p) {
|
||||
color: #475569 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-decision-band p) {
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-decision-band strong) {
|
||||
color: #0f172a !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-decision-band strong) {
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-city-body) {
|
||||
/* ── Scrollbar light overrides ── */
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-city-body) {
|
||||
scrollbar-color: rgba(37, 99, 235, 0.18) transparent;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-ai-city-body::-webkit-scrollbar-thumb) {
|
||||
background: rgba(37, 99, 235, 0.22) !important;
|
||||
html.light .root :global(.scan-ai-city-body::-webkit-scrollbar-thumb) {
|
||||
background: rgba(37, 99, 235, 0.22);
|
||||
}
|
||||
|
||||
/* ── AI prediction dual-card light mode ── */
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-dual) {
|
||||
gap: 10px;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card) {
|
||||
background: #ffffff;
|
||||
border-color: #e2e8f0;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card) {
|
||||
background: #ffffff !important;
|
||||
border-color: #e2e8f0 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card.ai) {
|
||||
background: linear-gradient(180deg, rgba(219, 234, 254, 0.52), #ffffff);
|
||||
border-color: rgba(14, 165, 233, 0.28);
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card.ai) {
|
||||
background: linear-gradient(180deg, rgba(219, 234, 254, 0.52), #ffffff) !important;
|
||||
border-color: rgba(14, 165, 233, 0.28) !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card.deb) {
|
||||
background: #ffffff;
|
||||
border-color: #e2e8f0;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card.deb) {
|
||||
background: #ffffff !important;
|
||||
border-color: #e2e8f0 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card small) {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card small) {
|
||||
color: #64748b !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card strong) {
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card strong) {
|
||||
color: #0f172a !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card.ai strong) {
|
||||
color: #0369a1;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card.ai strong) {
|
||||
color: #0369a1 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card em) {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card em) {
|
||||
color: #64748b !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card.ai.pending) {
|
||||
background: rgba(219, 234, 254, 0.28);
|
||||
border-color: rgba(14, 165, 233, 0.16);
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card.ai.pending) {
|
||||
background: rgba(219, 234, 254, 0.28) !important;
|
||||
border-color: rgba(14, 165, 233, 0.16) !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-prediction-card.ai.pending strong) {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-prediction-card.ai.pending strong) {
|
||||
color: #94a3b8 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-confidence) {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-confidence) {
|
||||
background: rgba(59, 130, 246, 0.1) !important;
|
||||
color: #2563eb !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-confidence.high) {
|
||||
background: rgba(16, 185, 129, 0.12);
|
||||
color: #047857;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-confidence.high) {
|
||||
background: rgba(16, 185, 129, 0.12) !important;
|
||||
color: #047857 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-confidence.medium) {
|
||||
background: rgba(245, 158, 11, 0.12);
|
||||
color: #b45309;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-confidence.medium) {
|
||||
background: rgba(245, 158, 11, 0.12) !important;
|
||||
color: #b45309 !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-confidence.low) {
|
||||
background: rgba(148, 163, 184, 0.12);
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-confidence.low) {
|
||||
background: rgba(148, 163, 184, 0.12) !important;
|
||||
color: #64748b !important;
|
||||
html.light .root :global(.scan-terminal.light .scan-ai-confidence.neutral) {
|
||||
background: rgba(148, 163, 184, 0.08);
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.root:global(.light) :global(.scan-terminal.light .scan-ai-confidence.neutral) {
|
||||
background: rgba(148, 163, 184, 0.08) !important;
|
||||
color: #64748b !important;
|
||||
/* ── Empty / Error / Retry light overrides ── */
|
||||
html.light .root :global(.scan-terminal.light .scan-empty-title),
|
||||
html.light .root :global(.scan-terminal.light .scan-error-title) {
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
html.light .root :global(.scan-terminal.light .scan-empty-copy),
|
||||
html.light .root :global(.scan-terminal.light .scan-error-copy) {
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
html.light .root :global(.scan-terminal.light .scan-empty-icon) {
|
||||
background: rgba(37, 99, 235, 0.08);
|
||||
border-color: rgba(37, 99, 235, 0.2);
|
||||
color: #2563EB;
|
||||
}
|
||||
|
||||
html.light .root :global(.scan-terminal.light .scan-error-icon) {
|
||||
background: rgba(239, 68, 68, 0.06);
|
||||
border-color: rgba(239, 68, 68, 0.18);
|
||||
color: #DC2626;
|
||||
}
|
||||
|
||||
html.light .root :global(.scan-terminal.light .scan-retry-button) {
|
||||
background: rgba(37, 99, 235, 0.08);
|
||||
border-color: rgba(37, 99, 235, 0.24);
|
||||
color: #2563EB;
|
||||
}
|
||||
|
||||
html.light .root :global(.scan-terminal.light .scan-retry-button:hover) {
|
||||
background: rgba(37, 99, 235, 0.14);
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
|
||||
.root :global(.scan-v4-decision p b) {
|
||||
color: #ecfeff;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.root :global(.scan-v4-metar-summary) {
|
||||
@@ -263,9 +263,9 @@
|
||||
.root :global(.scan-v4-heading strong),
|
||||
.root :global(.scan-v4-current b),
|
||||
.root :global(.scan-v4-brief-grid strong) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@
|
||||
background: rgba(20, 184, 166, 0.12);
|
||||
color: #7dfbe7;
|
||||
font-size: 12px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@
|
||||
.root :global(.scan-v4-current span) {
|
||||
color: #c8d8ec;
|
||||
font-size: 13px;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 999px;
|
||||
background: #4DA3FF;
|
||||
background: var(--color-accent-primary);
|
||||
box-shadow: 0 0 10px rgba(45, 212, 191, 0.45);
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@
|
||||
background: rgba(10, 30, 58, 0.52);
|
||||
color: #8fbdff;
|
||||
font-size: 12px;
|
||||
font-weight: 950;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
}
|
||||
@@ -425,7 +425,7 @@
|
||||
scroll-padding-top: 64px;
|
||||
border: 1px solid rgba(77, 163, 255, 0.16);
|
||||
border-radius: 18px;
|
||||
background: #0b1220;
|
||||
background: var(--color-bg-base);
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
@@ -454,7 +454,7 @@
|
||||
|
||||
.root :global(.scan-ai-workspace-head span) {
|
||||
display: block;
|
||||
color: #4da3ff;
|
||||
color: var(--color-accent-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0;
|
||||
@@ -462,7 +462,7 @@
|
||||
|
||||
.root :global(.scan-ai-workspace-head strong) {
|
||||
display: block;
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 20px;
|
||||
line-height: 1.2;
|
||||
margin-top: 4px;
|
||||
@@ -471,7 +471,7 @@
|
||||
.root :global(.scan-ai-workspace-head p) {
|
||||
max-width: 560px;
|
||||
margin: 0;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.55;
|
||||
text-align: right;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
.root :global(.scan-mobile-decision-head h3) {
|
||||
margin: 6px 0 0;
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 24px;
|
||||
line-height: 1.08;
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-mobile-decision-metrics small) {
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 10px;
|
||||
font-weight: 900;
|
||||
}
|
||||
@@ -121,7 +121,7 @@
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1480px) {
|
||||
@media (max-width: 1440px) {
|
||||
.root :global(.scan-terminal) {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
@@ -141,7 +141,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
@media (max-width: 1024px) {
|
||||
.root :global(.scan-terminal) {
|
||||
grid-template-columns: 1fr;
|
||||
min-height: 100dvh;
|
||||
@@ -281,7 +281,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
@media (max-width: 768px) {
|
||||
.root :global(.scan-terminal) {
|
||||
padding: 10px;
|
||||
}
|
||||
@@ -354,7 +354,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-city-mobile-priority small) {
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 10px;
|
||||
font-weight: 900;
|
||||
}
|
||||
@@ -394,13 +394,13 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-market-mobile-line span) {
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.root :global(.scan-ai-market-mobile-line b) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 13px;
|
||||
text-align: right;
|
||||
}
|
||||
@@ -475,7 +475,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
@media (max-width: 640px) {
|
||||
.root :global(.scan-terminal) {
|
||||
box-sizing: border-box;
|
||||
max-width: 100vw;
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
background: rgba(0, 224, 164, 0.12);
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.rank-amber .scan-rank-circle) {
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
.root :global(.rank-purple .scan-rank-circle) {
|
||||
background: rgba(123, 97, 255, 0.12);
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.rank-neutral .scan-rank-circle) {
|
||||
@@ -168,7 +168,7 @@
|
||||
|
||||
.root :global(.scan-status-badge.tone-green) {
|
||||
background: rgba(0, 224, 164, 0.12);
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.scan-status-badge.tone-amber) {
|
||||
@@ -178,7 +178,7 @@
|
||||
|
||||
.root :global(.scan-status-badge.tone-purple) {
|
||||
background: rgba(123, 97, 255, 0.12);
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.scan-status-badge.tone-neutral) {
|
||||
@@ -233,7 +233,7 @@
|
||||
.root :global(.scan-action-text) {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-edge-value.positive) {
|
||||
color: #4DA3FF;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.root :global(.scan-edge-value.neutral) {
|
||||
@@ -447,7 +447,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-opportunity-item.ai-veto .scan-opportunity-action) {
|
||||
color: #9FB2C7;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.root :global(.scan-opportunity-branch) {
|
||||
@@ -702,7 +702,7 @@
|
||||
|
||||
.root :global(.scan-v4-analysis strong) {
|
||||
display: block;
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.02em;
|
||||
@@ -892,11 +892,11 @@
|
||||
align-content: center;
|
||||
gap: 12px;
|
||||
text-align: center;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.root :global(.scan-opportunity-overview.empty strong) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
@@ -926,7 +926,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-opportunity-hero span) {
|
||||
color: #4da3ff;
|
||||
color: var(--color-accent-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
}
|
||||
@@ -934,7 +934,7 @@
|
||||
.root :global(.scan-opportunity-hero strong) {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 26px;
|
||||
line-height: 1.15;
|
||||
}
|
||||
@@ -942,7 +942,7 @@
|
||||
.root :global(.scan-opportunity-hero p) {
|
||||
max-width: 680px;
|
||||
margin: 9px 0 0;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
@@ -959,12 +959,12 @@
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 14px;
|
||||
background: rgba(13, 17, 23, 0.52);
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.root :global(.scan-opportunity-summary b) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@@ -990,13 +990,13 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-opportunity-lane-head strong) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.root :global(.scan-opportunity-lane-head p) {
|
||||
margin: 3px 0 0;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@@ -1060,7 +1060,7 @@
|
||||
.root :global(.scan-opportunity-decision-head span),
|
||||
.root :global(.scan-opportunity-decision-primary span),
|
||||
.root :global(.scan-opportunity-decision-foot small) {
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
}
|
||||
@@ -1068,7 +1068,7 @@
|
||||
.root :global(.scan-opportunity-decision-head strong) {
|
||||
display: block;
|
||||
margin-top: 3px;
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@@ -1108,7 +1108,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-opportunity-decision-primary b) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
/* Scan terminal shell, topbar, upgrade announcement, and shared action buttons.
|
||||
Extracted from ScanTerminal.module.css to keep terminal layout CSS maintainable. */
|
||||
|
||||
/* ── Button Hierarchy ──
|
||||
Primary: .scan-primary-button — filled gradient, main CTA
|
||||
Secondary: .scan-ai-button — tinted background, alternative action
|
||||
Ghost: .scan-theme-button — no border/background, icon-only
|
||||
Chrome: .scan-account-button — bordered icon, navigation
|
||||
Chrome: .scan-locale-switch — segmented control
|
||||
Chrome: .scan-ghost-button — bordered + bg, utility action
|
||||
────────────────────────────────────────────── */
|
||||
|
||||
.root :global(.scan-topbar) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -10,6 +19,32 @@
|
||||
border-bottom: 1px solid rgba(118, 146, 188, 0.1);
|
||||
}
|
||||
|
||||
.root :global(.scan-topbar-brand) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.root :global(.scan-topbar-logo) {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(135deg, var(--color-accent-primary), #22C55E);
|
||||
box-shadow: 0 4px 12px rgba(77, 163, 255, 0.28);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.root :global(.scan-topbar-logo::after) {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 3px;
|
||||
border-radius: 6px;
|
||||
background:
|
||||
radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.6), transparent 60%);
|
||||
}
|
||||
|
||||
.root :global(.scan-topbar-title) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -135,7 +170,7 @@
|
||||
background: rgba(77, 163, 255, 0.1);
|
||||
color: #d7e5f7;
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
font-weight: 800;
|
||||
padding: 7px 10px;
|
||||
}
|
||||
|
||||
@@ -168,7 +203,7 @@
|
||||
padding: 11px 16px;
|
||||
border: 1px solid rgba(77, 163, 255, 0.42);
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(180deg, #4DA3FF, #3B82F6);
|
||||
background: linear-gradient(180deg, var(--color-accent-primary), #3B82F6);
|
||||
color: #FFFFFF;
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
@@ -212,7 +247,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-cta-ghost) {
|
||||
color: #6FB7FF;
|
||||
color: var(--color-accent-secondary);
|
||||
border-color: rgba(23, 217, 139, 0.3);
|
||||
background: rgba(23, 217, 139, 0.12);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Scan terminal empty, loading, and skeleton signal states. */
|
||||
/* Scan terminal empty, loading, error, and skeleton signal states. */
|
||||
|
||||
/* ── Empty state ── */
|
||||
.root :global(.scan-empty-state) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
@@ -8,6 +9,20 @@
|
||||
align-items: center;
|
||||
padding: 48px 32px;
|
||||
text-align: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.root :global(.scan-empty-icon) {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 14px;
|
||||
background: rgba(77, 163, 255, 0.1);
|
||||
border: 1px solid rgba(77, 163, 255, 0.16);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: var(--color-accent-secondary);
|
||||
font-size: 20px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.root :global(.scan-empty-title) {
|
||||
@@ -17,12 +32,71 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-empty-copy) {
|
||||
margin-top: 10px;
|
||||
max-width: 360px;
|
||||
font-size: 14px;
|
||||
color: #8fa4c3;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ── Error state ── */
|
||||
.root :global(.scan-error-state) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 48px 32px;
|
||||
text-align: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.root :global(.scan-error-icon) {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 14px;
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #FCA5A5;
|
||||
font-size: 20px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.root :global(.scan-error-title) {
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
color: #e8f2ff;
|
||||
}
|
||||
|
||||
.root :global(.scan-error-copy) {
|
||||
max-width: 360px;
|
||||
font-size: 14px;
|
||||
color: #8fa4c3;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.root :global(.scan-retry-button) {
|
||||
margin-top: 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-height: 40px;
|
||||
padding: 10px 16px;
|
||||
border: 1px solid rgba(77, 163, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
background: rgba(77, 163, 255, 0.12);
|
||||
color: #9ecbff;
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.root :global(.scan-retry-button:hover) {
|
||||
background: rgba(77, 163, 255, 0.18);
|
||||
border-color: rgba(111, 183, 255, 0.48);
|
||||
}
|
||||
|
||||
.root :global(.scan-loading-state) {
|
||||
flex: 1;
|
||||
min-height: 520px;
|
||||
@@ -101,7 +175,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-loading-node.market) {
|
||||
background: linear-gradient(135deg, #38bdf8, #4da3ff);
|
||||
background: linear-gradient(135deg, #38bdf8, var(--color-accent-primary));
|
||||
box-shadow: 0 0 24px rgba(56, 189, 248, 0.26);
|
||||
}
|
||||
|
||||
@@ -141,7 +215,7 @@
|
||||
}
|
||||
|
||||
.root :global(.scan-loading-copy-block strong) {
|
||||
color: #e6edf3;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 18px;
|
||||
font-weight: 900;
|
||||
letter-spacing: -0.02em;
|
||||
@@ -149,9 +223,9 @@
|
||||
|
||||
.root :global(.scan-loading-copy-block span) {
|
||||
max-width: 320px;
|
||||
color: #9fb2c7;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 650;
|
||||
font-weight: 600;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
@@ -168,7 +242,7 @@
|
||||
width: 7px;
|
||||
min-height: 8px;
|
||||
border-radius: 999px 999px 4px 4px;
|
||||
background: linear-gradient(180deg, #7dd3fc, #4da3ff 52%, #1be392);
|
||||
background: linear-gradient(180deg, #7dd3fc, var(--color-accent-primary) 52%, #1be392);
|
||||
opacity: 0.42;
|
||||
transform-origin: center bottom;
|
||||
animation: scan-loading-bars 1.35s ease-in-out infinite;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Barrel: pre-combined scan-terminal root class name.
|
||||
Consolidates 22 CSS Modules that are always co-imported into
|
||||
a single className, keeping ScanTerminalDashboard.tsx lean. */
|
||||
|
||||
import clsx from "clsx";
|
||||
|
||||
import dashboardHomeStyles from "./DashboardHomeIntelligence.module.css";
|
||||
import dashboardMapStyles from "./DashboardMap.module.css";
|
||||
import dashboardModalGuideStyles from "./DashboardModalGuide.module.css";
|
||||
import dashboardShellStyles from "./DashboardShell.module.css";
|
||||
import detailChromeStyles from "./DetailPanelChrome.module.css";
|
||||
import detailContentStyles from "./DetailPanelContent.module.css";
|
||||
import detailSectionsStyles from "./DetailPanelSections.module.css";
|
||||
import futureForecastModalStyles from "./FutureForecastModal.module.css";
|
||||
import historyModalStyles from "./HistoryModal.module.css";
|
||||
import modalChromeStyles from "./ModalChrome.module.css";
|
||||
import scanTerminalStyles from "./ScanTerminal.module.css";
|
||||
import scanTerminalBoardStyles from "./ScanTerminalBoard.module.css";
|
||||
import scanTerminalCalendarStyles from "./ScanTerminalCalendar.module.css";
|
||||
import scanTerminalCardStyles from "./ScanTerminalCard.module.css";
|
||||
import scanTerminalDetailStyles from "./ScanTerminalDetail.module.css";
|
||||
import scanTerminalFiltersStyles from "./ScanTerminalFilters.module.css";
|
||||
import scanTerminalLightThemeStyles from "./ScanTerminalLightTheme.module.css";
|
||||
import scanTerminalListStyles from "./ScanTerminalList.module.css";
|
||||
import scanTerminalMobileStyles from "./ScanTerminalMobile.module.css";
|
||||
import scanTerminalOpportunityStyles from "./ScanTerminalOpportunity.module.css";
|
||||
import scanTerminalShellStyles from "./ScanTerminalShell.module.css";
|
||||
import scanTerminalStateStyles from "./ScanTerminalState.module.css";
|
||||
|
||||
export const scanRootClass = clsx(
|
||||
dashboardHomeStyles.root,
|
||||
dashboardMapStyles.root,
|
||||
dashboardShellStyles.root,
|
||||
dashboardModalGuideStyles.root,
|
||||
scanTerminalStyles.root,
|
||||
scanTerminalShellStyles.root,
|
||||
scanTerminalFiltersStyles.root,
|
||||
scanTerminalListStyles.root,
|
||||
scanTerminalBoardStyles.root,
|
||||
scanTerminalDetailStyles.root,
|
||||
scanTerminalStateStyles.root,
|
||||
scanTerminalOpportunityStyles.root,
|
||||
scanTerminalCardStyles.root,
|
||||
scanTerminalCalendarStyles.root,
|
||||
scanTerminalMobileStyles.root,
|
||||
scanTerminalLightThemeStyles.root,
|
||||
detailChromeStyles.root,
|
||||
detailContentStyles.root,
|
||||
detailSectionsStyles.root,
|
||||
modalChromeStyles.root,
|
||||
futureForecastModalStyles.root,
|
||||
historyModalStyles.root,
|
||||
);
|
||||
@@ -542,6 +542,7 @@ export function AiPinnedCityCard({
|
||||
collapsed && !isCompactCard && "collapsed",
|
||||
removing && "removing",
|
||||
)}
|
||||
tabIndex={-1}
|
||||
data-ai-status={decisionState.aiStatus}
|
||||
data-evidence-quality={decisionState.evidenceQuality}
|
||||
data-market-status={decisionState.marketStatus}
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
.sectionTitle {
|
||||
margin: 0 0 16px;
|
||||
font-size: 1.65rem;
|
||||
font-weight: 750;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.paragraph {
|
||||
@@ -283,7 +283,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
@media (max-width: 960px) {
|
||||
.docsHeader {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user