diff --git a/config/architecture-inventory.json b/config/architecture-inventory.json index f0eaaf4..e75cbda 100644 --- a/config/architecture-inventory.json +++ b/config/architecture-inventory.json @@ -370,19 +370,19 @@ } ], "css_layers": [ - "/shared/tokens.css?v=20260818-2", + "/shared/tokens.css?v=20260820-1", "/shared/base.css?v=20260806-1", - "/shared/shell.css?v=20260818-3", + "/shared/shell.css?v=20260820-1", "/shared/auth.css?v=20260806-1", - "/shared/components/controls.css?v=20260806-1", - "/shared/components/navigation.css?v=20260806-1", - "/shared/components/cards.css?v=20260806-1", - "/shared/components/tables.css?v=20260806-1", + "/shared/components/controls.css?v=20260820-1", + "/shared/components/navigation.css?v=20260820-1", + "/shared/components/cards.css?v=20260820-1", + "/shared/components/tables.css?v=20260820-1", "/shared/components/dialogs.css?v=20260806-1", "/shared/components/feedback.css?v=20260806-1", "/pages/market/foundation.css?v=20260806-1", - "/pages/sentiment/foundation.css?v=20260806-2", - "/pages/pools/foundation.css?v=20260806-2", + "/pages/sentiment/foundation.css?v=20260820-1", + "/pages/pools/foundation.css?v=20260820-1", "/pages/ladder/foundation.css?v=20260806-1", "/pages/rotation/foundation.css?v=20260806-1", "/pages/auction/foundation.css?v=20260806-2", @@ -390,7 +390,7 @@ "/pages/popularity/foundation.css?v=20260806-1", "/pages/dragon-tiger/foundation.css?v=20260806-1", "/pages/screener/foundation.css?v=20260806-2", - "/pages/mentor/foundation.css?v=20260818-3", + "/pages/mentor/foundation.css?v=20260820-1", "/pages/heaven/foundation.css?v=20260806-2", "/pages/review/foundation.css?v=20260806-1" ], @@ -451,8 +451,8 @@ }, { "path": "frontend/shared/shell.css", - "bytes": 52879, - "lines": 3274 + "bytes": 60932, + "lines": 3677 }, { "path": "backend/features/heaven/engine.py", @@ -461,8 +461,8 @@ }, { "path": "frontend/index.html", - "bytes": 46058, - "lines": 647 + "bytes": 46449, + "lines": 642 }, { "path": "backend/features/screener/catalog.py", @@ -531,7 +531,7 @@ }, { "path": "frontend/pages/pools/page.html", - "bytes": 14958, + "bytes": 14942, "lines": 235 }, { @@ -541,8 +541,8 @@ }, { "path": "frontend/shared/admin.js", - "bytes": 14556, - "lines": 270 + "bytes": 14145, + "lines": 261 }, { "path": "backend/features/heaven/market_context.py", @@ -561,13 +561,13 @@ }, { "path": "backend/features/system/service.py", - "bytes": 12812, - "lines": 262 + "bytes": 12392, + "lines": 254 }, { "path": "backend/features/market/insights_auction.py", - "bytes": 11618, - "lines": 243 + "bytes": 10717, + "lines": 221 }, { "path": "backend/features/heaven/readings.py", @@ -584,6 +584,11 @@ "bytes": 9348, "lines": 222 }, + { + "path": "frontend/shared/dashboard.js", + "bytes": 9323, + "lines": 210 + }, { "path": "frontend/pages/market/entity-detail.js", "bytes": 9119, @@ -599,26 +604,21 @@ "bytes": 8562, "lines": 238 }, - { - "path": "frontend/shared/dashboard.js", - "bytes": 8424, - "lines": 194 - }, { "path": "frontend/pages/mentor/page.html", "bytes": 8357, "lines": 116 }, - { - "path": "backend/data/providers/tushare_daily.py", - "bytes": 7121, - "lines": 167 - }, { "path": "backend/features/screener/formula.py", "bytes": 6983, "lines": 146 }, + { + "path": "backend/data/providers/tushare_daily.py", + "bytes": 6837, + "lines": 160 + }, { "path": "backend/application.py", "bytes": 6751, diff --git a/frontend/index.html b/frontend/index.html index 0d87ab4..e73cc4d 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -17,19 +17,19 @@ document.documentElement.style.colorScheme = theme; })(); - + - + - - - - + + + + - - + + @@ -37,7 +37,7 @@ - + @@ -72,12 +72,48 @@ 小白复盘 -
- 上涨 -- - 下跌 -- - 涨停 -- - 成交额 -- -
+
+
+
+ 市场情绪 + + -- + 等待数据 + + +
+
+ 涨停 + -- +
+
+ 跌停 + -- +
+
+ 炸板 + -- +
+
+ 封板率 + -- +
+
+ 两市成交 + -- +
+ +
+
+
上涨家数--
+
下跌家数--
+
涨停 / 跌停--
+
两市成交额--
+
数据日期--
+
+
@@ -173,47 +209,6 @@ -
-
-
-
- -- -
-
- 市场情绪 - 等待数据 -
-
-
- 涨停 - -- -
-
- 跌停 - -- -
-
- 炸板 - -- -
-
- 封板率 - -- -
-
- 两市成交 - -- -
-
- 数据日期 - -- -
- -
-
-
diff --git a/frontend/pages.config.js b/frontend/pages.config.js index 40a1200..010abf1 100644 --- a/frontend/pages.config.js +++ b/frontend/pages.config.js @@ -42,12 +42,12 @@ ]; const fragments = [ - ["pools", "/pages/pools/page.html?v=20260803-1", ["limitPool", "brokenView", "downView", "yesterdayView", "performanceView"]], + ["pools", "/pages/pools/page.html?v=20260820-1", ["limitPool", "brokenView", "downView", "yesterdayView", "performanceView"]], ["sentiment", "/pages/sentiment/page.html?v=20260803-1", ["sentimentCycleView"]], ["heaven", "/pages/heaven/page.html?v=20260803-1", ["heavenView"]], ["ladder", "/pages/ladder/page.html?v=20260803-1", ["ladderView"]], ["screener", "/pages/screener/page.html?v=20260804-1", ["screenerView", "screenerTrackingView"]], - ["mentor", "/pages/mentor/page.html?v=20260818-3", ["mentorView"]], + ["mentor", "/pages/mentor/page.html?v=20260820-1", ["mentorView"]], ["rotation", "/pages/rotation/page.html?v=20260803-1", ["rotationView"]], ["auction", "/pages/auction/page.html?v=20260803-1", ["auctionView"]], ["themes", "/pages/themes/page.html?v=20260803-1", ["themeLibraryView"]], @@ -66,7 +66,7 @@ "/shared/components.js?v=20260729-1", "/pages/runtime.js?v=20260729-1", "/pages/sentiment/page.js?v=20260729-1", - "/pages/pools/page.js?v=20260729-1", + "/pages/pools/page.js?v=20260820-1", "/pages/market/breadth.js?v=20260803-1", "/pages/market/charts.js?v=20260803-1", "/pages/market/entity-detail.js?v=20260803-1", @@ -81,12 +81,12 @@ "/pages/popularity/page.js?v=20260729-1", "/pages/dragon-tiger/page.js?v=20260806-1", "/pages/screener/page.js?v=20260806-1", - "/pages/mentor/page.js?v=20260818-3", + "/pages/mentor/page.js?v=20260820-1", "/pages/heaven/page.js?v=20260729-1", "/pages/review/page.js?v=20260729-1", "/shared/state.js?v=20260729-1", "/shared/api.js?v=20260729-1", - "/shared/shell.js?v=20260806-1", + "/shared/shell.js?v=20260820-1", "/shared/export.js?v=20260731-1", "/pages/heaven/loading-v2.js?v=20260728-2", "/shared/context.js?v=20260804-1", @@ -94,7 +94,7 @@ "/shared/application.js?v=20260803-1", "/shared/table.js?v=20260803-1", "/shared/theme.js?v=20260803-1", - "/shared/dashboard.js?v=20260803-1", + "/shared/dashboard.js?v=20260820-1", "/shared/session.js?v=20260803-1", "/shared/admin.js?v=20260803-1", "/app.js?v=20260803-2", diff --git a/frontend/pages/mentor/foundation.css b/frontend/pages/mentor/foundation.css index e626bb7..af78d9d 100644 --- a/frontend/pages/mentor/foundation.css +++ b/frontend/pages/mentor/foundation.css @@ -88,14 +88,7 @@ } #mentorView .mentor-page-header { - flex: 0 0 56px; - height: 56px; - min-height: 56px; - display: flex; - align-items: center; - padding: 0 20px; - border-bottom: 1px solid var(--qp-border); - background: var(--qp-bg-header); + display: none; } #mentorView .mentor-page-title { @@ -146,11 +139,14 @@ } #mentorView .mentor-directory-tools { + position: relative; + z-index: 30; flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-4); padding: 10px 8px; + overflow: visible; border-bottom: 1px solid var(--qp-border); } @@ -233,7 +229,7 @@ position: absolute; top: calc(100% + 4px); right: 0; - z-index: 20; + z-index: 40; min-width: 128px; display: flex; flex-direction: column; @@ -468,7 +464,7 @@ border-radius: 50%; background: var(--qp-avatar-bg); color: var(--qp-avatar-ink); - font-size: 16px; + font-size: 14px; font-weight: var(--font-weight-semibold); } @@ -490,7 +486,7 @@ min-width: 0; overflow: hidden; color: var(--qp-text-1); - font-size: 16px; + font-size: 14px; font-weight: var(--font-weight-semibold); text-overflow: ellipsis; white-space: nowrap; @@ -505,7 +501,7 @@ #mentorView :is(.mentor-option-copy > em, .mentor-option-meta) { min-width: 0; overflow: hidden; - font-size: 14px; + font-size: 11.5px; font-style: normal; line-height: 1.35; text-overflow: ellipsis; @@ -518,7 +514,7 @@ #mentorView .mentor-option-meta { color: var(--qp-text-3); - font-size: 13px; + font-size: 11.5px; } #mentorView .mentor-option-tools { @@ -646,10 +642,10 @@ } #mentorView .mentor-chat-identity .mentor-avatar { - width: 44px; - height: 44px; - flex: 0 0 44px; - font-size: 17px; + width: var(--mentor-chat-avatar-size); + height: var(--mentor-chat-avatar-size); + flex: 0 0 var(--mentor-chat-avatar-size); + font-size: 13.5px; } #mentorView .mentor-active-title { @@ -664,7 +660,7 @@ margin: 0; overflow: hidden; color: var(--qp-text-1); - font-size: 16px; + font-size: 14px; font-weight: var(--font-weight-semibold); letter-spacing: 0; text-overflow: ellipsis; @@ -674,7 +670,7 @@ #mentorView #activeMentorStatus { margin: 2px 0 0; color: var(--qp-text-3); - font-size: 13px; + font-size: 11.5px; line-height: 1.4; } @@ -783,9 +779,9 @@ } #mentorView .mentor-message-avatar { - width: var(--mentor-avatar-size); - height: var(--mentor-avatar-size); - flex: 0 0 var(--mentor-avatar-size); + width: var(--mentor-message-avatar-size); + height: var(--mentor-message-avatar-size); + flex: 0 0 var(--mentor-message-avatar-size); display: inline-flex; align-items: center; justify-content: center; @@ -793,7 +789,7 @@ border-radius: 50%; background: var(--qp-avatar-bg); color: var(--qp-avatar-ink); - font-size: 16px; + font-size: 12.5px; font-weight: var(--font-weight-semibold); } @@ -818,15 +814,15 @@ #mentorView .mentor-message-label { color: var(--qp-text-3); - font-size: 12px; + font-size: 11.5px; line-height: 1.4; } #mentorView .mentor-message-content { min-width: 0; color: var(--qp-text-1); - font-size: 16px; - line-height: 1.7; + font-size: 14px; + line-height: 1.65; overflow-wrap: anywhere; } @@ -835,6 +831,7 @@ border-radius: 12px; background: var(--qp-bg-bubble-self); color: var(--qp-text-1-on-accent-bg); + line-height: 1.6; } #mentorView .mentor-message.is-error .mentor-message-content { @@ -843,7 +840,7 @@ #mentorView .mentor-message small { color: var(--qp-text-3); - font-size: 12px; + font-size: 11.5px; } #mentorView .mentor-answer-paragraph { @@ -858,7 +855,7 @@ display: block; margin: var(--space-12) 0 var(--space-4); color: var(--qp-text-1); - font-size: 18px; + font-size: 14px; font-weight: var(--font-weight-semibold); line-height: 1.4; } @@ -882,6 +879,7 @@ padding-left: var(--space-12); border-left: 2px solid var(--qp-accent-soft); color: var(--qp-text-2); + font-size: 13.5px; } #mentorView .mentor-answer-rule { @@ -917,7 +915,7 @@ #mentorView .mentor-follow-ups > span { color: var(--qp-text-faint); - font-size: 12px; + font-size: 11.5px; } #mentorView .mentor-follow-ups button { @@ -929,7 +927,7 @@ border: 0; background: transparent; color: var(--qp-link); - font-size: 14px; + font-size: 13px; line-height: 1.8; text-align: left; cursor: pointer; @@ -963,7 +961,7 @@ #mentorView .mentor-prompt-label { flex: 0 0 auto; color: var(--qp-text-3); - font-size: 13px; + font-size: 11.5px; } #mentorView .mentor-quick-prompts button { @@ -976,7 +974,7 @@ border-radius: 8px; background: var(--qp-bg-control); color: var(--qp-text-2); - font-size: 14px; + font-size: 13px; cursor: pointer; transition: color var(--motion-fast), background var(--motion-fast); } @@ -1038,8 +1036,8 @@ background: transparent; color: var(--qp-text-1); font-family: inherit; - font-size: 16px; - line-height: 1.7; + font-size: 14px; + line-height: 1.55; } #mentorView #mentorQuestion::placeholder { @@ -1049,7 +1047,7 @@ #mentorView .mentor-composer-hint { flex: 0 0 auto; color: var(--qp-text-hint); - font-size: 12px; + font-size: 11.5px; line-height: 1.4; } @@ -1070,7 +1068,7 @@ border-radius: 10px; background: var(--qp-accent); color: #FFFFFF; - font-size: 14px; + font-size: 13px; font-weight: var(--font-weight-medium); } @@ -1117,7 +1115,7 @@ margin: 0; padding: 0 16px; color: var(--qp-text-hint); - font-size: 12px; + font-size: 11.5px; line-height: 1.4; text-align: center; overflow-wrap: anywhere; diff --git a/frontend/pages/mentor/page.js b/frontend/pages/mentor/page.js index da3e2fb..161ffbb 100644 --- a/frontend/pages/mentor/page.js +++ b/frontend/pages/mentor/page.js @@ -67,6 +67,7 @@ function renderMentorWorkspace() { if (!setup) return; const selected = setup.mentors.find((item) => item.id === state.selectedMentorId) || null; setText("mentorPageSubtitle", `与不同交易思维模型持续对话 · 数据日期 ${displayCompactDate(setup.trade_date)}`); + setText("currentPageSubtitle", `与不同交易思维模型持续对话 · 数据日期 ${displayCompactDate(setup.trade_date)}`); setText("activeMentorName", selected?.name || "--"); setText("activeMentorAvatar", mentorAvatarText(selected)); applyMentorAvatarTone(document.querySelector("#activeMentorAvatar"), mentorAvatarToneClass(selected)); @@ -643,7 +644,10 @@ function bindMentorEvents() { document.querySelector("#stopMentorQuestion").addEventListener("click", stopMentorGeneration); document.querySelector("#clearMentorChatButton").addEventListener("click", clearMentorConversation); document.querySelector("#mentorSortToggle").addEventListener("click", toggleMentorSortMode); - document.querySelector("#mentorFilterToggle").addEventListener("click", toggleMentorFilterMenu); + document.querySelector("#mentorFilterToggle").addEventListener("click", (event) => { + event.stopPropagation(); + toggleMentorFilterMenu(); + }); document.querySelector("#mentorSearchInput").addEventListener("input", (event) => { state.mentorQuery = event.target.value.trim().toLocaleLowerCase("zh-CN"); renderMentorDirectory(); diff --git a/frontend/pages/pools/foundation.css b/frontend/pages/pools/foundation.css index 6088a82..9903ebb 100644 --- a/frontend/pages/pools/foundation.css +++ b/frontend/pages/pools/foundation.css @@ -78,7 +78,7 @@ color: var(--r2-faint); - text-align: right; + text-align: left; } .redesigned-pool-view .data-table .number { @@ -207,7 +207,7 @@ color: var(--r2-faint); - text-align: right; + text-align: left; } .redesigned-broken-view .data-table .number { @@ -335,7 +335,7 @@ color: var(--r2-faint); - text-align: right; + text-align: left; } .redesigned-down-view .data-table .number { @@ -455,7 +455,7 @@ color: var(--r2-faint); - text-align: right; + text-align: left; } .redesigned-yesterday-view .data-table .number { @@ -2235,9 +2235,9 @@ :is(#limitTable, #brokenTable, #downTable, #yesterdayTable) .row-number { padding-right: 8px; - padding-left: 8px; + padding-left: 12px; - text-align: center; + text-align: left; } :is(#limitTable, #brokenTable, #downTable, #yesterdayTable) .reason-column { diff --git a/frontend/pages/pools/page.html b/frontend/pages/pools/page.html index 47bb871..1ea17c1 100644 --- a/frontend/pages/pools/page.html +++ b/frontend/pages/pools/page.html @@ -26,7 +26,7 @@ - + @@ -83,7 +83,7 @@
序号序号 股票 连板 涨幅(%)
- + @@ -122,7 +122,7 @@
序号序号 股票 现价涨幅(%) 距涨停(%)
- + @@ -176,7 +176,7 @@
序号序号 股票 跌幅(%) 价格(元)
- + diff --git a/frontend/pages/pools/page.js b/frontend/pages/pools/page.js index a1e0e9d..85d96b1 100644 --- a/frontend/pages/pools/page.js +++ b/frontend/pages/pools/page.js @@ -28,7 +28,7 @@ function renderLimitTable() { const body = document.querySelector("#limitTableBody"); body.innerHTML = rows.map((row, index) => ` - + @@ -75,7 +75,7 @@ function renderBrokenTable(rows) { const body = document.querySelector("#brokenTableBody"); body.innerHTML = visibleRows.map((row, index) => ` - + @@ -155,7 +155,7 @@ function renderDownTable(rows) { const body = document.querySelector("#downTableBody"); body.innerHTML = visibleRows.map((row, index) => ` - + @@ -228,7 +228,7 @@ function renderYesterdayTable(rows) { const body = document.querySelector("#yesterdayTableBody"); body.innerHTML = visibleRows.map((row, index) => ` - + diff --git a/frontend/pages/sentiment/foundation.css b/frontend/pages/sentiment/foundation.css index e7a9642..6e76e04 100644 --- a/frontend/pages/sentiment/foundation.css +++ b/frontend/pages/sentiment/foundation.css @@ -884,19 +884,21 @@ min-width: 0px; - min-height: 33px; + min-height: 0px; display: flex; flex: 0 0 auto; - flex-direction: row; + flex-direction: column; - align-items: center; + justify-content: center; - gap: 6px; + align-items: flex-start; - padding: 0px 10px 0px 0px; + gap: 2px; + + padding: 0 16px; border: 0px; } @@ -924,11 +926,11 @@ } .overview-strip .sentiment-text { - color: var(--r2-ink); + color: var(--accent); - font-size: 12px; + font-size: var(--fs-caption); - font-weight: 600; + font-weight: 500; white-space: nowrap; } @@ -1037,25 +1039,31 @@ align-items: flex-start; - gap: 16px; + gap: 14px; - padding: 14px 16px; + padding: 14px 16px 10px; } .sentiment-current-phase-badge { - min-width: 94px; + min-width: 92px; flex: 0 0 auto; - display: block; + display: flex; - padding: 10px 18px; + flex-direction: column; - border: 1px solid rgb(245, 207, 201); + align-items: center; - border-radius: 10px; + gap: 2px; - background: var(--r2-up-soft); + padding: 10px 16px; + + border: 1px solid var(--accent); + + border-radius: var(--card-radius); + + background: var(--accent-soft); text-align: center; } @@ -1063,11 +1071,11 @@ .sentiment-current-phase-badge strong { display: block; - color: var(--r2-up); + color: var(--accent); font-size: 19px; - font-weight: 800; + font-weight: 700; line-height: 1.35; } @@ -1075,11 +1083,11 @@ .sentiment-current-phase-badge span { display: block; - margin-top: 2px; + margin-top: 0; - color: var(--r2-sub); + color: var(--text-3); - font-size: 11px; + font-size: var(--fs-aux); white-space: nowrap; } @@ -1091,15 +1099,17 @@ } .sentiment-phase-info p { - color: var(--r2-sub); + color: var(--text-2); - font-size: 12.5px; + font-size: var(--fs-label); - line-height: 1.7; + line-height: 1.6; } .sentiment-phase-info p b { - font-weight: 700; + color: var(--text-1); + + font-weight: 600; } .sentiment-phase-info p .down { @@ -1113,17 +1123,17 @@ .sentiment-phase-advice { margin-top: 8px; - padding: 5px 9px; + padding: 8px 10px; - border-radius: 6px; + border-radius: var(--radius-md); - background: var(--r2-amber-soft); + background: var(--surface-muted); - color: var(--r2-amber); + color: var(--text-2); - font-size: 12px; + font-size: var(--fs-caption); - line-height: 1.6; + line-height: 1.55; } .sentiment-feedback-strip { @@ -1131,45 +1141,47 @@ grid-template-columns: 1fr 1fr; - border-top: 1px solid var(--r2-line-soft); + border-top: 1px solid var(--border); } .sentiment-feedback-strip > span { min-width: 0px; - display: grid; + display: flex; - grid-template-columns: auto 1fr; + flex-wrap: wrap; - gap: 2px 8px; + align-items: baseline; - padding: 8px 12px; + gap: 2px 6px; - color: var(--r2-faint); + padding: 9px 14px; - font-size: 10.5px; + color: var(--text-3); + + font-size: var(--fs-caption); } .sentiment-feedback-strip > span + span { - border-left: 1px solid var(--r2-line-soft); + border-left: 1px solid var(--border); } .sentiment-feedback-strip strong { - color: var(--r2-ink); + color: var(--text-1); - font-size: 11.5px; + font-size: inherit; - text-align: right; + font-weight: 600; + + text-align: left; } .sentiment-feedback-strip small { - grid-column: 1 / -1; - overflow: hidden; - color: var(--r2-sub); + color: var(--text-3); - font-size: 10px; + font-size: var(--fs-aux); text-overflow: ellipsis; @@ -1399,17 +1411,17 @@ } .overview-strip .sentiment-block .sentiment-text { - display: block; + display: inline-flex; margin: 0px; - padding: 0px; + padding: 0 6px; - font-size: 11px; + font-size: var(--fs-caption); font-weight: 500; - line-height: 1; + line-height: 18px; letter-spacing: 0px; @@ -1478,19 +1490,19 @@ } .overview-strip[data-overview-expanded="true"] .sentiment-block { - min-height: 76px; + min-height: 0; justify-content: center; - gap: 4px; + gap: 2px; - padding: 10px 16px; + padding: 0 16px; - flex-direction: row; + flex-direction: column; - align-items: center; + align-items: flex-start; - border-right: 1px solid var(--line-soft); + border-right: 0; background: transparent; } diff --git a/frontend/shared/components/cards.css b/frontend/shared/components/cards.css index 694d001..c3aefa9 100644 --- a/frontend/shared/components/cards.css +++ b/frontend/shared/components/cards.css @@ -227,7 +227,7 @@ font-size: var(--font-size-card-title); - font-weight: var(--font-weight-bold); + font-weight: var(--font-weight-semibold); } .card-h .sub { diff --git a/frontend/shared/components/navigation.css b/frontend/shared/components/navigation.css index 2761951..e0a9bd3 100644 --- a/frontend/shared/components/navigation.css +++ b/frontend/shared/components/navigation.css @@ -52,21 +52,21 @@ } .segmented { - height: 34px; + height: var(--control-height); display: flex; overflow: hidden; - min-height: 36px; + min-height: var(--control-height); padding: 2px; border: 0px; - border-radius: 7px; + border-radius: var(--radius-md); - background: rgb(236, 239, 244); + background: var(--surface-muted); } .segment { @@ -82,11 +82,11 @@ border: 0px; - border-radius: 5px; + border-radius: 6px; color: var(--text-secondary); - font-size: 11.5px; + font-size: var(--font-size-label); } .segment.active { diff --git a/frontend/shared/components/tables.css b/frontend/shared/components/tables.css index 8b5ef08..85b4d65 100644 --- a/frontend/shared/components/tables.css +++ b/frontend/shared/components/tables.css @@ -48,7 +48,7 @@ color: var(--text-muted); - text-align: center; + text-align: left; } .table-action { @@ -242,7 +242,7 @@ } .data-table thead th { - padding: 0px 11px; + padding: 0 12px; border-bottom: 1px solid var(--border); @@ -256,17 +256,25 @@ height: 36px; - font-size: var(--font-size-label); + font-size: var(--font-size-caption); } .data-table tbody td { - padding: 6px 11px; - - border-bottom: 1px solid var(--border-subtle); - + padding: 0 12px; + border-bottom: 1px solid var(--border); color: var(--text-primary); + height: 40px; +} - height: 41px; +.data-table thead tr:last-child th:first-child, +.data-table tbody td:first-child, +.tbl thead tr:last-child th:first-child, +.tbl tbody td:first-child { + text-align: left; +} + +.tbl .row-number { + text-align: left; } .main-grid .data-table thead th { @@ -300,11 +308,11 @@ font-weight: 600; - font-size: 12px; + font-size: var(--font-size-caption); text-align: left; - padding: 8px 12px; + padding: 0 12px; border-bottom: 1px solid var(--line); @@ -336,13 +344,17 @@ } .tbl tbody td { - padding: 9px 12px; + padding: 0 12px; border-bottom: 1px solid var(--line-soft); white-space: nowrap; vertical-align: middle; + + height: 40px; + + font-size: var(--font-size-table); } .tbl tbody tr:hover { diff --git a/frontend/shared/dashboard.js b/frontend/shared/dashboard.js index b9d890d..7ddb943 100644 --- a/frontend/shared/dashboard.js +++ b/frontend/shared/dashboard.js @@ -99,6 +99,22 @@ function renderDashboard() { setText("dataDateMetric", dashboardDataTimestamp(meta)); animateMetric("sentimentScore", overview.sentiment_score, (value) => Math.round(value)); setText("sentimentText", sentimentLabel(overview.sentiment_score)); + const sentimentChip = document.querySelector("#sentimentText"); + if (sentimentChip) { + const label = sentimentLabel(overview.sentiment_score); + sentimentChip.classList.toggle("is-hot", label === "情绪高涨"); + sentimentChip.classList.toggle("is-strong", label === "情绪偏强"); + sentimentChip.classList.toggle("is-cold", label === "情绪冰点" || label === "情绪偏弱"); + } + const pageSubtitle = document.querySelector("#currentPageSubtitle"); + const activePage = window.XiaobaiPages?.get(state.activeView); + if (pageSubtitle && activePage?.id !== "mentorView") { + const groupLabel = activePage?.group === "market" + ? "市场复盘" + : activePage?.group === "personal" ? "个人" : "智能工具"; + const dateText = displayCompactDate(meta.trade_date); + pageSubtitle.textContent = dateText === "--" ? groupLabel : `${groupLabel} · ${dateText}`; + } updateSentimentGauge(overview.sentiment_score); setText("updatedAt", `${dashboardSourceLabel(meta)} · 更新 ${formatTimestamp(meta.updated_at)}`); diff --git a/frontend/shared/shell.css b/frontend/shared/shell.css index 3b671a6..ffae285 100644 --- a/frontend/shared/shell.css +++ b/frontend/shared/shell.css @@ -1024,8 +1024,8 @@ body.sidebar-collapsed .app-main { grid-template-columns: 176px minmax(0px, 1fr) auto; } - .market-tape { - display: none; + .app-header .market-tape { + display: flex; } .module-nav { @@ -1424,19 +1424,19 @@ body.sidebar-collapsed .module-nav .nav-group + .nav-group { padding: 12px 10px 4px; - color: var(--r2-faint); + color: var(--text-3); - font-size: 11px; + font-size: var(--fs-aux); - font-weight: 400; + font-weight: 600; - letter-spacing: 0px; + letter-spacing: .04em; } .module-nav .module-tab { width: 100%; - min-height: 34px; + min-height: 36px; display: flex; @@ -1456,9 +1456,9 @@ body.sidebar-collapsed .module-nav .nav-group + .nav-group { background: transparent; - color: var(--text-secondary); + color: var(--text-2); - font-size: 13px; + font-size: var(--fs-table); font-weight: 400; } @@ -1476,23 +1476,23 @@ body.sidebar-collapsed .module-nav .nav-group + .nav-group { } .module-nav .module-tab:hover { - background: var(--surface-hover); + background: var(--hover); - color: var(--r2-ink); + color: var(--text-1); } .module-nav .module-tab.active { - background: var(--r2-blue-soft); + background: var(--selected); - color: var(--r2-blue); + color: var(--accent); font-weight: 600; } .module-nav .module-tab.mobile-active { - background: var(--r2-blue-soft); + background: var(--selected); - color: var(--r2-blue); + color: var(--accent); font-weight: 600; } @@ -2008,7 +2008,7 @@ body.sidebar-collapsed .module-nav .module-tab { width: auto; - min-height: 30px; + min-height: var(--statusbar-height); height: var(--statusbar-height); @@ -2022,11 +2022,11 @@ body.sidebar-collapsed .module-nav .module-tab { border-top: 1px solid var(--line); - background: var(--surface); + background: var(--header-bg); - color: var(--faint); + color: var(--text-3); - font-size: 11.5px; + font-size: var(--fs-aux); } body.sidebar-collapsed .status-bar { @@ -2168,7 +2168,7 @@ body.sidebar-collapsed .status-bar { width: var(--sidebar-width); - background: var(--surface); + background: var(--header-bg); border-right: 1px solid var(--line); @@ -2277,6 +2277,8 @@ body.sidebar-collapsed .status-bar { margin-left: var(--sidebar-width); min-width: 0; + + overflow-x: hidden; } @media (min-width: 1280px) { @@ -2292,7 +2294,7 @@ body.sidebar-collapsed .status-bar { width: auto; - min-height: 46px; + min-height: var(--topbar-height); box-shadow: none; @@ -2304,17 +2306,17 @@ body.sidebar-collapsed .status-bar { z-index: 50; - background: var(--surface); + background: var(--header-bg); - border-bottom: 1px solid var(--line); + border-bottom: 1px solid var(--border); display: flex; align-items: center; - gap: 14px; + gap: 24px; - padding: 0 var(--page-pad-x); + padding: 0 20px; height: var(--topbar-height); } @@ -2494,8 +2496,8 @@ body.sidebar-collapsed .status-bar { padding: var(--mobile-shell-pad); } - .market-tape { - display: none; + .app-header .market-tape { + display: flex; } .header-actions { @@ -2746,10 +2748,20 @@ body.sidebar-collapsed .status-bar { color: var(--text-primary); } -:root[data-theme="dark"] :is(.module-nav, .app-header, .overview-strip, .status-bar) { +:root[data-theme="dark"] :is(.module-nav, .app-header, .status-bar) { border-color: var(--border); - background: var(--surface); + background: var(--header-bg); + + color: var(--text-primary); + + box-shadow: none; +} + +:root[data-theme="dark"] .overview-strip { + border-color: var(--border); + + background: transparent; color: var(--text-primary); @@ -2757,7 +2769,7 @@ body.sidebar-collapsed .status-bar { } :root[data-theme="dark"] .app-header { - background: color-mix(in srgb, var(--surface) 96%, transparent); + background: var(--header-bg); } :root[data-theme="dark"] :is(.sidebar-brand, .module-nav .sidebar-brand, .nav-group, .sidebar-collapse-button, .header-date-group) { @@ -3242,12 +3254,14 @@ body.sidebar-collapsed .status-bar { /* Generic page title slot in the shell header. Kept hidden so each page owns its own in-view title header (mentor renders one inside #mentorView). */ .app-page-context { - min-width: 0; - flex: 1 1 auto; + min-width: 148px; + max-width: 280px; + flex: 0 1 auto; flex-direction: column; justify-content: center; gap: 2px; - display: none; + overflow: hidden; + display: flex; } #themeModeText { @@ -3256,9 +3270,9 @@ body.sidebar-collapsed .status-bar { .app-page-context strong { overflow: hidden; - color: var(--text-primary); - font-size: 18px; - font-weight: var(--font-weight-semibold); + color: var(--text-1); + font-size: var(--fs-page-title); + font-weight: 600; line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; @@ -3266,9 +3280,398 @@ body.sidebar-collapsed .status-bar { .app-page-context span { overflow: hidden; - color: var(--text-secondary); - font-size: 13px; + color: var(--text-3); + font-size: var(--fs-caption); line-height: 1.4; text-overflow: ellipsis; white-space: nowrap; } + +/* Canonical B-147 merged header. */ +.app-header .overview-strip, +.app-header .overview-strip[data-overview-expanded="true"] { + position: static; + display: flex; + flex: 1 1 auto; + align-items: stretch; + width: auto; + height: auto; + min-width: 0; + min-height: 0; + margin: 0; + padding: 0; + overflow: visible; + border: 0; + background: transparent; + box-shadow: none; +} + +.app-header .market-tape { + display: flex; + flex: 1 1 auto; + align-items: center; + min-width: 0; + gap: 0; + overflow: hidden; + white-space: nowrap; +} + +.tape-metric { + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + gap: 2px; + min-width: 0; + padding: 0 16px; +} + +.tape-metric + .tape-metric::before, +.tape-metric + .overview-toggle::before { + content: ""; + position: absolute; + top: 50%; + left: 0; + width: 1px; + height: 26px; + background: var(--border); + transform: translateY(-50%); +} + +.tape-metric .metric-label { + color: var(--text-3); + font-size: var(--fs-aux); +} + +.tape-metric-value, +.tape-metric .metric-value { + display: flex; + align-items: center; + gap: 5px; + overflow: hidden; + color: var(--text-1); + font-size: 15px; + font-weight: 600; + font-variant-numeric: tabular-nums; + line-height: 1.2; + white-space: nowrap; +} + +.tape-metric .metric-value.up, +.tape-detail-item .up { + color: var(--up); +} + +.tape-metric .metric-value.down, +.tape-detail-item .down { + color: var(--down); +} + +.tape-metric .metric-value.warning { + color: var(--warn); +} + +.tape-sentiment .sentiment-gauge { + position: absolute; + width: 0; + height: 0; + overflow: hidden; + opacity: 0; + pointer-events: none; +} + +.tape-sentiment .sentiment-text { + display: inline-flex; + align-items: center; + height: 18px; + padding: 0 6px; + border-radius: var(--radius-sm); + background: var(--accent-soft); + color: var(--accent); + font-size: var(--fs-caption); + font-style: normal; + font-weight: 500; + line-height: 18px; +} + +.tape-sentiment .sentiment-text.is-hot { + background: var(--up-soft); + color: var(--up); +} + +.tape-sentiment .sentiment-text.is-strong { + background: var(--accent-soft); + color: var(--accent); +} + +.tape-sentiment .sentiment-text.is-cold { + background: var(--down-soft); + color: var(--down); +} + +.app-header .overview-toggle { + position: relative; + display: inline-flex; + align-items: center; + gap: 4px; + height: 28px; + min-height: 28px; + margin-left: 14px; + padding: 0 10px; + border: 0; + border-radius: var(--radius-md); + background: transparent; + color: var(--text-2); + font-size: var(--fs-label); +} + +.app-header .overview-toggle:hover { + background: var(--hover); + color: var(--text-1); +} + +.app-header .overview-toggle .lucide { + width: 14px; + height: 14px; +} + +.tape-detail { + position: absolute; + top: calc(var(--topbar-height) + 1px); + right: 0; + left: 0; + z-index: 45; + display: none; + grid-template-columns: repeat(6, minmax(0, 1fr)); + gap: 0 16px; + padding: 14px 20px 16px; + border-bottom: 1px solid var(--border); + background: var(--header-bg); + box-shadow: var(--shadow-raised); +} + +.overview-strip[data-overview-expanded="true"] .tape-detail { + display: grid; +} + +.tape-detail-item { + display: flex; + flex-direction: column; + gap: 3px; + padding: 8px 14px; + border-radius: var(--radius-md); +} + +.tape-detail-item:hover { + background: var(--hover); +} + +.tape-detail-item span { + color: var(--text-3); + font-size: var(--fs-aux); +} + +.tape-detail-item strong { + color: var(--text-1); + font-size: 16px; + font-weight: 600; + font-variant-numeric: tabular-nums; +} + +.app-header .header-actions { + display: flex; + flex: 0 0 auto; + align-items: center; + gap: 6px; + margin-left: 0; +} + +.app-header .header-date-group { + height: 32px; + min-height: 32px; + gap: 2px; + margin-right: 6px; + padding: 0; + border: 0; + background: transparent; + box-shadow: none; +} + +.app-header .header-date-group .icon-button, +.app-header .header-actions > .icon-button { + width: 32px; + min-width: 32px; + height: 32px; + min-height: 32px; + border: 0; + border-radius: var(--radius-md); + background: transparent; + color: var(--text-2); + box-shadow: none; +} + +.app-header .header-actions > .icon-button:hover, +.app-header .header-date-group .icon-button:hover { + background: var(--hover); + color: var(--text-1); +} + +.app-header .header-date-group .date-input { + width: auto; + height: 32px; + padding: 0 10px; + border: 1px solid var(--border-strong); + border-radius: var(--radius-md); + background: var(--surface); + color: var(--text-1); + font-size: var(--fs-label); + font-variant-numeric: tabular-nums; +} + +.app-header .header-actions > .icon-button .lucide, +.app-header .header-date-group .lucide { + width: 16px; + height: 16px; +} + +.app-header .alert-button { + position: relative; +} + +.app-header .alert-badge { + position: absolute; + top: 5px; + right: 5px; + min-width: 14px; + height: 14px; + padding: 0 3px; + border-radius: 7px; + background: var(--up); + color: #fff; + font-size: 10px; + font-weight: 600; + line-height: 14px; + text-align: center; +} + +#heavenView.workspace-view, +#heavenReadingDialog { + --color-action-base: #2563eb; + --color-action: #2563eb; + --color-action-base-hover: #1d4ed8; + --color-action-hover: #1d4ed8; + --color-action-base-soft: #eff4ff; + --color-action-soft: #eff4ff; + --action: #2563eb; + --action-hover: #1d4ed8; + --action-soft: #eff4ff; + --accent: #2563eb; + --primary: #2563eb; + --blue: #2563eb; + --r2-blue: #2563eb; + --focus-ring: rgba(37, 99, 235, .16); + --text-primary: #1f2937; + --text-secondary: #6b7280; + --text-tertiary: #9ca3af; + --border: #e5e7eb; + --border-strong: #d1d5db; + --surface-hover: #f8faff; + --surface-selected: #eff4ff; + --size-radius-sm: 5px; + --size-radius-md: 7px; +} + +:root[data-theme="dark"] #heavenView.workspace-view, +:root[data-theme="dark"] #heavenReadingDialog { + --action: #6ca8e8; + --action-hover: #8bbcf0; + --action-soft: #23364a; + --accent: #6ca8e8; + --primary: #6ca8e8; + --blue: #6ca8e8; + --r2-blue: #6ca8e8; + --canvas: #121416; + --surface: #1b1e21; + --surface-muted: #202428; + --border: #343a40; + --border-strong: #474f57; + --text-primary: #e8eaed; + --text-secondary: #adb5bd; + --text-tertiary: #7f8993; + --market-up: #f06d73; + --market-up-soft: #40262a; + --focus-ring: rgba(108, 168, 232, .22); +} + +@media (min-width: 1024px) and (max-width: 1439px) { + .tape-optional { + display: none; + } +} + +@media (max-width: 1023px) { + .app-header { + gap: 8px; + height: var(--mobile-header-height); + min-height: var(--mobile-header-height); + padding: 0 10px; + } + + .app-page-context { + display: none; + } + + .app-header .overview-strip, + .app-header .overview-strip[data-overview-expanded="true"] { + flex: 0 0 auto; + width: auto; + } + + .app-header .market-tape .tape-metric { + display: none; + } + + .app-header .overview-toggle { + width: var(--mobile-touch-size); + min-width: var(--mobile-touch-size); + height: var(--mobile-touch-size); + min-height: var(--mobile-touch-size); + margin-left: 0; + justify-content: center; + } + + .app-header .overview-toggle span { + display: none; + } + + .tape-detail, + .overview-strip[data-overview-expanded="true"] .tape-detail { + top: calc(var(--mobile-header-height) + 1px); + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 767px) { + body.mobile-shell .app-header .overview-strip, + body.mobile-shell .app-header .overview-strip[data-overview-expanded="true"] { + width: auto; + height: auto; + min-height: 0; + display: flex; + margin: 0; + padding: 0; + overflow: visible; + border: 0; + background: transparent; + } + + body.mobile-shell .app-header .market-tape { + display: flex; + overflow: visible; + } + + body.mobile-shell .app-header .overview-toggle { + display: inline-flex; + } +} + diff --git a/frontend/shared/shell.js b/frontend/shared/shell.js index 0d2cc6c..682d0b2 100644 --- a/frontend/shared/shell.js +++ b/frontend/shared/shell.js @@ -73,7 +73,12 @@ const pageTitle = document.querySelector("#currentPageTitle"); if (pageTitle) pageTitle.textContent = page?.title || "小白复盘"; const pageSubtitle = document.querySelector("#currentPageSubtitle"); - if (pageSubtitle && previousActiveView !== viewId) pageSubtitle.textContent = ""; + if (pageSubtitle && previousActiveView !== viewId) { + const groupLabel = page?.group === "market" + ? "市场复盘" + : page?.group === "personal" ? "个人" : "智能工具"; + pageSubtitle.textContent = groupLabel; + } document.querySelectorAll(".module-tab").forEach((button) => { button.classList.toggle("active", button.dataset.view === navigationId); button.classList.toggle( @@ -189,26 +194,35 @@ toggleHeaderCommandMenu(false); } }); + function setOverviewExpanded(expanded) { + const overview = document.querySelector(".overview-strip"); + const button = document.querySelector("#overviewToggle"); + if (!overview || !button) return; + overview.dataset.overviewExpanded = String(expanded); + button.setAttribute("aria-expanded", String(expanded)); + button.title = expanded ? "收起市场详情" : "展开市场详情"; + const label = button.querySelector("span"); + if (label) label.textContent = "详情"; + button.querySelector("i")?.setAttribute("data-lucide", expanded ? "chevron-up" : "chevron-down"); + options.refreshIcons?.(); + } + document.querySelector("#overviewToggle")?.addEventListener("click", (event) => { + event.stopPropagation(); const overview = document.querySelector(".overview-strip"); if (!overview) return; const expanded = overview.dataset.overviewExpanded !== "true"; - overview.dataset.overviewExpanded = String(expanded); - event.currentTarget.setAttribute("aria-expanded", String(expanded)); - event.currentTarget.title = expanded ? "收起市场详情" : "展开市场详情"; - const label = event.currentTarget.querySelector("span"); - if (label) label.textContent = expanded ? "收起详情" : "展开详情"; - event.currentTarget.querySelector("i")?.setAttribute( - "data-lucide", - expanded ? "chevron-up" : "chevron-down", - ); - options.refreshIcons?.(); + setOverviewExpanded(expanded); + if (expanded) toggleHeaderCommandMenu(false); }); document.addEventListener("click", (event) => { if (!event.target.closest(".header-actions")) toggleHeaderCommandMenu(false); + if (!event.target.closest(".overview-strip")) setOverviewExpanded(false); }); document.addEventListener("keydown", (event) => { - if (event.key === "Escape") toggleHeaderCommandMenu(false); + if (event.key !== "Escape") return; + toggleHeaderCommandMenu(false); + setOverviewExpanded(false); }); global.addEventListener("resize", () => { toggleHeaderCommandMenu(false); diff --git a/frontend/shared/tokens.css b/frontend/shared/tokens.css index 4e4cdab..0fec78e 100644 --- a/frontend/shared/tokens.css +++ b/frontend/shared/tokens.css @@ -22,19 +22,20 @@ --color-gray-900: #1f2937; --color-shell-canvas: #f4f5f7; --color-page-canvas: #f4f5f7; - --color-surface-muted: #f3f4f6; - --color-surface-subtle: #f8fafc; - --color-border: #e5e7eb; - --color-border-strong: #d1d5db; - --color-text-primary: #1f2937; - --color-text-secondary: #6b7280; - --color-text-tertiary: #9ca3af; - --color-action-base: #2563eb; - --color-action-base-hover: #1d4ed8; - --color-action-base-soft: #eff4ff; - --color-action: #2563eb; - --color-action-hover: #1d4ed8; - --color-action-soft: #eff4ff; + --color-surface-muted: #f2f3f5; + --color-surface-subtle: #f8f9fb; + --color-border: #eceded; + --color-border-strong: #dee0e3; + --color-text-primary: #1f2329; + --color-text-secondary: #646a73; + --color-text-tertiary: #8f959e; + --color-action-base: #3370ff; + --color-action-base-hover: #2b5fd9; + --color-action-base-soft: #eaf1fe; + --color-action: #3370ff; + --color-action-hover: #2b5fd9; + --color-action-soft: #eaf1fe; + --color-action-press: #2456b8; --color-action-line: #c7d8fb; --color-market-up-base: #e04536; --color-market-up-base-soft: #fdecea; @@ -49,24 +50,25 @@ --color-warning: #b45309; --color-warning-soft: #fdf3e3; - --size-radius-sm: 5px; - --size-radius-md: 7px; + --size-radius-sm: 4px; + --size-radius-md: 8px; --size-radius-lg: 10px; + --size-radius-dialog: 12px; --size-control: 32px; --size-sidebar: 200px; - --size-topbar: 46px; - --size-summary: 36px; - --size-statusbar: 30px; + --size-topbar: 64px; + --size-summary: 0px; + --size-statusbar: 28px; --size-page-pad-y: 14px; --size-page-pad-x: 16px; --size-card-gap: 12px; - --elevation-card: 0 1px 2px rgba(16, 24, 40, .05); - --elevation-soft: 0 1px 2px rgba(16, 24, 40, .05); - --elevation-raised: 0 4px 14px rgba(16, 24, 40, .06); - --elevation-float: 0 12px 32px rgba(0, 0, 0, .18); + --elevation-card: 0 1px 2px rgba(31, 35, 41, .04); + --elevation-soft: 0 1px 2px rgba(31, 35, 41, .04); + --elevation-raised: 0 2px 6px rgba(31, 35, 41, .04), 0 8px 24px rgba(31, 35, 41, .06); + --elevation-float: 0 12px 32px rgba(0, 0, 0, .14); --motion-instant: 100ms; - --motion-fast: 140ms; + --motion-fast: 120ms; --motion-medium: 200ms; --motion-deliberate: 260ms; --motion-slow: 560ms; @@ -80,8 +82,11 @@ --surface-canvas: var(--color-page-canvas); --surface-raised: var(--color-white); --surface-sunken: #eef0f3; - --surface-hover: #f8faff; - --surface-selected: #eff4ff; + --header-bg: var(--color-white); + --surface-hover: #f2f3f5; + --surface-selected: #eaf1fe; + --hover: var(--surface-hover); + --selected: var(--surface-selected); --surface-overlay: var(--color-white); --border: var(--color-border); --border-strong: var(--color-border-strong); @@ -93,7 +98,12 @@ --on-action: #ffffff; --action: var(--color-action-base); --action-hover: var(--color-action-base-hover); + --action-press: var(--color-action-press); --action-soft: var(--color-action-base-soft); + --accent: var(--action); + --accent-hover: var(--action-hover); + --accent-press: var(--action-press); + --accent-soft: var(--action-soft); --market-up: var(--color-market-up-base); --market-up-soft: var(--color-market-up-base-soft); --market-down: var(--color-market-down-base); @@ -106,7 +116,12 @@ --table-header: var(--surface-subtle); --table-hover: #f8faff; --table-selected: var(--surface-selected); - --focus-ring: rgba(37, 99, 235, .16); + --focus-ring: rgba(51, 112, 255, .15); + --text-1: var(--text-primary); + --text-2: var(--text-secondary); + --text-3: var(--text-tertiary); + --warn: var(--warning-color); + --warn-soft: var(--warning-soft); --backdrop: rgba(17, 24, 39, .48); --primary: var(--color-action); --primary-hover: var(--color-action-hover); @@ -126,18 +141,32 @@ --radius-lg: var(--size-radius-lg); --shadow-xs: var(--elevation-card); --shadow-sm: var(--elevation-raised); + --shadow-card: var(--elevation-card); + --shadow-raised: var(--elevation-raised); --shadow-float: var(--elevation-float); --duration-fast: 150ms; --duration-normal: 220ms; - --font-size-aux: 10.5px; - --font-size-caption: 11px; - --font-size-label: 12px; - --font-size-table: 12.5px; - --font-size-body: 13px; - --font-size-card-title: 14px; - --font-size-page-title: 17px; - --font-size-metric: 22px; + --font-size-aux: 11.5px; + --font-size-caption: 12.5px; + --font-size-label: 13px; + --font-size-table: 13.5px; + --font-size-body: 14px; + --font-size-chat: 14px; + --font-size-card-title: 15px; + --font-size-page-title: 18px; + --font-size-metric: 24px; + --font-size-hero: 30px; + --fs-aux: var(--font-size-aux); + --fs-caption: var(--font-size-caption); + --fs-label: var(--font-size-label); + --fs-table: var(--font-size-table); + --fs-body: var(--font-size-body); + --fs-chat: var(--font-size-chat); + --fs-card-title: var(--font-size-card-title); + --fs-page-title: var(--font-size-page-title); + --fs-metric: var(--font-size-metric); + --fs-hero: var(--font-size-hero); --font-weight-regular: 400; --font-weight-medium: 500; --font-weight-semibold: 600; @@ -147,6 +176,7 @@ --space-8: 8px; --space-12: 12px; --space-16: 16px; + --space-20: 20px; --space-24: 24px; --sidebar-width: var(--size-sidebar); @@ -220,8 +250,10 @@ --dragon-profile-weight-semibold: 600; --mentor-directory-width: 300px; - --mentor-pane-header-height: 60px; - --mentor-avatar-size: 42px; + --mentor-pane-header-height: 56px; + --mentor-avatar-size: 40px; + --mentor-message-avatar-size: 36px; + --mentor-chat-avatar-size: 38px; --mentor-profile-avatar-size: 68px; --mentor-composer-min-height: 85px; --mentor-message-max-width: 60%; @@ -312,45 +344,64 @@ --r2-radius: var(--size-radius-lg); --r2-shadow: var(--elevation-card); - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Variable", "Segoe UI", "PingFang SC", "Microsoft YaHei UI", sans-serif; + font-family: "PingFang SC", "Microsoft YaHei", system-ui, sans-serif; font-size: 14px; } :root[data-theme="dark"] { color-scheme: dark; - --canvas: #121416; - --surface: #1b1e21; - --surface-muted: #202428; - --surface-subtle: #24282d; + --canvas: #141519; + --header-bg: #1c1e23; + --surface: #232529; + --surface-muted: #2a2d33; + --surface-subtle: #202329; --surface-canvas: var(--canvas); --surface-raised: var(--surface); - --surface-sunken: #16191c; - --surface-hover: #24282d; - --surface-selected: #23364a; - --surface-overlay: #24282d; - --border: #343a40; - --border-strong: #474f57; - --border-subtle: #2a2f34; + --surface-sunken: #191b1f; + --surface-hover: #2a2d33; + --surface-selected: #2b3b58; + --surface-overlay: #232529; + --hover: var(--surface-hover); + --selected: var(--surface-selected); + --border: #2b2e34; + --border-strong: #3a3e47; + --border-subtle: #2b2e34; --text-primary: #e8eaed; - --text-secondary: #adb5bd; - --text-tertiary: #7f8993; + --text-secondary: #a9adb3; + --text-tertiary: #7c828a; + --text-1: var(--text-primary); + --text-2: var(--text-secondary); + --text-3: var(--text-tertiary); --text-inverse: #ffffff; - --action: #6ca8e8; - --action-hover: #8bbcf0; - --action-soft: #23364a; - --market-up: #f06d73; - --market-up-soft: #40262a; + --action: #5b8def; + --action-hover: #7ba5f5; + --action-press: #3465c4; + --action-soft: #2b3b58; + --accent: var(--action); + --accent-hover: var(--action-hover); + --accent-press: var(--action-press); + --accent-soft: var(--action-soft); + --market-up: #f26762; + --market-up-soft: #3d2829; --market-down: #43bc8a; - --market-down-soft: #1d382f; + --market-down-soft: #22362c; --warning-color: #e2ad58; --warning-soft: #3d3220; - --control-surface: #202428; - --control-hover: #2a2f34; - --control-border: #474f57; - --table-header: #202428; - --table-hover: #242f39; - --table-selected: #23364a; - --focus-ring: rgba(108, 168, 232, .22); + --warn: var(--warning-color); + --warn-soft: var(--warning-soft); + --control-surface: #232529; + --control-hover: #2a2d33; + --control-border: #3a3e47; + --table-header: #202329; + --table-hover: #2a2d33; + --table-selected: #2b3b58; + --focus-ring: rgba(91, 141, 239, .25); + --elevation-card: 0 1px 2px rgba(0, 0, 0, .28); + --elevation-soft: 0 1px 2px rgba(0, 0, 0, .28); + --elevation-raised: 0 1px 2px rgba(0, 0, 0, .30), 0 8px 24px rgba(0, 0, 0, .35); + --elevation-float: 0 12px 32px rgba(0, 0, 0, .46); + --shadow-card: var(--elevation-card); + --shadow-raised: var(--elevation-raised); --backdrop: rgba(0, 0, 0, .66); --primary: var(--action); --primary-hover: var(--action-hover);
序号序号 股票 昨日高度(板) 今日涨幅(%)
${index + 1}${index + 1} ${escapeHtml(row.name)}${escapeHtml(row.code)} ${streakLabel(row.streak)} ${signed(row.change)}
${index + 1}${index + 1} ${escapeHtml(row.name)}${escapeHtml(row.code)} ${signed(row.change)} ${formatNumber(row.limitGap, 2)}
${index + 1}${index + 1} ${escapeHtml(row.name)}${escapeHtml(row.code)} ${signed(row.change)} ${formatNumber(row.price, 2)}
${index + 1}${index + 1} ${escapeHtml(row.name)}${escapeHtml(row.code)} ${number(row.prior_streak)} ${signed(row.current_change)}