bilisum 1.13.2 → 1.13.3

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 (125) hide show
  1. package/README.md +4 -4
  2. package/bin/bilisum.js +157 -76
  3. package/package.json +7 -2
  4. package/runtime/VERSION +1 -0
  5. package/runtime/apps/service/pyproject.toml +29 -0
  6. package/runtime/apps/service/src/video_sum_service/__init__.py +1 -0
  7. package/runtime/apps/service/src/video_sum_service/__main__.py +5 -0
  8. package/runtime/apps/service/src/video_sum_service/app.py +480 -0
  9. package/runtime/apps/service/src/video_sum_service/context.py +24 -0
  10. package/runtime/apps/service/src/video_sum_service/integrations.py +264 -0
  11. package/runtime/apps/service/src/video_sum_service/knowledge/__init__.py +5 -0
  12. package/runtime/apps/service/src/video_sum_service/knowledge/index_service.py +408 -0
  13. package/runtime/apps/service/src/video_sum_service/knowledge/local_llm.py +319 -0
  14. package/runtime/apps/service/src/video_sum_service/knowledge/rag_service.py +492 -0
  15. package/runtime/apps/service/src/video_sum_service/knowledge/tag_service.py +242 -0
  16. package/runtime/apps/service/src/video_sum_service/main.py +31 -0
  17. package/runtime/apps/service/src/video_sum_service/repository.py +942 -0
  18. package/runtime/apps/service/src/video_sum_service/routers/__init__.py +1 -0
  19. package/runtime/apps/service/src/video_sum_service/routers/knowledge.py +272 -0
  20. package/runtime/apps/service/src/video_sum_service/routers/system.py +280 -0
  21. package/runtime/apps/service/src/video_sum_service/routers/tasks.py +287 -0
  22. package/runtime/apps/service/src/video_sum_service/routers/videos.py +766 -0
  23. package/runtime/apps/service/src/video_sum_service/runtime_support.py +1007 -0
  24. package/runtime/apps/service/src/video_sum_service/schemas.py +418 -0
  25. package/runtime/apps/service/src/video_sum_service/settings_manager.py +130 -0
  26. package/runtime/apps/service/src/video_sum_service/task_artifacts.py +102 -0
  27. package/runtime/apps/service/src/video_sum_service/task_exports.py +108 -0
  28. package/runtime/apps/service/src/video_sum_service/transcribe_worker.py +9 -0
  29. package/runtime/apps/service/src/video_sum_service/video_assets.py +623 -0
  30. package/runtime/apps/service/src/video_sum_service/worker.py +381 -0
  31. package/runtime/apps/web/static/apple-touch-icon.png +0 -0
  32. package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  33. package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  34. package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  35. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  36. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  37. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  38. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  39. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  40. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  41. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  42. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  43. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  44. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  45. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  46. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  47. package/runtime/apps/web/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  48. package/runtime/apps/web/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  49. package/runtime/apps/web/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  50. package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  51. package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  52. package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  53. package/runtime/apps/web/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  54. package/runtime/apps/web/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  55. package/runtime/apps/web/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  56. package/runtime/apps/web/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  57. package/runtime/apps/web/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  58. package/runtime/apps/web/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  59. package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  60. package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  61. package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  62. package/runtime/apps/web/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  63. package/runtime/apps/web/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  64. package/runtime/apps/web/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  65. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  66. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  67. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  68. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  69. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  70. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  71. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  72. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  73. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  74. package/runtime/apps/web/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  75. package/runtime/apps/web/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  76. package/runtime/apps/web/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  77. package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  78. package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  79. package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  80. package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  81. package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  82. package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  83. package/runtime/apps/web/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  84. package/runtime/apps/web/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  85. package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  86. package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  87. package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  88. package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  89. package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  90. package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  91. package/runtime/apps/web/static/assets/icons/icon-180.png +0 -0
  92. package/runtime/apps/web/static/assets/icons/icon-512.png +0 -0
  93. package/runtime/apps/web/static/assets/icons/icon.svg +17 -0
  94. package/runtime/apps/web/static/assets/index-Cj5PVjQg.js +388 -0
  95. package/runtime/apps/web/static/assets/index-DU2t4_7s.css +1 -0
  96. package/runtime/apps/web/static/favicon-32x32.png +0 -0
  97. package/runtime/apps/web/static/favicon.ico +0 -0
  98. package/runtime/apps/web/static/favicon.svg +17 -0
  99. package/runtime/apps/web/static/index.html +19 -0
  100. package/runtime/apps/web/static/js/api.js +123 -0
  101. package/runtime/apps/web/static/js/main.js +932 -0
  102. package/runtime/apps/web/static/js/state.js +28 -0
  103. package/runtime/apps/web/static/js/utils.js +81 -0
  104. package/runtime/apps/web/static/js/views/home.js +604 -0
  105. package/runtime/apps/web/static/js/views/settings.js +477 -0
  106. package/runtime/apps/web/static/styles.css +2206 -0
  107. package/runtime/packages/core/pyproject.toml +18 -0
  108. package/runtime/packages/core/src/video_sum_core/__init__.py +1 -0
  109. package/runtime/packages/core/src/video_sum_core/errors.py +22 -0
  110. package/runtime/packages/core/src/video_sum_core/markdown_exports.py +154 -0
  111. package/runtime/packages/core/src/video_sum_core/models/__init__.py +1 -0
  112. package/runtime/packages/core/src/video_sum_core/models/tasks.py +70 -0
  113. package/runtime/packages/core/src/video_sum_core/pipeline/__init__.py +1 -0
  114. package/runtime/packages/core/src/video_sum_core/pipeline/base.py +46 -0
  115. package/runtime/packages/core/src/video_sum_core/pipeline/real.py +3467 -0
  116. package/runtime/packages/core/src/video_sum_core/transcribe_subprocess.py +173 -0
  117. package/runtime/packages/core/src/video_sum_core/utils.py +127 -0
  118. package/runtime/packages/infra/pyproject.toml +16 -0
  119. package/runtime/packages/infra/src/video_sum_infra/__init__.py +1 -0
  120. package/runtime/packages/infra/src/video_sum_infra/app.py +39 -0
  121. package/runtime/packages/infra/src/video_sum_infra/config.py +393 -0
  122. package/runtime/packages/infra/src/video_sum_infra/db.py +34 -0
  123. package/runtime/packages/infra/src/video_sum_infra/logging.py +54 -0
  124. package/runtime/packages/infra/src/video_sum_infra/paths.py +6 -0
  125. package/runtime/packages/infra/src/video_sum_infra/runtime.py +485 -0
