@waterwx/dsh-novel-forge 1.6.0 → 1.7.2

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 (41) hide show
  1. package/lib/client.js +37690 -2269
  2. package/lib/client.js.map +1 -1
  3. package/lib/index.js +767 -56
  4. package/lib/index.js.map +1 -1
  5. package/lib/types/client/api.d.ts +3 -0
  6. package/lib/types/client/locales.d.ts +0 -1
  7. package/lib/types/client/panel/FlowGuide.d.ts +21 -0
  8. package/lib/types/client/panel/MangaRoleLibrary.d.ts +18 -0
  9. package/lib/types/client/panel/MangaWorkspace.d.ts +6 -4
  10. package/lib/types/client/panel/RoleVisualPanel.d.ts +5 -3
  11. package/lib/types/client/panel/SceneLibrary.d.ts +1 -1
  12. package/lib/types/client/panel/StoryboardTab.d.ts +6 -2
  13. package/lib/types/engine.d.ts +23 -9
  14. package/lib/types/index.d.ts +6 -4
  15. package/lib/types/protocol.d.ts +171 -3
  16. package/package.json +100 -98
  17. package/src/client/api.ts +9 -0
  18. package/src/client/locales.ts +0 -1
  19. package/src/client/panel/AssetsTab.tsx +22 -22
  20. package/src/client/panel/AssistantTab.tsx +3 -3
  21. package/src/client/panel/BookshelfBar.tsx +1 -1
  22. package/src/client/panel/CreateBookView.tsx +10 -10
  23. package/src/client/panel/FlowGuide.tsx +83 -0
  24. package/src/client/panel/MangaRoleLibrary.tsx +810 -0
  25. package/src/client/panel/MangaWorkspace.tsx +359 -293
  26. package/src/client/panel/NovelPanel.tsx +465 -307
  27. package/src/client/panel/ReaderView.tsx +4 -4
  28. package/src/client/panel/RunPanel.tsx +9 -9
  29. package/src/client/panel/SceneLibrary.tsx +69 -68
  30. package/src/client/panel/ShelfView.tsx +28 -35
  31. package/src/client/panel/StoryboardTab.tsx +106 -42
  32. package/src/client/panel/StyleCard.tsx +13 -13
  33. package/src/client/panel/StyleGallery.tsx +2 -2
  34. package/src/client/panel/WorldTab.tsx +5 -5
  35. package/src/client/panel/panel.module.css +1189 -454
  36. package/src/client/panel/views.tsx +24 -24
  37. package/src/engine.ts +530 -59
  38. package/src/index.ts +37 -6
  39. package/src/protocol.ts +175 -3
  40. package/src/routes.ts +229 -1
  41. package/src/client/panel/RoleVisualPanel.tsx +0 -468
@@ -10,16 +10,17 @@
10
10
  .entry {
11
11
  display: flex;
12
12
  align-items: center;
13
- gap: 8px;
13
+ gap: var(--nf-space-8, 8px);
14
14
  width: 100%;
15
- padding: 8px 12px;
15
+ padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
16
16
  border: none;
17
17
  background: transparent;
18
18
  color: var(--dsw-alias-label-primary, #1f1f23);
19
19
  cursor: pointer;
20
- font-size: 13px;
20
+ /* 入口行在 .view 外,令牌不可达,用字面值对齐统一档(主文本 14px) */
21
+ font-size: 14px;
21
22
  text-align: left;
22
- border-radius: 6px;
23
+ border-radius: var(--nf-radius-6, 6px);
23
24
  transition: background 0.15s ease;
24
25
  }
25
26
 
@@ -90,24 +91,102 @@ body[data-ds-dark-theme] .entry {
90
91
  --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.07), 0 20px 48px rgba(0, 0, 0, 0.12);
91
92
  --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.06), 0 14px 38px rgba(0, 0, 0, 0.14);
92
93
  --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.08), 0 22px 52px rgba(0, 0, 0, 0.20);
93
- /* Liquid Glass: vertical glass face + soft top-left core + sheen border */
94
- --nf-glass-face: linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);
95
- --nf-glass-core: radial-gradient(30% 24% at 36% 28%, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.22) 45%, rgba(255, 255, 255, 0) 78%);
94
+ /* Liquid Glass: 薄透玻璃面(透明度以文字清晰为先,保留壁纸透色但不干扰阅读)+ 顶部高光 + 淡描边 */
95
+ --nf-glass-face: linear-gradient(180deg, rgba(255, 255, 255, 0.40) 0%, rgba(255, 255, 255, 0.30) 26%, rgba(255, 255, 255, 0.24) 52%, rgba(255, 255, 255, 0.20) 78%, rgba(255, 255, 255, 0.18) 100%);
96
+ --nf-glass-core: radial-gradient(60% 40% at 30% 0%, rgba(255, 255, 255, 0.60) 0%, rgba(255, 255, 255, 0.20) 42%, rgba(255, 255, 255, 0) 78%);
96
97
  --nf-glass-sheen: rgba(255, 255, 255, 0.55);
97
- --nf-glass-border: rgba(255, 255, 255, 0.65);
98
- --nf-glass-inset: rgba(255, 255, 255, 0.55);
99
- --nf-glass-orb-a: rgba(0, 184, 92, 0.18);
100
- --nf-glass-orb-b: rgba(120, 160, 255, 0.13);
98
+ --nf-glass-border: rgba(255, 255, 255, 0.5);
99
+ --nf-glass-inset: rgba(255, 255, 255, 0.4);
100
+ --nf-glass-orb-a: rgba(0, 184, 92, 0.24);
101
+ --nf-glass-orb-b: rgba(120, 160, 255, 0.20);
101
102
  --nf-glass-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
103
+ /* 容器形态(主题可覆盖,用于区分 液态玻璃/毛玻璃 等):液态=适圆角+薄玻璃+彩色流光 */
104
+ --nf-card-radius: 20px;
105
+ --nf-card-blur: 26px;
106
+ --nf-card-saturate: 170%;
107
+ --nf-card-brightness: 1.04;
108
+ --nf-card-sheen: rgba(255, 255, 255, 0.5);
109
+ --nf-card-border: 1px solid rgba(255, 255, 255, 0.35);
110
+ /* 控件形态(液态:圆润 + 玻璃底 + 强内高光 + 绿色箭头) */
111
+ --nf-ctrl-radius: 14px;
112
+ --nf-ctrl-bg: var(--nf-bg-raise);
113
+ --nf-ctrl-border: 1px solid rgba(255, 255, 255, 0.7);
114
+ --nf-ctrl-sheen: rgba(255, 255, 255, 0.5);
115
+ --nf-ctrl-caret: var(--nf-accent);
116
+ /* 液态:绿→蓝 流光壁纸底 */
117
+ --nf-glass-bg-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='110'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='300' cy='180' r='420' fill='%2335d07a' fill-opacity='0.62'/%3E%3Ccircle cx='1240' cy='260' r='470' fill='%233aa7ff' fill-opacity='0.58'/%3E%3Ccircle cx='900' cy='860' r='470' fill='%2340cfc0' fill-opacity='0.5'/%3E%3Ccircle cx='1500' cy='820' r='330' fill='%23ff9fb0' fill-opacity='0.4'/%3E%3Ccircle cx='600' cy='620' r='260' fill='%23b06ef0' fill-opacity='0.42'/%3E%3Ccircle cx='180' cy='600' r='220' fill='%23ffd166' fill-opacity='0.36'/%3E%3C/g%3E%3C/svg%3E");
102
118
  background: var(--nf-bg);
103
119
  /* Frosted glass: blur whatever is behind the panel (the chat dialog),
104
120
  * so translucency shows a soft blur instead of readable content. */
105
- -webkit-backdrop-filter: blur(32px) saturate(180%);
106
- backdrop-filter: blur(32px) saturate(180%);
121
+ -webkit-backdrop-filter: blur(30px) saturate(170%) brightness(1.04);
122
+ backdrop-filter: blur(30px) saturate(170%) brightness(1.04);
107
123
  color: var(--nf-text);
108
- }
109
-
110
- body[data-ds-dark-theme] .view {
124
+ /* ------------------------------------------------------------------
125
+ * Unified size tokens (单一尺寸来源).
126
+ * 约定:主题(data-nf-theme/data-nf-mode)只改颜色/质感,永不覆盖这些
127
+ * 尺寸令牌;界面密度(data-nf-density)是唯一允许重定义尺寸的开关。
128
+ * ------------------------------------------------------------------ */
129
+ /* 字号档:12=次要文本 / 14=主文本 / 16+ = 标题与大数字 */
130
+ --nf-fs-10: 10px;
131
+ --nf-fs-12: 12px;
132
+ --nf-fs-14: 14px;
133
+ --nf-fs-16: 16px;
134
+ --nf-fs-18: 18px;
135
+ --nf-fs-20: 20px;
136
+ --nf-fs-22: 22px;
137
+ --nf-fs-24: 24px;
138
+ --nf-fs-34: 34px;
139
+ --nf-fs-42: 42px;
140
+ /* 图标尺寸档 */
141
+ --nf-icon-s: 14px;
142
+ --nf-icon-m: 16px;
143
+ --nf-icon-l: 18px;
144
+ --nf-icon-xl: 22px;
145
+ /* 间距档 */
146
+ --nf-space-2: 2px;
147
+ --nf-space-4: 4px;
148
+ --nf-space-6: 6px;
149
+ --nf-space-8: 8px;
150
+ --nf-space-10: 10px;
151
+ --nf-space-12: 12px;
152
+ --nf-space-14: 14px;
153
+ --nf-space-16: 16px;
154
+ --nf-space-18: 18px;
155
+ --nf-space-20: 20px;
156
+ --nf-space-24: 24px;
157
+ --nf-space-28: 28px;
158
+ --nf-space-32: 32px;
159
+ /* 圆角档 */
160
+ --nf-radius-2: 2px;
161
+ --nf-radius-4: 4px;
162
+ --nf-radius-6: 6px;
163
+ --nf-radius-8: 8px;
164
+ --nf-radius-10: 10px;
165
+ --nf-radius-12: 12px;
166
+ --nf-radius-14: 14px;
167
+ --nf-radius-16: 16px;
168
+ --nf-radius-20: 20px;
169
+ --nf-radius-22: 22px;
170
+ --nf-radius-999: 999px;
171
+ /* 控件高度档 */
172
+ --nf-ctrl-s: 28px;
173
+ --nf-ctrl-m: 32px;
174
+ --nf-ctrl-l: 38px;
175
+ /* 页面主容器(以设置页为基准)与卡片 */
176
+ --nf-container-pad: 20px 22px;
177
+ --nf-container-gap: var(--nf-space-14, 14px);
178
+ --nf-card-pad: 20px 22px;
179
+ --nf-nav-pad: 16px 12px 14px;
180
+ }
181
+
182
+ /* 深色基准:由面板显示模式驱动(强制 dark / system 跟随宿主深色)。
183
+ * 注意 .view 是 .panel 的父容器,承载 background 与 color-scheme,必须同步设深色变量,
184
+ * 否则 .panel 设了深色也无法回传给父级 .view → 面板背景永远浅色。
185
+ * :has() 用于让 .view 跟随显式强制 dark/light(宿主深色时排除强制 light)。 */
186
+ .panel[data-nf-mode='dark'],
187
+ body[data-ds-dark-theme] .panel:not([data-nf-mode]),
188
+ .view:has(> .panel[data-nf-mode='dark']),
189
+ body[data-ds-dark-theme] .view:not(:has(> .panel[data-nf-mode='light'])) {
111
190
  color-scheme: dark;
112
191
  /* iOS dark palette — near-black canvas with green Liquid-Glass accents */
113
192
  --nf-bg: rgba(10, 11, 13, 0.86);
@@ -132,15 +211,30 @@ body[data-ds-dark-theme] .view {
132
211
  --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.4), 0 20px 48px rgba(0, 0, 0, 0.55);
133
212
  --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 14px 38px rgba(0, 0, 0, 0.45);
134
213
  --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.4), 0 22px 52px rgba(0, 0, 0, 0.55);
135
- /* Liquid Glass (dark): translucent charcoal glass face + soft bright core */
136
- --nf-glass-face: linear-gradient(180deg, rgba(112, 116, 122, 0.42) 0%, rgba(96, 100, 106, 0.42) 26%, rgba(82, 85, 90, 0.42) 52%, rgba(68, 71, 76, 0.42) 78%, rgba(56, 58, 63, 0.42) 100%);
137
- --nf-glass-core: radial-gradient(30% 24% at 36% 28%, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0.10) 45%, rgba(255, 255, 255, 0) 78%);
138
- --nf-glass-sheen: rgba(255, 255, 255, 0.26);
214
+ /* Liquid Glass (dark): 薄透玻璃面(透明度以文字清晰为先)+ 顶部高光 + 淡描边 */
215
+ --nf-glass-face: linear-gradient(180deg, rgba(62, 66, 74, 0.52) 0%, rgba(54, 58, 66, 0.46) 26%, rgba(48, 52, 60, 0.40) 52%, rgba(42, 46, 54, 0.36) 78%, rgba(38, 42, 50, 0.34) 100%);
216
+ --nf-glass-core: radial-gradient(60% 40% at 30% 0%, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0.08) 42%, rgba(255, 255, 255, 0) 78%);
217
+ --nf-glass-sheen: rgba(255, 255, 255, 0.24);
139
218
  --nf-glass-border: rgba(255, 255, 255, 0.14);
140
- --nf-glass-inset: rgba(255, 255, 255, 0.07);
141
- --nf-glass-orb-a: rgba(0, 202, 82, 0.28);
142
- --nf-glass-orb-b: rgba(190, 200, 215, 0.10);
219
+ --nf-glass-inset: rgba(255, 255, 255, 0.08);
220
+ --nf-glass-orb-a: rgba(0, 202, 82, 0.36);
221
+ --nf-glass-orb-b: rgba(120, 160, 255, 0.28);
143
222
  --nf-glass-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
223
+ /* 深色液态容器形态 */
224
+ --nf-card-radius: 20px;
225
+ --nf-card-blur: 28px;
226
+ --nf-card-saturate: 165%;
227
+ --nf-card-brightness: 1;
228
+ --nf-card-border: 1px solid rgba(255, 255, 255, 0.14);
229
+ --nf-card-sheen: rgba(255, 255, 255, 0.22);
230
+ /* 深色液态专用壁纸:压暗浓郁光斑(仅默认液态,macos/neumorph 在各自块覆盖) */
231
+ --nf-glass-bg-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='110'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='300' cy='180' r='420' fill='%231a9f4d' fill-opacity='0.44'/%3E%3Ccircle cx='1240' cy='260' r='470' fill='%23268bd6' fill-opacity='0.40'/%3E%3Ccircle cx='900' cy='860' r='470' fill='%232a9e94' fill-opacity='0.36'/%3E%3Ccircle cx='1500' cy='820' r='330' fill='%23e07a94' fill-opacity='0.30'/%3E%3Ccircle cx='600' cy='620' r='260' fill='%238c5bd6' fill-opacity='0.32'/%3E%3C/g%3E%3C/svg%3E");
232
+ /* 深色液态控件 */
233
+ --nf-ctrl-radius: 14px;
234
+ --nf-ctrl-bg: var(--nf-bg-raise);
235
+ --nf-ctrl-border: 1px solid rgba(255, 255, 255, 0.18);
236
+ --nf-ctrl-sheen: rgba(255, 255, 255, 0.2);
237
+ --nf-ctrl-caret: var(--nf-accent);
144
238
  }
145
239
 
146
240
  html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .view {
@@ -149,45 +243,132 @@ html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-
149
243
 
150
244
  /* ------------------------------------------------------------ themes
151
245
  * 'liquid' (default): iOS Liquid Glass, green accent — set on .view above.
152
- * 'classic': original frosted iOS look, blue accent — overrides below.
246
+ * 'macos' / 'neumorph' override below.
153
247
  */
154
- .panel[data-nf-theme='classic'] {
248
+
249
+ /* ------------------------------------------------------------
250
+ * 'macos': macOS 玻璃(浅色默认 / 深色亮蓝),强调色随外观自动切换 #007aff / #0a84ff。
251
+ * 第二个选择器:深色系统下强制「浅色」显示模式时也能覆盖宿主的深色规则。
252
+ * ------------------------------------------------------------ */
253
+ .panel[data-nf-theme='macos'],
254
+ body[data-ds-dark-theme] .panel[data-nf-mode='light'][data-nf-theme='macos'] {
255
+ --nf-bg: rgba(245, 246, 248, 0.92);
256
+ --nf-bg-raise: rgba(255, 255, 255, 0.78);
257
+ --nf-bg-inset: rgba(118, 118, 128, 0.1);
258
+ --nf-border: rgba(60, 60, 67, 0.14);
259
+ --nf-border-strong: rgba(60, 60, 67, 0.3);
260
+ --nf-text: #1d1d1f;
261
+ --nf-text-2: #3a3a3c;
262
+ --nf-text-2-alpha: rgba(58, 58, 60, 0.7);
263
+ --nf-text-3: #86868b;
155
264
  --nf-accent: #007aff;
156
265
  --nf-accent-hover: #0071e3;
157
266
  --nf-accent-soft: rgba(0, 122, 255, 0.12);
158
267
  --nf-accent-fg: #ffffff;
268
+ --nf-hover: rgba(0, 0, 0, 0.04);
159
269
  --nf-info: #5856d6;
160
- --nf-glass-face: var(--nf-bg-raise);
270
+ --nf-shadow: 0 1px 3px rgba(0, 0, 0, 0.05), 0 10px 28px rgba(0, 0, 0, 0.07);
271
+ --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.06), 0 18px 44px rgba(0, 0, 0, 0.11);
272
+ --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.05), 0 12px 34px rgba(0, 0, 0, 0.09);
273
+ --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.07), 0 20px 48px rgba(0, 0, 0, 0.14);
274
+ --nf-glass-face: rgba(255, 255, 255, 0.7);
161
275
  --nf-glass-core: transparent;
162
- --nf-glass-sheen: rgba(255, 255, 255, 0);
163
- --nf-glass-border: var(--nf-border);
164
- --nf-glass-inset: var(--nf-bg-inset);
165
- --nf-glass-orb-a: transparent;
166
- --nf-glass-orb-b: transparent;
276
+ --nf-glass-sheen: rgba(255, 255, 255, 0.8);
277
+ --nf-glass-border: rgba(255, 255, 255, 0.9);
278
+ --nf-glass-inset: rgba(255, 255, 255, 0.6);
279
+ --nf-glass-orb-a: rgba(0, 122, 255, 0.08);
280
+ --nf-glass-orb-b: rgba(88, 86, 214, 0.07);
167
281
  --nf-glass-noise: none;
