codexmate 0.0.36 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -5
- package/README.zh.md +14 -5
- package/package.json +1 -1
- package/web-ui/app.js +0 -1
- package/web-ui/partials/index/layout-header.html +6 -2
- package/web-ui/partials/index/panel-usage.html +8 -12
- package/web-ui/res/web-ui-render.precompiled.js +29 -34
- package/web-ui/styles/layout-shell.css +11 -12
- package/web-ui/styles/sessions-usage.css +299 -151
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
[](https://www.npmjs.com/package/codexmate)
|
|
16
16
|
[](https://github.com/SakuraByteCore/codexmate/actions/workflows/release.yml)
|
|
17
17
|
[](https://www.npmjs.com/package/codexmate)
|
|
18
|
+
[](#install-via-homebrew-macos--linux)
|
|
18
19
|
[](#quick-start)
|
|
19
20
|
[](https://nodejs.org/)
|
|
20
21
|
[](LICENSE)
|
|
@@ -70,11 +71,19 @@ Unlike simple wrappers, Codex Mate acts as a **Local Agent Bridge**:
|
|
|
70
71
|
|
|
71
72
|
## Quick Start
|
|
72
73
|
|
|
74
|
+
### Install via Homebrew (macOS / Linux)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
brew tap SakuraByteCore/codexmate
|
|
78
|
+
brew install codexmate
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Requires [Node.js](https://nodejs.org/) (`brew install node` if not present).
|
|
82
|
+
|
|
73
83
|
### Install via npm
|
|
74
84
|
|
|
75
85
|
```bash
|
|
76
86
|
npm install -g codexmate
|
|
77
|
-
codexmate setup
|
|
78
87
|
codexmate run
|
|
79
88
|
```
|
|
80
89
|
|
|
@@ -102,7 +111,7 @@ flowchart TD
|
|
|
102
111
|
CLI[CLI]
|
|
103
112
|
WebUI[Web UI]
|
|
104
113
|
MCP[MCP Server]
|
|
105
|
-
|
|
114
|
+
|
|
106
115
|
subgraph Mate [Codex Mate Core]
|
|
107
116
|
API[HTTP API]
|
|
108
117
|
Config[Config Engine]
|
|
@@ -110,7 +119,7 @@ flowchart TD
|
|
|
110
119
|
Skills[Skills Market]
|
|
111
120
|
Tasks[Task Runner]
|
|
112
121
|
end
|
|
113
|
-
|
|
122
|
+
|
|
114
123
|
subgraph Local [Local Filesystem]
|
|
115
124
|
CodexDir[~/.codex]
|
|
116
125
|
ClaudeDir[~/.claude]
|
|
@@ -120,9 +129,9 @@ flowchart TD
|
|
|
120
129
|
|
|
121
130
|
User --> CLI & WebUI & MCP
|
|
122
131
|
CLI & WebUI & MCP --> API
|
|
123
|
-
|
|
132
|
+
|
|
124
133
|
API --> Config & Session & Skills & Tasks
|
|
125
|
-
|
|
134
|
+
|
|
126
135
|
Config --> CodexDir & ClaudeDir & ClawDir
|
|
127
136
|
Session --> State
|
|
128
137
|
Skills --> Local
|
package/README.zh.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
[](https://www.npmjs.com/package/codexmate)
|
|
16
16
|
[](https://github.com/SakuraByteCore/codexmate/actions/workflows/release.yml)
|
|
17
17
|
[](https://www.npmjs.com/package/codexmate)
|
|
18
|
+
[](#homebrew-安装macos--linux)
|
|
18
19
|
[](#快速开始)
|
|
19
20
|
[](https://nodejs.org/)
|
|
20
21
|
[](LICENSE)
|
|
@@ -70,11 +71,19 @@
|
|
|
70
71
|
|
|
71
72
|
## 快速开始
|
|
72
73
|
|
|
74
|
+
### Homebrew 安装(macOS / Linux)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
brew tap SakuraByteCore/codexmate
|
|
78
|
+
brew install codexmate
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
需要 [Node.js](https://nodejs.org/)(如未安装可执行 `brew install node`)。
|
|
82
|
+
|
|
73
83
|
### 通过 npm 安装
|
|
74
84
|
|
|
75
85
|
```bash
|
|
76
86
|
npm install -g codexmate
|
|
77
|
-
codexmate setup
|
|
78
87
|
codexmate run
|
|
79
88
|
```
|
|
80
89
|
|
|
@@ -102,7 +111,7 @@ flowchart TD
|
|
|
102
111
|
CLI[CLI 命令]
|
|
103
112
|
WebUI[Web 界面]
|
|
104
113
|
MCP[MCP 服务]
|
|
105
|
-
|
|
114
|
+
|
|
106
115
|
subgraph Mate [Codex Mate 核心]
|
|
107
116
|
API[HTTP API]
|
|
108
117
|
Config[配置引擎]
|
|
@@ -110,7 +119,7 @@ flowchart TD
|
|
|
110
119
|
Skills[Skills 市场]
|
|
111
120
|
Tasks[任务运行器]
|
|
112
121
|
end
|
|
113
|
-
|
|
122
|
+
|
|
114
123
|
subgraph Local [本地文件系统]
|
|
115
124
|
CodexDir[~/.codex]
|
|
116
125
|
ClaudeDir[~/.claude]
|
|
@@ -120,9 +129,9 @@ flowchart TD
|
|
|
120
129
|
|
|
121
130
|
User --> CLI & WebUI & MCP
|
|
122
131
|
CLI & WebUI & MCP --> API
|
|
123
|
-
|
|
132
|
+
|
|
124
133
|
API --> Config & Session & Skills & Tasks
|
|
125
|
-
|
|
134
|
+
|
|
126
135
|
Config --> CodexDir & ClaudeDir & ClawDir
|
|
127
136
|
Session --> State
|
|
128
137
|
Skills --> Local
|
package/package.json
CHANGED
package/web-ui/app.js
CHANGED
|
@@ -118,11 +118,11 @@
|
|
|
118
118
|
|
|
119
119
|
<div :class="['app-shell', { standalone: sessionStandalone }]">
|
|
120
120
|
<aside class="side-rail" v-if="!sessionStandalone">
|
|
121
|
-
<div class="brand-block"
|
|
121
|
+
<div class="brand-block">
|
|
122
122
|
<div class="brand-head">
|
|
123
123
|
<img class="brand-logo" src="/res/logo-pack.webp" alt="Codex Mate logo">
|
|
124
124
|
<div class="brand-copy">
|
|
125
|
-
<div class="brand-kicker">Codex Mate<
|
|
125
|
+
<div class="brand-kicker">Codex Mate<span v-if="appVersion" class="brand-version"> v{{ appVersion }}</span></div>
|
|
126
126
|
</div>
|
|
127
127
|
</div>
|
|
128
128
|
</div>
|
|
@@ -315,6 +315,10 @@
|
|
|
315
315
|
</div>
|
|
316
316
|
</button>
|
|
317
317
|
</div>
|
|
318
|
+
<div id="side-tab-new" class="side-item side-item-ghost" tabindex="-1" aria-hidden="true">
|
|
319
|
+
<div class="side-item-title">New Tab</div>
|
|
320
|
+
<div class="side-item-meta"><span> </span></div>
|
|
321
|
+
</div>
|
|
318
322
|
</div>
|
|
319
323
|
|
|
320
324
|
<div class="side-rail-lang" role="group" :aria-label="t('lang.label')">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Usage 统计 -
|
|
1
|
+
<!-- Usage 统计 - 流光设计 -->
|
|
2
2
|
<div
|
|
3
3
|
v-show="mainTab === 'usage'"
|
|
4
4
|
class="mode-content"
|
|
@@ -71,24 +71,20 @@
|
|
|
71
71
|
</div>
|
|
72
72
|
</div>
|
|
73
73
|
|
|
74
|
-
<!--
|
|
75
|
-
<section v-if="sessionUsageWave.points && sessionUsageWave.points.length" class="usage-
|
|
74
|
+
<!-- 波浪图 -->
|
|
75
|
+
<section v-if="sessionUsageWave.points && sessionUsageWave.points.length" class="usage-wave-section">
|
|
76
76
|
<div class="usage-card-title">{{ t('usage.daily.title') }}</div>
|
|
77
77
|
<div class="usage-wave-container">
|
|
78
78
|
<svg class="usage-wave-chart" viewBox="0 0 800 140" preserveAspectRatio="none">
|
|
79
79
|
<defs>
|
|
80
80
|
<linearGradient :id="'wave-gradient-' + sessionsUsageTimeRange" x1="0" y1="0" x2="0" y2="1">
|
|
81
|
-
<stop offset="0%" :stop-color="'var(--color-brand)'" stop-opacity="0.
|
|
81
|
+
<stop offset="0%" :stop-color="'var(--color-brand)'" stop-opacity="0.35"/>
|
|
82
82
|
<stop offset="100%" :stop-color="'var(--color-brand)'" stop-opacity="0"/>
|
|
83
83
|
</linearGradient>
|
|
84
84
|
</defs>
|
|
85
|
-
<!-- 填充区域 -->
|
|
86
85
|
<path :d="sessionUsageWave.areaPath" :fill="'url(#wave-gradient-' + sessionsUsageTimeRange + ')'" class="usage-wave-area"/>
|
|
87
|
-
<!-- 曲线 -->
|
|
88
86
|
<path :d="sessionUsageWave.linePath" fill="none" :stroke="'var(--color-brand)'" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="usage-wave-line"/>
|
|
89
|
-
|
|
90
|
-
<line v-if="sessionsUsageSelectedDay" x1="0" :x2="sessionUsageWave.width" :y1="sessionUsageWave.hoverY" :y2="sessionUsageWave.hoverY" stroke="currentColor" stroke-width="1" stroke-dasharray="4 4" opacity="0.4" class="usage-wave-hover-line"/>
|
|
91
|
-
<!-- 悬停点 -->
|
|
87
|
+
<line v-if="sessionsUsageSelectedDay" x1="0" :x2="sessionUsageWave.width" :y1="sessionUsageWave.hoverY" :y2="sessionUsageWave.hoverY" stroke="currentColor" stroke-width="1" stroke-dasharray="4 4" opacity="0.5" class="usage-wave-hover-line"/>
|
|
92
88
|
<circle v-if="sessionsUsageSelectedDay" :cx="sessionUsageWave.hoverX" :cy="sessionUsageWave.hoverY" r="5" :fill="'var(--color-surface)'" :stroke="'var(--color-brand)'" stroke-width="2.5" class="usage-wave-hover-point"/>
|
|
93
89
|
</svg>
|
|
94
90
|
<div class="usage-wave-labels">
|
|
@@ -112,8 +108,8 @@
|
|
|
112
108
|
</section>
|
|
113
109
|
|
|
114
110
|
<div class="usage-chart-grid">
|
|
115
|
-
<!--
|
|
116
|
-
<section class="usage-card
|
|
111
|
+
<!-- 热力图 -->
|
|
112
|
+
<section class="usage-card-hourly-heatmap">
|
|
117
113
|
<div class="usage-card-title">{{ t('usage.hourlyHeatmap.title') }}</div>
|
|
118
114
|
<div class="hourly-heatmap-wrapper">
|
|
119
115
|
<div class="hourly-heatmap-header">
|
|
@@ -166,7 +162,7 @@
|
|
|
166
162
|
</section>
|
|
167
163
|
|
|
168
164
|
<!-- Top Paths -->
|
|
169
|
-
<section class="usage-
|
|
165
|
+
<section class="usage-paths-section">
|
|
170
166
|
<div class="usage-card-title">{{ t('usage.paths.title') }}</div>
|
|
171
167
|
<div v-if="!sessionUsageCharts.topPaths.length" class="usage-list-value">{{ t('usage.paths.empty') }}</div>
|
|
172
168
|
<div v-else class="usage-list-paths">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
window.__CODEXMATE_WEB_UI_RENDER__ = (() => {
|
|
2
|
-
const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode,
|
|
2
|
+
const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList, vShow: _vShow, withDirectives: _withDirectives, vModelSelect: _vModelSelect, vModelText: _vModelText, withKeys: _withKeys, withModifiers: _withModifiers, isMemoSame: _isMemoSame, withMemo: _withMemo, normalizeStyle: _normalizeStyle, vModelCheckbox: _vModelCheckbox, vModelDynamic: _vModelDynamic } = Vue
|
|
3
3
|
|
|
4
4
|
return function render(_ctx, _cache) {
|
|
5
5
|
return (_openBlock(), _createElementBlock(_Fragment, null, [
|
|
@@ -165,14 +165,7 @@ return function render(_ctx, _cache) {
|
|
|
165
165
|
key: 0,
|
|
166
166
|
class: "side-rail"
|
|
167
167
|
}, [
|
|
168
|
-
_createElementVNode("div", {
|
|
169
|
-
class: "brand-block",
|
|
170
|
-
tabindex: "0",
|
|
171
|
-
onMouseenter: $event => (_ctx.brandHovered = true),
|
|
172
|
-
onMouseleave: $event => (_ctx.brandHovered = false),
|
|
173
|
-
onFocus: $event => (_ctx.brandHovered = true),
|
|
174
|
-
onBlur: $event => (_ctx.brandHovered = false)
|
|
175
|
-
}, [
|
|
168
|
+
_createElementVNode("div", { class: "brand-block" }, [
|
|
176
169
|
_createElementVNode("div", { class: "brand-head" }, [
|
|
177
170
|
_createElementVNode("img", {
|
|
178
171
|
class: "brand-logo",
|
|
@@ -182,21 +175,16 @@ return function render(_ctx, _cache) {
|
|
|
182
175
|
_createElementVNode("div", { class: "brand-copy" }, [
|
|
183
176
|
_createElementVNode("div", { class: "brand-kicker" }, [
|
|
184
177
|
_createTextVNode("Codex Mate"),
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}, " v" + _toDisplayString(_ctx.appVersion), 1 /* TEXT */))
|
|
192
|
-
: _createCommentVNode("v-if", true)
|
|
193
|
-
]),
|
|
194
|
-
_: 1 /* STABLE */
|
|
195
|
-
})
|
|
178
|
+
(_ctx.appVersion)
|
|
179
|
+
? (_openBlock(), _createElementBlock("span", {
|
|
180
|
+
key: 0,
|
|
181
|
+
class: "brand-version"
|
|
182
|
+
}, " v" + _toDisplayString(_ctx.appVersion), 1 /* TEXT */))
|
|
183
|
+
: _createCommentVNode("v-if", true)
|
|
196
184
|
])
|
|
197
185
|
])
|
|
198
186
|
])
|
|
199
|
-
]
|
|
187
|
+
]),
|
|
200
188
|
_createElementVNode("div", { class: "side-rail-nav" }, [
|
|
201
189
|
_createElementVNode("div", {
|
|
202
190
|
class: "side-section",
|
|
@@ -437,7 +425,18 @@ return function render(_ctx, _cache) {
|
|
|
437
425
|
: _createCommentVNode("v-if", true)
|
|
438
426
|
])
|
|
439
427
|
], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"])
|
|
440
|
-
], 8 /* PROPS */, ["aria-label"])
|
|
428
|
+
], 8 /* PROPS */, ["aria-label"]),
|
|
429
|
+
_createElementVNode("div", {
|
|
430
|
+
id: "side-tab-new",
|
|
431
|
+
class: "side-item side-item-ghost",
|
|
432
|
+
tabindex: "-1",
|
|
433
|
+
"aria-hidden": "true"
|
|
434
|
+
}, [
|
|
435
|
+
_createElementVNode("div", { class: "side-item-title" }, "New Tab"),
|
|
436
|
+
_createElementVNode("div", { class: "side-item-meta" }, [
|
|
437
|
+
_createElementVNode("span", null, " ")
|
|
438
|
+
])
|
|
439
|
+
])
|
|
441
440
|
]),
|
|
442
441
|
_createElementVNode("div", {
|
|
443
442
|
class: "side-rail-lang",
|
|
@@ -2668,7 +2667,7 @@ return function render(_ctx, _cache) {
|
|
|
2668
2667
|
], 512 /* NEED_PATCH */), [
|
|
2669
2668
|
[_vShow, _ctx.mainTab === 'sessions']
|
|
2670
2669
|
]),
|
|
2671
|
-
_createCommentVNode(" Usage 统计 -
|
|
2670
|
+
_createCommentVNode(" Usage 统计 - 流光设计 "),
|
|
2672
2671
|
_withDirectives(_createElementVNode("div", {
|
|
2673
2672
|
class: "mode-content",
|
|
2674
2673
|
id: "panel-usage",
|
|
@@ -2848,11 +2847,11 @@ return function render(_ctx, _cache) {
|
|
|
2848
2847
|
])
|
|
2849
2848
|
])
|
|
2850
2849
|
]),
|
|
2851
|
-
_createCommentVNode("
|
|
2850
|
+
_createCommentVNode(" 波浪图 "),
|
|
2852
2851
|
(_ctx.sessionUsageWave.points && _ctx.sessionUsageWave.points.length)
|
|
2853
2852
|
? (_openBlock(), _createElementBlock("section", {
|
|
2854
2853
|
key: 1,
|
|
2855
|
-
class: "usage-
|
|
2854
|
+
class: "usage-wave-section"
|
|
2856
2855
|
}, [
|
|
2857
2856
|
_createElementVNode("div", { class: "usage-card-title" }, _toDisplayString(_ctx.t('usage.daily.title')), 1 /* TEXT */),
|
|
2858
2857
|
_createElementVNode("div", { class: "usage-wave-container" }, [
|
|
@@ -2872,7 +2871,7 @@ return function render(_ctx, _cache) {
|
|
|
2872
2871
|
_createElementVNode("stop", {
|
|
2873
2872
|
offset: "0%",
|
|
2874
2873
|
"stop-color": 'var(--color-brand)',
|
|
2875
|
-
"stop-opacity": "0.
|
|
2874
|
+
"stop-opacity": "0.35"
|
|
2876
2875
|
}),
|
|
2877
2876
|
_createElementVNode("stop", {
|
|
2878
2877
|
offset: "100%",
|
|
@@ -2881,13 +2880,11 @@ return function render(_ctx, _cache) {
|
|
|
2881
2880
|
})
|
|
2882
2881
|
], 8 /* PROPS */, ["id"])
|
|
2883
2882
|
]),
|
|
2884
|
-
_createCommentVNode(" 填充区域 "),
|
|
2885
2883
|
_createElementVNode("path", {
|
|
2886
2884
|
d: _ctx.sessionUsageWave.areaPath,
|
|
2887
2885
|
fill: 'url(#wave-gradient-' + _ctx.sessionsUsageTimeRange + ')',
|
|
2888
2886
|
class: "usage-wave-area"
|
|
2889
2887
|
}, null, 8 /* PROPS */, ["d", "fill"]),
|
|
2890
|
-
_createCommentVNode(" 曲线 "),
|
|
2891
2888
|
_createElementVNode("path", {
|
|
2892
2889
|
d: _ctx.sessionUsageWave.linePath,
|
|
2893
2890
|
fill: "none",
|
|
@@ -2897,7 +2894,6 @@ return function render(_ctx, _cache) {
|
|
|
2897
2894
|
"stroke-linejoin": "round",
|
|
2898
2895
|
class: "usage-wave-line"
|
|
2899
2896
|
}, null, 8 /* PROPS */, ["d"]),
|
|
2900
|
-
_createCommentVNode(" 悬停指示线 "),
|
|
2901
2897
|
(_ctx.sessionsUsageSelectedDay)
|
|
2902
2898
|
? (_openBlock(), _createElementBlock("line", {
|
|
2903
2899
|
key: 0,
|
|
@@ -2908,11 +2904,10 @@ return function render(_ctx, _cache) {
|
|
|
2908
2904
|
stroke: "currentColor",
|
|
2909
2905
|
"stroke-width": "1",
|
|
2910
2906
|
"stroke-dasharray": "4 4",
|
|
2911
|
-
opacity: "0.
|
|
2907
|
+
opacity: "0.5",
|
|
2912
2908
|
class: "usage-wave-hover-line"
|
|
2913
2909
|
}, null, 8 /* PROPS */, ["x2", "y1", "y2"]))
|
|
2914
2910
|
: _createCommentVNode("v-if", true),
|
|
2915
|
-
_createCommentVNode(" 悬停点 "),
|
|
2916
2911
|
(_ctx.sessionsUsageSelectedDay)
|
|
2917
2912
|
? (_openBlock(), _createElementBlock("circle", {
|
|
2918
2913
|
key: 1,
|
|
@@ -2956,8 +2951,8 @@ return function render(_ctx, _cache) {
|
|
|
2956
2951
|
]))
|
|
2957
2952
|
: _createCommentVNode("v-if", true),
|
|
2958
2953
|
_createElementVNode("div", { class: "usage-chart-grid" }, [
|
|
2959
|
-
_createCommentVNode("
|
|
2960
|
-
_createElementVNode("section", { class: "usage-card
|
|
2954
|
+
_createCommentVNode(" 热力图 "),
|
|
2955
|
+
_createElementVNode("section", { class: "usage-card-hourly-heatmap" }, [
|
|
2961
2956
|
_createElementVNode("div", { class: "usage-card-title" }, _toDisplayString(_ctx.t('usage.hourlyHeatmap.title')), 1 /* TEXT */),
|
|
2962
2957
|
_createElementVNode("div", { class: "hourly-heatmap-wrapper" }, [
|
|
2963
2958
|
_createElementVNode("div", { class: "hourly-heatmap-header" }, [
|
|
@@ -3050,7 +3045,7 @@ return function render(_ctx, _cache) {
|
|
|
3050
3045
|
]))
|
|
3051
3046
|
]),
|
|
3052
3047
|
_createCommentVNode(" Top Paths "),
|
|
3053
|
-
_createElementVNode("section", { class: "usage-
|
|
3048
|
+
_createElementVNode("section", { class: "usage-paths-section" }, [
|
|
3054
3049
|
_createElementVNode("div", { class: "usage-card-title" }, _toDisplayString(_ctx.t('usage.paths.title')), 1 /* TEXT */),
|
|
3055
3050
|
(!_ctx.sessionUsageCharts.topPaths.length)
|
|
3056
3051
|
? (_openBlock(), _createElementBlock("div", {
|
|
@@ -415,6 +415,14 @@ body::after {
|
|
|
415
415
|
word-break: break-word;
|
|
416
416
|
}
|
|
417
417
|
|
|
418
|
+
.side-item-ghost {
|
|
419
|
+
opacity: 0;
|
|
420
|
+
pointer-events: none;
|
|
421
|
+
user-select: none;
|
|
422
|
+
cursor: default;
|
|
423
|
+
flex: 0 0 auto;
|
|
424
|
+
}
|
|
425
|
+
|
|
418
426
|
@media (min-width: 721px) {
|
|
419
427
|
body:not(.force-compact) #app > .top-tabs {
|
|
420
428
|
display: none;
|
|
@@ -431,16 +439,6 @@ body::after {
|
|
|
431
439
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
|
|
432
440
|
}
|
|
433
441
|
|
|
434
|
-
.brand-block:focus-visible {
|
|
435
|
-
outline: 2px solid rgba(0, 122, 255, 0.5);
|
|
436
|
-
outline-offset: -2px;
|
|
437
|
-
border-radius: 4px;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
.brand-block:focus:not(:focus-visible) {
|
|
441
|
-
outline: none;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
442
|
.brand-head {
|
|
445
443
|
display: flex;
|
|
446
444
|
align-items: center;
|
|
@@ -484,7 +482,7 @@ body::after {
|
|
|
484
482
|
}
|
|
485
483
|
|
|
486
484
|
.brand-kicker {
|
|
487
|
-
font-size:
|
|
485
|
+
font-size: 15px;
|
|
488
486
|
line-height: 1.2;
|
|
489
487
|
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
|
|
490
488
|
color: #1d1d1f;
|
|
@@ -502,10 +500,11 @@ body::after {
|
|
|
502
500
|
}
|
|
503
501
|
|
|
504
502
|
.brand-version {
|
|
505
|
-
font-size:
|
|
503
|
+
font-size: 13px;
|
|
506
504
|
font-weight: 400;
|
|
507
505
|
color: #8e8e93;
|
|
508
506
|
vertical-align: baseline;
|
|
507
|
+
-webkit-text-fill-color: #8e8e93;
|
|
509
508
|
}
|
|
510
509
|
|
|
511
510
|
.brand-version-fade-enter-active,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ============================================
|
|
2
|
-
Usage Tab —
|
|
2
|
+
Usage Tab — 流光设计 (Flow of Light)
|
|
3
3
|
============================================ */
|
|
4
4
|
|
|
5
5
|
/* ---- Toolbar ---- */
|
|
@@ -7,73 +7,80 @@
|
|
|
7
7
|
display: flex;
|
|
8
8
|
justify-content: space-between;
|
|
9
9
|
align-items: center;
|
|
10
|
-
gap:
|
|
10
|
+
gap: 16px;
|
|
11
11
|
flex-wrap: wrap;
|
|
12
|
-
margin-bottom:
|
|
12
|
+
margin-bottom: 28px;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.usage-toolbar-title {
|
|
16
|
-
font-size:
|
|
16
|
+
font-size: 20px;
|
|
17
17
|
font-weight: 600;
|
|
18
18
|
color: var(--color-text-primary);
|
|
19
|
-
letter-spacing: -0.
|
|
19
|
+
letter-spacing: -0.03em;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.usage-range-group {
|
|
23
23
|
display: flex;
|
|
24
|
-
gap:
|
|
25
|
-
padding:
|
|
26
|
-
border-radius:
|
|
27
|
-
background:
|
|
28
|
-
border: 1px solid
|
|
24
|
+
gap: 2px;
|
|
25
|
+
padding: 3px;
|
|
26
|
+
border-radius: 12px;
|
|
27
|
+
background: linear-gradient(135deg, rgba(255,255,255,0.9), rgba(247,239,232,0.7));
|
|
28
|
+
border: 1px solid rgba(137, 111, 94, 0.08);
|
|
29
|
+
box-shadow: 0 2px 12px rgba(92, 68, 52, 0.06);
|
|
30
|
+
backdrop-filter: blur(8px);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
.usage-range-btn {
|
|
32
34
|
border: none;
|
|
33
35
|
background: transparent;
|
|
34
36
|
color: var(--color-text-tertiary);
|
|
35
|
-
padding:
|
|
36
|
-
border-radius:
|
|
37
|
+
padding: 8px 16px;
|
|
38
|
+
border-radius: 9px;
|
|
37
39
|
cursor: pointer;
|
|
38
40
|
font-size: 13px;
|
|
39
41
|
font-weight: 500;
|
|
40
42
|
font-family: var(--font-family);
|
|
41
43
|
white-space: nowrap;
|
|
42
|
-
transition: all
|
|
44
|
+
transition: all 180ms var(--ease-spring);
|
|
43
45
|
outline: none;
|
|
44
46
|
-webkit-tap-highlight-color: transparent;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
.usage-range-btn:hover:not(:disabled) {
|
|
48
50
|
color: var(--color-text-secondary);
|
|
49
|
-
background:
|
|
51
|
+
background: rgba(200, 121, 99, 0.08);
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
.usage-range-btn:active:not(:disabled) {
|
|
53
|
-
transform: scale(0.
|
|
55
|
+
transform: scale(0.95);
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
.usage-range-btn.active {
|
|
57
59
|
color: #fff;
|
|
58
|
-
background: var(--color-brand);
|
|
59
|
-
box-shadow: 0
|
|
60
|
+
background: linear-gradient(135deg, var(--color-brand), var(--color-brand-dark));
|
|
61
|
+
box-shadow: 0 4px 16px rgba(200, 121, 99, 0.35), 0 0 0 1px rgba(255,255,255,0.1) inset;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
.usage-range-btn:disabled {
|
|
63
|
-
opacity: 0.
|
|
65
|
+
opacity: 0.35;
|
|
64
66
|
cursor: not-allowed;
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
.usage-range-btn-icon {
|
|
68
|
-
padding:
|
|
70
|
+
padding: 8px 12px;
|
|
69
71
|
display: inline-flex;
|
|
70
72
|
align-items: center;
|
|
71
73
|
justify-content: center;
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
.usage-range-btn-icon svg {
|
|
75
|
-
width:
|
|
76
|
-
height:
|
|
77
|
+
width: 16px;
|
|
78
|
+
height: 16px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.usage-range-btn-icon:active {
|
|
82
|
+
transform: rotate(180deg);
|
|
83
|
+
transition: transform 400ms var(--ease-spring);
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
/* ---- Empty State (插画风格) ---- */
|
|
@@ -82,67 +89,87 @@
|
|
|
82
89
|
flex-direction: column;
|
|
83
90
|
align-items: center;
|
|
84
91
|
justify-content: center;
|
|
85
|
-
padding:
|
|
92
|
+
padding: 64px 20px;
|
|
86
93
|
text-align: center;
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
.usage-empty-illustration {
|
|
90
|
-
width:
|
|
91
|
-
height:
|
|
97
|
+
width: 72px;
|
|
98
|
+
height: 72px;
|
|
92
99
|
color: var(--color-text-muted);
|
|
93
|
-
opacity: 0.
|
|
94
|
-
margin-bottom:
|
|
95
|
-
animation: usage-empty-breathe
|
|
100
|
+
opacity: 0.5;
|
|
101
|
+
margin-bottom: 20px;
|
|
102
|
+
animation: usage-empty-breathe 4s ease-in-out infinite;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
@keyframes usage-empty-breathe {
|
|
99
|
-
0%, 100% { transform: scale(1); opacity: 0.5; }
|
|
100
|
-
50% { transform: scale(1.
|
|
106
|
+
0%, 100% { transform: scale(1) translateY(0); opacity: 0.5; }
|
|
107
|
+
50% { transform: scale(1.08) translateY(-4px); opacity: 0.7; }
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
.usage-empty-text {
|
|
104
|
-
font-size:
|
|
111
|
+
font-size: 14px;
|
|
105
112
|
color: var(--color-text-secondary);
|
|
106
|
-
max-width:
|
|
113
|
+
max-width: 300px;
|
|
114
|
+
line-height: 1.6;
|
|
107
115
|
}
|
|
108
116
|
|
|
109
|
-
/* ---- Hero 区域 ---- */
|
|
117
|
+
/* ---- Hero 区域 (全宽沉浸式) ---- */
|
|
110
118
|
.usage-hero {
|
|
111
|
-
padding:
|
|
112
|
-
margin-bottom:
|
|
113
|
-
border-radius:
|
|
114
|
-
background:
|
|
115
|
-
border: 1px solid
|
|
116
|
-
min-height:
|
|
119
|
+
padding: 32px 28px;
|
|
120
|
+
margin-bottom: 24px;
|
|
121
|
+
border-radius: 18px;
|
|
122
|
+
background: linear-gradient(135deg, rgba(255,255,255,0.95), rgba(252,248,241,0.9));
|
|
123
|
+
border: 1px solid rgba(137, 111, 94, 0.08);
|
|
124
|
+
min-height: 160px;
|
|
117
125
|
display: flex;
|
|
118
126
|
flex-direction: column;
|
|
119
127
|
justify-content: center;
|
|
120
|
-
gap:
|
|
128
|
+
gap: 20px;
|
|
129
|
+
box-shadow: 0 8px 32px rgba(92, 68, 52, 0.08), 0 0 0 1px rgba(255,255,255,0.5) inset;
|
|
130
|
+
backdrop-filter: blur(10px);
|
|
131
|
+
position: relative;
|
|
132
|
+
overflow: hidden;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.usage-hero::before {
|
|
136
|
+
content: '';
|
|
137
|
+
position: absolute;
|
|
138
|
+
top: -50%;
|
|
139
|
+
right: -20%;
|
|
140
|
+
width: 400px;
|
|
141
|
+
height: 400px;
|
|
142
|
+
background: radial-gradient(circle, rgba(200, 121, 99, 0.06) 0%, transparent 70%);
|
|
143
|
+
pointer-events: none;
|
|
121
144
|
}
|
|
122
145
|
|
|
123
146
|
.usage-hero-active {
|
|
124
147
|
display: flex;
|
|
125
148
|
flex-wrap: wrap;
|
|
126
149
|
align-items: center;
|
|
127
|
-
gap:
|
|
128
|
-
padding:
|
|
129
|
-
border-radius:
|
|
130
|
-
background:
|
|
150
|
+
gap: 10px 16px;
|
|
151
|
+
padding: 12px 18px;
|
|
152
|
+
border-radius: 12px;
|
|
153
|
+
background: linear-gradient(135deg, rgba(200, 121, 99, 0.08), rgba(200, 121, 99, 0.04));
|
|
154
|
+
border: 1px solid rgba(200, 121, 99, 0.12);
|
|
131
155
|
font-size: 12px;
|
|
156
|
+
position: relative;
|
|
157
|
+
z-index: 1;
|
|
132
158
|
}
|
|
133
159
|
|
|
134
160
|
.usage-hero-active-dot {
|
|
135
|
-
width:
|
|
136
|
-
height:
|
|
161
|
+
width: 7px;
|
|
162
|
+
height: 7px;
|
|
137
163
|
border-radius: 50%;
|
|
138
164
|
background: var(--color-success);
|
|
139
165
|
flex-shrink: 0;
|
|
140
|
-
animation: usage-pulse 2s ease-in-out infinite;
|
|
166
|
+
animation: usage-pulse 2.2s ease-in-out infinite;
|
|
167
|
+
box-shadow: 0 0 12px rgba(75, 139, 106, 0.4);
|
|
141
168
|
}
|
|
142
169
|
|
|
143
170
|
@keyframes usage-pulse {
|
|
144
171
|
0%, 100% { opacity: 1; transform: scale(1); }
|
|
145
|
-
50% { opacity: 0.
|
|
172
|
+
50% { opacity: 0.5; transform: scale(0.85); }
|
|
146
173
|
}
|
|
147
174
|
|
|
148
175
|
.usage-hero-active-label {
|
|
@@ -156,122 +183,162 @@
|
|
|
156
183
|
|
|
157
184
|
.usage-hero-active-stat::before {
|
|
158
185
|
content: '·';
|
|
159
|
-
margin-right:
|
|
186
|
+
margin-right: 12px;
|
|
160
187
|
color: var(--color-border-strong);
|
|
161
188
|
}
|
|
162
189
|
|
|
163
190
|
.usage-hero-metrics {
|
|
164
191
|
text-align: center;
|
|
192
|
+
position: relative;
|
|
193
|
+
z-index: 1;
|
|
165
194
|
}
|
|
166
195
|
|
|
167
196
|
.usage-hero-main {
|
|
168
|
-
font-size:
|
|
197
|
+
font-size: 52px;
|
|
169
198
|
font-weight: 700;
|
|
170
199
|
color: var(--color-text-primary);
|
|
171
200
|
line-height: 1;
|
|
172
|
-
letter-spacing: -0.
|
|
201
|
+
letter-spacing: -0.04em;
|
|
173
202
|
font-variant-numeric: tabular-nums;
|
|
174
|
-
animation: usage-hero-count
|
|
203
|
+
animation: usage-hero-count 1s var(--ease-out-expo);
|
|
204
|
+
background: linear-gradient(135deg, var(--color-text-primary) 0%, var(--color-brand) 100%);
|
|
205
|
+
-webkit-background-clip: text;
|
|
206
|
+
-webkit-text-fill-color: transparent;
|
|
207
|
+
background-clip: text;
|
|
175
208
|
}
|
|
176
209
|
|
|
177
210
|
@keyframes usage-hero-count {
|
|
178
|
-
from { opacity: 0; transform: translateY(
|
|
179
|
-
to { opacity: 1; transform: translateY(0); }
|
|
211
|
+
from { opacity: 0; transform: translateY(16px) scale(0.95); }
|
|
212
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
180
213
|
}
|
|
181
214
|
|
|
182
215
|
.usage-hero-sub {
|
|
183
|
-
margin-top:
|
|
184
|
-
font-size:
|
|
216
|
+
margin-top: 10px;
|
|
217
|
+
font-size: 14px;
|
|
185
218
|
color: var(--color-text-tertiary);
|
|
186
219
|
display: flex;
|
|
187
220
|
align-items: center;
|
|
188
221
|
justify-content: center;
|
|
189
|
-
gap:
|
|
222
|
+
gap: 14px;
|
|
190
223
|
flex-wrap: wrap;
|
|
191
224
|
}
|
|
192
225
|
|
|
193
226
|
.usage-hero-delta {
|
|
194
227
|
font-size: 12px;
|
|
195
228
|
font-weight: 600;
|
|
196
|
-
padding:
|
|
197
|
-
border-radius:
|
|
229
|
+
padding: 3px 10px;
|
|
230
|
+
border-radius: 16px;
|
|
198
231
|
}
|
|
199
232
|
|
|
200
233
|
.usage-hero-delta.delta-up {
|
|
201
|
-
color: var(--color-
|
|
202
|
-
background: rgba(
|
|
234
|
+
color: var(--color-success);
|
|
235
|
+
background: linear-gradient(135deg, rgba(75, 139, 106, 0.15), rgba(75, 139, 106, 0.08));
|
|
203
236
|
}
|
|
204
237
|
|
|
205
238
|
.usage-hero-delta.delta-down {
|
|
206
|
-
color: var(--color-
|
|
207
|
-
background: rgba(
|
|
239
|
+
color: var(--color-error);
|
|
240
|
+
background: linear-gradient(135deg, rgba(196, 69, 54, 0.15), rgba(196, 69, 54, 0.08));
|
|
208
241
|
}
|
|
209
242
|
|
|
210
|
-
/* ---- 波浪图 ---- */
|
|
243
|
+
/* ---- 波浪图 (流体动画) ---- */
|
|
211
244
|
.usage-wave-section {
|
|
212
245
|
overflow: hidden;
|
|
246
|
+
border: none;
|
|
247
|
+
background: transparent;
|
|
248
|
+
padding: 0;
|
|
249
|
+
margin-bottom: 24px;
|
|
213
250
|
}
|
|
214
251
|
|
|
215
252
|
.usage-wave-container {
|
|
216
|
-
margin-top:
|
|
253
|
+
margin-top: 16px;
|
|
217
254
|
position: relative;
|
|
255
|
+
padding: 20px;
|
|
256
|
+
border-radius: 18px;
|
|
257
|
+
background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(252,248,241,0.6));
|
|
258
|
+
border: 1px solid rgba(137, 111, 94, 0.06);
|
|
259
|
+
box-shadow: 0 4px 20px rgba(92, 68, 52, 0.05);
|
|
260
|
+
backdrop-filter: blur(8px);
|
|
218
261
|
}
|
|
219
262
|
|
|
220
263
|
.usage-wave-chart {
|
|
221
264
|
width: 100%;
|
|
222
|
-
height:
|
|
265
|
+
height: 150px;
|
|
223
266
|
display: block;
|
|
224
267
|
}
|
|
225
268
|
|
|
226
269
|
.usage-wave-area {
|
|
227
|
-
transition: d
|
|
270
|
+
transition: d 600ms var(--ease-spring);
|
|
271
|
+
animation: usage-wave-pulse 4s ease-in-out infinite;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@keyframes usage-wave-pulse {
|
|
275
|
+
0%, 100% { opacity: 1; }
|
|
276
|
+
50% { opacity: 0.85; }
|
|
228
277
|
}
|
|
229
278
|
|
|
230
279
|
.usage-wave-line {
|
|
231
|
-
transition: d
|
|
280
|
+
transition: d 600ms var(--ease-spring);
|
|
281
|
+
filter: drop-shadow(0 4px 12px rgba(200, 121, 99, 0.25));
|
|
232
282
|
}
|
|
233
283
|
|
|
234
284
|
.usage-wave-hover-line {
|
|
235
|
-
transition: x1
|
|
285
|
+
transition: x1 200ms var(--ease-spring), x2 200ms var(--ease-spring),
|
|
286
|
+
y1 200ms var(--ease-spring), y2 200ms var(--ease-spring);
|
|
287
|
+
stroke-dasharray: 4 4;
|
|
288
|
+
animation: usage-hover-dash 20s linear infinite;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@keyframes usage-hover-dash {
|
|
292
|
+
to { stroke-dashoffset: -100; }
|
|
236
293
|
}
|
|
237
294
|
|
|
238
295
|
.usage-wave-hover-point {
|
|
239
|
-
transition: cx
|
|
296
|
+
transition: cx 200ms var(--ease-spring), cy 200ms var(--ease-spring);
|
|
297
|
+
filter: drop-shadow(0 0 8px rgba(200, 121, 99, 0.4));
|
|
298
|
+
animation: usage-point-pulse 2s ease-in-out infinite;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@keyframes usage-point-pulse {
|
|
302
|
+
0%, 100% { r: 5; }
|
|
303
|
+
50% { r: 6.5; }
|
|
240
304
|
}
|
|
241
305
|
|
|
242
306
|
.usage-wave-labels {
|
|
243
307
|
display: flex;
|
|
244
308
|
justify-content: space-between;
|
|
245
|
-
margin-top:
|
|
246
|
-
padding: 0
|
|
309
|
+
margin-top: 12px;
|
|
310
|
+
padding: 0 8px;
|
|
247
311
|
}
|
|
248
312
|
|
|
249
313
|
.usage-wave-label {
|
|
250
|
-
font-size:
|
|
314
|
+
font-size: 11px;
|
|
251
315
|
color: var(--color-text-muted);
|
|
252
316
|
cursor: pointer;
|
|
253
|
-
padding:
|
|
254
|
-
border-radius:
|
|
255
|
-
transition: all
|
|
317
|
+
padding: 4px 8px;
|
|
318
|
+
border-radius: 6px;
|
|
319
|
+
transition: all 180ms var(--ease-spring);
|
|
256
320
|
-webkit-tap-highlight-color: transparent;
|
|
321
|
+
font-weight: 500;
|
|
257
322
|
}
|
|
258
323
|
|
|
259
324
|
.usage-wave-label:hover {
|
|
260
325
|
color: var(--color-text-secondary);
|
|
261
|
-
background:
|
|
326
|
+
background: rgba(200, 121, 99, 0.08);
|
|
262
327
|
}
|
|
263
328
|
|
|
264
329
|
.usage-wave-label.active {
|
|
265
330
|
color: var(--color-brand);
|
|
266
331
|
font-weight: 600;
|
|
332
|
+
background: linear-gradient(135deg, rgba(200, 121, 99, 0.12), rgba(200, 121, 99, 0.06));
|
|
267
333
|
}
|
|
268
334
|
|
|
269
335
|
/* ---- 日期详情 ---- */
|
|
270
336
|
.usage-daydetail {
|
|
271
337
|
margin-top: 16px;
|
|
272
|
-
padding:
|
|
273
|
-
border-radius:
|
|
274
|
-
background:
|
|
338
|
+
padding: 14px 18px;
|
|
339
|
+
border-radius: 12px;
|
|
340
|
+
background: linear-gradient(135deg, rgba(247, 239, 232, 0.8), rgba(247, 239, 232, 0.4));
|
|
341
|
+
border: 1px solid rgba(137, 111, 94, 0.06);
|
|
275
342
|
}
|
|
276
343
|
|
|
277
344
|
.usage-daydetail-header {
|
|
@@ -284,7 +351,7 @@
|
|
|
284
351
|
|
|
285
352
|
.usage-daydetail-date {
|
|
286
353
|
font-weight: 600;
|
|
287
|
-
font-size:
|
|
354
|
+
font-size: 14px;
|
|
288
355
|
color: var(--color-text-primary);
|
|
289
356
|
}
|
|
290
357
|
|
|
@@ -294,32 +361,41 @@
|
|
|
294
361
|
}
|
|
295
362
|
|
|
296
363
|
.usage-daydetail-compare {
|
|
297
|
-
margin-top:
|
|
364
|
+
margin-top: 6px;
|
|
298
365
|
font-size: 11px;
|
|
299
366
|
color: var(--color-text-muted);
|
|
300
367
|
}
|
|
301
368
|
|
|
302
|
-
/* ---- 热力图 ---- */
|
|
369
|
+
/* ---- 热力图 (动态呼吸) ---- */
|
|
303
370
|
.usage-card-hourly-heatmap {
|
|
304
371
|
overflow-x: auto;
|
|
372
|
+
border: none;
|
|
373
|
+
background: transparent;
|
|
374
|
+
padding: 0;
|
|
305
375
|
}
|
|
306
376
|
|
|
307
377
|
.hourly-heatmap-wrapper {
|
|
308
378
|
display: flex;
|
|
309
379
|
flex-direction: column;
|
|
310
|
-
gap:
|
|
311
|
-
margin-top:
|
|
312
|
-
min-width:
|
|
380
|
+
gap: 3px;
|
|
381
|
+
margin-top: 14px;
|
|
382
|
+
min-width: 500px;
|
|
383
|
+
padding: 16px;
|
|
384
|
+
border-radius: 18px;
|
|
385
|
+
background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(252,248,241,0.6));
|
|
386
|
+
border: 1px solid rgba(137, 111, 94, 0.06);
|
|
387
|
+
box-shadow: 0 4px 20px rgba(92, 68, 52, 0.05);
|
|
388
|
+
backdrop-filter: blur(8px);
|
|
313
389
|
}
|
|
314
390
|
|
|
315
391
|
.hourly-heatmap-header {
|
|
316
392
|
display: flex;
|
|
317
|
-
gap:
|
|
393
|
+
gap: 3px;
|
|
318
394
|
align-items: flex-end;
|
|
319
395
|
}
|
|
320
396
|
|
|
321
397
|
.hourly-heatmap-corner {
|
|
322
|
-
width:
|
|
398
|
+
width: 36px;
|
|
323
399
|
flex-shrink: 0;
|
|
324
400
|
}
|
|
325
401
|
|
|
@@ -334,83 +410,130 @@
|
|
|
334
410
|
|
|
335
411
|
.hourly-heatmap-row {
|
|
336
412
|
display: flex;
|
|
337
|
-
gap:
|
|
413
|
+
gap: 3px;
|
|
338
414
|
align-items: center;
|
|
339
415
|
}
|
|
340
416
|
|
|
341
417
|
.hourly-heatmap-weekday-label {
|
|
342
|
-
width:
|
|
418
|
+
width: 36px;
|
|
343
419
|
flex-shrink: 0;
|
|
344
|
-
font-size:
|
|
420
|
+
font-size: 11px;
|
|
345
421
|
color: var(--color-text-secondary);
|
|
346
422
|
text-align: right;
|
|
347
|
-
padding-right:
|
|
423
|
+
padding-right: 6px;
|
|
424
|
+
font-weight: 500;
|
|
348
425
|
}
|
|
349
426
|
|
|
350
427
|
.hourly-heatmap-cell {
|
|
351
428
|
flex: 1;
|
|
352
429
|
min-width: 0;
|
|
353
|
-
height:
|
|
354
|
-
border-radius:
|
|
355
|
-
transition:
|
|
430
|
+
height: 7px;
|
|
431
|
+
border-radius: 4px;
|
|
432
|
+
transition: all 200ms var(--ease-spring);
|
|
433
|
+
cursor: crosshair;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.hourly-heatmap-cell:hover {
|
|
437
|
+
transform: scaleY(1.4);
|
|
438
|
+
filter: brightness(1.1);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.hourly-heatmap-cell.level-0 {
|
|
442
|
+
background: var(--color-surface-alt);
|
|
443
|
+
}
|
|
444
|
+
.hourly-heatmap-cell.level-1 {
|
|
445
|
+
background: var(--color-heatmap-1);
|
|
446
|
+
animation: heatmap-breath-1 3s ease-in-out infinite;
|
|
447
|
+
}
|
|
448
|
+
.hourly-heatmap-cell.level-2 {
|
|
449
|
+
background: var(--color-heatmap-2);
|
|
450
|
+
animation: heatmap-breath-2 3s ease-in-out infinite;
|
|
451
|
+
}
|
|
452
|
+
.hourly-heatmap-cell.level-3 {
|
|
453
|
+
background: var(--color-heatmap-3);
|
|
454
|
+
animation: heatmap-breath-3 3s ease-in-out infinite;
|
|
455
|
+
}
|
|
456
|
+
.hourly-heatmap-cell.level-4 {
|
|
457
|
+
background: var(--color-heatmap-4);
|
|
458
|
+
animation: heatmap-breath-4 3s ease-in-out infinite;
|
|
459
|
+
box-shadow: 0 0 8px rgba(200, 121, 99, 0.3);
|
|
356
460
|
}
|
|
357
461
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
462
|
+
@keyframes heatmap-breath-1 {
|
|
463
|
+
0%, 100% { opacity: 1; }
|
|
464
|
+
50% { opacity: 0.85; }
|
|
465
|
+
}
|
|
466
|
+
@keyframes heatmap-breath-2 {
|
|
467
|
+
0%, 100% { opacity: 1; }
|
|
468
|
+
50% { opacity: 0.9; }
|
|
469
|
+
}
|
|
470
|
+
@keyframes heatmap-breath-3 {
|
|
471
|
+
0%, 100% { opacity: 1; }
|
|
472
|
+
50% { opacity: 0.95; }
|
|
473
|
+
}
|
|
474
|
+
@keyframes heatmap-breath-4 {
|
|
475
|
+
0%, 100% { opacity: 1; box-shadow: 0 0 8px rgba(200, 121, 99, 0.3); }
|
|
476
|
+
50% { opacity: 0.9; box-shadow: 0 0 14px rgba(200, 121, 99, 0.5); }
|
|
477
|
+
}
|
|
363
478
|
|
|
364
479
|
.hourly-heatmap-legend {
|
|
365
480
|
display: flex;
|
|
366
481
|
align-items: center;
|
|
367
|
-
gap:
|
|
482
|
+
gap: 4px;
|
|
368
483
|
justify-content: flex-end;
|
|
369
|
-
margin-top:
|
|
484
|
+
margin-top: 12px;
|
|
370
485
|
font-size: 10px;
|
|
371
486
|
color: var(--color-text-muted);
|
|
372
487
|
}
|
|
373
488
|
|
|
374
489
|
.hourly-heatmap-legend .hourly-heatmap-cell {
|
|
375
|
-
width:
|
|
376
|
-
height:
|
|
490
|
+
width: 12px;
|
|
491
|
+
height: 12px;
|
|
492
|
+
border-radius: 3px;
|
|
377
493
|
}
|
|
378
494
|
|
|
379
495
|
.hourly-heatmap-legend-label {
|
|
380
|
-
margin: 0
|
|
496
|
+
margin: 0 4px;
|
|
381
497
|
}
|
|
382
498
|
|
|
383
|
-
/* ---- 列表样式 ---- */
|
|
499
|
+
/* ---- 列表样式 (加大间距) ---- */
|
|
384
500
|
.usage-list-compact {
|
|
385
501
|
display: flex;
|
|
386
502
|
flex-direction: column;
|
|
387
|
-
gap:
|
|
503
|
+
gap: 6px;
|
|
388
504
|
}
|
|
389
505
|
|
|
390
506
|
.usage-list-compact-item {
|
|
391
507
|
display: flex;
|
|
392
508
|
align-items: flex-start;
|
|
393
|
-
gap:
|
|
394
|
-
padding:
|
|
395
|
-
border-radius:
|
|
509
|
+
gap: 10px;
|
|
510
|
+
padding: 10px 14px;
|
|
511
|
+
border-radius: 10px;
|
|
396
512
|
cursor: pointer;
|
|
397
|
-
transition: all
|
|
513
|
+
transition: all 180ms var(--ease-spring);
|
|
398
514
|
-webkit-tap-highlight-color: transparent;
|
|
399
515
|
}
|
|
400
516
|
|
|
401
517
|
.usage-list-compact-item:hover {
|
|
402
|
-
background:
|
|
518
|
+
background: linear-gradient(135deg, rgba(255,255,255,0.9), rgba(252,248,241,0.7));
|
|
519
|
+
transform: translateX(4px);
|
|
520
|
+
box-shadow: 0 2px 8px rgba(92, 68, 52, 0.06);
|
|
403
521
|
}
|
|
404
522
|
|
|
405
523
|
.usage-list-compact-item:active {
|
|
406
|
-
transform: scale(0.98);
|
|
524
|
+
transform: translateX(2px) scale(0.98);
|
|
407
525
|
}
|
|
408
526
|
|
|
409
527
|
.usage-list-bullet {
|
|
410
528
|
color: var(--color-brand);
|
|
411
|
-
font-size:
|
|
529
|
+
font-size: 16px;
|
|
412
530
|
line-height: 1.4;
|
|
413
531
|
flex-shrink: 0;
|
|
532
|
+
opacity: 0.7;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
.usage-list-compact-item:hover .usage-list-bullet {
|
|
536
|
+
opacity: 1;
|
|
414
537
|
}
|
|
415
538
|
|
|
416
539
|
.usage-list-compact-content {
|
|
@@ -419,7 +542,7 @@
|
|
|
419
542
|
}
|
|
420
543
|
|
|
421
544
|
.usage-list-title {
|
|
422
|
-
font-size:
|
|
545
|
+
font-size: 13px;
|
|
423
546
|
font-weight: 500;
|
|
424
547
|
color: var(--color-text-primary);
|
|
425
548
|
overflow: hidden;
|
|
@@ -430,50 +553,60 @@
|
|
|
430
553
|
.usage-list-meta {
|
|
431
554
|
font-size: 11px;
|
|
432
555
|
color: var(--color-text-muted);
|
|
433
|
-
margin-top:
|
|
556
|
+
margin-top: 3px;
|
|
434
557
|
}
|
|
435
558
|
|
|
436
559
|
.usage-list-value {
|
|
437
|
-
font-size:
|
|
560
|
+
font-size: 13px;
|
|
438
561
|
color: var(--color-text-secondary);
|
|
439
|
-
padding:
|
|
562
|
+
padding: 10px 0;
|
|
440
563
|
}
|
|
441
564
|
|
|
442
565
|
/* ---- Path 列表 ---- */
|
|
443
566
|
.usage-paths-section {
|
|
444
567
|
grid-column: 1 / -1;
|
|
568
|
+
border: none;
|
|
569
|
+
background: transparent;
|
|
570
|
+
padding: 0;
|
|
445
571
|
}
|
|
446
572
|
|
|
447
573
|
.usage-list-paths {
|
|
448
574
|
display: flex;
|
|
449
575
|
flex-direction: column;
|
|
450
|
-
gap:
|
|
576
|
+
gap: 8px;
|
|
577
|
+
padding: 16px;
|
|
578
|
+
border-radius: 18px;
|
|
579
|
+
background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(252,248,241,0.6));
|
|
580
|
+
border: 1px solid rgba(137, 111, 94, 0.06);
|
|
581
|
+
box-shadow: 0 4px 20px rgba(92, 68, 52, 0.05);
|
|
582
|
+
backdrop-filter: blur(8px);
|
|
451
583
|
}
|
|
452
584
|
|
|
453
585
|
.usage-list-path-row {
|
|
454
586
|
display: flex;
|
|
455
587
|
align-items: center;
|
|
456
|
-
gap:
|
|
457
|
-
padding:
|
|
458
|
-
border-radius:
|
|
459
|
-
transition:
|
|
588
|
+
gap: 12px;
|
|
589
|
+
padding: 10px 12px;
|
|
590
|
+
border-radius: 10px;
|
|
591
|
+
transition: all 180ms var(--ease-spring);
|
|
460
592
|
}
|
|
461
593
|
|
|
462
594
|
.usage-list-path-row:hover {
|
|
463
|
-
background:
|
|
595
|
+
background: rgba(255, 255, 255, 0.7);
|
|
596
|
+
transform: translateX(4px);
|
|
464
597
|
}
|
|
465
598
|
|
|
466
599
|
.usage-list-path-rank {
|
|
467
|
-
width:
|
|
468
|
-
height:
|
|
600
|
+
width: 22px;
|
|
601
|
+
height: 22px;
|
|
469
602
|
display: flex;
|
|
470
603
|
align-items: center;
|
|
471
604
|
justify-content: center;
|
|
472
|
-
font-size:
|
|
605
|
+
font-size: 11px;
|
|
473
606
|
font-weight: 600;
|
|
474
607
|
color: var(--color-brand);
|
|
475
|
-
background:
|
|
476
|
-
border-radius:
|
|
608
|
+
background: linear-gradient(135deg, rgba(200, 121, 99, 0.12), rgba(200, 121, 99, 0.06));
|
|
609
|
+
border-radius: 6px;
|
|
477
610
|
flex-shrink: 0;
|
|
478
611
|
}
|
|
479
612
|
|
|
@@ -482,7 +615,7 @@
|
|
|
482
615
|
display: flex;
|
|
483
616
|
justify-content: space-between;
|
|
484
617
|
align-items: center;
|
|
485
|
-
gap:
|
|
618
|
+
gap: 12px;
|
|
486
619
|
min-width: 0;
|
|
487
620
|
}
|
|
488
621
|
|
|
@@ -496,34 +629,45 @@
|
|
|
496
629
|
}
|
|
497
630
|
|
|
498
631
|
.usage-list-path-stat {
|
|
499
|
-
font-size:
|
|
632
|
+
font-size: 14px;
|
|
500
633
|
font-weight: 600;
|
|
501
634
|
color: var(--color-text-primary);
|
|
502
635
|
font-variant-numeric: tabular-nums;
|
|
503
636
|
flex-shrink: 0;
|
|
504
637
|
}
|
|
505
638
|
|
|
506
|
-
/* ---- 卡片 ---- */
|
|
639
|
+
/* ---- 卡片 (无边框浮动式) ---- */
|
|
507
640
|
.usage-card {
|
|
508
|
-
padding:
|
|
509
|
-
border-radius:
|
|
510
|
-
background:
|
|
511
|
-
border:
|
|
641
|
+
padding: 0;
|
|
642
|
+
border-radius: 0;
|
|
643
|
+
background: transparent;
|
|
644
|
+
border: none;
|
|
512
645
|
margin-bottom: 0;
|
|
513
646
|
}
|
|
514
647
|
|
|
515
648
|
.usage-card-title {
|
|
516
|
-
font-size:
|
|
649
|
+
font-size: 15px;
|
|
517
650
|
font-weight: 600;
|
|
518
651
|
color: var(--color-text-primary);
|
|
519
|
-
margin-bottom:
|
|
652
|
+
margin-bottom: 0;
|
|
653
|
+
letter-spacing: -0.02em;
|
|
520
654
|
}
|
|
521
655
|
|
|
522
|
-
/* ---- 图表网格 ---- */
|
|
656
|
+
/* ---- 图表网格 (加大间距) ---- */
|
|
523
657
|
.usage-chart-grid {
|
|
524
658
|
display: grid;
|
|
525
659
|
grid-template-columns: repeat(2, 1fr);
|
|
526
|
-
gap:
|
|
660
|
+
gap: 20px;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/* 为非 paths 卡片添加容器 */
|
|
664
|
+
.usage-chart-grid > .usage-card:not(.usage-paths-section):not(.usage-wave-section):not(.usage-card-hourly-heatmap) {
|
|
665
|
+
padding: 16px;
|
|
666
|
+
border-radius: 18px;
|
|
667
|
+
background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(252,248,241,0.6));
|
|
668
|
+
border: 1px solid rgba(137, 111, 94, 0.06);
|
|
669
|
+
box-shadow: 0 4px 20px rgba(92, 68, 52, 0.05);
|
|
670
|
+
backdrop-filter: blur(8px);
|
|
527
671
|
}
|
|
528
672
|
|
|
529
673
|
/* ---- 内容区域 ---- */
|
|
@@ -532,7 +676,7 @@
|
|
|
532
676
|
}
|
|
533
677
|
|
|
534
678
|
.usage-content-loading {
|
|
535
|
-
opacity: 0.
|
|
679
|
+
opacity: 0.6;
|
|
536
680
|
pointer-events: none;
|
|
537
681
|
}
|
|
538
682
|
|
|
@@ -542,15 +686,15 @@
|
|
|
542
686
|
display: flex;
|
|
543
687
|
align-items: flex-start;
|
|
544
688
|
justify-content: flex-end;
|
|
545
|
-
padding:
|
|
546
|
-
z-index:
|
|
689
|
+
padding: 16px;
|
|
690
|
+
z-index: 10;
|
|
547
691
|
}
|
|
548
692
|
|
|
549
693
|
.usage-spinner {
|
|
550
|
-
width:
|
|
551
|
-
height:
|
|
694
|
+
width: 18px;
|
|
695
|
+
height: 18px;
|
|
552
696
|
border-radius: 50%;
|
|
553
|
-
border: 2px solid
|
|
697
|
+
border: 2px solid rgba(137, 111, 94, 0.15);
|
|
554
698
|
border-top-color: var(--color-brand);
|
|
555
699
|
animation: usage-spin 0.8s linear infinite;
|
|
556
700
|
}
|
|
@@ -566,7 +710,7 @@
|
|
|
566
710
|
}
|
|
567
711
|
|
|
568
712
|
.usage-hero-main {
|
|
569
|
-
font-size:
|
|
713
|
+
font-size: 44px;
|
|
570
714
|
}
|
|
571
715
|
}
|
|
572
716
|
|
|
@@ -582,24 +726,28 @@
|
|
|
582
726
|
}
|
|
583
727
|
|
|
584
728
|
.usage-hero {
|
|
585
|
-
padding: 20px;
|
|
586
|
-
min-height:
|
|
729
|
+
padding: 24px 20px;
|
|
730
|
+
min-height: 140px;
|
|
587
731
|
}
|
|
588
732
|
|
|
589
733
|
.usage-hero-main {
|
|
590
|
-
font-size:
|
|
734
|
+
font-size: 38px;
|
|
591
735
|
}
|
|
592
736
|
|
|
593
737
|
.usage-wave-chart {
|
|
594
|
-
height:
|
|
738
|
+
height: 110px;
|
|
595
739
|
}
|
|
596
740
|
|
|
597
741
|
.usage-wave-labels {
|
|
598
|
-
font-size:
|
|
742
|
+
font-size: 10px;
|
|
599
743
|
}
|
|
600
744
|
|
|
601
745
|
.hourly-heatmap-wrapper {
|
|
602
746
|
min-width: 100%;
|
|
603
747
|
overflow-x: auto;
|
|
604
748
|
}
|
|
749
|
+
|
|
750
|
+
.usage-chart-grid {
|
|
751
|
+
gap: 16px;
|
|
752
|
+
}
|
|
605
753
|
}
|