@@ -0,0 +1,2206 @@
1
+ /* ============================================
2
+ BiliSum - 专业版 UI 样式
3
+ 现代简洁 · 精致排版 · 舒适布局
4
+ ============================================ */
5
+
6
+ /* ========== 设计令牌 ========== */
7
+ :root {
8
+ color-scheme: dark;
9
+
10
+ /* 品牌色 - 柔和粉色 */
11
+ --primary: #ec7ba3;
12
+ --primary-hover: #f495b5;
13
+ --primary-bg: rgba(236, 123, 163, 0.08);
14
+ --primary-border: rgba(236, 123, 163, 0.2);
15
+
16
+ /* 背景色 - 深空灰 */
17
+ --bg-base: #0a0a0b;
18
+ --bg-surface: #161618;
19
+ --bg-elevated: #1f1f22;
20
+ --bg-overlay: #252529;
21
+
22
+ /* 边框色 */
23
+ --border-subtle: #2a2a2e;
24
+ --border-default: #36363a;
25
+ --border-strong: #44444a;
26
+
27
+ /* 文字色 */
28
+ --text-primary: #f0f0f0;
29
+ --text-secondary: #a0a0a8;
30
+ --text-tertiary: #6a6a70;
31
+ --text-muted: #525258;
32
+
33
+ /* 语义色 */
34
+ --success: #4ade80;
35
+ --success-bg: rgba(74, 222, 128, 0.1);
36
+ --warning: #fbbf24;
37
+ --warning-bg: rgba(251, 191, 36, 0.1);
38
+ --error: #f87171;
39
+ --error-bg: rgba(248, 113, 113, 0.1);
40
+ --info: #60a5fa;
41
+ --info-bg: rgba(96, 165, 250, 0.1);
42
+
43
+ /* 字体 */
44
+ --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", "Noto Sans SC", sans-serif;
45
+ --font-mono: "SF Mono", Monaco, "Cascadia Code", "Consolas", monospace;
46
+
47
+ /* 字号 - 基于 14px */
48
+ --text-xs: 11px;
49
+ --text-sm: 13px;
50
+ --text-base: 14px;
51
+ --text-lg: 16px;
52
+ --text-xl: 20px;
53
+ --text-2xl: 24px;
54
+ --text-3xl: 30px;
55
+
56
+ /* 字重 */
57
+ --font-normal: 400;
58
+ --font-medium: 500;
59
+ --font-semibold: 600;
60
+ --font-bold: 700;
61
+
62
+ /* 行高 */
63
+ --leading-tight: 1.25;
64
+ --leading-normal: 1.5;
65
+ --leading-relaxed: 1.75;
66
+
67
+ /* 字间距 */
68
+ --tracking-tight: -0.02em;
69
+ --tracking-normal: 0;
70
+ --tracking-wide: 0.02em;
71
+ --tracking-wider: 0.05em;
72
+
73
+ /* 圆角 */
74
+ --radius-sm: 6px;
75
+ --radius-md: 8px;
76
+ --radius-lg: 12px;
77
+ --radius-xl: 16px;
78
+ --radius-2xl: 20px;
79
+ --radius-full: 9999px;
80
+
81
+ /* 间距 */
82
+ --space-1: 4px;
83
+ --space-2: 8px;
84
+ --space-3: 12px;
85
+ --space-4: 16px;
86
+ --space-5: 20px;
87
+ --space-6: 24px;
88
+ --space-8: 32px;
89
+ --space-10: 40px;
90
+
91
+ /* 阴影 */
92
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
93
+ --shadow-md: 0 4px 8px rgba(0, 0, 0, 0.3);
94
+ --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.35);
95
+
96
+ /* 布局 */
97
+ --sidebar-width: 260px;
98
+ --content-max: 1600px;
99
+ }
100
+
101
+ /* ========== 基础重置 ========== */
102
+ *, *::before, *::after {
103
+ box-sizing: border-box;
104
+ margin: 0;
105
+ padding: 0;
106
+ }
107
+
108
+ html {
109
+ font-size: 14px;
110
+ -webkit-font-smoothing: antialiased;
111
+ -moz-osx-font-smoothing: grayscale;
112
+ }
113
+
114
+ body {
115
+ min-height: 100vh;
116
+ font-family: var(--font-sans);
117
+ font-size: var(--text-base);
118
+ line-height: var(--leading-normal);
119
+ color: var(--text-primary);
120
+ background: var(--bg-base);
121
+ letter-spacing: var(--tracking-normal);
122
+ }
123
+
124
+ /* ========== 应用布局 ========== */
125
+ .app-shell {
126
+ display: flex;
127
+ min-height: 100vh;
128
+ }
129
+
130
+ /* ========== 侧边栏 ========== */
131
+ .sidebar {
132
+ position: fixed;
133
+ top: 0;
134
+ left: 0;
135
+ width: var(--sidebar-width);
136
+ height: 100vh;
137
+ padding: var(--space-5);
138
+ background: var(--bg-surface);
139
+ border-right: 1px solid var(--border-subtle);
140
+ display: flex;
141
+ flex-direction: column;
142
+ gap: var(--space-4);
143
+ overflow-y: auto;
144
+ z-index: 100;
145
+ }
146
+
147
+ /* 品牌区 */
148
+ .brand {
149
+ display: flex;
150
+ align-items: center;
151
+ gap: var(--space-3);
152
+ padding: var(--space-3);
153
+ border-radius: var(--radius-lg);
154
+ background: var(--bg-overlay);
155
+ border: 1px solid var(--border-subtle);
156
+ cursor: pointer;
157
+ transition: all 0.2s ease;
158
+ }
159
+
160
+ .brand:hover {
161
+ border-color: var(--border-default);
162
+ background: var(--bg-elevated);
163
+ }
164
+
165
+ .brand-mark {
166
+ width: 40px;
167
+ height: 40px;
168
+ border-radius: var(--radius-md);
169
+ display: grid;
170
+ place-items: center;
171
+ background: var(--primary-bg);
172
+ border: 1px solid var(--primary-border);
173
+ flex-shrink: 0;
174
+ }
175
+
176
+ .brand-mark img {
177
+ width: 100%;
178
+ height: 100%;
179
+ display: block;
180
+ }
181
+
182
+ .brand-text {
183
+ min-width: 0;
184
+ flex: 1;
185
+ }
186
+
187
+ .brand .eyebrow {
188
+ font-size: 9px;
189
+ font-weight: 600;
190
+ color: var(--text-tertiary);
191
+ text-transform: uppercase;
192
+ letter-spacing: var(--tracking-wide);
193
+ margin-bottom: 2px;
194
+ }
195
+
196
+ .brand h1 {
197
+ font-size: 16px;
198
+ font-weight: 700;
199
+ color: var(--text-primary);
200
+ white-space: nowrap;
201
+ overflow: hidden;
202
+ text-overflow: ellipsis;
203
+ }
204
+
205
+ /* 导航 */
206
+ .nav {
207
+ display: flex;
208
+ flex-direction: column;
209
+ gap: var(--space-1);
210
+ margin-top: var(--space-2);
211
+ }
212
+
213
+ .nav-item {
214
+ display: flex;
215
+ align-items: center;
216
+ gap: var(--space-3);
217
+ padding: var(--space-3);
218
+ border: none;
219
+ border-radius: var(--radius-md);
220
+ font-size: var(--text-sm);
221
+ font-weight: 500;
222
+ color: var(--text-secondary);
223
+ background: transparent;
224
+ cursor: pointer;
225
+ transition: all 0.15s ease;
226
+ text-align: left;
227
+ }
228
+
229
+ .nav-item:hover {
230
+ background: var(--bg-overlay);
231
+ color: var(--text-primary);
232
+ }
233
+
234
+ .nav-item.active {
235
+ background: var(--primary-bg);
236
+ color: var(--primary);
237
+ font-weight: 600;
238
+ }
239
+
240
+ .nav-item svg {
241
+ width: 18px;
242
+ height: 18px;
243
+ flex-shrink: 0;
244
+ opacity: 0.7;
245
+ }
246
+
247
+ .nav-item.active svg {
248
+ opacity: 1;
249
+ }
250
+
251
+ /* 状态面板 */
252
+ .live-panel {
253
+ background: var(--bg-overlay);
254
+ border: 1px solid var(--border-subtle);
255
+ border-radius: var(--radius-lg);
256
+ padding: var(--space-4);
257
+ margin-top: auto;
258
+ }
259
+
260
+ .live-panel .status-stack {
261
+ display: grid;
262
+ gap: var(--space-3);
263
+ }
264
+
265
+ .live-panel .panel-header {
266
+ padding-bottom: var(--space-3);
267
+ border-bottom: 1px solid var(--border-subtle);
268
+ margin-bottom: var(--space-3);
269
+ }
270
+
271
+ .live-panel .panel-header h2 {
272
+ font-size: 10px;
273
+ font-weight: 700;
274
+ color: var(--text-tertiary);
275
+ text-transform: uppercase;
276
+ letter-spacing: var(--tracking-wider);
277
+ display: flex;
278
+ align-items: center;
279
+ gap: var(--space-2);
280
+ }
281
+
282
+ .live-panel .panel-header h2::before {
283
+ content: "";
284
+ width: 6px;
285
+ height: 6px;
286
+ border-radius: 50%;
287
+ background: var(--success);
288
+ animation: pulse 2s ease-in-out infinite;
289
+ }
290
+
291
+ @keyframes pulse {
292
+ 0%, 100% { opacity: 1; }
293
+ 50% { opacity: 0.5; }
294
+ }
295
+
296
+ .live-panel .panel-header p {
297
+ font-size: 11px;
298
+ color: var(--text-muted);
299
+ margin-top: var(--space-1);
300
+ }
301
+
302
+ /* 状态卡片 */
303
+ .status-card {
304
+ padding: var(--space-3);
305
+ border-radius: var(--radius-md);
306
+ background: var(--bg-surface);
307
+ border: 1px solid var(--border-subtle);
308
+ display: flex;
309
+ flex-direction: column;
310
+ gap: var(--space-1);
311
+ transition: all 0.15s ease;
312
+ }
313
+
314
+ .status-card:hover {
315
+ border-color: var(--border-default);
316
+ background: var(--bg-elevated);
317
+ }
318
+
319
+ .status-card strong {
320
+ font-size: 10px;
321
+ font-weight: 600;
322
+ color: var(--text-tertiary);
323
+ text-transform: uppercase;
324
+ letter-spacing: var(--tracking-wide);
325
+ }
326
+
327
+ .status-caption {
328
+ font-size: 13px;
329
+ color: var(--text-primary);
330
+ font-weight: 500;
331
+ line-height: var(--leading-tight);
332
+ overflow: hidden;
333
+ text-overflow: ellipsis;
334
+ white-space: nowrap;
335
+ }
336
+
337
+ /* ========== 主内容区 ========== */
338
+ .content {
339
+ margin-left: var(--sidebar-width);
340
+ min-height: 100vh;
341
+ display: flex;
342
+ flex-direction: column;
343
+ flex: 1;
344
+ }
345
+
346
+ /* 页面头部 */
347
+ .page-header {
348
+ position: sticky;
349
+ top: 0;
350
+ z-index: 50;
351
+ display: flex;
352
+ align-items: center;
353
+ justify-content: space-between;
354
+ padding: var(--space-5) var(--space-8);
355
+ background: rgba(10, 10, 11, 0.8);
356
+ backdrop-filter: blur(12px);
357
+ border-bottom: 1px solid var(--border-subtle);
358
+ }
359
+
360
+ .page-header-content {
361
+ display: flex;
362
+ flex-direction: column;
363
+ gap: 2px;
364
+ }
365
+
366
+ .page-header .eyebrow {
367
+ font-size: 11px;
368
+ font-weight: 600;
369
+ color: var(--text-tertiary);
370
+ text-transform: uppercase;
371
+ letter-spacing: var(--tracking-wide);
372
+ }
373
+
374
+ .page-header h2 {
375
+ font-size: var(--text-xl);
376
+ font-weight: 600;
377
+ color: var(--text-primary);
378
+ letter-spacing: var(--tracking-tight);
379
+ }
380
+
381
+ /* 视图容器 */
382
+ #view-root {
383
+ flex: 1;
384
+ padding: var(--space-6) var(--space-8);
385
+ max-width: var(--content-max);
386
+ margin: 0 auto;
387
+ width: 100%;
388
+ }
389
+
390
+ /* ========== 通用卡片 ========== */
391
+ .grid-card,
392
+ .panel {
393
+ background: var(--bg-surface);
394
+ border: 1px solid var(--border-subtle);
395
+ border-radius: var(--radius-xl);
396
+ padding: var(--space-6);
397
+ transition: all 0.2s ease;
398
+ }
399
+
400
+ .grid-card:hover,
401
+ .panel:hover {
402
+ border-color: var(--border-default);
403
+ }
404
+
405
+ /* 面板头部 */
406
+ .panel-header {
407
+ margin-bottom: var(--space-5);
408
+ }
409
+
410
+ .panel-header h2 {
411
+ font-size: var(--text-lg);
412
+ font-weight: 600;
413
+ color: var(--text-primary);
414
+ display: flex;
415
+ align-items: center;
416
+ gap: var(--space-2);
417
+ margin-bottom: var(--space-2);
418
+ letter-spacing: var(--tracking-tight);
419
+ }
420
+
421
+ .panel-header h2 svg {
422
+ width: 20px;
423
+ height: 20px;
424
+ color: var(--primary);
425
+ flex-shrink: 0;
426
+ }
427
+
428
+ .panel-header p {
429
+ font-size: var(--text-sm);
430
+ color: var(--text-secondary);
431
+ line-height: var(--leading-normal);
432
+ }
433
+
434
+ /* 卡片头部 */
435
+ .card-header {
436
+ display: flex;
437
+ align-items: center;
438
+ justify-content: space-between;
439
+ margin-bottom: var(--space-4);
440
+ gap: var(--space-3);
441
+ }
442
+
443
+ .card-header h3 {
444
+ font-size: var(--text-base);
445
+ font-weight: 600;
446
+ color: var(--text-primary);
447
+ }
448
+
449
+ /* ========== 按钮 ========== */
450
+ .primary-button,
451
+ .secondary-button,
452
+ .tertiary-button {
453
+ display: inline-flex;
454
+ align-items: center;
455
+ justify-content: center;
456
+ gap: var(--space-2);
457
+ padding: 9px 18px;
458
+ border-radius: var(--radius-md);
459
+ font-size: var(--text-sm);
460
+ font-weight: 600;
461
+ cursor: pointer;
462
+ transition: all 0.15s ease;
463
+ border: none;
464
+ text-decoration: none;
465
+ white-space: nowrap;
466
+ }
467
+
468
+ .primary-button {
469
+ background: var(--primary);
470
+ color: white;
471
+ }
472
+
473
+ .primary-button:hover {
474
+ background: var(--primary-hover);
475
+ transform: translateY(-1px);
476
+ }
477
+
478
+ .primary-button:active {
479
+ transform: translateY(0);
480
+ }
481
+
482
+ .primary-button:disabled {
483
+ opacity: 0.5;
484
+ cursor: not-allowed;
485
+ transform: none;
486
+ }
487
+
488
+ .secondary-button {
489
+ background: var(--bg-overlay);
490
+ color: var(--text-primary);
491
+ border: 1px solid var(--border-default);
492
+ }
493
+
494
+ .secondary-button:hover {
495
+ background: var(--bg-elevated);
496
+ border-color: var(--border-strong);
497
+ }
498
+
499
+ .secondary-button.danger-outline,
500
+ .secondary-button.danger-button {
501
+ color: var(--error);
502
+ border-color: var(--error);
503
+ background: var(--error-bg);
504
+ }
505
+
506
+ .tertiary-button {
507
+ background: transparent;
508
+ color: var(--text-secondary);
509
+ border: 1px solid var(--border-subtle);
510
+ }
511
+
512
+ .tertiary-button:hover {
513
+ background: var(--bg-overlay);
514
+ color: var(--text-primary);
515
+ }
516
+
517
+ .tertiary-button.danger {
518
+ color: var(--error);
519
+ border-color: var(--error);
520
+ }
521
+
522
+ /* 图标按钮 */
523
+ .icon-button {
524
+ display: inline-flex;
525
+ align-items: center;
526
+ justify-content: center;
527
+ width: 36px;
528
+ height: 36px;
529
+ border: none;
530
+ border-radius: var(--radius-md);
531
+ background: transparent;
532
+ color: var(--text-tertiary);
533
+ cursor: pointer;
534
+ transition: all 0.15s ease;
535
+ }
536
+
537
+ .icon-button:hover {
538
+ background: var(--bg-overlay);
539
+ color: var(--text-primary);
540
+ }
541
+
542
+ /* ========== 表单 ========== */
543
+ .task-form,
544
+ .setting-form {
545
+ display: grid;
546
+ gap: var(--space-4);
547
+ }
548
+
549
+ .input-label {
550
+ display: block;
551
+ font-size: var(--text-sm);
552
+ font-weight: 500;
553
+ color: var(--text-secondary);
554
+ margin-bottom: var(--space-2);
555
+ }
556
+
557
+ .input-field,
558
+ .select-field,
559
+ .textarea-field {
560
+ width: 100%;
561
+ padding: 10px 14px;
562
+ font-size: var(--text-sm);
563
+ font-family: inherit;
564
+ line-height: var(--leading-normal);
565
+ color: var(--text-primary);
566
+ background: var(--bg-overlay);
567
+ border: 1px solid var(--border-default);
568
+ border-radius: var(--radius-md);
569
+ outline: none;
570
+ transition: all 0.15s ease;
571
+ }
572
+
573
+ .input-field:hover,
574
+ .select-field:hover,
575
+ .textarea-field:hover {
576
+ border-color: var(--border-strong);
577
+ }
578
+
579
+ .input-field:focus,
580
+ .select-field:focus,
581
+ .textarea-field:focus {
582
+ border-color: var(--primary);
583
+ box-shadow: 0 0 0 3px var(--primary-bg);
584
+ }
585
+
586
+ .input-field::placeholder {
587
+ color: var(--text-muted);
588
+ }
589
+
590
+ .select-field {
591
+ cursor: pointer;
592
+ appearance: none;
593
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236a6a70' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
594
+ background-repeat: no-repeat;
595
+ background-position: right 12px center;
596
+ padding-right: 40px;
597
+ }
598
+
599
+ .textarea-field {
600
+ resize: vertical;
601
+ min-height: 80px;
602
+ font-family: var(--font-mono);
603
+ }
604
+
605
+ /* 切换行 */
606
+ .toggle-row {
607
+ display: flex;
608
+ align-items: center;
609
+ justify-content: space-between;
610
+ padding: var(--space-3) var(--space-4);
611
+ border-radius: var(--radius-md);
612
+ background: var(--bg-overlay);
613
+ border: 1px solid var(--border-subtle);
614
+ transition: all 0.15s ease;
615
+ }
616
+
617
+ .toggle-row:hover {
618
+ background: var(--bg-elevated);
619
+ border-color: var(--border-default);
620
+ }
621
+
622
+ .api-key-help-row {
623
+ gap: var(--space-2);
624
+ }
625
+
626
+ .api-key-help-inline {
627
+ display: flex;
628
+ flex-wrap: wrap;
629
+ align-items: center;
630
+ gap: 6px 10px;
631
+ }
632
+
633
+ .api-key-help-copy {
634
+ font-size: var(--text-sm);
635
+ line-height: var(--leading-normal);
636
+ color: var(--text-muted);
637
+ }
638
+
639
+ .api-key-help-popover {
640
+ position: relative;
641
+ display: inline-flex;
642
+ align-items: center;
643
+ padding-bottom: 12px;
644
+ margin-bottom: -12px;
645
+ }
646
+
647
+ .api-key-help-link {
648
+ cursor: pointer;
649
+ font-size: var(--text-sm);
650
+ line-height: var(--leading-normal);
651
+ color: var(--primary);
652
+ text-decoration: underline;
653
+ text-decoration-style: dotted;
654
+ text-underline-offset: 3px;
655
+ }
656
+
657
+ .api-key-help-popover:hover .api-key-help-link,
658
+ .api-key-help-popover:focus-within .api-key-help-link {
659
+ color: var(--primary-hover);
660
+ }
661
+
662
+ .api-key-help-popover-card {
663
+ position: absolute;
664
+ top: calc(100% + 2px);
665
+ left: 0;
666
+ z-index: 20;
667
+ width: min(360px, calc(100vw - 48px));
668
+ padding: 14px 16px;
669
+ display: grid;
670
+ gap: 10px;
671
+ background: rgba(255, 255, 255, 0.98);
672
+ border: 1px solid rgba(251, 114, 153, 0.18);
673
+ border-radius: var(--radius-lg);
674
+ box-shadow: 0 20px 40px rgba(15, 23, 42, 0.12);
675
+ opacity: 0;
676
+ visibility: hidden;
677
+ pointer-events: none;
678
+ transition: opacity 120ms ease, visibility 120ms ease;
679
+ }
680
+
681
+ .api-key-help-popover:hover .api-key-help-popover-card,
682
+ .api-key-help-popover:focus-within .api-key-help-popover-card {
683
+ opacity: 1;
684
+ visibility: visible;
685
+ pointer-events: auto;
686
+ }
687
+
688
+ .api-key-help-popover-card strong {
689
+ font-size: var(--text-sm);
690
+ color: var(--text-primary);
691
+ }
692
+
693
+ .api-key-help-popover-card ol {
694
+ margin: 0;
695
+ padding-left: 18px;
696
+ display: grid;
697
+ gap: 8px;
698
+ font-size: var(--text-sm);
699
+ line-height: var(--leading-relaxed);
700
+ color: var(--text-secondary);
701
+ }
702
+
703
+ .api-key-help-popover-card a {
704
+ color: var(--primary);
705
+ word-break: break-all;
706
+ }
707
+
708
+ .toggle-row span {
709
+ font-size: var(--text-sm);
710
+ font-weight: 500;
711
+ color: var(--text-primary);
712
+ }
713
+
714
+ .toggle-row input[type="checkbox"] {
715
+ width: 18px;
716
+ height: 18px;
717
+ cursor: pointer;
718
+ accent-color: var(--primary);
719
+ }
720
+
721
+ /* ========== 布局网格 ========== */
722
+ .library-page {
723
+ display: grid;
724
+ gap: var(--space-6);
725
+ }
726
+
727
+ .library-topbar {
728
+ display: grid;
729
+ grid-template-columns: 1.1fr 0.9fr;
730
+ gap: var(--space-6);
731
+ }
732
+
733
+ .home-grid {
734
+ display: grid;
735
+ grid-template-columns: 1.2fr 0.8fr;
736
+ gap: var(--space-5);
737
+ }
738
+
739
+ .video-grid {
740
+ display: grid;
741
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
742
+ gap: var(--space-5);
743
+ }
744
+
745
+ .library-summary-grid {
746
+ display: grid;
747
+ grid-template-columns: repeat(2, 1fr);
748
+ gap: var(--space-3);
749
+ }
750
+
751
+ .env-summary-grid {
752
+ display: grid;
753
+ grid-template-columns: repeat(4, 1fr);
754
+ gap: var(--space-4);
755
+ margin-bottom: var(--space-2);
756
+ }
757
+
758
+ .stats-grid {
759
+ display: grid;
760
+ grid-template-columns: repeat(4, 1fr);
761
+ gap: var(--space-4);
762
+ }
763
+
764
+ .settings-grid {
765
+ display: grid;
766
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
767
+ gap: var(--space-6);
768
+ }
769
+
770
+ .result-grid {
771
+ display: grid;
772
+ grid-template-columns: repeat(2, 1fr);
773
+ gap: var(--space-4);
774
+ }
775
+
776
+ /* ========== 视频库概览卡片 ========== */
777
+ .summary-metric {
778
+ padding: var(--space-4);
779
+ border-radius: var(--radius-lg);
780
+ background: var(--bg-overlay);
781
+ border: 1px solid var(--border-subtle);
782
+ display: flex;
783
+ flex-direction: column;
784
+ gap: var(--space-1);
785
+ transition: all 0.15s ease;
786
+ }
787
+
788
+ .summary-metric:hover {
789
+ border-color: var(--border-default);
790
+ background: var(--bg-elevated);
791
+ }
792
+
793
+ .summary-metric strong {
794
+ font-size: 32px;
795
+ font-weight: 700;
796
+ color: var(--text-primary);
797
+ line-height: 1;
798
+ letter-spacing: var(--tracking-tight);
799
+ }
800
+
801
+ .summary-metric span {
802
+ font-size: 12px;
803
+ font-weight: 500;
804
+ color: var(--text-tertiary);
805
+ text-transform: uppercase;
806
+ letter-spacing: var(--tracking-wide);
807
+ }
808
+
809
+ /* ========== 视频卡片 ========== */
810
+ .video-card {
811
+ display: flex;
812
+ flex-direction: column;
813
+ border-radius: var(--radius-lg);
814
+ background: var(--bg-surface);
815
+ border: 1px solid var(--border-subtle);
816
+ overflow: hidden;
817
+ cursor: pointer;
818
+ transition: all 0.2s ease;
819
+ }
820
+
821
+ .video-card:hover,
822
+ .video-card.active {
823
+ transform: translateY(-4px);
824
+ border-color: var(--border-strong);
825
+ box-shadow: var(--shadow-lg);
826
+ }
827
+
828
+ .video-card-cover {
829
+ position: relative;
830
+ aspect-ratio: 16 / 9;
831
+ background: var(--bg-overlay);
832
+ overflow: hidden;
833
+ }
834
+
835
+ .video-card-cover img {
836
+ width: 100%;
837
+ height: 100%;
838
+ object-fit: cover;
839
+ display: block;
840
+ transition: transform 0.3s ease;
841
+ }
842
+
843
+ .video-card:hover .video-card-cover img {
844
+ transform: scale(1.05);
845
+ }
846
+
847
+ .video-card-placeholder {
848
+ width: 100%;
849
+ height: 100%;
850
+ display: grid;
851
+ place-items: center;
852
+ font-size: 12px;
853
+ font-weight: 600;
854
+ color: var(--text-muted);
855
+ text-transform: uppercase;
856
+ letter-spacing: var(--tracking-wide);
857
+ background: var(--bg-overlay);
858
+ }
859
+
860
+ .video-duration {
861
+ position: absolute;
862
+ right: var(--space-2);
863
+ bottom: var(--space-2);
864
+ padding: 3px 8px;
865
+ border-radius: var(--radius-sm);
866
+ background: rgba(0, 0, 0, 0.85);
867
+ color: white;
868
+ font-size: 11px;
869
+ font-weight: 600;
870
+ backdrop-filter: blur(4px);
871
+ }
872
+
873
+ .video-card-body {
874
+ padding: var(--space-4);
875
+ display: flex;
876
+ flex-direction: column;
877
+ gap: var(--space-2);
878
+ flex: 1;
879
+ }
880
+
881
+ .video-card-body h3 {
882
+ font-size: var(--text-sm);
883
+ font-weight: 600;
884
+ color: var(--text-primary);
885
+ line-height: var(--leading-tight);
886
+ display: -webkit-box;
887
+ -webkit-line-clamp: 2;
888
+ -webkit-box-orient: vertical;
889
+ overflow: hidden;
890
+ margin: 0;
891
+ }
892
+
893
+ .video-card-meta {
894
+ display: flex;
895
+ justify-content: space-between;
896
+ align-items: center;
897
+ gap: var(--space-2);
898
+ margin-top: auto;
899
+ }
900
+
901
+ /* 任务状态标签 */
902
+ .task-status {
903
+ display: inline-flex;
904
+ align-items: center;
905
+ gap: 4px;
906
+ padding: 3px 8px;
907
+ border-radius: var(--radius-full);
908
+ font-size: 10px;
909
+ font-weight: 600;
910
+ text-transform: uppercase;
911
+ letter-spacing: var(--tracking-wide);
912
+ }
913
+
914
+ .task-status.status-success {
915
+ background: var(--success-bg);
916
+ color: var(--success);
917
+ }
918
+
919
+ .task-status.status-running {
920
+ background: var(--warning-bg);
921
+ color: var(--warning);
922
+ }
923
+
924
+ .task-status.status-failed {
925
+ background: var(--error-bg);
926
+ color: var(--error);
927
+ }
928
+
929
+ .task-status.status-pending {
930
+ background: var(--bg-overlay);
931
+ color: var(--text-muted);
932
+ }
933
+
934
+ /* ========== 视频详情 ========== */
935
+ .video-detail-page {
936
+ display: grid;
937
+ gap: var(--space-6);
938
+ }
939
+
940
+ .video-detail-hero {
941
+ display: grid;
942
+ grid-template-columns: 320px 1fr;
943
+ gap: var(--space-6);
944
+ padding: var(--space-6);
945
+ border-radius: var(--radius-2xl);
946
+ background: var(--bg-surface);
947
+ border: 1px solid var(--border-subtle);
948
+ }
949
+
950
+ .video-detail-cover {
951
+ border-radius: var(--radius-lg);
952
+ overflow: hidden;
953
+ background: var(--bg-overlay);
954
+ aspect-ratio: 16 / 9;
955
+ }
956
+
957
+ .video-detail-cover img {
958
+ width: 100%;
959
+ height: 100%;
960
+ object-fit: cover;
961
+ display: block;
962
+ }
963
+
964
+ .video-detail-copy {
965
+ display: flex;
966
+ flex-direction: column;
967
+ gap: var(--space-4);
968
+ }
969
+
970
+ .hero-chip-row {
971
+ display: flex;
972
+ flex-wrap: wrap;
973
+ gap: var(--space-2);
974
+ }
975
+
976
+ .mini-chip {
977
+ display: inline-flex;
978
+ align-items: center;
979
+ padding: 4px 10px;
980
+ border-radius: var(--radius-full);
981
+ font-size: 11px;
982
+ font-weight: 500;
983
+ background: var(--bg-overlay);
984
+ color: var(--text-secondary);
985
+ }
986
+
987
+ .mini-chip.success {
988
+ background: var(--success-bg);
989
+ color: var(--success);
990
+ }
991
+
992
+ .mini-chip.running {
993
+ background: var(--warning-bg);
994
+ color: var(--warning);
995
+ }
996
+
997
+ .mini-chip.error {
998
+ background: var(--error-bg);
999
+ color: var(--error);
1000
+ }
1001
+
1002
+ .video-detail-title {
1003
+ font-size: var(--text-2xl);
1004
+ font-weight: 700;
1005
+ color: var(--text-primary);
1006
+ line-height: var(--leading-tight);
1007
+ letter-spacing: var(--tracking-tight);
1008
+ margin: 0;
1009
+ }
1010
+
1011
+ .detail-hero-actions {
1012
+ display: flex;
1013
+ flex-wrap: wrap;
1014
+ gap: var(--space-3);
1015
+ }
1016
+
1017
+ /* 视频详情主区域 */
1018
+ .video-detail-main {
1019
+ display: grid;
1020
+ grid-template-columns: 1.3fr 0.7fr;
1021
+ gap: var(--space-6);
1022
+ }
1023
+
1024
+ .video-detail-primary,
1025
+ .video-detail-sidebar {
1026
+ display: flex;
1027
+ flex-direction: column;
1028
+ gap: var(--space-5);
1029
+ }
1030
+
1031
+ .video-detail-sidebar {
1032
+ align-self: start;
1033
+ }
1034
+
1035
+ .detail-side-card {
1036
+ position: sticky;
1037
+ top: 24px;
1038
+ }
1039
+
1040
+ .detail-result-stack {
1041
+ display: grid;
1042
+ gap: var(--space-4);
1043
+ }
1044
+
1045
+ /* ========== 结果卡片 ========== */
1046
+ .result-card {
1047
+ position: relative;
1048
+ }
1049
+
1050
+ .result-count {
1051
+ display: inline-flex;
1052
+ align-items: center;
1053
+ padding: 3px 10px;
1054
+ border-radius: var(--radius-full);
1055
+ font-size: 11px;
1056
+ font-weight: 500;
1057
+ background: var(--bg-overlay);
1058
+ color: var(--text-tertiary);
1059
+ }
1060
+
1061
+ /* 时间轴 */
1062
+ .timeline {
1063
+ display: grid;
1064
+ gap: var(--space-3);
1065
+ }
1066
+
1067
+ .timeline-item {
1068
+ display: grid;
1069
+ grid-template-columns: auto 1fr;
1070
+ gap: var(--space-3);
1071
+ padding: var(--space-4);
1072
+ border-radius: var(--radius-lg);
1073
+ background: var(--bg-overlay);
1074
+ border: 1px solid var(--border-subtle);
1075
+ transition: all 0.15s ease;
1076
+ }
1077
+
1078
+ .timeline-item:hover {
1079
+ border-color: var(--border-default);
1080
+ transform: translateX(4px);
1081
+ }
1082
+
1083
+ .timeline-marker {
1084
+ width: 32px;
1085
+ height: 32px;
1086
+ border-radius: 50%;
1087
+ background: var(--primary);
1088
+ color: white;
1089
+ display: grid;
1090
+ place-items: center;
1091
+ font-size: 12px;
1092
+ font-weight: 700;
1093
+ flex-shrink: 0;
1094
+ }
1095
+
1096
+ .timeline-content h4 {
1097
+ font-size: var(--text-sm);
1098
+ font-weight: 600;
1099
+ color: var(--text-primary);
1100
+ margin-bottom: var(--space-1);
1101
+ }
1102
+
1103
+ .timeline-content p {
1104
+ font-size: var(--text-sm);
1105
+ color: var(--text-secondary);
1106
+ line-height: var(--leading-relaxed);
1107
+ }
1108
+
1109
+ .timeline-time {
1110
+ font-size: 11px;
1111
+ color: var(--text-tertiary);
1112
+ font-weight: 500;
1113
+ }
1114
+
1115
+ /* 要点列表 */
1116
+ .bullet-list {
1117
+ list-style: none;
1118
+ padding: 0;
1119
+ display: grid;
1120
+ gap: var(--space-2);
1121
+ }
1122
+
1123
+ .bullet-list li {
1124
+ font-size: var(--text-sm);
1125
+ color: var(--text-secondary);
1126
+ line-height: var(--leading-relaxed);
1127
+ padding-left: var(--space-4);
1128
+ position: relative;
1129
+ }
1130
+
1131
+ .bullet-list li::before {
1132
+ content: "•";
1133
+ position: absolute;
1134
+ left: 0;
1135
+ color: var(--primary);
1136
+ font-weight: bold;
1137
+ }
1138
+
1139
+ /* 转写文本 */
1140
+ .transcript {
1141
+ max-height: 500px;
1142
+ overflow: auto;
1143
+ padding: var(--space-4);
1144
+ border-radius: var(--radius-lg);
1145
+ background: var(--bg-overlay);
1146
+ border: 1px solid var(--border-subtle);
1147
+ font-family: var(--font-mono);
1148
+ font-size: var(--text-sm);
1149
+ line-height: var(--leading-relaxed);
1150
+ color: var(--text-secondary);
1151
+ white-space: pre-wrap;
1152
+ }
1153
+
1154
+ .transcript-card {
1155
+ grid-column: 1 / -1;
1156
+ }
1157
+
1158
+ /* ========== 进度条 ========== */
1159
+ .task-progress-simple {
1160
+ display: grid;
1161
+ gap: var(--space-4);
1162
+ }
1163
+
1164
+ .progress-bar-simple {
1165
+ height: 8px;
1166
+ background: var(--bg-overlay);
1167
+ border-radius: var(--radius-full);
1168
+ overflow: hidden;
1169
+ }
1170
+
1171
+ .progress-fill-simple {
1172
+ height: 100%;
1173
+ background: var(--primary);
1174
+ border-radius: var(--radius-full);
1175
+ transition: width 0.4s ease;
1176
+ }
1177
+
1178
+ .progress-fill-simple.success {
1179
+ background: var(--success);
1180
+ }
1181
+
1182
+ .progress-fill-simple.error {
1183
+ background: var(--error);
1184
+ }
1185
+
1186
+ .progress-info-simple {
1187
+ display: flex;
1188
+ align-items: center;
1189
+ justify-content: space-between;
1190
+ gap: var(--space-3);
1191
+ }
1192
+
1193
+ .progress-percent-simple {
1194
+ font-size: var(--text-lg);
1195
+ font-weight: 700;
1196
+ color: var(--primary);
1197
+ }
1198
+
1199
+ .progress-status-simple {
1200
+ font-size: var(--text-sm);
1201
+ color: var(--text-secondary);
1202
+ flex: 1;
1203
+ text-align: right;
1204
+ }
1205
+
1206
+ /* 进度阶段 */
1207
+ .progress-stage-card {
1208
+ border: 1px solid var(--border-subtle);
1209
+ border-radius: var(--radius-lg);
1210
+ background: var(--bg-overlay);
1211
+ overflow: hidden;
1212
+ }
1213
+
1214
+ .progress-stage-card summary {
1215
+ display: flex;
1216
+ align-items: center;
1217
+ justify-content: space-between;
1218
+ gap: var(--space-3);
1219
+ padding: var(--space-4);
1220
+ cursor: pointer;
1221
+ list-style: none;
1222
+ transition: all 0.15s ease;
1223
+ }
1224
+
1225
+ .progress-stage-card summary::-webkit-details-marker {
1226
+ display: none;
1227
+ }
1228
+
1229
+ .progress-stage-card summary strong {
1230
+ font-size: var(--text-sm);
1231
+ font-weight: 600;
1232
+ color: var(--text-primary);
1233
+ }
1234
+
1235
+ .progress-stage-card summary span {
1236
+ font-size: 11px;
1237
+ color: var(--text-tertiary);
1238
+ }
1239
+
1240
+ .progress-stage-card[open] summary {
1241
+ border-bottom: 1px solid var(--border-subtle);
1242
+ background: var(--bg-elevated);
1243
+ }
1244
+
1245
+ .progress-stage-toggle {
1246
+ font-size: var(--text-sm);
1247
+ font-weight: 500;
1248
+ color: var(--text-tertiary);
1249
+ }
1250
+
1251
+ .progress-stage-card[open] .progress-stage-toggle {
1252
+ color: var(--primary);
1253
+ }
1254
+
1255
+ .progress-stage-list {
1256
+ padding: var(--space-4);
1257
+ display: grid;
1258
+ gap: var(--space-3);
1259
+ }
1260
+
1261
+ /* 进度事件卡片 */
1262
+ .progress-event-card {
1263
+ display: grid;
1264
+ grid-template-columns: auto 1fr;
1265
+ gap: var(--space-3);
1266
+ padding: var(--space-3);
1267
+ border-radius: var(--radius-md);
1268
+ background: var(--bg-surface);
1269
+ border: 1px solid var(--border-subtle);
1270
+ transition: all 0.15s ease;
1271
+ }
1272
+
1273
+ .progress-event-card:hover {
1274
+ border-color: var(--border-default);
1275
+ }
1276
+
1277
+ .progress-event-card.active {
1278
+ border-color: var(--primary);
1279
+ background: var(--primary-bg);
1280
+ }
1281
+
1282
+ .progress-event-card.error {
1283
+ border-color: var(--error);
1284
+ background: var(--error-bg);
1285
+ }
1286
+
1287
+ .progress-event-card.completed {
1288
+ border-color: var(--success);
1289
+ }
1290
+
1291
+ .progress-event-index {
1292
+ display: inline-flex;
1293
+ align-items: center;
1294
+ justify-content: center;
1295
+ min-width: 60px;
1296
+ padding: 4px 10px;
1297
+ border-radius: var(--radius-full);
1298
+ font-size: 11px;
1299
+ font-weight: 600;
1300
+ background: var(--bg-overlay);
1301
+ color: var(--text-secondary);
1302
+ white-space: nowrap;
1303
+ }
1304
+
1305
+ .progress-event-card.completed .progress-event-index {
1306
+ background: var(--success-bg);
1307
+ color: var(--success);
1308
+ }
1309
+
1310
+ .progress-event-card.error .progress-event-index {
1311
+ background: var(--error-bg);
1312
+ color: var(--error);
1313
+ }
1314
+
1315
+ .progress-event-copy {
1316
+ display: grid;
1317
+ gap: var(--space-1);
1318
+ min-width: 0;
1319
+ }
1320
+
1321
+ .progress-event-topline {
1322
+ display: flex;
1323
+ align-items: flex-start;
1324
+ justify-content: space-between;
1325
+ gap: var(--space-3);
1326
+ }
1327
+
1328
+ .progress-event-topline strong {
1329
+ font-size: var(--text-sm);
1330
+ font-weight: 500;
1331
+ color: var(--text-primary);
1332
+ overflow-wrap: anywhere;
1333
+ }
1334
+
1335
+ .progress-event-topline span,
1336
+ .progress-event-meta {
1337
+ font-size: 11px;
1338
+ color: var(--text-tertiary);
1339
+ }
1340
+
1341
+ .error-text {
1342
+ color: var(--error);
1343
+ }
1344
+
1345
+ /* ========== 任务历史 ========== */
1346
+ .task-history-list {
1347
+ display: grid;
1348
+ gap: var(--space-3);
1349
+ }
1350
+
1351
+ .task-history-item {
1352
+ border: 1px solid var(--border-subtle);
1353
+ border-radius: var(--radius-lg);
1354
+ background: var(--bg-surface);
1355
+ overflow: hidden;
1356
+ transition: all 0.15s ease;
1357
+ }
1358
+
1359
+ .task-history-item:hover {
1360
+ border-color: var(--border-default);
1361
+ }
1362
+
1363
+ .task-history-item.active {
1364
+ border-color: var(--primary);
1365
+ }
1366
+
1367
+ .task-history-item summary {
1368
+ padding: var(--space-4);
1369
+ cursor: pointer;
1370
+ list-style: none;
1371
+ }
1372
+
1373
+ .task-history-item summary::-webkit-details-marker {
1374
+ display: none;
1375
+ }
1376
+
1377
+ .task-history-summary {
1378
+ display: flex;
1379
+ align-items: center;
1380
+ justify-content: space-between;
1381
+ gap: var(--space-3);
1382
+ }
1383
+
1384
+ .task-history-main {
1385
+ display: flex;
1386
+ flex-direction: column;
1387
+ gap: var(--space-1);
1388
+ flex: 1;
1389
+ }
1390
+
1391
+ .task-history-status {
1392
+ display: inline-flex;
1393
+ align-items: center;
1394
+ gap: 4px;
1395
+ padding: 3px 8px;
1396
+ border-radius: var(--radius-full);
1397
+ font-size: 10px;
1398
+ font-weight: 600;
1399
+ text-transform: uppercase;
1400
+ letter-spacing: var(--tracking-wide);
1401
+ }
1402
+
1403
+ .task-history-status.status-success {
1404
+ background: var(--success-bg);
1405
+ color: var(--success);
1406
+ }
1407
+
1408
+ .task-history-status.status-failed {
1409
+ background: var(--error-bg);
1410
+ color: var(--error);
1411
+ }
1412
+
1413
+ .task-history-status.status-running {
1414
+ background: var(--warning-bg);
1415
+ color: var(--warning);
1416
+ }
1417
+
1418
+ .task-history-status.status-pending {
1419
+ background: var(--bg-overlay);
1420
+ color: var(--text-muted);
1421
+ }
1422
+
1423
+ .task-history-time {
1424
+ font-size: 11px;
1425
+ color: var(--text-tertiary);
1426
+ }
1427
+
1428
+ .task-history-meta {
1429
+ display: flex;
1430
+ align-items: center;
1431
+ gap: var(--space-2);
1432
+ }
1433
+
1434
+ .task-history-id {
1435
+ font-family: var(--font-mono);
1436
+ font-size: 10px;
1437
+ color: var(--text-tertiary);
1438
+ background: var(--bg-overlay);
1439
+ padding: 2px 6px;
1440
+ border-radius: var(--radius-sm);
1441
+ }
1442
+
1443
+ .expand-icon {
1444
+ width: 16px;
1445
+ height: 16px;
1446
+ color: var(--text-tertiary);
1447
+ transition: transform 0.15s ease;
1448
+ }
1449
+
1450
+ .task-history-item[open] .expand-icon {
1451
+ transform: rotate(180deg);
1452
+ }
1453
+
1454
+ .task-history-details {
1455
+ padding: var(--space-4);
1456
+ border-top: 1px solid var(--border-subtle);
1457
+ background: var(--bg-overlay);
1458
+ display: grid;
1459
+ gap: var(--space-4);
1460
+ }
1461
+
1462
+ .task-history-info {
1463
+ display: grid;
1464
+ gap: var(--space-2);
1465
+ }
1466
+
1467
+ .task-history-info .info-row {
1468
+ display: flex;
1469
+ align-items: flex-start;
1470
+ justify-content: space-between;
1471
+ gap: var(--space-3);
1472
+ padding: var(--space-2) 0;
1473
+ border-bottom: 1px solid var(--border-subtle);
1474
+ }
1475
+
1476
+ .task-history-info .info-row:last-child {
1477
+ border-bottom: none;
1478
+ }
1479
+
1480
+ .task-history-info .info-row.error {
1481
+ background: var(--error-bg);
1482
+ padding: var(--space-3);
1483
+ border-radius: var(--radius-md);
1484
+ border: 1px solid var(--error-bg);
1485
+ }
1486
+
1487
+ .task-history-info .info-row.error .info-label,
1488
+ .task-history-info .info-row.error .info-value {
1489
+ color: var(--error);
1490
+ }
1491
+
1492
+ .task-history-info .info-label {
1493
+ font-size: 11px;
1494
+ font-weight: 500;
1495
+ color: var(--text-tertiary);
1496
+ white-space: nowrap;
1497
+ }
1498
+
1499
+ .task-history-info .info-value {
1500
+ font-size: 11px;
1501
+ color: var(--text-primary);
1502
+ text-align: right;
1503
+ word-break: break-all;
1504
+ }
1505
+
1506
+ .task-history-info .info-value.code {
1507
+ font-family: var(--font-mono);
1508
+ font-size: 10px;
1509
+ background: var(--bg-elevated);
1510
+ padding: 2px 6px;
1511
+ border-radius: var(--radius-sm);
1512
+ }
1513
+
1514
+ .task-history-item .task-history-actions {
1515
+ display: flex;
1516
+ gap: var(--space-2);
1517
+ justify-content: flex-end;
1518
+ }
1519
+
1520
+ /* ========== 探测预览 ========== */
1521
+ .probe-preview {
1522
+ display: grid;
1523
+ grid-template-columns: 140px 1fr;
1524
+ gap: var(--space-4);
1525
+ padding: var(--space-3);
1526
+ margin-top: var(--space-4);
1527
+ border-radius: var(--radius-lg);
1528
+ border: 1px solid var(--border-default);
1529
+ background: var(--bg-overlay);
1530
+ }
1531
+
1532
+ .probe-preview img {
1533
+ aspect-ratio: 16 / 9;
1534
+ border-radius: var(--radius-md);
1535
+ object-fit: cover;
1536
+ }
1537
+
1538
+ .probe-preview-copy {
1539
+ display: grid;
1540
+ align-content: center;
1541
+ gap: var(--space-1);
1542
+ }
1543
+
1544
+ .probe-preview-copy strong {
1545
+ font-size: var(--text-sm);
1546
+ font-weight: 600;
1547
+ color: var(--text-primary);
1548
+ display: -webkit-box;
1549
+ -webkit-line-clamp: 2;
1550
+ -webkit-box-orient: vertical;
1551
+ overflow: hidden;
1552
+ }
1553
+
1554
+ .probe-preview-copy span {
1555
+ font-size: 11px;
1556
+ color: var(--text-tertiary);
1557
+ }
1558
+
1559
+ /* ========== 设置页面 ========== */
1560
+ .settings-sections {
1561
+ gap: var(--space-5);
1562
+ }
1563
+
1564
+ .settings-subsection {
1565
+ padding: var(--space-4);
1566
+ border: 1px solid var(--border-subtle);
1567
+ border-radius: var(--radius-lg);
1568
+ background: var(--bg-overlay);
1569
+ }
1570
+
1571
+ .settings-subsection h3 {
1572
+ font-size: var(--text-base);
1573
+ font-weight: 600;
1574
+ color: var(--text-primary);
1575
+ display: flex;
1576
+ align-items: center;
1577
+ gap: var(--space-2);
1578
+ margin-bottom: var(--space-3);
1579
+ }
1580
+
1581
+ .settings-subsection h3::before {
1582
+ content: "";
1583
+ width: 3px;
1584
+ height: 16px;
1585
+ background: var(--primary);
1586
+ border-radius: var(--radius-full);
1587
+ }
1588
+
1589
+ .settings-actions {
1590
+ display: flex;
1591
+ align-items: center;
1592
+ gap: var(--space-3);
1593
+ flex-wrap: wrap;
1594
+ }
1595
+
1596
+ .settings-actions-section {
1597
+ background: var(--primary-bg);
1598
+ border-color: var(--primary-border);
1599
+ }
1600
+
1601
+ /* CUDA 面板 */
1602
+ .cuda-control-panel {
1603
+ display: grid;
1604
+ gap: var(--space-5);
1605
+ padding: var(--space-5);
1606
+ border: 1px solid var(--primary-border);
1607
+ border-radius: var(--radius-xl);
1608
+ background: var(--bg-overlay);
1609
+ margin-top: var(--space-5);
1610
+ }
1611
+
1612
+ .cuda-control-copy h3 {
1613
+ font-size: var(--text-base);
1614
+ font-weight: 600;
1615
+ color: var(--text-primary);
1616
+ margin-bottom: var(--space-1);
1617
+ }
1618
+
1619
+ .cuda-control-copy p {
1620
+ font-size: var(--text-sm);
1621
+ color: var(--text-secondary);
1622
+ }
1623
+
1624
+ .cuda-picker {
1625
+ min-width: 200px;
1626
+ }
1627
+
1628
+ .cuda-button-row {
1629
+ display: flex;
1630
+ gap: var(--space-3);
1631
+ }
1632
+
1633
+ /* 环境卡片 */
1634
+ .env-panel {
1635
+ padding: var(--space-5);
1636
+ margin-bottom: var(--space-6);
1637
+ border: 1px solid var(--border-subtle);
1638
+ border-radius: var(--radius-xl);
1639
+ background: var(--bg-overlay);
1640
+ }
1641
+
1642
+ .env-panel-head {
1643
+ margin-bottom: var(--space-5);
1644
+ padding-bottom: var(--space-3);
1645
+ border-bottom: 1px solid var(--border-subtle);
1646
+ }
1647
+
1648
+ .env-panel-kicker {
1649
+ font-size: 10px;
1650
+ font-weight: 700;
1651
+ color: var(--primary);
1652
+ text-transform: uppercase;
1653
+ letter-spacing: var(--tracking-wider);
1654
+ }
1655
+
1656
+ .env-panel-head p {
1657
+ font-size: var(--text-sm);
1658
+ color: var(--text-secondary);
1659
+ margin-top: var(--space-1);
1660
+ }
1661
+
1662
+ .env-card-item {
1663
+ display: flex;
1664
+ align-items: center;
1665
+ gap: var(--space-4);
1666
+ padding: var(--space-4);
1667
+ border-radius: var(--radius-lg);
1668
+ background: var(--bg-surface);
1669
+ border: 1px solid var(--border-subtle);
1670
+ min-height: 80px;
1671
+ transition: all 0.15s ease;
1672
+ }
1673
+
1674
+ .env-card-item:hover {
1675
+ border-color: var(--border-default);
1676
+ background: var(--bg-overlay);
1677
+ }
1678
+
1679
+ .env-card-item.success {
1680
+ border-color: var(--success);
1681
+ background: var(--success-bg);
1682
+ }
1683
+
1684
+ .env-card-item.warning {
1685
+ border-color: var(--warning);
1686
+ background: var(--warning-bg);
1687
+ }
1688
+
1689
+ .env-card-item.cpu,
1690
+ .env-card-item.model {
1691
+ background: var(--primary-bg);
1692
+ border-color: var(--primary-border);
1693
+ }
1694
+
1695
+ .env-card-icon {
1696
+ width: 40px;
1697
+ height: 40px;
1698
+ border-radius: var(--radius-md);
1699
+ background: var(--bg-overlay);
1700
+ display: grid;
1701
+ place-items: center;
1702
+ flex-shrink: 0;
1703
+ }
1704
+
1705
+ .env-card-item.success .env-card-icon {
1706
+ background: var(--success-bg);
1707
+ color: var(--success);
1708
+ }
1709
+
1710
+ .env-card-item.warning .env-card-icon {
1711
+ background: var(--warning-bg);
1712
+ color: var(--warning);
1713
+ }
1714
+
1715
+ .env-card-item.cpu .env-card-icon,
1716
+ .env-card-item.model .env-card-icon {
1717
+ background: var(--primary-bg);
1718
+ color: var(--primary);
1719
+ }
1720
+
1721
+ .env-card-content {
1722
+ display: flex;
1723
+ flex-direction: column;
1724
+ min-width: 0;
1725
+ gap: 2px;
1726
+ }
1727
+
1728
+ .env-card-label {
1729
+ font-size: 10px;
1730
+ font-weight: 500;
1731
+ color: var(--text-tertiary);
1732
+ text-transform: uppercase;
1733
+ letter-spacing: var(--tracking-wide);
1734
+ }
1735
+
1736
+ .env-card-value {
1737
+ font-size: 13px;
1738
+ font-weight: 600;
1739
+ color: var(--text-primary);
1740
+ line-height: var(--leading-tight);
1741
+ overflow: hidden;
1742
+ text-overflow: ellipsis;
1743
+ white-space: nowrap;
1744
+ }
1745
+
1746
+ /* 设置行 */
1747
+ .setting-row {
1748
+ display: flex;
1749
+ align-items: center;
1750
+ justify-content: space-between;
1751
+ gap: var(--space-4);
1752
+ padding: var(--space-3) var(--space-4);
1753
+ border-radius: var(--radius-md);
1754
+ background: var(--bg-overlay);
1755
+ border: 1px solid var(--border-subtle);
1756
+ transition: all 0.15s ease;
1757
+ }
1758
+
1759
+ .setting-row:hover {
1760
+ background: var(--bg-elevated);
1761
+ border-color: var(--border-default);
1762
+ }
1763
+
1764
+ .setting-label {
1765
+ font-size: var(--text-sm);
1766
+ font-weight: 500;
1767
+ color: var(--text-primary);
1768
+ white-space: nowrap;
1769
+ }
1770
+
1771
+ .setting-value {
1772
+ font-size: var(--text-sm);
1773
+ color: var(--text-secondary);
1774
+ text-align: right;
1775
+ word-break: break-all;
1776
+ }
1777
+
1778
+ .setting-row.row-success .setting-value { color: var(--success); }
1779
+ .setting-row.row-warning .setting-value { color: var(--warning); }
1780
+ .setting-row.row-info .setting-value { color: var(--info); }
1781
+
1782
+ /* ========== 空状态 ========== */
1783
+ .empty-state,
1784
+ .empty-placeholder {
1785
+ padding: var(--space-10) var(--space-6);
1786
+ text-align: center;
1787
+ color: var(--text-tertiary);
1788
+ font-size: var(--text-sm);
1789
+ background: var(--bg-overlay);
1790
+ border-radius: var(--radius-lg);
1791
+ border: 1px dashed var(--border-default);
1792
+ }
1793
+
1794
+ .empty-detail {
1795
+ display: flex;
1796
+ flex-direction: column;
1797
+ align-items: center;
1798
+ justify-content: center;
1799
+ padding: var(--space-12) var(--space-6);
1800
+ text-align: center;
1801
+ }
1802
+
1803
+ .empty-detail .empty-icon {
1804
+ margin-bottom: var(--space-4);
1805
+ color: var(--text-tertiary);
1806
+ opacity: 0.5;
1807
+ }
1808
+
1809
+ .empty-detail h3 {
1810
+ font-size: var(--text-lg);
1811
+ font-weight: 600;
1812
+ color: var(--text-primary);
1813
+ margin-bottom: var(--space-2);
1814
+ }
1815
+
1816
+ .empty-detail p {
1817
+ font-size: var(--text-sm);
1818
+ color: var(--text-tertiary);
1819
+ }
1820
+
1821
+ /* ========== 状态提示 ========== */
1822
+ .submit-status,
1823
+ .action-status {
1824
+ display: flex;
1825
+ align-items: center;
1826
+ gap: var(--space-3);
1827
+ justify-content: space-between;
1828
+ padding: var(--space-3) var(--space-4);
1829
+ border-radius: var(--radius-md);
1830
+ font-size: var(--text-sm);
1831
+ margin-top: var(--space-3);
1832
+ }
1833
+
1834
+ .submit-status {
1835
+ background: var(--bg-overlay);
1836
+ border: 1px solid var(--border-subtle);
1837
+ }
1838
+
1839
+ .submit-status.success,
1840
+ .submit-status.tone-success {
1841
+ background: var(--success-bg);
1842
+ border-color: var(--success);
1843
+ color: var(--success);
1844
+ }
1845
+
1846
+ .submit-status.error,
1847
+ .submit-status.tone-error {
1848
+ background: var(--error-bg);
1849
+ border-color: var(--error);
1850
+ color: var(--error);
1851
+ }
1852
+
1853
+ .action-status {
1854
+ background: var(--bg-overlay);
1855
+ border: 1px solid var(--border-subtle);
1856
+ }
1857
+
1858
+ .action-status.success,
1859
+ .action-status.tone-success {
1860
+ background: var(--success-bg);
1861
+ border-color: var(--success);
1862
+ color: var(--success);
1863
+ }
1864
+
1865
+ .action-status.error,
1866
+ .action-status.tone-error {
1867
+ background: var(--error-bg);
1868
+ border-color: var(--error);
1869
+ color: var(--error);
1870
+ }
1871
+
1872
+ .submit-status-copy,
1873
+ .action-status-copy {
1874
+ min-width: 0;
1875
+ flex: 1;
1876
+ }
1877
+
1878
+ .submit-status-close,
1879
+ .action-status-close {
1880
+ width: 18px;
1881
+ height: 18px;
1882
+ display: inline-flex;
1883
+ align-items: center;
1884
+ justify-content: center;
1885
+ flex-shrink: 0;
1886
+ padding: 0;
1887
+ border: 0;
1888
+ border-radius: var(--radius-full);
1889
+ background: transparent;
1890
+ color: currentColor;
1891
+ opacity: 0.4;
1892
+ cursor: pointer;
1893
+ transition: opacity 0.15s ease, background-color 0.15s ease;
1894
+ }
1895
+
1896
+ .submit-status-close:hover,
1897
+ .submit-status-close:focus-visible,
1898
+ .action-status-close:hover,
1899
+ .action-status-close:focus-visible {
1900
+ opacity: 0.82;
1901
+ background: rgba(255, 255, 255, 0.06);
1902
+ outline: none;
1903
+ }
1904
+
1905
+ /* ========== 徽章 ========== */
1906
+ .badge {
1907
+ display: inline-flex;
1908
+ align-items: center;
1909
+ padding: 3px 10px;
1910
+ border-radius: var(--radius-full);
1911
+ font-size: 11px;
1912
+ font-weight: 600;
1913
+ }
1914
+
1915
+ .badge-primary {
1916
+ background: var(--primary-bg);
1917
+ color: var(--primary);
1918
+ }
1919
+
1920
+ .badge-secondary {
1921
+ background: var(--bg-overlay);
1922
+ color: var(--text-secondary);
1923
+ }
1924
+
1925
+ /* ========== 辅助类 ========== */
1926
+ .muted {
1927
+ color: var(--text-tertiary);
1928
+ font-size: var(--text-sm);
1929
+ }
1930
+
1931
+ .code {
1932
+ font-family: var(--font-mono);
1933
+ font-size: var(--text-sm);
1934
+ background: var(--bg-overlay);
1935
+ padding: 2px 6px;
1936
+ border-radius: var(--radius-sm);
1937
+ }
1938
+
1939
+ /* 来源链接 */
1940
+ .source-link {
1941
+ display: inline-flex;
1942
+ align-items: center;
1943
+ gap: 4px;
1944
+ color: var(--primary);
1945
+ text-decoration: none;
1946
+ font-size: var(--text-sm);
1947
+ transition: all 0.15s ease;
1948
+ }
1949
+
1950
+ .source-link:hover {
1951
+ color: var(--primary-hover);
1952
+ text-decoration: underline;
1953
+ }
1954
+
1955
+ .source-link svg {
1956
+ flex-shrink: 0;
1957
+ opacity: 0.7;
1958
+ }
1959
+
1960
+ /* 关于卡片 */
1961
+ .about-card {
1962
+ background: var(--bg-overlay);
1963
+ }
1964
+
1965
+ /* ========== 焦点样式 ========== */
1966
+ :focus-visible {
1967
+ outline: 2px solid var(--primary);
1968
+ outline-offset: 2px;
1969
+ }
1970
+
1971
+ /* ========== 选择样式 ========== */
1972
+ ::selection {
1973
+ background: var(--primary-bg);
1974
+ color: var(--text-primary);
1975
+ }
1976
+
1977
+ /* ========== 滚动条 ========== */
1978
+ ::-webkit-scrollbar {
1979
+ width: 8px;
1980
+ height: 8px;
1981
+ }
1982
+
1983
+ ::-webkit-scrollbar-track {
1984
+ background: var(--bg-overlay);
1985
+ border-radius: var(--radius-full);
1986
+ }
1987
+
1988
+ ::-webkit-scrollbar-thumb {
1989
+ background: var(--border-strong);
1990
+ border-radius: var(--radius-full);
1991
+ }
1992
+
1993
+ ::-webkit-scrollbar-thumb:hover {
1994
+ background: var(--text-tertiary);
1995
+ }
1996
+
1997
+ /* ========== 动画 ========== */
1998
+ @keyframes fadeIn {
1999
+ from {
2000
+ opacity: 0;
2001
+ transform: translateY(8px);
2002
+ }
2003
+ to {
2004
+ opacity: 1;
2005
+ transform: translateY(0);
2006
+ }
2007
+ }
2008
+
2009
+ .grid-card,
2010
+ .panel,
2011
+ .video-card {
2012
+ animation: fadeIn 0.3s ease;
2013
+ }
2014
+
2015
+ /* ========== 响应式 ========== */
2016
+
2017
+ /* 大屏幕 */
2018
+ @media (max-width: 1400px) {
2019
+ .env-summary-grid,
2020
+ .stats-grid {
2021
+ grid-template-columns: repeat(3, 1fr);
2022
+ }
2023
+
2024
+ .video-detail-hero {
2025
+ grid-template-columns: 1fr;
2026
+ }
2027
+
2028
+ .video-detail-copy {
2029
+ align-content: start;
2030
+ }
2031
+ }
2032
+
2033
+ /* 中等屏幕 */
2034
+ @media (max-width: 1200px) {
2035
+ .video-detail-main {
2036
+ grid-template-columns: 1fr;
2037
+ }
2038
+
2039
+ .detail-side-card {
2040
+ position: static;
2041
+ }
2042
+
2043
+ .settings-grid {
2044
+ grid-template-columns: 1fr;
2045
+ }
2046
+ }
2047
+
2048
+ /* 平板 */
2049
+ @media (max-width: 1024px) {
2050
+ :root {
2051
+ --sidebar-width: 100%;
2052
+ }
2053
+
2054
+ .app-shell {
2055
+ flex-direction: column;
2056
+ }
2057
+
2058
+ .sidebar {
2059
+ position: sticky;
2060
+ top: 0;
2061
+ width: 100%;
2062
+ height: auto;
2063
+ border-right: none;
2064
+ border-bottom: 1px solid var(--border-subtle);
2065
+ flex-direction: row;
2066
+ flex-wrap: wrap;
2067
+ padding: var(--space-3) var(--space-4);
2068
+ }
2069
+
2070
+ .brand {
2071
+ flex: 1;
2072
+ min-width: 180px;
2073
+ }
2074
+
2075
+ .nav {
2076
+ flex-direction: row;
2077
+ flex-wrap: wrap;
2078
+ }
2079
+
2080
+ .live-panel {
2081
+ display: none;
2082
+ }
2083
+
2084
+ .content {
2085
+ margin-left: 0;
2086
+ }
2087
+
2088
+ .library-topbar,
2089
+ .home-grid {
2090
+ grid-template-columns: 1fr;
2091
+ }
2092
+
2093
+ .result-grid {
2094
+ grid-template-columns: 1fr;
2095
+ }
2096
+
2097
+ .env-summary-grid,
2098
+ .stats-grid {
2099
+ grid-template-columns: repeat(2, 1fr);
2100
+ }
2101
+ }
2102
+
2103
+ /* 小屏幕 */
2104
+ @media (max-width: 768px) {
2105
+ .page-header {
2106
+ padding: var(--space-3) var(--space-4);
2107
+ }
2108
+
2109
+ .page-header h2 {
2110
+ font-size: var(--text-lg);
2111
+ }
2112
+
2113
+ #view-root {
2114
+ padding: var(--space-4);
2115
+ }
2116
+
2117
+ .grid-card,
2118
+ .panel {
2119
+ padding: var(--space-4);
2120
+ }
2121
+
2122
+ .video-grid {
2123
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
2124
+ gap: var(--space-3);
2125
+ }
2126
+
2127
+ .video-detail-title {
2128
+ font-size: var(--text-lg);
2129
+ }
2130
+
2131
+ .detail-hero-actions,
2132
+ .hero-actions {
2133
+ flex-direction: column;
2134
+ }
2135
+
2136
+ .detail-hero-actions button,
2137
+ .hero-actions button {
2138
+ width: 100%;
2139
+ }
2140
+
2141
+ .probe-preview {
2142
+ grid-template-columns: 1fr;
2143
+ }
2144
+
2145
+ .probe-preview img {
2146
+ max-width: 160px;
2147
+ margin: 0 auto;
2148
+ }
2149
+
2150
+ .library-summary-grid {
2151
+ grid-template-columns: 1fr;
2152
+ }
2153
+
2154
+ .progress-status-simple {
2155
+ text-align: left;
2156
+ }
2157
+ }
2158
+
2159
+ /* 小手机 */
2160
+ @media (max-width: 480px) {
2161
+ .sidebar {
2162
+ padding: var(--space-3);
2163
+ }
2164
+
2165
+ .brand {
2166
+ min-width: 100%;
2167
+ }
2168
+
2169
+ .nav {
2170
+ width: 100%;
2171
+ justify-content: center;
2172
+ }
2173
+
2174
+ .nav-item {
2175
+ flex: 1;
2176
+ justify-content: center;
2177
+ min-width: 70px;
2178
+ }
2179
+
2180
+ .video-grid {
2181
+ grid-template-columns: repeat(2, 1fr);
2182
+ }
2183
+
2184
+ .video-card-body h3 {
2185
+ font-size: 12px;
2186
+ }
2187
+ }
2188
+
2189
+ /* 打印样式 */
2190
+ @media print {
2191
+ .sidebar,
2192
+ .page-header,
2193
+ .live-panel {
2194
+ display: none !important;
2195
+ }
2196
+
2197
+ .content {
2198
+ margin-left: 0;
2199
+ }
2200
+
2201
+ .grid-card,
2202
+ .panel {
2203
+ box-shadow: none;
2204
+ border: 1px solid #ddd;
2205
+ }
2206
+ }