168
- }
169
-
170
- body[data-ds-dark-theme] .panel[data-nf-theme='classic'] {
282
+ /* macOS 容器:小圆角 + 高模糊低饱和 + 冷描边,玻璃面板质感 */
283
+ --nf-card-radius: 12px;
284
+ --nf-card-blur: 42px;
285
+ --nf-card-saturate: 150%;
286
+ --nf-card-border: 1px solid var(--nf-border);
287
+ --nf-card-sheen: rgba(255, 255, 255, 0.35);
288
+ /* macOS 控件:小圆角 + 玻璃底 + 冷描边 + 蓝色箭头(focus 蓝环见特写) */
289
+ --nf-ctrl-radius: 8px;
290
+ --nf-ctrl-bg: var(--nf-bg-raise);
291
+ --nf-ctrl-border: 1px solid var(--nf-border-strong);
292
+ --nf-ctrl-sheen: rgba(255, 255, 255, 0.35);
293
+ --nf-ctrl-caret: var(--nf-accent);
294
+ }
295
+
296
+ .panel[data-nf-mode='dark'][data-nf-theme='macos'],
297
+ body[data-ds-dark-theme] .panel[data-nf-theme='macos']:not([data-nf-mode]) {
298
+ --nf-bg: rgba(28, 28, 30, 0.9);
299
+ --nf-bg-raise: rgba(44, 44, 46, 0.82);
300
+ --nf-bg-inset: rgba(118, 118, 128, 0.18);
301
+ --nf-border: rgba(255, 255, 255, 0.12);
302
+ --nf-border-strong: rgba(255, 255, 255, 0.26);
303
+ --nf-text: #f5f5f7;
304
+ --nf-text-2: #d1d1d6;
305
+ --nf-text-2-alpha: rgba(209, 209, 214, 0.7);
306
+ --nf-text-3: #98989d;
171
307
  --nf-accent: #0a84ff;
172
308
  --nf-accent-hover: #3a9bff;
173
309
  --nf-accent-soft: rgba(10, 132, 255, 0.2);
174
310
  --nf-accent-fg: #ffffff;
311
+ --nf-hover: rgba(255, 255, 255, 0.06);
175
312
  --nf-info: #bf5af2;
176
- --nf-glass-face: var(--nf-bg-raise);
313
+ --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.45);
314
+ --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45), 0 18px 44px rgba(0, 0, 0, 0.6);
315
+ --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.4), 0 14px 38px rgba(0, 0, 0, 0.5);
316
+ --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.45), 0 22px 52px rgba(0, 0, 0, 0.6);
317
+ --nf-glass-face: rgba(44, 44, 46, 0.85);
177
318
  --nf-glass-core: transparent;
178
- --nf-glass-sheen: rgba(255, 255, 255, 0);
179
- --nf-glass-border: var(--nf-border);
180
- --nf-glass-inset: var(--nf-bg-inset);
181
- --nf-glass-orb-a: transparent;
182
- --nf-glass-orb-b: transparent;
319
+ --nf-glass-sheen: rgba(255, 255, 255, 0.2);
320
+ --nf-glass-border: rgba(255, 255, 255, 0.18);
321
+ --nf-glass-inset: rgba(255, 255, 255, 0.06);
322
+ --nf-glass-orb-a: rgba(10, 132, 255, 0.16);
323
+ --nf-glass-orb-b: rgba(191, 90, 242, 0.08);
183
324
  --nf-glass-noise: none;
184
325
  }
185
326
 
327
+ /* macOS 按钮 / 输入框玻璃化(圆角由基础 .button/.input 引用 --nf-ctrl-radius 形态令牌提供) */
328
+ .panel[data-nf-theme='macos'] .button {
329
+ border: 1px solid var(--nf-border-strong);
330
+ background: color-mix(in srgb, var(--nf-bg-raise) 82%, #fff);
331
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.6);
332
+ }
333
+ .panel[data-nf-theme='macos'] .buttonPrimary {
334
+ background: linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 90%, #fff), var(--nf-accent));
335
+ border-color: transparent;
336
+ color: var(--nf-accent-fg);
337
+ box-shadow: 0 1px 3px color-mix(in srgb, var(--nf-accent) 45%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.35);
338
+ }
339
+ .panel[data-nf-theme='macos'] .input,
340
+ .panel[data-nf-theme='macos'] .textarea {
341
+ border: 1px solid var(--nf-border-strong);
342
+ background: var(--nf-bg-raise);
343
+ }
344
+ .panel[data-nf-theme='macos'] .input:focus,
345
+ .panel[data-nf-theme='macos'] .textarea:focus {
346
+ border-color: var(--nf-accent);
347
+ box-shadow: 0 0 0 3px var(--nf-accent-soft);
348
+ }
349
+
186
350
  /* ------------------------------------------------------------
187
351
  * 'neumorph': Neumorphism (dual-shadow soft UI).
188
352
  * Light variant in light mode; a dark dual-shadow variant in dark
189
353
  * mode so switching always has a visible effect.
190
354
  * ------------------------------------------------------------ */
355
+ /* 新拟物容器:实色无模糊、较大圆角、无内高光(不依赖深浅,任何模式一致) */
356
+ .panel[data-nf-theme='neumorph'] {
357
+ --nf-card-radius: 20px;
358
+ --nf-card-blur: 0px;
359
+ --nf-card-saturate: 100%;
360
+ --nf-card-border: none;
361
+ --nf-card-sheen: rgba(255, 255, 255, 0);
362
+ /* 新拟物控件:实色无模糊 + 较大圆角 + 无内高光(深浅一致) */
363
+ --nf-ctrl-radius: 10px;
364
+ --nf-ctrl-bg: var(--nf-bg-inset);
365
+ --nf-ctrl-border: none;
366
+ --nf-ctrl-sheen: rgba(255, 255, 255, 0);
367
+ --nf-ctrl-caret: var(--nf-text-3);
368
+ /* 新拟物:实色,无玻璃底图 */
369
+ --nf-glass-bg-image: none;
370
+ }
371
+
191
372
  body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] {
192
373
  --nf-bg: #e4e9f2;
193
374
  --nf-bg-raise: #e4e9f2;
@@ -213,7 +394,8 @@ body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] {
213
394
  --nf-glass-noise: none;
214
395
  }
215
396
 
216
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] {
397
+ .panel[data-nf-mode='dark'][data-nf-theme='neumorph'],
398
+ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph']:not([data-nf-mode]) {
217
399
  --nf-bg: #2b2f36;
218
400
  --nf-bg-raise: #2b2f36;
219
401
  --nf-bg-inset: #25292f;
@@ -237,6 +419,153 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] {
237
419
  --nf-glass-orb-b: transparent;
238
420
  --nf-glass-noise: none;
239
421
  }
422
+ /* ------------------------------------------------------------
423
+ * 'clay': Claymorphism(粘土拟态)—— 柔软圆润、同色系软阴影、奶油底色。
424
+ * 实心(无 backdrop 模糊)、大圆角、双阴影制造"黏土鼓起"感。
425
+ * ------------------------------------------------------------ */
426
+ /* 粘土形态(深浅一致):大圆角、无模糊、奶油高光描边、软阴影 */
427
+ .panel[data-nf-theme='clay'] {
428
+ /* 容器:大圆角 + 实心(关闭玻璃模糊)+ 顶部奶油高光 */
429
+ --nf-card-radius: 28px;
430
+ --nf-card-blur: 0px;
431
+ --nf-card-saturate: 100%;
432
+ --nf-card-brightness: 1;
433
+ --nf-card-border: 1px solid rgba(255, 255, 255, 0.6);
434
+ --nf-card-sheen: rgba(255, 255, 255, 0.85);
435
+ /* 控件:圆润 + 同色系软阴影 + 顶部高光 */
436
+ --nf-ctrl-radius: 16px;
437
+ --nf-ctrl-bg: var(--nf-bg-raise);
438
+ --nf-ctrl-border: 1px solid rgba(255, 255, 255, 0.55);
439
+ --nf-ctrl-sheen: rgba(255, 255, 255, 0.7);
440
+ --nf-ctrl-caret: var(--nf-accent);
441
+ /* 粘土为实心:无玻璃壁纸 */
442
+ --nf-glass-bg-image: none;
443
+ }
444
+
445
+ /* 浅色粘土(默认浅色系统 / 强制浅色) */
446
+ body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'],
447
+ .panel[data-nf-mode='light'][data-nf-theme='clay'] {
448
+ --nf-bg: #f2eae0;
449
+ --nf-bg-raise: #efe4d6;
450
+ --nf-bg-inset: #e6d8c6;
451
+ --nf-border: rgba(120, 96, 72, 0.16);
452
+ --nf-border-strong: rgba(120, 96, 72, 0.28);
453
+ --nf-text: #3a3330;
454
+ --nf-text-2: #5a4f48;
455
+ --nf-text-2-alpha: rgba(90, 79, 72, 0.7);
456
+ --nf-text-3: #9a8c80;
457
+ --nf-accent: #e08a5c;
458
+ --nf-accent-hover: #d67a4a;
459
+ --nf-accent-soft: rgba(224, 138, 92, 0.16);
460
+ --nf-accent-fg: #ffffff;
461
+ --nf-hover: rgba(120, 96, 72, 0.08);
462
+ --nf-success: #7fae6a;
463
+ --nf-error: #c96b63;
464
+ --nf-warn: #d9a660;
465
+ --nf-info: #e08a5c;
466
+ --nf-shadow: 0 8px 16px -6px rgba(90, 70, 50, 0.28), inset 0 6px 10px rgba(255, 255, 255, 0.55), inset 0 -6px 10px rgba(120, 96, 72, 0.12);
467
+ --nf-shadow-lg: 0 16px 28px -10px rgba(90, 70, 50, 0.34), inset 0 6px 10px rgba(255, 255, 255, 0.55), inset 0 -6px 10px rgba(120, 96, 72, 0.14);
468
+ --nf-card-shadow: 0 16px 28px -10px rgba(90, 70, 50, 0.34), inset 0 -8px 12px rgba(120, 96, 72, 0.14), inset 0 8px 12px rgba(255, 255, 255, 0.6);
469
+ --nf-card-shadow-hover: 0 22px 36px -12px rgba(90, 70, 50, 0.38), inset 0 -8px 12px rgba(120, 96, 72, 0.16), inset 0 8px 12px rgba(255, 255, 255, 0.7);
470
+ --nf-glass-face: #efe4d6;
471
+ --nf-glass-core: transparent;
472
+ --nf-glass-sheen: rgba(255, 255, 255, 0.85);
473
+ --nf-glass-border: rgba(255, 255, 255, 0.6);
474
+ --nf-glass-inset: #e6d8c6;
475
+ --nf-glass-orb-a: transparent;
476
+ --nf-glass-orb-b: transparent;
477
+ --nf-glass-noise: none;
478
+ }
479
+
480
+ /* 深色粘土(强制深色 / system 深色系统) */
481
+ .panel[data-nf-mode='dark'][data-nf-theme='clay'],
482
+ body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) {
483
+ --nf-bg: #2a2522;
484
+ --nf-bg-raise: #37302b;
485
+ --nf-bg-inset: #2f2925;
486
+ --nf-border: rgba(255, 255, 255, 0.08);
487
+ --nf-border-strong: rgba(255, 255, 255, 0.18);
488
+ --nf-text: #efe9e3;
489
+ --nf-text-2: #c7beb5;
490
+ --nf-text-2-alpha: rgba(199, 190, 181, 0.7);
491
+ --nf-text-3: #8a8078;
492
+ --nf-accent: #e69a6c;
493
+ --nf-accent-hover: #f0ac82;
494
+ --nf-accent-soft: rgba(230, 154, 108, 0.2);
495
+ --nf-accent-fg: #241b16;
496
+ --nf-hover: rgba(255, 255, 255, 0.06);
497
+ --nf-success: #9cba82;
498
+ --nf-error: #d98f86;
499
+ --nf-warn: #d9a660;
500
+ --nf-info: #e69a6c;
501
+ --nf-shadow: 0 8px 16px -6px rgba(0, 0, 0, 0.55), inset 0 6px 10px rgba(255, 255, 255, 0.12), inset 0 -6px 10px rgba(0, 0, 0, 0.35);
502
+ --nf-shadow-lg: 0 16px 28px -10px rgba(0, 0, 0, 0.62), inset 0 6px 10px rgba(255, 255, 255, 0.12), inset 0 -6px 10px rgba(0, 0, 0, 0.4);
503
+ --nf-card-shadow: 0 16px 28px -10px rgba(0, 0, 0, 0.62), inset 0 -8px 12px rgba(0, 0, 0, 0.4), inset 0 8px 12px rgba(255, 255, 255, 0.14);
504
+ --nf-card-shadow-hover: 0 22px 36px -12px rgba(0, 0, 0, 0.68), inset 0 -8px 12px rgba(0, 0, 0, 0.44), inset 0 8px 12px rgba(255, 255, 255, 0.18);
505
+ --nf-glass-face: #37302b;
506
+ --nf-glass-core: transparent;
507
+ --nf-glass-sheen: rgba(255, 255, 255, 0.16);
508
+ --nf-glass-border: rgba(255, 255, 255, 0.16);
509
+ --nf-glass-inset: #2f2925;
510
+ --nf-glass-orb-a: transparent;
511
+ --nf-glass-orb-b: transparent;
512
+ --nf-glass-noise: none;
513
+ }
514
+
515
+ /* 粘土输入框:凹陷黏土内阴影(深浅一致,深色下另覆盖) */
516
+ .panel[data-nf-theme='clay'] .input,
517
+ .panel[data-nf-theme='clay'] .textarea {
518
+ background: var(--nf-bg-inset);
519
+ border-color: var(--nf-border-strong);
520
+ box-shadow: inset 3px 3px 7px rgba(120, 96, 72, 0.14), inset -3px -3px 7px rgba(255, 255, 255, 0.5);
521
+ }
522
+
523
+ /* 粘土按钮:柔和的"黏土凸起"——外围软投影 + 顶部奶油高光 + 底部厚影 */
524
+ body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'] .button {
525
+ border-color: rgba(255, 255, 255, 0.6);
526
+ background: linear-gradient(180deg, #f6ecdf, #eee0cf);
527
+ box-shadow: 0 8px 16px -6px rgba(90, 70, 50, 0.35), inset 0 3px 4px rgba(255, 255, 255, 0.8), inset 0 -3px 5px rgba(120, 96, 72, 0.2);
528
+ }
529
+
530
+ body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'] .button:hover:not([disabled]) {
531
+ box-shadow: 0 12px 22px -8px rgba(90, 70, 50, 0.42), inset 0 3px 4px rgba(255, 255, 255, 0.85), inset 0 -3px 5px rgba(120, 96, 72, 0.22);
532
+ }
533
+
534
+ body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'] .buttonPrimary {
535
+ background: linear-gradient(180deg, #eda178, #e08a5c);
536
+ border-color: transparent;
537
+ color: var(--nf-accent-fg);
538
+ box-shadow: 0 8px 16px -6px rgba(224, 138, 92, 0.55), inset 0 3px 4px rgba(255, 255, 255, 0.5), inset 0 -3px 5px rgba(150, 70, 40, 0.3);
539
+ }
540
+
541
+ /* 深色粘土按钮 */
542
+ .panel[data-nf-mode='dark'][data-nf-theme='clay'] .button,
543
+ body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .button {
544
+ border-color: rgba(255, 255, 255, 0.16);
545
+ background: linear-gradient(180deg, #403731, #332c27);
546
+ box-shadow: 0 8px 16px -6px rgba(0, 0, 0, 0.55), inset 0 3px 4px rgba(255, 255, 255, 0.14), inset 0 -3px 5px rgba(0, 0, 0, 0.4);
547
+ }
548
+
549
+ .panel[data-nf-mode='dark'][data-nf-theme='clay'] .button:hover:not([disabled]),
550
+ body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .button:hover:not([disabled]) {
551
+ box-shadow: 0 12px 22px -8px rgba(0, 0, 0, 0.6), inset 0 3px 4px rgba(255, 255, 255, 0.16), inset 0 -3px 5px rgba(0, 0, 0, 0.44);
552
+ }
553
+
554
+ .panel[data-nf-mode='dark'][data-nf-theme='clay'] .buttonPrimary,
555
+ body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .buttonPrimary {
556
+ background: linear-gradient(180deg, #f0ac82, #d67a4a);
557
+ border-color: transparent;
558
+ color: var(--nf-accent-fg);
559
+ box-shadow: 0 8px 16px -6px rgba(230, 154, 108, 0.5), inset 0 3px 4px rgba(255, 255, 255, 0.4), inset 0 -3px 5px rgba(120, 50, 20, 0.3);
560
+ }
561
+
562
+ .panel[data-nf-mode='dark'][data-nf-theme='clay'] .input,
563
+ .panel[data-nf-mode='dark'][data-nf-theme='clay'] .textarea,
564
+ body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .input,
565
+ body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .textarea {
566
+ box-shadow: inset 3px 3px 7px rgba(0, 0, 0, 0.45), inset -3px -3px 7px rgba(255, 255, 255, 0.08);
567
+ }
568
+
240
569
 
241
570
  /* Neumorphic inset inputs (sunken). */
242
571
  body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .input,
@@ -315,13 +644,13 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
315
644
  flex-direction: column;
316
645
  height: 100%;
317
646
  min-width: 0;
318
- font-size: 14px;
647
+ font-size: var(--nf-fs-14, 14px);
319
648
  line-height: 1.6;
320
649
  position: relative;
321
650
  overflow: hidden;
322
651
  }
323
652
 
324
- /* Liquid-Glass backdrop: colored orbs + vignette behind the frosted cards. */
653
+ /* Liquid-Glass backdrop: themed abstract image + colored orbs + vignette behind the frosted cards. */
325
654
  .panel::before {
326
655
  content: '';
327
656
  position: absolute;
@@ -329,26 +658,32 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
329
658
  z-index: 0;
330
659
  pointer-events: none;
331
660
  background:
661
+ var(--nf-glass-bg-image, none) center / cover no-repeat,
332
662
  radial-gradient(46% 36% at 18% 12%, var(--nf-glass-orb-a), transparent 70%),
333
663
  radial-gradient(52% 42% at 88% 22%, var(--nf-glass-orb-b), transparent 72%),
334
664
  radial-gradient(120% 95% at 50% 42%, transparent 55%, rgba(2, 2, 3, 0.10) 100%);
335
665
  }
336
666
 
667
+ /* --- 玻璃主题背后的「抽象壁纸」底图(每主题一种色调,供卡片 blur 出真实玻璃感) --- */
668
+ .panel[data-nf-theme='macos'] {
669
+ --nf-glass-bg-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='140'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='320' cy='220' r='320' fill='%230a84ff' fill-opacity='0.34'/%3E%3Ccircle cx='1180' cy='320' r='360' fill='%237f5af0' fill-opacity='0.30'/%3E%3Ccircle cx='920' cy='820' r='380' fill='%2340cfc0' fill-opacity='0.26'/%3E%3Ccircle cx='1460' cy='820' r='260' fill='%23ff9fb0' fill-opacity='0.18'/%3E%3C/g%3E%3C/svg%3E");
670
+ }
671
+
337
672
  .panelTitle {
338
673
  margin: 0;
339
- font-size: 16px;
674
+ font-size: var(--nf-fs-16, 16px);
340
675
  font-weight: 700;
341
676
  letter-spacing: 0.2px;
342
677
  display: flex;
343
678
  align-items: center;
344
- gap: 8px;
679
+ gap: var(--nf-space-8, 8px);
345
680
  }
346
681
 
347
682
  .panelTitle::before {
348
683
  content: '';
349
684
  width: 4px;
350
685
  height: 16px;
351
- border-radius: 2px;
686
+ border-radius: var(--nf-radius-2, 2px);
352
687
  background: linear-gradient(180deg, var(--nf-accent), var(--nf-info));
353
688
  }
354
689
 
@@ -356,24 +691,25 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
356
691
  border: none;
357
692
  background: transparent;
358
693
  cursor: pointer;
359
- font-size: 16px;
694
+ font-size: var(--nf-fs-16, 16px);
360
695
  color: var(--nf-text-2);
361
- padding: 4px 9px;
362
- border-radius: 8px;
363
- transition: background 0.15s ease, color 0.15s ease;
696
+ padding: var(--nf-space-4, 4px) var(--nf-space-10, 9px);
697
+ border-radius: var(--nf-radius-10, 9px);
698
+ transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
364
699
  }
365
700
 
366
701
  .iconButton:hover {
367
702
  background: var(--nf-hover);
368
703
  color: var(--nf-text);
704
+ transform: translateY(-1px);
369
705
  }
