From 5dbee844e52cd0e51b61e089706c522ae9eba312 Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Tue, 7 Apr 2026 08:44:30 +0000 Subject: [PATCH 01/27] feat(web-ui): refine layout hierarchy inspired by dory --- web-ui/partials/index/layout-header.html | 63 ++++++---- web-ui/styles/layout-shell.css | 144 +++++++++++++++++++---- web-ui/styles/navigation-panels.css | 85 ++++++++----- web-ui/styles/responsive.css | 48 ++++++-- web-ui/styles/titles-cards.css | 30 ++--- 5 files changed, 268 insertions(+), 102 deletions(-) diff --git a/web-ui/partials/index/layout-header.html b/web-ui/partials/index/layout-header.html index b9a1477..a46dd99 100644 --- a/web-ui/partials/index/layout-header.html +++ b/web-ui/partials/index/layout-header.html @@ -8,16 +8,38 @@ -
- -
- Codex Mate. -
-
- 配置中枢:管理 Codex / Claude / OpenClaw / 会话 - 本地配置中枢,统一管理 Codex / Claude Code / OpenClaw / 会话。 +
+
+
LOCAL AI WORKSPACE
+
+ +
+
+ Codex Mate. +
+
+ 参考 Dory 的层级组织方式,但只保留 codexmate 真正需要的入口、状态和操作,不把界面硬凑成别人的样子。 + 本地配置中枢,统一管理 Codex / Claude Code / OpenClaw / 会话。 +
+
+
+
+ + GitHub + SakuraByteCore/codexmate + +
+ 当前区域 + {{ mainTab === 'config' ? '配置中心' : (mainTab === 'sessions' ? '会话浏览' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? '技能市场' : '设置'))) }} +
+
-
+
-
-

- {{ mainTab === 'config' ? '配置中心' : (mainTab === 'sessions' ? '会话浏览' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? '技能市场' : '设置'))) }} -

-

- 配置中枢:管理 Codex / Claude / OpenClaw - 本地配置中枢,统一管理 Codex / Claude Code / OpenClaw。 -

-

- 统一查看与导出 Codex / Claude 会话。 -

-

- 单独查看本地会话用量、趋势与高频路径。 -

-

- 统一管理 Codex / Claude Skills,并聚焦本地导入与分发。 -

+
+
+
{{ mainTab === 'config' ? '配置中心' : (mainTab === 'sessions' ? '会话浏览' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? '技能市场' : '设置'))) }}
+

{{ mainTab === 'config' ? '本地 AI 工作台' : (mainTab === 'sessions' ? '会话与上下文' : (mainTab === 'usage' ? '本地用量与趋势' : (mainTab === 'market' ? '技能与分发' : '运行与数据设置'))) }}

+

{{ mainTab === 'config' ? '集中整理 Codex、Claude Code 与 OpenClaw 的关键配置,保持入口清爽、信息成组。' : (mainTab === 'sessions' ? '统一查看、检索和导出 Codex / Claude 会话,不把信息挤成一坨。' : (mainTab === 'usage' ? '把用量统计独立出来,避免会话浏览和趋势信息互相打架。' : (mainTab === 'market' ? '围绕本地 Skills 的安装、导入与同步建立清晰工作流。' : '处理下载、数据管理与全局行为,不往别的面板乱塞杂项。'))) }}

