codexmate 0.0.21 → 0.0.23

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.
Files changed (115) hide show
  1. package/README.md +390 -284
  2. package/README.zh.md +322 -0
  3. package/cli/agents-files.js +224 -162
  4. package/cli/archive-helpers.js +446 -446
  5. package/cli/auth-profiles.js +359 -359
  6. package/cli/builtin-proxy.js +1044 -580
  7. package/cli/claude-proxy.js +998 -998
  8. package/cli/config-bootstrap.js +384 -384
  9. package/cli/config-health.js +338 -338
  10. package/cli/openai-bridge.js +950 -0
  11. package/cli/openclaw-config.js +629 -629
  12. package/cli/session-usage.concurrent.js +28 -0
  13. package/cli/session-usage.js +112 -0
  14. package/cli/session-usage.models.js +176 -0
  15. package/cli/skills.js +1141 -1141
  16. package/cli/zip-commands.js +510 -510
  17. package/cli.js +13214 -13129
  18. package/lib/cli-file-utils.js +151 -151
  19. package/lib/cli-models-utils.js +419 -419
  20. package/lib/cli-network-utils.js +164 -164
  21. package/lib/cli-path-utils.js +69 -69
  22. package/lib/cli-session-utils.js +121 -121
  23. package/lib/cli-sessions.js +386 -386
  24. package/lib/cli-utils.js +155 -155
  25. package/lib/download-artifacts.js +77 -77
  26. package/lib/mcp-stdio.js +440 -440
  27. package/lib/task-orchestrator.js +869 -869
  28. package/lib/text-diff.js +303 -303
  29. package/lib/workflow-engine.js +340 -340
  30. package/package.json +74 -74
  31. package/res/json5.min.js +1 -1
  32. package/res/logo.png +0 -0
  33. package/res/vue.global.prod.js +13 -13
  34. package/web-ui/app.js +626 -530
  35. package/web-ui/index.html +34 -33
  36. package/web-ui/logic.agents-diff.mjs +386 -386
  37. package/web-ui/logic.claude.mjs +168 -168
  38. package/web-ui/logic.mjs +5 -5
  39. package/web-ui/logic.runtime.mjs +128 -124
  40. package/web-ui/logic.sessions.mjs +614 -581
  41. package/web-ui/modules/api.mjs +90 -90
  42. package/web-ui/modules/app.computed.dashboard.mjs +126 -113
  43. package/web-ui/modules/app.computed.index.mjs +17 -15
  44. package/web-ui/modules/app.computed.main-tabs.mjs +202 -195
  45. package/web-ui/modules/app.computed.session.mjs +653 -507
  46. package/web-ui/modules/app.constants.mjs +15 -15
  47. package/web-ui/modules/app.methods.agents.mjs +544 -493
  48. package/web-ui/modules/app.methods.claude-config.mjs +174 -174
  49. package/web-ui/modules/app.methods.codex-config.mjs +795 -640
  50. package/web-ui/modules/app.methods.index.mjs +92 -88
  51. package/web-ui/modules/app.methods.install.mjs +177 -149
  52. package/web-ui/modules/app.methods.navigation.mjs +662 -619
  53. package/web-ui/modules/app.methods.openclaw-core.mjs +814 -814
  54. package/web-ui/modules/app.methods.openclaw-editing.mjs +372 -372
  55. package/web-ui/modules/app.methods.openclaw-persist.mjs +369 -369
  56. package/web-ui/modules/app.methods.providers.mjs +404 -363
  57. package/web-ui/modules/app.methods.runtime.mjs +323 -323
  58. package/web-ui/modules/app.methods.session-actions.mjs +537 -520
  59. package/web-ui/modules/app.methods.session-browser.mjs +691 -626
  60. package/web-ui/modules/app.methods.session-timeline.mjs +448 -448
  61. package/web-ui/modules/app.methods.session-trash.mjs +422 -422
  62. package/web-ui/modules/app.methods.startup-claude.mjs +417 -412
  63. package/web-ui/modules/app.methods.task-orchestration.mjs +556 -471
  64. package/web-ui/modules/config-mode.computed.mjs +126 -126
  65. package/web-ui/modules/config-template-confirm-pref.mjs +33 -0
  66. package/web-ui/modules/i18n.mjs +1823 -0
  67. package/web-ui/modules/plugins.computed.mjs +3 -0
  68. package/web-ui/modules/plugins.methods.mjs +3 -0
  69. package/web-ui/modules/plugins.storage.mjs +11 -0
  70. package/web-ui/modules/sessions-filters-url.mjs +85 -0
  71. package/web-ui/modules/skills.computed.mjs +107 -107
  72. package/web-ui/modules/skills.methods.mjs +481 -481
  73. package/web-ui/partials/index/layout-footer.html +13 -13
  74. package/web-ui/partials/index/layout-header.html +461 -402
  75. package/web-ui/partials/index/modal-config-template-agents.html +175 -125
  76. package/web-ui/partials/index/modal-confirm-toast.html +32 -32
  77. package/web-ui/partials/index/modal-health-check.html +72 -72
  78. package/web-ui/partials/index/modal-openclaw-config.html +280 -280
  79. package/web-ui/partials/index/modal-skills.html +200 -184
  80. package/web-ui/partials/index/modals-basic.html +165 -156
  81. package/web-ui/partials/index/panel-config-claude.html +159 -126
  82. package/web-ui/partials/index/panel-config-codex.html +255 -237
  83. package/web-ui/partials/index/panel-config-openclaw.html +78 -78
  84. package/web-ui/partials/index/panel-docs.html +147 -130
  85. package/web-ui/partials/index/panel-market.html +174 -174
  86. package/web-ui/partials/index/panel-orchestration.html +388 -397
  87. package/web-ui/partials/index/panel-plugins.html +273 -0
  88. package/web-ui/partials/index/panel-sessions.html +298 -292
  89. package/web-ui/partials/index/panel-settings.html +258 -190
  90. package/web-ui/partials/index/panel-usage.html +353 -213
  91. package/web-ui/session-helpers.mjs +573 -559
  92. package/web-ui/source-bundle.cjs +233 -233
  93. package/web-ui/styles/base-theme.css +264 -271
  94. package/web-ui/styles/controls-forms.css +369 -360
  95. package/web-ui/styles/docs-panel.css +247 -182
  96. package/web-ui/styles/feedback.css +108 -108
  97. package/web-ui/styles/health-check-dialog.css +144 -144
  98. package/web-ui/styles/layout-shell.css +602 -376
  99. package/web-ui/styles/modals-core.css +464 -464
  100. package/web-ui/styles/navigation-panels.css +390 -348
  101. package/web-ui/styles/openclaw-structured.css +266 -266
  102. package/web-ui/styles/plugins-panel.css +523 -0
  103. package/web-ui/styles/responsive.css +456 -450
  104. package/web-ui/styles/sessions-list.css +400 -400
  105. package/web-ui/styles/sessions-preview.css +411 -411
  106. package/web-ui/styles/sessions-toolbar-trash.css +268 -243
  107. package/web-ui/styles/sessions-usage.css +879 -628
  108. package/web-ui/styles/settings-panel.css +166 -0
  109. package/web-ui/styles/skills-list.css +303 -296
  110. package/web-ui/styles/skills-market.css +406 -335
  111. package/web-ui/styles/task-orchestration.css +822 -776
  112. package/web-ui/styles/titles-cards.css +408 -408
  113. package/web-ui/styles.css +20 -18
  114. package/web-ui.html +17 -17
  115. package/README.en.md +0 -349