370
706
 
371
707
  /* ------------------------------------------------------------ tab bar */
372
708
 
373
709
  .tabBar {
374
710
  display: flex;
375
- gap: 2px;
376
- padding: 8px 14px 0;
711
+ gap: var(--nf-space-2, 2px);
712
+ padding: var(--nf-space-8, 8px) var(--nf-space-14, 14px) 0;
377
713
  border-bottom: 1px solid var(--nf-border);
378
714
  flex-shrink: 0;
379
715
  background: var(--nf-bg-raise);
@@ -385,10 +721,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
385
721
  .tab {
386
722
  border: none;
387
723
  background: transparent;
388
- padding: 7px 13px;
724
+ padding: var(--nf-space-8, 7px) var(--nf-space-14, 13px);
389
725
  cursor: pointer;
390
- border-radius: 8px 8px 0 0;
391
- font-size: 13.5px;
726
+ border-radius: var(--nf-radius-8, 8px) var(--nf-radius-8, 8px) 0 0;
727
+ font-size: var(--nf-fs-14, 13.5px);
392
728
  color: var(--nf-text-2);
393
729
  transition: color 0.15s ease, background 0.15s ease;
394
730
  position: relative;
@@ -412,17 +748,17 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
412
748
  right: 10px;
413
749
  bottom: -1px;
414
750
  height: 2.5px;
415
- border-radius: 2px 2px 0 0;
751
+ border-radius: var(--nf-radius-2, 2px) var(--nf-radius-2, 2px) 0 0;
416
752
  background: var(--nf-accent);
417
753
  }
418
754
 
419
755
  .panelContent {
420
756
  flex: 1;
421
757
  overflow: auto;
422
- padding: 16px 18px 20px;
758
+ padding: var(--nf-container-pad, 20px 22px);
423
759
  display: flex;
424
760
  flex-direction: column;
425
- gap: 14px;
761
+ gap: var(--nf-container-gap, 14px);
426
762
  position: relative;
427
763
  z-index: 1;
428
764
  }
@@ -443,11 +779,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
443
779
  width: 216px;
444
780
  display: flex;
445
781
  flex-direction: column;
446
- gap: 6px;
782
+ gap: var(--nf-space-6, 6px);
447
783
  margin: 10px 0 10px 12px;
448
- padding: 16px 12px 14px;
784
+ padding: var(--nf-nav-pad, 16px 12px 14px);
449
785
  border: 1px solid var(--nf-glass-border);
450
- border-radius: 18px;
786
+ border-radius: var(--nf-radius-16, 18px);
451
787
  background: var(--nf-glass-face);
452
788
  box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
453
789
  -webkit-backdrop-filter: blur(28px) saturate(175%);
@@ -458,22 +794,22 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
458
794
 
459
795
  .panelNavCollapsed {
460
796
  width: 52px;
461
- padding: 10px 6px;
797
+ padding: var(--nf-space-10, 10px) var(--nf-space-6, 6px);
462
798
  }
463
799
 
464
800
  .navGroup {
465
801
  display: flex;
466
802
  flex-direction: column;
467
- gap: 6px;
803
+ gap: var(--nf-space-6, 6px);
468
804
  }
469
805
 
470
806
  .navGroupLabel {
471
- font-size: 12px;
807
+ font-size: var(--nf-fs-12, 12px);
472
808
  font-weight: 600;
473
809
  letter-spacing: 0.8px;
474
810
  text-transform: uppercase;
475
811
  color: var(--nf-text-3);
476
- padding: 12px 10px 6px;
812
+ padding: var(--nf-space-12, 12px) var(--nf-space-10, 10px) var(--nf-space-6, 6px);
477
813
  user-select: none;
478
814
  }
479
815
 
@@ -494,8 +830,8 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
494
830
  flex: none;
495
831
  display: flex;
496
832
  flex-direction: column;
497
- gap: 4px;
498
- padding: 8px 6px 4px;
833
+ gap: var(--nf-space-4, 4px);
834
+ padding: var(--nf-space-8, 8px) var(--nf-space-6, 6px) var(--nf-space-4, 4px);
499
835
  border-top: 1px solid var(--nf-border);
500
836
  margin-top: 4px;
501
837
  }
@@ -504,14 +840,14 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
504
840
  display: flex;
505
841
  align-items: center;
506
842
  justify-content: space-between;
507
- gap: 4px;
843
+ gap: var(--nf-space-4, 4px);
508
844
  border: none;
509
845
  background: transparent;
510
846
  cursor: pointer;
511
- font-size: 11px;
847
+ font-size: var(--nf-fs-12, 11px);
512
848
  color: var(--nf-text-3);
513
- padding: 4px 6px;
514
- border-radius: 8px;
849
+ padding: var(--nf-space-4, 4px) var(--nf-space-6, 6px);
850
+ border-radius: var(--nf-radius-8, 8px);
515
851
  transition: color 0.15s ease, background 0.15s ease;
516
852
  text-align: left;
517
853
  white-space: nowrap;
@@ -527,10 +863,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
527
863
  background: var(--nf-accent-soft);
528
864
  color: var(--nf-accent);
529
865
  cursor: pointer;
530
- font-size: 10.5px;
866
+ font-size: var(--nf-fs-12, 10.5px);
531
867
  font-weight: 600;
532
- padding: 4px 6px;
533
- border-radius: 8px;
868
+ padding: var(--nf-space-4, 4px) var(--nf-space-6, 6px);
869
+ border-radius: var(--nf-radius-8, 8px);
534
870
  text-align: left;
535
871
  white-space: nowrap;
536
872
  }
@@ -540,13 +876,13 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
540
876
  }
541
877
 
542
878
  .panelNavCollapsed .navAbout {
543
- padding: 6px 2px 2px;
879
+ padding: var(--nf-space-6, 6px) var(--nf-space-2, 2px) var(--nf-space-2, 2px);
544
880
  align-items: center;
545
881
  }
546
882
 
547
883
  .panelNavCollapsed .navAboutRow {
548
884
  justify-content: center;
549
- padding: 4px 0;
885
+ padding: var(--nf-space-4, 4px) 0;
550
886
  width: 100%;
551
887
  }
552
888
 
@@ -555,11 +891,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
555
891
  flex: none;
556
892
  min-width: 18px;
557
893
  height: 18px;
558
- padding: 0 5px;
559
- border-radius: 999px;
894
+ padding: 0 var(--nf-space-6, 5px);
895
+ border-radius: var(--nf-radius-999, 999px);
560
896
  background: var(--nf-accent);
561
897
  color: #fff;
562
- font-size: 10.5px;
898
+ font-size: var(--nf-fs-12, 10.5px);
563
899
  font-weight: 700;
564
900
  line-height: 18px;
565
901
  text-align: center;
@@ -570,11 +906,12 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
570
906
  position: absolute;
571
907
  top: 2px;
572
908
  right: 2px;
573
- min-width: 14px;
574
- height: 14px;
575
- line-height: 14px;
576
- font-size: 9px;
577
- padding: 0 3px;
909
+ /* 字号统一为 12px 后,徽标容器同步放大到 18px 避免溢出 */
910
+ min-width: 18px;
911
+ height: 18px;
912
+ line-height: 18px;
913
+ font-size: var(--nf-fs-12, 9px);
914
+ padding: 0 var(--nf-space-6, 5px);
578
915
  }
579
916
 
580
917
  .navTabBadgeDanger {
@@ -589,7 +926,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
589
926
  background: var(--nf-success);
590
927
  }
591
928
 