+
diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 3db55ec..3db828d 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -5,9 +5,11 @@ body::before { content: ""; position: fixed; inset: 0; - background-image: - linear-gradient(180deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0)); - opacity: 0.16; + background: + radial-gradient(circle at top left, rgba(208, 88, 58, 0.1), transparent 34%), + radial-gradient(circle at top right, rgba(245, 201, 160, 0.24), transparent 28%), + linear-gradient(180deg, rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0)); + opacity: 0.92; pointer-events: none; z-index: 0; } @@ -18,10 +20,10 @@ body::after { position: fixed; inset: 0; background-image: - linear-gradient(90deg, rgba(255, 255, 255, 0.08) 1px, transparent 1px), - linear-gradient(0deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px); - background-size: 180px 180px; - opacity: 0.08; + linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px), + linear-gradient(0deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px); + background-size: 160px 160px; + opacity: 0.06; pointer-events: none; z-index: 0; } @@ -33,7 +35,7 @@ body::after { width: 100%; max-width: 2200px; margin: 0 auto; - padding: 16px 12px 28px; + padding: 24px 20px 36px; position: relative; z-index: 1; } @@ -43,8 +45,8 @@ body::after { ============================================ */ .app-shell { display: grid; - grid-template-columns: 260px minmax(0, 1fr) 340px; - gap: 16px; + grid-template-columns: 272px minmax(0, 1fr) 332px; + gap: 20px; align-items: flex-start; } @@ -58,13 +60,14 @@ body::after { align-self: start; display: flex; flex-direction: column; - gap: var(--spacing-sm); - padding: var(--spacing-md) var(--spacing-sm); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 250, 245, 0.9) 100%); - border: 1px solid rgba(216, 201, 184, 0.65); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-card); + gap: 18px; + padding: 18px 14px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 250, 245, 0.82) 100%); + border: 1px solid rgba(216, 201, 184, 0.5); + border-radius: 24px; + box-shadow: 0 18px 48px rgba(31, 26, 23, 0.08); min-height: 420px; + backdrop-filter: blur(18px); } .side-rail .brand-title { @@ -162,9 +165,9 @@ body::after { grid-template-columns: 48px 1fr; grid-template-rows: auto auto; column-gap: var(--spacing-sm); - row-gap: 2px; + row-gap: 4px; align-items: center; - margin-bottom: var(--spacing-md); + margin-bottom: 8px; } .brand-logo-wrap { @@ -200,10 +203,11 @@ body::after { } .brand-subtitle { - margin-top: 8px; - font-size: var(--font-size-secondary); + margin-top: 4px; + font-size: 12px; color: var(--color-text-tertiary); - line-height: 1.45; + line-height: 1.5; + max-width: 18ch; } .github-badge { @@ -213,16 +217,17 @@ body::after { justify-content: space-between; gap: 10px; margin-top: 6px; - padding: 6px 10px; + padding: 7px 11px; border-radius: 999px; - border: 1px solid var(--color-border-soft); - background: linear-gradient(to bottom, rgba(255, 255, 255, 0.92) 0%, rgba(255, 255, 255, 0.72) 100%); + border: 1px solid rgba(216, 201, 184, 0.5); + background: rgba(255, 255, 255, 0.78); color: var(--color-text-secondary); font-size: var(--font-size-caption); text-decoration: none; box-shadow: var(--shadow-subtle); transition: all var(--transition-fast) var(--ease-spring); min-width: 0; + backdrop-filter: blur(10px); } .github-badge-rail { @@ -328,3 +333,94 @@ body::after { transform: translateY(-1px); border-color: rgba(201, 94, 75, 0.5); } + +.hero-surface { + margin-bottom: 20px; + padding: 24px 28px; + border-radius: 30px; + border: 1px solid rgba(216, 201, 184, 0.5); + background: + linear-gradient(135deg, rgba(255, 255, 255, 0.94) 0%, rgba(255, 247, 240, 0.88) 100%), + radial-gradient(circle at top right, rgba(208, 88, 58, 0.08), transparent 28%); + box-shadow: 0 24px 60px rgba(31, 26, 23, 0.08); + position: relative; + overflow: hidden; +} + +.hero-surface::after { + content: ""; + position: absolute; + inset: auto -40px -80px auto; + width: 240px; + height: 240px; + border-radius: 50%; + background: radial-gradient(circle, rgba(208, 88, 58, 0.08), transparent 68%); + pointer-events: none; +} + +.hero-copy { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + gap: 18px; +} + +.hero-eyebrow { + font-size: 12px; + font-weight: 700; + letter-spacing: 0.18em; + color: var(--color-text-tertiary); +} + +.hero-title-row { + display: flex; + align-items: center; + gap: 18px; +} + +.hero-title-block { + display: flex; + flex-direction: column; + gap: 8px; +} + +.hero-actions-row { + display: flex; + flex-wrap: wrap; + gap: 12px; + align-items: center; +} + +.hero-link-pill, +.hero-summary-pill { + display: inline-flex; + align-items: center; + gap: 10px; + min-height: 40px; + padding: 0 14px; + border-radius: 999px; + border: 1px solid rgba(216, 201, 184, 0.56); + background: rgba(255, 255, 255, 0.78); + box-shadow: var(--shadow-subtle); +} + +.hero-link-pill { + color: var(--color-text-primary); + text-decoration: none; +} + +.hero-link-label, +.hero-summary-label { + font-size: 11px; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-text-tertiary); +} + +.hero-link-value, +.hero-summary-value { + font-size: 13px; + font-weight: 600; + color: var(--color-text-primary); +} diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index 2ce5d0f..a3bfccc 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -32,19 +32,19 @@ } .status-strip { - display: flex; - flex-wrap: wrap; - gap: var(--spacing-xs); - margin-bottom: var(--spacing-sm); - margin-top: 6px; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + gap: 12px; + margin-bottom: 18px; + margin-top: 8px; } .status-chip { - min-width: 200px; - padding: 10px 12px; - border-radius: var(--radius-lg); - border: 1px solid var(--color-border-soft); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.99) 0%, rgba(255, 250, 245, 0.97) 100%); + min-width: 0; + padding: 14px 16px; + border-radius: 18px; + border: 1px solid rgba(216, 201, 184, 0.42); + background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(255, 250, 245, 0.94) 100%); box-shadow: var(--shadow-subtle); } @@ -108,12 +108,12 @@ .main-panel { min-width: 0; - background: rgba(255, 255, 255, 0.95); - border: 1px solid rgba(216, 201, 184, 0.48); - border-radius: 18px; - box-shadow: var(--shadow-card); - padding: var(--spacing-md) var(--spacing-lg); - backdrop-filter: blur(8px); + background: rgba(255, 255, 255, 0.84); + border: 1px solid rgba(216, 201, 184, 0.44); + border-radius: 28px; + box-shadow: 0 24px 64px rgba(31, 26, 23, 0.08); + padding: 28px 32px; + backdrop-filter: blur(18px); position: relative; overflow-x: hidden; overflow-y: visible; @@ -209,6 +209,29 @@ text-align: left; } +.panel-header-dory { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 18px; + margin-bottom: 24px; +} + +.panel-header-copy { + display: flex; + flex-direction: column; + gap: 8px; + max-width: 760px; +} + +.panel-kicker { + font-size: 12px; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--color-text-tertiary); + font-weight: 700; +} + .hero { display: flex; align-items: center; @@ -217,23 +240,24 @@ } .hero-logo { - display: none; - width: 64px; - height: 64px; - border-radius: 18px; - padding: 8px; - background: var(--color-surface-elevated); - border: 1px solid var(--color-border-soft); - box-shadow: var(--shadow-card); + display: block; + width: 72px; + height: 72px; + border-radius: 22px; + padding: 10px; + background: rgba(255, 255, 255, 0.9); + border: 1px solid rgba(216, 201, 184, 0.5); + box-shadow: 0 16px 36px rgba(31, 26, 23, 0.08); object-fit: contain; + flex-shrink: 0; } .hero-title { - font-size: 48px; - line-height: 1.05; + font-size: 56px; + line-height: 1; font-family: var(--font-family-display); color: var(--color-text-primary); - letter-spacing: -0.02em; + letter-spacing: -0.04em; } .hero-title .accent { @@ -241,10 +265,11 @@ } .hero-subtitle { - margin-top: 8px; - font-size: var(--font-size-body); + margin-top: 0; + font-size: 15px; color: var(--color-text-tertiary); - line-height: 1.5; + line-height: 1.7; + max-width: 64ch; } .hero-github { diff --git a/web-ui/styles/responsive.css b/web-ui/styles/responsive.css index 10b3308..40819fa 100644 --- a/web-ui/styles/responsive.css +++ b/web-ui/styles/responsive.css @@ -13,8 +13,8 @@ textarea:focus-visible { @media (max-width: 1280px) { .app-shell { - grid-template-columns: 240px minmax(0, 1fr) 300px; - gap: 14px; + grid-template-columns: 236px minmax(0, 1fr) 292px; + gap: 16px; } .status-inspector { @@ -23,7 +23,11 @@ textarea:focus-visible { } .main-panel { - padding: var(--spacing-sm) var(--spacing-md); + padding: 22px 24px; + } + + .hero-surface { + padding: 20px 22px; } } @@ -42,6 +46,8 @@ textarea:focus-visible { } .hero-logo { display: block; + width: 60px; + height: 60px; } .hero-github { display: flex; @@ -54,8 +60,22 @@ textarea:focus-visible { font-size: var(--font-size-secondary); } .main-panel { - padding: var(--spacing-sm) var(--spacing-sm); - border-radius: 14px; + padding: 18px; + border-radius: 20px; + } + + .hero-surface { + padding: 18px; + border-radius: 22px; + } + + .hero-title-row { + align-items: flex-start; + } + + .hero-actions-row { + flex-direction: column; + align-items: stretch; } .top-tabs { display: grid !important; @@ -90,13 +110,17 @@ textarea:focus-visible { @media (max-width: 720px) { .main-title { - font-size: 40px; + font-size: 36px; } .hero-title { font-size: 32px; } + .hero-title-row { + flex-direction: column; + } + .subtitle { font-size: var(--font-size-secondary); margin-bottom: 16px; @@ -147,11 +171,21 @@ textarea:focus-visible { padding: 0 var(--spacing-sm) var(--spacing-md); } .hero-title { - font-size: 32px; + font-size: 30px; } .hero-subtitle { font-size: var(--font-size-secondary); } + + .hero-surface { + padding: 16px 14px; + } + + .hero-link-pill, + .hero-summary-pill { + width: 100%; + justify-content: space-between; + } .top-tabs { grid-template-columns: repeat(1, minmax(0, 1fr)); } diff --git a/web-ui/styles/titles-cards.css b/web-ui/styles/titles-cards.css index f8be702..8fcc2a4 100644 --- a/web-ui/styles/titles-cards.css +++ b/web-ui/styles/titles-cards.css @@ -2,14 +2,14 @@ 主标题 ============================================ */ .main-title { - font-size: var(--font-size-display); + font-size: clamp(34px, 4.2vw, 56px); font-weight: var(--font-weight-display); - line-height: var(--line-height-tight); - letter-spacing: -0.03em; - margin-bottom: 10px; + line-height: 0.98; + letter-spacing: -0.05em; + margin-bottom: 0; color: var(--color-text-primary); font-family: var(--font-family-display); - background: linear-gradient(135deg, var(--color-text-primary) 0%, rgba(27, 23, 20, 0.78) 100%); + background: linear-gradient(135deg, var(--color-text-primary) 0%, rgba(27, 23, 20, 0.72) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -22,11 +22,11 @@ } .subtitle { - font-size: var(--font-size-body); + font-size: 15px; color: var(--color-text-tertiary); - line-height: var(--line-height-normal); - margin-bottom: 20px; - max-width: 640px; + line-height: 1.75; + margin-bottom: 0; + max-width: 60ch; letter-spacing: 0.01em; } @@ -85,9 +85,9 @@ 卡片 ============================================ */ .card { - background: linear-gradient(180deg, #fffdf9 0%, #fff8f2 100%); - border-radius: var(--radius-lg); - padding: 10px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(255, 249, 243, 0.9) 100%); + border-radius: 20px; + padding: 14px; display: flex; align-items: center; justify-content: space-between; @@ -96,10 +96,10 @@ transform var(--transition-normal) var(--ease-spring), box-shadow var(--transition-normal) var(--ease-spring), background-color var(--transition-fast) var(--ease-smooth); - box-shadow: 0 10px 24px rgba(27, 23, 20, 0.08); + box-shadow: 0 18px 36px rgba(27, 23, 20, 0.06); user-select: none; will-change: transform; - border: 1px solid rgba(216, 201, 184, 0.55); + border: 1px solid rgba(216, 201, 184, 0.48); position: relative; overflow: hidden; } @@ -235,7 +235,7 @@ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - opacity: 0.8; + opacity: 0.9; } .card-trailing { From 214f4fdfbeaafa7b93ce84d26faf6c08c196f3fa Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Tue, 7 Apr 2026 08:50:49 +0000 Subject: [PATCH 02/27] fix(web-ui): tighten light layout refresh and parity coverage --- tests/unit/web-ui-behavior-parity.test.mjs | 6 ++- web-ui/app.js | 1 + web-ui/partials/index/layout-header.html | 4 +- web-ui/styles/layout-shell.css | 60 +++++++++++----------- web-ui/styles/navigation-panels.css | 36 ++++++------- 5 files changed, 55 insertions(+), 52 deletions(-) diff --git a/tests/unit/web-ui-behavior-parity.test.mjs b/tests/unit/web-ui-behavior-parity.test.mjs index f05bf67..a993dba 100644 --- a/tests/unit/web-ui-behavior-parity.test.mjs +++ b/tests/unit/web-ui-behavior-parity.test.mjs @@ -319,10 +319,12 @@ test('captured bundled app skeleton only exposes expected data key drift versus const headDataKeys = Object.keys(headAppOptions.data()).sort(); const extraCurrentKeys = currentDataKeys.filter((key) => !headDataKeys.includes(key)).sort(); const missingCurrentKeys = headDataKeys.filter((key) => !currentDataKeys.includes(key)).sort(); - const allowedExtraCurrentKeys = []; - const allowedMissingCurrentKeys = [ + const allowedExtraCurrentKeys = parityAgainstHead ? [] : [ 'sessionsViewMode' ]; + const allowedMissingCurrentKeys = parityAgainstHead ? [ + 'sessionsViewMode' + ] : []; if (parityAgainstHead) { const allowedExtraKeySet = new Set(allowedExtraCurrentKeys); const allowedMissingKeySet = new Set(allowedMissingCurrentKeys); diff --git a/web-ui/app.js b/web-ui/app.js index bd7bcb4..6c83612 100644 --- a/web-ui/app.js +++ b/web-ui/app.js @@ -117,6 +117,7 @@ document.addEventListener('DOMContentLoaded', () => { skillsMarketLocalLoadedOnce: false, skillsMarketImportLoadedOnce: false, sessionPinnedMap: {}, + sessionsViewMode: 'browser', sessionsUsageTimeRange: '7d', sessionsList: [], sessionsLoadedOnce: false, diff --git a/web-ui/partials/index/layout-header.html b/web-ui/partials/index/layout-header.html index a46dd99..d7fa19c 100644 --- a/web-ui/partials/index/layout-header.html +++ b/web-ui/partials/index/layout-header.html @@ -18,7 +18,7 @@ Codex Mate.
- 参考 Dory 的层级组织方式,但只保留 codexmate 真正需要的入口、状态和操作,不把界面硬凑成别人的样子。 + 把层级、留白和信息编排重新整理清楚,只保留 codexmate 真正需要的入口、状态和操作,不把界面硬凑成花架子。 本地配置中枢,统一管理 Codex / Claude Code / OpenClaw / 会话。
@@ -279,7 +279,7 @@
-
+
{{ mainTab === 'config' ? '配置中心' : (mainTab === 'sessions' ? '会话浏览' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? '技能市场' : '设置'))) }}

{{ mainTab === 'config' ? '本地 AI 工作台' : (mainTab === 'sessions' ? '会话与上下文' : (mainTab === 'usage' ? '本地用量与趋势' : (mainTab === 'market' ? '技能与分发' : '运行与数据设置'))) }}

diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 3db828d..cf3f2fc 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -6,10 +6,10 @@ body::before { position: fixed; inset: 0; background: - radial-gradient(circle at top left, rgba(208, 88, 58, 0.1), transparent 34%), - radial-gradient(circle at top right, rgba(245, 201, 160, 0.24), transparent 28%), - linear-gradient(180deg, rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0)); - opacity: 0.92; + radial-gradient(circle at top left, rgba(208, 88, 58, 0.04), transparent 28%), + radial-gradient(circle at top right, rgba(245, 201, 160, 0.1), transparent 24%), + linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0)); + opacity: 0.84; pointer-events: none; z-index: 0; } @@ -22,8 +22,8 @@ body::after { background-image: linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px), linear-gradient(0deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px); - background-size: 160px 160px; - opacity: 0.06; + background-size: 180px 180px; + opacity: 0.04; pointer-events: none; z-index: 0; } @@ -60,14 +60,14 @@ body::after { align-self: start; display: flex; flex-direction: column; - gap: 18px; - padding: 18px 14px; - background: linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 250, 245, 0.82) 100%); - border: 1px solid rgba(216, 201, 184, 0.5); - border-radius: 24px; - box-shadow: 0 18px 48px rgba(31, 26, 23, 0.08); + gap: 16px; + padding: 16px 12px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(255, 251, 247, 0.9) 100%); + border: 1px solid rgba(216, 201, 184, 0.44); + border-radius: 22px; + box-shadow: 0 14px 34px rgba(31, 26, 23, 0.06); min-height: 420px; - backdrop-filter: blur(18px); + backdrop-filter: blur(12px); } .side-rail .brand-title { @@ -219,15 +219,15 @@ body::after { margin-top: 6px; padding: 7px 11px; border-radius: 999px; - border: 1px solid rgba(216, 201, 184, 0.5); - background: rgba(255, 255, 255, 0.78); + border: 1px solid rgba(216, 201, 184, 0.42); + background: rgba(255, 255, 255, 0.9); color: var(--color-text-secondary); font-size: var(--font-size-caption); text-decoration: none; box-shadow: var(--shadow-subtle); transition: all var(--transition-fast) var(--ease-spring); min-width: 0; - backdrop-filter: blur(10px); + backdrop-filter: blur(6px); } .github-badge-rail { @@ -335,14 +335,14 @@ body::after { } .hero-surface { - margin-bottom: 20px; - padding: 24px 28px; - border-radius: 30px; - border: 1px solid rgba(216, 201, 184, 0.5); + margin-bottom: 18px; + padding: 22px 24px; + border-radius: 26px; + border: 1px solid rgba(216, 201, 184, 0.44); background: - linear-gradient(135deg, rgba(255, 255, 255, 0.94) 0%, rgba(255, 247, 240, 0.88) 100%), - radial-gradient(circle at top right, rgba(208, 88, 58, 0.08), transparent 28%); - box-shadow: 0 24px 60px rgba(31, 26, 23, 0.08); + linear-gradient(135deg, rgba(255, 255, 255, 0.96) 0%, rgba(255, 251, 247, 0.93) 100%), + radial-gradient(circle at top right, rgba(208, 88, 58, 0.04), transparent 24%); + box-shadow: 0 18px 42px rgba(31, 26, 23, 0.06); position: relative; overflow: hidden; } @@ -351,10 +351,10 @@ body::after { content: ""; position: absolute; inset: auto -40px -80px auto; - width: 240px; - height: 240px; + width: 220px; + height: 220px; border-radius: 50%; - background: radial-gradient(circle, rgba(208, 88, 58, 0.08), transparent 68%); + background: radial-gradient(circle, rgba(208, 88, 58, 0.04), transparent 68%); pointer-events: none; } @@ -397,11 +397,11 @@ body::after { display: inline-flex; align-items: center; gap: 10px; - min-height: 40px; - padding: 0 14px; + min-height: 38px; + padding: 0 13px; border-radius: 999px; - border: 1px solid rgba(216, 201, 184, 0.56); - background: rgba(255, 255, 255, 0.78); + border: 1px solid rgba(216, 201, 184, 0.48); + background: rgba(255, 255, 255, 0.92); box-shadow: var(--shadow-subtle); } diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index a3bfccc..1ebfb64 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -41,10 +41,10 @@ .status-chip { min-width: 0; - padding: 14px 16px; - border-radius: 18px; - border: 1px solid rgba(216, 201, 184, 0.42); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(255, 250, 245, 0.94) 100%); + padding: 13px 15px; + border-radius: 16px; + border: 1px solid rgba(216, 201, 184, 0.38); + background: linear-gradient(180deg, rgba(255, 255, 255, 0.99) 0%, rgba(255, 252, 249, 0.96) 100%); box-shadow: var(--shadow-subtle); } @@ -108,12 +108,12 @@ .main-panel { min-width: 0; - background: rgba(255, 255, 255, 0.84); - border: 1px solid rgba(216, 201, 184, 0.44); - border-radius: 28px; - box-shadow: 0 24px 64px rgba(31, 26, 23, 0.08); - padding: 28px 32px; - backdrop-filter: blur(18px); + background: rgba(255, 255, 255, 0.92); + border: 1px solid rgba(216, 201, 184, 0.4); + border-radius: 24px; + box-shadow: 0 18px 42px rgba(31, 26, 23, 0.06); + padding: 24px 28px; + backdrop-filter: blur(10px); position: relative; overflow-x: hidden; overflow-y: visible; @@ -209,12 +209,12 @@ text-align: left; } -.panel-header-dory { +.panel-header-refined { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; - margin-bottom: 24px; + margin-bottom: 20px; } .panel-header-copy { @@ -241,13 +241,13 @@ .hero-logo { display: block; - width: 72px; - height: 72px; - border-radius: 22px; + width: 68px; + height: 68px; + border-radius: 20px; padding: 10px; - background: rgba(255, 255, 255, 0.9); - border: 1px solid rgba(216, 201, 184, 0.5); - box-shadow: 0 16px 36px rgba(31, 26, 23, 0.08); + background: rgba(255, 255, 255, 0.96); + border: 1px solid rgba(216, 201, 184, 0.42); + box-shadow: 0 12px 28px rgba(31, 26, 23, 0.06); object-fit: contain; flex-shrink: 0; } From 1f673fb2f0e378b06e162b1df7c56294de530f3a Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Tue, 7 Apr 2026 09:22:15 +0000 Subject: [PATCH 03/27] fix(web-ui): hide scrollbars and harden reset-main --- cmd/reset-main.js | 14 ++++++++---- web-ui/partials/index/layout-header.html | 2 +- web-ui/styles/sessions-list.css | 29 +++++------------------- web-ui/styles/sessions-preview.css | 10 ++++++-- web-ui/styles/skills-list.css | 18 +++++++-------- 5 files changed, 32 insertions(+), 41 deletions(-) diff --git a/cmd/reset-main.js b/cmd/reset-main.js index 795ec39..6a6fe15 100644 --- a/cmd/reset-main.js +++ b/cmd/reset-main.js @@ -24,19 +24,23 @@ function main() { process.exit(1); } - console.log('[1/5] Fetch origin/main'); + console.log('[1/6] Fetch origin/main'); run('git fetch origin main --prune'); - console.log('[2/5] Checkout main'); + console.log('[2/6] Discard local changes'); + run('git reset --hard'); + run('git clean -fd'); + + console.log('[3/6] Checkout main'); run('git checkout main'); - console.log('[3/5] Reset local changes to origin/main'); + console.log('[4/6] Reset local changes to origin/main'); run('git reset --hard origin/main'); - console.log('[4/5] Remove untracked files'); + console.log('[5/6] Remove untracked files'); run('git clean -fd'); - console.log('[5/5] Final status'); + console.log('[6/6] Final status'); run('git status --short --branch'); console.log('Done. Working tree synced to origin/main.'); diff --git a/web-ui/partials/index/layout-header.html b/web-ui/partials/index/layout-header.html index d7fa19c..702c2d9 100644 --- a/web-ui/partials/index/layout-header.html +++ b/web-ui/partials/index/layout-header.html @@ -18,7 +18,7 @@ Codex Mate.
- 把层级、留白和信息编排重新整理清楚,只保留 codexmate 真正需要的入口、状态和操作,不把界面硬凑成花架子。 + 统一管理 Codex、Claude Code、OpenClaw 与本地会话。 本地配置中枢,统一管理 Codex / Claude Code / OpenClaw / 会话。
diff --git a/web-ui/styles/sessions-list.css b/web-ui/styles/sessions-list.css index 102ffa1..cfbb869 100644 --- a/web-ui/styles/sessions-list.css +++ b/web-ui/styles/sessions-list.css @@ -178,34 +178,17 @@ max-height: none; overflow-y: auto; overflow-x: hidden; - padding-right: 4px; + padding-right: 0; min-width: 0; - scrollbar-width: thin; - scrollbar-color: rgba(166, 149, 130, 0.85) transparent; + scrollbar-width: none; + -ms-overflow-style: none; } .session-list::-webkit-scrollbar, .session-preview-scroll::-webkit-scrollbar { - width: 10px; - height: 10px; -} - -.session-list::-webkit-scrollbar-track, -.session-preview-scroll::-webkit-scrollbar-track { - background: transparent; - border-radius: 999px; -} - -.session-list::-webkit-scrollbar-thumb, -.session-preview-scroll::-webkit-scrollbar-thumb { - background: linear-gradient(to bottom, rgba(191, 174, 154, 0.95) 0%, rgba(160, 141, 121, 0.95) 100%); - border-radius: 999px; - border: 2px solid rgba(255, 255, 255, 0.9); -} - -.session-list::-webkit-scrollbar-thumb:hover, -.session-preview-scroll::-webkit-scrollbar-thumb:hover { - background: linear-gradient(to bottom, rgba(175, 156, 136, 0.95) 0%, rgba(145, 126, 107, 0.95) 100%); + width: 0; + height: 0; + display: none; } .session-item { diff --git a/web-ui/styles/sessions-preview.css b/web-ui/styles/sessions-preview.css index 7a3ce40..e269d8d 100644 --- a/web-ui/styles/sessions-preview.css +++ b/web-ui/styles/sessions-preview.css @@ -12,8 +12,14 @@ padding-right: 68px; display: flex; flex-direction: column; - scrollbar-width: thin; - scrollbar-color: rgba(166, 149, 130, 0.85) transparent; + scrollbar-width: none; + -ms-overflow-style: none; +} + +.session-preview-scroll::-webkit-scrollbar { + width: 0; + height: 0; + display: none; } .session-preview-header { diff --git a/web-ui/styles/skills-list.css b/web-ui/styles/skills-list.css index 2c99193..d52fdd3 100644 --- a/web-ui/styles/skills-list.css +++ b/web-ui/styles/skills-list.css @@ -14,29 +14,27 @@ margin-bottom: var(--spacing-sm); max-height: min(52vh, 440px); overflow-y: auto; - padding-right: 2px; - scrollbar-width: thin; - scrollbar-color: rgba(166, 149, 130, 0.82) transparent; + padding-right: 0; + scrollbar-width: none; + -ms-overflow-style: none; } .skill-list::-webkit-scrollbar { - width: 6px; - height: 6px; + width: 0; + height: 0; } .skill-list::-webkit-scrollbar-track { background: transparent; - border-radius: 999px; } .skill-list::-webkit-scrollbar-thumb { - background: linear-gradient(to bottom, rgba(191, 174, 154, 0.95) 0%, rgba(160, 141, 121, 0.9) 100%); - border-radius: 999px; - border: 1px solid rgba(255, 255, 255, 0.9); + background: transparent; + border: 0; } .skill-list::-webkit-scrollbar-thumb:hover { - background: linear-gradient(to bottom, rgba(176, 157, 137, 0.95) 0%, rgba(145, 126, 107, 0.92) 100%); + background: transparent; } .skill-item { From 4c39313fb42a02e59b6333e33f51536312904a3c Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Tue, 7 Apr 2026 13:35:18 +0000 Subject: [PATCH 04/27] fix(web-ui): tighten layout polish and parity drift --- cmd/reset-main.js | 3 +++ tests/unit/web-ui-behavior-parity.test.mjs | 4 +--- web-ui/partials/index/layout-header.html | 10 ++++---- web-ui/styles/layout-shell.css | 27 +++++++++++++++++----- web-ui/styles/responsive.css | 10 ++++---- web-ui/styles/sessions-list.css | 3 +-- 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/cmd/reset-main.js b/cmd/reset-main.js index 6a6fe15..a25216f 100644 --- a/cmd/reset-main.js +++ b/cmd/reset-main.js @@ -2,6 +2,7 @@ /** * Reset working tree to origin/main: * - fetch origin/main + * - discard local changes * - checkout main * - hard reset to origin/main * - clean untracked files/dirs @@ -37,6 +38,8 @@ function main() { console.log('[4/6] Reset local changes to origin/main'); run('git reset --hard origin/main'); + // Defensive extra clean: keep this pass in case future reset steps create + // untracked files before the final status check. console.log('[5/6] Remove untracked files'); run('git clean -fd'); diff --git a/tests/unit/web-ui-behavior-parity.test.mjs b/tests/unit/web-ui-behavior-parity.test.mjs index a993dba..a62b54b 100644 --- a/tests/unit/web-ui-behavior-parity.test.mjs +++ b/tests/unit/web-ui-behavior-parity.test.mjs @@ -322,9 +322,7 @@ test('captured bundled app skeleton only exposes expected data key drift versus const allowedExtraCurrentKeys = parityAgainstHead ? [] : [ 'sessionsViewMode' ]; - const allowedMissingCurrentKeys = parityAgainstHead ? [ - 'sessionsViewMode' - ] : []; + const allowedMissingCurrentKeys = parityAgainstHead ? [] : []; if (parityAgainstHead) { const allowedExtraKeySet = new Set(allowedExtraCurrentKeys); const allowedMissingKeySet = new Set(allowedMissingCurrentKeys); diff --git a/web-ui/partials/index/layout-header.html b/web-ui/partials/index/layout-header.html index 702c2d9..18c0de8 100644 --- a/web-ui/partials/index/layout-header.html +++ b/web-ui/partials/index/layout-header.html @@ -28,7 +28,7 @@ class="hero-link-pill" href="https://github.com/SakuraByteCore/codexmate" target="_blank" - rel="noopener" + rel="noopener noreferrer" title="打开 GitHub 仓库"> GitHub SakuraByteCore/codexmate @@ -45,7 +45,7 @@ class="github-badge github-badge-mobile" href="https://github.com/SakuraByteCore/codexmate" target="_blank" - rel="noopener" + rel="noopener noreferrer" title="打开 GitHub 仓库">
{{ mainTab === 'config' ? '配置中心' : (mainTab === 'sessions' ? '会话浏览' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? '技能市场' : '设置'))) }}
-

{{ mainTab === 'config' ? '本地 AI 工作台' : (mainTab === 'sessions' ? '会话与上下文' : (mainTab === 'usage' ? '本地用量与趋势' : (mainTab === 'market' ? '技能与分发' : '运行与数据设置'))) }}

-

{{ mainTab === 'config' ? '集中整理 Codex、Claude Code 与 OpenClaw 的关键配置,保持入口清爽、信息成组。' : (mainTab === 'sessions' ? '统一查看、检索和导出 Codex / Claude 会话,不把信息挤成一坨。' : (mainTab === 'usage' ? '把用量统计独立出来,避免会话浏览和趋势信息互相打架。' : (mainTab === 'market' ? '围绕本地 Skills 的安装、导入与同步建立清晰工作流。' : '处理下载、数据管理与全局行为,不往别的面板乱塞杂项。'))) }}

+

{{ mainTab === 'config' ? '配置与运行' : (mainTab === 'sessions' ? '会话与上下文' : (mainTab === 'usage' ? '本地用量与趋势' : (mainTab === 'market' ? '技能与分发' : '运行与数据设置'))) }}

+

{{ mainTab === 'config' ? '统一处理 Provider、Claude Code 与 OpenClaw 配置。' : (mainTab === 'sessions' ? '查看、检索、导出并继续处理本地会话记录。' : (mainTab === 'usage' ? '单独查看本地使用趋势与活跃来源。' : (mainTab === 'market' ? '围绕本地 Skills 的安装、导入与同步整理入口。' : '管理下载、数据目录与全局行为。'))) }}

diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index cf3f2fc..79bfd8d 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -45,8 +45,8 @@ body::after { ============================================ */ .app-shell { display: grid; - grid-template-columns: 272px minmax(0, 1fr) 332px; - gap: 20px; + grid-template-columns: minmax(188px, 248px) minmax(0, 1fr) minmax(220px, 292px); + gap: 18px; align-items: flex-start; } @@ -60,12 +60,12 @@ body::after { align-self: start; display: flex; flex-direction: column; - gap: 16px; - padding: 16px 12px; + gap: var(--spacing-sm); + padding: var(--spacing-sm) 12px; background: linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(255, 251, 247, 0.9) 100%); border: 1px solid rgba(216, 201, 184, 0.44); - border-radius: 22px; - box-shadow: 0 14px 34px rgba(31, 26, 23, 0.06); + border-radius: var(--radius-xl); + box-shadow: var(--shadow-card); min-height: 420px; backdrop-filter: blur(12px); } @@ -408,6 +408,21 @@ body::after { .hero-link-pill { color: var(--color-text-primary); text-decoration: none; + transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth), box-shadow var(--transition-fast) var(--ease-smooth); +} + +.hero-link-pill:hover { + border-color: rgba(201, 94, 75, 0.46); + background: rgba(255, 252, 249, 0.98); + color: var(--color-text-primary); +} + +.hero-link-pill:focus, +.hero-link-pill:focus-visible { + outline: 3px solid rgba(201, 94, 75, 0.22); + outline-offset: 2px; + border-color: rgba(201, 94, 75, 0.54); + background: rgba(255, 252, 249, 0.98); } .hero-link-label, diff --git a/web-ui/styles/responsive.css b/web-ui/styles/responsive.css index 40819fa..1b0b972 100644 --- a/web-ui/styles/responsive.css +++ b/web-ui/styles/responsive.css @@ -13,8 +13,8 @@ textarea:focus-visible { @media (max-width: 1280px) { .app-shell { - grid-template-columns: 236px minmax(0, 1fr) 292px; - gap: 16px; + grid-template-columns: minmax(168px, 216px) minmax(0, 1fr) minmax(200px, 252px); + gap: 14px; } .status-inspector { @@ -123,7 +123,7 @@ textarea:focus-visible { .subtitle { font-size: var(--font-size-secondary); - margin-bottom: 16px; + margin-bottom: 0; } .segmented-control { @@ -132,8 +132,8 @@ textarea:focus-visible { } .status-strip { - flex-direction: row; - flex-wrap: wrap; + grid-template-columns: 1fr; + gap: 12px; } .market-grid { diff --git a/web-ui/styles/sessions-list.css b/web-ui/styles/sessions-list.css index cfbb869..27bf123 100644 --- a/web-ui/styles/sessions-list.css +++ b/web-ui/styles/sessions-list.css @@ -184,8 +184,7 @@ -ms-overflow-style: none; } -.session-list::-webkit-scrollbar, -.session-preview-scroll::-webkit-scrollbar { +.session-list::-webkit-scrollbar { width: 0; height: 0; display: none; From 49a95671a7450355852ffca09efc424415c9e69e Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Tue, 7 Apr 2026 14:50:05 +0000 Subject: [PATCH 05/27] refactor(web-ui): harden layout hierarchy --- web-ui/partials/index/layout-header.html | 29 ++-- web-ui/styles/layout-shell.css | 185 ++++++++++++----------- web-ui/styles/navigation-panels.css | 142 ++++++++--------- web-ui/styles/responsive.css | 27 ++-- web-ui/styles/titles-cards.css | 98 ++++++------ 5 files changed, 233 insertions(+), 248 deletions(-) diff --git a/web-ui/partials/index/layout-header.html b/web-ui/partials/index/layout-header.html index 18c0de8..8dcd8b7 100644 --- a/web-ui/partials/index/layout-header.html +++ b/web-ui/partials/index/layout-header.html @@ -10,32 +10,27 @@
-
LOCAL AI WORKSPACE
-
- -
-
- Codex Mate. -
-
- 统一管理 Codex、Claude Code、OpenClaw 与本地会话。 - 本地配置中枢,统一管理 Codex / Claude Code / OpenClaw / 会话。 -
+
+
Codex Mate 工作台
+
+ 当前区域 + {{ mainTab === 'config' ? '配置中心' : (mainTab === 'sessions' ? '会话浏览' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? '技能市场' : '设置'))) }}
-
-
- GitHub + 仓库 SakuraByteCore/codexmate -
- 当前区域 - {{ mainTab === 'config' ? '配置中心' : (mainTab === 'sessions' ? '会话浏览' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? '技能市场' : '设置'))) }} +
+
+
本地配置、会话与技能入口
+
+ 统一处理 Codex、Claude Code、OpenClaw 与本地会话。 + 本地配置中枢,统一管理 Codex / Claude Code / OpenClaw / 会话。
diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 79bfd8d..3cbbe47 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -6,10 +6,9 @@ body::before { position: fixed; inset: 0; background: - radial-gradient(circle at top left, rgba(208, 88, 58, 0.04), transparent 28%), - radial-gradient(circle at top right, rgba(245, 201, 160, 0.1), transparent 24%), - linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0)); - opacity: 0.84; + radial-gradient(circle at top left, rgba(208, 88, 58, 0.025), transparent 24%), + linear-gradient(180deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0)); + opacity: 0.58; pointer-events: none; z-index: 0; } @@ -20,10 +19,10 @@ body::after { position: fixed; inset: 0; background-image: - linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px), - linear-gradient(0deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px); - background-size: 180px 180px; - opacity: 0.04; + linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px), + linear-gradient(0deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px); + background-size: 220px 220px; + opacity: 0.018; pointer-events: none; z-index: 0; } @@ -60,14 +59,14 @@ body::after { align-self: start; display: flex; flex-direction: column; - gap: var(--spacing-sm); - padding: var(--spacing-sm) 12px; - background: linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(255, 251, 247, 0.9) 100%); - border: 1px solid rgba(216, 201, 184, 0.44); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-card); + gap: 10px; + padding: 12px 10px; + background: rgba(255, 255, 255, 0.88); + border: 1px solid rgba(216, 201, 184, 0.34); + border-radius: 18px; + box-shadow: 0 8px 18px rgba(31, 26, 23, 0.035); min-height: 420px; - backdrop-filter: blur(12px); + backdrop-filter: blur(8px); } .side-rail .brand-title { @@ -92,46 +91,44 @@ body::after { .side-item { width: 100%; text-align: left; - padding: 12px var(--spacing-sm); - border-radius: var(--radius-lg); - border: 1px solid var(--color-border-soft); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(255, 247, 240, 0.95) 100%); + padding: 11px var(--spacing-sm); + border-radius: 12px; + border: 1px solid rgba(216, 201, 184, 0.34); + background: rgba(255, 255, 255, 0.92); color: var(--color-text-secondary); cursor: pointer; - transition: none; + transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth); display: flex; flex-direction: column; gap: 6px; - box-shadow: var(--shadow-subtle); + box-shadow: none; } .side-item:hover { - border-color: var(--color-brand); + border-color: rgba(201, 94, 75, 0.38); color: var(--color-text-primary); - transform: translateY(-1px); - box-shadow: var(--shadow-card-hover); } .side-item.active { - border-color: var(--color-brand); - background: linear-gradient(135deg, rgba(201, 94, 75, 0.14), rgba(255, 255, 255, 0.96)); + border-color: rgba(201, 94, 75, 0.48); + background: rgba(249, 244, 240, 0.98); color: var(--color-text-primary); - box-shadow: var(--shadow-float); + box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.06); } .side-item.nav-intent-active { - border-color: var(--color-brand); - background: linear-gradient(135deg, rgba(201, 94, 75, 0.14), rgba(255, 255, 255, 0.96)); + border-color: rgba(201, 94, 75, 0.48); + background: rgba(249, 244, 240, 0.98); color: var(--color-text-primary); - box-shadow: var(--shadow-float); + box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.06); } .side-item.nav-intent-inactive, .side-item.active.nav-intent-inactive { - border-color: var(--color-border-soft); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(255, 247, 240, 0.95) 100%); + border-color: rgba(216, 201, 184, 0.34); + background: rgba(255, 255, 255, 0.92); color: var(--color-text-secondary); - box-shadow: var(--shadow-subtle); + box-shadow: none; } .side-item-title { @@ -203,10 +200,10 @@ body::after { } .brand-subtitle { - margin-top: 4px; - font-size: 12px; + margin-top: 2px; + font-size: 11px; color: var(--color-text-tertiary); - line-height: 1.5; + line-height: 1.45; max-width: 18ch; } @@ -216,18 +213,18 @@ body::after { align-items: center; justify-content: space-between; gap: 10px; - margin-top: 6px; - padding: 7px 11px; - border-radius: 999px; - border: 1px solid rgba(216, 201, 184, 0.42); - background: rgba(255, 255, 255, 0.9); + margin-top: 4px; + padding: 8px 10px; + border-radius: 12px; + border: 1px solid rgba(216, 201, 184, 0.4); + background: rgba(255, 255, 255, 0.82); color: var(--color-text-secondary); font-size: var(--font-size-caption); text-decoration: none; - box-shadow: var(--shadow-subtle); - transition: all var(--transition-fast) var(--ease-spring); + box-shadow: none; + transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth), box-shadow var(--transition-fast) var(--ease-smooth); min-width: 0; - backdrop-filter: blur(6px); + backdrop-filter: blur(4px); } .github-badge-rail { @@ -235,18 +232,26 @@ body::after { align-items: center; justify-content: flex-start; gap: 8px; - padding: 6px 8px; + padding: 8px 9px; border-radius: 10px; - background: rgba(255, 255, 255, 0.8); - border: 1px solid rgba(216, 201, 184, 0.5); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7); + background: rgba(255, 255, 255, 0.72); + border: 1px solid rgba(216, 201, 184, 0.38); + box-shadow: none; } .github-badge:hover { - border-color: rgba(201, 94, 75, 0.5); + border-color: rgba(201, 94, 75, 0.46); + background: rgba(255, 255, 255, 0.92); color: var(--color-text-primary); - transform: translateY(-1px); - box-shadow: 0 6px 12px rgba(27, 23, 20, 0.08); + box-shadow: 0 0 0 1px rgba(201, 94, 75, 0.08); +} + +.github-badge:focus-visible { + outline: 3px solid rgba(201, 94, 75, 0.22); + outline-offset: 2px; + border-color: rgba(201, 94, 75, 0.52); + color: var(--color-text-primary); + background: rgba(255, 255, 255, 0.94); } .github-badge-icon { @@ -330,32 +335,22 @@ body::after { } .github-badge-rail:hover { - transform: translateY(-1px); border-color: rgba(201, 94, 75, 0.5); } .hero-surface { margin-bottom: 18px; - padding: 22px 24px; - border-radius: 26px; - border: 1px solid rgba(216, 201, 184, 0.44); - background: - linear-gradient(135deg, rgba(255, 255, 255, 0.96) 0%, rgba(255, 251, 247, 0.93) 100%), - radial-gradient(circle at top right, rgba(208, 88, 58, 0.04), transparent 24%); - box-shadow: 0 18px 42px rgba(31, 26, 23, 0.06); + padding: 16px 20px; + border-radius: 18px; + border: 1px solid rgba(216, 201, 184, 0.36); + background: rgba(255, 255, 255, 0.9); + box-shadow: 0 10px 22px rgba(31, 26, 23, 0.035); position: relative; overflow: hidden; } .hero-surface::after { - content: ""; - position: absolute; - inset: auto -40px -80px auto; - width: 220px; - height: 220px; - border-radius: 50%; - background: radial-gradient(circle, rgba(208, 88, 58, 0.04), transparent 68%); - pointer-events: none; + display: none; } .hero-copy { @@ -363,46 +358,51 @@ body::after { z-index: 1; display: flex; flex-direction: column; - gap: 18px; + gap: 12px; +} + +.hero-meta-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; } .hero-eyebrow { - font-size: 12px; + font-size: 11px; font-weight: 700; - letter-spacing: 0.18em; + letter-spacing: 0.08em; color: var(--color-text-tertiary); + text-transform: uppercase; } .hero-title-row { display: flex; - align-items: center; - gap: 18px; + align-items: flex-end; + justify-content: space-between; + gap: 16px; } .hero-title-block { display: flex; flex-direction: column; - gap: 8px; -} - -.hero-actions-row { - display: flex; - flex-wrap: wrap; - gap: 12px; - align-items: center; + gap: 4px; + min-width: 0; } .hero-link-pill, .hero-summary-pill { display: inline-flex; align-items: center; - gap: 10px; - min-height: 38px; - padding: 0 13px; - border-radius: 999px; - border: 1px solid rgba(216, 201, 184, 0.48); - background: rgba(255, 255, 255, 0.92); - box-shadow: var(--shadow-subtle); + gap: 8px; + min-height: 34px; + min-width: 0; + max-width: 100%; + padding: 0 11px; + border-radius: 10px; + border: 1px solid rgba(216, 201, 184, 0.38); + background: rgba(251, 249, 246, 0.92); + box-shadow: none; } .hero-link-pill { @@ -413,7 +413,7 @@ body::after { .hero-link-pill:hover { border-color: rgba(201, 94, 75, 0.46); - background: rgba(255, 252, 249, 0.98); + background: rgba(255, 255, 255, 0.98); color: var(--color-text-primary); } @@ -422,15 +422,16 @@ body::after { outline: 3px solid rgba(201, 94, 75, 0.22); outline-offset: 2px; border-color: rgba(201, 94, 75, 0.54); - background: rgba(255, 252, 249, 0.98); + background: rgba(255, 255, 255, 0.98); } .hero-link-label, .hero-summary-label { font-size: 11px; - letter-spacing: 0.08em; + letter-spacing: 0.04em; text-transform: uppercase; color: var(--color-text-tertiary); + flex-shrink: 0; } .hero-link-value, @@ -438,4 +439,8 @@ body::after { font-size: 13px; font-weight: 600; color: var(--color-text-primary); + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index 1ebfb64..9271774 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -34,18 +34,18 @@ .status-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); - gap: 12px; - margin-bottom: 18px; - margin-top: 8px; + gap: 10px; + margin-bottom: 16px; + margin-top: 6px; } .status-chip { min-width: 0; - padding: 13px 15px; - border-radius: 16px; - border: 1px solid rgba(216, 201, 184, 0.38); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.99) 0%, rgba(255, 252, 249, 0.96) 100%); - box-shadow: var(--shadow-subtle); + padding: 12px 13px; + border-radius: 12px; + border: 1px solid rgba(216, 201, 184, 0.32); + background: rgba(252, 250, 247, 0.96); + box-shadow: none; } .status-chip .label { @@ -68,10 +68,10 @@ .provider-fast-switch { margin: 0 0 var(--spacing-sm); padding: 10px 12px; - border-radius: var(--radius-lg); - border: 1px solid rgba(216, 201, 184, 0.6); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(255, 249, 243, 0.96) 100%); - box-shadow: var(--shadow-subtle); + border-radius: 12px; + border: 1px solid rgba(216, 201, 184, 0.42); + background: rgba(252, 250, 247, 0.96); + box-shadow: none; display: grid; gap: 6px; } @@ -108,12 +108,12 @@ .main-panel { min-width: 0; - background: rgba(255, 255, 255, 0.92); - border: 1px solid rgba(216, 201, 184, 0.4); - border-radius: 24px; - box-shadow: 0 18px 42px rgba(31, 26, 23, 0.06); - padding: 24px 28px; - backdrop-filter: blur(10px); + background: rgba(255, 255, 255, 0.96); + border: 1px solid rgba(216, 201, 184, 0.34); + border-radius: 18px; + box-shadow: 0 12px 24px rgba(31, 26, 23, 0.035); + padding: 22px 24px; + backdrop-filter: blur(6px); position: relative; overflow-x: hidden; overflow-y: visible; @@ -125,14 +125,14 @@ align-self: start; height: calc(100vh - 48px); overflow: auto; - padding: 16px; - border-radius: var(--radius-xl); - border: 1px solid var(--color-border-soft); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(255, 248, 241, 0.92) 100%); - box-shadow: var(--shadow-card); + padding: 14px; + border-radius: 16px; + border: 1px solid rgba(216, 201, 184, 0.34); + background: rgba(250, 248, 245, 0.92); + box-shadow: 0 8px 18px rgba(31, 26, 23, 0.03); display: flex; flex-direction: column; - gap: 12px; + gap: 10px; } .inspector-head { @@ -154,11 +154,11 @@ } .inspector-group { - padding: 12px; - border-radius: var(--radius-lg); - border: 1px solid rgba(216, 201, 184, 0.34); - background: rgba(255, 255, 255, 0.88); - box-shadow: var(--shadow-subtle); + padding: 11px; + border-radius: 12px; + border: 1px solid rgba(216, 201, 184, 0.28); + background: rgba(255, 255, 255, 0.82); + box-shadow: none; } .inspector-group-title { @@ -213,20 +213,22 @@ display: flex; align-items: flex-start; justify-content: space-between; - gap: 18px; - margin-bottom: 20px; + gap: 14px; + margin-bottom: 16px; + padding-bottom: 12px; + border-bottom: 1px solid rgba(216, 201, 184, 0.24); } .panel-header-copy { display: flex; flex-direction: column; - gap: 8px; - max-width: 760px; + gap: 6px; + max-width: 720px; } .panel-kicker { - font-size: 12px; - letter-spacing: 0.12em; + font-size: 11px; + letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-text-tertiary); font-weight: 700; @@ -240,24 +242,15 @@ } .hero-logo { - display: block; - width: 68px; - height: 68px; - border-radius: 20px; - padding: 10px; - background: rgba(255, 255, 255, 0.96); - border: 1px solid rgba(216, 201, 184, 0.42); - box-shadow: 0 12px 28px rgba(31, 26, 23, 0.06); - object-fit: contain; - flex-shrink: 0; + display: none; } .hero-title { - font-size: 56px; - line-height: 1; + font-size: clamp(22px, 2.4vw, 30px); + line-height: 1.08; font-family: var(--font-family-display); color: var(--color-text-primary); - letter-spacing: -0.04em; + letter-spacing: -0.025em; } .hero-title .accent { @@ -266,10 +259,10 @@ .hero-subtitle { margin-top: 0; - font-size: 15px; + font-size: 13px; color: var(--color-text-tertiary); - line-height: 1.7; - max-width: 64ch; + line-height: 1.5; + max-width: 54ch; } .hero-github { @@ -278,57 +271,56 @@ } .top-tabs { - margin: 14px 0 18px; - background: rgba(255, 255, 255, 0.92); - border: 1px solid rgba(255, 255, 255, 0.7); - border-radius: 14px; - padding: 6px; - box-shadow: inset 0 1px 2px rgba(31, 26, 23, 0.06); + margin: 12px 0 16px; + background: rgba(255, 255, 255, 0.88); + border: 1px solid rgba(216, 201, 184, 0.3); + border-radius: 12px; + padding: 5px; + box-shadow: none; display: grid; grid-template-columns: repeat(4, 1fr); - gap: 8px; - backdrop-filter: blur(6px); + gap: 6px; + backdrop-filter: blur(4px); } .top-tab { - border: 1px solid rgba(216, 201, 184, 0.55); - border-radius: 12px; - background: rgba(255, 255, 255, 0.96); - padding: 11px 10px; + border: 1px solid rgba(216, 201, 184, 0.42); + border-radius: 10px; + background: rgba(255, 255, 255, 0.94); + padding: 10px 10px; font-size: var(--font-size-body); color: var(--color-text-secondary); text-align: center; cursor: pointer; - transition: none; - box-shadow: var(--shadow-subtle); + transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth); + box-shadow: none; } .top-tab:hover { border-color: var(--color-brand); color: var(--color-text-primary); - transform: translateY(-1px); } .top-tab.active { - border-color: var(--color-brand); + border-color: rgba(201, 94, 75, 0.46); color: var(--color-text-primary); - background: linear-gradient(135deg, rgba(201, 94, 75, 0.12), rgba(255, 255, 255, 0.95)); - box-shadow: 0 10px 24px rgba(27, 23, 20, 0.08); + background: rgba(249, 244, 240, 0.98); + box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.08); } .top-tab.nav-intent-active { - border-color: var(--color-brand); + border-color: rgba(201, 94, 75, 0.46); color: var(--color-text-primary); - background: linear-gradient(135deg, rgba(201, 94, 75, 0.12), rgba(255, 255, 255, 0.95)); - box-shadow: 0 10px 24px rgba(27, 23, 20, 0.08); + background: rgba(249, 244, 240, 0.98); + box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.08); } .top-tab.nav-intent-inactive, .top-tab.active.nav-intent-inactive { - border-color: rgba(216, 201, 184, 0.55); + border-color: rgba(216, 201, 184, 0.42); color: var(--color-text-secondary); - background: rgba(255, 255, 255, 0.96); - box-shadow: var(--shadow-subtle); + background: rgba(255, 255, 255, 0.94); + box-shadow: none; } #panel-sessions.session-panel-fast-hidden { diff --git a/web-ui/styles/responsive.css b/web-ui/styles/responsive.css index 1b0b972..e815a56 100644 --- a/web-ui/styles/responsive.css +++ b/web-ui/styles/responsive.css @@ -23,11 +23,11 @@ textarea:focus-visible { } .main-panel { - padding: 22px 24px; + padding: 20px 22px; } .hero-surface { - padding: 20px 22px; + padding: 15px 18px; } } @@ -65,17 +65,14 @@ textarea:focus-visible { } .hero-surface { - padding: 18px; - border-radius: 22px; + padding: 16px; + border-radius: 16px; } + .hero-meta-row, .hero-title-row { - align-items: flex-start; - } - - .hero-actions-row { flex-direction: column; - align-items: stretch; + align-items: flex-start; } .top-tabs { display: grid !important; @@ -110,15 +107,11 @@ textarea:focus-visible { @media (max-width: 720px) { .main-title { - font-size: 36px; + font-size: 34px; } .hero-title { - font-size: 32px; - } - - .hero-title-row { - flex-direction: column; + font-size: 30px; } .subtitle { @@ -171,14 +164,14 @@ textarea:focus-visible { padding: 0 var(--spacing-sm) var(--spacing-md); } .hero-title { - font-size: 30px; + font-size: 28px; } .hero-subtitle { font-size: var(--font-size-secondary); } .hero-surface { - padding: 16px 14px; + padding: 14px 12px; } .hero-link-pill, diff --git a/web-ui/styles/titles-cards.css b/web-ui/styles/titles-cards.css index 8fcc2a4..fa52601 100644 --- a/web-ui/styles/titles-cards.css +++ b/web-ui/styles/titles-cards.css @@ -2,17 +2,17 @@ 主标题 ============================================ */ .main-title { - font-size: clamp(34px, 4.2vw, 56px); + font-size: clamp(30px, 3.2vw, 42px); font-weight: var(--font-weight-display); - line-height: 0.98; - letter-spacing: -0.05em; + line-height: 1.02; + letter-spacing: -0.04em; margin-bottom: 0; color: var(--color-text-primary); font-family: var(--font-family-display); - background: linear-gradient(135deg, var(--color-text-primary) 0%, rgba(27, 23, 20, 0.72) 100%); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; + background: none; + -webkit-background-clip: border-box; + -webkit-text-fill-color: currentColor; + background-clip: border-box; } .main-title .accent { @@ -22,12 +22,12 @@ } .subtitle { - font-size: 15px; + font-size: 14px; color: var(--color-text-tertiary); - line-height: 1.75; + line-height: 1.6; margin-bottom: 0; - max-width: 60ch; - letter-spacing: 0.01em; + max-width: 56ch; + letter-spacing: 0; } /* ============================================ @@ -35,30 +35,30 @@ ============================================ */ .segmented-control { display: flex; - background: rgba(255, 255, 255, 0.92); - border-radius: var(--radius-xl); - padding: 6px; - margin-bottom: 20px; + background: rgba(250, 248, 245, 0.92); + border-radius: 12px; + padding: 5px; + margin-bottom: 18px; position: relative; - box-shadow: inset 0 1px 2px rgba(31, 26, 23, 0.06); - border: 1px solid rgba(255, 255, 255, 0.7); - backdrop-filter: blur(6px); + box-shadow: none; + border: 1px solid rgba(216, 201, 184, 0.32); + backdrop-filter: blur(4px); } .segment { flex: 1; - padding: 11px 16px; + padding: 10px 14px; border: none; background: transparent; font-size: var(--font-size-body); font-weight: var(--font-weight-secondary); color: var(--color-text-secondary); cursor: pointer; - border-radius: 10px; - transition: all var(--transition-normal) var(--ease-spring); + border-radius: 9px; + transition: color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth); position: relative; z-index: 2; - letter-spacing: 0.01em; + letter-spacing: 0; } .segment:hover { @@ -67,8 +67,8 @@ .segment.active { color: var(--color-text-primary); - background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.8) 100%); - box-shadow: var(--shadow-subtle), inset 0 1px 0 rgba(255, 255, 255, 0.85); + background: rgba(255, 255, 255, 0.96); + box-shadow: inset 0 0 0 1px rgba(216, 201, 184, 0.28); } /* ============================================ @@ -85,28 +85,28 @@ 卡片 ============================================ */ .card { - background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(255, 249, 243, 0.9) 100%); - border-radius: 20px; - padding: 14px; + background: rgba(255, 255, 255, 0.96); + border-radius: 14px; + padding: 13px; display: flex; align-items: center; justify-content: space-between; cursor: pointer; transition: - transform var(--transition-normal) var(--ease-spring), - box-shadow var(--transition-normal) var(--ease-spring), - background-color var(--transition-fast) var(--ease-smooth); - box-shadow: 0 18px 36px rgba(27, 23, 20, 0.06); + border-color var(--transition-fast) var(--ease-smooth), + background-color var(--transition-fast) var(--ease-smooth), + box-shadow var(--transition-fast) var(--ease-smooth); + box-shadow: none; user-select: none; - will-change: transform; - border: 1px solid rgba(216, 201, 184, 0.48); + will-change: auto; + border: 1px solid rgba(216, 201, 184, 0.38); position: relative; overflow: hidden; } .card:hover { - transform: translateY(-1px); - box-shadow: var(--shadow-card-hover); + border-color: rgba(201, 94, 75, 0.38); + box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.06); } .card::before, @@ -129,9 +129,9 @@ .card::after { inset: 0; border-radius: inherit; - background: linear-gradient(120deg, rgba(255, 255, 255, 0.7) 0%, transparent 55%); + background: linear-gradient(120deg, rgba(255, 255, 255, 0.35) 0%, transparent 55%); opacity: 0; - transition: opacity var(--transition-normal) var(--ease-smooth); + transition: opacity var(--transition-fast) var(--ease-smooth); } .card:active { @@ -140,9 +140,9 @@ } .card.active { - background: linear-gradient(to bottom, rgba(210, 107, 90, 0.14) 0%, rgba(255, 255, 255, 0.98) 100%); - border-color: rgba(201, 94, 75, 0.55); - box-shadow: 0 10px 28px rgba(210, 107, 90, 0.14); + background: rgba(249, 244, 240, 0.98); + border-color: rgba(201, 94, 75, 0.52); + box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.08); } .card.active::before { @@ -166,10 +166,10 @@ } .card-icon { - width: 40px; - height: 40px; - border-radius: var(--radius-sm); - background: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(247, 241, 232, 0.65) 100%); + width: 38px; + height: 38px; + border-radius: 10px; + background: rgba(247, 241, 232, 0.78); display: flex; align-items: center; justify-content: center; @@ -177,14 +177,14 @@ font-weight: var(--font-weight-title); color: var(--color-text-secondary); flex-shrink: 0; - transition: all var(--transition-normal) var(--ease-spring-soft); - box-shadow: inset 0 1px 2px rgba(255, 255, 255, 0.7); + transition: background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth); + box-shadow: none; } .card.active .card-icon { - background: linear-gradient(135deg, var(--color-brand) 0%, var(--color-brand-dark) 100%); - color: white; - box-shadow: 0 2px 8px rgba(210, 107, 90, 0.3); + background: rgba(201, 94, 75, 0.14); + color: var(--color-brand-dark); + box-shadow: none; } .card-content { From 5309210ed8c64bdf08d59fc8fd5ead577b606ab8 Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Tue, 7 Apr 2026 15:22:48 +0000 Subject: [PATCH 06/27] refactor(web-ui): tighten desktop hierarchy --- web-ui/styles/layout-shell.css | 8 +++-- web-ui/styles/navigation-panels.css | 50 +++++++++++++++-------------- web-ui/styles/titles-cards.css | 10 +++--- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 3cbbe47..5b49954 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -34,7 +34,7 @@ body::after { width: 100%; max-width: 2200px; margin: 0 auto; - padding: 24px 20px 36px; + padding: 18px 20px 32px; position: relative; z-index: 1; } @@ -45,7 +45,7 @@ body::after { .app-shell { display: grid; grid-template-columns: minmax(188px, 248px) minmax(0, 1fr) minmax(220px, 292px); - gap: 18px; + gap: 16px; align-items: flex-start; } @@ -155,6 +155,10 @@ body::after { body:not(.force-compact) #app > .top-tabs { display: none; } + + body:not(.force-compact) #app > .hero-surface { + display: none; + } } .brand-block { diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index 9271774..6e14b31 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -33,26 +33,28 @@ .status-strip { display: grid; - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); - gap: 10px; - margin-bottom: 16px; - margin-top: 6px; + grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); + gap: 8px; + margin-bottom: 14px; + margin-top: 4px; } .status-chip { min-width: 0; - padding: 12px 13px; - border-radius: 12px; - border: 1px solid rgba(216, 201, 184, 0.32); - background: rgba(252, 250, 247, 0.96); - box-shadow: none; + padding: 11px 12px; + border-radius: 10px; + border: 1px solid rgba(216, 201, 184, 0.38); + background: rgba(255, 255, 255, 0.98); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9); } .status-chip .label { display: block; - font-size: var(--font-size-caption); + font-size: 11px; color: var(--color-text-tertiary); - margin-bottom: 4px; + margin-bottom: 3px; + letter-spacing: 0.03em; + text-transform: uppercase; } .status-chip .value { @@ -108,12 +110,12 @@ .main-panel { min-width: 0; - background: rgba(255, 255, 255, 0.96); - border: 1px solid rgba(216, 201, 184, 0.34); - border-radius: 18px; - box-shadow: 0 12px 24px rgba(31, 26, 23, 0.035); - padding: 22px 24px; - backdrop-filter: blur(6px); + background: rgba(255, 255, 255, 0.985); + border: 1px solid rgba(216, 201, 184, 0.4); + border-radius: 16px; + box-shadow: 0 14px 28px rgba(31, 26, 23, 0.04); + padding: 24px 26px; + backdrop-filter: blur(4px); position: relative; overflow-x: hidden; overflow-y: visible; @@ -214,23 +216,23 @@ align-items: flex-start; justify-content: space-between; gap: 14px; - margin-bottom: 16px; - padding-bottom: 12px; - border-bottom: 1px solid rgba(216, 201, 184, 0.24); + margin-bottom: 18px; + padding-bottom: 10px; + border-bottom: 1px solid rgba(216, 201, 184, 0.3); } .panel-header-copy { display: flex; flex-direction: column; - gap: 6px; - max-width: 720px; + gap: 5px; + max-width: 680px; } .panel-kicker { font-size: 11px; - letter-spacing: 0.08em; + letter-spacing: 0.06em; text-transform: uppercase; - color: var(--color-text-tertiary); + color: var(--color-text-secondary); font-weight: 700; } diff --git a/web-ui/styles/titles-cards.css b/web-ui/styles/titles-cards.css index fa52601..c24665f 100644 --- a/web-ui/styles/titles-cards.css +++ b/web-ui/styles/titles-cards.css @@ -2,10 +2,10 @@ 主标题 ============================================ */ .main-title { - font-size: clamp(30px, 3.2vw, 42px); + font-size: clamp(32px, 3.6vw, 46px); font-weight: var(--font-weight-display); - line-height: 1.02; - letter-spacing: -0.04em; + line-height: 0.99; + letter-spacing: -0.045em; margin-bottom: 0; color: var(--color-text-primary); font-family: var(--font-family-display); @@ -24,9 +24,9 @@ .subtitle { font-size: 14px; color: var(--color-text-tertiary); - line-height: 1.6; + line-height: 1.55; margin-bottom: 0; - max-width: 56ch; + max-width: 48ch; letter-spacing: 0; } From 8a9240b0101d747e67f715262dd993fc4ce579db Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Tue, 7 Apr 2026 16:11:46 +0000 Subject: [PATCH 07/27] refactor(web-ui): simplify navigation chrome --- web-ui/partials/index/layout-footer.html | 4 +- web-ui/partials/index/layout-header.html | 17 ++---- web-ui/styles/layout-shell.css | 72 ++++++++---------------- web-ui/styles/navigation-panels.css | 53 +++++++++-------- 4 files changed, 59 insertions(+), 87 deletions(-) diff --git a/web-ui/partials/index/layout-footer.html b/web-ui/partials/index/layout-footer.html index 10336b3..1cb673f 100644 --- a/web-ui/partials/index/layout-footer.html +++ b/web-ui/partials/index/layout-footer.html @@ -12,8 +12,8 @@
diff --git a/web-ui/styles/base-theme.css b/web-ui/styles/base-theme.css index 3f682cf..6e11c77 100644 --- a/web-ui/styles/base-theme.css +++ b/web-ui/styles/base-theme.css @@ -147,10 +147,6 @@ body.force-compact .top-tabs::-webkit-scrollbar { display: none; } -body.force-compact .workbench-bar { - display: flex; -} - body.force-compact .main-panel { padding: 14px 12px; } @@ -261,83 +257,3 @@ body { overflow-x: hidden; } -.fab-install { - position: fixed; - left: auto; - right: 14px; - bottom: calc(14px + env(safe-area-inset-bottom, 0px)); - z-index: 90; - display: inline-grid; - place-items: center; - width: 42px; - height: 42px; - min-width: 40px; - min-height: 40px; - padding: 0; - border-radius: var(--radius-full); - border: 1px solid rgba(201, 94, 75, 0.2); - background: rgba(201, 94, 75, 0.9); - color: #fff; - font-size: 12px; - font-weight: var(--font-weight-secondary); - letter-spacing: 0.015em; - box-shadow: 0 8px 18px rgba(31, 26, 23, 0.1); - cursor: pointer; - overflow: hidden; - transition: - transform var(--transition-fast) var(--ease-spring), - box-shadow var(--transition-fast) var(--ease-spring), - filter var(--transition-fast) var(--ease-smooth); - animation: none; - opacity: 0.82; -} - -.fab-install::after { - content: ""; - position: absolute; - inset: 1px; - border-radius: inherit; - border: 1px solid rgba(255, 255, 255, 0.08); - pointer-events: none; -} - -.fab-install-icon { - width: 16px; - height: 16px; - display: inline-grid; - place-items: center; - color: #fff; - background: transparent; - box-shadow: none; - flex-shrink: 0; -} - -.fab-install-icon svg { - width: 14px; - height: 14px; -} - -.fab-install:hover { - transform: translateY(-1px); - box-shadow: 0 10px 20px rgba(31, 26, 23, 0.12); - filter: saturate(1.02); - opacity: 0.96; -} - -.fab-install:active { - transform: translateY(0); - filter: saturate(0.98); -} - -@media (max-width: 960px) { - .fab-install { - display: none; - } -} - -@media (prefers-reduced-motion: reduce) { - .fab-install { - animation: none; - transition: none; - } -} diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 7abb85d..231de3e 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -34,7 +34,7 @@ body::after { width: 100%; max-width: 2200px; margin: 0 auto; - padding: 14px 16px 22px; + padding: 12px 14px 18px; position: relative; z-index: 1; } @@ -44,8 +44,8 @@ body::after { ============================================ */ .app-shell { display: grid; - grid-template-columns: minmax(216px, 236px) minmax(0, 1fr); - gap: 18px; + grid-template-columns: minmax(196px, 216px) minmax(0, 1fr); + gap: 16px; align-items: flex-start; } @@ -59,13 +59,13 @@ body::after { align-self: start; display: flex; flex-direction: column; - gap: 14px; - padding: 14px 10px 12px; - background: rgba(241, 235, 227, 0.98); - border: 1px solid rgba(198, 180, 159, 0.56); - border-radius: 18px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.78), 0 8px 18px rgba(31, 26, 23, 0.035); - min-height: calc(100vh - 32px); + gap: 12px; + padding: 12px 8px 10px; + background: rgba(242, 237, 231, 0.92); + border: 1px solid rgba(201, 184, 165, 0.42); + border-radius: 16px; + box-shadow: none; + min-height: 0; backdrop-filter: blur(10px); } @@ -77,13 +77,13 @@ body::after { .side-section { display: flex; flex-direction: column; - gap: 6px; + gap: 4px; } .side-rail-nav { display: flex; flex-direction: column; - gap: 12px; + gap: 10px; flex: 1 1 auto; } @@ -99,7 +99,7 @@ body::after { .side-item { width: 100%; text-align: left; - padding: 10px 10px 10px 13px; + padding: 9px 9px 9px 12px; border-radius: 12px; border: 1px solid transparent; background: transparent; @@ -163,7 +163,7 @@ body::after { } .side-item-title { - font-size: 13px; + font-size: 12px; font-weight: 600; letter-spacing: -0.01em; } @@ -171,12 +171,17 @@ body::after { .side-item-meta { font-size: 10px; color: var(--color-text-tertiary); - display: flex; + display: none; gap: 5px; flex-wrap: wrap; line-height: 1.35; } +.side-item.active .side-item-meta, +.side-item.nav-intent-active .side-item-meta { + display: flex; +} + .side-item-meta > span { min-width: 0; overflow-wrap: anywhere; @@ -187,20 +192,16 @@ body::after { body:not(.force-compact) #app > .top-tabs { display: none; } - - body:not(.force-compact) #app > .workbench-bar { - display: none; - } } .brand-block { display: flex; flex-direction: column; align-items: flex-start; - gap: 4px; + gap: 3px; margin-bottom: 0; - padding: 2px 4px 10px; - border-bottom: 1px solid rgba(216, 201, 184, 0.28); + padding: 2px 4px 8px; + border-bottom: 1px solid rgba(216, 201, 184, 0.22); } .brand-kicker { @@ -213,59 +214,21 @@ body::after { } .brand-block::after { - content: "统一管理本地配置、会话与 Skills"; - font-size: 11px; - line-height: 1.35; - color: var(--color-text-tertiary); - max-width: 20ch; + content: "本地配置与会话工作台"; + font-size: 10px; + line-height: 1.3; + color: var(--color-text-muted); + max-width: 18ch; } .brand-title { - font-size: 21px; + font-size: 20px; line-height: 1.02; font-family: var(--font-family-display); color: var(--color-text-primary); letter-spacing: -0.04em; } -.side-rail-footer { - display: flex; - flex-direction: column; - gap: 4px; - padding: 8px 8px 0; - border-top: 1px solid rgba(216, 201, 184, 0.2); -} - -.side-rail-link { - display: inline-flex; - align-items: center; - justify-content: flex-start; - min-width: 0; - padding: 6px 8px; - border-radius: 8px; - border: 1px solid rgba(216, 201, 184, 0.24); - background: rgba(255, 255, 255, 0.42); - color: var(--color-text-primary); - text-decoration: none; - font-size: 11px; - font-family: var(--font-family-mono); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.side-rail-link:hover { - border-color: rgba(201, 94, 75, 0.42); - background: rgba(255, 255, 255, 0.96); -} - -.side-rail-note { - font-size: 10px; - line-height: 1.3; - color: var(--color-text-muted); - padding: 0 2px; -} - .github-badge { display: inline-flex; align-items: center; @@ -395,72 +358,3 @@ body::after { .github-badge-rail:hover { border-color: rgba(201, 94, 75, 0.5); } - -.workbench-bar { - display: none; - align-items: center; - justify-content: space-between; - gap: 12px; - margin-bottom: 10px; - padding: 10px 12px; - border-radius: 14px; - border: 1px solid rgba(216, 201, 184, 0.32); - background: rgba(255, 255, 255, 0.82); - backdrop-filter: blur(8px); -} - -.workbench-bar-copy { - min-width: 0; -} - -.workbench-bar-kicker { - font-size: 10px; - font-weight: 700; - letter-spacing: 0.08em; - color: var(--color-text-tertiary); - text-transform: uppercase; -} - -.workbench-bar-title { - margin-top: 2px; - font-size: 16px; - line-height: 1.15; - letter-spacing: -0.03em; - color: var(--color-text-primary); - font-family: var(--font-family-display); -} - -.workbench-bar-repo { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 0; - max-width: min(34vw, 120px); - padding: 8px 10px; - border-radius: 10px; - border: 1px solid rgba(216, 201, 184, 0.38); - background: rgba(250, 247, 243, 0.96); - box-shadow: none; - color: var(--color-text-primary); - text-decoration: none; - font-size: 12px; - font-family: var(--font-family-body); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth), box-shadow var(--transition-fast) var(--ease-smooth); -} - -.workbench-bar-repo:hover { - border-color: rgba(201, 94, 75, 0.46); - background: rgba(255, 255, 255, 0.98); - color: var(--color-text-primary); -} - -.workbench-bar-repo:focus, -.workbench-bar-repo:focus-visible { - outline: 3px solid rgba(201, 94, 75, 0.22); - outline-offset: 2px; - border-color: rgba(201, 94, 75, 0.54); - background: rgba(255, 255, 255, 0.98); -} diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index 7fb7f80..041dc7b 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -33,24 +33,24 @@ .status-strip { display: grid; - grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); - gap: 8px; - margin-bottom: 14px; + grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); + gap: 6px; + margin-bottom: 10px; margin-top: 0; } .status-chip { min-width: 0; max-width: 100%; - padding: 9px 10px; - border-radius: 12px; + padding: 7px 8px; + border-radius: 10px; border: 1px solid rgba(216, 201, 184, 0.26); background: rgba(248, 244, 239, 0.82); box-shadow: none; display: flex; flex-direction: column; align-items: flex-start; - gap: 3px; + gap: 2px; } .status-chip .label { @@ -64,7 +64,7 @@ } .status-chip .value { - font-size: 13px; + font-size: 12px; font-weight: 600; color: var(--color-text-primary); letter-spacing: -0.01em; @@ -120,12 +120,12 @@ border: 1px solid rgba(208, 192, 173, 0.38); border-radius: 18px; box-shadow: 0 10px 24px rgba(31, 26, 23, 0.03); - padding: 20px 22px; + padding: 16px 18px; backdrop-filter: blur(6px); position: relative; overflow-x: hidden; overflow-y: visible; - min-height: calc(100vh - 32px); + min-height: 0; } .panel-header { @@ -138,8 +138,8 @@ align-items: flex-start; justify-content: space-between; gap: 12px; - margin-bottom: 12px; - padding-bottom: 12px; + margin-bottom: 10px; + padding-bottom: 10px; border-bottom: 1px solid rgba(216, 201, 184, 0.22); } diff --git a/web-ui/styles/responsive.css b/web-ui/styles/responsive.css index 50b364d..f762636 100644 --- a/web-ui/styles/responsive.css +++ b/web-ui/styles/responsive.css @@ -33,14 +33,6 @@ textarea:focus-visible { .side-rail { display: none; } - .workbench-bar { - display: flex; - justify-content: flex-start; - } - - .workbench-bar-repo { - display: none; - } .main-panel { padding: 14px; border-radius: 16px; @@ -97,12 +89,6 @@ textarea:focus-visible { display: none; } - .workbench-bar { - margin-bottom: 8px; - padding: 8px 10px; - border-radius: 12px; - } - .top-tabs { margin: 3px 0 8px; gap: 5px; @@ -149,21 +135,6 @@ textarea:focus-visible { .container { padding: 0 var(--spacing-sm) var(--spacing-md); } - .workbench-bar { - flex-direction: row; - align-items: center; - justify-content: flex-start; - } - - .workbench-bar-kicker { - font-size: 9px; - } - - .workbench-bar-title { - font-size: 15px; - margin-top: 1px; - } - .top-tabs { gap: 5px; margin: 2px 0 8px; From 451b3a5d57ecf382e488539c66a11a618ac71d68 Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Tue, 7 Apr 2026 18:48:42 +0000 Subject: [PATCH 17/27] refactor(web-ui): shift settings panel into document flow --- web-ui/styles/controls-forms.css | 30 +++++++++-------- web-ui/styles/layout-shell.css | 12 +++---- web-ui/styles/navigation-panels.css | 52 ++++++++++++++--------------- web-ui/styles/titles-cards.css | 12 +++---- 4 files changed, 54 insertions(+), 52 deletions(-) diff --git a/web-ui/styles/controls-forms.css b/web-ui/styles/controls-forms.css index ea5e4fe..dc628ad 100644 --- a/web-ui/styles/controls-forms.css +++ b/web-ui/styles/controls-forms.css @@ -2,12 +2,13 @@ 选择器 - 用于模型选择 ============================================ */ .selector-section { - background: rgba(255, 255, 255, 0.82); - border-radius: 10px; - padding: 8px; - margin-bottom: 8px; + background: transparent; + border-radius: 0; + padding: 10px 0 0; + margin-bottom: 10px; box-shadow: none; - border: 1px solid rgba(216, 201, 184, 0.22); + border: none; + border-top: 1px solid rgba(224, 214, 202, 0.72); display: flex; flex-direction: column; gap: 4px; @@ -17,7 +18,7 @@ display: flex; justify-content: space-between; align-items: center; - margin-bottom: 4px; + margin-bottom: 2px; } .settings-tab-header { @@ -89,10 +90,11 @@ .health-report { margin-top: 8px; - padding: 8px 10px; - border-radius: 10px; + padding: 8px 0 0; + border-radius: 0; border: 1px solid var(--color-border-soft); - background: var(--color-surface-alt); + border-width: 1px 0 0; + background: transparent; display: grid; gap: 8px; } @@ -220,7 +222,7 @@ .config-template-hint { margin-top: 6px; - margin-bottom: 6px; + margin-bottom: 4px; font-size: 11px; color: var(--color-text-tertiary); line-height: 1.35; @@ -251,8 +253,8 @@ min-height: 38px; padding: 8px 10px; border: 1px dashed rgba(208, 196, 182, 0.55); - border-radius: 10px; - background: rgba(255, 255, 255, 0.36); + border-radius: 8px; + background: rgba(255, 255, 255, 0.22); font-size: 13px; font-weight: var(--font-weight-secondary); color: var(--color-text-tertiary); @@ -297,13 +299,13 @@ padding: 8px 10px; border-radius: 8px; border: 1px solid var(--color-border-soft); - background: rgba(255, 255, 255, 0.86); + background: rgba(255, 255, 255, 0.72); font-size: 13px; font-weight: var(--font-weight-secondary); color: var(--color-text-secondary); cursor: pointer; transition: all var(--transition-fast) var(--ease-spring); - box-shadow: var(--shadow-subtle); + box-shadow: none; letter-spacing: -0.01em; width: 100%; text-align: center; diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 231de3e..8a0beb7 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -131,17 +131,17 @@ body::after { } .side-item.active { - border-color: rgba(201, 94, 75, 0.28); - background: rgba(255, 255, 255, 0.92); + border-color: rgba(201, 94, 75, 0.18); + background: rgba(255, 255, 255, 0.82); color: var(--color-text-primary); - box-shadow: 0 2px 8px rgba(31, 26, 23, 0.03); + box-shadow: none; } .side-item.nav-intent-active { - border-color: rgba(201, 94, 75, 0.28); - background: rgba(255, 255, 255, 0.92); + border-color: rgba(201, 94, 75, 0.18); + background: rgba(255, 255, 255, 0.82); color: var(--color-text-primary); - box-shadow: 0 2px 8px rgba(31, 26, 23, 0.03); + box-shadow: none; } .side-item.nav-intent-inactive, diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index 041dc7b..bf78255 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -32,9 +32,9 @@ } .status-strip { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); - gap: 6px; + display: flex; + flex-wrap: wrap; + gap: 6px 8px; margin-bottom: 10px; margin-top: 0; } @@ -42,23 +42,22 @@ .status-chip { min-width: 0; max-width: 100%; - padding: 7px 8px; - border-radius: 10px; - border: 1px solid rgba(216, 201, 184, 0.26); - background: rgba(248, 244, 239, 0.82); + padding: 0; + border: none; + background: transparent; box-shadow: none; - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 2px; + display: inline-flex; + flex-direction: row; + align-items: baseline; + gap: 6px; } .status-chip .label { - display: block; + display: inline; font-size: 10px; - color: var(--color-text-tertiary); + color: var(--color-text-muted); margin-bottom: 0; - letter-spacing: 0.08em; + letter-spacing: 0.06em; text-transform: uppercase; flex-shrink: 0; } @@ -68,9 +67,9 @@ font-weight: 600; color: var(--color-text-primary); letter-spacing: -0.01em; - white-space: normal; - overflow-wrap: anywhere; - word-break: break-word; + white-space: nowrap; + overflow-wrap: normal; + word-break: normal; } .provider-fast-switch { @@ -116,12 +115,12 @@ .main-panel { min-width: 0; - background: rgba(255, 255, 255, 0.97); - border: 1px solid rgba(208, 192, 173, 0.38); - border-radius: 18px; - box-shadow: 0 10px 24px rgba(31, 26, 23, 0.03); - padding: 16px 18px; - backdrop-filter: blur(6px); + background: rgba(255, 255, 255, 0.98); + border: 1px solid rgba(214, 201, 186, 0.34); + border-radius: 14px; + box-shadow: 0 4px 14px rgba(31, 26, 23, 0.02); + padding: 14px 16px 18px; + backdrop-filter: none; position: relative; overflow-x: hidden; overflow-y: visible; @@ -138,9 +137,9 @@ align-items: flex-start; justify-content: space-between; gap: 12px; - margin-bottom: 10px; - padding-bottom: 10px; - border-bottom: 1px solid rgba(216, 201, 184, 0.22); + margin-bottom: 8px; + padding-bottom: 8px; + border-bottom: 1px solid rgba(216, 201, 184, 0.18); } .panel-header-copy { @@ -324,6 +323,7 @@ border-radius: 0; box-shadow: none; padding: 0; + max-width: 980px; } .mode-content { diff --git a/web-ui/styles/titles-cards.css b/web-ui/styles/titles-cards.css index 942e399..c676ee7 100644 --- a/web-ui/styles/titles-cards.css +++ b/web-ui/styles/titles-cards.css @@ -2,10 +2,10 @@ 主标题 ============================================ */ .main-title { - font-size: clamp(22px, 1.7vw, 28px); + font-size: clamp(24px, 1.8vw, 30px); font-weight: var(--font-weight-display); - line-height: 1.04; - letter-spacing: -0.028em; + line-height: 1.06; + letter-spacing: -0.03em; margin-bottom: 0; color: var(--color-text-primary); font-family: var(--font-family-display); @@ -22,11 +22,11 @@ } .subtitle { - font-size: 11px; + font-size: 12px; color: var(--color-text-tertiary); - line-height: 1.4; + line-height: 1.5; margin-bottom: 0; - max-width: 62ch; + max-width: 68ch; letter-spacing: 0; } From 54526224d5cae25b16dfc836e5cccc3d7e2aef4a Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Wed, 8 Apr 2026 00:23:24 +0000 Subject: [PATCH 18/27] refactor(web-ui): keep split layout on tablet --- tests/unit/compact-layout-ui.test.mjs | 2 +- web-ui/styles/layout-shell.css | 2 +- web-ui/styles/responsive.css | 32 ++++++++++++++++++--------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/tests/unit/compact-layout-ui.test.mjs b/tests/unit/compact-layout-ui.test.mjs index dd4b524..11f36e6 100644 --- a/tests/unit/compact-layout-ui.test.mjs +++ b/tests/unit/compact-layout-ui.test.mjs @@ -30,7 +30,7 @@ test('styles include force-compact fallback rules for readability on touch devic assert.match(styles, /body\.force-compact\s+\.status-inspector\s*\{[\s\S]*display:\s*none;/); assert.match(styles, /body\.force-compact\s+\.top-tabs\s*\{[\s\S]*display:\s*flex\s*!important;[\s\S]*flex-wrap:\s*nowrap;[\s\S]*overflow-x:\s*auto;/); assert.match(styles, /body\.force-compact\s+\.top-tabs::-webkit-scrollbar\s*\{[\s\S]*display:\s*none;/); - assert.match(layoutShell, /@media\s*\(min-width:\s*961px\)\s*\{[\s\S]*body:not\(.force-compact\)\s+#app\s*>\s*\.top-tabs\s*\{[\s\S]*display:\s*none;/); + assert.match(layoutShell, /@media\s*\(min-width:\s*721px\)\s*\{[\s\S]*body:not\(.force-compact\)\s+#app\s*>\s*\.top-tabs\s*\{[\s\S]*display:\s*none;/); assert.doesNotMatch(layoutShell, /^\s*\.top-tabs\s*\{[\s\S]*display:\s*none\s*!important;/m); assert.match(styles, /body\.force-compact\s+\.card-subtitle/); const compactSubtitleBlock = styles.match(/body\.force-compact\s+\.card-subtitle\s*\{[^}]*\}/); diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 8a0beb7..5fba049 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -188,7 +188,7 @@ body::after { word-break: break-word; } -@media (min-width: 961px) { +@media (min-width: 721px) { body:not(.force-compact) #app > .top-tabs { display: none; } diff --git a/web-ui/styles/responsive.css b/web-ui/styles/responsive.css index f762636..a73b876 100644 --- a/web-ui/styles/responsive.css +++ b/web-ui/styles/responsive.css @@ -28,10 +28,8 @@ textarea:focus-visible { padding: 12px; } .app-shell { - grid-template-columns: 1fr; - } - .side-rail { - display: none; + grid-template-columns: minmax(158px, 176px) minmax(0, 1fr); + gap: 12px; } .main-panel { padding: 14px; @@ -39,13 +37,7 @@ textarea:focus-visible { min-height: 0; } .top-tabs { - display: flex !important; - flex-wrap: nowrap; - overflow-x: auto; - overflow-y: hidden; - padding-bottom: 2px; - margin-left: -2px; - margin-right: -2px; + display: none !important; } .status-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); @@ -75,6 +67,24 @@ textarea:focus-visible { } @media (max-width: 720px) { + .app-shell { + grid-template-columns: 1fr; + } + + .side-rail { + display: none; + } + + .top-tabs { + display: flex !important; + flex-wrap: nowrap; + overflow-x: auto; + overflow-y: hidden; + padding-bottom: 2px; + margin-left: -2px; + margin-right: -2px; + } + .main-title { font-size: 22px; } From e18aaaa34f1fa96e4dbe09872c80c906320c6338 Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Wed, 8 Apr 2026 01:35:06 +0000 Subject: [PATCH 19/27] refactor(web-ui): tidy split layout nav details --- web-ui/partials/index/layout-header.html | 1 + web-ui/styles/layout-shell.css | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/web-ui/partials/index/layout-header.html b/web-ui/partials/index/layout-header.html index 7ba83d0..57ec4d6 100644 --- a/web-ui/partials/index/layout-header.html +++ b/web-ui/partials/index/layout-header.html @@ -80,6 +80,7 @@
Workspace
Codex Mate
+
本地配置与会话工作台
diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 5fba049..5513765 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -40,7 +40,7 @@ body::after { } /* ============================================ - 布局:三栏(侧栏 + 主区 + 状态检查器) + 布局:双栏(侧栏 + 主区) ============================================ */ .app-shell { display: grid; @@ -130,13 +130,7 @@ body::after { color: var(--color-text-primary); } -.side-item.active { - border-color: rgba(201, 94, 75, 0.18); - background: rgba(255, 255, 255, 0.82); - color: var(--color-text-primary); - box-shadow: none; -} - +.side-item.active, .side-item.nav-intent-active { border-color: rgba(201, 94, 75, 0.18); background: rgba(255, 255, 255, 0.82); @@ -171,15 +165,20 @@ body::after { .side-item-meta { font-size: 10px; color: var(--color-text-tertiary); - display: none; + display: flex; + visibility: hidden; + opacity: 0; gap: 5px; flex-wrap: wrap; line-height: 1.35; + min-height: 1.35em; + transition: opacity var(--transition-fast) var(--ease-smooth), visibility var(--transition-fast) var(--ease-smooth); } .side-item.active .side-item-meta, .side-item.nav-intent-active .side-item-meta { - display: flex; + visibility: visible; + opacity: 1; } .side-item-meta > span { @@ -213,8 +212,7 @@ body::after { font-weight: 700; } -.brand-block::after { - content: "本地配置与会话工作台"; +.brand-subtitle { font-size: 10px; line-height: 1.3; color: var(--color-text-muted); From 4971406b9ec9eea5d83fbb1fd2dfc08ff48f3111 Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Wed, 8 Apr 2026 02:02:30 +0000 Subject: [PATCH 20/27] refactor(web-ui): restyle shell like SaaS console --- tests/unit/compact-layout-ui.test.mjs | 3 +- web-ui/styles/base-theme.css | 74 ++++++------ web-ui/styles/controls-forms.css | 26 ++--- web-ui/styles/layout-shell.css | 162 ++++++++++++-------------- web-ui/styles/navigation-panels.css | 89 +++++++------- web-ui/styles/responsive.css | 37 +++--- web-ui/styles/titles-cards.css | 63 +++++----- 7 files changed, 226 insertions(+), 228 deletions(-) diff --git a/tests/unit/compact-layout-ui.test.mjs b/tests/unit/compact-layout-ui.test.mjs index 11f36e6..9b13c17 100644 --- a/tests/unit/compact-layout-ui.test.mjs +++ b/tests/unit/compact-layout-ui.test.mjs @@ -47,7 +47,8 @@ test('styles include force-compact fallback rules for readability on touch devic test('styles keep desktop layout wide and session history readable on large screens', () => { const styles = readBundledWebUiCss(); - assert.match(styles, /\.container\s*\{[\s\S]*max-width:\s*2200px;/); + assert.match(styles, /\.container\s*\{[\s\S]*max-width:\s*none;[\s\S]*min-height:\s*100vh;/); + assert.match(styles, /\.app-shell\s*\{[\s\S]*grid-template-columns:\s*248px\s+minmax\(0,\s*1fr\);[\s\S]*min-height:\s*100vh;/); assert.match(styles, /\.session-layout\s*\{[\s\S]*grid-template-columns:\s*minmax\(260px,\s*360px\)\s*minmax\(0,\s*1fr\);/); assert.match(styles, /\.session-item\s*\{[\s\S]*min-height:\s*102px;/); diff --git a/web-ui/styles/base-theme.css b/web-ui/styles/base-theme.css index 6e11c77..c24ab2f 100644 --- a/web-ui/styles/base-theme.css +++ b/web-ui/styles/base-theme.css @@ -4,35 +4,35 @@ 设计系统 - Design Tokens ============================================ */ :root { - /* 色彩系统:去除杂纹,强调干净留白与温柔橙红 */ - --color-brand: #D0583A; - --color-brand-dark: #B8442B; - --color-brand-light: rgba(208, 88, 58, 0.14); - --color-brand-subtle: rgba(201, 94, 75, 0.2); - - --color-bg: #F8F2EA; - --color-surface: #FFFDFC; - --color-surface-alt: #FFF8F2; + /* 色彩系统:冷白控制台 / slate + blue */ + --color-brand: #3B82F6; + --color-brand-dark: #2563EB; + --color-brand-light: rgba(59, 130, 246, 0.14); + --color-brand-subtle: rgba(59, 130, 246, 0.2); + + --color-bg: #F8FAFC; + --color-surface: #FFFFFF; + --color-surface-alt: #F8FAFC; --color-surface-elevated: #FFFFFF; - --color-surface-tint: rgba(255, 255, 255, 0.84); - --color-text-primary: #1B1714; - --color-text-secondary: #473C34; - --color-text-tertiary: #6F6054; - --color-text-muted: #6C5B50; - --color-border: #D8C9B8; - --color-border-soft: rgba(216, 201, 184, 0.38); - --color-border-strong: rgba(216, 201, 184, 0.68); - - --color-success: #4B8B6A; - --color-error: #C44536; + --color-surface-tint: rgba(255, 255, 255, 0.88); + --color-text-primary: #0F172A; + --color-text-secondary: #475569; + --color-text-tertiary: #64748B; + --color-text-muted: #94A3B8; + --color-border: #E2E8F0; + --color-border-soft: rgba(148, 163, 184, 0.24); + --color-border-strong: rgba(148, 163, 184, 0.42); + + --color-success: #10B981; + --color-error: #EF4444; --bg-warm-gradient: - linear-gradient(180deg, #F8F2EA 0%, #F8F2EA 100%); + linear-gradient(180deg, #F8FAFC 0%, #F8FAFC 100%); /* 字体系统 */ - --font-family-body: 'JetBrainsMono Nerd Font Mono', 'OPPO Sans 4.0', 'Fira Mono', 'JetBrains Mono', 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', monospace; - --font-family-display: 'JetBrainsMono Nerd Font Mono', 'OPPO Sans 4.0', 'Fira Mono', 'JetBrains Mono', 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', monospace; - --font-family-mono: 'JetBrainsMono Nerd Font Mono', 'OPPO Sans 4.0', 'Fira Mono', 'JetBrains Mono', 'SFMono-Regular', Consolas, 'Liberation Mono', monospace; + --font-family-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif; + --font-family-display: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif; + --font-family-mono: 'JetBrainsMono Nerd Font Mono', 'JetBrains Mono', 'Fira Code', 'SFMono-Regular', Consolas, 'Liberation Mono', monospace; --font-family: var(--font-family-body); --font-size-display: 52px; @@ -66,15 +66,15 @@ --radius-xl: 18px; --radius-full: 50px; - /* 阴影系统 - 多层叠加提升真实感 */ - --shadow-subtle: 0 1px 2px rgba(31, 26, 23, 0.03); - --shadow-card: 0 6px 18px rgba(31, 26, 23, 0.06); - --shadow-card-hover: 0 10px 24px rgba(31, 26, 23, 0.08); - --shadow-float: 0 12px 26px rgba(31, 26, 23, 0.12); - --shadow-raised: 0 10px 20px rgba(31, 26, 23, 0.1); + /* 阴影系统 - 冷静、克制 */ + --shadow-subtle: 0 1px 2px rgba(15, 23, 42, 0.04); + --shadow-card: 0 4px 12px rgba(15, 23, 42, 0.05); + --shadow-card-hover: 0 8px 22px rgba(15, 23, 42, 0.08); + --shadow-float: 0 12px 28px rgba(15, 23, 42, 0.12); + --shadow-raised: 0 8px 18px rgba(15, 23, 42, 0.1); --shadow-modal: - 0 8px 24px rgba(31, 26, 23, 0.08), - 0 24px 64px rgba(31, 26, 23, 0.06); + 0 8px 24px rgba(15, 23, 42, 0.08), + 0 24px 64px rgba(15, 23, 42, 0.06); --shadow-input-focus: 0 0 0 3px var(--color-brand-light), 0 1px 3px rgba(31, 26, 23, 0.04); @@ -101,8 +101,8 @@ body.force-compact { } body.force-compact .container { - max-width: 760px; - padding: 10px 10px 16px; + max-width: none; + padding: 0; } body.force-compact .provider-fast-switch { @@ -247,10 +247,10 @@ body { background: var(--bg-warm-gradient); color: var(--color-text-primary); display: flex; - justify-content: center; - align-items: center; + justify-content: stretch; + align-items: stretch; min-height: 100vh; - padding: var(--spacing-lg) var(--spacing-md); + padding: 0; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; diff --git a/web-ui/styles/controls-forms.css b/web-ui/styles/controls-forms.css index dc628ad..c5f3fe4 100644 --- a/web-ui/styles/controls-forms.css +++ b/web-ui/styles/controls-forms.css @@ -4,14 +4,14 @@ .selector-section { background: transparent; border-radius: 0; - padding: 10px 0 0; - margin-bottom: 10px; + padding: 12px 0 0; + margin-bottom: 12px; box-shadow: none; border: none; - border-top: 1px solid rgba(224, 214, 202, 0.72); + border-top: 1px solid var(--color-border); display: flex; flex-direction: column; - gap: 4px; + gap: 6px; } .selector-header { @@ -89,10 +89,10 @@ } .health-report { - margin-top: 8px; - padding: 8px 0 0; + margin-top: 10px; + padding: 10px 0 0; border-radius: 0; - border: 1px solid var(--color-border-soft); + border: 1px solid var(--color-border); border-width: 1px 0 0; background: transparent; display: grid; @@ -117,10 +117,10 @@ } .health-issue { - background: #fff6f5; + background: #FEF2F2; border-left: 3px solid var(--color-error); padding: 8px 10px; - border-radius: 10px; + border-radius: 8px; } .health-issue-title { @@ -166,11 +166,11 @@ min-height: 36px; padding: 8px 10px; padding-right: 34px; - border: 1px solid var(--color-border-soft); + border: 1px solid var(--color-border); border-radius: 8px; font-size: 13px; font-weight: var(--font-weight-body); - background-color: var(--color-surface-alt); + background-color: var(--color-surface); color: var(--color-text-primary); outline: none; cursor: pointer; @@ -198,11 +198,11 @@ width: 100%; min-height: 36px; padding: 8px 10px; - border: 1px solid var(--color-border-soft); + border: 1px solid var(--color-border); border-radius: 8px; font-size: 13px; font-weight: var(--font-weight-body); - background-color: var(--color-surface-alt); + background-color: var(--color-surface); color: var(--color-text-primary); outline: none; transition: all var(--transition-fast) var(--ease-smooth); diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 5513765..7d5c4ce 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -1,30 +1,9 @@ /* ============================================ 容器 ============================================ */ -body::before { - content: ""; - position: fixed; - inset: 0; - background: - radial-gradient(circle at top left, rgba(208, 88, 58, 0.025), transparent 24%), - linear-gradient(180deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0)); - opacity: 0.34; - pointer-events: none; - z-index: 0; -} - -/* 背景网格 */ +body::before, body::after { - content: ""; - position: fixed; - inset: 0; - background-image: - linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px), - linear-gradient(0deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px); - background-size: 220px 220px; - opacity: 0.01; - pointer-events: none; - z-index: 0; + content: none; } /* ============================================ @@ -32,11 +11,12 @@ body::after { ============================================ */ .container { width: 100%; - max-width: 2200px; - margin: 0 auto; - padding: 12px 14px 18px; + max-width: none; + margin: 0; + padding: 0; position: relative; z-index: 1; + min-height: 100vh; } /* ============================================ @@ -44,9 +24,11 @@ body::after { ============================================ */ .app-shell { display: grid; - grid-template-columns: minmax(196px, 216px) minmax(0, 1fr); - gap: 16px; - align-items: flex-start; + grid-template-columns: 248px minmax(0, 1fr); + gap: 0; + align-items: stretch; + min-height: 100vh; + background: var(--color-bg); } .app-shell.standalone { @@ -55,18 +37,18 @@ body::after { .side-rail { position: sticky; - top: var(--spacing-md); - align-self: start; + top: 0; + align-self: stretch; display: flex; flex-direction: column; - gap: 12px; - padding: 12px 8px 10px; - background: rgba(242, 237, 231, 0.92); - border: 1px solid rgba(201, 184, 165, 0.42); - border-radius: 16px; + gap: 0; + padding: 0; + background: var(--color-surface); + border-right: 1px solid var(--color-border); + border-radius: 0; box-shadow: none; - min-height: 0; - backdrop-filter: blur(10px); + min-height: 100vh; + backdrop-filter: none; } .side-rail .brand-title { @@ -78,29 +60,35 @@ body::after { display: flex; flex-direction: column; gap: 4px; + padding: 16px 12px; +} + +.side-section + .side-section { + border-top: 1px solid var(--color-border); } .side-rail-nav { display: flex; flex-direction: column; - gap: 10px; + gap: 0; flex: 1 1 auto; } .side-section-title { - font-size: 10px; + font-size: 11px; font-weight: 700; - color: var(--color-text-tertiary); - letter-spacing: 0.08em; + color: var(--color-text-muted); + letter-spacing: 0.06em; text-transform: uppercase; - padding: 0 8px 0; + padding: 0 8px; + margin-bottom: 8px; } .side-item { width: 100%; text-align: left; - padding: 9px 9px 9px 12px; - border-radius: 12px; + padding: 8px 12px; + border-radius: 8px; border: 1px solid transparent; background: transparent; color: var(--color-text-secondary); @@ -108,7 +96,7 @@ body::after { transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth); display: flex; flex-direction: column; - gap: 3px; + gap: 2px; box-shadow: none; position: relative; } @@ -117,24 +105,25 @@ body::after { content: ""; position: absolute; left: 0; - top: 8px; - bottom: 8px; + top: 50%; + transform: translateY(-50%); width: 3px; - border-radius: 999px; + height: 16px; + border-radius: 0 2px 2px 0; background: transparent; transition: background-color var(--transition-fast) var(--ease-smooth); } .side-item:hover { - background: rgba(255, 255, 255, 0.58); + background: var(--color-surface-alt); color: var(--color-text-primary); } .side-item.active, .side-item.nav-intent-active { - border-color: rgba(201, 94, 75, 0.18); - background: rgba(255, 255, 255, 0.82); - color: var(--color-text-primary); + border-color: transparent; + background: rgba(59, 130, 246, 0.08); + color: var(--color-brand-dark); box-shadow: none; } @@ -148,7 +137,7 @@ body::after { .side-item.active::before, .side-item.nav-intent-active::before { - background: rgba(201, 94, 75, 0.9); + background: var(--color-brand); } .side-item.nav-intent-inactive::before, @@ -157,14 +146,14 @@ body::after { } .side-item-title { - font-size: 12px; + font-size: 13px; font-weight: 600; letter-spacing: -0.01em; } .side-item-meta { - font-size: 10px; - color: var(--color-text-tertiary); + font-size: 11px; + color: var(--color-text-muted); display: flex; visibility: hidden; opacity: 0; @@ -197,34 +186,34 @@ body::after { display: flex; flex-direction: column; align-items: flex-start; - gap: 3px; + gap: 6px; margin-bottom: 0; - padding: 2px 4px 8px; - border-bottom: 1px solid rgba(216, 201, 184, 0.22); + padding: 20px; + border-bottom: 1px solid var(--color-border); } .brand-kicker { - font-size: 10px; + font-size: 11px; line-height: 1; - letter-spacing: 0.08em; + letter-spacing: 0.06em; text-transform: uppercase; - color: var(--color-text-tertiary); + color: var(--color-text-muted); font-weight: 700; } .brand-subtitle { - font-size: 10px; - line-height: 1.3; - color: var(--color-text-muted); + font-size: 12px; + line-height: 1.4; + color: var(--color-text-secondary); max-width: 18ch; } .brand-title { - font-size: 20px; - line-height: 1.02; + font-size: 18px; + line-height: 1.1; font-family: var(--font-family-display); color: var(--color-text-primary); - letter-spacing: -0.04em; + letter-spacing: -0.02em; } .github-badge { @@ -234,43 +223,44 @@ body::after { gap: 10px; margin-top: 0; padding: 8px 10px; - border-radius: 10px; - border: 1px solid rgba(216, 201, 184, 0.36); - background: rgba(255, 255, 255, 0.8); + border-radius: 8px; + border: 1px solid var(--color-border); + background: var(--color-surface); color: var(--color-text-secondary); font-size: var(--font-size-caption); text-decoration: none; box-shadow: none; transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth), box-shadow var(--transition-fast) var(--ease-smooth); min-width: 0; - backdrop-filter: blur(4px); + backdrop-filter: none; } .github-badge-rail { - width: 100%; + width: calc(100% - 24px); + margin: 0 12px 12px; align-items: center; justify-content: flex-start; gap: 8px; - padding: 8px 9px; - border-radius: 12px; - background: rgba(255, 255, 255, 0.62); - border: 1px solid rgba(216, 201, 184, 0.32); + padding: 8px 10px; + border-radius: 8px; + background: var(--color-surface); + border: 1px solid var(--color-border); box-shadow: none; } .github-badge:hover { - border-color: rgba(201, 94, 75, 0.46); - background: rgba(255, 255, 255, 0.92); + border-color: var(--color-border-strong); + background: var(--color-surface-alt); color: var(--color-text-primary); - box-shadow: 0 0 0 1px rgba(201, 94, 75, 0.08); + box-shadow: none; } .github-badge:focus-visible { - outline: 3px solid rgba(201, 94, 75, 0.22); + outline: 3px solid rgba(59, 130, 246, 0.18); outline-offset: 2px; - border-color: rgba(201, 94, 75, 0.52); + border-color: var(--color-brand); color: var(--color-text-primary); - background: rgba(255, 255, 255, 0.94); + background: var(--color-surface); } .github-badge-icon { @@ -346,7 +336,7 @@ body::after { .github-badge-rail .github-badge-left { padding: 4px; border-radius: 999px; - background: rgba(201, 94, 75, 0.12); + background: rgba(59, 130, 246, 0.12); } .github-badge-rail .github-badge-label { @@ -354,5 +344,5 @@ body::after { } .github-badge-rail:hover { - border-color: rgba(201, 94, 75, 0.5); + border-color: var(--color-border-strong); } diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index bf78255..c4f1560 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -34,22 +34,22 @@ .status-strip { display: flex; flex-wrap: wrap; - gap: 6px 8px; - margin-bottom: 10px; - margin-top: 0; + gap: 8px; + margin: 0 0 14px; } .status-chip { min-width: 0; max-width: 100%; - padding: 0; - border: none; - background: transparent; + padding: 6px 10px; + border: 1px solid var(--color-border); + background: var(--color-surface); box-shadow: none; display: inline-flex; flex-direction: row; - align-items: baseline; - gap: 6px; + align-items: center; + gap: 8px; + border-radius: 999px; } .status-chip .label { @@ -73,11 +73,11 @@ } .provider-fast-switch { - margin: 0 0 10px; - padding: 8px 10px; + margin: 0 0 14px; + padding: 10px 12px; border-radius: 10px; - border: 1px solid rgba(216, 201, 184, 0.42); - background: rgba(252, 250, 247, 0.96); + border: 1px solid var(--color-border); + background: var(--color-surface); box-shadow: none; display: grid; gap: 6px; @@ -87,6 +87,7 @@ font-size: 11px; color: var(--color-text-tertiary); letter-spacing: 0.02em; + font-weight: 600; } .provider-fast-switch-select { @@ -115,11 +116,11 @@ .main-panel { min-width: 0; - background: rgba(255, 255, 255, 0.98); - border: 1px solid rgba(214, 201, 186, 0.34); - border-radius: 14px; - box-shadow: 0 4px 14px rgba(31, 26, 23, 0.02); - padding: 14px 16px 18px; + background: var(--color-bg); + border: none; + border-radius: 0; + box-shadow: none; + padding: 0 24px 24px; backdrop-filter: none; position: relative; overflow-x: hidden; @@ -128,32 +129,33 @@ } .panel-header { - margin-bottom: 8px; + margin-bottom: 14px; text-align: left; } .panel-header-refined { display: flex; - align-items: flex-start; + align-items: center; justify-content: space-between; - gap: 12px; - margin-bottom: 8px; - padding-bottom: 8px; - border-bottom: 1px solid rgba(216, 201, 184, 0.18); + gap: 14px; + margin: 0 -24px 14px; + padding: 16px 24px; + border-bottom: 1px solid var(--color-border); + background: var(--color-surface); } .panel-header-copy { display: flex; flex-direction: column; - gap: 3px; - max-width: 760px; + gap: 4px; + max-width: none; } .panel-kicker { - font-size: 9px; + font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; - color: var(--color-text-tertiary); + color: var(--color-brand); font-weight: 700; } @@ -194,11 +196,11 @@ } .top-tabs { - margin: 6px 0 10px; + margin: 10px 12px 12px; background: transparent; border: none; border-radius: 0; - padding: 0; + padding: 0 8px 2px 2px; box-shadow: none; display: flex; flex-wrap: nowrap; @@ -209,7 +211,6 @@ -webkit-overflow-scrolling: touch; scrollbar-width: none; scroll-snap-type: x proximity; - padding: 0 8px 2px 2px; } .top-tabs::-webkit-scrollbar { @@ -217,10 +218,10 @@ } .top-tab { - border: 1px solid rgba(216, 201, 184, 0.42); + border: 1px solid var(--color-border); border-radius: 999px; - background: rgba(255, 255, 255, 0.94); - padding: 6px 9px; + background: var(--color-surface); + padding: 6px 10px; font-size: 11px; color: var(--color-text-secondary); text-align: center; @@ -232,29 +233,23 @@ } .top-tab:hover { - border-color: var(--color-brand); - color: var(--color-text-primary); -} - -.top-tab.active { - border-color: rgba(201, 94, 75, 0.46); + border-color: var(--color-border-strong); color: var(--color-text-primary); - background: rgba(249, 244, 240, 0.98); - box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.08); } +.top-tab.active, .top-tab.nav-intent-active { - border-color: rgba(201, 94, 75, 0.46); - color: var(--color-text-primary); - background: rgba(249, 244, 240, 0.98); - box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.08); + border-color: rgba(59, 130, 246, 0.22); + color: var(--color-brand-dark); + background: rgba(59, 130, 246, 0.08); + box-shadow: none; } .top-tab.nav-intent-inactive, .top-tab.active.nav-intent-inactive { - border-color: rgba(216, 201, 184, 0.42); + border-color: var(--color-border); color: var(--color-text-secondary); - background: rgba(255, 255, 255, 0.94); + background: var(--color-surface); box-shadow: none; } diff --git a/web-ui/styles/responsive.css b/web-ui/styles/responsive.css index a73b876..e9bec75 100644 --- a/web-ui/styles/responsive.css +++ b/web-ui/styles/responsive.css @@ -13,27 +13,27 @@ textarea:focus-visible { @media (max-width: 1280px) { .app-shell { - grid-template-columns: minmax(198px, 220px) minmax(0, 1fr); - gap: 14px; + grid-template-columns: 224px minmax(0, 1fr); + gap: 0; } .main-panel { - padding: 18px 18px 20px; + padding: 0 20px 20px; } } @media (max-width: 960px) { .container { - padding: 12px; + padding: 0; } .app-shell { - grid-template-columns: minmax(158px, 176px) minmax(0, 1fr); - gap: 12px; + grid-template-columns: 188px minmax(0, 1fr); + gap: 0; } .main-panel { - padding: 14px; - border-radius: 16px; + padding: 0 16px 16px; + border-radius: 0; min-height: 0; } .top-tabs { @@ -69,6 +69,7 @@ textarea:focus-visible { @media (max-width: 720px) { .app-shell { grid-template-columns: 1fr; + min-height: auto; } .side-rail { @@ -85,14 +86,24 @@ textarea:focus-visible { margin-right: -2px; } + .main-panel { + padding: 0 12px 16px; + } + + .panel-header-refined { + margin-left: -12px; + margin-right: -12px; + padding: 14px 12px; + } + .main-title { - font-size: 22px; + font-size: 18px; } .subtitle { - font-size: 11px; + font-size: 12px; margin-bottom: 0; - line-height: 1.35; + line-height: 1.4; } .panel-kicker { @@ -100,7 +111,7 @@ textarea:focus-visible { } .top-tabs { - margin: 3px 0 8px; + margin: 8px 0 10px; gap: 5px; } @@ -151,7 +162,7 @@ textarea:focus-visible { padding-right: 14px; } .main-panel { - padding: 10px; + padding: 0 10px 12px; } .card { padding: 12px; diff --git a/web-ui/styles/titles-cards.css b/web-ui/styles/titles-cards.css index c676ee7..44fe5df 100644 --- a/web-ui/styles/titles-cards.css +++ b/web-ui/styles/titles-cards.css @@ -2,10 +2,10 @@ 主标题 ============================================ */ .main-title { - font-size: clamp(24px, 1.8vw, 30px); - font-weight: var(--font-weight-display); - line-height: 1.06; - letter-spacing: -0.03em; + font-size: clamp(18px, 1.3vw, 22px); + font-weight: 700; + line-height: 1.15; + letter-spacing: -0.02em; margin-bottom: 0; color: var(--color-text-primary); font-family: var(--font-family-display); @@ -22,11 +22,11 @@ } .subtitle { - font-size: 12px; - color: var(--color-text-tertiary); - line-height: 1.5; + font-size: 13px; + color: var(--color-text-secondary); + line-height: 1.45; margin-bottom: 0; - max-width: 68ch; + max-width: 72ch; letter-spacing: 0; } @@ -35,13 +35,13 @@ ============================================ */ .segmented-control { display: flex; - background: rgba(246, 241, 235, 0.78); + background: var(--color-surface); border-radius: 10px; padding: 4px; - margin-bottom: 12px; + margin-bottom: 14px; position: relative; box-shadow: none; - border: 1px solid rgba(216, 201, 184, 0.26); + border: 1px solid var(--color-border); backdrop-filter: none; } @@ -66,9 +66,9 @@ } .segment.active { - color: var(--color-text-primary); - background: rgba(255, 255, 255, 0.96); - box-shadow: inset 0 0 0 1px rgba(216, 201, 184, 0.28); + color: var(--color-brand-dark); + background: rgba(59, 130, 246, 0.08); + box-shadow: inset 0 0 0 1px rgba(59, 130, 246, 0.14); } /* ============================================ @@ -85,9 +85,9 @@ 卡片 ============================================ */ .card { - background: rgba(255, 255, 255, 0.92); - border-radius: 12px; - padding: 10px 11px; + background: var(--color-surface); + border-radius: 10px; + padding: 10px 12px; display: flex; align-items: center; justify-content: space-between; @@ -99,14 +99,14 @@ box-shadow: none; user-select: none; will-change: auto; - border: 1px solid rgba(216, 201, 184, 0.3); + border: 1px solid var(--color-border); position: relative; overflow: hidden; } .card:hover { - border-color: rgba(201, 94, 75, 0.38); - box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.04); + border-color: var(--color-border-strong); + box-shadow: none; } .card::before, @@ -118,10 +118,11 @@ .card::before { left: 0; - top: 8px; - bottom: 8px; + top: 50%; + transform: translateY(-50%); width: 3px; - border-radius: 999px; + height: 18px; + border-radius: 0 2px 2px 0; background: transparent; transition: background var(--transition-fast) var(--ease-smooth); } @@ -129,7 +130,7 @@ .card::after { inset: 0; border-radius: inherit; - background: linear-gradient(120deg, rgba(255, 255, 255, 0.18) 0%, transparent 55%); + background: linear-gradient(120deg, rgba(255, 255, 255, 0.1) 0%, transparent 55%); opacity: 0; transition: opacity var(--transition-fast) var(--ease-smooth); } @@ -140,13 +141,13 @@ } .card.active { - background: rgba(248, 243, 237, 0.92); - border-color: rgba(201, 94, 75, 0.4); - box-shadow: inset 0 0 0 1px rgba(201, 94, 75, 0.05); + background: rgba(59, 130, 246, 0.08); + border-color: rgba(59, 130, 246, 0.2); + box-shadow: none; } .card.active::before { - background: linear-gradient(180deg, rgba(201, 94, 75, 0.95) 0%, rgba(201, 94, 75, 0.35) 100%); + background: var(--color-brand); } .card:hover::after { @@ -169,20 +170,20 @@ width: 32px; height: 32px; border-radius: 8px; - background: rgba(244, 237, 228, 0.72); + background: rgba(59, 130, 246, 0.1); display: flex; align-items: center; justify-content: center; font-size: var(--font-size-title); font-weight: var(--font-weight-title); - color: var(--color-text-secondary); + color: var(--color-brand-dark); flex-shrink: 0; transition: background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth); box-shadow: none; } .card.active .card-icon { - background: rgba(201, 94, 75, 0.14); + background: rgba(59, 130, 246, 0.14); color: var(--color-brand-dark); box-shadow: none; } From 386b32a4af2dcc88f44aa8d5df15c1678d77143e Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Wed, 8 Apr 2026 02:15:41 +0000 Subject: [PATCH 21/27] refactor(web-ui): soften shell palette for reading --- web-ui/styles/base-theme.css | 58 ++++++++++++++--------------- web-ui/styles/layout-shell.css | 6 +-- web-ui/styles/navigation-panels.css | 20 +++++----- web-ui/styles/titles-cards.css | 16 ++++---- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/web-ui/styles/base-theme.css b/web-ui/styles/base-theme.css index c24ab2f..e23d24f 100644 --- a/web-ui/styles/base-theme.css +++ b/web-ui/styles/base-theme.css @@ -4,30 +4,30 @@ 设计系统 - Design Tokens ============================================ */ :root { - /* 色彩系统:冷白控制台 / slate + blue */ - --color-brand: #3B82F6; - --color-brand-dark: #2563EB; - --color-brand-light: rgba(59, 130, 246, 0.14); - --color-brand-subtle: rgba(59, 130, 246, 0.2); - - --color-bg: #F8FAFC; - --color-surface: #FFFFFF; - --color-surface-alt: #F8FAFC; + /* 色彩系统:温和中性暖灰 + 柔粉强调 */ + --color-brand: #C77462; + --color-brand-dark: #B45E4E; + --color-brand-light: rgba(199, 116, 98, 0.14); + --color-brand-subtle: rgba(199, 116, 98, 0.2); + + --color-bg: #F7F3EF; + --color-surface: #FFFDFC; + --color-surface-alt: #F8F3EE; --color-surface-elevated: #FFFFFF; - --color-surface-tint: rgba(255, 255, 255, 0.88); - --color-text-primary: #0F172A; - --color-text-secondary: #475569; - --color-text-tertiary: #64748B; - --color-text-muted: #94A3B8; - --color-border: #E2E8F0; - --color-border-soft: rgba(148, 163, 184, 0.24); - --color-border-strong: rgba(148, 163, 184, 0.42); - - --color-success: #10B981; - --color-error: #EF4444; + --color-surface-tint: rgba(255, 253, 252, 0.9); + --color-text-primary: #241F1C; + --color-text-secondary: #5A514B; + --color-text-tertiary: #7A6E66; + --color-text-muted: #A39286; + --color-border: #E7DDD4; + --color-border-soft: rgba(163, 146, 134, 0.22); + --color-border-strong: rgba(163, 146, 134, 0.4); + + --color-success: #4B8B6A; + --color-error: #C44536; --bg-warm-gradient: - linear-gradient(180deg, #F8FAFC 0%, #F8FAFC 100%); + linear-gradient(180deg, #F7F3EF 0%, #F7F3EF 100%); /* 字体系统 */ --font-family-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif; @@ -66,15 +66,15 @@ --radius-xl: 18px; --radius-full: 50px; - /* 阴影系统 - 冷静、克制 */ - --shadow-subtle: 0 1px 2px rgba(15, 23, 42, 0.04); - --shadow-card: 0 4px 12px rgba(15, 23, 42, 0.05); - --shadow-card-hover: 0 8px 22px rgba(15, 23, 42, 0.08); - --shadow-float: 0 12px 28px rgba(15, 23, 42, 0.12); - --shadow-raised: 0 8px 18px rgba(15, 23, 42, 0.1); + /* 阴影系统 - 温和、轻量 */ + --shadow-subtle: 0 1px 2px rgba(36, 31, 28, 0.03); + --shadow-card: 0 4px 12px rgba(36, 31, 28, 0.045); + --shadow-card-hover: 0 8px 22px rgba(36, 31, 28, 0.07); + --shadow-float: 0 12px 28px rgba(36, 31, 28, 0.1); + --shadow-raised: 0 8px 18px rgba(36, 31, 28, 0.08); --shadow-modal: - 0 8px 24px rgba(15, 23, 42, 0.08), - 0 24px 64px rgba(15, 23, 42, 0.06); + 0 8px 24px rgba(36, 31, 28, 0.08), + 0 24px 64px rgba(36, 31, 28, 0.05); --shadow-input-focus: 0 0 0 3px var(--color-brand-light), 0 1px 3px rgba(31, 26, 23, 0.04); diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index 7d5c4ce..d045fab 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -122,7 +122,7 @@ body::after { .side-item.active, .side-item.nav-intent-active { border-color: transparent; - background: rgba(59, 130, 246, 0.08); + background: var(--color-brand-light); color: var(--color-brand-dark); box-shadow: none; } @@ -256,7 +256,7 @@ body::after { } .github-badge:focus-visible { - outline: 3px solid rgba(59, 130, 246, 0.18); + outline: 3px solid rgba(199, 116, 98, 0.18); outline-offset: 2px; border-color: var(--color-brand); color: var(--color-text-primary); @@ -336,7 +336,7 @@ body::after { .github-badge-rail .github-badge-left { padding: 4px; border-radius: 999px; - background: rgba(59, 130, 246, 0.12); + background: var(--color-brand-light); } .github-badge-rail .github-badge-label { diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index c4f1560..cdfef65 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -43,7 +43,7 @@ max-width: 100%; padding: 6px 10px; border: 1px solid var(--color-border); - background: var(--color-surface); + background: rgba(255, 253, 252, 0.82); box-shadow: none; display: inline-flex; flex-direction: row; @@ -77,7 +77,7 @@ padding: 10px 12px; border-radius: 10px; border: 1px solid var(--color-border); - background: var(--color-surface); + background: rgba(255, 253, 252, 0.88); box-shadow: none; display: grid; gap: 6px; @@ -120,7 +120,7 @@ border: none; border-radius: 0; box-shadow: none; - padding: 0 24px 24px; + padding: 0 28px 28px; backdrop-filter: none; position: relative; overflow-x: hidden; @@ -138,10 +138,10 @@ align-items: center; justify-content: space-between; gap: 14px; - margin: 0 -24px 14px; - padding: 16px 24px; + margin: 0 -28px 16px; + padding: 18px 28px 16px; border-bottom: 1px solid var(--color-border); - background: var(--color-surface); + background: rgba(255, 253, 252, 0.74); } .panel-header-copy { @@ -155,7 +155,7 @@ font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; - color: var(--color-brand); + color: var(--color-brand-dark); font-weight: 700; } @@ -239,9 +239,9 @@ .top-tab.active, .top-tab.nav-intent-active { - border-color: rgba(59, 130, 246, 0.22); + border-color: rgba(199, 116, 98, 0.18); color: var(--color-brand-dark); - background: rgba(59, 130, 246, 0.08); + background: var(--color-brand-light); box-shadow: none; } @@ -318,7 +318,7 @@ border-radius: 0; box-shadow: none; padding: 0; - max-width: 980px; + max-width: 1040px; } .mode-content { diff --git a/web-ui/styles/titles-cards.css b/web-ui/styles/titles-cards.css index 44fe5df..87fb73d 100644 --- a/web-ui/styles/titles-cards.css +++ b/web-ui/styles/titles-cards.css @@ -24,9 +24,9 @@ .subtitle { font-size: 13px; color: var(--color-text-secondary); - line-height: 1.45; + line-height: 1.58; margin-bottom: 0; - max-width: 72ch; + max-width: 70ch; letter-spacing: 0; } @@ -67,8 +67,8 @@ .segment.active { color: var(--color-brand-dark); - background: rgba(59, 130, 246, 0.08); - box-shadow: inset 0 0 0 1px rgba(59, 130, 246, 0.14); + background: var(--color-brand-light); + box-shadow: inset 0 0 0 1px rgba(199, 116, 98, 0.12); } /* ============================================ @@ -141,8 +141,8 @@ } .card.active { - background: rgba(59, 130, 246, 0.08); - border-color: rgba(59, 130, 246, 0.2); + background: var(--color-brand-light); + border-color: rgba(199, 116, 98, 0.18); box-shadow: none; } @@ -170,7 +170,7 @@ width: 32px; height: 32px; border-radius: 8px; - background: rgba(59, 130, 246, 0.1); + background: rgba(199, 116, 98, 0.1); display: flex; align-items: center; justify-content: center; @@ -183,7 +183,7 @@ } .card.active .card-icon { - background: rgba(59, 130, 246, 0.14); + background: rgba(199, 116, 98, 0.14); color: var(--color-brand-dark); box-shadow: none; } From abd41cc12237360c8f12b7f9d2647aee46baddb8 Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Wed, 8 Apr 2026 02:22:33 +0000 Subject: [PATCH 22/27] refactor(web-ui): keep shell chrome pinned --- tests/unit/compact-layout-ui.test.mjs | 5 +- web-ui/partials/index/layout-header.html | 172 ++++++++++++----------- web-ui/styles/base-theme.css | 12 ++ web-ui/styles/layout-shell.css | 9 ++ web-ui/styles/navigation-panels.css | 29 +++- web-ui/styles/responsive.css | 31 +++- 6 files changed, 163 insertions(+), 95 deletions(-) diff --git a/tests/unit/compact-layout-ui.test.mjs b/tests/unit/compact-layout-ui.test.mjs index 9b13c17..166a2eb 100644 --- a/tests/unit/compact-layout-ui.test.mjs +++ b/tests/unit/compact-layout-ui.test.mjs @@ -48,7 +48,10 @@ test('styles include force-compact fallback rules for readability on touch devic test('styles keep desktop layout wide and session history readable on large screens', () => { const styles = readBundledWebUiCss(); assert.match(styles, /\.container\s*\{[\s\S]*max-width:\s*none;[\s\S]*min-height:\s*100vh;/); - assert.match(styles, /\.app-shell\s*\{[\s\S]*grid-template-columns:\s*248px\s+minmax\(0,\s*1fr\);[\s\S]*min-height:\s*100vh;/); + assert.match(styles, /\.app-shell\s*\{[\s\S]*grid-template-columns:\s*248px\s+minmax\(0,\s*1fr\);[\s\S]*min-height:\s*100vh;[\s\S]*height:\s*100vh;[\s\S]*overflow:\s*hidden;/); + assert.match(styles, /\.side-rail\s*\{[\s\S]*overflow-y:\s*auto;[\s\S]*scrollbar-width:\s*none;/); + assert.match(styles, /\.main-panel\s*\{[\s\S]*overflow-y:\s*auto;[\s\S]*height:\s*100vh;[\s\S]*scrollbar-width:\s*none;/); + assert.match(styles, /\.main-panel-topbar\s*\{[\s\S]*position:\s*sticky;[\s\S]*top:\s*0;/); assert.match(styles, /\.session-layout\s*\{[\s\S]*grid-template-columns:\s*minmax\(260px,\s*360px\)\s*minmax\(0,\s*1fr\);/); assert.match(styles, /\.session-item\s*\{[\s\S]*min-height:\s*102px;/); diff --git a/web-ui/partials/index/layout-header.html b/web-ui/partials/index/layout-header.html index 57ec4d6..eae6b34 100644 --- a/web-ui/partials/index/layout-header.html +++ b/web-ui/partials/index/layout-header.html @@ -196,110 +196,112 @@
-
-
-
{{ mainTab === 'config' ? 'Configuration' : (mainTab === 'sessions' ? 'Sessions' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? 'Skills' : 'Settings'))) }}
-

{{ mainTab === 'config' ? '本地配置控制台' : (mainTab === 'sessions' ? '会话与导出' : (mainTab === 'usage' ? '本地用量与趋势' : (mainTab === 'market' ? 'Skills 安装与同步' : '系统与数据设置'))) }}

-

{{ mainTab === 'config' ? '管理 Codex、Claude Code 与 OpenClaw 的本地配置、模型与运行参数。' : (mainTab === 'sessions' ? '浏览、筛选、导出与整理本地会话记录。' : (mainTab === 'usage' ? '查看近 7 / 30 天的会话、消息与来源趋势。' : (mainTab === 'market' ? '整理安装目标、导入来源与分发入口。' : '管理下载、数据目录、回收站与全局行为。'))) }}

+
+
+
+
{{ mainTab === 'config' ? 'Configuration' : (mainTab === 'sessions' ? 'Sessions' : (mainTab === 'usage' ? 'Usage' : (mainTab === 'market' ? 'Skills' : 'Settings'))) }}
+

{{ mainTab === 'config' ? '本地配置控制台' : (mainTab === 'sessions' ? '会话与导出' : (mainTab === 'usage' ? '本地用量与趋势' : (mainTab === 'market' ? 'Skills 安装与同步' : '系统与数据设置'))) }}

+

{{ mainTab === 'config' ? '管理 Codex、Claude Code 与 OpenClaw 的本地配置、模型与运行参数。' : (mainTab === 'sessions' ? '浏览、筛选、导出与整理本地会话记录。' : (mainTab === 'usage' ? '查看近 7 / 30 天的会话、消息与来源趋势。' : (mainTab === 'market' ? '整理安装目标、导入来源与分发入口。' : '管理下载、数据目录、回收站与全局行为。'))) }}

+
-
-
- - - - -
-
-
- 当前来源 - - {{ sessionFilterSource === 'all' ? '全部' : (sessionFilterSource === 'claude' ? 'Claude Code' : 'Codex') }} - -
-
- 会话数 - {{ sessionsList.length }} -
-
-
-
- 统计范围 - {{ sessionsUsageTimeRange === '30d' ? '近 30 天' : '近 7 天' }} -
-
- 总会话数 - {{ sessionUsageSummaryCards[0]?.value ?? 0 }} -
-
- 总消息数 - {{ sessionUsageSummaryCards[1]?.value ?? 0 }} -
-
-
-
- 当前目标 - {{ skillsTargetLabel }} -
-
- 本地 Skills - {{ skillsList.length }} -
-
- 可导入 - {{ skillsImportList.length }}
-
- 可直接导入 - {{ skillsImportConfiguredCount }} +
+ +
-
- - -
diff --git a/web-ui/styles/base-theme.css b/web-ui/styles/base-theme.css index e23d24f..aa1f287 100644 --- a/web-ui/styles/base-theme.css +++ b/web-ui/styles/base-theme.css @@ -119,6 +119,9 @@ body.force-compact .provider-fast-switch-select { body.force-compact .app-shell { grid-template-columns: 1fr; gap: 12px; + height: auto; + min-height: auto; + overflow: visible; } body.force-compact .main-panel { @@ -127,6 +130,7 @@ body.force-compact .main-panel { align-self: stretch; width: 100%; height: auto; + overflow-y: visible; } body.force-compact .side-rail, @@ -151,6 +155,14 @@ body.force-compact .main-panel { padding: 14px 12px; } +body.force-compact .main-panel-topbar { + position: static; + margin: 0 0 10px; + padding: 0; + background: transparent; + backdrop-filter: none; +} + body.force-compact .card { display: flex; flex-direction: column; diff --git a/web-ui/styles/layout-shell.css b/web-ui/styles/layout-shell.css index d045fab..32eeb5b 100644 --- a/web-ui/styles/layout-shell.css +++ b/web-ui/styles/layout-shell.css @@ -28,6 +28,8 @@ body::after { gap: 0; align-items: stretch; min-height: 100vh; + height: 100vh; + overflow: hidden; background: var(--color-bg); } @@ -48,9 +50,16 @@ body::after { border-radius: 0; box-shadow: none; min-height: 100vh; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; backdrop-filter: none; } +.side-rail::-webkit-scrollbar { + display: none; +} + .side-rail .brand-title { font-size: 22px; margin-bottom: 0; diff --git a/web-ui/styles/navigation-panels.css b/web-ui/styles/navigation-panels.css index cdfef65..6601505 100644 --- a/web-ui/styles/navigation-panels.css +++ b/web-ui/styles/navigation-panels.css @@ -35,7 +35,7 @@ display: flex; flex-wrap: wrap; gap: 8px; - margin: 0 0 14px; + margin: 0 0 12px; } .status-chip { @@ -124,8 +124,25 @@ backdrop-filter: none; position: relative; overflow-x: hidden; - overflow-y: visible; + overflow-y: auto; min-height: 0; + height: 100vh; + scrollbar-width: none; + -ms-overflow-style: none; +} + +.main-panel::-webkit-scrollbar { + display: none; +} + +.main-panel-topbar { + position: sticky; + top: 0; + z-index: 12; + margin: 0 -28px 14px; + padding: 0 28px 12px; + background: linear-gradient(180deg, rgba(247, 243, 239, 0.96) 0%, rgba(247, 243, 239, 0.92) 78%, rgba(247, 243, 239, 0) 100%); + backdrop-filter: blur(8px); } .panel-header { @@ -138,10 +155,10 @@ align-items: center; justify-content: space-between; gap: 14px; - margin: 0 -28px 16px; - padding: 18px 28px 16px; + margin: 0 0 14px; + padding: 18px 0 14px; border-bottom: 1px solid var(--color-border); - background: rgba(255, 253, 252, 0.74); + background: transparent; } .panel-header-copy { @@ -317,7 +334,7 @@ border: none; border-radius: 0; box-shadow: none; - padding: 0; + padding: 0 0 40px; max-width: 1040px; } diff --git a/web-ui/styles/responsive.css b/web-ui/styles/responsive.css index e9bec75..14a64a4 100644 --- a/web-ui/styles/responsive.css +++ b/web-ui/styles/responsive.css @@ -21,6 +21,11 @@ textarea:focus-visible { padding: 0 20px 20px; } + .main-panel-topbar { + margin: 0 -20px 12px; + padding: 0 20px 10px; + } + } @media (max-width: 960px) { @@ -36,6 +41,10 @@ textarea:focus-visible { border-radius: 0; min-height: 0; } + .main-panel-topbar { + margin: 0 -16px 12px; + padding: 0 16px 10px; + } .top-tabs { display: none !important; } @@ -70,6 +79,8 @@ textarea:focus-visible { .app-shell { grid-template-columns: 1fr; min-height: auto; + height: auto; + overflow: visible; } .side-rail { @@ -88,12 +99,22 @@ textarea:focus-visible { .main-panel { padding: 0 12px 16px; + height: auto; + overflow-y: visible; + } + + .main-panel-topbar { + position: static; + margin: 0 0 10px; + padding: 0; + background: transparent; + backdrop-filter: none; } .panel-header-refined { - margin-left: -12px; - margin-right: -12px; - padding: 14px 12px; + margin-left: 0; + margin-right: 0; + padding: 14px 0 12px; } .main-title { @@ -164,6 +185,10 @@ textarea:focus-visible { .main-panel { padding: 0 10px 12px; } + + .main-panel-topbar { + margin-bottom: 8px; + } .card { padding: 12px; } From 7f97d29afd7de91eb02cdf328962bdf59a2e91b1 Mon Sep 17 00:00:00 2001 From: awsl233777 Date: Wed, 8 Apr 2026 02:37:26 +0000 Subject: [PATCH 23/27] refactor(web-ui): always show nav meta and logo --- tests/unit/compact-layout-ui.test.mjs | 8 ++++- web-ui/partials/index/layout-header.html | 9 ++++-- web-ui/styles/layout-shell.css | 39 ++++++++++++++++++------ 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/tests/unit/compact-layout-ui.test.mjs b/tests/unit/compact-layout-ui.test.mjs index 166a2eb..65aac74 100644 --- a/tests/unit/compact-layout-ui.test.mjs +++ b/tests/unit/compact-layout-ui.test.mjs @@ -2,7 +2,8 @@ import assert from 'assert'; import { readBundledWebUiCss, readProjectFile, - readBundledWebUiScript + readBundledWebUiScript, + readBundledWebUiHtml } from './helpers/web-ui-source.mjs'; test('app script includes compact layout detection and body class toggling', () => { @@ -52,9 +53,14 @@ test('styles keep desktop layout wide and session history readable on large scre assert.match(styles, /\.side-rail\s*\{[\s\S]*overflow-y:\s*auto;[\s\S]*scrollbar-width:\s*none;/); assert.match(styles, /\.main-panel\s*\{[\s\S]*overflow-y:\s*auto;[\s\S]*height:\s*100vh;[\s\S]*scrollbar-width:\s*none;/); assert.match(styles, /\.main-panel-topbar\s*\{[\s\S]*position:\s*sticky;[\s\S]*top:\s*0;/); + assert.match(styles, /\.side-item-meta\s*\{[\s\S]*display:\s*flex;[\s\S]*opacity:\s*1;/); + assert.match(styles, /\.brand-logo\s*\{[\s\S]*width:\s*38px;[\s\S]*height:\s*38px;/); assert.match(styles, /\.session-layout\s*\{[\s\S]*grid-template-columns:\s*minmax\(260px,\s*360px\)\s*minmax\(0,\s*1fr\);/); assert.match(styles, /\.session-item\s*\{[\s\S]*min-height:\s*102px;/); + const html = readBundledWebUiHtml(); + assert.match(html, /class="brand-logo"\s+src="\/res\/logo\.png"/); + const titleBlock = styles.match(/\.session-item-title\s*\{[^}]*\}/); assert.ok(titleBlock, 'missing session item title style block'); assert.match(titleBlock[0], /display:\s*-webkit-box;/); diff --git a/web-ui/partials/index/layout-header.html b/web-ui/partials/index/layout-header.html index eae6b34..ea9ea97 100644 --- a/web-ui/partials/index/layout-header.html +++ b/web-ui/partials/index/layout-header.html @@ -78,8 +78,13 @@
+
+
+ 包管理器 + {{ String(installPackageManager || 'npm').toUpperCase() }} +
+
+ 当前操作 + {{ installCommandAction === 'update' ? '升级' : (installCommandAction === 'uninstall' ? '卸载' : '安装') }} +
+
+ 镜像 + {{ installRegistryPreview || '官方默认' }} +
+
diff --git a/web-ui/partials/index/modals-basic.html b/web-ui/partials/index/modals-basic.html index 329d0e5..6c2718c 100644 --- a/web-ui/partials/index/modals-basic.html +++ b/web-ui/partials/index/modals-basic.html @@ -23,67 +23,6 @@
- -