@@ -1,376 +1,602 @@
1
- /* ============================================
2
- 容器
3
- ============================================ */
4
- body::before,
5
- body::after {
6
- content: none;
7
- }
8
-
9
- /* ============================================
10
- 容器
11
- ============================================ */
12
- .container {
13
- width: 100%;
14
- max-width: none;
15
- margin: 0;
16
- padding: 0;
17
- position: relative;
18
- z-index: 1;
19
- min-height: 100vh;
20
- }
21
-
22
- /* ============================================
23
- 布局:双栏(侧栏 + 主区)
24
- ============================================ */
25
- .app-shell {
26
- display: grid;
27
- grid-template-columns: 248px minmax(0, 1fr);
28
- gap: 0;
29
- align-items: stretch;
30
- min-height: 100vh;
31
- height: 100vh;
32
- overflow: hidden;
33
- background: var(--color-bg);
34
- }
35
-
36
- .app-shell.standalone {
37
- grid-template-columns: 1fr;
38
- }
39
-
40
- .side-rail {
41
- position: sticky;
42
- top: 0;
43
- align-self: stretch;
44
- display: flex;
45
- flex-direction: column;
46
- gap: 0;
47
- padding: 0;
48
- background: var(--color-surface);
49
- border-right: 1px solid var(--color-border);
50
- border-radius: 0;
51
- box-shadow: none;
52
- min-height: 100vh;
53
- overflow-y: auto;
54
- scrollbar-width: none;
55
- -ms-overflow-style: none;
56
- backdrop-filter: none;
57
- }
58
-
59
- .side-rail::-webkit-scrollbar {
60
- display: none;
61
- }
62
-
63
- .side-rail .brand-title {
64
- font-size: 22px;
65
- margin-bottom: 0;
66
- }
67
-
68
- .side-section {
69
- display: flex;
70
- flex-direction: column;
71
- gap: 4px;
72
- padding: 14px 10px;
73
- }
74
-
75
- .side-section + .side-section {
76
- border-top: 1px solid var(--color-border);
77
- }
78
-
79
- .side-rail-nav {
80
- display: flex;
81
- flex-direction: column;
82
- gap: 0;
83
- flex: 1 1 auto;
84
- }
85
-
86
- .side-section-title {
87
- font-size: 11px;
88
- font-weight: 700;
89
- color: var(--color-text-muted);
90
- letter-spacing: 0.06em;
91
- text-transform: uppercase;
92
- padding: 0 8px;
93
- margin-bottom: 8px;
94
- }
95
-
96
- .side-item {
97
- width: 100%;
98
- text-align: left;
99
- padding: 7px 10px;
100
- border-radius: 8px;
101
- border: 1px solid transparent;
102
- background: transparent;
103
- color: var(--color-text-secondary);
104
- cursor: pointer;
105
- transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth);
106
- display: flex;
107
- flex-direction: column;
108
- gap: 2px;
109
- box-shadow: none;
110
- position: relative;
111
- }
112
-
113
- .side-item::before {
114
- content: "";
115
- position: absolute;
116
- left: 0;
117
- top: 50%;
118
- transform: translateY(-50%);
119
- width: 3px;
120
- height: 16px;
121
- border-radius: 0 2px 2px 0;
122
- background: transparent;
123
- transition: background-color var(--transition-fast) var(--ease-smooth);
124
- }
125
-
126
- .side-item:hover {
127
- background: var(--color-surface-alt);
128
- color: var(--color-text-primary);
129
- }
130
-
131
- .side-item.active,
132
- .side-item.nav-intent-active {
133
- border-color: transparent;
134
- background: var(--color-brand-light);
135
- color: var(--color-brand-dark);
136
- box-shadow: none;
137
- }
138
-
139
- .side-item.nav-intent-inactive,
140
- .side-item.active.nav-intent-inactive {
141
- border-color: transparent;
142
- background: transparent;
143
- color: var(--color-text-secondary);
144
- box-shadow: none;
145
- }
146
-
147
- .side-item.active::before,
148
- .side-item.nav-intent-active::before {
149
- background: var(--color-brand);
150
- }
151
-
152
- .side-item.nav-intent-inactive::before,
153
- .side-item.active.nav-intent-inactive::before {
154
- background: transparent;
155
- }
156
-
157
- .side-item-title {
158
- font-size: 13px;
159
- font-weight: 600;
160
- letter-spacing: -0.01em;
161
- }
162
-
163
- .side-item-meta {
164
- font-size: 11px;
165
- color: var(--color-text-muted);
166
- display: flex;
167
- opacity: 1;
168
- gap: 5px;
169
- flex-wrap: wrap;
170
- line-height: 1.4;
171
- min-height: 1.4em;
172
- }
173
-
174
- .side-item.active .side-item-meta,
175
- .side-item.nav-intent-active .side-item-meta {
176
- color: var(--color-text-secondary);
177
- }
178
-
179
- .side-item-meta > span {
180
- min-width: 0;
181
- overflow-wrap: anywhere;
182
- word-break: break-word;
183
- }
184
-
185
- @media (min-width: 721px) {
186
- body:not(.force-compact) #app > .top-tabs {
187
- display: none;
188
- }
189
- }
190
-
191
- .brand-block {
192
- display: flex;
193
- flex-direction: column;
194
- align-items: flex-start;
195
- gap: 10px;
196
- margin-bottom: 0;
197
- padding: 20px;
198
- border-bottom: 1px solid var(--color-border);
199
- }
200
-
201
- .brand-head {
202
- display: flex;
203
- align-items: center;
204
- gap: 12px;
205
- }
206
-
207
- .brand-logo {
208
- width: 38px;
209
- height: 38px;
210
- border-radius: 10px;
211
- object-fit: cover;
212
- flex-shrink: 0;
213
- box-shadow: var(--shadow-subtle);
214
- }
215
-
216
- .brand-copy {
217
- display: flex;
218
- flex-direction: column;
219
- gap: 4px;
220
- min-width: 0;
221
- }
222
-
223
- .brand-kicker {
224
- font-size: 11px;
225
- line-height: 1;
226
- letter-spacing: 0.06em;
227
- text-transform: uppercase;
228
- color: var(--color-text-muted);
229
- font-weight: 700;
230
- }
231
-
232
- .brand-subtitle {
233
- font-size: 12px;
234
- line-height: 1.45;
235
- color: var(--color-text-secondary);
236
- max-width: 22ch;
237
- }
238
-
239
- .brand-title {
240
- font-size: 18px;
241
- line-height: 1.1;
242
- font-family: var(--font-family-display);
243
- color: var(--color-text-primary);
244
- letter-spacing: -0.02em;
245
- }
246
-
247
- .github-badge {
248
- display: inline-flex;
249
- align-items: center;
250
- justify-content: space-between;
251
- gap: 10px;
252
- margin-top: 0;
253
- padding: 8px 10px;
254
- border-radius: 8px;
255
- border: 1px solid var(--color-border);
256
- background: var(--color-surface);
257
- color: var(--color-text-secondary);
258
- font-size: var(--font-size-caption);
259
- text-decoration: none;
260
- box-shadow: none;
261
- 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);
262
- min-width: 0;
263
- backdrop-filter: none;
264
- }
265
-
266
- .github-badge-rail {
267
- width: calc(100% - 24px);
268
- margin: 0 12px 12px;
269
- align-items: center;
270
- justify-content: flex-start;
271
- gap: 8px;
272
- padding: 8px 10px;
273
- border-radius: 8px;
274
- background: var(--color-surface);
275
- border: 1px solid var(--color-border);
276
- box-shadow: none;
277
- }
278
-
279
- .github-badge:hover {
280
- border-color: var(--color-border-strong);
281
- background: var(--color-surface-alt);
282
- color: var(--color-text-primary);
283
- box-shadow: none;
284
- }
285
-
286
- .github-badge:focus-visible {
287
- outline: 3px solid rgba(199, 116, 98, 0.18);
288
- outline-offset: 2px;
289
- border-color: var(--color-brand);
290
- color: var(--color-text-primary);
291
- background: var(--color-surface);
292
- }
293
-
294
- .github-badge-icon {
295
- width: 16px;
296
- height: 16px;
297
- flex-shrink: 0;
298
- }
299
-
300
- .github-badge-left {
301
- display: inline-flex;
302
- align-items: center;
303
- gap: 6px;
304
- flex-shrink: 0;
305
- }
306
-
307
- .github-badge-label {
308
- font-size: var(--font-size-caption);
309
- font-weight: var(--font-weight-secondary);
310
- color: var(--color-text-secondary);
311
- }
312
-
313
- .github-badge-text {
314
- min-width: 0;
315
- font-family: var(--font-family-mono);
316
- font-size: var(--font-size-caption);
317
- color: var(--color-text-tertiary);
318
- line-height: 1.3;
319
- display: inline-block;
320
- overflow: hidden;
321
- text-overflow: ellipsis;
322
- white-space: nowrap;
323
- }
324
-
325
- .github-badge-text > span {
326
- white-space: nowrap;
327
- }
328
-
329
- .github-owner {
330
- font-weight: 600;
331
- color: var(--color-text-secondary);
332
- }
333
-
334
- .github-sep {
335
- margin: 0 2px;
336
- color: var(--color-text-tertiary);
337
- }
338
-
339
- .github-repo {
340
- font-weight: 600;
341
- color: var(--color-text-primary);
342
- }
343
-
344
- .github-badge-rail .github-badge-text {
345
- display: flex;
346
- flex-direction: column;
347
- align-items: flex-start;
348
- gap: 2px;
349
- white-space: normal;
350
- overflow: visible;
351
- text-overflow: clip;
352
- color: var(--color-text-secondary);
353
- }
354
-
355
- .github-badge-rail .github-sep {
356
- display: none;
357
- }
358
-
359
- .github-badge-rail .github-owner,
360
- .github-badge-rail .github-repo {
361
- font-weight: 600;
362
- }
363
-
364
- .github-badge-rail .github-badge-left {
365
- padding: 4px;
366
- border-radius: 999px;
367
- background: var(--color-brand-light);
368
- }
369
-
370
- .github-badge-rail .github-badge-label {
371
- display: none;
372
- }
373
-
374
- .github-badge-rail:hover {
375
- border-color: var(--color-border-strong);
376
- }
1
+ /* ============================================
2
+ 容器
3
+ ============================================ */
4
+ body::before,
5
+ body::after {
6
+ content: none;
7
+ }
8
+
9
+ /* ============================================
10
+ 容器
11
+ ============================================ */
12
+ .container {
13
+ width: 100%;
14
+ max-width: none;
15
+ margin: 0;
16
+ padding: 0;
17
+ position: relative;
18
+ z-index: 1;
19
+ min-height: 100vh;
20
+ }
21
+
22
+ :root {
23
+ --side-rail-width: 248px;
24
+ }
25
+
26
+ /* ============================================
27
+ 布局:双栏(侧栏 + 主区)
28
+ ============================================ */
29
+ .app-shell {
30
+ display: grid;
31
+ grid-template-columns: 248px minmax(0, 1fr);
32
+ gap: 0;
33
+ align-items: stretch;
34
+ min-height: 100vh;
35
+ height: 100vh;
36
+ overflow: hidden;
37
+ background: var(--color-bg);
38
+ }
39
+
40
+ .app-shell.standalone {
41
+ grid-template-columns: 1fr;
42
+ }
43
+
44
+ .side-rail {
45
+ position: sticky;
46
+ top: 0;
47
+ align-self: stretch;
48
+ display: flex;
49
+ flex-direction: column;
50
+ gap: 0;
51
+ padding: 0;
52
+ background: var(--color-surface);
53
+ border-right: 1px solid var(--color-border);
54
+ border-radius: 0;
55
+ box-shadow: none;
56
+ min-height: 100vh;
57
+ overflow-y: auto;
58
+ scrollbar-width: none;
59
+ -ms-overflow-style: none;
60
+ backdrop-filter: none;
61
+ }
62
+
63
+ .side-rail::-webkit-scrollbar {
64
+ display: none;
65
+ }
66
+
67
+ .side-rail .brand-title {
68
+ font-size: 22px;
69
+ margin-bottom: 0;
70
+ }
71
+
72
+ .side-section {
73
+ display: flex;
74
+ flex-direction: column;
75
+ gap: 4px;
76
+ padding: 6px;
77
+ }
78
+
79
+ .side-section + .side-section {
80
+ border-top: 1px solid var(--color-border);
81
+ }
82
+
83
+ .side-rail-nav {
84
+ display: flex;
85
+ flex-direction: column;
86
+ gap: 0;
87
+ flex: 1 1 auto;
88
+ }
89
+
90
+ .lang-fab {
91
+ display: none;
92
+ }
93
+
94
+ .lang-fab .lang-switch {
95
+ width: auto;
96
+ }
97
+
98
+ .lang-choice {
99
+ display: inline-flex;
100
+ align-items: center;
101
+ gap: 4px;
102
+ padding: 4px;
103
+ border-radius: 999px;
104
+ border: 1px solid rgba(163, 146, 134, 0.32);
105
+ background: rgba(255, 253, 252, 0.92);
106
+ box-shadow: 0 14px 34px rgba(27, 23, 20, 0.22);
107
+ backdrop-filter: blur(10px);
108
+ }
109
+
110
+ .lang-choice-btn {
111
+ min-width: 44px;
112
+ height: 30px;
113
+ border-radius: 999px;
114
+ border: 1px solid transparent;
115
+ background: transparent;
116
+ color: var(--color-text-secondary);
117
+ font-family: var(--font-family-mono);
118
+ font-size: 12px;
119
+ font-weight: 700;
120
+ letter-spacing: 0.08em;
121
+ text-transform: uppercase;
122
+ transition: background-color var(--transition-fast) var(--ease-smooth), border-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth), transform var(--transition-fast) var(--ease-smooth);
123
+ }
124
+
125
+ .lang-choice-btn:hover {
126
+ border-color: rgba(163, 146, 134, 0.32);
127
+ background: rgba(255, 255, 255, 0.72);
128
+ color: var(--color-text-primary);
129
+ }
130
+
131
+ .lang-choice-btn.active {
132
+ border-color: rgba(199, 116, 98, 0.55);
133
+ background: rgba(199, 116, 98, 0.14);
134
+ color: var(--color-brand-dark);
135
+ }
136
+
137
+ .lang-choice-btn:active {
138
+ transform: translateY(1px);
139
+ }
140
+
141
+ .lang-fab .lang-switch-track {
142
+ box-shadow: 0 14px 34px rgba(27, 23, 20, 0.22);
143
+ background: rgba(255, 253, 252, 0.92);
144
+ }
145
+
146
+ .lang-fab .lang-switch:hover .lang-switch-track {
147
+ transform: translateY(-1px);
148
+ }
149
+
150
+ .lang-fab .lang-switch:active .lang-switch-track {
151
+ transform: translateY(0);
152
+ }
153
+
154
+ .lang-fab .lang-switch-track::after {
155
+ opacity: 1;
156
+ }
157
+
158
+ .lang-fab .lang-switch-text {
159
+ color: var(--color-text-primary);
160
+ }
161
+
162
+ .lang-fab {
163
+ position: fixed;
164
+ left: 0;
165
+ bottom: calc(12px + env(safe-area-inset-bottom, 0px));
166
+ width: var(--side-rail-width, 248px);
167
+ transform: none;
168
+ z-index: 60;
169
+ pointer-events: none;
170
+ display: flex;
171
+ justify-content: center;
172
+ }
173
+
174
+ .lang-fab .lang-choice {
175
+ pointer-events: auto;
176
+ position: relative;
177
+ z-index: 1;
178
+ }
179
+
180
+ .lang-fab .lang-switch {
181
+ pointer-events: auto;
182
+ }
183
+
184
+ .lang-fab::before {
185
+ content: "";
186
+ position: absolute;
187
+ inset: -12px -18px;
188
+ background: radial-gradient(circle at 50% 70%, rgba(247, 243, 239, 0.92), rgba(247, 243, 239, 0));
189
+ filter: blur(2px);
190
+ pointer-events: none;
191
+ }
192
+
193
+ .lang-fab > .lang-switch {
194
+ position: relative;
195
+ z-index: 1;
196
+ }
197
+
198
+ .lang-fab .lang-switch-track {
199
+ border-color: rgba(163, 146, 134, 0.32);
200
+ backdrop-filter: blur(10px);
201
+ }
202
+
203
+ .lang-fab .lang-switch:hover .lang-switch-track {
204
+ border-color: rgba(199, 116, 98, 0.7);
205
+ }
206
+
207
+ .side-rail-lang {
208
+ position: sticky;
209
+ bottom: 0;
210
+ z-index: 2;
211
+ margin-top: auto;
212
+ padding: 12px 10px;
213
+ background: transparent;
214
+ border-top: 1px solid var(--color-border);
215
+ backdrop-filter: none;
216
+ display: flex;
217
+ justify-content: center;
218
+ }
219
+
220
+ .side-rail-lang .lang-choice {
221
+ background: rgba(255, 253, 252, 0.9);
222
+ box-shadow: none;
223
+ backdrop-filter: none;
224
+ }
225
+
226
+ .lang-switch {
227
+ width: 100%;
228
+ border: none;
229
+ background: transparent;
230
+ padding: 0;
231
+ cursor: pointer;
232
+ display: flex;
233
+ justify-content: center;
234
+ align-items: center;
235
+ }
236
+
237
+ .lang-switch-track {
238
+ width: 52px;
239
+ height: 34px;
240
+ border-radius: 999px;
241
+ border: 1px solid rgba(163, 146, 134, 0.38);
242
+ background: rgba(255, 253, 252, 0.78);
243
+ box-shadow: 0 1px 2px rgba(36, 31, 28, 0.06);
244
+ display: grid;
245
+ place-items: center;
246
+ position: relative;
247
+ overflow: hidden;
248
+ transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), transform var(--transition-fast) var(--ease-smooth);
249
+ }
250
+
251
+ .lang-switch:hover .lang-switch-track {
252
+ border-color: rgba(199, 116, 98, 0.6);
253
+ background: rgba(255, 253, 252, 0.92);
254
+ transform: translateY(-1px);
255
+ }
256
+
257
+ .lang-switch:active .lang-switch-track {
258
+ transform: translateY(0);
259
+ }
260
+
261
+ .lang-switch-text {
262
+ position: absolute;
263
+ inset: 0;
264
+ display: grid;
265
+ place-items: center;
266
+ font-family: var(--font-family-mono);
267
+ font-size: 12px;
268
+ font-weight: 700;
269
+ letter-spacing: 0.08em;
270
+ text-transform: uppercase;
271
+ color: var(--color-text-secondary);
272
+ transition: transform 220ms var(--ease-spring), opacity 220ms var(--ease-spring);
273
+ will-change: transform, opacity;
274
+ opacity: 0;
275
+ transform: translateY(10px);
276
+ }
277
+
278
+ .lang-switch-track[data-lang="zh"] .lang-switch-zh {
279
+ opacity: 1;
280
+ transform: translateY(0);
281
+ }
282
+
283
+ .lang-switch-track[data-lang="zh"] .lang-switch-en {
284
+ opacity: 0;
285
+ }
286
+
287
+ .lang-switch-track[data-lang="en"] .lang-switch-en {
288
+ opacity: 1;
289
+ transform: translateY(0);
290
+ }
291
+
292
+ .lang-switch-track[data-lang="en"] .lang-switch-zh {
293
+ opacity: 0;
294
+ }
295
+
296
+ .lang-switch-track::after {
297
+ content: "";
298
+ position: absolute;
299
+ inset: -20px;
300
+ background: radial-gradient(circle at 30% 20%, rgba(199, 116, 98, 0.18), rgba(199, 116, 98, 0) 55%);
301
+ opacity: 0;
302
+ transform: translateY(10px);
303
+ transition: opacity 240ms var(--ease-smooth), transform 240ms var(--ease-smooth);
304
+ pointer-events: none;
305
+ }
306
+
307
+ .lang-switch:hover .lang-switch-track::after {
308
+ opacity: 1;
309
+ transform: translateY(0);
310
+ }
311
+
312
+ .side-section-title {
313
+ font-size: 11px;
314
+ font-weight: 700;
315
+ color: var(--color-text-muted);
316
+ letter-spacing: 0.06em;
317
+ text-transform: uppercase;
318
+ padding: 0 8px;
319
+ margin-bottom: 8px;
320
+ }
321
+
322
+ .side-item {
323
+ width: 100%;
324
+ text-align: left;
325
+ padding: 7px 10px;
326
+ border-radius: 8px;
327
+ border: 1px solid transparent;
328
+ background: transparent;
329
+ color: var(--color-text-secondary);
330
+ cursor: pointer;
331
+ transition: border-color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth);
332
+ display: flex;
333
+ flex-direction: column;
334
+ gap: 2px;
335
+ box-shadow: none;
336
+ position: relative;
337
+ }
338
+
339
+ .side-item::before {
340
+ content: "";
341
+ position: absolute;
342
+ left: 0;
343
+ top: 50%;
344
+ transform: translateY(-50%);
345
+ width: 3px;
346
+ height: 16px;
347
+ border-radius: 0 2px 2px 0;
348
+ background: transparent;
349
+ transition: background-color var(--transition-fast) var(--ease-smooth);
350
+ }
351
+
352
+ .side-item:hover {
353
+ background: var(--color-surface-alt);
354
+ color: var(--color-text-primary);
355
+ }
356
+
357
+ .side-item.active,
358
+ .side-item.nav-intent-active {
359
+ border-color: transparent;
360
+ background: var(--color-brand-light);
361
+ color: var(--color-brand-dark);
362
+ box-shadow: none;
363
+ }
364
+
365
+ .side-item.nav-intent-inactive,
366
+ .side-item.active.nav-intent-inactive {
367
+ border-color: transparent;
368
+ background: transparent;
369
+ color: var(--color-text-secondary);
370
+ box-shadow: none;
371
+ }
372
+
373
+ .side-item.active::before,
374
+ .side-item.nav-intent-active::before {
375
+ background: var(--color-brand);
376
+ }
377
+
378
+ .side-item.nav-intent-inactive::before,
379
+ .side-item.active.nav-intent-inactive::before {
380
+ background: transparent;
381
+ }
382
+
383
+ .side-item-title {
384
+ font-size: 13px;
385
+ font-weight: 600;
386
+ letter-spacing: -0.01em;
387
+ }
388
+
389
+ .side-item-meta {
390
+ font-size: 11px;
391
+ color: var(--color-text-muted);
392
+ display: flex;
393
+ opacity: 1;
394
+ gap: 5px;
395
+ flex-wrap: wrap;
396
+ line-height: 1.4;
397
+ min-height: 1.4em;
398
+ }
399
+
400
+ .side-item.active .side-item-meta,
401
+ .side-item.nav-intent-active .side-item-meta {
402
+ color: var(--color-text-secondary);
403
+ }
404
+
405
+ .side-item-meta > span {
406
+ min-width: 0;
407
+ overflow-wrap: anywhere;
408
+ word-break: break-word;
409
+ }
410
+
411
+ @media (min-width: 721px) {
412
+ body:not(.force-compact) #app > .top-tabs {
413
+ display: none;
414
+ }
415
+ }
416
+
417
+ .brand-block {
418
+ display: flex;
419
+ flex-direction: column;
420
+ align-items: flex-start;
421
+ gap: 10px;
422
+ margin-bottom: 0;
423
+ padding: 20px;
424
+ border-bottom: 1px solid var(--color-border);
425
+ }
426
+
427
+ .brand-head {
428
+ display: flex;
429
+ align-items: center;
430
+ gap: 12px;
431
+ }
432
+
433
+ .brand-logo {
434
+ width: 38px;
435
+ height: 38px;
436
+ border-radius: 10px;
437
+ object-fit: cover;
438
+ flex-shrink: 0;
439
+ box-shadow: var(--shadow-subtle);
440
+ }
441
+
442
+ .brand-copy {
443
+ display: flex;
444
+ flex-direction: column;
445
+ gap: 4px;
446
+ min-width: 0;
447
+ }
448
+
449
+ .brand-kicker {
450
+ font-size: 11px;
451
+ line-height: 1;
452
+ letter-spacing: 0.06em;
453
+ text-transform: uppercase;
454
+ color: var(--color-text-muted);
455
+ font-weight: 700;
456
+ }
457
+
458
+ .brand-subtitle {
459
+ font-size: 12px;
460
+ line-height: 1.45;
461
+ color: var(--color-text-secondary);
462
+ max-width: 22ch;
463
+ }
464
+
465
+ .brand-title {
466
+ font-size: 18px;
467
+ line-height: 1.1;
468
+ font-family: var(--font-family-display);
469
+ color: var(--color-text-primary);
470
+ letter-spacing: -0.02em;
471
+ }
472
+
473
+ .github-badge {
474
+ display: inline-flex;
475
+ align-items: center;
476
+ justify-content: space-between;
477
+ gap: 10px;
478
+ margin-top: 0;
479
+ padding: 8px 10px;
480
+ border-radius: 8px;
481
+ border: 1px solid var(--color-border);
482
+ background: var(--color-surface);
483
+ color: var(--color-text-secondary);
484
+ font-size: var(--font-size-caption);
485
+ text-decoration: none;
486
+ box-shadow: none;
487
+ 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);
488
+ min-width: 0;
489
+ backdrop-filter: none;
490
+ }
491
+
492
+ .github-badge-rail {
493
+ width: calc(100% - 24px);
494
+ margin: 0 12px 12px;
495
+ align-items: center;
496
+ justify-content: flex-start;
497
+ gap: 8px;
498
+ padding: 8px 10px;
499
+ border-radius: 8px;
500
+ background: var(--color-surface);
501
+ border: 1px solid var(--color-border);
502
+ box-shadow: none;
503
+ }
504
+
505
+ .github-badge:hover {
506
+ border-color: var(--color-border-strong);
507
+ background: var(--color-surface-alt);
508
+ color: var(--color-text-primary);
509
+ box-shadow: none;
510
+ }
511
+
512
+ .github-badge:focus-visible {
513
+ outline: 3px solid rgba(199, 116, 98, 0.18);
514
+ outline-offset: 2px;
515
+ border-color: var(--color-brand);
516
+ color: var(--color-text-primary);
517
+ background: var(--color-surface);
518
+ }
519
+
520
+ .github-badge-icon {
521
+ width: 16px;
522
+ height: 16px;
523
+ flex-shrink: 0;
524
+ }
525
+
526
+ .github-badge-left {
527
+ display: inline-flex;
528
+ align-items: center;
529
+ gap: 6px;
530
+ flex-shrink: 0;
531
+ }
532
+
533
+ .github-badge-label {
534
+ font-size: var(--font-size-caption);
535
+ font-weight: var(--font-weight-secondary);
536
+ color: var(--color-text-secondary);
537
+ }
538
+
539
+ .github-badge-text {
540
+ min-width: 0;
541
+ font-family: var(--font-family-mono);
542
+ font-size: var(--font-size-caption);
543
+ color: var(--color-text-tertiary);
544
+ line-height: 1.3;
545
+ display: inline-block;
546
+ overflow: hidden;
547
+ text-overflow: ellipsis;
548
+ white-space: nowrap;
549
+ }
550
+
551
+ .github-badge-text > span {
552
+ white-space: nowrap;
553
+ }
554
+
555
+ .github-owner {
556
+ font-weight: 600;
557
+ color: var(--color-text-secondary);
558
+ }
559
+
560
+ .github-sep {
561
+ margin: 0 2px;
562
+ color: var(--color-text-tertiary);
563
+ }
564
+
565
+ .github-repo {
566
+ font-weight: 600;
567
+ color: var(--color-text-primary);
568
+ }
569
+
570
+ .github-badge-rail .github-badge-text {
571
+ display: flex;
572
+ flex-direction: column;
573
+ align-items: flex-start;
574
+ gap: 2px;
575
+ white-space: normal;
576
+ overflow: visible;
577
+ text-overflow: clip;
578
+ color: var(--color-text-secondary);
579
+ }
580
+
581
+ .github-badge-rail .github-sep {
582
+ display: none;
583
+ }
584
+
585
+ .github-badge-rail .github-owner,
586
+ .github-badge-rail .github-repo {
587
+ font-weight: 600;
588
+ }
589
+
590
+ .github-badge-rail .github-badge-left {
591
+ padding: 4px;
592
+ border-radius: 999px;
593
+ background: var(--color-brand-light);
594
+ }
595
+
596
+ .github-badge-rail .github-badge-label {
597
+ display: none;
598
+ }
599
+
600
+ .github-badge-rail:hover {
601
+ border-color: var(--color-border-strong);
602
+ }