592
- /* 任务进行中:工作进度导航呼吸绿点(不自动弹窗,点击导航查看悬浮窗) */
929
+ /* 任务进行中:AI进度导航呼吸绿点(不自动弹窗,点击导航查看悬浮窗) */
593
930
  .navTabBadgeLive {
594
931
  background: var(--nf-success);
595
932
  animation: navBadgePulse 1.2s ease-in-out infinite;
@@ -603,14 +940,14 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
603
940
  .navTab {
604
941
  display: flex;
605
942
  align-items: center;
606
- gap: 10px;
943
+ gap: var(--nf-space-10, 10px);
607
944
  width: 100%;
608
945
  border: 1px solid transparent;
609
946
  background: transparent;
610
947
  cursor: pointer;
611
- border-radius: 10px;
612
- padding: 11px 12px;
613
- font-size: 14px;
948
+ border-radius: var(--nf-radius-10, 10px);
949
+ padding: var(--nf-space-12, 11px) var(--nf-space-12, 12px);
950
+ font-size: var(--nf-fs-14, 14px);
614
951
  color: var(--nf-text-2-alpha, var(--nf-text-2));
615
952
  font-weight: 500;
616
953
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
@@ -621,7 +958,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
621
958
 
622
959
  .panelNavCollapsed .navTab {
623
960
  justify-content: center;
624
- padding: 8px 0;
961
+ padding: var(--nf-space-8, 8px) 0;
625
962
  }
626
963
 
627
964
  .navTab:hover {
@@ -645,7 +982,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
645
982
  flex: none;
646
983
  width: 22px;
647
984
  text-align: center;
648
- font-size: 17px;
985
+ font-size: var(--nf-fs-16, 17px);
649
986
  line-height: 1;
650
987
  }
651
988
 
@@ -658,8 +995,8 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
658
995
  .navTitle {
659
996
  display: flex;
660
997
  align-items: center;
661
- gap: 10px;
662
- padding: 2px 6px 12px;
998
+ gap: var(--nf-space-10, 10px);
999
+ padding: var(--nf-space-2, 2px) var(--nf-space-6, 6px) var(--nf-space-12, 12px);
663
1000
  border-bottom: 1px solid var(--nf-border);
664
1001
  margin-bottom: 6px;
665
1002
  flex: none;
@@ -669,11 +1006,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
669
1006
  .navTitleLogo {
670
1007
  width: 34px;
671
1008
  height: 34px;
672
- border-radius: 10px;
1009
+ border-radius: var(--nf-radius-10, 10px);
673
1010
  background: linear-gradient(145deg, var(--nf-accent), var(--nf-accent-hover));
674
1011
  color: var(--nf-accent-fg);
675
1012
  font-weight: 800;
676
- font-size: 15px;
1013
+ font-size: var(--nf-fs-14, 15px);
677
1014
  display: flex;
678
1015
  align-items: center;
679
1016
  justify-content: center;
@@ -683,7 +1020,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
683
1020
 
684
1021
  .navTitleName {
685
1022
  font-weight: 700;
686
- font-size: 15px;
1023
+ font-size: var(--nf-fs-14, 15px);
687
1024
  letter-spacing: 0.2px;
688
1025
  white-space: nowrap;
689
1026
  overflow: hidden;
@@ -691,7 +1028,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
691
1028
  }
692
1029
 
693
1030
  .navTitleBook {
694
- font-size: 11px;
1031
+ font-size: var(--nf-fs-12, 11px);
695
1032
  color: var(--nf-text-3);
696
1033
  white-space: nowrap;
697
1034
  overflow: hidden;
@@ -700,21 +1037,21 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
700
1037
 
701
1038
  .panelNavCollapsed .navTitle {
702
1039
  justify-content: center;
703
- padding: 2px 0 10px;
1040
+ padding: var(--nf-space-2, 2px) 0 var(--nf-space-10, 10px);
704
1041
  }
705
1042
 
706
1043
  .panelNavCollapsed .navTitleLogo {
707
1044
  width: 32px;
708
- height: 32px;
1045
+ height: var(--nf-ctrl-m, 32px);
709
1046
  }
710
1047
 
711
1048
  /* 操作行:收起导航 / 关闭面板 */
712
1049
  .navActions {
713
1050
  flex: none;
714
1051
  display: flex;
715
- gap: 6px;
1052
+ gap: var(--nf-space-6, 6px);
716
1053
  margin-top: 8px;
717
- padding-top: 8px;
1054
+ padding-top: var(--nf-space-8, 8px);
718
1055
  border-top: 1px solid var(--nf-border);
719
1056
  }
720
1057
 
@@ -724,9 +1061,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
724
1061
  background: rgba(0, 0, 0, 0);
725
1062
  color: var(--nf-text-2);
726
1063
  cursor: pointer;
727
- border-radius: 10px;
728
- height: 32px;
729
- font-size: 14px;
1064
+ border-radius: var(--nf-radius-10, 10px);
1065
+ height: var(--nf-ctrl-m, 32px);
1066
+ font-size: var(--nf-fs-14, 14px);
730
1067
  line-height: 1;
731
1068
  display: inline-flex;
732
1069
  align-items: center;
@@ -750,10 +1087,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
750
1087
  flex: none;
751
1088
  display: flex;
752
1089
  align-items: center;
753
- gap: 8px;
1090
+ gap: var(--nf-space-8, 8px);
754
1091
  margin-top: 4px;
755
- padding: 9px;
756
- border-radius: 12px;
1092
+ padding: var(--nf-space-10, 9px);
1093
+ border-radius: var(--nf-radius-12, 12px);
757
1094
  background: var(--nf-bg-inset);
758
1095
  border: 1px solid var(--nf-border);
759
1096
  cursor: pointer;
@@ -772,19 +1109,19 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
772
1109
  .bookSwitchCover {
773
1110
  width: 26px;
774
1111
  height: 34px;
775
- border-radius: 5px;
1112
+ border-radius: var(--nf-radius-6, 5px);
776
1113
  background: linear-gradient(160deg, var(--nf-accent), color-mix(in srgb, var(--nf-accent) 45%, #000));
777
1114
  color: var(--nf-accent-fg);
778
1115
  display: flex;
779
1116
  align-items: center;
780
1117
  justify-content: center;
781
- font-size: 11px;
1118
+ font-size: var(--nf-fs-12, 11px);
782
1119
  font-weight: 700;
783
1120
  flex: none;
784
1121
  }
785
1122
 
786
1123
  .bookSwitchName {
787
- font-size: 12.5px;
1124
+ font-size: var(--nf-fs-12, 12.5px);
788
1125
  font-weight: 600;
789
1126
  overflow: hidden;
790
1127
  text-overflow: ellipsis;
@@ -792,7 +1129,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
792
1129
  }
793
1130
 
794
1131
  .bookSwitchMeta {
795
- font-size: 11px;
1132
+ font-size: var(--nf-fs-12, 11px);
796
1133
  color: var(--nf-text-3);
797
1134
  overflow: hidden;
798
1135
  text-overflow: ellipsis;
@@ -802,31 +1139,31 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
802
1139
  .bookSwitchArrow {
803
1140
  margin-left: auto;
804
1141
  color: var(--nf-text-3);
805
- font-size: 12px;
1142
+ font-size: var(--nf-fs-12, 12px);
806
1143
  flex: none;
807
1144
  }
808
1145
 
809
1146
  /* demo 风格统计卡(今日待写 / 写作中 / 已通过 / 待审稿) */
810
- .statRowD { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
811
- .statCardD { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 14px 16px; border-radius: 16px; background: var(--nf-bg-inset); border: 1px solid var(--nf-border); min-width: 0; }
812
- .statCardDLabel { font-size: 12px; color: var(--nf-text-3); }
813
- .statCardDValue { font-size: 22px; font-weight: 700; margin-top: 2px; color: var(--nf-text); }
814
- .statCardDUnit { font-size: 12px; color: var(--nf-text-3); font-weight: 400; }
815
- .statCardDDetail { font-size: 11.5px; color: var(--nf-text-3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1147
+ .statRowD { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--nf-space-12, 12px); }
1148
+ .statCardD { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--nf-space-10, 10px); padding: var(--nf-space-14, 14px) var(--nf-space-16, 16px); border-radius: var(--nf-radius-16, 16px); background: var(--nf-bg-inset); border: 1px solid var(--nf-border); min-width: 0; }
1149
+ .statCardDLabel { font-size: var(--nf-fs-12, 12px); color: var(--nf-text-3); }
1150
+ .statCardDValue { font-size: var(--nf-fs-22, 22px); font-weight: 700; margin-top: 2px; color: var(--nf-text); }
1151
+ .statCardDUnit { font-size: var(--nf-fs-12, 12px); color: var(--nf-text-3); font-weight: 400; }
1152
+ .statCardDDetail { font-size: var(--nf-fs-12, 11.5px); color: var(--nf-text-3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
816
1153
  .statCardDDown { color: var(--nf-error); }
817
- .statCardDIcon { width: 38px; height: 38px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 18px; flex: none; background: var(--nf-accent-soft); }
1154
+ .statCardDIcon { width: 38px; height: var(--nf-ctrl-l, 38px); border-radius: var(--nf-radius-12, 12px); display: flex; align-items: center; justify-content: center; font-size: var(--nf-fs-18, 18px); flex: none; background: var(--nf-accent-soft); }
818
1155
  .statCardDIconRed { background: color-mix(in srgb, var(--nf-error) 13%, transparent); }
819
1156
 
820
1157
  /* demo 风格创作时间线(6 阶段分段条,点击跳转对应 tab) */
821
- .tlBar { display: flex; gap: 6px; margin-top: 8px; }
822
- .tlSeg { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; border: none; background: transparent; padding: 0; cursor: pointer; font: inherit; }
823
- .tlSegTrack { height: 8px; border-radius: 999px; background: var(--nf-hover); border: 1px solid var(--nf-border); overflow: hidden; }
824
- .tlSegFill { display: block; height: 100%; width: 100%; border-radius: 999px; background: var(--nf-accent); }
1158
+ .tlBar { display: flex; gap: var(--nf-space-6, 6px); margin-top: 8px; }
1159
+ .tlSeg { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--nf-space-4, 4px); border: none; background: transparent; padding: 0; cursor: pointer; font: inherit; }
1160
+ .tlSegTrack { height: 8px; border-radius: var(--nf-radius-999, 999px); background: var(--nf-hover); border: 1px solid var(--nf-border); overflow: hidden; }
1161
+ .tlSegFill { display: block; height: 100%; width: 100%; border-radius: var(--nf-radius-999, 999px); background: var(--nf-accent); }
825
1162
  .tlSegTodo .tlSegFill { opacity: 0; }
826
1163
  .tlSegTodo .tlSegTrack { background: transparent; }
827
1164
  .tlSegCurrent .tlSegTrack { border-color: var(--nf-accent); box-shadow: 0 0 0 2px var(--nf-accent-soft); }
828
1165
  .tlSegCurrent .tlSegFill { opacity: 0.45; }
829
- .tlSegLabel { font-size: 10.5px; color: var(--nf-text-3); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
1166
+ .tlSegLabel { font-size: var(--nf-fs-12, 10.5px); color: var(--nf-text-3); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
830
1167
  .tlSegDone .tlSegLabel { color: var(--nf-accent); font-weight: 600; }
831
1168
  .tlSeg:hover .tlSegTrack { border-color: var(--nf-border-strong); }
832
1169
 
@@ -835,19 +1172,19 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
835
1172
 
836
1173
  .card {
837
1174
  position: relative;
838
- border: 1px solid var(--nf-glass-border);
839
- border-radius: 22px;
840
- padding: 16px 18px;
1175
+ border: var(--nf-card-border, 1px solid var(--nf-glass-border));
1176
+ border-radius: var(--nf-card-radius, 22px);
1177
+ padding: var(--nf-card-pad, 20px 22px);
841
1178
  display: flex;
842
1179
  flex-direction: column;
843
- gap: 10px;
1180
+ gap: var(--nf-space-10, 10px);
844
1181
  background: var(--nf-glass-face);
845
1182
  box-shadow:
846
1183
  var(--nf-card-shadow),
847
- inset 0 1.5px 0 var(--nf-glass-sheen),
848
- inset 0 -1px 0 rgba(255, 255, 255, 0.25);
849
- -webkit-backdrop-filter: blur(30px) saturate(180%);
850
- backdrop-filter: blur(30px) saturate(180%);
1184
+ inset 0 1.5px 0 var(--nf-card-sheen, var(--nf-glass-sheen)),
1185
+ inset 0 -1px 0 rgba(255, 255, 255, 0.10);
1186
+ -webkit-backdrop-filter: blur(var(--nf-card-blur, 30px)) saturate(var(--nf-card-saturate, 180%)) brightness(var(--nf-card-brightness, 1.06));
1187
+ backdrop-filter: blur(var(--nf-card-blur, 30px)) saturate(var(--nf-card-saturate, 180%)) brightness(var(--nf-card-brightness, 1.06));
851
1188
  transition: transform 0.22s ease, box-shadow 0.22s ease;
852
1189
  }
853
1190
 
@@ -860,7 +1197,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
860
1197
  pointer-events: none;
861
1198
  background:
862
1199
  var(--nf-glass-core),
863
- linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px,
1200
+ linear-gradient(90deg, transparent, var(--nf-card-sheen, var(--nf-glass-sheen)), transparent) no-repeat 10% 0 / 80% 1px,
864
1201
  linear-gradient(156deg, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0) 55%);
865
1202
  z-index: 0;
866
1203
  }
@@ -881,7 +1218,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
881
1218
  transform: translateY(-3px);
882
1219
  box-shadow:
883
1220
  var(--nf-card-shadow-hover),
884
- inset 0 1.5px 0 var(--nf-glass-sheen),
1221
+ inset 0 1.5px 0 var(--nf-card-sheen, var(--nf-glass-sheen)),
885
1222
  inset 0 -1px 0 rgba(255, 255, 255, 0.25);
886
1223
  }
887
1224
 
@@ -892,25 +1229,27 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
892
1229
 
893
1230
  .cardTitle {
894
1231
  margin: 0;
895
- font-size: 14px;
1232
+ font-size: var(--nf-fs-14, 14px);
896
1233
  font-weight: 650;
897
1234
  color: var(--nf-text);
898
1235
  display: flex;
899
1236
  align-items: center;
900
- gap: 8px;
1237
+ gap: var(--nf-space-8, 8px);
901
1238
  }
902
1239
 
903
1240
  /* ------------------------------------------------------------ buttons */
904
1241
 
905
1242
  .button {
906
- border: 1px solid var(--nf-border-strong);
907
- background: var(--nf-bg-inset);
1243
+ /* 控件形态令牌:按钮与 input/textarea 一致,随主题(液态/粘土/macOS/新拟物)走形状 */
1244
+ border: 1px solid var(--nf-ctrl-border, var(--nf-border-strong));
1245
+ background: var(--nf-ctrl-bg, var(--nf-bg-inset));
908
1246
  color: var(--nf-text);
909
- padding: 6px 14px;
910
- border-radius: 12px;
1247
+ padding: var(--nf-space-8, 7px) var(--nf-space-16, 15px);
1248
+ border-radius: var(--nf-ctrl-radius, 10px);
911
1249
  cursor: pointer;
912
- font-size: 13px;
1250
+ font-size: var(--nf-fs-14, 13px);
913
1251
  font-weight: 500;
1252
+ box-shadow: inset 0 1px 0 var(--nf-ctrl-sheen, rgba(255, 255, 255, 0.09));
914
1253
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
915
1254
  white-space: nowrap;
916
1255
  }
@@ -918,10 +1257,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
918
1257
  .button:hover:not([disabled]) {
919
1258
  background: var(--nf-hover);
920
1259
  border-color: var(--nf-border-strong);
1260
+ transform: translateY(-1px);
921
1261
  }
922
1262
 
923
1263
  .button:active:not([disabled]) {
924
- transform: scale(0.96);
1264
+ transform: translateY(0) scale(0.97);
925
1265
  }
926
1266
 
927
1267
  .button[disabled] {
@@ -933,12 +1273,15 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
933
1273
  border-color: transparent;
934
1274
  background: linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #ffffff), var(--nf-accent));
935
1275
  color: var(--nf-accent-fg);
936
- box-shadow: 0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 0.5px color-mix(in srgb, var(--nf-accent) 30%, transparent);
1276
+ border-radius: var(--nf-radius-10, 10px);
1277
+ box-shadow: 0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 0.5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.45);
937
1278
  }
938
1279
 
939
1280
  .buttonPrimary:hover:not([disabled]) {
940
1281
  background: linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000000));
941
1282
  border-color: transparent;
1283
+ transform: translateY(-1px);
1284
+ box-shadow: 0 12px 30px color-mix(in srgb, var(--nf-accent) 50%, transparent), 0 0 0 0.5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.45);
942
1285
  }
943
1286
 
944
1287
  .buttonDanger {
@@ -951,9 +1294,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
951
1294
  }
952
1295
 
953
1296
  .buttonSmall {
954
- padding: 3px 10px;
955
- font-size: 12px;
956
- border-radius: 9px;
1297
+ padding: var(--nf-space-4, 4px) var(--nf-space-10, 10px);
1298
+ font-size: var(--nf-fs-12, 12px);
1299
+ /* 与常规按钮同一控件形态令牌,保证主题一致 */
1300
+ border-radius: var(--nf-ctrl-radius, 8px);
957
1301
  }
958
1302
 
959
1303
  /* ------------------------------------------------------------ forms */
@@ -961,27 +1305,61 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
961
1305
  .field {
962
1306
  display: flex;
963
1307
  flex-direction: column;
964
- gap: 5px;
1308
+ gap: var(--nf-space-6, 5px);
965
1309
  }
966
1310
 
967
1311
  .fieldLabel {
968
- font-size: 12px;
1312
+ font-size: var(--nf-fs-12, 12px);
969
1313
  color: var(--nf-text-2);
970
1314
  font-weight: 500;
971
1315
  }
972
1316
 
973
1317
  .input {
974
- border: 1px solid var(--nf-border-strong);
975
- background: var(--nf-bg-inset);
1318
+ border: var(--nf-ctrl-border, 1px solid var(--nf-border-strong));
1319
+ background: var(--nf-ctrl-bg, var(--nf-bg-inset));
976
1320
  color: var(--nf-text);
977
- border-radius: 12px;
978
- padding: 7px 11px;
979
- font-size: 13px;
1321
+ color-scheme: light;
1322
+ border-radius: var(--nf-ctrl-radius, 12px);
1323
+ padding: var(--nf-space-8, 7px) var(--nf-space-12, 11px);
1324
+ font-size: var(--nf-fs-14, 13px);
980
1325
  width: 100%;
981
1326
  box-sizing: border-box;
1327
+ box-shadow: inset 0 1px 0 var(--nf-ctrl-sheen, rgba(255, 255, 255, 0.09));
982
1328
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
983
1329
  }
984
1330
 
1331
+ /* 原生下拉浮层配色跟随主题(防白底白字) */
1332
+ body[data-ds-dark-theme] .input {
1333
+ color-scheme: dark;
1334
+ }
1335
+ .panel[data-nf-mode='dark'] .input {
1336
+ color-scheme: dark;
1337
+ }
1338
+ .panel[data-nf-mode='light'] .input {
1339
+ color-scheme: light;
1340
+ }
1341
+ body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .input {
1342
+ color-scheme: light;
1343
+ }
1344
+ select.input {
1345
+ cursor: pointer;
1346
+ appearance: none;
1347
+ -webkit-appearance: none;
1348
+ /* 自绘下拉箭头(跟随主题色),去掉浏览器默认黑色 caret */
1349
+ background-image:
1350
+ linear-gradient(45deg, transparent 50%, var(--nf-ctrl-caret, var(--nf-text-3)) 50%),
1351
+ linear-gradient(135deg, var(--nf-ctrl-caret, var(--nf-text-3)) 50%, transparent 50%);
1352
+ background-position: calc(100% - 18px) 50%, calc(100% - 12px) 50%;
1353
+ background-size: 6px 6px, 6px 6px;
1354
+ background-repeat: no-repeat;
1355
+ padding-right: 30px;
1356
+ }
1357
+ .input option {
1358
+ color: var(--nf-text);
1359
+ background: var(--nf-bg-raise);
1360
+ font-size: var(--nf-fs-14, 15px);
1361
+ }
1362
+
985
1363
  .input:focus,
986
1364
  .textarea:focus {
987
1365
  outline: none;
@@ -995,12 +1373,12 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
995
1373
  }
996
1374
 
997
1375
  .textarea {
998
- border: 1px solid var(--nf-border-strong);
999
- background: var(--nf-bg-inset);
1376
+ border: var(--nf-ctrl-border, 1px solid var(--nf-border-strong));
1377
+ background: var(--nf-ctrl-bg, var(--nf-bg-inset));
1000
1378
  color: var(--nf-text);
1001
- border-radius: 12px;
1002
- padding: 9px 11px;
1003
- font-size: 13px;
1379
+ border-radius: var(--nf-ctrl-radius, 12px);
1380
+ padding: var(--nf-space-10, 9px) var(--nf-space-12, 11px);
1381
+ font-size: var(--nf-fs-14, 13px);
1004
1382
  width: 100%;
1005
1383
  box-sizing: border-box;
1006
1384
  min-height: 200px;
@@ -1013,7 +1391,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1013
1391
  .row {
1014
1392
  display: flex;
1015
1393
  align-items: center;
1016
- gap: 8px;
1394
+ gap: var(--nf-space-8, 8px);
1017
1395
  flex-wrap: wrap;
1018
1396
  }
1019
1397
 
@@ -1026,27 +1404,27 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1026
1404
  .chapterList {
1027
1405
  display: flex;
1028
1406
  flex-direction: column;
1029
- gap: 8px;
1407
+ gap: var(--nf-space-8, 8px);
1030
1408
  }
1031
1409
 
1032
1410
  /* 章节按卷分组 */
1033
1411
  .volumeGroup {
1034
1412
  display: flex;
1035
1413
  flex-direction: column;
1036
- gap: 6px;
1414
+ gap: var(--nf-space-6, 6px);
1037
1415
  }
1038
1416
 
1039
1417
  .volumeGroupHeader {
1040
1418
  display: flex;
1041
1419
  align-items: center;
1042
- gap: 8px;
1043
- padding: 6px 10px;
1044
- border-radius: 10px;
1420
+ gap: var(--nf-space-8, 8px);
1421
+ padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
1422
+ border-radius: var(--nf-radius-10, 10px);
1045
1423
  background: var(--nf-bg-inset);
1046
1424
  border: 1px solid var(--nf-border);
1047
1425
  cursor: pointer;
1048
1426
  user-select: none;
1049
- font-size: 13px;
1427
+ font-size: var(--nf-fs-14, 13px);
1050
1428
  transition: border-color 0.15s ease;
1051
1429
  }
1052
1430
 
@@ -1056,17 +1434,17 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1056
1434
 
1057
1435
  .volumeGroupToggle {
1058
1436
  flex: none;
1059
- font-size: 11px;
1437
+ font-size: var(--nf-fs-12, 11px);
1060
1438
  color: var(--nf-text-2);
1061
1439
  }
1062
1440
 
1063
1441
  .chapter {
1064
1442
  display: flex;
1065
1443
  align-items: center;
1066
- gap: 10px;
1067
- padding: 9px 12px;
1444
+ gap: var(--nf-space-10, 10px);
1445
+ padding: var(--nf-space-10, 9px) var(--nf-space-12, 12px);
1068
1446
  border: 1px solid var(--nf-border);
1069
- border-radius: 10px;
1447
+ border-radius: var(--nf-radius-10, 10px);
1070
1448
  background: var(--nf-bg);
1071
1449
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
1072
1450
  }
@@ -1093,12 +1471,12 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1093
1471
  align-items: center;
1094
1472
  justify-content: center;
1095
1473
  min-width: 28px;
1096
- height: 28px;
1097
- padding: 0 8px;
1098
- border-radius: 8px;
1474
+ height: var(--nf-ctrl-s, 28px);
1475
+ padding: 0 var(--nf-space-8, 8px);
1476
+ border-radius: var(--nf-radius-8, 8px);
1099
1477
  background: var(--nf-bg-inset);
1100
1478
  border: 1px solid var(--nf-border);
1101
- font-size: 12px;
1479
+ font-size: var(--nf-fs-12, 12px);
1102
1480
  font-weight: 700;
1103
1481
  color: var(--nf-text-2);
1104
1482
  flex-shrink: 0;
@@ -1111,15 +1489,15 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1111
1489
 
1112
1490
  .chapterTitle {
1113
1491
  font-weight: 600;
1114
- font-size: 13px;
1492
+ font-size: var(--nf-fs-14, 13px);
1115
1493
  display: flex;
1116
1494
  align-items: center;
1117
- gap: 8px;
1495
+ gap: var(--nf-space-8, 8px);
1118
1496
  color: var(--nf-text);
1119
1497
  }
1120
1498
 
1121
1499
  .chapterBeats {
1122
- font-size: 12px;
1500
+ font-size: var(--nf-fs-12, 12px);
1123
1501
  color: var(--nf-text-2);
1124
1502
  opacity: 0.85;
1125
1503
  overflow: hidden;
@@ -1129,7 +1507,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1129
1507
 
1130
1508
  .chapterActions {
1131
1509
  display: flex;
1132
- gap: 4px;
1510
+ gap: var(--nf-space-4, 4px);
1133
1511
  flex-shrink: 0;
1134
1512
  opacity: 0.85;
1135
1513
  transition: opacity 0.15s ease;
@@ -1142,9 +1520,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1142
1520
  /* ------------------------------------------------------------ badges */
1143
1521
 
1144
1522
  .badge {
1145
- font-size: 11px;
1146
- padding: 2px 9px;
1147
- border-radius: 999px;
1523
+ font-size: var(--nf-fs-12, 11px);
1524
+ padding: var(--nf-space-2, 2px) var(--nf-space-10, 9px);
1525
+ border-radius: var(--nf-radius-999, 999px);
1148
1526
  border: 1px solid;
1149
1527
  white-space: nowrap;
1150
1528
  font-weight: 600;
@@ -1192,13 +1570,13 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1192
1570
 
1193
1571
  .reviewBox {
1194
1572
  border: 1px solid var(--nf-border);
1195
- border-radius: 10px;
1196
- padding: 10px 12px;
1573
+ border-radius: var(--nf-radius-10, 10px);
1574
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
1197
1575
  background: var(--nf-bg-inset);
1198
1576
  display: flex;
1199
1577
  flex-direction: column;
1200
- gap: 6px;
1201
- font-size: 12.5px;
1578
+ gap: var(--nf-space-6, 6px);
1579
+ font-size: var(--nf-fs-12, 12.5px);
1202
1580
  }
1203
1581
 
1204
1582
  .chapterPreview {
@@ -1206,14 +1584,14 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1206
1584
  overflow: auto;
1207
1585
  white-space: pre-wrap;
1208
1586
  word-break: break-all;
1209
- font-size: 12.5px;
1587
+ font-size: var(--nf-fs-12, 12.5px);
1210
1588
  line-height: 1.8;
1211
1589
  font-family: inherit;
1212
1590
  color: var(--nf-text);
1213
1591
  background: var(--nf-bg-inset);
1214
1592
  border: 1px solid var(--nf-border);
1215
- border-radius: 10px;
1216
- padding: 10px 12px;
1593
+ border-radius: var(--nf-radius-10, 10px);
1594
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
1217
1595
  margin: 0;
1218
1596
  }
1219
1597
 
@@ -1226,10 +1604,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1226
1604
  overflow-y: auto;
1227
1605
  display: flex;
1228
1606
  flex-direction: column;
1229
- gap: 10px;
1230
- padding: 14px;
1607
+ gap: var(--nf-space-10, 10px);
1608
+ padding: var(--nf-space-14, 14px);
1231
1609
  border: 1px solid var(--nf-border);
1232
- border-radius: 12px;
1610
+ border-radius: var(--nf-radius-12, 12px);
1233
1611
  background: var(--nf-bg-inset);
1234
1612
  }
1235
1613
 
@@ -1238,9 +1616,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1238
1616
  max-width: 90%;
1239
1617
  background: linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));
1240
1618
  color: var(--nf-accent-fg);
1241
- border-radius: 14px 14px 4px 14px;
1242
- padding: 9px 14px;
1243
- font-size: 13px;
1619
+ border-radius: var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-4, 4px) var(--nf-radius-14, 14px);
1620
+ padding: var(--nf-space-10, 9px) var(--nf-space-14, 14px);
1621
+ font-size: var(--nf-fs-14, 13px);
1244
1622
  box-shadow: 0 2px 6px rgba(77, 107, 254, 0.2);
1245
1623
  }
1246
1624
 
@@ -1250,14 +1628,14 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1250
1628
  background: var(--nf-bg-raise);
1251
1629
  color: var(--nf-text);
1252
1630
  border: 1px solid var(--nf-border);
1253
- border-radius: 14px 14px 14px 4px;
1254
- padding: 9px 14px;
1255
- font-size: 13px;
1631
+ border-radius: var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-4, 4px);
1632
+ padding: var(--nf-space-10, 9px) var(--nf-space-14, 14px);
1633
+ font-size: var(--nf-fs-14, 13px);
1256
1634
  box-shadow: var(--nf-shadow);
1257
1635
  }
1258
1636
 
1259
1637
  .chatRole {
1260
- font-size: 11px;
1638
+ font-size: var(--nf-fs-12, 11px);
1261
1639
  color: var(--nf-text-3);
1262
1640
  margin-bottom: 3px;
1263
1641
  font-weight: 600;
@@ -1266,11 +1644,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1266
1644
  /* Live tool output (text streaming while a chapter is generated/rewritten). */
1267
1645
  .toolLive {
1268
1646
  margin-top: 6px;
1269
- padding: 8px 10px;
1270
- border-radius: 8px;
1647
+ padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
1648
+ border-radius: var(--nf-radius-8, 8px);
1271
1649
  background: var(--nf-bg-inset);
1272
1650
  border: 1px dashed var(--nf-border-strong);
1273
- font-size: 12px;
1651
+ font-size: var(--nf-fs-12, 12px);
1274
1652
  line-height: 1.7;
1275
1653
  white-space: pre-wrap;
1276
1654
  word-break: break-all;
@@ -1283,15 +1661,15 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1283
1661
  .assistantStatus {
1284
1662
  flex: none;
1285
1663
  margin-top: 6px;
1286
- padding: 6px 12px;
1287
- border-radius: 999px;
1288
- font-size: 12px;
1664
+ padding: var(--nf-space-6, 6px) var(--nf-space-12, 12px);
1665
+ border-radius: var(--nf-radius-999, 999px);
1666
+ font-size: var(--nf-fs-12, 12px);
1289
1667
  color: var(--nf-text-2);
1290
1668
  background: var(--nf-bg-inset);
1291
1669
  border: 1px solid var(--nf-border);
1292
1670
  display: flex;
1293
1671
  align-items: center;
1294
- gap: 6px;
1672
+ gap: var(--nf-space-6, 6px);
1295
1673
  }
1296
1674
 
1297
1675
  .assistantStatusBusy {
@@ -1305,17 +1683,17 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1305
1683
  .toolSteps {
1306
1684
  display: flex;
1307
1685
  flex-direction: column;
1308
- gap: 4px;
1686
+ gap: var(--nf-space-4, 4px);
1309
1687
  margin-top: 6px;
1310
1688
  }
1311
1689
 
1312
1690
  .toolStep {
1313
1691
  display: flex;
1314
1692
  align-items: center;
1315
- gap: 8px;
1316
- padding: 5px 10px;
1317
- border-radius: 8px;
1318
- font-size: 12px;
1693
+ gap: var(--nf-space-8, 8px);
1694
+ padding: var(--nf-space-6, 5px) var(--nf-space-10, 10px);
1695
+ border-radius: var(--nf-radius-8, 8px);
1696
+ font-size: var(--nf-fs-12, 12px);
1319
1697
  background: var(--nf-bg-inset);
1320
1698
  border: 1px solid var(--nf-border);
1321
1699
  }
@@ -1332,7 +1710,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1332
1710
 
1333
1711
  .toolStepIcon {
1334
1712
  flex: none;
1335
- font-size: 13px;
1713
+ font-size: var(--nf-fs-14, 13px);
1336
1714
  }
1337
1715
 
1338
1716
  .toolStepName {
@@ -1347,7 +1725,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1347
1725
  .toolStepStatus {
1348
1726
  flex: none;
1349
1727
  color: var(--nf-text-2);
1350
- font-size: 11px;
1728
+ font-size: var(--nf-fs-12, 11px);
1351
1729
  }
1352
1730
 
1353
1731
  .toolStepActive .toolStepStatus {
@@ -1361,7 +1739,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1361
1739
  .toolStepDetail {
1362
1740
  width: 100%;
1363
1741
  color: var(--nf-error);
1364
- font-size: 11px;
1742
+ font-size: var(--nf-fs-12, 11px);
1365
1743
  word-break: break-all;
1366
1744
  }
1367
1745
 
@@ -1369,9 +1747,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1369
1747
 
1370
1748
  .progress {
1371
1749
  border: 1px solid var(--nf-border);
1372
- border-radius: 10px;
1373
- padding: 10px 14px;
1374
- font-size: 12px;
1750
+ border-radius: var(--nf-radius-10, 10px);
1751
+ padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
1752
+ font-size: var(--nf-fs-12, 12px);
1375
1753
  min-height: 60px;
1376
1754
  max-height: 220px;
1377
1755
  overflow: auto;
@@ -1393,7 +1771,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1393
1771
  font-weight: 600;
1394
1772
  display: flex;
1395
1773
  align-items: center;
1396
- gap: 8px;
1774
+ gap: var(--nf-space-8, 8px);
1397
1775
  }
1398
1776
 
1399
1777
  .progressBar {
@@ -1401,7 +1779,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1401
1779
  flex: none;
1402
1780
  width: 110px;
1403
1781
  height: 6px;
1404
- border-radius: 999px;
1782
+ border-radius: var(--nf-radius-999, 999px);
1405
1783
  background: var(--nf-border);
1406
1784
  overflow: hidden;
1407
1785
  }
@@ -1409,7 +1787,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1409
1787
  .progressBarFill {
1410
1788
  display: block;
1411
1789
  height: 100%;
1412
- border-radius: 3px;
1790
+ border-radius: var(--nf-radius-4, 3px);
1413
1791
  background: var(--nf-accent);
1414
1792
  transition: width 0.3s ease;
1415
1793
  }
@@ -1419,12 +1797,12 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1419
1797
  display: flex;
1420
1798
  align-items: center;
1421
1799
  justify-content: space-between;
1422
- gap: 12px;
1800
+ gap: var(--nf-space-12, 12px);
1423
1801
  flex-wrap: wrap;
1424
1802
  }
1425
1803
 
1426
1804
  .liveText {
1427
- font-size: 12px;
1805
+ font-size: var(--nf-fs-12, 12px);
1428
1806
  font-variant-numeric: tabular-nums;
1429
1807
  color: var(--nf-text-2);
1430
1808
  }
@@ -1432,7 +1810,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1432
1810
  .bigProgressBar {
1433
1811
  margin-top: 10px;
1434
1812
  height: 8px;
1435
- border-radius: 999px;
1813
+ border-radius: var(--nf-radius-999, 999px);
1436
1814
  background: var(--nf-border);
1437
1815
  overflow: hidden;
1438
1816
  }
@@ -1440,7 +1818,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1440
1818
  .bigProgressBarFill {
1441
1819
  display: block;
1442
1820
  height: 100%;
1443
- border-radius: 999px;
1821
+ border-radius: var(--nf-radius-999, 999px);
1444
1822
  background: linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2, var(--nf-accent)));
1445
1823
  transition: width 0.3s ease;
1446
1824
  }
@@ -1449,10 +1827,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1449
1827
  .diffLegend {
1450
1828
  display: flex;
1451
1829
  align-items: center;
1452
- gap: 14px;
1830
+ gap: var(--nf-space-14, 14px);
1453
1831
  flex-wrap: wrap;
1454
1832
  margin: 6px 0 8px;
1455
- font-size: 12px;
1833
+ font-size: var(--nf-fs-12, 12px);
1456
1834
  }
1457
1835
 
1458
1836
  .legendOld {
@@ -1468,7 +1846,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1468
1846
  .onlyChanges {
1469
1847
  display: inline-flex;
1470
1848
  align-items: center;
1471
- gap: 4px;
1849
+ gap: var(--nf-space-4, 4px);
1472
1850
  color: var(--nf-text-2);
1473
1851
  cursor: pointer;
1474
1852
  margin-left: auto;
@@ -1479,27 +1857,27 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1479
1857
  min-height: 0;
1480
1858
  overflow-y: auto;
1481
1859
  border: 1px solid var(--nf-border);
1482
- border-radius: 8px;
1860
+ border-radius: var(--nf-radius-8, 8px);
1483
1861
  background: var(--nf-bg-inset);
1484
- padding: 10px 12px;
1862
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
1485
1863
  display: flex;
1486
1864
  flex-direction: column;
1487
- gap: 8px;
1488
- font-size: 13px;
1865
+ gap: var(--nf-space-8, 8px);
1866
+ font-size: var(--nf-fs-14, 13px);
1489
1867
  line-height: 1.7;
1490
1868
  }
1491
1869
 
1492
1870
  .diffSame {
1493
1871
  border: 1px dashed var(--nf-border);
1494
- border-radius: 6px;
1495
- padding: 6px 10px;
1872
+ border-radius: var(--nf-radius-6, 6px);
1873
+ padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
1496
1874
  color: var(--nf-text-2);
1497
1875
  opacity: 0.85;
1498
1876
  }
1499
1877
 
1500
1878
  .diffSame summary {
1501
1879
  cursor: pointer;
1502
- font-size: 12px;
1880
+ font-size: var(--nf-fs-12, 12px);
1503
1881
  user-select: none;
1504
1882
  }
1505
1883
 
@@ -1513,16 +1891,16 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1513
1891
  display: grid;
1514
1892
  grid-template-columns: 1fr 1fr;
1515
1893
  border: 1px solid var(--nf-border);
1516
- border-radius: 8px;
1894
+ border-radius: var(--nf-radius-8, 8px);
1517
1895
  overflow: hidden;
1518
1896
  }
1519
1897
 
1520
1898
  .diffColumn {
1521
1899
  display: flex;
1522
1900
  flex-direction: column;
1523
- gap: 6px;
1901
+ gap: var(--nf-space-6, 6px);
1524
1902
  min-width: 0;
1525
- padding: 8px 10px;
1903
+ padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
1526
1904
  }
1527
1905
 
1528
1906
  .diffColumn:first-child {
@@ -1533,10 +1911,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1533
1911
  .diffTagNew {
1534
1912
  align-self: flex-start;
1535
1913
  flex: none;
1536
- font-size: 11px;
1914
+ font-size: var(--nf-fs-12, 11px);
1537
1915
  font-weight: 700;
1538
- border-radius: 4px;
1539
- padding: 1px 7px;
1916
+ border-radius: var(--nf-radius-4, 4px);
1917
+ padding: var(--nf-space-2, 1px) var(--nf-space-8, 7px);
1540
1918
  letter-spacing: 0.5px;
1541
1919
  }
1542
1920
 
@@ -1568,9 +1946,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1568
1946
  .diffDel {
1569
1947
  display: flex;
1570
1948
  flex-direction: column;
1571
- gap: 4px;
1572
- padding: 6px 10px;
1573
- border-radius: 6px;
1949
+ gap: var(--nf-space-4, 4px);
1950
+ padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
1951
+ border-radius: var(--nf-radius-6, 6px);
1574
1952
  border: 1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);
1575
1953
  background: color-mix(in srgb, var(--nf-error) 7%, transparent);
1576
1954
  }
@@ -1578,9 +1956,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1578
1956
  .diffAdd {
1579
1957
  display: flex;
1580
1958
  flex-direction: column;
1581
- gap: 4px;
1582
- padding: 6px 10px;
1583
- border-radius: 6px;
1959
+ gap: var(--nf-space-4, 4px);
1960
+ padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
1961
+ border-radius: var(--nf-radius-6, 6px);
1584
1962
  border: 1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);
1585
1963
  background: color-mix(in srgb, var(--nf-success) 7%, transparent);
1586
1964
  }
@@ -1605,13 +1983,13 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1605
1983
  flex-direction: column;
1606
1984
  flex: 1;
1607
1985
  min-height: 0;
1608
- gap: 10px;
1986
+ gap: var(--nf-space-10, 10px);
1609
1987
  }
1610
1988
 
1611
1989
  .wsPageHeader {
1612
1990
  display: flex;
1613
1991
  align-items: center;
1614
- gap: 8px;
1992
+ gap: var(--nf-space-8, 8px);
1615
1993
  flex: none;
1616
1994
  flex-wrap: wrap;
1617
1995
  }
@@ -1621,20 +1999,20 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1621
1999
  flex: none;
1622
2000
  display: flex;
1623
2001
  align-items: center;
1624
- gap: 8px;
2002
+ gap: var(--nf-space-8, 8px);
1625
2003
  flex-wrap: wrap;
1626
- padding: 8px 12px;
2004
+ padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
1627
2005
  border: 1px solid var(--nf-success);
1628
- border-radius: 10px;
2006
+ border-radius: var(--nf-radius-10, 10px);
1629
2007
  background: color-mix(in srgb, var(--nf-success) 8%, transparent);
1630
- font-size: 12px;
2008
+ font-size: var(--nf-fs-12, 12px);
1631
2009
  font-weight: 600;
1632
2010
  }
1633
2011
 
1634
2012
  .wsColumns {
1635
2013
  display: grid;
1636
2014
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
1637
- gap: 14px;
2015
+ gap: var(--nf-space-14, 14px);
1638
2016
  flex: 1;
1639
2017
  min-height: 0;
1640
2018
  }
@@ -1642,7 +2020,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1642
2020
  .wsColumn {
1643
2021
  display: flex;
1644
2022
  flex-direction: column;
1645
- gap: 8px;
2023
+ gap: var(--nf-space-8, 8px);
1646
2024
  min-width: 0;
1647
2025
  min-height: 0;
1648
2026
  }
@@ -1652,15 +2030,15 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1652
2030
  min-height: 0;
1653
2031
  resize: vertical;
1654
2032
  font-family: var(--nf-font);
1655
- font-size: 13px;
2033
+ font-size: var(--nf-fs-14, 13px);
1656
2034
  line-height: 1.75;
1657
2035
  white-space: pre-wrap;
1658
2036
  }
1659
2037
 
1660
2038
  .wsSelected {
1661
2039
  border: 1px solid var(--nf-accent);
1662
- border-radius: 6px;
1663
- padding: 6px 10px;
2040
+ border-radius: var(--nf-radius-6, 6px);
2041
+ padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
1664
2042
  background: color-mix(in srgb, var(--nf-accent) 8%, transparent);
1665
2043
  max-height: 120px;
1666
2044
  overflow: auto;
@@ -1668,18 +2046,18 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1668
2046
 
1669
2047
  .wsSelectedText {
1670
2048
  margin-top: 4px;
1671
- font-size: 12px;
2049
+ font-size: var(--nf-fs-12, 12px);
1672
2050
  color: var(--nf-text-2);
1673
2051
  white-space: pre-wrap;
1674
2052
  }
1675
2053
 
1676
2054
  .wsPreview {
1677
2055
  border: 1px solid var(--nf-border);
1678
- border-radius: 8px;
1679
- padding: 8px 10px;
2056
+ border-radius: var(--nf-radius-8, 8px);
2057
+ padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
1680
2058
  display: flex;
1681
2059
  flex-direction: column;
1682
- gap: 8px;
2060
+ gap: var(--nf-space-8, 8px);
1683
2061
  background: var(--nf-bg-inset);
1684
2062
  }
1685
2063
 
@@ -1688,7 +2066,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1688
2066
  flex: 1;
1689
2067
  min-height: 0;
1690
2068
  overflow: auto;
1691
- font-size: 13px;
2069
+ font-size: var(--nf-fs-14, 13px);
1692
2070
  line-height: 1.7;
1693
2071
  white-space: pre-wrap;
1694
2072
  color: var(--nf-text);
@@ -1698,16 +2076,16 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1698
2076
  .assetGrid {
1699
2077
  display: grid;
1700
2078
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
1701
- gap: 10px;
2079
+ gap: var(--nf-space-10, 10px);
1702
2080
  }
1703
2081
 
1704
2082
  .assetStat {
1705
2083
  border: 1px solid var(--nf-glass-border);
1706
- border-radius: 14px;
1707
- padding: 10px 12px;
2084
+ border-radius: var(--nf-radius-14, 14px);
2085
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
1708
2086
  display: flex;
1709
2087
  flex-direction: column;
1710
- gap: 4px;
2088
+ gap: var(--nf-space-4, 4px);
1711
2089
  background: var(--nf-glass-face);
1712
2090
  box-shadow: var(--nf-card-shadow), inset 0 1px 0 var(--nf-glass-sheen);
1713
2091
  -webkit-backdrop-filter: blur(30px) saturate(180%);
@@ -1721,20 +2099,20 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1721
2099
  }
1722
2100
 
1723
2101
  .assetStatLabel {
1724
- font-size: 11px;
2102
+ font-size: var(--nf-fs-12, 11px);
1725
2103
  color: var(--nf-text-2);
1726
2104
  opacity: 0.9;
1727
2105
  }
1728
2106
 
1729
2107
  .assetStatValue {
1730
- font-size: 15px;
2108
+ font-size: var(--nf-fs-14, 15px);
1731
2109
  font-weight: 700;
1732
2110
  line-height: 1.2;
1733
2111
  color: var(--nf-text);
1734
2112
  }
1735
2113
 
1736
2114
  .assetStatDetail {
1737
- font-size: 11px;
2115
+ font-size: var(--nf-fs-12, 11px);
1738
2116
  color: var(--nf-text-2);
1739
2117
  opacity: 0.85;
1740
2118
  overflow: hidden;
@@ -1747,8 +2125,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1747
2125
  .dashHero {
1748
2126
  position: relative;
1749
2127
  border: 1px solid var(--nf-glass-border);
1750
- border-radius: 22px;
1751
- padding: 18px 20px;
2128
+ border-radius: var(--nf-radius-22, 22px);
2129
+ /* 主容器统一:与设置页卡片同一 --nf-card-pad */
2130
+ padding: var(--nf-card-pad, 20px 22px);
1752
2131
  background: var(--nf-glass-face);
1753
2132
  box-shadow:
1754
2133
  var(--nf-card-shadow),
@@ -1758,7 +2137,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1758
2137
  backdrop-filter: blur(30px) saturate(180%);
1759
2138
  display: flex;
1760
2139
  flex-direction: column;
1761
- gap: 14px;
2140
+ gap: var(--nf-space-14, 14px);
1762
2141
  transition: transform 0.22s ease, box-shadow 0.22s ease;
1763
2142
  }
1764
2143
 
@@ -1804,25 +2183,25 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1804
2183
  .dashHeroEyebrow {
1805
2184
  display: inline-flex;
1806
2185
  align-items: center;
1807
- gap: 6px;
1808
- font-size: 13px;
2186
+ gap: var(--nf-space-6, 6px);
2187
+ font-size: var(--nf-fs-14, 13px);
1809
2188
  font-weight: 600;
1810
2189
  color: var(--nf-accent);
1811
2190
  }
1812
2191
 
1813
2192
  .dashHeroSparkle {
1814
- font-size: 14px;
2193
+ font-size: var(--nf-fs-14, 14px);
1815
2194
  }
1816
2195
 
1817
2196
  .dashHeroTitle {
1818
2197
  display: flex;
1819
2198
  flex-direction: column;
1820
- gap: 2px;
2199
+ gap: var(--nf-space-2, 2px);
1821
2200
  }
1822
2201
 
1823
2202
  .dashHeroBook {
1824
2203
  margin: 0;
1825
- font-size: 24px;
2204
+ font-size: var(--nf-fs-24, 24px);
1826
2205
  font-weight: 700;
1827
2206
  letter-spacing: -0.3px;
1828
2207
  line-height: 1.25;
@@ -1831,25 +2210,25 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1831
2210
  .dashHeroAction {
1832
2211
  display: flex;
1833
2212
  align-items: center;
1834
- gap: 12px;
2213
+ gap: var(--nf-space-12, 12px);
1835
2214
  border: 1px solid var(--nf-glass-border);
1836
- border-radius: 14px;
2215
+ border-radius: var(--nf-radius-14, 14px);
1837
2216
  background: var(--nf-glass-inset);
1838
2217
  box-shadow: inset 0 1px 0 var(--nf-glass-sheen);
1839
- padding: 10px 14px;
2218
+ padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
1840
2219
  }
1841
2220
 
1842
2221
  .dashHeroArrow {
1843
2222
  flex: none;
1844
2223
  width: 28px;
1845
- height: 28px;
2224
+ height: var(--nf-ctrl-s, 28px);
1846
2225
  border-radius: 50%;
1847
2226
  background: var(--nf-accent);
1848
2227
  color: #fff;
1849
2228
  display: inline-flex;
1850
2229
  align-items: center;
1851
2230
  justify-content: center;
1852
- font-size: 14px;
2231
+ font-size: var(--nf-fs-14, 14px);
1853
2232
  }
1854
2233
 
1855
2234
  .dashHeroActionBody {
@@ -1857,23 +2236,23 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1857
2236
  min-width: 0;
1858
2237
  display: flex;
1859
2238
  flex-direction: column;
1860
- gap: 2px;
2239
+ gap: var(--nf-space-2, 2px);
1861
2240
  }
1862
2241
 
1863
2242
  .dashHeroActionTitle {
1864
- font-size: 14px;
2243
+ font-size: var(--nf-fs-14, 14px);
1865
2244
  font-weight: 600;
1866
2245
  }
1867
2246
 
1868
2247
  .dashJourney {
1869
2248
  display: flex;
1870
2249
  flex-direction: column;
1871
- gap: 6px;
2250
+ gap: var(--nf-space-6, 6px);
1872
2251
  }
1873
2252
 
1874
2253
  .dashJourneyBar {
1875
2254
  height: 6px;
1876
- border-radius: 999px;
2255
+ border-radius: var(--nf-radius-999, 999px);
1877
2256
  background: var(--nf-border);
1878
2257
  overflow: hidden;
1879
2258
  }
@@ -1881,7 +2260,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1881
2260
  .dashJourneyFill {
1882
2261
  display: block;
1883
2262
  height: 100%;
1884
- border-radius: 999px;
2263
+ border-radius: var(--nf-radius-999, 999px);
1885
2264
  background: linear-gradient(90deg, var(--nf-info), var(--nf-accent));
1886
2265
  transition: width 0.4s ease;
1887
2266
  }
@@ -1889,15 +2268,15 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1889
2268
  .dashJourneyStages {
1890
2269
  display: grid;
1891
2270
  grid-template-columns: repeat(6, minmax(0, 1fr));
1892
- gap: 4px;
2271
+ gap: var(--nf-space-4, 4px);
1893
2272
  }
1894
2273
 
1895
2274
  .dashStage {
1896
2275
  display: flex;
1897
2276
  flex-direction: column;
1898
2277
  align-items: center;
1899
- gap: 3px;
1900
- font-size: 11px;
2278
+ gap: var(--nf-space-4, 3px);
2279
+ font-size: var(--nf-fs-12, 11px);
1901
2280
  color: var(--nf-text-3);
1902
2281
  text-align: center;
1903
2282
  white-space: nowrap;
@@ -1911,7 +2290,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1911
2290
  display: inline-flex;
1912
2291
  align-items: center;
1913
2292
  justify-content: center;
1914
- font-size: 10px;
2293
+ font-size: var(--nf-fs-12, 10px);
1915
2294
  background: var(--nf-bg-base);
1916
2295
  }
1917
2296
 
@@ -1939,20 +2318,20 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1939
2318
  .dashFacts {
1940
2319
  display: grid;
1941
2320
  grid-template-columns: repeat(4, minmax(0, 1fr));
1942
- gap: 8px;
2321
+ gap: var(--nf-space-8, 8px);
1943
2322
  border-top: 1px solid var(--nf-border);
1944
- padding-top: 12px;
2323
+ padding-top: var(--nf-space-12, 12px);
1945
2324
  }
1946
2325
 
1947
2326
  .dashFact {
1948
2327
  display: flex;
1949
2328
  flex-direction: column;
1950
- gap: 2px;
2329
+ gap: var(--nf-space-2, 2px);
1951
2330
  min-width: 0;
1952
2331
  }
1953
2332
 
1954
2333
  .dashFact b {
1955
- font-size: 13px;
2334
+ font-size: var(--nf-fs-14, 13px);
1956
2335
  white-space: nowrap;
1957
2336
  overflow: hidden;
1958
2337
  text-overflow: ellipsis;
@@ -1961,17 +2340,17 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1961
2340
  .dashGrid {
1962
2341
  display: grid;
1963
2342
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
1964
- gap: 14px;
2343
+ gap: var(--nf-space-14, 14px);
1965
2344
  align-items: start;
1966
2345
  }
1967
2346
 
1968
2347
  .todoItem {
1969
2348
  display: flex;
1970
2349
  align-items: center;
1971
- gap: 10px;
1972
- border-radius: 8px;
1973
- padding: 8px 12px;
1974
- font-size: 12.5px;
2350
+ gap: var(--nf-space-10, 10px);
2351
+ border-radius: var(--nf-radius-8, 8px);
2352
+ padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
2353
+ font-size: var(--nf-fs-12, 12.5px);
1975
2354
  border: 1px solid var(--nf-border);
1976
2355
  }
1977
2356
 
@@ -1995,17 +2374,17 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
1995
2374
  min-width: 0;
1996
2375
  display: flex;
1997
2376
  flex-direction: column;
1998
- gap: 2px;
2377
+ gap: var(--nf-space-2, 2px);
1999
2378
  }
2000
2379
 
2001
2380
  /* 只读大纲(开书后的出生证明) */
2002
2381
  .outlineReadonly {
2003
2382
  margin: 0;
2004
- padding: 12px 14px;
2383
+ padding: var(--nf-space-12, 12px) var(--nf-space-14, 14px);
2005
2384
  border: 1px solid var(--nf-border);
2006
- border-radius: 12px;
2385
+ border-radius: var(--nf-radius-12, 12px);
2007
2386
  background: var(--nf-bg-inset);
2008
- font-size: 12.5px;
2387
+ font-size: var(--nf-fs-12, 12.5px);
2009
2388
  line-height: 1.8;
2010
2389
  white-space: pre-wrap;
2011
2390
  max-height: 480px;
@@ -2017,7 +2396,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2017
2396
  .bookCreateOutline {
2018
2397
  display: flex;
2019
2398
  flex-direction: column;
2020
- gap: 6px;
2399
+ gap: var(--nf-space-6, 6px);
2021
2400
  align-items: flex-start;
2022
2401
  }
2023
2402
 
@@ -2028,7 +2407,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2028
2407
  display: flex;
2029
2408
  flex-direction: column;
2030
2409
  border: 1px solid var(--nf-border);
2031
- border-radius: 16px;
2410
+ border-radius: var(--nf-radius-16, 16px);
2032
2411
  background: var(--nf-bg-raise);
2033
2412
  -webkit-backdrop-filter: blur(24px) saturate(180%);
2034
2413
  backdrop-filter: blur(24px) saturate(180%);
@@ -2043,11 +2422,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2043
2422
  display: flex;
2044
2423
  align-items: center;
2045
2424
  justify-content: space-between;
2046
- gap: 8px;
2047
- padding: 8px 10px 8px 14px;
2425
+ gap: var(--nf-space-8, 8px);
2426
+ padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px) var(--nf-space-8, 8px) var(--nf-space-14, 14px);
2048
2427
  cursor: grab;
2049
2428
  user-select: none;
2050
- font-size: 13px;
2429
+ font-size: var(--nf-fs-14, 13px);
2051
2430
  font-weight: 600;
2052
2431
  border-bottom: 1px solid var(--nf-border);
2053
2432
  background: var(--nf-bg-inset);
@@ -2062,7 +2441,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2062
2441
  min-height: 0;
2063
2442
  overflow: hidden;
2064
2443
  display: flex;
2065
- padding: 10px;
2444
+ padding: var(--nf-space-10, 10px);
2066
2445
  }
2067
2446
 
2068
2447
  .assistantFloatBody > * {
@@ -2087,7 +2466,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2087
2466
  width: 150px;
2088
2467
  height: 200px;
2089
2468
  border: 1px solid var(--nf-border);
2090
- border-radius: 12px;
2469
+ border-radius: var(--nf-radius-12, 12px);
2091
2470
  overflow: hidden;
2092
2471
  background: var(--nf-bg-inset);
2093
2472
  display: flex;
@@ -2103,7 +2482,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2103
2482
  }
2104
2483
 
2105
2484
  .coverPlaceholder {
2106
- font-size: 12px;
2485
+ font-size: var(--nf-fs-12, 12px);
2107
2486
  color: var(--nf-text-3);
2108
2487
  }
2109
2488
 
@@ -2113,29 +2492,47 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2113
2492
  flex: 1;
2114
2493
  min-height: 0;
2115
2494
  overflow: auto;
2116
- padding: 18px;
2495
+ padding: var(--nf-container-pad, 20px 22px);
2117
2496
  display: flex;
2118
2497
  flex-direction: column;
2119
- gap: 16px;
2498
+ gap: var(--nf-container-gap, 14px);
2120
2499
  }
2121
2500
 
2122
2501
  .shelfHeader {
2123
2502
  display: flex;
2124
2503
  flex-direction: column;
2125
- gap: 10px;
2504
+ gap: var(--nf-space-10, 10px);
2505
+ }
2506
+
2507
+ /* 书架顶部主容器:加高玻璃卡 */
2508
+ .shelfHero {
2509
+ display: flex;
2510
+ flex-direction: column;
2511
+ gap: var(--nf-space-14, 14px);
2512
+ padding: var(--nf-card-pad, 20px 22px);
2513
+ border: 1px solid var(--nf-glass-border);
2514
+ border-radius: var(--nf-radius-22, 22px);
2515
+ background: var(--nf-glass-face);
2516
+ box-shadow: var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);
2517
+ }
2518
+
2519
+ .shelfHero .panelTitle {
2520
+ font-size: var(--nf-fs-22, 22px);
2521
+ letter-spacing: 0.3px;
2126
2522
  }
2127
2523
 
2128
2524
  .shelfTitleRow {
2129
2525
  display: flex;
2130
- align-items: baseline;
2131
- gap: 10px;
2526
+ align-items: center;
2527
+ justify-content: space-between;
2528
+ gap: var(--nf-space-10, 10px);
2132
2529
  flex-wrap: wrap;
2133
2530
  }
2134
2531
 
2135
2532
  .shelfToolbar {
2136
2533
  display: flex;
2137
2534
  align-items: center;
2138
- gap: 10px;
2535
+ gap: var(--nf-space-10, 10px);
2139
2536
  flex-wrap: wrap;
2140
2537
  }
2141
2538
 
@@ -2145,10 +2542,91 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2145
2542
  max-width: 320px;
2146
2543
  }
2147
2544
 
2148
- .shelfFilters {
2545
+ .shelfStats {
2546
+ display: grid;
2547
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
2548
+ gap: var(--nf-space-10, 10px);
2549
+ }
2550
+
2551
+ .shelfStat {
2149
2552
  display: flex;
2150
- gap: 6px;
2151
- flex-wrap: wrap;
2553
+ align-items: baseline;
2554
+ justify-content: space-between;
2555
+ gap: var(--nf-space-8, 8px);
2556
+ padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
2557
+ border: 1px solid var(--nf-glass-border);
2558
+ border-radius: var(--nf-radius-14, 14px);
2559
+ background: var(--nf-glass-face);
2560
+ box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
2561
+ cursor: pointer;
2562
+ user-select: none;
2563
+ transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
2564
+ }
2565
+
2566
+ .shelfStat:hover {
2567
+ border-color: var(--nf-accent);
2568
+ transform: translateY(-1px);
2569
+ }
2570
+
2571
+ .shelfStatActive {
2572
+ border-color: var(--nf-accent);
2573
+ background: var(--nf-accent-soft);
2574
+ box-shadow: 0 0 0 2px var(--nf-accent-soft), var(--nf-shadow);
2575
+ }
2576
+
2577
+ .shelfStat b {
2578
+ font-size: var(--nf-fs-20, 20px);
2579
+ font-weight: 800;
2580
+ color: var(--nf-accent);
2581
+ }
2582
+
2583
+ .shelfStat span {
2584
+ font-size: var(--nf-fs-12, 12px);
2585
+ color: var(--nf-text-2);
2586
+ }
2587
+
2588
+ /* 筛选:胶囊分段控件 */
2589
+ .shelfFilters {
2590
+ display: inline-flex;
2591
+ gap: var(--nf-space-2, 2px);
2592
+ padding: var(--nf-space-4, 3px);
2593
+ border: 1px solid var(--nf-border);
2594
+ border-radius: var(--nf-radius-999, 999px);
2595
+ background: var(--nf-bg-inset);
2596
+ }
2597
+
2598
+ .shelfFilter {
2599
+ border: none;
2600
+ background: transparent;
2601
+ color: var(--nf-text-2);
2602
+ font-size: var(--nf-fs-12, 12.5px);
2603
+ font-weight: 600;
2604
+ padding: var(--nf-space-6, 5px) var(--nf-space-12, 12px);
2605
+ border-radius: var(--nf-radius-999, 999px);
2606
+ cursor: pointer;
2607
+ display: inline-flex;
2608
+ align-items: center;
2609
+ gap: var(--nf-space-6, 5px);
2610
+ white-space: nowrap;
2611
+ transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
2612
+ }
2613
+
2614
+ .shelfFilter:hover {
2615
+ color: var(--nf-text);
2616
+ }
2617
+
2618
+ .shelfFilterActive {
2619
+ background: linear-gradient(135deg, var(--nf-accent), var(--nf-accent-hover));
2620
+ color: var(--nf-accent-fg);
2621
+ box-shadow: 0 3px 12px color-mix(in srgb, var(--nf-accent) 40%, transparent);
2622
+ }
2623
+
2624
+ .shelfFilterCount {
2625
+ font-size: var(--nf-fs-12, 10.5px);
2626
+ opacity: 0.8;
2627
+ background: color-mix(in srgb, currentColor 14%, transparent);
2628
+ border-radius: var(--nf-radius-999, 999px);
2629
+ padding: 0 var(--nf-space-6, 6px);
2152
2630
  }
2153
2631
 
2154
2632
  /* 书架空态 / 无结果引导卡 */
@@ -2158,10 +2636,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2158
2636
  flex-direction: column;
2159
2637
  align-items: center;
2160
2638
  justify-content: center;
2161
- gap: 10px;
2162
- padding: 40px 20px;
2639
+ gap: var(--nf-space-10, 10px);
2640
+ padding: var(--nf-space-40, 40px) var(--nf-space-20, 20px);
2163
2641
  border: 1px dashed var(--nf-border-strong);
2164
- border-radius: 16px;
2642
+ border-radius: var(--nf-radius-16, 16px);
2165
2643
  background: var(--nf-bg-raise);
2166
2644
  -webkit-backdrop-filter: blur(24px) saturate(180%);
2167
2645
  backdrop-filter: blur(24px) saturate(180%);
@@ -2169,28 +2647,206 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2169
2647
  }
2170
2648
 
2171
2649
  .shelfEmptyIcon {
2172
- font-size: 42px;
2650
+ font-size: var(--nf-fs-42, 42px);
2173
2651
  }
2174
2652
 
2175
2653
  .shelfEmptyTitle {
2176
- font-size: 16px;
2654
+ font-size: var(--nf-fs-16, 16px);
2177
2655
  font-weight: 700;
2178
2656
  }
2179
2657
 
2180
2658
  .shelfGrid {
2181
2659
  display: grid;
2182
2660
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
2183
- gap: 14px;
2661
+ gap: var(--nf-container-gap, 14px);
2184
2662
  align-content: start;
2185
2663
  }
2186
2664
 
2665
+ /* ------------------------------------------------------------
2666
+ * 外观设置扩展:强制显示模式 + 界面密度 + 主题暗色覆盖
2667
+ * ------------------------------------------------------------ */
2668
+ /* 界面密度:唯一允许重定义尺寸的开关(主题永不触碰这些令牌)。
2669
+ * comfort = 设置页主容器基准;compact/spacious 只缩放令牌,不改组件。 */
2670
+ .panel {
2671
+ --nf-container-pad: 20px 22px;
2672
+ --nf-container-gap: var(--nf-space-14, 14px);
2673
+ --nf-card-pad: 20px 22px;
2674
+ --nf-nav-pad: 16px 12px 14px;
2675
+ }
2676
+
2677
+ .panel[data-nf-density='compact'] {
2678
+ --nf-container-pad: 12px 14px;
2679
+ --nf-container-gap: var(--nf-space-8, 8px);
2680
+ --nf-card-pad: 12px 14px;
2681
+ --nf-nav-pad: 8px 8px;
2682
+ }
2683
+
2684
+ .panel[data-nf-density='spacious'] {
2685
+ --nf-container-pad: 24px 28px;
2686
+ --nf-container-gap: var(--nf-space-18, 18px);
2687
+ --nf-card-pad: 22px 26px;
2688
+ --nf-nav-pad: 18px 14px;
2689
+ }
2690
+
2691
+ /* 强制浅色(不跟随系统时覆盖 .view 的明暗变量) */
2692
+ .panel[data-nf-mode='light'] {
2693
+ color-scheme: light;
2694
+ --nf-bg: rgba(242, 242, 247, 0.86);
2695
+ --nf-bg-raise: rgba(255, 255, 255, 0.72);
2696
+ --nf-bg-inset: rgba(118, 118, 128, 0.12);
2697
+ --nf-border: rgba(60, 60, 67, 0.16);
2698
+ --nf-border-strong: rgba(60, 60, 67, 0.32);
2699
+ --nf-text: #1c1c1e;
2700
+ --nf-text-2: #3c3c43;
2701
+ --nf-text-2-alpha: rgba(60, 60, 67, 0.68);
2702
+ --nf-text-3: #8e8e93;
2703
+ --nf-accent: #00b85c;
2704
+ --nf-accent-hover: #00a04e;
2705
+ --nf-accent-soft: rgba(0, 184, 92, 0.12);
2706
+ --nf-accent-fg: #ffffff;
2707
+ --nf-hover: rgba(0, 0, 0, 0.05);
2708
+ --nf-success: #34c759;
2709
+ --nf-error: #ff3b30;
2710
+ --nf-warn: #ff9500;
2711
+ --nf-info: #00b85c;
2712
+ --nf-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 12px 32px rgba(0, 0, 0, 0.08);
2713
+ --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.07), 0 20px 48px rgba(0, 0, 0, 0.12);
2714
+ --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.06), 0 14px 38px rgba(0, 0, 0, 0.14);
2715
+ --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.08), 0 22px 52px rgba(0, 0, 0, 0.20);
2716
+ --nf-glass-face: linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);
2717
+ --nf-glass-core: radial-gradient(30% 24% at 36% 28%, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.22) 45%, rgba(255, 255, 255, 0) 78%);
2718
+ --nf-glass-sheen: rgba(255, 255, 255, 0.55);
2719
+ --nf-glass-border: rgba(255, 255, 255, 0.65);
2720
+ --nf-glass-inset: rgba(255, 255, 255, 0.55);
2721
+ --nf-glass-orb-a: rgba(0, 184, 92, 0.18);
2722
+ --nf-glass-orb-b: rgba(120, 160, 255, 0.13);
2723
+ }
2724
+
2725
+ /* 强制深色 */
2726
+ .panel[data-nf-mode='dark'] {
2727
+ color-scheme: dark;
2728
+ --nf-bg: rgba(10, 11, 13, 0.86);
2729
+ --nf-bg-raise: rgba(28, 28, 30, 0.78);
2730
+ --nf-bg-inset: rgba(118, 118, 128, 0.18);
2731
+ --nf-border: rgba(255, 255, 255, 0.12);
2732
+ --nf-border-strong: rgba(255, 255, 255, 0.28);
2733
+ --nf-text: #f2f2f7;
2734
+ --nf-text-2: #d1d1d6;
2735
+ --nf-text-2-alpha: rgba(209, 209, 214, 0.72);
2736
+ --nf-text-3: #8e8e93;
2737
+ --nf-accent: #35d07a;
2738
+ --nf-accent-hover: #5ce695;
2739
+ --nf-accent-soft: rgba(53, 208, 122, 0.2);
2740
+ --nf-accent-fg: #062b18;
2741
+ --nf-hover: rgba(255, 255, 255, 0.09);
2742
+ --nf-success: #30d158;
2743
+ --nf-error: #ff453a;
2744
+ --nf-warn: #ff9f0a;
2745
+ --nf-info: #35d07a;
2746
+ --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px rgba(0, 0, 0, 0.4);
2747
+ --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.4), 0 20px 48px rgba(0, 0, 0, 0.55);
2748
+ --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 14px 38px rgba(0, 0, 0, 0.45);
2749
+ --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.4), 0 22px 52px rgba(0, 0, 0, 0.55);
2750
+ --nf-glass-face: linear-gradient(180deg, rgba(112, 116, 122, 0.42) 0%, rgba(96, 100, 106, 0.42) 26%, rgba(82, 85, 90, 0.42) 52%, rgba(68, 71, 76, 0.42) 78%, rgba(56, 58, 63, 0.42) 100%);
2751
+ --nf-glass-core: radial-gradient(30% 24% at 36% 28%, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0.10) 45%, rgba(255, 255, 255, 0) 78%);
2752
+ --nf-glass-sheen: rgba(255, 255, 255, 0.26);
2753
+ --nf-glass-border: rgba(255, 255, 255, 0.14);
2754
+ --nf-glass-inset: rgba(255, 255, 255, 0.07);
2755
+ --nf-glass-orb-a: rgba(0, 202, 82, 0.28);
2756
+ --nf-glass-orb-b: rgba(190, 200, 215, 0.10);
2757
+ }
2758
+
2759
+ /* 强制深色时:新拟物 的暗色变体 */
2760
+
2761
+ .panel[data-nf-mode='dark'][data-nf-theme='macos'] {
2762
+ --nf-bg: rgba(28, 28, 30, 0.9);
2763
+ --nf-bg-raise: rgba(44, 44, 46, 0.82);
2764
+ --nf-bg-inset: rgba(118, 118, 128, 0.18);
2765
+ --nf-border: rgba(255, 255, 255, 0.12);
2766
+ --nf-border-strong: rgba(255, 255, 255, 0.26);
2767
+ --nf-text: #f5f5f7;
2768
+ --nf-text-2: #d1d1d6;
2769
+ --nf-text-2-alpha: rgba(209, 209, 214, 0.7);
2770
+ --nf-text-3: #98989d;
2771
+ --nf-accent: #0a84ff;
2772
+ --nf-accent-hover: #3a9bff;
2773
+ --nf-accent-soft: rgba(10, 132, 255, 0.2);
2774
+ --nf-accent-fg: #ffffff;
2775
+ --nf-hover: rgba(255, 255, 255, 0.06);
2776
+ --nf-info: #bf5af2;
2777
+ --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.45);
2778
+ --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45), 0 18px 44px rgba(0, 0, 0, 0.6);
2779
+ --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.4), 0 14px 38px rgba(0, 0, 0, 0.5);
2780
+ --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.45), 0 22px 52px rgba(0, 0, 0, 0.6);
2781
+ --nf-glass-face: rgba(44, 44, 46, 0.85);
2782
+ --nf-glass-core: transparent;
2783
+ --nf-glass-sheen: rgba(255, 255, 255, 0.2);
2784
+ --nf-glass-border: rgba(255, 255, 255, 0.18);
2785
+ --nf-glass-inset: rgba(255, 255, 255, 0.06);
2786
+ --nf-glass-orb-a: rgba(10, 132, 255, 0.16);
2787
+ --nf-glass-orb-b: rgba(191, 90, 242, 0.08);
2788
+ --nf-glass-noise: none;
2789
+ }
2790
+
2791
+ .panel[data-nf-mode='dark'][data-nf-theme='neumorph'] {
2792
+ --nf-bg: #2b2f36;
2793
+ --nf-bg-raise: #2b2f36;
2794
+ --nf-bg-inset: #25292f;
2795
+ --nf-border: rgba(10, 12, 16, 0.5);
2796
+ --nf-border-strong: rgba(8, 10, 14, 0.6);
2797
+ --nf-text: #d6dae1;
2798
+ --nf-text-2: #a8aeb8;
2799
+ --nf-text-2-alpha: rgba(168, 174, 184, 0.7);
2800
+ --nf-text-3: #757c88;
2801
+ --nf-hover: rgba(255, 255, 255, 0.05);
2802
+ --nf-shadow: 4px 4px 10px rgba(0, 0, 0, 0.5), -4px -4px 10px rgba(96, 104, 118, 0.24);
2803
+ --nf-shadow-lg: 6px 6px 14px rgba(0, 0, 0, 0.55), -6px -6px 14px rgba(96, 104, 118, 0.26);
2804
+ --nf-card-shadow: 9px 9px 18px rgba(0, 0, 0, 0.5), -9px -9px 18px rgba(96, 104, 118, 0.24);
2805
+ --nf-card-shadow-hover: 12px 12px 24px rgba(0, 0, 0, 0.6), -12px -12px 24px rgba(96, 104, 118, 0.28);
2806
+ --nf-glass-face: #2b2f36;
2807
+ --nf-glass-core: transparent;
2808
+ --nf-glass-sheen: rgba(255, 255, 255, 0);
2809
+ --nf-glass-border: rgba(12, 14, 18, 0.45);
2810
+ --nf-glass-inset: #25292f;
2811
+ --nf-glass-orb-a: transparent;
2812
+ --nf-glass-orb-b: transparent;
2813
+ --nf-glass-noise: none;
2814
+ }
2815
+
2816
+ /* 强制浅色时:新拟物 的浅色变体(深色系统下也能用) */
2817
+ .panel[data-nf-mode='light'][data-nf-theme='neumorph'] {
2818
+ --nf-bg: #e4e9f2;
2819
+ --nf-bg-raise: #e4e9f2;
2820
+ --nf-bg-inset: #d9dfe8;
2821
+ --nf-border: rgba(140, 155, 175, 0.35);
2822
+ --nf-border-strong: rgba(120, 135, 158, 0.5);
2823
+ --nf-text: #3a4250;
2824
+ --nf-text-2: #5b6472;
2825
+ --nf-text-2-alpha: rgba(70, 80, 96, 0.7);
2826
+ --nf-text-3: #8b94a3;
2827
+ --nf-hover: rgba(90, 105, 125, 0.08);
2828
+ --nf-shadow: 4px 4px 10px rgba(163, 177, 198, 0.55), -4px -4px 10px rgba(255, 255, 255, 0.85);
2829
+ --nf-shadow-lg: 6px 6px 14px rgba(163, 177, 198, 0.6), -6px -6px 14px rgba(255, 255, 255, 0.9);
2830
+ --nf-card-shadow: 9px 9px 18px rgba(163, 177, 198, 0.55), -9px -9px 18px rgba(255, 255, 255, 0.85);
2831
+ --nf-card-shadow-hover: 12px 12px 24px rgba(163, 177, 198, 0.65), -12px -12px 24px rgba(255, 255, 255, 0.95);
2832
+ --nf-glass-face: #e4e9f2;
2833
+ --nf-glass-core: transparent;
2834
+ --nf-glass-sheen: rgba(255, 255, 255, 0);
2835
+ --nf-glass-border: rgba(163, 177, 198, 0.4);
2836
+ --nf-glass-inset: #d9dfe8;
2837
+ --nf-glass-orb-a: transparent;
2838
+ --nf-glass-orb-b: transparent;
2839
+ --nf-glass-noise: none;
2840
+ }
2841
+
2842
+
2187
2843
  .bookCard {
2188
2844
  display: flex;
2189
2845
  flex-direction: column;
2190
- gap: 8px;
2846
+ gap: var(--nf-space-8, 8px);
2191
2847
  border: 1px solid var(--nf-border);
2192
- border-radius: 16px;
2193
- padding: 12px;
2848
+ border-radius: var(--nf-radius-16, 16px);
2849
+ padding: var(--nf-space-12, 12px);
2194
2850
  background: var(--nf-bg-raise);
2195
2851
  -webkit-backdrop-filter: blur(24px) saturate(180%);
2196
2852
  backdrop-filter: blur(24px) saturate(180%);
@@ -2213,20 +2869,42 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2213
2869
  .bookCardCover {
2214
2870
  flex: none;
2215
2871
  aspect-ratio: 3 / 4;
2216
- border-radius: 12px;
2872
+ border-radius: var(--nf-radius-12, 12px);
2217
2873
  overflow: hidden;
2218
2874
  background: var(--nf-bg-inset);
2219
2875
  border: 1px solid var(--nf-border);
2220
2876
  display: flex;
2221
2877
  align-items: center;
2222
2878
  justify-content: center;
2879
+ position: relative;
2223
2880
  }
2224
2881
 
2225
2882
  .bookCardCover img {
2226
2883
  width: 100%;
2227
2884
  height: 100%;
2228
- object-fit: contain;
2885
+ object-fit: cover;
2229
2886
  display: block;
2887
+ transition: transform 0.35s ease;
2888
+ }
2889
+
2890
+ .bookCard:hover .bookCardCover img {
2891
+ transform: scale(1.06);
2892
+ }
2893
+
2894
+ /* 封面底部渐暗(hover 出现,突出书名区) */
2895
+ .bookCardCover::after {
2896
+ content: '';
2897
+ position: absolute;
2898
+ inset: 0;
2899
+ border-radius: inherit;
2900
+ pointer-events: none;
2901
+ background: linear-gradient(180deg, transparent 55%, rgba(0, 0, 0, 0.28));
2902
+ opacity: 0;
2903
+ transition: opacity 0.25s ease;
2904
+ }
2905
+
2906
+ .bookCard:hover .bookCardCover::after {
2907
+ opacity: 1;
2230
2908
  }
2231
2909
 
2232
2910
  .bookCardCoverFallback {
@@ -2234,7 +2912,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2234
2912
  flex-direction: column;
2235
2913
  align-items: center;
2236
2914
  justify-content: center;
2237
- gap: 6px;
2915
+ gap: var(--nf-space-6, 6px);
2238
2916
  width: 100%;
2239
2917
  height: 100%;
2240
2918
  background:
@@ -2243,7 +2921,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2243
2921
  }
2244
2922
 
2245
2923
  .bookCardCoverTitle {
2246
- font-size: 22px;
2924
+ font-size: var(--nf-fs-22, 22px);
2247
2925
  font-weight: 800;
2248
2926
  color: var(--nf-accent);
2249
2927
  letter-spacing: 2px;
@@ -2252,20 +2930,21 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2252
2930
  .bookCardBody {
2253
2931
  display: flex;
2254
2932
  flex-direction: column;
2255
- gap: 5px;
2933
+ gap: var(--nf-space-6, 5px);
2256
2934
  min-width: 0;
2935
+ flex: 1;
2257
2936
  }
2258
2937
 
2259
2938
  .bookCardTitleRow {
2260
2939
  display: flex;
2261
2940
  align-items: center;
2262
2941
  justify-content: space-between;
2263
- gap: 6px;
2942
+ gap: var(--nf-space-6, 6px);
2264
2943
  }
2265
2944
 
2266
2945
  .bookCardName {
2267
2946
  font-weight: 700;
2268
- font-size: 13.5px;
2947
+ font-size: var(--nf-fs-14, 13.5px);
2269
2948
  overflow: hidden;
2270
2949
  text-overflow: ellipsis;
2271
2950
  white-space: nowrap;
@@ -2283,21 +2962,22 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2283
2962
  display: flex;
2284
2963
  align-items: center;
2285
2964
  justify-content: space-between;
2286
- gap: 6px;
2965
+ gap: var(--nf-space-6, 6px);
2287
2966
  flex-wrap: wrap;
2288
2967
  }
2289
2968
 
2290
2969
  .bookCardProgressBar {
2291
- height: 5px;
2292
- border-radius: 999px;
2970
+ height: 6px;
2971
+ border-radius: var(--nf-radius-999, 999px);
2293
2972
  background: var(--nf-border);
2294
2973
  overflow: hidden;
2974
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
2295
2975
  }
2296
2976
 
2297
2977
  .bookCardProgressFill {
2298
2978
  display: block;
2299
2979
  height: 100%;
2300
- border-radius: 999px;
2980
+ border-radius: var(--nf-radius-999, 999px);
2301
2981
  background: linear-gradient(90deg, var(--nf-info), var(--nf-accent));
2302
2982
  transition: width 0.3s ease;
2303
2983
  }
@@ -2305,21 +2985,30 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2305
2985
  .bookAddCard {
2306
2986
  align-items: center;
2307
2987
  justify-content: center;
2308
- gap: 8px;
2988
+ gap: var(--nf-space-8, 8px);
2309
2989
  text-align: center;
2310
2990
  border-style: dashed;
2311
2991
  color: var(--nf-text-2);
2312
2992
  min-height: 260px;
2993
+ transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease, transform 0.15s ease;
2313
2994
  }
2314
2995
 
2315
2996
  .bookAddCard:hover {
2997
+ border-color: var(--nf-accent);
2998
+ background: var(--nf-accent-soft);
2316
2999
  color: var(--nf-accent);
3000
+ transform: translateY(-2px);
2317
3001
  }
2318
3002
 
2319
3003
  .bookAddIcon {
2320
- font-size: 34px;
3004
+ font-size: var(--nf-fs-34, 34px);
2321
3005
  line-height: 1;
2322
3006
  color: var(--nf-accent);
3007
+ transition: transform 0.15s ease;
3008
+ }
3009
+
3010
+ .bookAddCard:hover .bookAddIcon {
3011
+ transform: scale(1.12);
2323
3012
  }
2324
3013
 
2325
3014
  .bookCreateCard {
@@ -2333,10 +3022,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2333
3022
  flex: 1;
2334
3023
  min-height: 0;
2335
3024
  overflow: auto;
2336
- padding: 14px 18px 24px;
3025
+ /* 主容器统一:与工作台/书架/设置页同一令牌 */
3026
+ padding: var(--nf-container-pad, 20px 22px);
2337
3027
  display: flex;
2338
3028
  flex-direction: column;
2339
- gap: 14px;
3029
+ gap: var(--nf-container-gap, 14px);
2340
3030
  }
2341
3031
 
2342
3032
  .createBookTop {
@@ -2349,10 +3039,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2349
3039
  width: min(520px, 100%);
2350
3040
  display: flex;
2351
3041
  flex-direction: column;
2352
- gap: 12px;
3042
+ gap: var(--nf-space-12, 12px);
2353
3043
  border: 1px solid var(--nf-border);
2354
- border-radius: 20px;
2355
- padding: 26px 28px;
3044
+ border-radius: var(--nf-radius-20, 20px);
3045
+ /* 主容器统一:与设置页卡片同一 --nf-card-pad */
3046
+ padding: var(--nf-card-pad, 20px 22px);
2356
3047
  background: var(--nf-bg-raise);
2357
3048
  -webkit-backdrop-filter: blur(24px) saturate(180%);
2358
3049
  backdrop-filter: blur(24px) saturate(180%);
@@ -2360,13 +3051,13 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2360
3051
  }
2361
3052
 
2362
3053
  .createBookIcon {
2363
- font-size: 34px;
3054
+ font-size: var(--nf-fs-34, 34px);
2364
3055
  line-height: 1;
2365
3056
  }
2366
3057
 
2367
3058
  .createBookTitle {
2368
3059
  margin: 0;
2369
- font-size: 22px;
3060
+ font-size: var(--nf-fs-22, 22px);
2370
3061
  font-weight: 800;
2371
3062
  letter-spacing: -0.3px;
2372
3063
  }
@@ -2375,21 +3066,21 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2375
3066
  .ideaCard {
2376
3067
  display: flex;
2377
3068
  flex-direction: column;
2378
- gap: 8px;
3069
+ gap: var(--nf-space-8, 8px);
2379
3070
  border: 1px dashed var(--nf-border-strong);
2380
- border-radius: 14px;
2381
- padding: 10px 12px;
3071
+ border-radius: var(--nf-radius-14, 14px);
3072
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
2382
3073
  background: color-mix(in srgb, var(--nf-accent) 3%, transparent);
2383
3074
  }
2384
3075
 
2385
3076
  .ideaToggle {
2386
3077
  display: flex;
2387
3078
  align-items: center;
2388
- gap: 6px;
3079
+ gap: var(--nf-space-6, 6px);
2389
3080
  border: none;
2390
3081
  background: none;
2391
3082
  color: var(--nf-accent);
2392
- font-size: 13px;
3083
+ font-size: var(--nf-fs-14, 13px);
2393
3084
  font-weight: 700;
2394
3085
  cursor: pointer;
2395
3086
  text-align: left;
@@ -2399,10 +3090,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2399
3090
  .ideaCandidate {
2400
3091
  display: flex;
2401
3092
  flex-direction: column;
2402
- gap: 6px;
3093
+ gap: var(--nf-space-6, 6px);
2403
3094
  border: 1px solid var(--nf-border);
2404
- border-radius: 12px;
2405
- padding: 10px 12px;
3095
+ border-radius: var(--nf-radius-12, 12px);
3096
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
2406
3097
  background: var(--nf-bg);
2407
3098
  }
2408
3099
 
@@ -2419,7 +3110,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2419
3110
  /* ------------------------------------------------------------ misc */
2420
3111
 
2421
3112
  .meta {
2422
- font-size: 12px;
3113
+ font-size: var(--nf-fs-12, 12px);
2423
3114
  color: var(--nf-text-2);
2424
3115
  opacity: 0.9;
2425
3116
  }
@@ -2436,8 +3127,8 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2436
3127
  .fileList {
2437
3128
  display: flex;
2438
3129
  flex-direction: column;
2439
- gap: 3px;
2440
- font-size: 12px;
3130
+ gap: var(--nf-space-4, 3px);
3131
+ font-size: var(--nf-fs-12, 12px);
2441
3132
  color: var(--nf-text-2);
2442
3133
  opacity: 0.9;
2443
3134
  word-break: break-all;
@@ -2459,7 +3150,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2459
3150
  .progress::-webkit-scrollbar-thumb,
2460
3151
  .toolLive::-webkit-scrollbar-thumb {
2461
3152
  background: var(--nf-border-strong);
2462
- border-radius: 4px;
3153
+ border-radius: var(--nf-radius-4, 4px);
2463
3154
  }
2464
3155
 
2465
3156
  .panelContent::-webkit-scrollbar-thumb:hover,
@@ -2480,8 +3171,8 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2480
3171
  .workflowRow {
2481
3172
  display: flex;
2482
3173
  align-items: flex-start;
2483
- gap: 12px;
2484
- padding: 8px 4px;
3174
+ gap: var(--nf-space-12, 12px);
3175
+ padding: var(--nf-space-8, 8px) var(--nf-space-4, 4px);
2485
3176
  position: relative;
2486
3177
  }
2487
3178
 
@@ -2501,12 +3192,12 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2501
3192
 
2502
3193
  .workflowDot {
2503
3194
  width: 28px;
2504
- height: 28px;
3195
+ height: var(--nf-ctrl-s, 28px);
2505
3196
  border-radius: 50%;
2506
3197
  display: inline-flex;
2507
3198
  align-items: center;
2508
3199
  justify-content: center;
2509
- font-size: 12px;
3200
+ font-size: var(--nf-fs-12, 12px);
2510
3201
  font-weight: 700;
2511
3202
  flex-shrink: 0;
2512
3203
  border: 2px solid var(--nf-border-strong);
@@ -2533,18 +3224,18 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2533
3224
  min-width: 0;
2534
3225
  display: flex;
2535
3226
  flex-direction: column;
2536
- gap: 4px;
2537
- padding-top: 2px;
3227
+ gap: var(--nf-space-4, 4px);
3228
+ padding-top: var(--nf-space-2, 2px);
2538
3229
  }
2539
3230
 
2540
3231
  .workflowLabel {
2541
- font-size: 13px;
3232
+ font-size: var(--nf-fs-14, 13px);
2542
3233
  font-weight: 600;
2543
3234
  color: var(--nf-text);
2544
3235
  }
2545
3236
 
2546
3237
  .workflowHint {
2547
- font-size: 12px;
3238
+ font-size: var(--nf-fs-12, 12px);
2548
3239
  color: var(--nf-text-2);
2549
3240
  }
2550
3241
 
@@ -2567,11 +3258,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2567
3258
  .bookshelf {
2568
3259
  display: flex;
2569
3260
  align-items: center;
2570
- gap: 10px;
3261
+ gap: var(--nf-space-10, 10px);
2571
3262
  margin: 10px 12px 0;
2572
- padding: 8px 14px;
3263
+ padding: var(--nf-space-8, 8px) var(--nf-space-14, 14px);
2573
3264
  border: 1px solid var(--nf-glass-border);
2574
- border-radius: 16px;
3265
+ border-radius: var(--nf-radius-16, 16px);
2575
3266
  background: var(--nf-glass-face);
2576
3267
  box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
2577
3268
  -webkit-backdrop-filter: blur(26px) saturate(175%);
@@ -2583,7 +3274,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2583
3274
  }
2584
3275
 
2585
3276
  .bookshelfLabel {
2586
- font-size: 12px;
3277
+ font-size: var(--nf-fs-12, 12px);
2587
3278
  font-weight: 700;
2588
3279
  color: var(--nf-text-3);
2589
3280
  letter-spacing: 1px;
@@ -2593,7 +3284,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2593
3284
  .bookshelfList {
2594
3285
  display: flex;
2595
3286
  align-items: center;
2596
- gap: 6px;
3287
+ gap: var(--nf-space-6, 6px);
2597
3288
  flex-wrap: wrap;
2598
3289
  flex: 1;
2599
3290
  min-width: 0;
@@ -2602,13 +3293,13 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2602
3293
  .bookChip {
2603
3294
  display: flex;
2604
3295
  align-items: center;
2605
- gap: 6px;
2606
- padding: 4px 8px 4px 10px;
3296
+ gap: var(--nf-space-6, 6px);
3297
+ padding: var(--nf-space-4, 4px) var(--nf-space-8, 8px) var(--nf-space-4, 4px) var(--nf-space-10, 10px);
2607
3298
  border: 1px solid var(--nf-border);
2608
- border-radius: 999px;
3299
+ border-radius: var(--nf-radius-999, 999px);
2609
3300
  background: var(--nf-bg-inset);
2610
3301
  cursor: pointer;
2611
- font-size: 12px;
3302
+ font-size: var(--nf-fs-12, 12px);
2612
3303
  transition: border-color 0.15s ease, background 0.15s ease;
2613
3304
  max-width: 220px;
2614
3305
  }
@@ -2631,7 +3322,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2631
3322
  }
2632
3323
 
2633
3324
  .bookChipMeta {
2634
- font-size: 11px;
3325
+ font-size: var(--nf-fs-12, 11px);
2635
3326
  opacity: 0.7;
2636
3327
  white-space: nowrap;
2637
3328
  }
@@ -2641,10 +3332,10 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2641
3332
  background: transparent;
2642
3333
  color: var(--nf-text-3);
2643
3334
  cursor: pointer;
2644
- font-size: 13px;
3335
+ font-size: var(--nf-fs-14, 13px);
2645
3336
  line-height: 1;
2646
- padding: 0 2px;
2647
- border-radius: 4px;
3337
+ padding: 0 var(--nf-space-2, 2px);
3338
+ border-radius: var(--nf-radius-4, 4px);
2648
3339
  }
2649
3340
 
2650
3341
  .bookChipRemove:hover {
@@ -2656,9 +3347,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2656
3347
  background: transparent;
2657
3348
  color: var(--nf-text-2);
2658
3349
  cursor: pointer;
2659
- font-size: 12px;
2660
- padding: 4px 12px;
2661
- border-radius: 999px;
3350
+ font-size: var(--nf-fs-12, 12px);
3351
+ padding: var(--nf-space-4, 4px) var(--nf-space-12, 12px);
3352
+ border-radius: var(--nf-radius-999, 999px);
2662
3353
  transition: border-color 0.15s ease, color 0.15s ease;
2663
3354
  }
2664
3355
 
@@ -2670,24 +3361,24 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2670
3361
  .bookCreateForm {
2671
3362
  display: flex;
2672
3363
  align-items: center;
2673
- gap: 6px;
3364
+ gap: var(--nf-space-6, 6px);
2674
3365
  }
2675
3366
 
2676
3367
  /* ------------------------------------------------------------ dropzone */
2677
3368
 
2678
3369
  .dropzone {
2679
3370
  border: 2px dashed var(--nf-border-strong);
2680
- border-radius: 10px;
2681
- padding: 18px 14px;
3371
+ border-radius: var(--nf-radius-10, 10px);
3372
+ padding: var(--nf-space-18, 18px) var(--nf-space-14, 14px);
2682
3373
  text-align: center;
2683
- font-size: 13px;
3374
+ font-size: var(--nf-fs-14, 13px);
2684
3375
  color: var(--nf-text-2);
2685
3376
  cursor: pointer;
2686
3377
  transition: border-color 0.15s ease, background 0.15s ease;
2687
3378
  display: flex;
2688
3379
  flex-direction: column;
2689
3380
  align-items: center;
2690
- gap: 6px;
3381
+ gap: var(--nf-space-6, 6px);
2691
3382
  }
2692
3383
 
2693
3384
  .dropzone:hover,
@@ -2698,7 +3389,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2698
3389
  }
2699
3390
 
2700
3391
  .dropzoneIcon {
2701
- font-size: 22px;
3392
+ font-size: var(--nf-fs-22, 22px);
2702
3393
  line-height: 1;
2703
3394
  }
2704
3395
 
@@ -2707,8 +3398,9 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2707
3398
  .bookCardActions {
2708
3399
  display: flex;
2709
3400
  align-items: center;
2710
- gap: 6px;
2711
- margin-top: 2px;
3401
+ gap: var(--nf-space-6, 6px);
3402
+ margin-top: auto;
3403
+ padding-top: var(--nf-space-8, 8px);
2712
3404
  }
2713
3405
 
2714
3406
  .bookCardActions .button {
@@ -2731,31 +3423,31 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2731
3423
  flex: none;
2732
3424
  display: flex;
2733
3425
  align-items: center;
2734
- gap: 8px;
2735
- padding: 8px 12px;
3426
+ gap: var(--nf-space-8, 8px);
3427
+ padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
2736
3428
  border-bottom: 1px solid;
2737
3429
  flex-wrap: wrap;
2738
3430
  }
2739
3431
 
2740
3432
  .readerTitle {
2741
3433
  font-weight: 700;
2742
- font-size: 14px;
3434
+ font-size: var(--nf-fs-14, 14px);
2743
3435
  }
2744
3436
 
2745
3437
  .readerSeg {
2746
3438
  display: flex;
2747
3439
  align-items: center;
2748
- gap: 2px;
2749
- border-radius: 8px;
3440
+ gap: var(--nf-space-2, 2px);
3441
+ border-radius: var(--nf-radius-8, 8px);
2750
3442
  overflow: hidden;
2751
3443
  }
2752
3444
 
2753
3445
  .readerSegBtn {
2754
3446
  border: none;
2755
3447
  background: transparent;
2756
- font-size: 12px;
2757
- padding: 3px 8px;
2758
- border-radius: 6px;
3448
+ font-size: var(--nf-fs-12, 12px);
3449
+ padding: var(--nf-space-4, 3px) var(--nf-space-8, 8px);
3450
+ border-radius: var(--nf-radius-6, 6px);
2759
3451
  cursor: pointer;
2760
3452
  opacity: 0.75;
2761
3453
  }
@@ -2780,34 +3472,34 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2780
3472
  width: 220px;
2781
3473
  min-width: 220px;
2782
3474
  overflow-y: auto;
2783
- padding: 8px 6px 24px;
3475
+ padding: var(--nf-space-8, 8px) var(--nf-space-6, 6px) var(--nf-space-24, 24px);
2784
3476
  border-right: 1px solid;
2785
3477
  scrollbar-width: thin;
2786
3478
  display: flex;
2787
3479
  flex-direction: column;
2788
- gap: 10px;
3480
+ gap: var(--nf-space-10, 10px);
2789
3481
  }
2790
3482
 
2791
3483
  .readerGroup {
2792
3484
  display: flex;
2793
3485
  flex-direction: column;
2794
- gap: 1px;
3486
+ gap: var(--nf-space-2, 1px);
2795
3487
  }
2796
3488
 
2797
3489
  .readerGroupTitle {
2798
3490
  display: flex;
2799
3491
  align-items: center;
2800
- gap: 6px;
3492
+ gap: var(--nf-space-6, 6px);
2801
3493
  width: 100%;
2802
3494
  border: none;
2803
3495
  background: transparent;
2804
- font-size: 12px;
3496
+ font-size: var(--nf-fs-12, 12px);
2805
3497
  font-weight: 700;
2806
- padding: 6px 8px 4px;
3498
+ padding: var(--nf-space-6, 6px) var(--nf-space-8, 8px) var(--nf-space-4, 4px);
2807
3499
  opacity: 0.9;
2808
3500
  cursor: pointer;
2809
3501
  text-align: left;
2810
- border-radius: 6px;
3502
+ border-radius: var(--nf-radius-6, 6px);
2811
3503
  }
2812
3504
 
2813
3505
  .readerGroupTitle:hover {
@@ -2817,30 +3509,30 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2817
3509
 
2818
3510
  .readerGroupArrow {
2819
3511
  flex: none;
2820
- font-size: 10px;
3512
+ font-size: var(--nf-fs-12, 10px);
2821
3513
  width: 12px;
2822
3514
  text-align: center;
2823
3515
  }
2824
3516
 
2825
3517
  .readerGroupCount {
2826
3518
  flex: none;
2827
- font-size: 11px;
3519
+ font-size: var(--nf-fs-12, 11px);
2828
3520
  font-weight: 400;
2829
3521
  opacity: 0.6;
2830
3522
  margin-left: auto;
2831
- padding-right: 2px;
3523
+ padding-right: var(--nf-space-2, 2px);
2832
3524
  }
2833
3525
 
2834
3526
  .readerItem {
2835
3527
  display: flex;
2836
3528
  align-items: center;
2837
- gap: 6px;
3529
+ gap: var(--nf-space-6, 6px);
2838
3530
  border: 1px solid;
2839
- border-radius: 8px;
3531
+ border-radius: var(--nf-radius-8, 8px);
2840
3532
  background: transparent;
2841
- font-size: 12px;
3533
+ font-size: var(--nf-fs-12, 12px);
2842
3534
  text-align: left;
2843
- padding: 4px 8px;
3535
+ padding: var(--nf-space-4, 4px) var(--nf-space-8, 8px);
2844
3536
  cursor: pointer;
2845
3537
  opacity: 0.8;
2846
3538
  transition: opacity 0.15s ease, background 0.15s ease;
@@ -2874,14 +3566,14 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2874
3566
 
2875
3567
  .readerItemBadge {
2876
3568
  flex: none;
2877
- font-size: 11px;
3569
+ font-size: var(--nf-fs-12, 11px);
2878
3570
  }
2879
3571
 
2880
3572
  .readerMain {
2881
3573
  flex: 1;
2882
3574
  min-height: 0;
2883
3575
  overflow-y: auto;
2884
- padding: 20px 16px 48px;
3576
+ padding: var(--nf-space-20, 20px) var(--nf-space-16, 16px) var(--nf-space-48, 48px);
2885
3577
  display: flex;
2886
3578
  justify-content: center;
2887
3579
  scrollbar-width: thin;
@@ -2891,12 +3583,12 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2891
3583
  width: 100%;
2892
3584
  display: flex;
2893
3585
  flex-direction: column;
2894
- gap: 12px;
3586
+ gap: var(--nf-space-12, 12px);
2895
3587
  }
2896
3588
 
2897
3589
  .readerChapterTitle {
2898
3590
  margin: 0;
2899
- font-size: 24px;
3591
+ font-size: var(--nf-fs-24, 24px);
2900
3592
  font-weight: 800;
2901
3593
  letter-spacing: 1px;
2902
3594
  }
@@ -2904,8 +3596,8 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2904
3596
  .readerChapterMeta {
2905
3597
  display: flex;
2906
3598
  align-items: center;
2907
- gap: 8px;
2908
- font-size: 12px;
3599
+ gap: var(--nf-space-8, 8px);
3600
+ font-size: var(--nf-fs-12, 12px);
2909
3601
  }
2910
3602
 
2911
3603
  .readerText {
@@ -2922,17 +3614,17 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2922
3614
  display: flex;
2923
3615
  align-items: center;
2924
3616
  justify-content: space-between;
2925
- gap: 8px;
3617
+ gap: var(--nf-space-8, 8px);
2926
3618
  margin-top: 12px;
2927
- padding-top: 12px;
3619
+ padding-top: var(--nf-space-12, 12px);
2928
3620
  border-top: 1px dashed;
2929
3621
  }
2930
3622
 
2931
3623
  .readerLoading,
2932
3624
  .readerError {
2933
3625
  align-self: center;
2934
- padding: 32px 0;
2935
- font-size: 13px;
3626
+ padding: var(--nf-space-32, 32px) 0;
3627
+ font-size: var(--nf-fs-14, 13px);
2936
3628
  opacity: 0.7;
2937
3629
  }
2938
3630
 
@@ -2952,7 +3644,7 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2952
3644
  background: rgba(0, 0, 0, 0.45);
2953
3645
  -webkit-backdrop-filter: blur(4px);
2954
3646
  backdrop-filter: blur(4px);
2955
- padding: 24px;
3647
+ padding: var(--nf-space-24, 24px);
2956
3648
  }
2957
3649
 
2958
3650
  .importModal {
@@ -2961,10 +3653,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2961
3653
  overflow: auto;
2962
3654
  display: flex;
2963
3655
  flex-direction: column;
2964
- gap: 12px;
3656
+ gap: var(--nf-space-12, 12px);
2965
3657
  border: 1px solid var(--nf-border-strong);
2966
- border-radius: 16px;
2967
- padding: 16px;
3658
+ border-radius: var(--nf-radius-16, 16px);
3659
+ /* 主容器统一:与设置页卡片同一 --nf-card-pad */
3660
+ padding: var(--nf-card-pad, 20px 22px);
2968
3661
  background: var(--nf-bg-raise);
2969
3662
  -webkit-backdrop-filter: blur(28px) saturate(180%);
2970
3663
  backdrop-filter: blur(28px) saturate(180%);
@@ -2975,12 +3668,12 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2975
3668
  display: flex;
2976
3669
  align-items: center;
2977
3670
  justify-content: space-between;
2978
- gap: 10px;
3671
+ gap: var(--nf-space-10, 10px);
2979
3672
  }
2980
3673
 
2981
3674
  .importModalTabs {
2982
3675
  display: flex;
2983
- gap: 8px;
3676
+ gap: var(--nf-space-8, 8px);
2984
3677
  }
2985
3678
 
2986
3679
  .importModalTabs .button {
@@ -2990,28 +3683,28 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
2990
3683
  .importModalBody {
2991
3684
  display: flex;
2992
3685
  flex-direction: column;
2993
- gap: 10px;
3686
+ gap: var(--nf-space-10, 10px);
2994
3687
  }
2995
3688
 
2996
3689
  .importField {
2997
3690
  display: flex;
2998
3691
  flex-direction: column;
2999
- gap: 5px;
3000
- font-size: 13px;
3692
+ gap: var(--nf-space-6, 5px);
3693
+ font-size: var(--nf-fs-14, 13px);
3001
3694
  color: var(--nf-text-2);
3002
3695
  }
3003
3696
 
3004
3697
  .importHint {
3005
- font-size: 12px;
3698
+ font-size: var(--nf-fs-12, 12px);
3006
3699
  color: var(--nf-text-3);
3007
3700
  line-height: 1.5;
3008
3701
  }
3009
3702
 
3010
3703
  .importError {
3011
3704
  border: 1px solid color-mix(in srgb, var(--nf-danger, #e5484d) 55%, transparent);
3012
- border-radius: 10px;
3013
- padding: 8px 10px;
3014
- font-size: 12.5px;
3705
+ border-radius: var(--nf-radius-10, 10px);
3706
+ padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
3707
+ font-size: var(--nf-fs-12, 12.5px);
3015
3708
  color: var(--nf-danger, #e5484d);
3016
3709
  background: color-mix(in srgb, var(--nf-danger, #e5484d) 10%, transparent);
3017
3710
  white-space: pre-wrap;
@@ -3021,11 +3714,11 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
3021
3714
  .importResult {
3022
3715
  display: flex;
3023
3716
  flex-direction: column;
3024
- gap: 4px;
3717
+ gap: var(--nf-space-4, 4px);
3025
3718
  border: 1px solid color-mix(in srgb, var(--nf-ok, #46a758) 45%, transparent);
3026
- border-radius: 10px;
3027
- padding: 10px 12px;
3028
- font-size: 13px;
3719
+ border-radius: var(--nf-radius-10, 10px);
3720
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
3721
+ font-size: var(--nf-fs-14, 13px);
3029
3722
  background: color-mix(in srgb, var(--nf-ok, #46a758) 9%, transparent);
3030
3723
  word-break: break-all;
3031
3724
  }
@@ -3033,14 +3726,14 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
3033
3726
  .importModalActions {
3034
3727
  display: flex;
3035
3728
  justify-content: flex-end;
3036
- gap: 8px;
3729
+ gap: var(--nf-space-8, 8px);
3037
3730
  }
3038
3731
 
3039
3732
  .importFileInfo {
3040
3733
  display: flex;
3041
3734
  align-items: center;
3042
- gap: 8px;
3043
- font-size: 13px;
3735
+ gap: var(--nf-space-8, 8px);
3736
+ font-size: var(--nf-fs-14, 13px);
3044
3737
  color: var(--nf-text-1);
3045
3738
  flex-wrap: wrap;
3046
3739
  }
@@ -3048,21 +3741,21 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
3048
3741
  .importPreview {
3049
3742
  display: flex;
3050
3743
  flex-direction: column;
3051
- gap: 4px;
3744
+ gap: var(--nf-space-4, 4px);
3052
3745
  border: 1px solid var(--nf-border-strong);
3053
- border-radius: 10px;
3054
- padding: 10px 12px;
3055
- font-size: 13px;
3746
+ border-radius: var(--nf-radius-10, 10px);
3747
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
3748
+ font-size: var(--nf-fs-14, 13px);
3056
3749
  background: var(--nf-bg-inset);
3057
3750
  }
3058
3751
 
3059
3752
  .importPreviewList {
3060
3753
  margin: 0;
3061
- padding-left: 18px;
3754
+ padding-left: var(--nf-space-18, 18px);
3062
3755
  display: flex;
3063
3756
  flex-direction: column;
3064
- gap: 2px;
3065
- font-size: 12.5px;
3757
+ gap: var(--nf-space-2, 2px);
3758
+ font-size: var(--nf-fs-12, 12.5px);
3066
3759
  color: var(--nf-text-2);
3067
3760
  max-height: 140px;
3068
3761
  overflow: auto;
@@ -3092,12 +3785,12 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
3092
3785
  transform: translateX(-50%);
3093
3786
  width: 280px;
3094
3787
  max-width: 70vw;
3095
- padding: 10px 12px;
3096
- border-radius: 10px;
3788
+ padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
3789
+ border-radius: var(--nf-radius-10, 10px);
3097
3790
  background: var(--nf-bg-raise);
3098
3791
  border: 1px solid var(--nf-border-strong);
3099
3792
  box-shadow: var(--nf-shadow-lg);
3100
- font-size: 12px;
3793
+ font-size: var(--nf-fs-12, 12px);
3101
3794
  font-weight: 400;
3102
3795
  line-height: 1.7;
3103
3796
  color: var(--nf-text-2);
@@ -3112,3 +3805,45 @@ body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
3112
3805
  .helpTip:focus-within .helpTipText {
3113
3806
  display: block;
3114
3807
  }
3808
+
3809
+ /* 设置页:字号已统一为全局档(次要 12 / 主 14 / 标题 16+),不再放大;
3810
+ * 主容器由 .card 的 --nf-card-pad 统一提供(舒适 20px 22px)。 */
3811
+ .settingsCard + .settingsCard {
3812
+ flex: 1;
3813
+ min-height: 0;
3814
+ }
3815
+
3816
+ /* 设置页开关(滑块) */
3817
+ .switch {
3818
+ position: relative;
3819
+ width: 42px;
3820
+ height: 24px;
3821
+ border-radius: var(--nf-radius-999, 999px);
3822
+ border: 1px solid var(--nf-border-strong);
3823
+ background: var(--nf-bg-inset);
3824
+ cursor: pointer;
3825
+ padding: 0;
3826
+ flex: none;
3827
+ transition: background 0.18s ease, border-color 0.18s ease;
3828
+ }
3829
+
3830
+ .switchKnob {
3831
+ position: absolute;
3832
+ top: 3px;
3833
+ left: 3px;
3834
+ width: 16px;
3835
+ height: 16px;
3836
+ border-radius: 50%;
3837
+ background: #fff;
3838
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
3839
+ transition: transform 0.18s ease;
3840
+ }
3841
+
3842
+ .switchOn {
3843
+ background: var(--nf-accent);
3844
+ border-color: var(--nf-accent);
3845
+ }
3846
+
3847
+ .switchOn .switchKnob {
3848
+ transform: translateX(18px);
3849
+ }