@waterwx/dsh-novel-forge 1.7.3 → 1.9.0

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 (44) hide show
  1. package/lib/client.js +3627 -447
  2. package/lib/client.js.map +1 -1
  3. package/lib/index.js +1127 -141
  4. package/lib/index.js.map +1 -1
  5. package/lib/types/author-assets.d.ts +25 -0
  6. package/lib/types/client/api.d.ts +31 -1
  7. package/lib/types/client/locales.d.ts +16 -0
  8. package/lib/types/client/panel/AdaptModeView.d.ts +4 -0
  9. package/lib/types/client/panel/AuthorAssetsView.d.ts +4 -0
  10. package/lib/types/client/panel/AuthorHome.d.ts +30 -0
  11. package/lib/types/client/panel/ModelManager.d.ts +14 -0
  12. package/lib/types/client/panel/ModelPicker.d.ts +11 -0
  13. package/lib/types/client/panel/ProgressConsole.d.ts +17 -0
  14. package/lib/types/client/panel/ProgressHomeView.d.ts +5 -0
  15. package/lib/types/client/panel/ReasoningSection.d.ts +10 -0
  16. package/lib/types/client/panel/SettingsView.d.ts +14 -0
  17. package/lib/types/client/text.d.ts +9 -0
  18. package/lib/types/engine.d.ts +39 -1
  19. package/lib/types/index.d.ts +8 -0
  20. package/lib/types/protocol.d.ts +339 -0
  21. package/package.json +1 -1
  22. package/src/author-assets.ts +166 -0
  23. package/src/client/api.ts +82 -0
  24. package/src/client/locales.ts +32 -0
  25. package/src/client/mount.tsx._new +97 -0
  26. package/src/client/mount.tsx._nf +97 -0
  27. package/src/client/mount.tsx._tmp +97 -0
  28. package/src/client/panel/AdaptModeView.tsx +202 -0
  29. package/src/client/panel/AuthorAssetsView.tsx +206 -0
  30. package/src/client/panel/AuthorHome.tsx +107 -0
  31. package/src/client/panel/ImportModal.tsx +2 -1
  32. package/src/client/panel/ModelManager.tsx +205 -0
  33. package/src/client/panel/NovelPanel.tsx +73 -79
  34. package/src/client/panel/ProgressConsole.tsx +64 -0
  35. package/src/client/panel/ProgressHomeView.tsx +87 -0
  36. package/src/client/panel/ReasoningSection.tsx +31 -0
  37. package/src/client/panel/SettingsView.tsx +292 -0
  38. package/src/client/panel/panel.module.css +325 -0
  39. package/src/client/sidebar-entry.ts +1 -1
  40. package/src/client/text.ts +28 -0
  41. package/src/engine.ts +442 -0
  42. package/src/index.ts +20 -0
  43. package/src/protocol.ts +356 -0
  44. package/src/routes.ts +323 -0
package/lib/client.js CHANGED
@@ -61,6 +61,18 @@ window.__ModuleLoader__.load({
61
61
  storyboardPrompts: "/api/dsh-novel-forge/storyboard/prompts",
62
62
  /** 生图接口连通性测试(设置页每个模型条目用)。 */
63
63
  imageTest: "/api/dsh-novel-forge/image-test",
64
+ /** LLM 模型连通性测试:真实最小调用,验证 Key / 端点 / 模型可用。 */
65
+ llmTest: "/api/dsh-novel-forge/llm-test",
66
+ /** 添加模型:厂商直填 key 或自定义路由,写进 DSH 凭据与 llm-pi-ai 路由。 */
67
+ addModel: "/api/dsh-novel-forge/llm-add",
68
+ /** 运行时厂商目录(DSH pi-ai 可配置提供方 + 内置适配器)。 */
69
+ llmVendors: "/api/dsh-novel-forge/llm-vendors",
70
+ /** 查询某个 provider 当前可用的模型(添加成功后可即时刷新)。 */
71
+ llmModels: "/api/dsh-novel-forge/llm-models",
72
+ /** 已注册的提供方路由列表(提供方管理)。 */
73
+ llmProviders: "/api/dsh-novel-forge/llm-providers",
74
+ /** 移除一个提供方。 */
75
+ llmRemove: "/api/dsh-novel-forge/llm-remove",
64
76
  /** 重置项目(可选携带新大纲):清空设定/卷/章节/伏笔/资产/事实库。 */
65
77
  reset: "/api/dsh-novel-forge/reset",
66
78
  /** 全书一致性质检:LLM 扫描已生成章节,输出矛盾问题清单。 */
@@ -109,8 +121,94 @@ window.__ModuleLoader__.load({
109
121
  /** 生产单状态(含进度统计与日志)。 */
110
122
  runStatus: "/api/dsh-novel-forge/run/status",
111
123
  config: "/api/dsh-novel-forge/config",
112
- openFolder: "/api/dsh-novel-forge/open-folder"
124
+ openFolder: "/api/dsh-novel-forge/open-folder",
125
+ /** 作者资产库/总数据:读取个人跨书资产(笔法/红线/套路/角色模板/世界观模板)。 */
126
+ authorAssets: "/api/dsh-novel-forge/author-assets",
127
+ /** 作者资产库:新增/更新一条资产(upsert by id)。 */
128
+ authorAssetsUpsert: "/api/dsh-novel-forge/author-assets/upsert",
129
+ /** 作者资产库:删除一条资产。 */
130
+ authorAssetsRemove: "/api/dsh-novel-forge/author-assets/remove",
131
+ /** 作者资产库:导入默认(书架书的写作资产/角色 + 内置全局库)批量沉淀。 */
132
+ authorAssetsImportDefault: "/api/dsh-novel-forge/author-assets/import-default",
133
+ /** 改编模式:上传全文 → 分析 → 原文设定卡片/可改范围矩阵。 */
134
+ adaptAnalyze: "/api/dsh-novel-forge/adapt/analyze",
135
+ /** 改编模式:确认要改的维度 → 生成映射表/改编规则/联动影响清单。 */
136
+ adaptPropose: "/api/dsh-novel-forge/adapt/propose",
137
+ /** 改编模式:执行术语替换(全局替换 + 命中统计 + 改编文本预览)。 */
138
+ adaptExecute: "/api/dsh-novel-forge/adapt/execute",
139
+ /** 主题自定义背景:上传图片(POST,存盘并返回服务端 URL)。 */
140
+ themeBackgroundUpload: "/api/dsh-novel-forge/theme/background",
141
+ /** 主题自定义背景:读取已上传文件(GET prefix,/theme/background/<name>)。 */
142
+ themeBackgroundGet: "/api/dsh-novel-forge/theme/background"
113
143
  };
144
+ /** 预置的常见厂商(id=provider 路由;添加模型下拉兜底用,其余厂商由运行时目录动态补充)。 */
145
+ const LLM_VENDORS = [
146
+ {
147
+ id: "deepseek-official",
148
+ name: "DeepSeek",
149
+ route: "deepseek-official",
150
+ apiKeyEnv: "DEEPSEEK_API_KEY",
151
+ defaultModel: "deepseek-v4-flash",
152
+ models: [
153
+ "deepseek-v4-flash",
154
+ "deepseek-v4-pro",
155
+ "deepseek-chat",
156
+ "deepseek-reasoner"
157
+ ],
158
+ builtin: true
159
+ },
160
+ {
161
+ id: "zai-coding-cn",
162
+ name: "智谱 GLM",
163
+ route: "zai-coding-cn",
164
+ apiKeyEnv: "ZAI_CODING_CN_API_KEY",
165
+ defaultModel: "glm-5.3-flash",
166
+ models: [
167
+ "glm-4.5-air",
168
+ "glm-4.7",
169
+ "glm-5-turbo",
170
+ "glm-5.1",
171
+ "glm-5.2",
172
+ "glm-5.3",
173
+ "glm-5.3-flash",
174
+ "glm-5v-turbo"
175
+ ]
176
+ },
177
+ {
178
+ id: "qwen-token-plan-cn",
179
+ name: "千问百炼",
180
+ route: "qwen-token-plan-cn",
181
+ apiKeyEnv: "QWEN_TOKEN_PLAN_CN_API_KEY",
182
+ defaultModel: "qwen3.7-max",
183
+ models: [
184
+ "qwen3.6-flash",
185
+ "qwen3.6-plus",
186
+ "qwen3.7-max",
187
+ "qwen3.7-plus",
188
+ "qwen3.8-max",
189
+ "qwen3.8-max-preview"
190
+ ]
191
+ },
192
+ {
193
+ id: "openrouter",
194
+ name: "OpenRouter",
195
+ route: "openrouter",
196
+ apiKeyEnv: "OPENROUTER_API_KEY",
197
+ defaultModel: "z-ai/glm-5.3-flash",
198
+ models: [
199
+ "z-ai/glm-4.6",
200
+ "z-ai/glm-4.7",
201
+ "z-ai/glm-5",
202
+ "z-ai/glm-5-turbo",
203
+ "z-ai/glm-5.1",
204
+ "z-ai/glm-5.2",
205
+ "z-ai/glm-5.3-flash",
206
+ "auto",
207
+ "deepseek/deepseek-v4-flash",
208
+ "anthropic/claude-sonnet-4.6"
209
+ ]
210
+ }
211
+ ];
114
212
  //#endregion
115
213
  //#region src/client/api.ts
116
214
  /**
@@ -318,6 +416,33 @@ window.__ModuleLoader__.load({
318
416
  async imageTest(req) {
319
417
  return postJson(NOVEL_API.imageTest, req);
320
418
  }
419
+ /** 对选中的提供商/模型发一次最小真实调用,验证连通性。 */
420
+ async llmTest(provider, model) {
421
+ return postJson(NOVEL_API.llmTest, {
422
+ provider,
423
+ model
424
+ });
425
+ }
426
+ /** 添加模型:厂商直填 key,或自定义 OpenAI 兼容路由(写 DSH 凭据 + 注册路由)。 */
427
+ async addModel(req) {
428
+ return postJson(NOVEL_API.addModel, req);
429
+ }
430
+ /** 运行时厂商目录(DSH pi-ai 可配置提供方 + 内置适配器)。 */
431
+ async llmVendors() {
432
+ return readJson(await fetch(NOVEL_API.llmVendors));
433
+ }
434
+ /** 查询某个 provider 当前可用的模型(添加成功后可即时刷新)。 */
435
+ async llmModels(provider) {
436
+ return readJson(await fetch(NOVEL_API.llmModels + "?provider=" + encodeURIComponent(provider)));
437
+ }
438
+ /** 已注册的提供方路由列表(提供方管理卡片)。 */
439
+ async llmProviders() {
440
+ return readJson(await fetch(NOVEL_API.llmProviders));
441
+ }
442
+ /** 移除一个提供方(unset key + 移除 llm-pi-ai 路由)。 */
443
+ async removeProvider(req) {
444
+ return postJson(NOVEL_API.llmRemove, req);
445
+ }
321
446
  async roles(req) {
322
447
  return postJson(NOVEL_API.roles, req);
323
448
  }
@@ -542,6 +667,41 @@ window.__ModuleLoader__.load({
542
667
  async assistantClear() {
543
668
  return postJson(NOVEL_API.assistantClear, {});
544
669
  }
670
+ /** 作者资产库/总数据:读取跨书可复用资产。 */
671
+ async authorAssets() {
672
+ return readJson(await fetch(NOVEL_API.authorAssets));
673
+ }
674
+ /** 作者资产库:新增/更新一条资产(upsert by id)。 */
675
+ async authorAssetsUpsert(asset) {
676
+ return postJson(NOVEL_API.authorAssetsUpsert, { asset });
677
+ }
678
+ /** 作者资产库:删除一条资产。 */
679
+ async authorAssetsRemove(id) {
680
+ return postJson(NOVEL_API.authorAssetsRemove, { id });
681
+ }
682
+ /** 作者资产库:导入默认(书架书的写作资产/角色 + 内置全局库)批量沉淀。 */
683
+ async authorAssetsImportDefault() {
684
+ return postJson(NOVEL_API.authorAssetsImportDefault, {});
685
+ }
686
+ /** 改编模式 P0:上传全文 → 原文设定卡片 / 可改范围矩阵。 */
687
+ async adaptAnalyze(text, filePath) {
688
+ return postJson(NOVEL_API.adaptAnalyze, {
689
+ text,
690
+ filePath
691
+ });
692
+ }
693
+ /** 改编模式 P1:确认要改的维度 → 生成映射表/改编规则/联动影响清单。 */
694
+ async adaptPropose(req) {
695
+ return postJson(NOVEL_API.adaptPropose, req);
696
+ }
697
+ /** 改编模式 P2:执行术语替换(全局替换 + 命中统计 + 改编文本预览)。 */
698
+ async adaptExecute(req) {
699
+ return postJson(NOVEL_API.adaptExecute, req);
700
+ }
701
+ /** 主题自定义背景:上传图片,服务端存盘并返回可访问 URL。 */
702
+ async themeBackgroundUpload(dataUrl) {
703
+ return postJson(NOVEL_API.themeBackgroundUpload, { dataUrl });
704
+ }
545
705
  };
546
706
  //#endregion
547
707
  //#region src/client/locales.ts
@@ -689,7 +849,23 @@ window.__ModuleLoader__.load({
689
849
  "settings.provider": "模型提供商",
690
850
  "settings.model": "模型",
691
851
  "settings.modelCustom": "自定义…",
852
+ "settings.customProvider": "自定义提供商…",
853
+ "settings.edit": "编辑",
854
+ "settings.delete": "删除",
692
855
  "settings.modelCustomPlaceholder": "输入任意模型 id",
856
+ "settings.savedModels": "我的模型",
857
+ "settings.modelCards": "模型卡片(内置 + 已添加)",
858
+ "settings.savedModelName": "名称",
859
+ "settings.addModel": "添加模型",
860
+ "settings.catalogRefresh": "刷新厂商",
861
+ "settings.refreshModels": "刷新模型",
862
+ "settings.savedModelsHint": "手动添加常用模型(provider + 模型 id),点击即可切换当前模型;厂商模式会写入 DSH 凭据并注册路由。",
863
+ "settings.testConnection": "测试连通",
864
+ "settings.testRunning": "测试中",
865
+ "settings.testOk": "连通",
866
+ "settings.testFail": "失败",
867
+ "settings.testHint": "真实发送一次最小调用(约几十 token),验证 Key / 端点 / 模型可用。",
868
+ "settings.reasoningSection": "推理强度",
693
869
  "settings.reasoningEffort": "写作类任务思考强度 (reasoningEffort)",
694
870
  "settings.reasoningHint": "章节生成/润色/重写/审稿等写作任务使用;关掉更省更快。",
695
871
  "settings.analysisReasoning": "分析类任务思考强度(提炼/拆书/反推大纲)",
@@ -840,7 +1016,23 @@ window.__ModuleLoader__.load({
840
1016
  "settings.provider": "Provider",
841
1017
  "settings.model": "Model",
842
1018
  "settings.modelCustom": "Custom…",
1019
+ "settings.customProvider": "Custom provider…",
1020
+ "settings.edit": "Edit",
1021
+ "settings.delete": "Delete",
843
1022
  "settings.modelCustomPlaceholder": "Type any model id",
1023
+ "settings.savedModels": "My Models",
1024
+ "settings.modelCards": "Model cards (built-in + added)",
1025
+ "settings.savedModelName": "Name",
1026
+ "settings.addModel": "Add model",
1027
+ "settings.catalogRefresh": "Refresh vendors",
1028
+ "settings.refreshModels": "Refresh models",
1029
+ "settings.savedModelsHint": "Manually add a model (provider + model id); click to switch. Vendor mode writes the key into DSH credentials and registers the route.",
1030
+ "settings.testConnection": "Test",
1031
+ "settings.testRunning": "Testing",
1032
+ "settings.testOk": "OK",
1033
+ "settings.testFail": "Failed",
1034
+ "settings.testHint": "Sends one minimal real call (~dozens of tokens) to verify key / endpoint / model.",
1035
+ "settings.reasoningSection": "Reasoning",
844
1036
  "settings.reasoningEffort": "Writing-task reasoning effort",
845
1037
  "settings.analysisReasoning": "Analysis-task reasoning (extract / breakdown / reverse outline)",
846
1038
  "settings.analysisReasoningHint": "One-off analysis tasks (roles/scenes/bible extract, breakdown, reverse outline) default to low; not affected by the writing-level switch.",
@@ -5202,7 +5394,7 @@ window.__ModuleLoader__.load({
5202
5394
  key: "d0xqtd"
5203
5395
  }]
5204
5396
  ]);
5205
- createLucideIcon("boxes", [
5397
+ const Boxes = createLucideIcon("boxes", [
5206
5398
  ["path", {
5207
5399
  d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z",
5208
5400
  key: "lc1i9w"
@@ -5739,7 +5931,7 @@ window.__ModuleLoader__.load({
5739
5931
  key: "s3unb"
5740
5932
  }]
5741
5933
  ]);
5742
- createLucideIcon("brush", [
5934
+ const Brush = createLucideIcon("brush", [
5743
5935
  ["path", {
5744
5936
  d: "m11 10 3 3",
5745
5937
  key: "fzmg1i"
@@ -17618,7 +17810,7 @@ window.__ModuleLoader__.load({
17618
17810
  key: "af1f0g"
17619
17811
  }]
17620
17812
  ]);
17621
- createLucideIcon("image", [
17813
+ const Image = createLucideIcon("image", [
17622
17814
  ["rect", {
17623
17815
  width: "18",
17624
17816
  height: "18",
@@ -17749,7 +17941,7 @@ window.__ModuleLoader__.load({
17749
17941
  d: "M6 16c5 0 7-8 12-8a4 4 0 0 1 0 8c-5 0-7-8-12-8a4 4 0 1 0 0 8",
17750
17942
  key: "18ogeb"
17751
17943
  }]]);
17752
- createLucideIcon("info", [
17944
+ const Info = createLucideIcon("info", [
17753
17945
  ["circle", {
17754
17946
  cx: "12",
17755
17947
  cy: "12",
@@ -18908,7 +19100,7 @@ window.__ModuleLoader__.load({
18908
19100
  key: "1szwhi"
18909
19101
  }]
18910
19102
  ]);
18911
- createLucideIcon("list-checks", [
19103
+ const ListChecks = createLucideIcon("list-checks", [
18912
19104
  ["path", {
18913
19105
  d: "M13 5h8",
18914
19106
  key: "a7qcls"
@@ -23663,7 +23855,7 @@ window.__ModuleLoader__.load({
23663
23855
  key: "165o2o"
23664
23856
  }]
23665
23857
  ]);
23666
- createLucideIcon("pencil", [["path", {
23858
+ const Pencil = createLucideIcon("pencil", [["path", {
23667
23859
  d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
23668
23860
  key: "1a8usu"
23669
23861
  }], ["path", {
@@ -24114,7 +24306,7 @@ window.__ModuleLoader__.load({
24114
24306
  key: "1ooewy"
24115
24307
  }]
24116
24308
  ]);
24117
- createLucideIcon("play", [["path", {
24309
+ const Play = createLucideIcon("play", [["path", {
24118
24310
  d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",
24119
24311
  key: "10ikf1"
24120
24312
  }]]);
@@ -25137,7 +25329,7 @@ window.__ModuleLoader__.load({
25137
25329
  key: "1r8tn9"
25138
25330
  }]
25139
25331
  ]);
25140
- createLucideIcon("refresh-cw", [
25332
+ const RefreshCw = createLucideIcon("refresh-cw", [
25141
25333
  ["path", {
25142
25334
  d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",
25143
25335
  key: "v9h5vc"
@@ -32359,7 +32551,7 @@ window.__ModuleLoader__.load({
32359
32551
  d: "M12 19v3",
32360
32552
  key: "npa21l"
32361
32553
  }]]);
32362
- createLucideIcon("trash-2", [
32554
+ const Trash2 = createLucideIcon("trash-2", [
32363
32555
  ["path", {
32364
32556
  d: "M10 11v6",
32365
32557
  key: "nco0om"
@@ -32975,7 +33167,7 @@ window.__ModuleLoader__.load({
32975
33167
  key: "1snsnr"
32976
33168
  }]
32977
33169
  ]);
32978
- createLucideIcon("upload", [
33170
+ const Upload = createLucideIcon("upload", [
32979
33171
  ["path", {
32980
33172
  d: "M12 3v12",
32981
33173
  key: "1x0j5s"
@@ -34149,7 +34341,7 @@ window.__ModuleLoader__.load({
34149
34341
  key: "x3v2xh"
34150
34342
  }]
34151
34343
  ]);
34152
- createLucideIcon("wand-sparkles", [
34344
+ const WandSparkles = createLucideIcon("wand-sparkles", [
34153
34345
  ["path", {
34154
34346
  d: "m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",
34155
34347
  key: "ul74o6"
@@ -34953,7 +35145,7 @@ window.__ModuleLoader__.load({
34953
35145
  key: "qb1veh"
34954
35146
  }]
34955
35147
  ]);
34956
- createLucideIcon("x", [["path", {
35148
+ const X = createLucideIcon("x", [["path", {
34957
35149
  d: "M18 6 6 18",
34958
35150
  key: "1bl5f8"
34959
35151
  }], ["path", {
@@ -35202,26 +35394,38 @@ window.__ModuleLoader__.load({
35202
35394
  exports.BarChart3 = ChartColumn;
35203
35395
  exports.BookMarked = BookMarked;
35204
35396
  exports.BookOpen = BookOpen;
35397
+ exports.Boxes = Boxes;
35205
35398
  exports.Brain = Brain;
35399
+ exports.Brush = Brush;
35206
35400
  exports.Clapperboard = Clapperboard;
35207
35401
  exports.Download = Download;
35208
35402
  exports.Factory = Factory;
35209
35403
  exports.FileText = FileText;
35210
35404
  exports.Folder = Folder;
35405
+ exports.Image = Image;
35406
+ exports.Info = Info;
35211
35407
  exports.Library = Library;
35408
+ exports.ListChecks = ListChecks;
35212
35409
  exports.MessageSquare = MessageSquare;
35213
35410
  exports.Palette = Palette;
35214
35411
  exports.PenLine = PenLine;
35412
+ exports.Pencil = Pencil;
35413
+ exports.Play = Play;
35215
35414
  exports.PlugZap = PlugZap;
35216
35415
  exports.Plus = Plus;
35416
+ exports.RefreshCw = RefreshCw;
35217
35417
  exports.RotateCcw = RotateCcw;
35218
35418
  exports.ScrollText = ScrollText;
35219
35419
  exports.Search = Search;
35220
35420
  exports.Settings = Settings;
35221
35421
  exports.Sparkles = Sparkles;
35422
+ exports.Trash2 = Trash2;
35423
+ exports.Upload = Upload;
35424
+ exports.Wand2 = WandSparkles;
35222
35425
  exports.Wrench = Wrench;
35426
+ exports.X = X;
35223
35427
  })))();
35224
- const css = ".zE6uZW_entry{align-items:center;gap:var(--nf-space-8,8px);width:100%;padding:var(--nf-space-8,8px) var(--nf-space-12,12px);color:var(--dsw-alias-label-primary,#1f1f23);cursor:pointer;text-align:left;border-radius:var(--nf-radius-6,6px);background:0 0;border:none;font-size:14px;transition:background .15s;display:flex}body[data-ds-dark-theme] .zE6uZW_entry{color:var(--dsw-alias-label-primary,#ececf1)}.zE6uZW_entry:hover{background:var(--dsw-alias-interactive-bg-hover,#7f7f7f1f)}.zE6uZW_entry[data-active]{background:var(--dsw-alias-interactive-bg-active,#7f7f7f33)}.zE6uZW_entryIcon{flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_entryLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-pane=conversation]{position:relative}.zE6uZW_view{z-index:60;color-scheme:light;--nf-font:-apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"SF Pro Text\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;--nf-font-mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #fff6 0%, #ffffff4d 26%, #ffffff3d 52%, #fff3 78%, #ffffff2e 100%);--nf-glass-core:radial-gradient(60% 40% at 30% 0%, #fff9 0%, #fff3 42%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffff80;--nf-glass-inset:#fff6;--nf-glass-orb-a:#00b85c3d;--nf-glass-orb-b:#78a0ff33;--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\");--nf-card-radius:20px;--nf-card-blur:26px;--nf-card-saturate:170%;--nf-card-brightness:1.04;--nf-card-sheen:#ffffff80;--nf-card-border:1px solid #ffffff59;--nf-ctrl-radius:14px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffffb3;--nf-ctrl-sheen:#ffffff80;--nf-ctrl-caret:var(--nf-accent);--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\");background:var(--nf-bg);backdrop-filter:blur(30px)saturate(170%)brightness(1.04);color:var(--nf-text);--nf-fs-10:10px;--nf-fs-12:12px;--nf-fs-14:14px;--nf-fs-16:16px;--nf-fs-18:18px;--nf-fs-20:20px;--nf-fs-22:22px;--nf-fs-24:24px;--nf-fs-34:34px;--nf-fs-42:42px;--nf-icon-s:14px;--nf-icon-m:16px;--nf-icon-l:18px;--nf-icon-xl:22px;--nf-space-2:2px;--nf-space-4:4px;--nf-space-6:6px;--nf-space-8:8px;--nf-space-10:10px;--nf-space-12:12px;--nf-space-14:14px;--nf-space-16:16px;--nf-space-18:18px;--nf-space-20:20px;--nf-space-24:24px;--nf-space-28:28px;--nf-space-32:32px;--nf-radius-2:2px;--nf-radius-4:4px;--nf-radius-6:6px;--nf-radius-8:8px;--nf-radius-10:10px;--nf-radius-12:12px;--nf-radius-14:14px;--nf-radius-16:16px;--nf-radius-20:20px;--nf-radius-22:22px;--nf-radius-999:999px;--nf-ctrl-s:28px;--nf-ctrl-m:32px;--nf-ctrl-l:38px;--nf-container-pad:20px 22px;--nf-container-gap:var(--nf-space-14,14px);--nf-card-pad:20px 22px;--nf-nav-pad:16px 12px 14px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Segoe UI,Roboto,Helvetica Neue,sans-serif;display:none;position:absolute;inset:0;overflow:auto}.zE6uZW_panel[data-nf-mode=dark],body[data-ds-dark-theme] .zE6uZW_panel:not([data-nf-mode]),.zE6uZW_view:has(>.zE6uZW_panel[data-nf-mode=dark]),body[data-ds-dark-theme] .zE6uZW_view:not(:has(>.zE6uZW_panel[data-nf-mode=light])){color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #3e424a85 0%, #363a4275 26%, #30343c66 52%, #2a2e365c 78%, #262a3257 100%);--nf-glass-core:radial-gradient(60% 40% at 30% 0%, #ffffff38 0%, #ffffff14 42%, #fff0 78%);--nf-glass-sheen:#ffffff3d;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff14;--nf-glass-orb-a:#00ca525c;--nf-glass-orb-b:#78a0ff47;--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\");--nf-card-radius:20px;--nf-card-blur:28px;--nf-card-saturate:165%;--nf-card-brightness:1;--nf-card-border:1px solid #ffffff24;--nf-card-sheen:#ffffff38;--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\");--nf-ctrl-radius:14px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffff2e;--nf-ctrl-sheen:#fff3;--nf-ctrl-caret:var(--nf-accent)}html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .zE6uZW_view{display:block}.zE6uZW_panel[data-nf-theme=macos],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-mode=light][data-nf-theme=macos]{--nf-bg:#f5f6f8eb;--nf-bg-raise:#ffffffc7;--nf-bg-inset:#7676801a;--nf-border:#3c3c4324;--nf-border-strong:#3c3c434d;--nf-text:#1d1d1f;--nf-text-2:#3a3a3c;--nf-text-2-alpha:#3a3a3cb3;--nf-text-3:#86868b;--nf-accent:#007aff;--nf-accent-hover:#0071e3;--nf-accent-soft:#007aff1f;--nf-accent-fg:#fff;--nf-hover:#0000000a;--nf-info:#5856d6;--nf-shadow:0 1px 3px #0000000d, 0 10px 28px #00000012;--nf-shadow-lg:0 4px 12px #0000000f, 0 18px 44px #0000001c;--nf-card-shadow:0 2px 6px #0000000d, 0 12px 34px #00000017;--nf-card-shadow-hover:0 4px 10px #00000012, 0 20px 48px #00000024;--nf-glass-face:#ffffffb3;--nf-glass-core:transparent;--nf-glass-sheen:#fffc;--nf-glass-border:#ffffffe6;--nf-glass-inset:#fff9;--nf-glass-orb-a:#007aff14;--nf-glass-orb-b:#5856d612;--nf-glass-noise:none;--nf-card-radius:12px;--nf-card-blur:42px;--nf-card-saturate:150%;--nf-card-border:1px solid var(--nf-border);--nf-card-sheen:#ffffff59;--nf-ctrl-radius:8px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid var(--nf-border-strong);--nf-ctrl-sheen:#ffffff59;--nf-ctrl-caret:var(--nf-accent)}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=macos],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=macos]:not([data-nf-mode]){--nf-bg:#1c1c1ee6;--nf-bg-raise:#2c2c2ed1;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff42;--nf-text:#f5f5f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b3;--nf-text-3:#98989d;--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-hover:#ffffff0f;--nf-info:#bf5af2;--nf-shadow:0 1px 2px #0006, 0 10px 30px #00000073;--nf-shadow-lg:0 4px 12px #00000073, 0 18px 44px #0009;--nf-card-shadow:0 2px 6px #0006, 0 14px 38px #00000080;--nf-card-shadow-hover:0 4px 10px #00000073, 0 22px 52px #0009;--nf-glass-face:#2c2c2ed9;--nf-glass-core:transparent;--nf-glass-sheen:#fff3;--nf-glass-border:#ffffff2e;--nf-glass-inset:#ffffff0f;--nf-glass-orb-a:#0a84ff29;--nf-glass-orb-b:#bf5af214;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_button{border:1px solid var(--nf-border-strong);background:color-mix(in srgb, var(--nf-bg-raise) 82%, #fff);box-shadow:0 1px 1px #0000000a,inset 0 1px #fff9}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 90%, #fff), var(--nf-accent));color:var(--nf-accent-fg);box-shadow:0 1px 3px color-mix(in srgb, var(--nf-accent) 45%, transparent), inset 0 1px 0 #ffffff59;border-color:#0000}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_input,.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_textarea{border:1px solid var(--nf-border-strong);background:var(--nf-bg-raise)}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_input:focus,.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.zE6uZW_panel[data-nf-theme=neumorph]{--nf-card-radius:20px;--nf-card-blur:0px;--nf-card-saturate:100%;--nf-card-border:none;--nf-card-sheen:#fff0;--nf-ctrl-radius:10px;--nf-ctrl-bg:var(--nf-bg-inset);--nf-ctrl-border:none;--nf-ctrl-sheen:#fff0;--nf-ctrl-caret:var(--nf-text-3);--nf-glass-bg-image:none}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph]:not([data-nf-mode]){--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=clay]{--nf-card-radius:28px;--nf-card-blur:0px;--nf-card-saturate:100%;--nf-card-brightness:1;--nf-card-border:1px solid #fff9;--nf-card-sheen:#ffffffd9;--nf-ctrl-radius:16px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffff8c;--nf-ctrl-sheen:#ffffffb3;--nf-ctrl-caret:var(--nf-accent);--nf-glass-bg-image:none}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay],.zE6uZW_panel[data-nf-mode=light][data-nf-theme=clay]{--nf-bg:#f2eae0;--nf-bg-raise:#efe4d6;--nf-bg-inset:#e6d8c6;--nf-border:#78604829;--nf-border-strong:#78604847;--nf-text:#3a3330;--nf-text-2:#5a4f48;--nf-text-2-alpha:#5a4f48b3;--nf-text-3:#9a8c80;--nf-accent:#e08a5c;--nf-accent-hover:#d67a4a;--nf-accent-soft:#e08a5c29;--nf-accent-fg:#fff;--nf-hover:#78604814;--nf-success:#7fae6a;--nf-error:#c96b63;--nf-warn:#d9a660;--nf-info:#e08a5c;--nf-shadow:0 8px 16px -6px #5a463247, inset 0 6px 10px #ffffff8c, inset 0 -6px 10px #7860481f;--nf-shadow-lg:0 16px 28px -10px #5a463257, inset 0 6px 10px #ffffff8c, inset 0 -6px 10px #78604824;--nf-card-shadow:0 16px 28px -10px #5a463257, inset 0 -8px 12px #78604824, inset 0 8px 12px #fff9;--nf-card-shadow-hover:0 22px 36px -12px #5a463261, inset 0 -8px 12px #78604829, inset 0 8px 12px #ffffffb3;--nf-glass-face:#efe4d6;--nf-glass-core:transparent;--nf-glass-sheen:#ffffffd9;--nf-glass-border:#fff9;--nf-glass-inset:#e6d8c6;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]){--nf-bg:#2a2522;--nf-bg-raise:#37302b;--nf-bg-inset:#2f2925;--nf-border:#ffffff14;--nf-border-strong:#ffffff2e;--nf-text:#efe9e3;--nf-text-2:#c7beb5;--nf-text-2-alpha:#c7beb5b3;--nf-text-3:#8a8078;--nf-accent:#e69a6c;--nf-accent-hover:#f0ac82;--nf-accent-soft:#e69a6c33;--nf-accent-fg:#241b16;--nf-hover:#ffffff0f;--nf-success:#9cba82;--nf-error:#d98f86;--nf-warn:#d9a660;--nf-info:#e69a6c;--nf-shadow:0 8px 16px -6px #0000008c, inset 0 6px 10px #ffffff1f, inset 0 -6px 10px #00000059;--nf-shadow-lg:0 16px 28px -10px #0000009e, inset 0 6px 10px #ffffff1f, inset 0 -6px 10px #0006;--nf-card-shadow:0 16px 28px -10px #0000009e, inset 0 -8px 12px #0006, inset 0 8px 12px #ffffff24;--nf-card-shadow-hover:0 22px 36px -12px #000000ad, inset 0 -8px 12px #00000070, inset 0 8px 12px #ffffff2e;--nf-glass-face:#37302b;--nf-glass-core:transparent;--nf-glass-sheen:#ffffff29;--nf-glass-border:#ffffff29;--nf-glass-inset:#2f2925;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=clay] .zE6uZW_input,.zE6uZW_panel[data-nf-theme=clay] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:var(--nf-border-strong);box-shadow:inset 3px 3px 7px #78604824,inset -3px -3px 7px #ffffff80}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_button{background:linear-gradient(#f6ecdf,#eee0cf);border-color:#fff9;box-shadow:0 8px 16px -6px #5a463259,inset 0 3px 4px #fffc,inset 0 -3px 5px #78604833}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_button:hover:not([disabled]){box-shadow:0 12px 22px -8px #5a46326b,inset 0 3px 4px #ffffffd9,inset 0 -3px 5px #78604838}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_buttonPrimary{color:var(--nf-accent-fg);background:linear-gradient(#eda178,#e08a5c);border-color:#0000;box-shadow:0 8px 16px -6px #e08a5c8c,inset 0 3px 4px #ffffff80,inset 0 -3px 5px #9646284d}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_button,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_button{background:linear-gradient(#403731,#332c27);border-color:#ffffff29;box-shadow:0 8px 16px -6px #0000008c,inset 0 3px 4px #ffffff24,inset 0 -3px 5px #0006}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_button:hover:not([disabled]),body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_button:hover:not([disabled]){box-shadow:0 12px 22px -8px #0009,inset 0 3px 4px #ffffff29,inset 0 -3px 5px #00000070}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_buttonPrimary,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_buttonPrimary{color:var(--nf-accent-fg);background:linear-gradient(#f0ac82,#d67a4a);border-color:#0000;box-shadow:0 8px 16px -6px #e69a6c80,inset 0 3px 4px #fff6,inset 0 -3px 5px #7832144d}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_input,.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_textarea,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_input,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_textarea{box-shadow:inset 3px 3px 7px #00000073,inset -3px -3px 7px #ffffff14}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input:focus,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #a3b1c680, inset -2px -2px 6px #ffffffd9, 0 0 0 3px var(--nf-accent-soft)}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input:focus,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #00000080, inset -2px -2px 6px #60687638, 0 0 0 3px var(--nf-accent-soft)}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #a3b1c68c,-5px -5px 10px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #a3b1c699,-7px -7px 14px #fffffff2}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_buttonPrimary{background:linear-gradient(#00c563,#00a952);box-shadow:5px 5px 10px #a3b1c699,-5px -5px 10px #ffffffd9}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #0000008c,-7px -7px 14px #60687642}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_buttonPrimary{background:linear-gradient(#3ddc86,#27b96a);box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}.zE6uZW_panel{min-width:0;height:100%;font-size:var(--nf-fs-14,14px);flex-direction:column;line-height:1.6;display:flex;position:relative;overflow:hidden}.zE6uZW_panel:before{content:\"\";z-index:0;pointer-events:none;background:var(--nf-glass-bg-image,none) center / cover no-repeat, radial-gradient(46% 36% at 18% 12%, var(--nf-glass-orb-a), transparent 70%), radial-gradient(52% 42% at 88% 22%, var(--nf-glass-orb-b), transparent 72%), radial-gradient(120% 95% at 50% 42%, transparent 55%, #0202031a 100%);position:absolute;inset:0}.zE6uZW_panel[data-nf-theme=macos]{--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\")}.zE6uZW_panelTitle{font-size:var(--nf-fs-16,16px);letter-spacing:.2px;align-items:center;gap:var(--nf-space-8,8px);margin:0;font-weight:700;display:flex}.zE6uZW_panelTitle:before{content:\"\";border-radius:var(--nf-radius-2,2px);background:linear-gradient(180deg, var(--nf-accent), var(--nf-info));width:4px;height:16px}.zE6uZW_iconButton{cursor:pointer;font-size:var(--nf-fs-16,16px);color:var(--nf-text-2);padding:var(--nf-space-4,4px) var(--nf-space-10,9px);border-radius:var(--nf-radius-10,9px);background:0 0;border:none;transition:background .15s,color .15s,transform .1s}.zE6uZW_iconButton:hover{background:var(--nf-hover);color:var(--nf-text);transform:translateY(-1px)}.zE6uZW_tabBar{gap:var(--nf-space-2,2px);padding:var(--nf-space-8,8px) var(--nf-space-14,14px) 0;border-bottom:1px solid var(--nf-border);background:var(--nf-bg-raise);z-index:4;flex-shrink:0;display:flex;position:sticky;top:45px}.zE6uZW_tab{padding:var(--nf-space-8,7px) var(--nf-space-14,13px);cursor:pointer;border-radius:var(--nf-radius-8,8px) var(--nf-radius-8,8px) 0 0;font-size:var(--nf-fs-14,13.5px);color:var(--nf-text-2);background:0 0;border:none;font-weight:500;transition:color .15s,background .15s;position:relative}.zE6uZW_tab:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_tab[data-active]{color:var(--nf-accent);font-weight:600}.zE6uZW_tab[data-active]:after{content:\"\";border-radius:var(--nf-radius-2,2px) var(--nf-radius-2,2px) 0 0;background:var(--nf-accent);height:2.5px;position:absolute;bottom:-1px;left:10px;right:10px}.zE6uZW_panelContent{padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);z-index:1;flex-direction:column;flex:1;display:flex;position:relative;overflow:auto}.zE6uZW_panelBody{z-index:1;flex:1;min-height:0;display:flex;position:relative}.zE6uZW_panelNav{align-self:stretch;gap:var(--nf-space-6,6px);width:216px;padding:var(--nf-nav-pad,16px 12px 14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-16,18px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);flex-direction:column;flex:none;margin:10px 0 10px 12px;transition:width .18s;display:flex;overflow-y:auto}.zE6uZW_panelNavCollapsed{width:52px;padding:var(--nf-space-10,10px) var(--nf-space-6,6px)}.zE6uZW_navGroup{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_navGroupLabel{font-size:var(--nf-fs-12,12px);letter-spacing:.8px;text-transform:uppercase;color:var(--nf-text-3);padding:var(--nf-space-12,12px) var(--nf-space-10,10px) var(--nf-space-6,6px);user-select:none;font-weight:600}.zE6uZW_navGroupSep{background:var(--nf-border);height:1px;margin:6px 8px 4px}.zE6uZW_navSpacer{flex:1;min-height:8px}.zE6uZW_navAbout{gap:var(--nf-space-4,4px);padding:var(--nf-space-8,8px) var(--nf-space-6,6px) var(--nf-space-4,4px);border-top:1px solid var(--nf-border);flex-direction:column;flex:none;margin-top:4px;display:flex}.zE6uZW_navAboutRow{justify-content:space-between;align-items:center;gap:var(--nf-space-4,4px);cursor:pointer;font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);padding:var(--nf-space-4,4px) var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);text-align:left;white-space:nowrap;background:0 0;border:none;transition:color .15s,background .15s;display:flex}.zE6uZW_navAboutRow:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_navAboutUpdate{background:var(--nf-accent-soft);color:var(--nf-accent);cursor:pointer;font-size:var(--nf-fs-12,10.5px);padding:var(--nf-space-4,4px) var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);text-align:left;white-space:nowrap;border:none;font-weight:600}.zE6uZW_navAboutUpdate:hover{color:var(--nf-accent-hover)}.zE6uZW_panelNavCollapsed .zE6uZW_navAbout{padding:var(--nf-space-6,6px) var(--nf-space-2,2px) var(--nf-space-2,2px);align-items:center}.zE6uZW_panelNavCollapsed .zE6uZW_navAboutRow{padding:var(--nf-space-4,4px) 0;justify-content:center;width:100%}.zE6uZW_navTabBadge{min-width:18px;height:18px;padding:0 var(--nf-space-6,5px);border-radius:var(--nf-radius-999,999px);background:var(--nf-accent);color:#fff;font-size:var(--nf-fs-12,10.5px);text-align:center;flex:none;margin-left:auto;font-weight:700;line-height:18px;display:inline-block}.zE6uZW_panelNavCollapsed .zE6uZW_navTabBadge{min-width:18px;height:18px;line-height:18px;font-size:var(--nf-fs-12,9px);padding:0 var(--nf-space-6,5px);position:absolute;top:2px;right:2px}.zE6uZW_navTabBadgeDanger{background:var(--nf-error)}.zE6uZW_navTabBadgeWarn{background:var(--nf-warn)}.zE6uZW_navTabBadgeDone{background:var(--nf-success)}.zE6uZW_navTabBadgeLive{background:var(--nf-success);animation:1.2s ease-in-out infinite zE6uZW_navBadgePulse}@keyframes zE6uZW_navBadgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}.zE6uZW_navTab{align-items:center;gap:var(--nf-space-10,10px);cursor:pointer;border-radius:var(--nf-radius-10,10px);width:100%;padding:var(--nf-space-12,11px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,14px);color:var(--nf-text-2-alpha,var(--nf-text-2));text-align:left;white-space:nowrap;background:0 0;border:1px solid #0000;font-weight:500;transition:color .15s,background .15s,border-color .15s,box-shadow .15s;display:flex;position:relative}.zE6uZW_panelNavCollapsed .zE6uZW_navTab{padding:var(--nf-space-8,8px) 0;justify-content:center}.zE6uZW_navTab:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_navTab[data-active]{color:var(--nf-accent);background:color-mix(in srgb, var(--nf-text) 8%, transparent);border-color:color-mix(in srgb, var(--nf-text) 16%, transparent);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--nf-text) 6%, transparent);font-weight:600}.zE6uZW_navTab[data-active] .zE6uZW_navTabIcon{color:var(--nf-accent)}.zE6uZW_navTabIcon{text-align:center;width:22px;font-size:var(--nf-fs-16,17px);flex:none;line-height:1}.zE6uZW_navTabLabel{text-overflow:ellipsis;overflow:hidden}.zE6uZW_navTitle{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-2,2px) var(--nf-space-6,6px) var(--nf-space-12,12px);border-bottom:1px solid var(--nf-border);flex:none;min-width:0;margin-bottom:6px;display:flex}.zE6uZW_navTitleLogo{border-radius:var(--nf-radius-10,10px);background:linear-gradient(145deg, var(--nf-accent), var(--nf-accent-hover));width:34px;height:34px;color:var(--nf-accent-fg);font-weight:800;font-size:var(--nf-fs-14,15px);box-shadow:0 6px 16px var(--nf-accent-soft);flex:none;justify-content:center;align-items:center;display:flex}.zE6uZW_navTitleName{font-weight:700;font-size:var(--nf-fs-14,15px);letter-spacing:.2px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_navTitleBook{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_panelNavCollapsed .zE6uZW_navTitle{padding:var(--nf-space-2,2px) 0 var(--nf-space-10,10px);justify-content:center}.zE6uZW_panelNavCollapsed .zE6uZW_navTitleLogo{width:32px;height:var(--nf-ctrl-m,32px)}.zE6uZW_navActions{gap:var(--nf-space-6,6px);padding-top:var(--nf-space-8,8px);border-top:1px solid var(--nf-border);flex:none;margin-top:8px;display:flex}.zE6uZW_navActionBtn{border:1px solid var(--nf-border);color:var(--nf-text-2);cursor:pointer;border-radius:var(--nf-radius-10,10px);height:var(--nf-ctrl-m,32px);font-size:var(--nf-fs-14,14px);background:0 0;flex:1;justify-content:center;align-items:center;line-height:1;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.zE6uZW_navActionBtn:hover{background:var(--nf-hover);color:var(--nf-text);border-color:var(--nf-border-strong)}.zE6uZW_panelNavCollapsed .zE6uZW_navActions{flex-direction:column;align-items:stretch}.zE6uZW_bookSwitch{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-10,9px);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;text-align:left;font:inherit;color:var(--nf-text);flex:none;min-width:0;margin-top:4px;transition:background .15s,border-color .15s;display:flex}.zE6uZW_bookSwitch:hover{background:var(--nf-hover);border-color:var(--nf-border-strong)}.zE6uZW_bookSwitchCover{border-radius:var(--nf-radius-6,5px);background:linear-gradient(160deg, var(--nf-accent), color-mix(in srgb, var(--nf-accent) 45%, #000));width:26px;height:34px;color:var(--nf-accent-fg);font-size:var(--nf-fs-12,11px);flex:none;justify-content:center;align-items:center;font-weight:700;display:flex}.zE6uZW_bookSwitchName{font-size:var(--nf-fs-12,12.5px);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.zE6uZW_bookSwitchMeta{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_bookSwitchArrow{color:var(--nf-text-3);font-size:var(--nf-fs-12,12px);flex:none;margin-left:auto}.zE6uZW_statRowD{gap:var(--nf-space-12,12px);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));display:grid}.zE6uZW_statCardD{justify-content:space-between;align-items:flex-start;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;display:flex}.zE6uZW_statCardDLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3)}.zE6uZW_statCardDValue{font-size:var(--nf-fs-22,22px);color:var(--nf-text);margin-top:2px;font-weight:700}.zE6uZW_statCardDUnit{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);font-weight:400}.zE6uZW_statCardDDetail{font-size:var(--nf-fs-12,11.5px);color:var(--nf-text-3);text-overflow:ellipsis;white-space:nowrap;margin-top:2px;overflow:hidden}.zE6uZW_statCardDDown{color:var(--nf-error)}.zE6uZW_statCardDIcon{width:38px;height:var(--nf-ctrl-l,38px);border-radius:var(--nf-radius-12,12px);font-size:var(--nf-fs-18,18px);background:var(--nf-accent-soft);flex:none;justify-content:center;align-items:center;display:flex}.zE6uZW_statCardDIconRed{background:color-mix(in srgb, var(--nf-error) 13%, transparent)}.zE6uZW_tlBar{gap:var(--nf-space-6,6px);margin-top:8px;display:flex}.zE6uZW_tlSeg{gap:var(--nf-space-4,4px);cursor:pointer;min-width:0;font:inherit;background:0 0;border:none;flex-direction:column;flex:1;padding:0;display:flex}.zE6uZW_tlSegTrack{border-radius:var(--nf-radius-999,999px);background:var(--nf-hover);border:1px solid var(--nf-border);height:8px;overflow:hidden}.zE6uZW_tlSegFill{border-radius:var(--nf-radius-999,999px);background:var(--nf-accent);width:100%;height:100%;display:block}.zE6uZW_tlSegTodo .zE6uZW_tlSegFill{opacity:0}.zE6uZW_tlSegTodo .zE6uZW_tlSegTrack{background:0 0}.zE6uZW_tlSegCurrent .zE6uZW_tlSegTrack{border-color:var(--nf-accent);box-shadow:0 0 0 2px var(--nf-accent-soft)}.zE6uZW_tlSegCurrent .zE6uZW_tlSegFill{opacity:.45}.zE6uZW_tlSegLabel{font-size:var(--nf-fs-12,10.5px);color:var(--nf-text-3);text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_tlSegDone .zE6uZW_tlSegLabel{color:var(--nf-accent);font-weight:600}.zE6uZW_tlSeg:hover .zE6uZW_tlSegTrack{border-color:var(--nf-border-strong)}.zE6uZW_card{border:var(--nf-card-border,1px solid var(--nf-glass-border));border-radius:var(--nf-card-radius,22px);padding:var(--nf-card-pad,20px 22px);gap:var(--nf-space-10,10px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-card-sheen,var(--nf-glass-sheen)), inset 0 -1px 0 #ffffff1a;backdrop-filter:blur(var(--nf-card-blur,30px)) saturate(var(--nf-card-saturate,180%)) brightness(var(--nf-card-brightness,1.06));flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.zE6uZW_card:before{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-card-sheen,var(--nf-glass-sheen)), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.zE6uZW_card:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.zE6uZW_card:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-card-sheen,var(--nf-glass-sheen)), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.zE6uZW_card>*{z-index:1;position:relative}.zE6uZW_cardTitle{font-size:var(--nf-fs-14,14px);color:var(--nf-text);align-items:center;gap:var(--nf-space-8,8px);margin:0;font-weight:650;display:flex}.zE6uZW_button{border:1px solid var(--nf-ctrl-border,var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);padding:var(--nf-space-8,7px) var(--nf-space-16,15px);border-radius:var(--nf-ctrl-radius,10px);cursor:pointer;font-size:var(--nf-fs-14,13px);box-shadow:inset 0 1px 0 var(--nf-ctrl-sheen,#ffffff17);white-space:nowrap;font-weight:500;transition:background .15s,border-color .15s,transform .1s,box-shadow .15s}.zE6uZW_button:hover:not([disabled]){background:var(--nf-hover);border-color:var(--nf-border-strong);transform:translateY(-1px)}.zE6uZW_button:active:not([disabled]){transform:translateY(0)scale(.97)}.zE6uZW_button[disabled]{opacity:.45;cursor:not-allowed}.zE6uZW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #fff), var(--nf-accent));color:var(--nf-accent-fg);border-radius:var(--nf-radius-10,10px);box-shadow:0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 #ffffff73;border-color:#0000}.zE6uZW_buttonPrimary:hover:not([disabled]){background:linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000));box-shadow:0 12px 30px color-mix(in srgb, var(--nf-accent) 50%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 #ffffff73;border-color:#0000;transform:translateY(-1px)}.zE6uZW_buttonDanger{border-color:var(--nf-error);color:var(--nf-error)}.zE6uZW_buttonDanger:hover:not([disabled]){background:#ff3b301a}.zE6uZW_buttonSmall{padding:var(--nf-space-4,4px) var(--nf-space-10,10px);font-size:var(--nf-fs-12,12px);border-radius:var(--nf-ctrl-radius,8px)}.zE6uZW_field{gap:var(--nf-space-6,5px);flex-direction:column;display:flex}.zE6uZW_fieldLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);font-weight:500}.zE6uZW_input{border:var(--nf-ctrl-border,1px solid var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);color-scheme:light;border-radius:var(--nf-ctrl-radius,12px);padding:var(--nf-space-8,7px) var(--nf-space-12,11px);font-size:var(--nf-fs-14,13px);box-sizing:border-box;width:100%;box-shadow:inset 0 1px 0 var(--nf-ctrl-sheen,#ffffff17);transition:border-color .15s,box-shadow .15s}body[data-ds-dark-theme] .zE6uZW_input,.zE6uZW_panel[data-nf-mode=dark] .zE6uZW_input{color-scheme:dark}.zE6uZW_panel[data-nf-mode=light] .zE6uZW_input,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input{color-scheme:light}select.zE6uZW_input{cursor:pointer;-webkit-appearance:none;appearance:none;background-image:linear-gradient(45deg, transparent 50%, var(--nf-ctrl-caret,var(--nf-text-3)) 50%), linear-gradient(135deg, var(--nf-ctrl-caret,var(--nf-text-3)) 50%, transparent 50%);background-position:calc(100% - 18px),calc(100% - 12px);background-repeat:no-repeat;background-size:6px 6px,6px 6px;padding-right:30px}.zE6uZW_input option{color:var(--nf-text);background:var(--nf-bg-raise);font-size:var(--nf-fs-14,15px)}.zE6uZW_input:focus,.zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft);outline:none}.zE6uZW_input::placeholder,.zE6uZW_textarea::placeholder{color:var(--nf-text-3)}.zE6uZW_textarea{border:var(--nf-ctrl-border,1px solid var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);border-radius:var(--nf-ctrl-radius,12px);padding:var(--nf-space-10,9px) var(--nf-space-12,11px);font-size:var(--nf-fs-14,13px);box-sizing:border-box;resize:vertical;width:100%;min-height:200px;font-family:inherit;line-height:1.7;transition:border-color .15s,box-shadow .15s}.zE6uZW_row{align-items:center;gap:var(--nf-space-8,8px);flex-wrap:wrap;display:flex}.zE6uZW_spaceBetween{justify-content:space-between}.zE6uZW_chapterList{gap:var(--nf-space-8,8px);flex-direction:column;display:flex}.zE6uZW_volumeGroup{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_volumeGroupHeader{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;user-select:none;font-size:var(--nf-fs-14,13px);transition:border-color .15s;display:flex}.zE6uZW_volumeGroupHeader:hover{border-color:var(--nf-accent)}.zE6uZW_volumeGroupToggle{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);flex:none}.zE6uZW_chapter{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-10,9px) var(--nf-space-12,12px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg);transition:border-color .15s,box-shadow .15s,transform .1s;display:flex}.zE6uZW_chapter:hover{border-color:var(--nf-border-strong);box-shadow:var(--nf-shadow)}.zE6uZW_chapterFocus{animation:.9s ease-in-out 3 zE6uZW_chapterFocusPulse;border-color:var(--nf-accent)!important;box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 35%, transparent)!important}@keyframes zE6uZW_chapterFocusPulse{0%,to{background:var(--nf-bg)}50%{background:color-mix(in srgb, var(--nf-accent) 18%, var(--nf-bg))}}.zE6uZW_chapterNum{min-width:28px;height:var(--nf-ctrl-s,28px);padding:0 var(--nf-space-8,8px);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);flex-shrink:0;justify-content:center;align-items:center;font-weight:700;display:inline-flex}.zE6uZW_chapterMain{flex:1;min-width:0}.zE6uZW_chapterTitle{font-weight:600;font-size:var(--nf-fs-14,13px);align-items:center;gap:var(--nf-space-8,8px);color:var(--nf-text);display:flex}.zE6uZW_chapterBeats{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_chapterActions{gap:var(--nf-space-4,4px);opacity:.85;flex-shrink:0;transition:opacity .15s;display:flex}.zE6uZW_chapter:hover .zE6uZW_chapterActions{opacity:1}.zE6uZW_badge{font-size:var(--nf-fs-12,11px);padding:var(--nf-space-2,2px) var(--nf-space-10,9px);border-radius:var(--nf-radius-999,999px);white-space:nowrap;letter-spacing:.2px;border:1px solid;font-weight:600}.zE6uZW_badgePending{color:var(--nf-info);border-color:var(--nf-info);background:color-mix(in srgb, var(--nf-info) 10%, transparent)}.zE6uZW_badgeGenerating{color:var(--nf-accent);border-color:var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 12%, transparent);animation:1.2s ease-in-out infinite zE6uZW_pulse}.zE6uZW_badgeWritten{color:var(--nf-warn);border-color:var(--nf-warn);background:color-mix(in srgb, var(--nf-warn) 10%, transparent)}.zE6uZW_badgeRejected{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.zE6uZW_badgeDone{color:var(--nf-success);border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 10%, transparent)}.zE6uZW_badgeError{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.zE6uZW_reviewBox{border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:var(--nf-bg-inset);gap:var(--nf-space-6,6px);font-size:var(--nf-fs-12,12.5px);flex-direction:column;display:flex}.zE6uZW_chapterPreview{white-space:pre-wrap;word-break:break-all;max-height:320px;font-size:var(--nf-fs-12,12.5px);color:var(--nf-text);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);margin:0;font-family:inherit;line-height:1.8;overflow:auto}.zE6uZW_chatScroll{gap:var(--nf-space-10,10px);min-height:240px;max-height:480px;padding:var(--nf-space-14,14px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);flex-direction:column;flex:1;display:flex;overflow-y:auto}.zE6uZW_chatBubbleUser{background:linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));max-width:90%;color:var(--nf-accent-fg);border-radius:var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-4,4px) var(--nf-radius-14,14px);padding:var(--nf-space-10,9px) var(--nf-space-14,14px);font-size:var(--nf-fs-14,13px);align-self:flex-end;box-shadow:0 2px 6px #4d6bfe33}.zE6uZW_chatBubbleAssistant{background:var(--nf-bg-raise);max-width:92%;color:var(--nf-text);border:1px solid var(--nf-border);border-radius:var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-4,4px);padding:var(--nf-space-10,9px) var(--nf-space-14,14px);font-size:var(--nf-fs-14,13px);box-shadow:var(--nf-shadow);align-self:flex-start}.zE6uZW_chatRole{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);margin-bottom:3px;font-weight:600}.zE6uZW_toolLive{padding:var(--nf-space-8,8px) var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);border:1px dashed var(--nf-border-strong);font-size:var(--nf-fs-12,12px);white-space:pre-wrap;word-break:break-all;color:var(--nf-text-2);max-height:180px;margin-top:6px;line-height:1.7;overflow-y:auto}.zE6uZW_assistantStatus{padding:var(--nf-space-6,6px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);background:var(--nf-bg-inset);border:1px solid var(--nf-border);align-items:center;gap:var(--nf-space-6,6px);flex:none;margin-top:6px;display:flex}.zE6uZW_assistantStatusBusy{color:var(--nf-accent);border-color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.zE6uZW_toolSteps{gap:var(--nf-space-4,4px);flex-direction:column;margin-top:6px;display:flex}.zE6uZW_toolStep{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-6,5px) var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);font-size:var(--nf-fs-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);display:flex}.zE6uZW_toolStepActive{border-color:var(--nf-accent);background:var(--nf-accent-soft)}.zE6uZW_toolStepError{border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.zE6uZW_toolStepIcon{font-size:var(--nf-fs-14,13px);flex:none}.zE6uZW_toolStepName{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:600;overflow:hidden}.zE6uZW_toolStepStatus{color:var(--nf-text-2);font-size:var(--nf-fs-12,11px);flex:none}.zE6uZW_toolStepActive .zE6uZW_toolStepStatus{color:var(--nf-accent)}.zE6uZW_toolStepError .zE6uZW_toolStepStatus{color:var(--nf-error)}.zE6uZW_toolStepDetail{width:100%;color:var(--nf-error);font-size:var(--nf-fs-12,11px);word-break:break-all}.zE6uZW_progress{border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);font-size:var(--nf-fs-12,12px);white-space:pre-wrap;word-break:break-all;min-height:60px;max-height:220px;color:var(--nf-text-2);font-family:var(--nf-font-mono);background:var(--nf-bg-inset);line-height:1.8;overflow:auto}.zE6uZW_progressLine{color:var(--nf-text-2);opacity:.9}.zE6uZW_progressLineLive{color:var(--nf-accent);align-items:center;gap:var(--nf-space-8,8px);font-weight:600;display:flex}.zE6uZW_progressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);flex:none;width:110px;height:6px;display:inline-block;overflow:hidden}.zE6uZW_progressBarFill{border-radius:var(--nf-radius-4,3px);background:var(--nf-accent);height:100%;transition:width .3s;display:block}.zE6uZW_busyRow{justify-content:space-between;align-items:center;gap:var(--nf-space-12,12px);flex-wrap:wrap;display:flex}.zE6uZW_liveText{font-size:var(--nf-fs-12,12px);font-variant-numeric:tabular-nums;color:var(--nf-text-2)}.zE6uZW_bigProgressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:8px;margin-top:10px;overflow:hidden}.zE6uZW_bigProgressBarFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2,var(--nf-accent)));height:100%;transition:width .3s;display:block}.zE6uZW_diffLegend{align-items:center;gap:var(--nf-space-14,14px);font-size:var(--nf-fs-12,12px);flex-wrap:wrap;margin:6px 0 8px;display:flex}.zE6uZW_legendOld{color:var(--nf-error);font-weight:700}.zE6uZW_legendNew{color:var(--nf-success);font-weight:700}.zE6uZW_onlyChanges{align-items:center;gap:var(--nf-space-4,4px);color:var(--nf-text-2);cursor:pointer;margin-left:auto;display:inline-flex}.zE6uZW_diffList{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);min-height:0;padding:var(--nf-space-10,10px) var(--nf-space-12,12px);gap:var(--nf-space-8,8px);font-size:var(--nf-fs-14,13px);flex-direction:column;flex:1;line-height:1.7;display:flex;overflow-y:auto}.zE6uZW_diffSame{border:1px dashed var(--nf-border);border-radius:var(--nf-radius-6,6px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);color:var(--nf-text-2);opacity:.85}.zE6uZW_diffSame summary{cursor:pointer;font-size:var(--nf-fs-12,12px);user-select:none}.zE6uZW_diffSameBody{white-space:pre-wrap;margin-top:6px}.zE6uZW_diffChange{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);grid-template-columns:1fr 1fr;display:grid;overflow:hidden}.zE6uZW_diffColumn{gap:var(--nf-space-6,6px);min-width:0;padding:var(--nf-space-8,8px) var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_diffColumn:first-child{border-right:1px solid var(--nf-border)}.zE6uZW_diffTagOld,.zE6uZW_diffTagNew{font-size:var(--nf-fs-12,11px);border-radius:var(--nf-radius-4,4px);padding:var(--nf-space-2,1px) var(--nf-space-8,7px);letter-spacing:.5px;flex:none;align-self:flex-start;font-weight:700}.zE6uZW_diffTagOld{color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-error) 45%, transparent)}.zE6uZW_diffTagNew{color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-success) 45%, transparent)}.zE6uZW_diffOld{color:var(--nf-error);white-space:pre-wrap;text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 55%, transparent)}.zE6uZW_diffNew{color:var(--nf-success);white-space:pre-wrap;font-weight:500}.zE6uZW_diffDel{gap:var(--nf-space-4,4px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-6,6px);border:1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);background:color-mix(in srgb, var(--nf-error) 7%, transparent);flex-direction:column;display:flex}.zE6uZW_diffAdd{gap:var(--nf-space-4,4px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-6,6px);border:1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);background:color-mix(in srgb, var(--nf-success) 7%, transparent);flex-direction:column;display:flex}.zE6uZW_diffText{white-space:pre-wrap}.zE6uZW_diffDel .zE6uZW_diffText{color:var(--nf-error);text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 50%, transparent)}.zE6uZW_diffAdd .zE6uZW_diffText{color:var(--nf-success)}.zE6uZW_wsPage{gap:var(--nf-space-10,10px);flex-direction:column;flex:1;min-height:0;display:flex}.zE6uZW_wsPageHeader{align-items:center;gap:var(--nf-space-8,8px);flex-wrap:wrap;flex:none;display:flex}.zE6uZW_wsAppliedBanner{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);border:1px solid var(--nf-success);border-radius:var(--nf-radius-10,10px);background:color-mix(in srgb, var(--nf-success) 8%, transparent);font-size:var(--nf-fs-12,12px);flex-wrap:wrap;flex:none;font-weight:600;display:flex}.zE6uZW_wsColumns{gap:var(--nf-space-14,14px);flex:1;grid-template-columns:minmax(0,1fr) minmax(0,1fr);min-height:0;display:grid}.zE6uZW_wsColumn{gap:var(--nf-space-8,8px);flex-direction:column;min-width:0;min-height:0;display:flex}.zE6uZW_wsEditor{resize:vertical;min-height:0;font-family:var(--nf-font);font-size:var(--nf-fs-14,13px);white-space:pre-wrap;flex:1;line-height:1.75}.zE6uZW_wsSelected{border:1px solid var(--nf-accent);border-radius:var(--nf-radius-6,6px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);background:color-mix(in srgb, var(--nf-accent) 8%, transparent);max-height:120px;overflow:auto}.zE6uZW_wsSelectedText{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);white-space:pre-wrap;margin-top:4px}.zE6uZW_wsPreview{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px);gap:var(--nf-space-8,8px);background:var(--nf-bg-inset);flex-direction:column;display:flex}.zE6uZW_wsPreviewText{min-height:0;font-size:var(--nf-fs-14,13px);white-space:pre-wrap;color:var(--nf-text);flex:1;margin:0;line-height:1.7;overflow:auto}.zE6uZW_assetGrid{gap:var(--nf-space-10,10px);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));display:grid}.zE6uZW_assetStat{border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);gap:var(--nf-space-4,4px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(30px)saturate(180%);flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex}.zE6uZW_assetStat:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1px 0 var(--nf-glass-sheen);transform:translateY(-3px)}.zE6uZW_assetStatLabel{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);opacity:.9}.zE6uZW_assetStatValue{font-size:var(--nf-fs-14,15px);color:var(--nf-text);font-weight:700;line-height:1.2}.zE6uZW_assetStatDetail{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_dashHero{border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);padding:var(--nf-card-pad,20px 22px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;backdrop-filter:blur(30px)saturate(180%);gap:var(--nf-space-14,14px);flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.zE6uZW_dashHero:before{content:\"\";border-radius:inherit;pointer-events:none;background:radial-gradient(46% 40% at 92% -10%, color-mix(in srgb, var(--nf-accent) 13%, transparent), transparent 62%), var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.zE6uZW_dashHero:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.zE6uZW_dashHero:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.zE6uZW_dashHero>*{z-index:1;position:relative}.zE6uZW_dashHeroEyebrow{align-items:center;gap:var(--nf-space-6,6px);font-size:var(--nf-fs-14,13px);color:var(--nf-accent);font-weight:600;display:inline-flex}.zE6uZW_dashHeroSparkle{font-size:var(--nf-fs-14,14px)}.zE6uZW_dashHeroTitle{gap:var(--nf-space-2,2px);flex-direction:column;display:flex}.zE6uZW_dashHeroBook{font-size:var(--nf-fs-24,24px);letter-spacing:-.3px;margin:0;font-weight:700;line-height:1.25}.zE6uZW_dashHeroAction{align-items:center;gap:var(--nf-space-12,12px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);display:flex}.zE6uZW_dashHeroArrow{width:28px;height:var(--nf-ctrl-s,28px);background:var(--nf-accent);color:#fff;font-size:var(--nf-fs-14,14px);border-radius:50%;flex:none;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_dashHeroActionBody{gap:var(--nf-space-2,2px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_dashHeroActionTitle{font-size:var(--nf-fs-14,14px);font-weight:600}.zE6uZW_dashJourney{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_dashJourneyBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:6px;overflow:hidden}.zE6uZW_dashJourneyFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));height:100%;transition:width .4s;display:block}.zE6uZW_dashJourneyStages{gap:var(--nf-space-4,4px);grid-template-columns:repeat(6,minmax(0,1fr));display:grid}.zE6uZW_dashStage{align-items:center;gap:var(--nf-space-4,3px);font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);text-align:center;white-space:nowrap;flex-direction:column;display:flex}.zE6uZW_dashStageDot{border:1px solid var(--nf-border-strong,var(--nf-text-3));width:18px;height:18px;font-size:var(--nf-fs-12,10px);background:var(--nf-bg-base);border-radius:50%;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_dashStageDone{color:var(--nf-text-2)}.zE6uZW_dashStageDone .zE6uZW_dashStageDot{background:var(--nf-success);border-color:var(--nf-success);color:#fff}.zE6uZW_dashStageCurrent{color:var(--nf-accent);font-weight:600}.zE6uZW_dashStageCurrent .zE6uZW_dashStageDot{border-color:var(--nf-accent);color:var(--nf-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 18%, transparent)}.zE6uZW_dashFacts{gap:var(--nf-space-8,8px);border-top:1px solid var(--nf-border);padding-top:var(--nf-space-12,12px);grid-template-columns:repeat(4,minmax(0,1fr));display:grid}.zE6uZW_dashFact{gap:var(--nf-space-2,2px);flex-direction:column;min-width:0;display:flex}.zE6uZW_dashFact b{font-size:var(--nf-fs-14,13px);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_dashGrid{gap:var(--nf-space-14,14px);grid-template-columns:minmax(0,3fr) minmax(0,2fr);align-items:start;display:grid}.zE6uZW_todoItem{align-items:center;gap:var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);font-size:var(--nf-fs-12,12.5px);border:1px solid var(--nf-border);display:flex}.zE6uZW_todoDanger{border-color:color-mix(in srgb, var(--nf-error) 40%, transparent);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.zE6uZW_todoWarning{border-color:color-mix(in srgb, var(--nf-warn) 40%, transparent);background:color-mix(in srgb, var(--nf-warn) 8%, transparent)}.zE6uZW_todoInfo{border-color:color-mix(in srgb, var(--nf-info) 40%, transparent);background:color-mix(in srgb, var(--nf-info) 7%, transparent)}.zE6uZW_todoText{gap:var(--nf-space-2,2px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_outlineReadonly{padding:var(--nf-space-12,12px) var(--nf-space-14,14px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);font-size:var(--nf-fs-12,12.5px);white-space:pre-wrap;user-select:text;max-height:480px;margin:0;line-height:1.8;overflow:auto}.zE6uZW_bookCreateOutline{gap:var(--nf-space-6,6px);flex-direction:column;align-items:flex-start;display:flex}.zE6uZW_assistantFloat{z-index:80;border:1px solid var(--nf-border);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;min-width:320px;min-height:220px;display:flex;position:absolute;overflow:hidden}.zE6uZW_assistantFloatHeader{justify-content:space-between;align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px) var(--nf-space-8,8px) var(--nf-space-14,14px);cursor:grab;user-select:none;font-size:var(--nf-fs-14,13px);border-bottom:1px solid var(--nf-border);background:var(--nf-bg-inset);flex:none;font-weight:600;display:flex}.zE6uZW_assistantFloatHeader:active{cursor:grabbing}.zE6uZW_assistantFloatBody{min-height:0;padding:var(--nf-space-10,10px);flex:1;display:flex;overflow:hidden}.zE6uZW_assistantFloatBody>*{flex:1;min-width:0}.zE6uZW_assistantResize{cursor:nwse-resize;background:linear-gradient(135deg, transparent 0 55%, var(--nf-border-strong) 55% 62%, transparent 62%) no-repeat 4px 4px / 12px 12px;width:20px;height:20px;position:absolute;bottom:0;right:0}.zE6uZW_coverPreview{border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);flex:none;justify-content:center;align-items:center;width:150px;height:200px;display:flex;overflow:hidden}.zE6uZW_coverPreview img{object-fit:contain;width:100%;height:100%;display:block}.zE6uZW_coverPlaceholder{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3)}.zE6uZW_shelfView{min-height:0;padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);flex-direction:column;flex:1;display:flex;overflow:auto}.zE6uZW_shelfHeader{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_shelfHero{gap:var(--nf-space-14,14px);padding:var(--nf-card-pad,20px 22px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);flex-direction:column;display:flex}.zE6uZW_shelfHero .zE6uZW_panelTitle{font-size:var(--nf-fs-22,22px);letter-spacing:.3px}.zE6uZW_shelfTitleRow{justify-content:space-between;align-items:center;gap:var(--nf-space-10,10px);flex-wrap:wrap;display:flex}.zE6uZW_shelfToolbar{align-items:center;gap:var(--nf-space-10,10px);flex-wrap:wrap;display:flex}.zE6uZW_shelfSearch{flex:1;min-width:180px;max-width:320px}.zE6uZW_shelfStats{gap:var(--nf-space-10,10px);grid-template-columns:repeat(auto-fit,minmax(120px,1fr));display:grid}.zE6uZW_shelfStat{justify-content:space-between;align-items:baseline;gap:var(--nf-space-8,8px);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);cursor:pointer;user-select:none;transition:border-color .15s,background .15s,box-shadow .15s,transform .1s;display:flex}.zE6uZW_shelfStat:hover{border-color:var(--nf-accent);transform:translateY(-1px)}.zE6uZW_shelfStatActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);box-shadow:0 0 0 2px var(--nf-accent-soft), var(--nf-shadow)}.zE6uZW_shelfStat b{font-size:var(--nf-fs-20,20px);color:var(--nf-accent);font-weight:800}.zE6uZW_shelfStat span{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2)}.zE6uZW_shelfFilters{gap:var(--nf-space-2,2px);padding:var(--nf-space-4,3px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-999,999px);background:var(--nf-bg-inset);display:inline-flex}.zE6uZW_shelfFilter{color:var(--nf-text-2);font-size:var(--nf-fs-12,12.5px);padding:var(--nf-space-6,5px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);cursor:pointer;align-items:center;gap:var(--nf-space-6,5px);white-space:nowrap;background:0 0;border:none;font-weight:600;transition:background .15s,color .15s,box-shadow .15s;display:inline-flex}.zE6uZW_shelfFilter:hover{color:var(--nf-text)}.zE6uZW_shelfFilterActive{background:linear-gradient(135deg, var(--nf-accent), var(--nf-accent-hover));color:var(--nf-accent-fg);box-shadow:0 3px 12px color-mix(in srgb, var(--nf-accent) 40%, transparent)}.zE6uZW_shelfFilterCount{font-size:var(--nf-fs-12,10.5px);opacity:.8;background:color-mix(in srgb, currentColor 14%, transparent);border-radius:var(--nf-radius-999,999px);padding:0 var(--nf-space-6,6px)}.zE6uZW_shelfEmpty{justify-content:center;align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-40,40px) var(--nf-space-20,20px);border:1px dashed var(--nf-border-strong);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);text-align:center;flex-direction:column;flex:1;display:flex}.zE6uZW_shelfEmptyIcon{font-size:var(--nf-fs-42,42px)}.zE6uZW_shelfEmptyTitle{font-size:var(--nf-fs-16,16px);font-weight:700}.zE6uZW_shelfGrid{gap:var(--nf-container-gap,14px);grid-template-columns:repeat(auto-fill,minmax(190px,1fr));align-content:start;display:grid}.zE6uZW_panel{--nf-container-pad:20px 22px;--nf-container-gap:var(--nf-space-14,14px);--nf-card-pad:20px 22px;--nf-nav-pad:16px 12px 14px}.zE6uZW_panel[data-nf-density=compact]{--nf-container-pad:12px 14px;--nf-container-gap:var(--nf-space-8,8px);--nf-card-pad:12px 14px;--nf-nav-pad:8px 8px}.zE6uZW_panel[data-nf-density=spacious]{--nf-container-pad:24px 28px;--nf-container-gap:var(--nf-space-18,18px);--nf-card-pad:22px 26px;--nf-nav-pad:18px 14px}.zE6uZW_panel[data-nf-mode=light]{color-scheme:light;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff80 0%, #ffffff38 45%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffffa6;--nf-glass-inset:#ffffff8c;--nf-glass-orb-a:#00b85c2e;--nf-glass-orb-b:#78a0ff21}.zE6uZW_panel[data-nf-mode=dark]{color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #70747a6b 0%, #60646a6b 26%, #52555a6b 52%, #44474c6b 78%, #383a3f6b 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff42 0%, #ffffff1a 45%, #fff0 78%);--nf-glass-sheen:#ffffff42;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff12;--nf-glass-orb-a:#00ca5247;--nf-glass-orb-b:#bec8d71a}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=macos]{--nf-bg:#1c1c1ee6;--nf-bg-raise:#2c2c2ed1;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff42;--nf-text:#f5f5f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b3;--nf-text-3:#98989d;--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-hover:#ffffff0f;--nf-info:#bf5af2;--nf-shadow:0 1px 2px #0006, 0 10px 30px #00000073;--nf-shadow-lg:0 4px 12px #00000073, 0 18px 44px #0009;--nf-card-shadow:0 2px 6px #0006, 0 14px 38px #00000080;--nf-card-shadow-hover:0 4px 10px #00000073, 0 22px 52px #0009;--nf-glass-face:#2c2c2ed9;--nf-glass-core:transparent;--nf-glass-sheen:#fff3;--nf-glass-border:#ffffff2e;--nf-glass-inset:#ffffff0f;--nf-glass-orb-a:#0a84ff29;--nf-glass-orb-b:#bf5af214;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph]{--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=light][data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_bookCard{gap:var(--nf-space-8,8px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-16,16px);padding:var(--nf-space-12,12px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow);cursor:pointer;flex-direction:column;transition:border-color .15s,transform .1s,box-shadow .15s;display:flex}.zE6uZW_bookCard:hover{border-color:var(--nf-accent);box-shadow:var(--nf-shadow-lg);transform:translateY(-2px)}.zE6uZW_bookCardActive{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.zE6uZW_bookCardCover{aspect-ratio:3/4;border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);flex:none;justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden}.zE6uZW_bookCardCover img{object-fit:cover;width:100%;height:100%;transition:transform .35s;display:block}.zE6uZW_bookCard:hover .zE6uZW_bookCardCover img{transform:scale(1.06)}.zE6uZW_bookCardCover:after{content:\"\";border-radius:inherit;pointer-events:none;opacity:0;background:linear-gradient(#0000 55%,#00000047);transition:opacity .25s;position:absolute;inset:0}.zE6uZW_bookCard:hover .zE6uZW_bookCardCover:after{opacity:1}.zE6uZW_bookCardCoverFallback{justify-content:center;align-items:center;gap:var(--nf-space-6,6px);background:radial-gradient(400px 200px at 80% -20%, color-mix(in srgb, var(--nf-accent) 25%, transparent), transparent 70%), linear-gradient(155deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 10%, var(--nf-bg-inset)));flex-direction:column;width:100%;height:100%;display:flex}.zE6uZW_bookCardCoverTitle{font-size:var(--nf-fs-22,22px);color:var(--nf-accent);letter-spacing:2px;font-weight:800}.zE6uZW_bookCardBody{gap:var(--nf-space-6,5px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_bookCardTitleRow{justify-content:space-between;align-items:center;gap:var(--nf-space-6,6px);display:flex}.zE6uZW_bookCardName{font-weight:700;font-size:var(--nf-fs-14,13.5px);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_bookCardBlurb{-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:34px;display:-webkit-box;overflow:hidden}.zE6uZW_bookCardMetaRow{justify-content:space-between;align-items:center;gap:var(--nf-space-6,6px);flex-wrap:wrap;display:flex}.zE6uZW_bookCardProgressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:6px;overflow:hidden;box-shadow:inset 0 1px 2px #0000001f}.zE6uZW_bookCardProgressFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));height:100%;transition:width .3s;display:block}.zE6uZW_bookAddCard{justify-content:center;align-items:center;gap:var(--nf-space-8,8px);text-align:center;color:var(--nf-text-2);border-style:dashed;min-height:260px;transition:border-color .15s,color .15s,background .15s,transform .15s}.zE6uZW_bookAddCard:hover{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent);transform:translateY(-2px)}.zE6uZW_bookAddIcon{font-size:var(--nf-fs-34,34px);color:var(--nf-accent);line-height:1;transition:transform .15s}.zE6uZW_bookAddCard:hover .zE6uZW_bookAddIcon{transform:scale(1.12)}.zE6uZW_bookCreateCard{border-color:var(--nf-accent);min-height:260px}.zE6uZW_createBookView{min-height:0;padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);flex-direction:column;flex:1;display:flex;overflow:auto}.zE6uZW_createBookTop{align-items:center;display:flex}.zE6uZW_createBookCard{align-self:center;gap:var(--nf-space-12,12px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-20,20px);width:min(520px,100%);padding:var(--nf-card-pad,20px 22px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;display:flex}.zE6uZW_createBookIcon{font-size:var(--nf-fs-34,34px);line-height:1}.zE6uZW_createBookTitle{font-size:var(--nf-fs-22,22px);letter-spacing:-.3px;margin:0;font-weight:800}.zE6uZW_ideaCard{gap:var(--nf-space-8,8px);border:1px dashed var(--nf-border-strong);border-radius:var(--nf-radius-14,14px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:color-mix(in srgb, var(--nf-accent) 3%, transparent);flex-direction:column;display:flex}.zE6uZW_ideaToggle{align-items:center;gap:var(--nf-space-6,6px);color:var(--nf-accent);font-size:var(--nf-fs-14,13px);cursor:pointer;text-align:left;background:0 0;border:none;padding:0;font-weight:700;display:flex}.zE6uZW_ideaCandidate{gap:var(--nf-space-6,6px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:var(--nf-bg);flex-direction:column;display:flex}.zE6uZW_progressLineDone{color:var(--nf-success);font-weight:600}.zE6uZW_progressLineError{color:var(--nf-error);font-weight:600}.zE6uZW_meta{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.9}.zE6uZW_genreDesc{-webkit-line-clamp:2;-webkit-box-orient:vertical;max-width:560px;display:-webkit-box;overflow:hidden}.zE6uZW_fileList{gap:var(--nf-space-4,3px);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.9;word-break:break-all;flex-direction:column;display:flex}.zE6uZW_panelContent::-webkit-scrollbar,.zE6uZW_chatScroll::-webkit-scrollbar,.zE6uZW_chapterPreview::-webkit-scrollbar,.zE6uZW_progress::-webkit-scrollbar,.zE6uZW_toolLive::-webkit-scrollbar{width:8px;height:8px}.zE6uZW_panelContent::-webkit-scrollbar-thumb,.zE6uZW_chatScroll::-webkit-scrollbar-thumb,.zE6uZW_chapterPreview::-webkit-scrollbar-thumb,.zE6uZW_progress::-webkit-scrollbar-thumb,.zE6uZW_toolLive::-webkit-scrollbar-thumb{background:var(--nf-border-strong);border-radius:var(--nf-radius-4,4px)}.zE6uZW_panelContent::-webkit-scrollbar-thumb:hover,.zE6uZW_chatScroll::-webkit-scrollbar-thumb:hover,.zE6uZW_chapterPreview::-webkit-scrollbar-thumb:hover,.zE6uZW_progress::-webkit-scrollbar-thumb:hover,.zE6uZW_toolLive::-webkit-scrollbar-thumb:hover{background:var(--nf-text-3)}.zE6uZW_workflowList{flex-direction:column;gap:0;display:flex}.zE6uZW_workflowRow{align-items:flex-start;gap:var(--nf-space-12,12px);padding:var(--nf-space-8,8px) var(--nf-space-4,4px);display:flex;position:relative}.zE6uZW_workflowRow:before{content:\"\";background:var(--nf-border);width:2px;position:absolute;top:34px;bottom:-8px;left:13px}.zE6uZW_workflowRow:last-child:before{display:none}.zE6uZW_workflowDot{width:28px;height:var(--nf-ctrl-s,28px);font-size:var(--nf-fs-12,12px);border:2px solid var(--nf-border-strong);background:var(--nf-bg-raise);color:var(--nf-text-2);z-index:1;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-weight:700;display:inline-flex}.zE6uZW_workflowDotDone{border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));color:var(--nf-success)}.zE6uZW_workflowDotActive{border-color:var(--nf-accent);background:var(--nf-accent);color:var(--nf-accent-fg);box-shadow:0 0 0 4px var(--nf-accent-soft)}.zE6uZW_workflowBody{gap:var(--nf-space-4,4px);min-width:0;padding-top:var(--nf-space-2,2px);flex-direction:column;flex:1;display:flex}.zE6uZW_workflowLabel{font-size:var(--nf-fs-14,13px);color:var(--nf-text);font-weight:600}.zE6uZW_workflowHint{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2)}@keyframes zE6uZW_pulse{0%,to{opacity:1}50%{opacity:.45}}@keyframes zE6uZW_fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.zE6uZW_card{animation:.2s zE6uZW_fadeIn}.zE6uZW_bookshelf{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-8,8px) var(--nf-space-14,14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-16,16px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(26px)saturate(175%);z-index:1;flex-wrap:wrap;flex-shrink:0;margin:10px 12px 0;display:flex;position:relative}.zE6uZW_bookshelfLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);letter-spacing:1px;flex-shrink:0;font-weight:700}.zE6uZW_bookshelfList{align-items:center;gap:var(--nf-space-6,6px);flex-wrap:wrap;flex:1;min-width:0;display:flex}.zE6uZW_bookChip{align-items:center;gap:var(--nf-space-6,6px);padding:var(--nf-space-4,4px) var(--nf-space-8,8px) var(--nf-space-4,4px) var(--nf-space-10,10px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-999,999px);background:var(--nf-bg-inset);cursor:pointer;font-size:var(--nf-fs-12,12px);max-width:220px;transition:border-color .15s,background .15s;display:flex}.zE6uZW_bookChip:hover{border-color:var(--nf-border-strong)}.zE6uZW_bookChipActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.zE6uZW_bookChipName{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.zE6uZW_bookChipMeta{font-size:var(--nf-fs-12,11px);opacity:.7;white-space:nowrap}.zE6uZW_bookChipRemove{color:var(--nf-text-3);cursor:pointer;font-size:var(--nf-fs-14,13px);padding:0 var(--nf-space-2,2px);border-radius:var(--nf-radius-4,4px);background:0 0;border:none;line-height:1}.zE6uZW_bookChipRemove:hover{color:var(--nf-error)}.zE6uZW_bookAdd{border:1px dashed var(--nf-border-strong);color:var(--nf-text-2);cursor:pointer;font-size:var(--nf-fs-12,12px);padding:var(--nf-space-4,4px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);background:0 0;transition:border-color .15s,color .15s}.zE6uZW_bookAdd:hover{border-color:var(--nf-accent);color:var(--nf-accent)}.zE6uZW_bookCreateForm{align-items:center;gap:var(--nf-space-6,6px);display:flex}.zE6uZW_dropzone{border:2px dashed var(--nf-border-strong);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-18,18px) var(--nf-space-14,14px);text-align:center;font-size:var(--nf-fs-14,13px);color:var(--nf-text-2);cursor:pointer;align-items:center;gap:var(--nf-space-6,6px);flex-direction:column;transition:border-color .15s,background .15s;display:flex}.zE6uZW_dropzone:hover,.zE6uZW_dropzoneActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.zE6uZW_dropzoneIcon{font-size:var(--nf-fs-22,22px);line-height:1}.zE6uZW_bookCardActions{align-items:center;gap:var(--nf-space-6,6px);padding-top:var(--nf-space-8,8px);margin-top:auto;display:flex}.zE6uZW_bookCardActions .zE6uZW_button{flex:1;justify-content:center}.zE6uZW_readerView{flex-direction:column;transition:background .2s,color .2s;display:flex;position:absolute;inset:0;overflow:hidden}.zE6uZW_readerHeader{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);border-bottom:1px solid;flex-wrap:wrap;flex:none;display:flex}.zE6uZW_readerTitle{font-weight:700;font-size:var(--nf-fs-14,14px)}.zE6uZW_readerSeg{align-items:center;gap:var(--nf-space-2,2px);border-radius:var(--nf-radius-8,8px);display:flex;overflow:hidden}.zE6uZW_readerSegBtn{font-size:var(--nf-fs-12,12px);padding:var(--nf-space-4,3px) var(--nf-space-8,8px);border-radius:var(--nf-radius-6,6px);cursor:pointer;opacity:.75;background:0 0;border:none}.zE6uZW_readerSegBtn:hover,.zE6uZW_readerSegActive{opacity:1}.zE6uZW_readerBody{flex:1;align-items:stretch;min-height:0;display:flex}.zE6uZW_readerSidebar{width:220px;min-width:220px;padding:var(--nf-space-8,8px) var(--nf-space-6,6px) var(--nf-space-24,24px);scrollbar-width:thin;gap:var(--nf-space-10,10px);border-right:1px solid;flex-direction:column;flex:none;display:flex;overflow-y:auto}.zE6uZW_readerGroup{gap:var(--nf-space-2,1px);flex-direction:column;display:flex}.zE6uZW_readerGroupTitle{align-items:center;gap:var(--nf-space-6,6px);width:100%;font-size:var(--nf-fs-12,12px);padding:var(--nf-space-6,6px) var(--nf-space-8,8px) var(--nf-space-4,4px);opacity:.9;cursor:pointer;text-align:left;border-radius:var(--nf-radius-6,6px);background:0 0;border:none;font-weight:700;display:flex}.zE6uZW_readerGroupTitle:hover{opacity:1;background:#8080801f}.zE6uZW_readerGroupArrow{font-size:var(--nf-fs-12,10px);text-align:center;flex:none;width:12px}.zE6uZW_readerGroupCount{font-size:var(--nf-fs-12,11px);opacity:.6;padding-right:var(--nf-space-2,2px);flex:none;margin-left:auto;font-weight:400}.zE6uZW_readerItem{align-items:center;gap:var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);font-size:var(--nf-fs-12,12px);text-align:left;padding:var(--nf-space-4,4px) var(--nf-space-8,8px);cursor:pointer;opacity:.8;background:0 0;border:1px solid;min-width:0;transition:opacity .15s,background .15s;display:flex}.zE6uZW_readerItem:hover{opacity:1}.zE6uZW_readerItemActive{opacity:1;font-weight:700}.zE6uZW_readerItemNo{text-align:right;opacity:.75;flex:none;min-width:26px;font-weight:700}.zE6uZW_readerItemTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.zE6uZW_readerItemBadge{font-size:var(--nf-fs-12,11px);flex:none}.zE6uZW_readerMain{min-height:0;padding:var(--nf-space-20,20px) var(--nf-space-16,16px) var(--nf-space-48,48px);scrollbar-width:thin;flex:1;justify-content:center;display:flex;overflow-y:auto}.zE6uZW_readerArticle{gap:var(--nf-space-12,12px);flex-direction:column;width:100%;display:flex}.zE6uZW_readerChapterTitle{font-size:var(--nf-fs-24,24px);letter-spacing:1px;margin:0;font-weight:800}.zE6uZW_readerChapterMeta{align-items:center;gap:var(--nf-space-8,8px);font-size:var(--nf-fs-12,12px);display:flex}.zE6uZW_readerText{text-align:justify;letter-spacing:.02em}.zE6uZW_readerPara{text-indent:2em;margin:0 0 .85em}.zE6uZW_readerFoot{justify-content:space-between;align-items:center;gap:var(--nf-space-8,8px);padding-top:var(--nf-space-12,12px);border-top:1px dashed;margin-top:12px;display:flex}.zE6uZW_readerLoading,.zE6uZW_readerError{padding:var(--nf-space-32,32px) 0;font-size:var(--nf-fs-14,13px);opacity:.7;align-self:center}.zE6uZW_readerError{color:var(--nf-error)}.zE6uZW_importModalOverlay{z-index:1000;backdrop-filter:blur(4px);padding:var(--nf-space-24,24px);background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.zE6uZW_importModal{gap:var(--nf-space-12,12px);border:1px solid var(--nf-border-strong);border-radius:var(--nf-radius-16,16px);width:min(520px,100%);max-height:85vh;padding:var(--nf-card-pad,20px 22px);background:var(--nf-bg-raise);backdrop-filter:blur(28px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;display:flex;overflow:auto}.zE6uZW_importModalHead{justify-content:space-between;align-items:center;gap:var(--nf-space-10,10px);display:flex}.zE6uZW_importModalTabs{gap:var(--nf-space-8,8px);display:flex}.zE6uZW_importModalTabs .zE6uZW_button{flex:1}.zE6uZW_importModalBody{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_importField{gap:var(--nf-space-6,5px);font-size:var(--nf-fs-14,13px);color:var(--nf-text-2);flex-direction:column;display:flex}.zE6uZW_importHint{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);line-height:1.5}.zE6uZW_importError{border:1px solid color-mix(in srgb, var(--nf-danger,#e5484d) 55%, transparent);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px);font-size:var(--nf-fs-12,12.5px);color:var(--nf-danger,#e5484d);background:color-mix(in srgb, var(--nf-danger,#e5484d) 10%, transparent);white-space:pre-wrap;word-break:break-all}.zE6uZW_importResult{gap:var(--nf-space-4,4px);border:1px solid color-mix(in srgb, var(--nf-ok,#46a758) 45%, transparent);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,13px);background:color-mix(in srgb, var(--nf-ok,#46a758) 9%, transparent);word-break:break-all;flex-direction:column;display:flex}.zE6uZW_importModalActions{justify-content:flex-end;gap:var(--nf-space-8,8px);display:flex}.zE6uZW_importFileInfo{align-items:center;gap:var(--nf-space-8,8px);font-size:var(--nf-fs-14,13px);color:var(--nf-text-1);flex-wrap:wrap;display:flex}.zE6uZW_importPreview{gap:var(--nf-space-4,4px);border:1px solid var(--nf-border-strong);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,13px);background:var(--nf-bg-inset);flex-direction:column;display:flex}.zE6uZW_importPreviewList{padding-left:var(--nf-space-18,18px);gap:var(--nf-space-2,2px);font-size:var(--nf-fs-12,12.5px);color:var(--nf-text-2);flex-direction:column;max-height:140px;margin:0;display:flex;overflow:auto}.zE6uZW_settingsCard .zE6uZW_fieldLabel{white-space:nowrap;text-overflow:ellipsis;max-width:100%;min-height:18px;line-height:18px;overflow:hidden}.zE6uZW_settingsCard .zE6uZW_row{align-items:flex-start}.zE6uZW_helpTipText{width:280px;max-width:70vw;padding:var(--nf-space-10,10px) var(--nf-space-12,12px);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg-raise);border:1px solid var(--nf-border-strong);box-shadow:var(--nf-shadow-lg);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);white-space:normal;z-index:20;text-align:left;pointer-events:none;font-weight:400;line-height:1.7;display:none;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%)}.zE6uZW_helpTip:hover .zE6uZW_helpTipText,.zE6uZW_helpTip:focus .zE6uZW_helpTipText,.zE6uZW_helpTip:focus-within .zE6uZW_helpTipText{display:block}.zE6uZW_settingsCard+.zE6uZW_settingsCard{flex:1;min-height:0}.zE6uZW_switch{border-radius:var(--nf-radius-999,999px);border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);cursor:pointer;flex:none;width:42px;height:24px;padding:0;transition:background .18s,border-color .18s;position:relative}.zE6uZW_switchKnob{background:#fff;border-radius:50%;width:16px;height:16px;transition:transform .18s;position:absolute;top:3px;left:3px;box-shadow:0 1px 3px #0000004d}.zE6uZW_switchOn{background:var(--nf-accent);border-color:var(--nf-accent)}.zE6uZW_switchOn .zE6uZW_switchKnob{transform:translate(18px)}";
35428
+ const css = ".zE6uZW_entry{align-items:center;gap:var(--nf-space-8,8px);width:100%;padding:var(--nf-space-8,8px) var(--nf-space-12,12px);color:var(--dsw-alias-label-primary,#1f1f23);cursor:pointer;text-align:left;border-radius:var(--nf-radius-6,6px);background:0 0;border:none;font-size:14px;transition:background .15s;display:flex}body[data-ds-dark-theme] .zE6uZW_entry{color:var(--dsw-alias-label-primary,#ececf1)}.zE6uZW_entry:hover{background:var(--dsw-alias-interactive-bg-hover,#7f7f7f1f)}.zE6uZW_entry[data-active]{background:var(--dsw-alias-interactive-bg-active,#7f7f7f33)}.zE6uZW_entryIcon{flex-shrink:0;justify-content:center;align-items:center;width:20px;height:20px;display:inline-flex}.zE6uZW_entryLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-pane=conversation]{position:relative}.zE6uZW_view{z-index:60;color-scheme:light;--nf-font:-apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"SF Pro Text\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;--nf-font-mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #fff6 0%, #ffffff4d 26%, #ffffff3d 52%, #fff3 78%, #ffffff2e 100%);--nf-glass-core:radial-gradient(60% 40% at 30% 0%, #fff9 0%, #fff3 42%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffff80;--nf-glass-inset:#fff6;--nf-glass-orb-a:#00b85c3d;--nf-glass-orb-b:#78a0ff33;--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\");--nf-card-radius:20px;--nf-card-blur:26px;--nf-card-saturate:170%;--nf-card-brightness:1.04;--nf-card-sheen:#ffffff80;--nf-card-border:1px solid #ffffff59;--nf-ctrl-radius:14px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffffb3;--nf-ctrl-sheen:#ffffff80;--nf-ctrl-caret:var(--nf-accent);--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\");background:var(--nf-bg);backdrop-filter:blur(30px)saturate(170%)brightness(1.04);color:var(--nf-text);--nf-fs-10:10px;--nf-fs-12:12px;--nf-fs-14:14px;--nf-fs-16:16px;--nf-fs-18:18px;--nf-fs-20:20px;--nf-fs-22:22px;--nf-fs-24:24px;--nf-fs-34:34px;--nf-fs-42:42px;--nf-icon-s:14px;--nf-icon-m:16px;--nf-icon-l:18px;--nf-icon-xl:22px;--nf-space-2:2px;--nf-space-4:4px;--nf-space-6:6px;--nf-space-8:8px;--nf-space-10:10px;--nf-space-12:12px;--nf-space-14:14px;--nf-space-16:16px;--nf-space-18:18px;--nf-space-20:20px;--nf-space-24:24px;--nf-space-28:28px;--nf-space-32:32px;--nf-radius-2:2px;--nf-radius-4:4px;--nf-radius-6:6px;--nf-radius-8:8px;--nf-radius-10:10px;--nf-radius-12:12px;--nf-radius-14:14px;--nf-radius-16:16px;--nf-radius-20:20px;--nf-radius-22:22px;--nf-radius-999:999px;--nf-ctrl-s:28px;--nf-ctrl-m:32px;--nf-ctrl-l:38px;--nf-container-pad:20px 22px;--nf-container-gap:var(--nf-space-14,14px);--nf-card-pad:20px 22px;--nf-nav-pad:16px 12px 14px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Segoe UI,Roboto,Helvetica Neue,sans-serif;display:none;position:absolute;inset:0;overflow:auto}.zE6uZW_panel[data-nf-mode=dark],body[data-ds-dark-theme] .zE6uZW_panel:not([data-nf-mode]),.zE6uZW_view:has(>.zE6uZW_panel[data-nf-mode=dark]),body[data-ds-dark-theme] .zE6uZW_view:not(:has(>.zE6uZW_panel[data-nf-mode=light])){color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #3e424a85 0%, #363a4275 26%, #30343c66 52%, #2a2e365c 78%, #262a3257 100%);--nf-glass-core:radial-gradient(60% 40% at 30% 0%, #ffffff38 0%, #ffffff14 42%, #fff0 78%);--nf-glass-sheen:#ffffff3d;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff14;--nf-glass-orb-a:#00ca525c;--nf-glass-orb-b:#78a0ff47;--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\");--nf-card-radius:20px;--nf-card-blur:28px;--nf-card-saturate:165%;--nf-card-brightness:1;--nf-card-border:1px solid #ffffff24;--nf-card-sheen:#ffffff38;--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\");--nf-ctrl-radius:14px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffff2e;--nf-ctrl-sheen:#fff3;--nf-ctrl-caret:var(--nf-accent)}html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .zE6uZW_view{display:block}.zE6uZW_panel[data-nf-theme=macos],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-mode=light][data-nf-theme=macos]{--nf-bg:#f5f6f8eb;--nf-bg-raise:#ffffffc7;--nf-bg-inset:#7676801a;--nf-border:#3c3c4324;--nf-border-strong:#3c3c434d;--nf-text:#1d1d1f;--nf-text-2:#3a3a3c;--nf-text-2-alpha:#3a3a3cb3;--nf-text-3:#86868b;--nf-accent:#007aff;--nf-accent-hover:#0071e3;--nf-accent-soft:#007aff1f;--nf-accent-fg:#fff;--nf-hover:#0000000a;--nf-info:#5856d6;--nf-shadow:0 1px 3px #0000000d, 0 10px 28px #00000012;--nf-shadow-lg:0 4px 12px #0000000f, 0 18px 44px #0000001c;--nf-card-shadow:0 2px 6px #0000000d, 0 12px 34px #00000017;--nf-card-shadow-hover:0 4px 10px #00000012, 0 20px 48px #00000024;--nf-glass-face:#ffffffb3;--nf-glass-core:transparent;--nf-glass-sheen:#fffc;--nf-glass-border:#ffffffe6;--nf-glass-inset:#fff9;--nf-glass-orb-a:#007aff14;--nf-glass-orb-b:#5856d612;--nf-glass-noise:none;--nf-card-radius:12px;--nf-card-blur:42px;--nf-card-saturate:150%;--nf-card-border:1px solid var(--nf-border);--nf-card-sheen:#ffffff59;--nf-ctrl-radius:8px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid var(--nf-border-strong);--nf-ctrl-sheen:#ffffff59;--nf-ctrl-caret:var(--nf-accent)}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=macos],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=macos]:not([data-nf-mode]){--nf-bg:#1c1c1ee6;--nf-bg-raise:#2c2c2ed1;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff42;--nf-text:#f5f5f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b3;--nf-text-3:#98989d;--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-hover:#ffffff0f;--nf-info:#bf5af2;--nf-shadow:0 1px 2px #0006, 0 10px 30px #00000073;--nf-shadow-lg:0 4px 12px #00000073, 0 18px 44px #0009;--nf-card-shadow:0 2px 6px #0006, 0 14px 38px #00000080;--nf-card-shadow-hover:0 4px 10px #00000073, 0 22px 52px #0009;--nf-glass-face:#2c2c2ed9;--nf-glass-core:transparent;--nf-glass-sheen:#fff3;--nf-glass-border:#ffffff2e;--nf-glass-inset:#ffffff0f;--nf-glass-orb-a:#0a84ff29;--nf-glass-orb-b:#bf5af214;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_button{border:1px solid var(--nf-border-strong);background:color-mix(in srgb, var(--nf-bg-raise) 82%, #fff);box-shadow:0 1px 1px #0000000a,inset 0 1px #fff9}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 90%, #fff), var(--nf-accent));color:var(--nf-accent-fg);box-shadow:0 1px 3px color-mix(in srgb, var(--nf-accent) 45%, transparent), inset 0 1px 0 #ffffff59;border-color:#0000}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_input,.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_textarea{border:1px solid var(--nf-border-strong);background:var(--nf-bg-raise)}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_input:focus,.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.zE6uZW_panel[data-nf-theme=neumorph]{--nf-card-radius:20px;--nf-card-blur:0px;--nf-card-saturate:100%;--nf-card-border:none;--nf-card-sheen:#fff0;--nf-ctrl-radius:10px;--nf-ctrl-bg:var(--nf-bg-inset);--nf-ctrl-border:none;--nf-ctrl-sheen:#fff0;--nf-ctrl-caret:var(--nf-text-3);--nf-glass-bg-image:none}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph]:not([data-nf-mode]){--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=clay]{--nf-card-radius:28px;--nf-card-blur:0px;--nf-card-saturate:100%;--nf-card-brightness:1;--nf-card-border:1px solid #fff9;--nf-card-sheen:#ffffffd9;--nf-ctrl-radius:16px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffff8c;--nf-ctrl-sheen:#ffffffb3;--nf-ctrl-caret:var(--nf-accent);--nf-glass-bg-image:none}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay],.zE6uZW_panel[data-nf-mode=light][data-nf-theme=clay]{--nf-bg:#f2eae0;--nf-bg-raise:#efe4d6;--nf-bg-inset:#e6d8c6;--nf-border:#78604829;--nf-border-strong:#78604847;--nf-text:#3a3330;--nf-text-2:#5a4f48;--nf-text-2-alpha:#5a4f48b3;--nf-text-3:#9a8c80;--nf-accent:#e08a5c;--nf-accent-hover:#d67a4a;--nf-accent-soft:#e08a5c29;--nf-accent-fg:#fff;--nf-hover:#78604814;--nf-success:#7fae6a;--nf-error:#c96b63;--nf-warn:#d9a660;--nf-info:#e08a5c;--nf-shadow:0 8px 16px -6px #5a463247, inset 0 6px 10px #ffffff8c, inset 0 -6px 10px #7860481f;--nf-shadow-lg:0 16px 28px -10px #5a463257, inset 0 6px 10px #ffffff8c, inset 0 -6px 10px #78604824;--nf-card-shadow:0 16px 28px -10px #5a463257, inset 0 -8px 12px #78604824, inset 0 8px 12px #fff9;--nf-card-shadow-hover:0 22px 36px -12px #5a463261, inset 0 -8px 12px #78604829, inset 0 8px 12px #ffffffb3;--nf-glass-face:#efe4d6;--nf-glass-core:transparent;--nf-glass-sheen:#ffffffd9;--nf-glass-border:#fff9;--nf-glass-inset:#e6d8c6;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]){--nf-bg:#2a2522;--nf-bg-raise:#37302b;--nf-bg-inset:#2f2925;--nf-border:#ffffff14;--nf-border-strong:#ffffff2e;--nf-text:#efe9e3;--nf-text-2:#c7beb5;--nf-text-2-alpha:#c7beb5b3;--nf-text-3:#8a8078;--nf-accent:#e69a6c;--nf-accent-hover:#f0ac82;--nf-accent-soft:#e69a6c33;--nf-accent-fg:#241b16;--nf-hover:#ffffff0f;--nf-success:#9cba82;--nf-error:#d98f86;--nf-warn:#d9a660;--nf-info:#e69a6c;--nf-shadow:0 8px 16px -6px #0000008c, inset 0 6px 10px #ffffff1f, inset 0 -6px 10px #00000059;--nf-shadow-lg:0 16px 28px -10px #0000009e, inset 0 6px 10px #ffffff1f, inset 0 -6px 10px #0006;--nf-card-shadow:0 16px 28px -10px #0000009e, inset 0 -8px 12px #0006, inset 0 8px 12px #ffffff24;--nf-card-shadow-hover:0 22px 36px -12px #000000ad, inset 0 -8px 12px #00000070, inset 0 8px 12px #ffffff2e;--nf-glass-face:#37302b;--nf-glass-core:transparent;--nf-glass-sheen:#ffffff29;--nf-glass-border:#ffffff29;--nf-glass-inset:#2f2925;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=clay] .zE6uZW_input,.zE6uZW_panel[data-nf-theme=clay] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:var(--nf-border-strong);box-shadow:inset 3px 3px 7px #78604824,inset -3px -3px 7px #ffffff80}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_button{background:linear-gradient(#f6ecdf,#eee0cf);border-color:#fff9;box-shadow:0 8px 16px -6px #5a463259,inset 0 3px 4px #fffc,inset 0 -3px 5px #78604833}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_button:hover:not([disabled]){box-shadow:0 12px 22px -8px #5a46326b,inset 0 3px 4px #ffffffd9,inset 0 -3px 5px #78604838}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_buttonPrimary{color:var(--nf-accent-fg);background:linear-gradient(#eda178,#e08a5c);border-color:#0000;box-shadow:0 8px 16px -6px #e08a5c8c,inset 0 3px 4px #ffffff80,inset 0 -3px 5px #9646284d}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_button,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_button{background:linear-gradient(#403731,#332c27);border-color:#ffffff29;box-shadow:0 8px 16px -6px #0000008c,inset 0 3px 4px #ffffff24,inset 0 -3px 5px #0006}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_button:hover:not([disabled]),body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_button:hover:not([disabled]){box-shadow:0 12px 22px -8px #0009,inset 0 3px 4px #ffffff29,inset 0 -3px 5px #00000070}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_buttonPrimary,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_buttonPrimary{color:var(--nf-accent-fg);background:linear-gradient(#f0ac82,#d67a4a);border-color:#0000;box-shadow:0 8px 16px -6px #e69a6c80,inset 0 3px 4px #fff6,inset 0 -3px 5px #7832144d}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_input,.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_textarea,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_input,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_textarea{box-shadow:inset 3px 3px 7px #00000073,inset -3px -3px 7px #ffffff14}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input:focus,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #a3b1c680, inset -2px -2px 6px #ffffffd9, 0 0 0 3px var(--nf-accent-soft)}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input:focus,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #00000080, inset -2px -2px 6px #60687638, 0 0 0 3px var(--nf-accent-soft)}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #a3b1c68c,-5px -5px 10px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #a3b1c699,-7px -7px 14px #fffffff2}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_buttonPrimary{background:linear-gradient(#00c563,#00a952);box-shadow:5px 5px 10px #a3b1c699,-5px -5px 10px #ffffffd9}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #0000008c,-7px -7px 14px #60687642}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_buttonPrimary{background:linear-gradient(#3ddc86,#27b96a);box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}.zE6uZW_panel{min-width:0;height:100%;font-size:var(--nf-fs-14,14px);flex-direction:column;line-height:1.6;display:flex;position:relative;overflow:hidden}.zE6uZW_panel:before{content:\"\";z-index:0;pointer-events:none;background:linear-gradient(rgba(0, 0, 0, calc(var(--nf-glass-bg-dim,0) / 100)), rgba(0, 0, 0, calc(var(--nf-glass-bg-dim,0) / 100))), var(--nf-glass-bg-image,none) center / cover no-repeat, radial-gradient(46% 36% at 18% 12%, var(--nf-glass-orb-a), transparent 70%), radial-gradient(52% 42% at 88% 22%, var(--nf-glass-orb-b), transparent 72%), radial-gradient(120% 95% at 50% 42%, transparent 55%, #0202031a 100%);position:absolute;inset:0}.zE6uZW_panel[data-nf-theme=macos]{--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\")}.zE6uZW_panelTitle{font-size:var(--nf-fs-16,16px);letter-spacing:.2px;align-items:center;gap:var(--nf-space-8,8px);margin:0;font-weight:700;display:flex}.zE6uZW_panelTitle:before{content:\"\";border-radius:var(--nf-radius-2,2px);background:linear-gradient(180deg, var(--nf-accent), var(--nf-info));width:4px;height:16px}.zE6uZW_iconButton{cursor:pointer;font-size:var(--nf-fs-16,16px);color:var(--nf-text-2);padding:var(--nf-space-4,4px) var(--nf-space-10,9px);border-radius:var(--nf-radius-10,9px);background:0 0;border:none;transition:background .15s,color .15s,transform .1s}.zE6uZW_iconButton:hover{background:var(--nf-hover);color:var(--nf-text);transform:translateY(-1px)}.zE6uZW_tabBar{gap:var(--nf-space-2,2px);padding:var(--nf-space-8,8px) var(--nf-space-14,14px) 0;border-bottom:1px solid var(--nf-border);background:var(--nf-bg-raise);z-index:4;flex-shrink:0;display:flex;position:sticky;top:45px}.zE6uZW_tab{padding:var(--nf-space-8,7px) var(--nf-space-14,13px);cursor:pointer;border-radius:var(--nf-radius-8,8px) var(--nf-radius-8,8px) 0 0;font-size:var(--nf-fs-14,13.5px);color:var(--nf-text-2);background:0 0;border:none;font-weight:500;transition:color .15s,background .15s;position:relative}.zE6uZW_tab:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_tab[data-active]{color:var(--nf-accent);font-weight:600}.zE6uZW_tab[data-active]:after{content:\"\";border-radius:var(--nf-radius-2,2px) var(--nf-radius-2,2px) 0 0;background:var(--nf-accent);height:2.5px;position:absolute;bottom:-1px;left:10px;right:10px}.zE6uZW_panelContent{padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);z-index:1;flex-direction:column;flex:1;display:flex;position:relative;overflow:auto}.zE6uZW_panelBody{z-index:1;flex:1;min-height:0;display:flex;position:relative}.zE6uZW_panelNav{align-self:stretch;gap:var(--nf-space-6,6px);width:216px;padding:var(--nf-nav-pad,16px 12px 14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-16,18px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);flex-direction:column;flex:none;margin:10px 0 10px 12px;transition:width .18s;display:flex;overflow-y:auto}.zE6uZW_panelNavCollapsed{width:52px;padding:var(--nf-space-10,10px) var(--nf-space-6,6px)}.zE6uZW_navGroup{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_navGroupLabel{font-size:var(--nf-fs-12,12px);letter-spacing:.8px;text-transform:uppercase;color:var(--nf-text-3);padding:var(--nf-space-12,12px) var(--nf-space-10,10px) var(--nf-space-6,6px);user-select:none;font-weight:600}.zE6uZW_navGroupSep{background:var(--nf-border);height:1px;margin:6px 8px 4px}.zE6uZW_navSpacer{flex:1;min-height:8px}.zE6uZW_navAbout{gap:var(--nf-space-4,4px);padding:var(--nf-space-8,8px) var(--nf-space-6,6px) var(--nf-space-4,4px);border-top:1px solid var(--nf-border);flex-direction:column;flex:none;margin-top:4px;display:flex}.zE6uZW_navAboutRow{justify-content:space-between;align-items:center;gap:var(--nf-space-4,4px);cursor:pointer;font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);padding:var(--nf-space-4,4px) var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);text-align:left;white-space:nowrap;background:0 0;border:none;transition:color .15s,background .15s;display:flex}.zE6uZW_navAboutRow:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_navAboutUpdate{background:var(--nf-accent-soft);color:var(--nf-accent);cursor:pointer;font-size:var(--nf-fs-12,10.5px);padding:var(--nf-space-4,4px) var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);text-align:left;white-space:nowrap;border:none;font-weight:600}.zE6uZW_navAboutUpdate:hover{color:var(--nf-accent-hover)}.zE6uZW_panelNavCollapsed .zE6uZW_navAbout{padding:var(--nf-space-6,6px) var(--nf-space-2,2px) var(--nf-space-2,2px);align-items:center}.zE6uZW_panelNavCollapsed .zE6uZW_navAboutRow{padding:var(--nf-space-4,4px) 0;justify-content:center;width:100%}.zE6uZW_navTabBadge{min-width:18px;height:18px;padding:0 var(--nf-space-6,5px);border-radius:var(--nf-radius-999,999px);background:var(--nf-accent);color:#fff;font-size:var(--nf-fs-12,10.5px);text-align:center;flex:none;margin-left:auto;font-weight:700;line-height:18px;display:inline-block}.zE6uZW_panelNavCollapsed .zE6uZW_navTabBadge{min-width:18px;height:18px;line-height:18px;font-size:var(--nf-fs-12,9px);padding:0 var(--nf-space-6,5px);position:absolute;top:2px;right:2px}.zE6uZW_navTabBadgeDanger{background:var(--nf-error)}.zE6uZW_navTabBadgeWarn{background:var(--nf-warn)}.zE6uZW_navTabBadgeDone{background:var(--nf-success)}.zE6uZW_navTabBadgeLive{background:var(--nf-success);animation:1.2s ease-in-out infinite zE6uZW_navBadgePulse}@keyframes zE6uZW_navBadgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}.zE6uZW_navTab{align-items:center;gap:var(--nf-space-10,10px);cursor:pointer;border-radius:var(--nf-radius-10,10px);width:100%;padding:var(--nf-space-12,11px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,14px);color:var(--nf-text-2-alpha,var(--nf-text-2));text-align:left;white-space:nowrap;background:0 0;border:1px solid #0000;font-weight:500;transition:color .15s,background .15s,border-color .15s,box-shadow .15s;display:flex;position:relative}.zE6uZW_panelNavCollapsed .zE6uZW_navTab{padding:var(--nf-space-8,8px) 0;justify-content:center}.zE6uZW_navTab:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_navTab[data-active]{color:var(--nf-accent);background:color-mix(in srgb, var(--nf-text) 8%, transparent);border-color:color-mix(in srgb, var(--nf-text) 16%, transparent);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--nf-text) 6%, transparent);font-weight:600}.zE6uZW_navTab[data-active] .zE6uZW_navTabIcon{color:var(--nf-accent)}.zE6uZW_navTabIcon{text-align:center;width:22px;height:22px;font-size:var(--nf-fs-16,17px);flex:none;justify-content:center;align-items:center;line-height:1;display:inline-flex}.zE6uZW_navTabLabel{text-overflow:ellipsis;overflow:hidden}.zE6uZW_navTitle{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-2,2px) var(--nf-space-6,6px) var(--nf-space-12,12px);border-bottom:1px solid var(--nf-border);flex:none;min-width:0;margin-bottom:6px;display:flex}.zE6uZW_navTitleLogo{border-radius:var(--nf-radius-10,10px);background:linear-gradient(145deg, var(--nf-accent), var(--nf-accent-hover));width:34px;height:34px;color:var(--nf-accent-fg);font-weight:800;font-size:var(--nf-fs-14,15px);box-shadow:0 6px 16px var(--nf-accent-soft);flex:none;justify-content:center;align-items:center;display:flex}.zE6uZW_navTitleName{font-weight:700;font-size:var(--nf-fs-14,15px);letter-spacing:.2px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_navTitleBook{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_panelNavCollapsed .zE6uZW_navTitle{padding:var(--nf-space-2,2px) 0 var(--nf-space-10,10px);justify-content:center}.zE6uZW_panelNavCollapsed .zE6uZW_navTitleLogo{width:32px;height:var(--nf-ctrl-m,32px)}.zE6uZW_navActions{gap:var(--nf-space-6,6px);padding-top:var(--nf-space-8,8px);border-top:1px solid var(--nf-border);flex:none;margin-top:8px;display:flex}.zE6uZW_navActionBtn{border:1px solid var(--nf-border);color:var(--nf-text-2);cursor:pointer;border-radius:var(--nf-radius-10,10px);height:var(--nf-ctrl-m,32px);font-size:var(--nf-fs-14,14px);background:0 0;flex:1;justify-content:center;align-items:center;line-height:1;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.zE6uZW_navActionBtn:hover{background:var(--nf-hover);color:var(--nf-text);border-color:var(--nf-border-strong)}.zE6uZW_panelNavCollapsed .zE6uZW_navActions{flex-direction:column;align-items:stretch}.zE6uZW_bookSwitch{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-10,9px);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;text-align:left;font:inherit;color:var(--nf-text);flex:none;min-width:0;margin-top:4px;transition:background .15s,border-color .15s;display:flex}.zE6uZW_bookSwitch:hover{background:var(--nf-hover);border-color:var(--nf-border-strong)}.zE6uZW_bookSwitchCover{border-radius:var(--nf-radius-6,5px);background:linear-gradient(160deg, var(--nf-accent), color-mix(in srgb, var(--nf-accent) 45%, #000));width:26px;height:34px;color:var(--nf-accent-fg);font-size:var(--nf-fs-12,11px);flex:none;justify-content:center;align-items:center;font-weight:700;display:flex}.zE6uZW_bookSwitchName{font-size:var(--nf-fs-12,12.5px);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.zE6uZW_bookSwitchMeta{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_bookSwitchArrow{color:var(--nf-text-3);font-size:var(--nf-fs-12,12px);flex:none;margin-left:auto}.zE6uZW_statRowD{gap:var(--nf-space-12,12px);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));display:grid}.zE6uZW_statCardD{justify-content:space-between;align-items:flex-start;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;display:flex}.zE6uZW_statCardDLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3)}.zE6uZW_statCardDValue{font-size:var(--nf-fs-22,22px);color:var(--nf-text);margin-top:2px;font-weight:700}.zE6uZW_statCardDUnit{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);font-weight:400}.zE6uZW_statCardDDetail{font-size:var(--nf-fs-12,11.5px);color:var(--nf-text-3);text-overflow:ellipsis;white-space:nowrap;margin-top:2px;overflow:hidden}.zE6uZW_statCardDDown{color:var(--nf-error)}.zE6uZW_statCardDIcon{width:38px;height:var(--nf-ctrl-l,38px);border-radius:var(--nf-radius-12,12px);font-size:var(--nf-fs-18,18px);background:var(--nf-accent-soft);flex:none;justify-content:center;align-items:center;display:flex}.zE6uZW_statCardDIconRed{background:color-mix(in srgb, var(--nf-error) 13%, transparent)}.zE6uZW_tlBar{gap:var(--nf-space-6,6px);margin-top:8px;display:flex}.zE6uZW_tlSeg{gap:var(--nf-space-4,4px);cursor:pointer;min-width:0;font:inherit;background:0 0;border:none;flex-direction:column;flex:1;padding:0;display:flex}.zE6uZW_tlSegTrack{border-radius:var(--nf-radius-999,999px);background:var(--nf-hover);border:1px solid var(--nf-border);height:8px;overflow:hidden}.zE6uZW_tlSegFill{border-radius:var(--nf-radius-999,999px);background:var(--nf-accent);width:100%;height:100%;display:block}.zE6uZW_tlSegTodo .zE6uZW_tlSegFill{opacity:0}.zE6uZW_tlSegTodo .zE6uZW_tlSegTrack{background:0 0}.zE6uZW_tlSegCurrent .zE6uZW_tlSegTrack{border-color:var(--nf-accent);box-shadow:0 0 0 2px var(--nf-accent-soft)}.zE6uZW_tlSegCurrent .zE6uZW_tlSegFill{opacity:.45}.zE6uZW_tlSegLabel{font-size:var(--nf-fs-12,10.5px);color:var(--nf-text-3);text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_tlSegDone .zE6uZW_tlSegLabel{color:var(--nf-accent);font-weight:600}.zE6uZW_tlSeg:hover .zE6uZW_tlSegTrack{border-color:var(--nf-border-strong)}.zE6uZW_card{border:var(--nf-card-border,1px solid var(--nf-glass-border));border-radius:var(--nf-card-radius,22px);padding:var(--nf-card-pad,20px 22px);gap:var(--nf-space-10,10px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-card-sheen,var(--nf-glass-sheen)), inset 0 -1px 0 #ffffff1a;backdrop-filter:blur(var(--nf-card-blur,30px)) saturate(var(--nf-card-saturate,180%)) brightness(var(--nf-card-brightness,1.06));flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.zE6uZW_card:before{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-card-sheen,var(--nf-glass-sheen)), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.zE6uZW_card:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.zE6uZW_card:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-card-sheen,var(--nf-glass-sheen)), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.zE6uZW_card>*{z-index:1;position:relative}.zE6uZW_cardTitle{font-size:var(--nf-fs-14,14px);color:var(--nf-text);align-items:center;gap:var(--nf-space-8,8px);margin:0;font-weight:650;display:flex}.zE6uZW_button{border:1px solid var(--nf-ctrl-border,var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);padding:var(--nf-space-8,7px) var(--nf-space-16,15px);border-radius:var(--nf-ctrl-radius,10px);cursor:pointer;font-size:var(--nf-fs-14,13px);box-shadow:inset 0 1px 0 var(--nf-ctrl-sheen,#ffffff17);white-space:nowrap;font-weight:500;transition:background .15s,border-color .15s,transform .1s,box-shadow .15s}.zE6uZW_button:hover:not([disabled]){background:var(--nf-hover);border-color:var(--nf-border-strong);transform:translateY(-1px)}.zE6uZW_button:active:not([disabled]){transform:translateY(0)scale(.97)}.zE6uZW_button[disabled]{opacity:.45;cursor:not-allowed}.zE6uZW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #fff), var(--nf-accent));color:var(--nf-accent-fg);border-radius:var(--nf-radius-10,10px);box-shadow:0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 #ffffff73;border-color:#0000}.zE6uZW_buttonPrimary:hover:not([disabled]){background:linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000));box-shadow:0 12px 30px color-mix(in srgb, var(--nf-accent) 50%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 #ffffff73;border-color:#0000;transform:translateY(-1px)}.zE6uZW_buttonDanger{border-color:var(--nf-error);color:var(--nf-error)}.zE6uZW_buttonDanger:hover:not([disabled]){background:#ff3b301a}.zE6uZW_buttonSmall{padding:var(--nf-space-4,4px) var(--nf-space-10,10px);font-size:var(--nf-fs-12,12px);border-radius:var(--nf-ctrl-radius,8px)}.zE6uZW_field{gap:var(--nf-space-6,5px);flex-direction:column;display:flex}.zE6uZW_fieldLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);font-weight:500}.zE6uZW_input{border:var(--nf-ctrl-border,1px solid var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);color-scheme:light;border-radius:var(--nf-ctrl-radius,12px);padding:var(--nf-space-8,7px) var(--nf-space-12,11px);font-size:var(--nf-fs-14,13px);box-sizing:border-box;width:100%;box-shadow:inset 0 1px 0 var(--nf-ctrl-sheen,#ffffff17);transition:border-color .15s,box-shadow .15s}body[data-ds-dark-theme] .zE6uZW_input,.zE6uZW_panel[data-nf-mode=dark] .zE6uZW_input{color-scheme:dark}.zE6uZW_panel[data-nf-mode=light] .zE6uZW_input,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input{color-scheme:light}select.zE6uZW_input{cursor:pointer;-webkit-appearance:none;appearance:none;background-image:linear-gradient(45deg, transparent 50%, var(--nf-ctrl-caret,var(--nf-text-3)) 50%), linear-gradient(135deg, var(--nf-ctrl-caret,var(--nf-text-3)) 50%, transparent 50%);background-position:calc(100% - 18px),calc(100% - 12px);background-repeat:no-repeat;background-size:6px 6px,6px 6px;padding-right:30px}.zE6uZW_input option{color:var(--nf-text);background:var(--nf-bg-raise);font-size:var(--nf-fs-14,15px)}.zE6uZW_input:focus,.zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft);outline:none}.zE6uZW_input::placeholder,.zE6uZW_textarea::placeholder{color:var(--nf-text-3)}.zE6uZW_textarea{border:var(--nf-ctrl-border,1px solid var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);border-radius:var(--nf-ctrl-radius,12px);padding:var(--nf-space-10,9px) var(--nf-space-12,11px);font-size:var(--nf-fs-14,13px);box-sizing:border-box;resize:vertical;width:100%;min-height:200px;font-family:inherit;line-height:1.7;transition:border-color .15s,box-shadow .15s}.zE6uZW_row{align-items:center;gap:var(--nf-space-8,8px);flex-wrap:wrap;display:flex}.zE6uZW_spaceBetween{justify-content:space-between}.zE6uZW_chapterList{gap:var(--nf-space-8,8px);flex-direction:column;display:flex}.zE6uZW_volumeGroup{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_volumeGroupHeader{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;user-select:none;font-size:var(--nf-fs-14,13px);transition:border-color .15s;display:flex}.zE6uZW_volumeGroupHeader:hover{border-color:var(--nf-accent)}.zE6uZW_volumeGroupToggle{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);flex:none}.zE6uZW_chapter{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-10,9px) var(--nf-space-12,12px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg);transition:border-color .15s,box-shadow .15s,transform .1s;display:flex}.zE6uZW_chapter:hover{border-color:var(--nf-border-strong);box-shadow:var(--nf-shadow)}.zE6uZW_chapterFocus{animation:.9s ease-in-out 3 zE6uZW_chapterFocusPulse;border-color:var(--nf-accent)!important;box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 35%, transparent)!important}@keyframes zE6uZW_chapterFocusPulse{0%,to{background:var(--nf-bg)}50%{background:color-mix(in srgb, var(--nf-accent) 18%, var(--nf-bg))}}.zE6uZW_chapterNum{min-width:28px;height:var(--nf-ctrl-s,28px);padding:0 var(--nf-space-8,8px);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);flex-shrink:0;justify-content:center;align-items:center;font-weight:700;display:inline-flex}.zE6uZW_chapterMain{flex:1;min-width:0}.zE6uZW_chapterTitle{font-weight:600;font-size:var(--nf-fs-14,13px);align-items:center;gap:var(--nf-space-8,8px);color:var(--nf-text);display:flex}.zE6uZW_chapterBeats{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_chapterActions{gap:var(--nf-space-4,4px);opacity:.85;flex-shrink:0;transition:opacity .15s;display:flex}.zE6uZW_chapter:hover .zE6uZW_chapterActions{opacity:1}.zE6uZW_badge{font-size:var(--nf-fs-12,11px);padding:var(--nf-space-2,2px) var(--nf-space-10,9px);border-radius:var(--nf-radius-999,999px);white-space:nowrap;letter-spacing:.2px;border:1px solid;font-weight:600}.zE6uZW_badgePending{color:var(--nf-info);border-color:var(--nf-info);background:color-mix(in srgb, var(--nf-info) 10%, transparent)}.zE6uZW_badgeGenerating{color:var(--nf-accent);border-color:var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 12%, transparent);animation:1.2s ease-in-out infinite zE6uZW_pulse}.zE6uZW_badgeWritten{color:var(--nf-warn);border-color:var(--nf-warn);background:color-mix(in srgb, var(--nf-warn) 10%, transparent)}.zE6uZW_badgeRejected{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.zE6uZW_badgeDone{color:var(--nf-success);border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 10%, transparent)}.zE6uZW_badgeError{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.zE6uZW_reviewBox{border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:var(--nf-bg-inset);gap:var(--nf-space-6,6px);font-size:var(--nf-fs-12,12.5px);flex-direction:column;display:flex}.zE6uZW_chapterPreview{white-space:pre-wrap;word-break:break-all;max-height:320px;font-size:var(--nf-fs-12,12.5px);color:var(--nf-text);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);margin:0;font-family:inherit;line-height:1.8;overflow:auto}.zE6uZW_chatScroll{gap:var(--nf-space-10,10px);min-height:240px;max-height:480px;padding:var(--nf-space-14,14px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);flex-direction:column;flex:1;display:flex;overflow-y:auto}.zE6uZW_chatBubbleUser{background:linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));max-width:90%;color:var(--nf-accent-fg);border-radius:var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-4,4px) var(--nf-radius-14,14px);padding:var(--nf-space-10,9px) var(--nf-space-14,14px);font-size:var(--nf-fs-14,13px);align-self:flex-end;box-shadow:0 2px 6px #4d6bfe33}.zE6uZW_chatBubbleAssistant{background:var(--nf-bg-raise);max-width:92%;color:var(--nf-text);border:1px solid var(--nf-border);border-radius:var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-4,4px);padding:var(--nf-space-10,9px) var(--nf-space-14,14px);font-size:var(--nf-fs-14,13px);box-shadow:var(--nf-shadow);align-self:flex-start}.zE6uZW_chatRole{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);margin-bottom:3px;font-weight:600}.zE6uZW_toolLive{padding:var(--nf-space-8,8px) var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);border:1px dashed var(--nf-border-strong);font-size:var(--nf-fs-12,12px);white-space:pre-wrap;word-break:break-all;color:var(--nf-text-2);max-height:180px;margin-top:6px;line-height:1.7;overflow-y:auto}.zE6uZW_assistantStatus{padding:var(--nf-space-6,6px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);background:var(--nf-bg-inset);border:1px solid var(--nf-border);align-items:center;gap:var(--nf-space-6,6px);flex:none;margin-top:6px;display:flex}.zE6uZW_assistantStatusBusy{color:var(--nf-accent);border-color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.zE6uZW_toolSteps{gap:var(--nf-space-4,4px);flex-direction:column;margin-top:6px;display:flex}.zE6uZW_toolStep{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-6,5px) var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);font-size:var(--nf-fs-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);display:flex}.zE6uZW_toolStepActive{border-color:var(--nf-accent);background:var(--nf-accent-soft)}.zE6uZW_toolStepError{border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.zE6uZW_toolStepIcon{font-size:var(--nf-fs-14,13px);flex:none}.zE6uZW_toolStepName{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:600;overflow:hidden}.zE6uZW_toolStepStatus{color:var(--nf-text-2);font-size:var(--nf-fs-12,11px);flex:none}.zE6uZW_toolStepActive .zE6uZW_toolStepStatus{color:var(--nf-accent)}.zE6uZW_toolStepError .zE6uZW_toolStepStatus{color:var(--nf-error)}.zE6uZW_toolStepDetail{width:100%;color:var(--nf-error);font-size:var(--nf-fs-12,11px);word-break:break-all}.zE6uZW_progress{border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);font-size:var(--nf-fs-12,12px);white-space:pre-wrap;word-break:break-all;min-height:60px;max-height:220px;color:var(--nf-text-2);font-family:var(--nf-font-mono);background:var(--nf-bg-inset);line-height:1.8;overflow:auto}.zE6uZW_progressLine{color:var(--nf-text-2);opacity:.9}.zE6uZW_progressLineLive{color:var(--nf-accent);align-items:center;gap:var(--nf-space-8,8px);font-weight:600;display:flex}.zE6uZW_progressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);flex:none;width:110px;height:6px;display:inline-block;overflow:hidden}.zE6uZW_progressBarFill{border-radius:var(--nf-radius-4,3px);background:var(--nf-accent);height:100%;transition:width .3s;display:block}.zE6uZW_busyRow{justify-content:space-between;align-items:center;gap:var(--nf-space-12,12px);flex-wrap:wrap;display:flex}.zE6uZW_liveText{font-size:var(--nf-fs-12,12px);font-variant-numeric:tabular-nums;color:var(--nf-text-2)}.zE6uZW_bigProgressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:8px;margin-top:10px;overflow:hidden}.zE6uZW_bigProgressBarFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2,var(--nf-accent)));height:100%;transition:width .3s;display:block}.zE6uZW_diffLegend{align-items:center;gap:var(--nf-space-14,14px);font-size:var(--nf-fs-12,12px);flex-wrap:wrap;margin:6px 0 8px;display:flex}.zE6uZW_legendOld{color:var(--nf-error);font-weight:700}.zE6uZW_legendNew{color:var(--nf-success);font-weight:700}.zE6uZW_onlyChanges{align-items:center;gap:var(--nf-space-4,4px);color:var(--nf-text-2);cursor:pointer;margin-left:auto;display:inline-flex}.zE6uZW_diffList{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);min-height:0;padding:var(--nf-space-10,10px) var(--nf-space-12,12px);gap:var(--nf-space-8,8px);font-size:var(--nf-fs-14,13px);flex-direction:column;flex:1;line-height:1.7;display:flex;overflow-y:auto}.zE6uZW_diffSame{border:1px dashed var(--nf-border);border-radius:var(--nf-radius-6,6px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);color:var(--nf-text-2);opacity:.85}.zE6uZW_diffSame summary{cursor:pointer;font-size:var(--nf-fs-12,12px);user-select:none}.zE6uZW_diffSameBody{white-space:pre-wrap;margin-top:6px}.zE6uZW_diffChange{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);grid-template-columns:1fr 1fr;display:grid;overflow:hidden}.zE6uZW_diffColumn{gap:var(--nf-space-6,6px);min-width:0;padding:var(--nf-space-8,8px) var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_diffColumn:first-child{border-right:1px solid var(--nf-border)}.zE6uZW_diffTagOld,.zE6uZW_diffTagNew{font-size:var(--nf-fs-12,11px);border-radius:var(--nf-radius-4,4px);padding:var(--nf-space-2,1px) var(--nf-space-8,7px);letter-spacing:.5px;flex:none;align-self:flex-start;font-weight:700}.zE6uZW_diffTagOld{color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-error) 45%, transparent)}.zE6uZW_diffTagNew{color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-success) 45%, transparent)}.zE6uZW_diffOld{color:var(--nf-error);white-space:pre-wrap;text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 55%, transparent)}.zE6uZW_diffNew{color:var(--nf-success);white-space:pre-wrap;font-weight:500}.zE6uZW_diffDel{gap:var(--nf-space-4,4px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-6,6px);border:1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);background:color-mix(in srgb, var(--nf-error) 7%, transparent);flex-direction:column;display:flex}.zE6uZW_diffAdd{gap:var(--nf-space-4,4px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-6,6px);border:1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);background:color-mix(in srgb, var(--nf-success) 7%, transparent);flex-direction:column;display:flex}.zE6uZW_diffText{white-space:pre-wrap}.zE6uZW_diffDel .zE6uZW_diffText{color:var(--nf-error);text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 50%, transparent)}.zE6uZW_diffAdd .zE6uZW_diffText{color:var(--nf-success)}.zE6uZW_wsPage{gap:var(--nf-space-10,10px);flex-direction:column;flex:1;min-height:0;display:flex}.zE6uZW_wsPageHeader{align-items:center;gap:var(--nf-space-8,8px);flex-wrap:wrap;flex:none;display:flex}.zE6uZW_wsAppliedBanner{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);border:1px solid var(--nf-success);border-radius:var(--nf-radius-10,10px);background:color-mix(in srgb, var(--nf-success) 8%, transparent);font-size:var(--nf-fs-12,12px);flex-wrap:wrap;flex:none;font-weight:600;display:flex}.zE6uZW_wsColumns{gap:var(--nf-space-14,14px);flex:1;grid-template-columns:minmax(0,1fr) minmax(0,1fr);min-height:0;display:grid}.zE6uZW_wsColumn{gap:var(--nf-space-8,8px);flex-direction:column;min-width:0;min-height:0;display:flex}.zE6uZW_wsEditor{resize:vertical;min-height:0;font-family:var(--nf-font);font-size:var(--nf-fs-14,13px);white-space:pre-wrap;flex:1;line-height:1.75}.zE6uZW_wsSelected{border:1px solid var(--nf-accent);border-radius:var(--nf-radius-6,6px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);background:color-mix(in srgb, var(--nf-accent) 8%, transparent);max-height:120px;overflow:auto}.zE6uZW_wsSelectedText{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);white-space:pre-wrap;margin-top:4px}.zE6uZW_wsPreview{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px);gap:var(--nf-space-8,8px);background:var(--nf-bg-inset);flex-direction:column;display:flex}.zE6uZW_wsPreviewText{min-height:0;font-size:var(--nf-fs-14,13px);white-space:pre-wrap;color:var(--nf-text);flex:1;margin:0;line-height:1.7;overflow:auto}.zE6uZW_assetGrid{gap:var(--nf-space-10,10px);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));display:grid}.zE6uZW_assetGroups{gap:var(--nf-space-14,14px);flex-direction:column;display:flex}.zE6uZW_assetGroup{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_assetGroupHeader{color:var(--nf-accent);border-bottom:1px solid var(--nf-glass-border);align-items:center;gap:8px;padding-bottom:2px;font-size:14px;font-weight:600;display:flex}.zE6uZW_assetStat{border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);gap:var(--nf-space-4,4px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(30px)saturate(180%);flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex}.zE6uZW_assetStat:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1px 0 var(--nf-glass-sheen);transform:translateY(-3px)}.zE6uZW_assetStatLabel{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);opacity:.9}.zE6uZW_assetStatValue{font-size:var(--nf-fs-14,15px);color:var(--nf-text);font-weight:700;line-height:1.2}.zE6uZW_assetStatDetail{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_dashHero{border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);padding:var(--nf-card-pad,20px 22px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;backdrop-filter:blur(30px)saturate(180%);gap:var(--nf-space-14,14px);flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.zE6uZW_dashHero:before{content:\"\";border-radius:inherit;pointer-events:none;background:radial-gradient(46% 40% at 92% -10%, color-mix(in srgb, var(--nf-accent) 13%, transparent), transparent 62%), var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.zE6uZW_dashHero:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.zE6uZW_dashHero:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.zE6uZW_dashHero>*{z-index:1;position:relative}.zE6uZW_dashHeroEyebrow{align-items:center;gap:var(--nf-space-6,6px);font-size:var(--nf-fs-14,13px);color:var(--nf-accent);font-weight:600;display:inline-flex}.zE6uZW_dashHeroSparkle{font-size:var(--nf-fs-14,14px)}.zE6uZW_dashHeroTitle{gap:var(--nf-space-2,2px);flex-direction:column;display:flex}.zE6uZW_dashHeroBook{font-size:var(--nf-fs-24,24px);letter-spacing:-.3px;margin:0;font-weight:700;line-height:1.25}.zE6uZW_dashHeroAction{align-items:center;gap:var(--nf-space-12,12px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);display:flex}.zE6uZW_dashHeroArrow{width:28px;height:var(--nf-ctrl-s,28px);background:var(--nf-accent);color:#fff;font-size:var(--nf-fs-14,14px);border-radius:50%;flex:none;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_dashHeroActionBody{gap:var(--nf-space-2,2px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_dashHeroActionTitle{font-size:var(--nf-fs-14,14px);font-weight:600}.zE6uZW_dashJourney{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_dashJourneyBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:6px;overflow:hidden}.zE6uZW_dashJourneyFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));height:100%;transition:width .4s;display:block}.zE6uZW_dashJourneyStages{gap:var(--nf-space-4,4px);grid-template-columns:repeat(6,minmax(0,1fr));display:grid}.zE6uZW_dashStage{align-items:center;gap:var(--nf-space-4,3px);font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);text-align:center;white-space:nowrap;flex-direction:column;display:flex}.zE6uZW_dashStageDot{border:1px solid var(--nf-border-strong,var(--nf-text-3));width:18px;height:18px;font-size:var(--nf-fs-12,10px);background:var(--nf-bg-base);border-radius:50%;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_dashStageDone{color:var(--nf-text-2)}.zE6uZW_dashStageDone .zE6uZW_dashStageDot{background:var(--nf-success);border-color:var(--nf-success);color:#fff}.zE6uZW_dashStageCurrent{color:var(--nf-accent);font-weight:600}.zE6uZW_dashStageCurrent .zE6uZW_dashStageDot{border-color:var(--nf-accent);color:var(--nf-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 18%, transparent)}.zE6uZW_dashFacts{gap:var(--nf-space-8,8px);border-top:1px solid var(--nf-border);padding-top:var(--nf-space-12,12px);grid-template-columns:repeat(4,minmax(0,1fr));display:grid}.zE6uZW_dashFact{gap:var(--nf-space-2,2px);flex-direction:column;min-width:0;display:flex}.zE6uZW_dashFact b{font-size:var(--nf-fs-14,13px);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_dashGrid{gap:var(--nf-space-14,14px);grid-template-columns:minmax(0,3fr) minmax(0,2fr);align-items:start;display:grid}.zE6uZW_todoItem{align-items:center;gap:var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);font-size:var(--nf-fs-12,12.5px);border:1px solid var(--nf-border);display:flex}.zE6uZW_todoDanger{border-color:color-mix(in srgb, var(--nf-error) 40%, transparent);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.zE6uZW_todoWarning{border-color:color-mix(in srgb, var(--nf-warn) 40%, transparent);background:color-mix(in srgb, var(--nf-warn) 8%, transparent)}.zE6uZW_todoInfo{border-color:color-mix(in srgb, var(--nf-info) 40%, transparent);background:color-mix(in srgb, var(--nf-info) 7%, transparent)}.zE6uZW_todoText{gap:var(--nf-space-2,2px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_outlineReadonly{padding:var(--nf-space-12,12px) var(--nf-space-14,14px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);font-size:var(--nf-fs-12,12.5px);white-space:pre-wrap;user-select:text;max-height:480px;margin:0;line-height:1.8;overflow:auto}.zE6uZW_bookCreateOutline{gap:var(--nf-space-6,6px);flex-direction:column;align-items:flex-start;display:flex}.zE6uZW_assistantFloat{z-index:80;border:1px solid var(--nf-border);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;min-width:320px;min-height:220px;display:flex;position:absolute;overflow:hidden}.zE6uZW_assistantFloatHeader{justify-content:space-between;align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px) var(--nf-space-8,8px) var(--nf-space-14,14px);cursor:grab;user-select:none;font-size:var(--nf-fs-14,13px);border-bottom:1px solid var(--nf-border);background:var(--nf-bg-inset);flex:none;font-weight:600;display:flex}.zE6uZW_assistantFloatHeader:active{cursor:grabbing}.zE6uZW_assistantFloatBody{min-height:0;padding:var(--nf-space-10,10px);flex:1;display:flex;overflow:hidden}.zE6uZW_assistantFloatBody>*{flex:1;min-width:0}.zE6uZW_assistantResize{cursor:nwse-resize;background:linear-gradient(135deg, transparent 0 55%, var(--nf-border-strong) 55% 62%, transparent 62%) no-repeat 4px 4px / 12px 12px;width:20px;height:20px;position:absolute;bottom:0;right:0}.zE6uZW_coverPreview{border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);flex:none;justify-content:center;align-items:center;width:150px;height:200px;display:flex;overflow:hidden}.zE6uZW_coverPreview img{object-fit:contain;width:100%;height:100%;display:block}.zE6uZW_coverPlaceholder{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3)}.zE6uZW_shelfView{min-height:0;padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);flex-direction:column;flex:1;display:flex;overflow:auto}.zE6uZW_authorHome{z-index:1;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.zE6uZW_authorRail{border-right:1px solid var(--nf-glass-border);background:var(--nf-glass-face);flex-direction:column;flex-shrink:0;gap:4px;width:180px;padding:14px 10px;display:flex}.zE6uZW_authorRailTitle{color:var(--nf-accent);align-items:center;gap:8px;padding:4px 8px 12px;font-weight:600;display:flex}.zE6uZW_authorRailBtn{color:var(--nf-text);cursor:pointer;text-align:left;background:0 0;border:1px solid #0000;border-radius:10px;align-items:center;gap:10px;width:100%;padding:8px 12px;font-size:14px;display:flex}.zE6uZW_authorRailBtn:hover{background:color-mix(in srgb, var(--nf-accent) 12%, transparent);color:var(--nf-text)}.zE6uZW_authorRailBtnActive{background:color-mix(in srgb, var(--nf-accent) 16%, var(--nf-glass-face));border-color:var(--nf-accent);color:var(--nf-accent);box-shadow:inset 0 0 0 1px var(--nf-accent);font-weight:600}.zE6uZW_authorRailAbout{padding:8px 12px}.zE6uZW_authorContent{flex-direction:column;flex:1;min-width:0;display:flex;overflow:hidden}.zE6uZW_authorPageBody{padding:var(--nf-container-pad,20px 22px);flex-direction:column;flex:1;gap:14px;min-height:0;display:flex;overflow:auto}.zE6uZW_authorPageHeader{flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:14px;display:flex}.zE6uZW_authorPageHero{gap:var(--nf-space-12,12px);padding:var(--nf-card-pad,20px 22px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);backdrop-filter:blur(26px)saturate(175%);flex-direction:column;display:flex}.zE6uZW_noticeError{background:color-mix(in srgb, var(--nf-error) 14%, transparent);color:var(--nf-error);border:1px solid var(--nf-error);border-radius:10px;padding:10px 14px}.zE6uZW_rowEnd{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.zE6uZW_assetFilterBar{flex-wrap:wrap;gap:8px;display:flex}.zE6uZW_assetFilterChip{border:1px solid var(--nf-glass-border);color:var(--nf-text);cursor:pointer;background:0 0;border-radius:999px;padding:4px 10px}.zE6uZW_assetFilterChipActive{background:var(--nf-accent);color:#fff;border-color:#0000}.zE6uZW_assetEditor{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:12px;padding:16px;display:flex}.zE6uZW_assetEditorRow{flex-wrap:wrap;gap:12px;display:flex}.zE6uZW_assetLabel{color:var(--nf-muted);flex-direction:column;flex:1;gap:4px;min-width:180px;font-size:12px;display:flex}.zE6uZW_assetTextarea{resize:vertical;min-height:160px;font-family:inherit}.zE6uZW_assetGrid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;display:grid}.zE6uZW_assetCard{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.zE6uZW_assetCardTop{justify-content:space-between;align-items:center;gap:8px;display:flex}.zE6uZW_assetKind{font-size:12px;font-weight:600}.zE6uZW_assetCardName{font-weight:600}.zE6uZW_assetCardContent{white-space:pre-wrap;color:var(--nf-text);max-height:150px;font-size:13px;overflow:auto}.zE6uZW_assetCardFooter{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.zE6uZW_iconBtn{color:var(--nf-text);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:8px;justify-content:center;align-items:center;padding:4px;display:inline-flex}.zE6uZW_iconBtn:hover{background:#0000000f}.zE6uZW_adaptInputCard{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:12px;padding:16px;display:flex}.zE6uZW_adaptTextarea{resize:vertical;min-height:220px}.zE6uZW_adaptResult{flex-direction:column;gap:14px;display:flex}.zE6uZW_adaptOutline{background:var(--nf-glass-face);border:1px solid var(--nf-glass-border);border-radius:12px;padding:10px 14px}.zE6uZW_adaptMatrix{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:12px;display:grid}.zE6uZW_dimCard{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.zE6uZW_dimCardHead{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.zE6uZW_dimTitle{font-weight:600}.zE6uZW_dimCurrent{white-space:pre-wrap;font-size:13px}.zE6uZW_dimCardSelected{border-color:var(--nf-accent);box-shadow:0 0 0 1px var(--nf-accent)}.zE6uZW_dimEdit{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.zE6uZW_adaptOutlinePre{white-space:pre-wrap;max-height:260px;margin:0;font-family:inherit;font-size:13px;overflow:auto}.zE6uZW_adaptProposal{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.zE6uZW_adaptTable{border-collapse:collapse;width:100%;font-size:13px}.zE6uZW_adaptTable th,.zE6uZW_adaptTable td{border:1px solid var(--nf-glass-border);text-align:left;padding:6px 8px}.zE6uZW_adaptImpacts{flex-direction:column;gap:4px;display:flex}.zE6uZW_adaptImpact{font-size:13px}.zE6uZW_progressOverview{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;display:grid}.zE6uZW_progressOverviewCard{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;flex-direction:column;gap:4px;padding:14px;display:flex}.zE6uZW_progressOverviewNum{color:var(--nf-accent);font-size:24px;font-weight:700}.zE6uZW_progressTotalBar{background:var(--nf-glass-face);border:1px solid var(--nf-glass-border);border-radius:999px;height:14px;position:relative;overflow:hidden}.zE6uZW_progressTotalFill{background:linear-gradient(90deg, var(--nf-accent), var(--nf-info));border-radius:999px;height:100%;position:absolute;inset:0 auto 0 0}.zE6uZW_progressTotalBar .zE6uZW_meta{color:var(--nf-text);justify-content:center;align-items:center;font-size:11px;font-weight:600;display:flex;position:absolute;inset:0}.zE6uZW_progressBookList{flex-direction:column;gap:12px;display:flex}.zE6uZW_progressBook{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.zE6uZW_progressBookActive{border-color:var(--nf-accent);box-shadow:0 0 0 1px var(--nf-accent)}.zE6uZW_progressBookHead{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.zE6uZW_progressBookName{font-weight:600}.zE6uZW_progressLive{color:var(--nf-accent);font-weight:600}.zE6uZW_progressBookBar{background:var(--nf-glass-face-hover,#0000000d);border-radius:999px;height:8px;overflow:hidden}.zE6uZW_progressBookFill{background:var(--nf-accent);border-radius:999px;height:100%}.zE6uZW_shelfHeader{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_shelfHero{gap:var(--nf-space-14,14px);padding:var(--nf-card-pad,20px 22px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);flex-direction:column;display:flex}.zE6uZW_shelfHero .zE6uZW_panelTitle{font-size:var(--nf-fs-22,22px);letter-spacing:.3px}.zE6uZW_shelfTitleRow{justify-content:space-between;align-items:center;gap:var(--nf-space-10,10px);flex-wrap:wrap;display:flex}.zE6uZW_shelfToolbar{align-items:center;gap:var(--nf-space-10,10px);flex-wrap:wrap;display:flex}.zE6uZW_shelfSearch{flex:1;min-width:180px;max-width:320px}.zE6uZW_shelfStats{gap:var(--nf-space-10,10px);grid-template-columns:repeat(auto-fit,minmax(120px,1fr));display:grid}.zE6uZW_shelfStat{justify-content:space-between;align-items:baseline;gap:var(--nf-space-8,8px);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);cursor:pointer;user-select:none;transition:border-color .15s,background .15s,box-shadow .15s,transform .1s;display:flex}.zE6uZW_shelfStat:hover{border-color:var(--nf-accent);transform:translateY(-1px)}.zE6uZW_shelfStatActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);box-shadow:0 0 0 2px var(--nf-accent-soft), var(--nf-shadow)}.zE6uZW_shelfStat b{font-size:var(--nf-fs-20,20px);color:var(--nf-accent);font-weight:800}.zE6uZW_shelfStat span{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2)}.zE6uZW_shelfFilters{gap:var(--nf-space-2,2px);padding:var(--nf-space-4,3px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-999,999px);background:var(--nf-bg-inset);display:inline-flex}.zE6uZW_shelfFilter{color:var(--nf-text-2);font-size:var(--nf-fs-12,12.5px);padding:var(--nf-space-6,5px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);cursor:pointer;align-items:center;gap:var(--nf-space-6,5px);white-space:nowrap;background:0 0;border:none;font-weight:600;transition:background .15s,color .15s,box-shadow .15s;display:inline-flex}.zE6uZW_shelfFilter:hover{color:var(--nf-text)}.zE6uZW_shelfFilterActive{background:linear-gradient(135deg, var(--nf-accent), var(--nf-accent-hover));color:var(--nf-accent-fg);box-shadow:0 3px 12px color-mix(in srgb, var(--nf-accent) 40%, transparent)}.zE6uZW_shelfFilterCount{font-size:var(--nf-fs-12,10.5px);opacity:.8;background:color-mix(in srgb, currentColor 14%, transparent);border-radius:var(--nf-radius-999,999px);padding:0 var(--nf-space-6,6px)}.zE6uZW_shelfEmpty{justify-content:center;align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-40,40px) var(--nf-space-20,20px);border:1px dashed var(--nf-border-strong);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);text-align:center;flex-direction:column;flex:1;display:flex}.zE6uZW_shelfEmptyIcon{font-size:var(--nf-fs-42,42px)}.zE6uZW_shelfEmptyTitle{font-size:var(--nf-fs-16,16px);font-weight:700}.zE6uZW_shelfGrid{gap:var(--nf-container-gap,14px);grid-template-columns:repeat(auto-fill,minmax(190px,1fr));align-content:start;display:grid}.zE6uZW_panel{--nf-container-pad:20px 22px;--nf-container-gap:var(--nf-space-14,14px);--nf-card-pad:20px 22px;--nf-nav-pad:16px 12px 14px}.zE6uZW_panel[data-nf-density=compact]{--nf-container-pad:12px 14px;--nf-container-gap:var(--nf-space-8,8px);--nf-card-pad:12px 14px;--nf-nav-pad:8px 8px}.zE6uZW_panel[data-nf-density=spacious]{--nf-container-pad:24px 28px;--nf-container-gap:var(--nf-space-18,18px);--nf-card-pad:22px 26px;--nf-nav-pad:18px 14px}.zE6uZW_panel[data-nf-mode=light]{color-scheme:light;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff80 0%, #ffffff38 45%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffffa6;--nf-glass-inset:#ffffff8c;--nf-glass-orb-a:#00b85c2e;--nf-glass-orb-b:#78a0ff21}.zE6uZW_panel[data-nf-mode=dark]{color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #70747a6b 0%, #60646a6b 26%, #52555a6b 52%, #44474c6b 78%, #383a3f6b 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff42 0%, #ffffff1a 45%, #fff0 78%);--nf-glass-sheen:#ffffff42;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff12;--nf-glass-orb-a:#00ca5247;--nf-glass-orb-b:#bec8d71a}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=macos]{--nf-bg:#1c1c1ee6;--nf-bg-raise:#2c2c2ed1;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff42;--nf-text:#f5f5f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b3;--nf-text-3:#98989d;--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-hover:#ffffff0f;--nf-info:#bf5af2;--nf-shadow:0 1px 2px #0006, 0 10px 30px #00000073;--nf-shadow-lg:0 4px 12px #00000073, 0 18px 44px #0009;--nf-card-shadow:0 2px 6px #0006, 0 14px 38px #00000080;--nf-card-shadow-hover:0 4px 10px #00000073, 0 22px 52px #0009;--nf-glass-face:#2c2c2ed9;--nf-glass-core:transparent;--nf-glass-sheen:#fff3;--nf-glass-border:#ffffff2e;--nf-glass-inset:#ffffff0f;--nf-glass-orb-a:#0a84ff29;--nf-glass-orb-b:#bf5af214;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph]{--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=light][data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_bookCard{gap:var(--nf-space-8,8px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-16,16px);padding:var(--nf-space-12,12px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow);cursor:pointer;flex-direction:column;transition:border-color .15s,transform .1s,box-shadow .15s;display:flex}.zE6uZW_bookCard:hover{border-color:var(--nf-accent);box-shadow:var(--nf-shadow-lg);transform:translateY(-2px)}.zE6uZW_bookCardActive{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.zE6uZW_bookCardCover{aspect-ratio:3/4;border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);flex:none;justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden}.zE6uZW_bookCardCover img{object-fit:cover;width:100%;height:100%;transition:transform .35s;display:block}.zE6uZW_bookCard:hover .zE6uZW_bookCardCover img{transform:scale(1.06)}.zE6uZW_bookCardCover:after{content:\"\";border-radius:inherit;pointer-events:none;opacity:0;background:linear-gradient(#0000 55%,#00000047);transition:opacity .25s;position:absolute;inset:0}.zE6uZW_bookCard:hover .zE6uZW_bookCardCover:after{opacity:1}.zE6uZW_bookCardCoverFallback{justify-content:center;align-items:center;gap:var(--nf-space-6,6px);background:radial-gradient(400px 200px at 80% -20%, color-mix(in srgb, var(--nf-accent) 25%, transparent), transparent 70%), linear-gradient(155deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 10%, var(--nf-bg-inset)));flex-direction:column;width:100%;height:100%;display:flex}.zE6uZW_bookCardCoverTitle{font-size:var(--nf-fs-22,22px);color:var(--nf-accent);letter-spacing:2px;font-weight:800}.zE6uZW_bookCardBody{gap:var(--nf-space-6,5px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_bookCardTitleRow{justify-content:space-between;align-items:center;gap:var(--nf-space-6,6px);display:flex}.zE6uZW_bookCardName{font-weight:700;font-size:var(--nf-fs-14,13.5px);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_bookCardBlurb{-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:34px;display:-webkit-box;overflow:hidden}.zE6uZW_bookCardMetaRow{justify-content:space-between;align-items:center;gap:var(--nf-space-6,6px);flex-wrap:wrap;display:flex}.zE6uZW_bookCardProgressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:6px;overflow:hidden;box-shadow:inset 0 1px 2px #0000001f}.zE6uZW_bookCardProgressFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));height:100%;transition:width .3s;display:block}.zE6uZW_bookAddCard{justify-content:center;align-items:center;gap:var(--nf-space-8,8px);text-align:center;color:var(--nf-text-2);border-style:dashed;min-height:260px;transition:border-color .15s,color .15s,background .15s,transform .15s}.zE6uZW_bookAddCard:hover{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent);transform:translateY(-2px)}.zE6uZW_bookAddIcon{font-size:var(--nf-fs-34,34px);color:var(--nf-accent);line-height:1;transition:transform .15s}.zE6uZW_bookAddCard:hover .zE6uZW_bookAddIcon{transform:scale(1.12)}.zE6uZW_bookCreateCard{border-color:var(--nf-accent);min-height:260px}.zE6uZW_createBookView{min-height:0;padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);flex-direction:column;flex:1;display:flex;overflow:auto}.zE6uZW_createBookTop{align-items:center;display:flex}.zE6uZW_createBookCard{align-self:center;gap:var(--nf-space-12,12px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-20,20px);width:min(520px,100%);padding:var(--nf-card-pad,20px 22px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;display:flex}.zE6uZW_createBookIcon{font-size:var(--nf-fs-34,34px);line-height:1}.zE6uZW_createBookTitle{font-size:var(--nf-fs-22,22px);letter-spacing:-.3px;margin:0;font-weight:800}.zE6uZW_ideaCard{gap:var(--nf-space-8,8px);border:1px dashed var(--nf-border-strong);border-radius:var(--nf-radius-14,14px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:color-mix(in srgb, var(--nf-accent) 3%, transparent);flex-direction:column;display:flex}.zE6uZW_ideaToggle{align-items:center;gap:var(--nf-space-6,6px);color:var(--nf-accent);font-size:var(--nf-fs-14,13px);cursor:pointer;text-align:left;background:0 0;border:none;padding:0;font-weight:700;display:flex}.zE6uZW_ideaCandidate{gap:var(--nf-space-6,6px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:var(--nf-bg);flex-direction:column;display:flex}.zE6uZW_progressLineDone{color:var(--nf-success);font-weight:600}.zE6uZW_progressLineError{color:var(--nf-error);font-weight:600}.zE6uZW_meta{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.9}.zE6uZW_genreDesc{-webkit-line-clamp:2;-webkit-box-orient:vertical;max-width:560px;display:-webkit-box;overflow:hidden}.zE6uZW_fileList{gap:var(--nf-space-4,3px);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.9;word-break:break-all;flex-direction:column;display:flex}.zE6uZW_panelContent::-webkit-scrollbar,.zE6uZW_chatScroll::-webkit-scrollbar,.zE6uZW_chapterPreview::-webkit-scrollbar,.zE6uZW_progress::-webkit-scrollbar,.zE6uZW_toolLive::-webkit-scrollbar{width:8px;height:8px}.zE6uZW_panelContent::-webkit-scrollbar-thumb,.zE6uZW_chatScroll::-webkit-scrollbar-thumb,.zE6uZW_chapterPreview::-webkit-scrollbar-thumb,.zE6uZW_progress::-webkit-scrollbar-thumb,.zE6uZW_toolLive::-webkit-scrollbar-thumb{background:var(--nf-border-strong);border-radius:var(--nf-radius-4,4px)}.zE6uZW_panelContent::-webkit-scrollbar-thumb:hover,.zE6uZW_chatScroll::-webkit-scrollbar-thumb:hover,.zE6uZW_chapterPreview::-webkit-scrollbar-thumb:hover,.zE6uZW_progress::-webkit-scrollbar-thumb:hover,.zE6uZW_toolLive::-webkit-scrollbar-thumb:hover{background:var(--nf-text-3)}.zE6uZW_workflowList{flex-direction:column;gap:0;display:flex}.zE6uZW_workflowRow{align-items:flex-start;gap:var(--nf-space-12,12px);padding:var(--nf-space-8,8px) var(--nf-space-4,4px);display:flex;position:relative}.zE6uZW_workflowRow:before{content:\"\";background:var(--nf-border);width:2px;position:absolute;top:34px;bottom:-8px;left:13px}.zE6uZW_workflowRow:last-child:before{display:none}.zE6uZW_workflowDot{width:28px;height:var(--nf-ctrl-s,28px);font-size:var(--nf-fs-12,12px);border:2px solid var(--nf-border-strong);background:var(--nf-bg-raise);color:var(--nf-text-2);z-index:1;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-weight:700;display:inline-flex}.zE6uZW_workflowDotDone{border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));color:var(--nf-success)}.zE6uZW_workflowDotActive{border-color:var(--nf-accent);background:var(--nf-accent);color:var(--nf-accent-fg);box-shadow:0 0 0 4px var(--nf-accent-soft)}.zE6uZW_workflowBody{gap:var(--nf-space-4,4px);min-width:0;padding-top:var(--nf-space-2,2px);flex-direction:column;flex:1;display:flex}.zE6uZW_workflowLabel{font-size:var(--nf-fs-14,13px);color:var(--nf-text);font-weight:600}.zE6uZW_workflowHint{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2)}@keyframes zE6uZW_pulse{0%,to{opacity:1}50%{opacity:.45}}@keyframes zE6uZW_fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.zE6uZW_card{animation:.2s zE6uZW_fadeIn}.zE6uZW_bookshelf{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-8,8px) var(--nf-space-14,14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-16,16px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(26px)saturate(175%);z-index:1;flex-wrap:wrap;flex-shrink:0;margin:10px 12px 0;display:flex;position:relative}.zE6uZW_bookshelfLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);letter-spacing:1px;flex-shrink:0;font-weight:700}.zE6uZW_bookshelfList{align-items:center;gap:var(--nf-space-6,6px);flex-wrap:wrap;flex:1;min-width:0;display:flex}.zE6uZW_bookChip{align-items:center;gap:var(--nf-space-6,6px);padding:var(--nf-space-4,4px) var(--nf-space-8,8px) var(--nf-space-4,4px) var(--nf-space-10,10px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-999,999px);background:var(--nf-bg-inset);cursor:pointer;font-size:var(--nf-fs-12,12px);max-width:220px;transition:border-color .15s,background .15s;display:flex}.zE6uZW_bookChip:hover{border-color:var(--nf-border-strong)}.zE6uZW_bookChipActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.zE6uZW_bookChipName{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.zE6uZW_bookChipMeta{font-size:var(--nf-fs-12,11px);opacity:.7;white-space:nowrap}.zE6uZW_bookChipRemove{color:var(--nf-text-3);cursor:pointer;font-size:var(--nf-fs-14,13px);padding:0 var(--nf-space-2,2px);border-radius:var(--nf-radius-4,4px);background:0 0;border:none;line-height:1}.zE6uZW_bookChipRemove:hover{color:var(--nf-error)}.zE6uZW_bookAdd{border:1px dashed var(--nf-border-strong);color:var(--nf-text-2);cursor:pointer;font-size:var(--nf-fs-12,12px);padding:var(--nf-space-4,4px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);background:0 0;transition:border-color .15s,color .15s}.zE6uZW_bookAdd:hover{border-color:var(--nf-accent);color:var(--nf-accent)}.zE6uZW_bookCreateForm{align-items:center;gap:var(--nf-space-6,6px);display:flex}.zE6uZW_dropzone{border:2px dashed var(--nf-border-strong);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-18,18px) var(--nf-space-14,14px);text-align:center;font-size:var(--nf-fs-14,13px);color:var(--nf-text-2);cursor:pointer;align-items:center;gap:var(--nf-space-6,6px);flex-direction:column;transition:border-color .15s,background .15s;display:flex}.zE6uZW_dropzone:hover,.zE6uZW_dropzoneActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.zE6uZW_dropzoneIcon{font-size:var(--nf-fs-22,22px);line-height:1}.zE6uZW_bookCardActions{align-items:center;gap:var(--nf-space-6,6px);padding-top:var(--nf-space-8,8px);margin-top:auto;display:flex}.zE6uZW_bookCardActions .zE6uZW_button{flex:1;justify-content:center}.zE6uZW_readerView{flex-direction:column;transition:background .2s,color .2s;display:flex;position:absolute;inset:0;overflow:hidden}.zE6uZW_readerHeader{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);border-bottom:1px solid;flex-wrap:wrap;flex:none;display:flex}.zE6uZW_readerTitle{font-weight:700;font-size:var(--nf-fs-14,14px)}.zE6uZW_readerSeg{align-items:center;gap:var(--nf-space-2,2px);border-radius:var(--nf-radius-8,8px);display:flex;overflow:hidden}.zE6uZW_readerSegBtn{font-size:var(--nf-fs-12,12px);padding:var(--nf-space-4,3px) var(--nf-space-8,8px);border-radius:var(--nf-radius-6,6px);cursor:pointer;opacity:.75;background:0 0;border:none}.zE6uZW_readerSegBtn:hover,.zE6uZW_readerSegActive{opacity:1}.zE6uZW_readerBody{flex:1;align-items:stretch;min-height:0;display:flex}.zE6uZW_readerSidebar{width:220px;min-width:220px;padding:var(--nf-space-8,8px) var(--nf-space-6,6px) var(--nf-space-24,24px);scrollbar-width:thin;gap:var(--nf-space-10,10px);border-right:1px solid;flex-direction:column;flex:none;display:flex;overflow-y:auto}.zE6uZW_readerGroup{gap:var(--nf-space-2,1px);flex-direction:column;display:flex}.zE6uZW_readerGroupTitle{align-items:center;gap:var(--nf-space-6,6px);width:100%;font-size:var(--nf-fs-12,12px);padding:var(--nf-space-6,6px) var(--nf-space-8,8px) var(--nf-space-4,4px);opacity:.9;cursor:pointer;text-align:left;border-radius:var(--nf-radius-6,6px);background:0 0;border:none;font-weight:700;display:flex}.zE6uZW_readerGroupTitle:hover{opacity:1;background:#8080801f}.zE6uZW_readerGroupArrow{font-size:var(--nf-fs-12,10px);text-align:center;flex:none;width:12px}.zE6uZW_readerGroupCount{font-size:var(--nf-fs-12,11px);opacity:.6;padding-right:var(--nf-space-2,2px);flex:none;margin-left:auto;font-weight:400}.zE6uZW_readerItem{align-items:center;gap:var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);font-size:var(--nf-fs-12,12px);text-align:left;padding:var(--nf-space-4,4px) var(--nf-space-8,8px);cursor:pointer;opacity:.8;background:0 0;border:1px solid;min-width:0;transition:opacity .15s,background .15s;display:flex}.zE6uZW_readerItem:hover{opacity:1}.zE6uZW_readerItemActive{opacity:1;font-weight:700}.zE6uZW_readerItemNo{text-align:right;opacity:.75;flex:none;min-width:26px;font-weight:700}.zE6uZW_readerItemTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.zE6uZW_readerItemBadge{font-size:var(--nf-fs-12,11px);flex:none}.zE6uZW_readerMain{min-height:0;padding:var(--nf-space-20,20px) var(--nf-space-16,16px) var(--nf-space-48,48px);scrollbar-width:thin;flex:1;justify-content:center;display:flex;overflow-y:auto}.zE6uZW_readerArticle{gap:var(--nf-space-12,12px);flex-direction:column;width:100%;display:flex}.zE6uZW_readerChapterTitle{font-size:var(--nf-fs-24,24px);letter-spacing:1px;margin:0;font-weight:800}.zE6uZW_readerChapterMeta{align-items:center;gap:var(--nf-space-8,8px);font-size:var(--nf-fs-12,12px);display:flex}.zE6uZW_readerText{text-align:justify;letter-spacing:.02em}.zE6uZW_readerPara{text-indent:2em;margin:0 0 .85em}.zE6uZW_readerFoot{justify-content:space-between;align-items:center;gap:var(--nf-space-8,8px);padding-top:var(--nf-space-12,12px);border-top:1px dashed;margin-top:12px;display:flex}.zE6uZW_readerLoading,.zE6uZW_readerError{padding:var(--nf-space-32,32px) 0;font-size:var(--nf-fs-14,13px);opacity:.7;align-self:center}.zE6uZW_readerError{color:var(--nf-error)}.zE6uZW_importModalOverlay{z-index:1000;backdrop-filter:blur(4px);padding:var(--nf-space-24,24px);background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.zE6uZW_importModal{gap:var(--nf-space-12,12px);border:1px solid var(--nf-border-strong);border-radius:var(--nf-radius-16,16px);width:min(520px,100%);max-height:85vh;padding:var(--nf-card-pad,20px 22px);background:var(--nf-bg-raise);backdrop-filter:blur(28px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;display:flex;overflow:auto}.zE6uZW_importModalHead{justify-content:space-between;align-items:center;gap:var(--nf-space-10,10px);display:flex}.zE6uZW_importModalTabs{gap:var(--nf-space-8,8px);display:flex}.zE6uZW_importModalTabs .zE6uZW_button{flex:1}.zE6uZW_importModalBody{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_importField{gap:var(--nf-space-6,5px);font-size:var(--nf-fs-14,13px);color:var(--nf-text-2);flex-direction:column;display:flex}.zE6uZW_importHint{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);line-height:1.5}.zE6uZW_importError{border:1px solid color-mix(in srgb, var(--nf-danger,#e5484d) 55%, transparent);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px);font-size:var(--nf-fs-12,12.5px);color:var(--nf-danger,#e5484d);background:color-mix(in srgb, var(--nf-danger,#e5484d) 10%, transparent);white-space:pre-wrap;word-break:break-all}.zE6uZW_importResult{gap:var(--nf-space-4,4px);border:1px solid color-mix(in srgb, var(--nf-ok,#46a758) 45%, transparent);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,13px);background:color-mix(in srgb, var(--nf-ok,#46a758) 9%, transparent);word-break:break-all;flex-direction:column;display:flex}.zE6uZW_importModalActions{justify-content:flex-end;gap:var(--nf-space-8,8px);display:flex}.zE6uZW_importFileInfo{align-items:center;gap:var(--nf-space-8,8px);font-size:var(--nf-fs-14,13px);color:var(--nf-text-1);flex-wrap:wrap;display:flex}.zE6uZW_importPreview{gap:var(--nf-space-4,4px);border:1px solid var(--nf-border-strong);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,13px);background:var(--nf-bg-inset);flex-direction:column;display:flex}.zE6uZW_importPreviewList{padding-left:var(--nf-space-18,18px);gap:var(--nf-space-2,2px);font-size:var(--nf-fs-12,12.5px);color:var(--nf-text-2);flex-direction:column;max-height:140px;margin:0;display:flex;overflow:auto}.zE6uZW_settingsCard .zE6uZW_fieldLabel{white-space:nowrap;text-overflow:ellipsis;max-width:100%;min-height:18px;line-height:18px;overflow:hidden}.zE6uZW_settingsCard .zE6uZW_row{align-items:flex-start}.zE6uZW_helpTipText{width:280px;max-width:70vw;padding:var(--nf-space-10,10px) var(--nf-space-12,12px);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg-raise);border:1px solid var(--nf-border-strong);box-shadow:var(--nf-shadow-lg);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);white-space:normal;z-index:20;text-align:left;pointer-events:none;font-weight:400;line-height:1.7;display:none;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%)}.zE6uZW_helpTip:hover .zE6uZW_helpTipText,.zE6uZW_helpTip:focus .zE6uZW_helpTipText,.zE6uZW_helpTip:focus-within .zE6uZW_helpTipText{display:block}.zE6uZW_settingsCard+.zE6uZW_settingsCard{flex:1;min-height:0}.zE6uZW_switch{border-radius:var(--nf-radius-999,999px);border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);cursor:pointer;flex:none;width:42px;height:24px;padding:0;transition:background .18s,border-color .18s;position:relative}.zE6uZW_switchKnob{background:#fff;border-radius:50%;width:16px;height:16px;transition:transform .18s;position:absolute;top:3px;left:3px;box-shadow:0 1px 3px #0000004d}.zE6uZW_switchOn{background:var(--nf-accent);border-color:var(--nf-accent)}.zE6uZW_switchOn .zE6uZW_switchKnob{transform:translate(18px)}.zE6uZW_panel[data-nf-theme=neumorph]:not([data-nf-mode=dark]),body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph][data-nf-mode=light]{--nf-glass-face:color-mix(in srgb, #e4e9f2, transparent calc(100% - var(--nf-glass-opacity,100%)));--nf-bg-raise:color-mix(in srgb, #e4e9f2, transparent calc(100% - var(--nf-glass-opacity,100%)))}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph]:not([data-nf-mode]){--nf-glass-face:color-mix(in srgb, #2b2f36, transparent calc(100% - var(--nf-glass-opacity,100%)));--nf-bg-raise:color-mix(in srgb, #2b2f36, transparent calc(100% - var(--nf-glass-opacity,100%)))}.zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode=dark]),body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay][data-nf-mode=light]{--nf-glass-face:color-mix(in srgb, #efe4d6, transparent calc(100% - var(--nf-glass-opacity,100%)));--nf-bg-raise:color-mix(in srgb, #efe4d6, transparent calc(100% - var(--nf-glass-opacity,100%)))}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]){--nf-glass-face:color-mix(in srgb, #37302b, transparent calc(100% - var(--nf-glass-opacity,100%)));--nf-bg-raise:color-mix(in srgb, #37302b, transparent calc(100% - var(--nf-glass-opacity,100%)))}";
35225
35429
  const tagId = "@waterwx/dsh-novel-forge/panel.module.css";
35226
35430
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
35227
35431
  const tag = document.createElement("style");
@@ -35231,311 +35435,1100 @@ window.__ModuleLoader__.load({
35231
35435
  document.head.appendChild(tag);
35232
35436
  }
35233
35437
  var panel_module_css_default = {
35234
- "helpTipText": "zE6uZW_helpTipText",
35235
- "dropzone": "zE6uZW_dropzone",
35236
- "workflowDotDone": "zE6uZW_workflowDotDone",
35237
- "statCardDIconRed": "zE6uZW_statCardDIconRed",
35238
- "navTitleLogo": "zE6uZW_navTitleLogo",
35239
- "badgePending": "zE6uZW_badgePending",
35438
+ "diffAdd": "zE6uZW_diffAdd",
35439
+ "progressOverviewCard": "zE6uZW_progressOverviewCard",
35240
35440
  "toolStep": "zE6uZW_toolStep",
35241
- "importHint": "zE6uZW_importHint",
35242
- "bookAddIcon": "zE6uZW_bookAddIcon",
35243
- "statCardDUnit": "zE6uZW_statCardDUnit",
35244
- "wsPageHeader": "zE6uZW_wsPageHeader",
35245
- "navTitle": "zE6uZW_navTitle",
35246
- "todoText": "zE6uZW_todoText",
35247
- "readerItemBadge": "zE6uZW_readerItemBadge",
35248
- "assetGrid": "zE6uZW_assetGrid",
35249
- "coverPreview": "zE6uZW_coverPreview",
35250
- "bookAdd": "zE6uZW_bookAdd",
35251
- "chapterBeats": "zE6uZW_chapterBeats",
35252
- "readerMain": "zE6uZW_readerMain",
35253
- "meta": "zE6uZW_meta",
35254
- "readerLoading": "zE6uZW_readerLoading",
35441
+ "volumeGroupHeader": "zE6uZW_volumeGroupHeader",
35442
+ "authorRail": "zE6uZW_authorRail",
35443
+ "rowEnd": "zE6uZW_rowEnd",
35444
+ "readerSidebar": "zE6uZW_readerSidebar",
35445
+ "readerItemTitle": "zE6uZW_readerItemTitle",
35446
+ "importFileInfo": "zE6uZW_importFileInfo",
35447
+ "authorRailBtn": "zE6uZW_authorRailBtn",
35448
+ "adaptOutlinePre": "zE6uZW_adaptOutlinePre",
35449
+ "switchOn": "zE6uZW_switchOn",
35450
+ "progressLineLive": "zE6uZW_progressLineLive",
35451
+ "dashHeroTitle": "zE6uZW_dashHeroTitle",
35452
+ "bookSwitchCover": "zE6uZW_bookSwitchCover",
35453
+ "shelfStats": "zE6uZW_shelfStats",
35454
+ "wsSelectedText": "zE6uZW_wsSelectedText",
35455
+ "chatBubbleUser": "zE6uZW_chatBubbleUser",
35456
+ "badgeError": "zE6uZW_badgeError",
35457
+ "progressLive": "zE6uZW_progressLive",
35458
+ "readerBody": "zE6uZW_readerBody",
35459
+ "dashStageDot": "zE6uZW_dashStageDot",
35460
+ "assistantFloat": "zE6uZW_assistantFloat",
35461
+ "importError": "zE6uZW_importError",
35462
+ "adaptResult": "zE6uZW_adaptResult",
35463
+ "bookshelfLabel": "zE6uZW_bookshelfLabel",
35464
+ "bookChipRemove": "zE6uZW_bookChipRemove",
35465
+ "importField": "zE6uZW_importField",
35466
+ "tlBar": "zE6uZW_tlBar",
35467
+ "bookCardName": "zE6uZW_bookCardName",
35468
+ "bookCardCover": "zE6uZW_bookCardCover",
35469
+ "toolLive": "zE6uZW_toolLive",
35470
+ "shelfHeader": "zE6uZW_shelfHeader",
35255
35471
  "view": "zE6uZW_view",
35256
- "createBookTitle": "zE6uZW_createBookTitle",
35257
- "readerTitle": "zE6uZW_readerTitle",
35258
- "dashFact": "zE6uZW_dashFact",
35259
- "wsPreview": "zE6uZW_wsPreview",
35260
- "bookshelfList": "zE6uZW_bookshelfList",
35261
- "readerItemActive": "zE6uZW_readerItemActive",
35262
- "chapterFocus": "zE6uZW_chapterFocus",
35263
- "fieldLabel": "zE6uZW_fieldLabel",
35264
- "bookCardActions": "zE6uZW_bookCardActions",
35265
- "shelfStat": "zE6uZW_shelfStat",
35266
- "buttonDanger": "zE6uZW_buttonDanger",
35267
- "badgeWritten": "zE6uZW_badgeWritten",
35472
+ "bookAdd": "zE6uZW_bookAdd",
35473
+ "diffChange": "zE6uZW_diffChange",
35474
+ "navBadgePulse": "zE6uZW_navBadgePulse",
35475
+ "badgePending": "zE6uZW_badgePending",
35268
35476
  "assistantStatusBusy": "zE6uZW_assistantStatusBusy",
35269
- "toolStepIcon": "zE6uZW_toolStepIcon",
35270
- "dashFacts": "zE6uZW_dashFacts",
35271
- "outlineReadonly": "zE6uZW_outlineReadonly",
35272
- "assetStatDetail": "zE6uZW_assetStatDetail",
35273
- "readerItemNo": "zE6uZW_readerItemNo",
35274
- "readerGroupArrow": "zE6uZW_readerGroupArrow",
35275
- "entry": "zE6uZW_entry",
35276
- "navTab": "zE6uZW_navTab",
35277
- "bookCreateCard": "zE6uZW_bookCreateCard",
35278
- "chapterNum": "zE6uZW_chapterNum",
35279
- "reviewBox": "zE6uZW_reviewBox",
35280
- "bookCardName": "zE6uZW_bookCardName",
35281
- "bookSwitchName": "zE6uZW_bookSwitchName",
35282
- "chapterList": "zE6uZW_chapterList",
35283
- "toolStepError": "zE6uZW_toolStepError",
35284
- "dashJourney": "zE6uZW_dashJourney",
35285
- "busyRow": "zE6uZW_busyRow",
35286
- "navTabBadge": "zE6uZW_navTabBadge",
35287
- "tlBar": "zE6uZW_tlBar",
35288
- "tlSegDone": "zE6uZW_tlSegDone",
35289
- "todoDanger": "zE6uZW_todoDanger",
35290
- "navActions": "zE6uZW_navActions",
35291
- "toolStepDetail": "zE6uZW_toolStepDetail",
35292
- "bookCardCoverTitle": "zE6uZW_bookCardCoverTitle",
35293
- "panelNav": "zE6uZW_panelNav",
35294
- "onlyChanges": "zE6uZW_onlyChanges",
35295
- "card": "zE6uZW_card",
35296
- "dashJourneyFill": "zE6uZW_dashJourneyFill",
35297
- "navAboutUpdate": "zE6uZW_navAboutUpdate",
35298
- "wsSelectedText": "zE6uZW_wsSelectedText",
35299
- "wsPreviewText": "zE6uZW_wsPreviewText",
35300
- "progressLineDone": "zE6uZW_progressLineDone",
35301
- "iconButton": "zE6uZW_iconButton",
35302
- "readerFoot": "zE6uZW_readerFoot",
35303
- "importModalActions": "zE6uZW_importModalActions",
35304
- "badgeRejected": "zE6uZW_badgeRejected",
35305
- "chatRole": "zE6uZW_chatRole",
35306
- "navAbout": "zE6uZW_navAbout",
35307
- "navTabLabel": "zE6uZW_navTabLabel",
35308
- "dropzoneActive": "zE6uZW_dropzoneActive",
35309
- "shelfEmptyTitle": "zE6uZW_shelfEmptyTitle",
35477
+ "readerPara": "zE6uZW_readerPara",
35478
+ "chapterFocus": "zE6uZW_chapterFocus",
35479
+ "badgeDone": "zE6uZW_badgeDone",
35480
+ "dashHero": "zE6uZW_dashHero",
35481
+ "bookshelf": "zE6uZW_bookshelf",
35310
35482
  "importModalOverlay": "zE6uZW_importModalOverlay",
35311
- "spaceBetween": "zE6uZW_spaceBetween",
35312
- "volumeGroup": "zE6uZW_volumeGroup",
35483
+ "importHint": "zE6uZW_importHint",
35484
+ "workflowBody": "zE6uZW_workflowBody",
35485
+ "outlineReadonly": "zE6uZW_outlineReadonly",
35486
+ "progressBookFill": "zE6uZW_progressBookFill",
35313
35487
  "bookChipActive": "zE6uZW_bookChipActive",
35488
+ "bookChipName": "zE6uZW_bookChipName",
35489
+ "createBookView": "zE6uZW_createBookView",
35490
+ "diffNew": "zE6uZW_diffNew",
35491
+ "dashHeroSparkle": "zE6uZW_dashHeroSparkle",
35492
+ "assetLabel": "zE6uZW_assetLabel",
35493
+ "assetCardContent": "zE6uZW_assetCardContent",
35494
+ "readerFoot": "zE6uZW_readerFoot",
35495
+ "workflowDot": "zE6uZW_workflowDot",
35496
+ "dashFacts": "zE6uZW_dashFacts",
35497
+ "ideaCandidate": "zE6uZW_ideaCandidate",
35314
35498
  "workflowDotActive": "zE6uZW_workflowDotActive",
35315
- "importError": "zE6uZW_importError",
35316
- "ideaCard": "zE6uZW_ideaCard",
35317
- "statCardDDown": "zE6uZW_statCardDDown",
35318
- "shelfToolbar": "zE6uZW_shelfToolbar",
35319
- "bookChip": "zE6uZW_bookChip",
35320
- "navTabBadgeDone": "zE6uZW_navTabBadgeDone",
35321
- "readerArticle": "zE6uZW_readerArticle",
35322
- "importModal": "zE6uZW_importModal",
35323
- "badgeDone": "zE6uZW_badgeDone",
35324
- "dashHeroActionTitle": "zE6uZW_dashHeroActionTitle",
35499
+ "bookCardActions": "zE6uZW_bookCardActions",
35500
+ "liveText": "zE6uZW_liveText",
35501
+ "pulse": "zE6uZW_pulse",
35325
35502
  "diffSame": "zE6uZW_diffSame",
35326
- "bookCardProgressFill": "zE6uZW_bookCardProgressFill",
35327
- "bookCardBody": "zE6uZW_bookCardBody",
35328
- "panelNavCollapsed": "zE6uZW_panelNavCollapsed",
35329
- "input": "zE6uZW_input",
35330
- "workflowDot": "zE6uZW_workflowDot",
35331
- "workflowBody": "zE6uZW_workflowBody",
35332
- "navBadgePulse": "zE6uZW_navBadgePulse",
35333
- "importResult": "zE6uZW_importResult",
35334
- "bookAddCard": "zE6uZW_bookAddCard",
35335
- "dashGrid": "zE6uZW_dashGrid",
35336
- "assistantResize": "zE6uZW_assistantResize",
35337
- "diffText": "zE6uZW_diffText",
35338
- "bookCard": "zE6uZW_bookCard",
35339
- "progressLineLive": "zE6uZW_progressLineLive",
35340
- "readerError": "zE6uZW_readerError",
35341
- "diffColumn": "zE6uZW_diffColumn",
35342
- "shelfSearch": "zE6uZW_shelfSearch",
35343
- "chatBubbleAssistant": "zE6uZW_chatBubbleAssistant",
35344
- "readerSidebar": "zE6uZW_readerSidebar",
35345
- "statCardDValue": "zE6uZW_statCardDValue",
35346
- "navTabBadgeWarn": "zE6uZW_navTabBadgeWarn",
35347
- "progress": "zE6uZW_progress",
35348
- "switchOn": "zE6uZW_switchOn",
35349
- "chapterPreview": "zE6uZW_chapterPreview",
35350
- "cardTitle": "zE6uZW_cardTitle",
35351
- "badgeError": "zE6uZW_badgeError",
35352
- "tabBar": "zE6uZW_tabBar",
35353
- "dashHero": "zE6uZW_dashHero",
35354
- "dropzoneIcon": "zE6uZW_dropzoneIcon",
35355
- "importModalHead": "zE6uZW_importModalHead",
35356
- "wsSelected": "zE6uZW_wsSelected",
35357
- "bookCardTitleRow": "zE6uZW_bookCardTitleRow",
35358
- "bookCardProgressBar": "zE6uZW_bookCardProgressBar",
35359
- "coverPlaceholder": "zE6uZW_coverPlaceholder",
35360
- "dashHeroAction": "zE6uZW_dashHeroAction",
35361
- "chapterFocusPulse": "zE6uZW_chapterFocusPulse",
35362
- "wsEditor": "zE6uZW_wsEditor",
35503
+ "fieldLabel": "zE6uZW_fieldLabel",
35363
35504
  "diffList": "zE6uZW_diffList",
35364
- "workflowLabel": "zE6uZW_workflowLabel",
35365
- "workflowHint": "zE6uZW_workflowHint",
35366
- "field": "zE6uZW_field",
35367
- "panelContent": "zE6uZW_panelContent",
35368
35505
  "navGroupLabel": "zE6uZW_navGroupLabel",
35369
- "shelfHeader": "zE6uZW_shelfHeader",
35370
- "readerPara": "zE6uZW_readerPara",
35371
- "assistantStatus": "zE6uZW_assistantStatus",
35372
- "bookSwitchCover": "zE6uZW_bookSwitchCover",
35373
- "bookChipRemove": "zE6uZW_bookChipRemove",
35374
- "shelfEmpty": "zE6uZW_shelfEmpty",
35375
- "chapter": "zE6uZW_chapter",
35506
+ "assetGroup": "zE6uZW_assetGroup",
35507
+ "assistantFloatHeader": "zE6uZW_assistantFloatHeader",
35508
+ "dimCurrent": "zE6uZW_dimCurrent",
35509
+ "progressBookHead": "zE6uZW_progressBookHead",
35510
+ "diffLegend": "zE6uZW_diffLegend",
35511
+ "noticeError": "zE6uZW_noticeError",
35512
+ "bookCreateCard": "zE6uZW_bookCreateCard",
35513
+ "readerTitle": "zE6uZW_readerTitle",
35376
35514
  "bookSwitchMeta": "zE6uZW_bookSwitchMeta",
35377
- "dashStageDone": "zE6uZW_dashStageDone",
35378
- "legendOld": "zE6uZW_legendOld",
35379
- "progressBar": "zE6uZW_progressBar",
35380
- "bookCardCoverFallback": "zE6uZW_bookCardCoverFallback",
35381
- "diffTagNew": "zE6uZW_diffTagNew",
35382
- "bookSwitch": "zE6uZW_bookSwitch",
35383
- "readerGroup": "zE6uZW_readerGroup",
35384
- "bookCardActive": "zE6uZW_bookCardActive",
35385
- "volumeGroupHeader": "zE6uZW_volumeGroupHeader",
35386
- "toolStepName": "zE6uZW_toolStepName",
35387
- "tab": "zE6uZW_tab",
35388
- "shelfView": "zE6uZW_shelfView",
35389
- "genreDesc": "zE6uZW_genreDesc",
35390
- "readerText": "zE6uZW_readerText",
35391
- "helpTip": "zE6uZW_helpTip",
35392
- "switchKnob": "zE6uZW_switchKnob",
35393
- "wsPage": "zE6uZW_wsPage",
35515
+ "statCardD": "zE6uZW_statCardD",
35516
+ "wsColumns": "zE6uZW_wsColumns",
35517
+ "adaptTextarea": "zE6uZW_adaptTextarea",
35394
35518
  "diffTagOld": "zE6uZW_diffTagOld",
35395
35519
  "statRowD": "zE6uZW_statRowD",
35396
- "navActionBtn": "zE6uZW_navActionBtn",
35397
- "progressLine": "zE6uZW_progressLine",
35520
+ "tlSegFill": "zE6uZW_tlSegFill",
35521
+ "diffOld": "zE6uZW_diffOld",
35522
+ "workflowHint": "zE6uZW_workflowHint",
35523
+ "navTitleName": "zE6uZW_navTitleName",
35524
+ "chapterPreview": "zE6uZW_chapterPreview",
35525
+ "toolStepActive": "zE6uZW_toolStepActive",
35526
+ "progressBarFill": "zE6uZW_progressBarFill",
35527
+ "wsPreview": "zE6uZW_wsPreview",
35528
+ "assetStatValue": "zE6uZW_assetStatValue",
35529
+ "dashGrid": "zE6uZW_dashGrid",
35530
+ "shelfGrid": "zE6uZW_shelfGrid",
35531
+ "entry": "zE6uZW_entry",
35532
+ "progressLineDone": "zE6uZW_progressLineDone",
35533
+ "shelfFilterCount": "zE6uZW_shelfFilterCount",
35534
+ "fadeIn": "zE6uZW_fadeIn",
35535
+ "statCardDIcon": "zE6uZW_statCardDIcon",
35536
+ "readerText": "zE6uZW_readerText",
35398
35537
  "navTitleBook": "zE6uZW_navTitleBook",
35399
- "navGroup": "zE6uZW_navGroup",
35400
- "todoWarning": "zE6uZW_todoWarning",
35538
+ "readerLoading": "zE6uZW_readerLoading",
35539
+ "importPreview": "zE6uZW_importPreview",
35540
+ "buttonDanger": "zE6uZW_buttonDanger",
35541
+ "diffColumn": "zE6uZW_diffColumn",
35542
+ "wsPreviewText": "zE6uZW_wsPreviewText",
35543
+ "chatRole": "zE6uZW_chatRole",
35544
+ "chapterBeats": "zE6uZW_chapterBeats",
35545
+ "bookCreateOutline": "zE6uZW_bookCreateOutline",
35546
+ "volumeGroup": "zE6uZW_volumeGroup",
35547
+ "assistantResize": "zE6uZW_assistantResize",
35548
+ "panelTitle": "zE6uZW_panelTitle",
35549
+ "progressBook": "zE6uZW_progressBook",
35401
35550
  "readerChapterTitle": "zE6uZW_readerChapterTitle",
35402
- "importPreviewList": "zE6uZW_importPreviewList",
35403
- "row": "zE6uZW_row",
35404
- "bookCardCover": "zE6uZW_bookCardCover",
35405
- "assetStatValue": "zE6uZW_assetStatValue",
35406
- "bookChipName": "zE6uZW_bookChipName",
35407
- "toolStepStatus": "zE6uZW_toolStepStatus",
35408
- "diffDel": "zE6uZW_diffDel",
35409
- "workflowRow": "zE6uZW_workflowRow",
35410
- "buttonSmall": "zE6uZW_buttonSmall",
35411
- "diffAdd": "zE6uZW_diffAdd",
35412
- "assetStat": "zE6uZW_assetStat",
35413
- "todoItem": "zE6uZW_todoItem",
35414
- "bookCardMetaRow": "zE6uZW_bookCardMetaRow",
35415
- "importField": "zE6uZW_importField",
35416
- "settingsCard": "zE6uZW_settingsCard",
35417
- "entryIcon": "zE6uZW_entryIcon",
35418
- "wsAppliedBanner": "zE6uZW_wsAppliedBanner",
35419
- "bookshelfLabel": "zE6uZW_bookshelfLabel",
35420
- "chatScroll": "zE6uZW_chatScroll",
35421
- "dashStage": "zE6uZW_dashStage",
35551
+ "statCardDUnit": "zE6uZW_statCardDUnit",
35552
+ "readerError": "zE6uZW_readerError",
35553
+ "bookChip": "zE6uZW_bookChip",
35554
+ "dropzoneActive": "zE6uZW_dropzoneActive",
35555
+ "iconButton": "zE6uZW_iconButton",
35556
+ "toolStepName": "zE6uZW_toolStepName",
35557
+ "navGroupSep": "zE6uZW_navGroupSep",
35558
+ "readerSegBtn": "zE6uZW_readerSegBtn",
35559
+ "bigProgressBarFill": "zE6uZW_bigProgressBarFill",
35560
+ "bookCardBody": "zE6uZW_bookCardBody",
35561
+ "authorRailAbout": "zE6uZW_authorRailAbout",
35562
+ "readerHeader": "zE6uZW_readerHeader",
35563
+ "createBookTitle": "zE6uZW_createBookTitle",
35564
+ "statCardDValue": "zE6uZW_statCardDValue",
35565
+ "todoText": "zE6uZW_todoText",
35566
+ "dashStageCurrent": "zE6uZW_dashStageCurrent",
35567
+ "progressBookList": "zE6uZW_progressBookList",
35568
+ "bookCardCoverTitle": "zE6uZW_bookCardCoverTitle",
35569
+ "bookCardBlurb": "zE6uZW_bookCardBlurb",
35570
+ "ideaToggle": "zE6uZW_ideaToggle",
35571
+ "readerItem": "zE6uZW_readerItem",
35572
+ "fileList": "zE6uZW_fileList",
35573
+ "badgeRejected": "zE6uZW_badgeRejected",
35574
+ "dashJourneyFill": "zE6uZW_dashJourneyFill",
35575
+ "dashJourneyStages": "zE6uZW_dashJourneyStages",
35576
+ "assetFilterBar": "zE6uZW_assetFilterBar",
35577
+ "assetKind": "zE6uZW_assetKind",
35578
+ "dashHeroBook": "zE6uZW_dashHeroBook",
35422
35579
  "shelfFilters": "zE6uZW_shelfFilters",
35423
- "bookCreateForm": "zE6uZW_bookCreateForm",
35424
- "progressLineError": "zE6uZW_progressLineError",
35425
- "dashHeroActionBody": "zE6uZW_dashHeroActionBody",
35426
- "chapterActions": "zE6uZW_chapterActions",
35427
- "navTabBadgeDanger": "zE6uZW_navTabBadgeDanger",
35428
- "dashHeroEyebrow": "zE6uZW_dashHeroEyebrow",
35580
+ "shelfFilter": "zE6uZW_shelfFilter",
35581
+ "shelfStatActive": "zE6uZW_shelfStatActive",
35582
+ "shelfEmptyIcon": "zE6uZW_shelfEmptyIcon",
35583
+ "shelfFilterActive": "zE6uZW_shelfFilterActive",
35584
+ "createBookTop": "zE6uZW_createBookTop",
35585
+ "bookSwitchArrow": "zE6uZW_bookSwitchArrow",
35429
35586
  "shelfTitleRow": "zE6uZW_shelfTitleRow",
35430
- "pulse": "zE6uZW_pulse",
35431
- "bigProgressBar": "zE6uZW_bigProgressBar",
35432
- "progressBarFill": "zE6uZW_progressBarFill",
35587
+ "bookshelfList": "zE6uZW_bookshelfList",
35588
+ "navAbout": "zE6uZW_navAbout",
35589
+ "progressTotalFill": "zE6uZW_progressTotalFill",
35590
+ "navTitle": "zE6uZW_navTitle",
35591
+ "chatBubbleAssistant": "zE6uZW_chatBubbleAssistant",
35592
+ "assetStatLabel": "zE6uZW_assetStatLabel",
35593
+ "dashHeroArrow": "zE6uZW_dashHeroArrow",
35594
+ "shelfHero": "zE6uZW_shelfHero",
35595
+ "adaptInputCard": "zE6uZW_adaptInputCard",
35596
+ "shelfStat": "zE6uZW_shelfStat",
35597
+ "ideaCard": "zE6uZW_ideaCard",
35433
35598
  "readerSeg": "zE6uZW_readerSeg",
35434
- "diffSameBody": "zE6uZW_diffSameBody",
35435
- "statCardD": "zE6uZW_statCardD",
35436
- "bookshelf": "zE6uZW_bookshelf",
35437
- "diffOld": "zE6uZW_diffOld",
35438
- "bookSwitchArrow": "zE6uZW_bookSwitchArrow",
35439
- "readerSegActive": "zE6uZW_readerSegActive",
35440
- "readerHeader": "zE6uZW_readerHeader",
35599
+ "spaceBetween": "zE6uZW_spaceBetween",
35600
+ "readerItemBadge": "zE6uZW_readerItemBadge",
35601
+ "shelfView": "zE6uZW_shelfView",
35602
+ "switch": "zE6uZW_switch",
35603
+ "navTitleLogo": "zE6uZW_navTitleLogo",
35604
+ "importModalTabs": "zE6uZW_importModalTabs",
35605
+ "assetEditorRow": "zE6uZW_assetEditorRow",
35606
+ "navTabBadgeDanger": "zE6uZW_navTabBadgeDanger",
35607
+ "reviewBox": "zE6uZW_reviewBox",
35608
+ "toolSteps": "zE6uZW_toolSteps",
35441
35609
  "todoInfo": "zE6uZW_todoInfo",
35442
- "button": "zE6uZW_button",
35443
- "liveText": "zE6uZW_liveText",
35444
- "panelTitle": "zE6uZW_panelTitle",
35445
- "navTabBadgeLive": "zE6uZW_navTabBadgeLive",
35446
- "shelfEmptyIcon": "zE6uZW_shelfEmptyIcon",
35447
- "shelfHero": "zE6uZW_shelfHero",
35448
- "navTabIcon": "zE6uZW_navTabIcon",
35449
- "fadeIn": "zE6uZW_fadeIn",
35450
- "tlSegTodo": "zE6uZW_tlSegTodo",
35451
- "tlSegTrack": "zE6uZW_tlSegTrack",
35452
- "dashHeroBook": "zE6uZW_dashHeroBook",
35453
- "readerItemTitle": "zE6uZW_readerItemTitle",
35454
- "shelfFilter": "zE6uZW_shelfFilter",
35455
- "navAboutRow": "zE6uZW_navAboutRow",
35456
- "fileList": "zE6uZW_fileList",
35610
+ "dimTitle": "zE6uZW_dimTitle",
35611
+ "field": "zE6uZW_field",
35612
+ "assistantStatus": "zE6uZW_assistantStatus",
35613
+ "adaptProposal": "zE6uZW_adaptProposal",
35614
+ "legendOld": "zE6uZW_legendOld",
35615
+ "navActions": "zE6uZW_navActions",
35457
35616
  "volumeGroupToggle": "zE6uZW_volumeGroupToggle",
35458
- "dashStageCurrent": "zE6uZW_dashStageCurrent",
35459
- "createBookCard": "zE6uZW_createBookCard",
35460
- "readerView": "zE6uZW_readerView",
35617
+ "settingsCard": "zE6uZW_settingsCard",
35618
+ "dimCard": "zE6uZW_dimCard",
35619
+ "toolStepStatus": "zE6uZW_toolStepStatus",
35620
+ "wsAppliedBanner": "zE6uZW_wsAppliedBanner",
35621
+ "buttonSmall": "zE6uZW_buttonSmall",
35461
35622
  "buttonPrimary": "zE6uZW_buttonPrimary",
35462
- "tlSegFill": "zE6uZW_tlSegFill",
35463
- "importPreview": "zE6uZW_importPreview",
35464
- "dashHeroArrow": "zE6uZW_dashHeroArrow",
35465
- "textarea": "zE6uZW_textarea",
35466
- "diffNew": "zE6uZW_diffNew",
35467
- "bookCardBlurb": "zE6uZW_bookCardBlurb",
35468
- "toolStepActive": "zE6uZW_toolStepActive",
35469
- "chatBubbleUser": "zE6uZW_chatBubbleUser",
35470
- "switch": "zE6uZW_switch",
35623
+ "diffDel": "zE6uZW_diffDel",
35624
+ "assetFilterChip": "zE6uZW_assetFilterChip",
35625
+ "switchKnob": "zE6uZW_switchKnob",
35626
+ "tlSegLabel": "zE6uZW_tlSegLabel",
35627
+ "navActionBtn": "zE6uZW_navActionBtn",
35628
+ "bookAddIcon": "zE6uZW_bookAddIcon",
35471
35629
  "chapterMain": "zE6uZW_chapterMain",
35472
- "readerChapterMeta": "zE6uZW_readerChapterMeta",
35473
- "shelfFilterCount": "zE6uZW_shelfFilterCount",
35474
- "navTitleName": "zE6uZW_navTitleName",
35630
+ "workflowLabel": "zE6uZW_workflowLabel",
35631
+ "tlSegDone": "zE6uZW_tlSegDone",
35475
35632
  "assistantFloatBody": "zE6uZW_assistantFloatBody",
35476
- "navGroupSep": "zE6uZW_navGroupSep",
35477
- "ideaToggle": "zE6uZW_ideaToggle",
35478
- "entryLabel": "zE6uZW_entryLabel",
35633
+ "input": "zE6uZW_input",
35634
+ "diffText": "zE6uZW_diffText",
35635
+ "dashStage": "zE6uZW_dashStage",
35636
+ "coverPlaceholder": "zE6uZW_coverPlaceholder",
35637
+ "statCardDDown": "zE6uZW_statCardDDown",
35638
+ "bigProgressBar": "zE6uZW_bigProgressBar",
35639
+ "onlyChanges": "zE6uZW_onlyChanges",
35640
+ "assetGroupHeader": "zE6uZW_assetGroupHeader",
35641
+ "todoItem": "zE6uZW_todoItem",
35642
+ "assetFilterChipActive": "zE6uZW_assetFilterChipActive",
35643
+ "assetCard": "zE6uZW_assetCard",
35644
+ "shelfEmptyTitle": "zE6uZW_shelfEmptyTitle",
35645
+ "readerGroupArrow": "zE6uZW_readerGroupArrow",
35646
+ "busyRow": "zE6uZW_busyRow",
35647
+ "shelfToolbar": "zE6uZW_shelfToolbar",
35648
+ "bookCardTitleRow": "zE6uZW_bookCardTitleRow",
35649
+ "card": "zE6uZW_card",
35650
+ "chapterTitle": "zE6uZW_chapterTitle",
35651
+ "adaptMatrix": "zE6uZW_adaptMatrix",
35652
+ "dimCardHead": "zE6uZW_dimCardHead",
35653
+ "bookAddCard": "zE6uZW_bookAddCard",
35654
+ "createBookCard": "zE6uZW_createBookCard",
35655
+ "importModalActions": "zE6uZW_importModalActions",
35656
+ "workflowRow": "zE6uZW_workflowRow",
35657
+ "adaptOutline": "zE6uZW_adaptOutline",
35658
+ "diffSameBody": "zE6uZW_diffSameBody",
35659
+ "authorRailTitle": "zE6uZW_authorRailTitle",
35660
+ "panelContent": "zE6uZW_panelContent",
35661
+ "navAboutRow": "zE6uZW_navAboutRow",
35662
+ "panelNav": "zE6uZW_panelNav",
35663
+ "chapterFocusPulse": "zE6uZW_chapterFocusPulse",
35664
+ "entryIcon": "zE6uZW_entryIcon",
35665
+ "toolStepError": "zE6uZW_toolStepError",
35666
+ "progress": "zE6uZW_progress",
35667
+ "tab": "zE6uZW_tab",
35668
+ "dashHeroAction": "zE6uZW_dashHeroAction",
35669
+ "todoDanger": "zE6uZW_todoDanger",
35670
+ "dimEdit": "zE6uZW_dimEdit",
35671
+ "adaptImpact": "zE6uZW_adaptImpact",
35672
+ "progressOverview": "zE6uZW_progressOverview",
35673
+ "tlSegCurrent": "zE6uZW_tlSegCurrent",
35674
+ "bookCardMetaRow": "zE6uZW_bookCardMetaRow",
35675
+ "dropzoneIcon": "zE6uZW_dropzoneIcon",
35479
35676
  "statCardDDetail": "zE6uZW_statCardDDetail",
35480
- "toolLive": "zE6uZW_toolLive",
35481
- "wsColumns": "zE6uZW_wsColumns",
35677
+ "dashFact": "zE6uZW_dashFact",
35678
+ "navTabBadgeLive": "zE6uZW_navTabBadgeLive",
35679
+ "readerArticle": "zE6uZW_readerArticle",
35680
+ "toolStepIcon": "zE6uZW_toolStepIcon",
35681
+ "progressTotalBar": "zE6uZW_progressTotalBar",
35682
+ "wsColumn": "zE6uZW_wsColumn",
35683
+ "dashJourney": "zE6uZW_dashJourney",
35684
+ "chapterNum": "zE6uZW_chapterNum",
35685
+ "progressBookActive": "zE6uZW_progressBookActive",
35686
+ "navTabBadgeDone": "zE6uZW_navTabBadgeDone",
35687
+ "dashHeroActionBody": "zE6uZW_dashHeroActionBody",
35688
+ "shelfSearch": "zE6uZW_shelfSearch",
35689
+ "bookCardActive": "zE6uZW_bookCardActive",
35690
+ "assetCardFooter": "zE6uZW_assetCardFooter",
35482
35691
  "tlSeg": "zE6uZW_tlSeg",
35483
- "importFileInfo": "zE6uZW_importFileInfo",
35484
- "shelfStatActive": "zE6uZW_shelfStatActive",
35485
- "badgeGenerating": "zE6uZW_badgeGenerating",
35486
- "bigProgressBarFill": "zE6uZW_bigProgressBarFill",
35487
- "bookCreateOutline": "zE6uZW_bookCreateOutline",
35488
- "shelfStats": "zE6uZW_shelfStats",
35489
- "workflowList": "zE6uZW_workflowList",
35490
- "legendNew": "zE6uZW_legendNew",
35491
- "readerBody": "zE6uZW_readerBody",
35492
- "readerGroupTitle": "zE6uZW_readerGroupTitle",
35493
- "dashJourneyStages": "zE6uZW_dashJourneyStages",
35692
+ "navTabBadgeWarn": "zE6uZW_navTabBadgeWarn",
35693
+ "authorRailBtnActive": "zE6uZW_authorRailBtnActive",
35694
+ "genreDesc": "zE6uZW_genreDesc",
35695
+ "wsEditor": "zE6uZW_wsEditor",
35696
+ "progressLineError": "zE6uZW_progressLineError",
35697
+ "importModal": "zE6uZW_importModal",
35698
+ "readerItemNo": "zE6uZW_readerItemNo",
35699
+ "navAboutUpdate": "zE6uZW_navAboutUpdate",
35700
+ "tlSegTodo": "zE6uZW_tlSegTodo",
35701
+ "authorContent": "zE6uZW_authorContent",
35702
+ "row": "zE6uZW_row",
35703
+ "authorPageBody": "zE6uZW_authorPageBody",
35704
+ "readerView": "zE6uZW_readerView",
35705
+ "assetCardName": "zE6uZW_assetCardName",
35706
+ "navTabBadge": "zE6uZW_navTabBadge",
35707
+ "dashHeroEyebrow": "zE6uZW_dashHeroEyebrow",
35708
+ "readerItemActive": "zE6uZW_readerItemActive",
35709
+ "assetStatDetail": "zE6uZW_assetStatDetail",
35710
+ "chapterActions": "zE6uZW_chapterActions",
35711
+ "statCardDIconRed": "zE6uZW_statCardDIconRed",
35494
35712
  "panel": "zE6uZW_panel",
35495
- "wsColumn": "zE6uZW_wsColumn",
35496
- "tlSegLabel": "zE6uZW_tlSegLabel",
35497
- "shelfGrid": "zE6uZW_shelfGrid",
35498
- "navSpacer": "zE6uZW_navSpacer",
35499
- "chapterTitle": "zE6uZW_chapterTitle",
35500
- "ideaCandidate": "zE6uZW_ideaCandidate",
35501
- "readerGroupCount": "zE6uZW_readerGroupCount",
35502
- "readerSegBtn": "zE6uZW_readerSegBtn",
35503
- "importModalTabs": "zE6uZW_importModalTabs",
35504
- "importModalBody": "zE6uZW_importModalBody",
35505
- "statCardDLabel": "zE6uZW_statCardDLabel",
35506
- "bookChipMeta": "zE6uZW_bookChipMeta",
35507
- "assetStatLabel": "zE6uZW_assetStatLabel",
35713
+ "textarea": "zE6uZW_textarea",
35714
+ "wsPageHeader": "zE6uZW_wsPageHeader",
35508
35715
  "dashJourneyBar": "zE6uZW_dashJourneyBar",
35509
- "readerItem": "zE6uZW_readerItem",
35510
- "toolSteps": "zE6uZW_toolSteps",
35511
- "dashHeroSparkle": "zE6uZW_dashHeroSparkle",
35512
- "assistantFloatHeader": "zE6uZW_assistantFloatHeader",
35513
- "diffLegend": "zE6uZW_diffLegend",
35514
- "diffChange": "zE6uZW_diffChange",
35515
- "createBookView": "zE6uZW_createBookView",
35516
- "badge": "zE6uZW_badge",
35517
- "shelfFilterActive": "zE6uZW_shelfFilterActive",
35518
- "createBookTop": "zE6uZW_createBookTop",
35519
35716
  "panelBody": "zE6uZW_panelBody",
35520
- "tlSegCurrent": "zE6uZW_tlSegCurrent",
35521
- "dashStageDot": "zE6uZW_dashStageDot",
35522
- "statCardDIcon": "zE6uZW_statCardDIcon",
35523
- "assistantFloat": "zE6uZW_assistantFloat",
35524
- "createBookIcon": "zE6uZW_createBookIcon",
35525
- "dashHeroTitle": "zE6uZW_dashHeroTitle"
35526
- };
35527
- //#endregion
35528
- //#region src/client/panel/AssistantTab.tsx
35529
- /**
35530
- * AI 助手(编辑老师):与 AI 编辑对话讨论剧情,助手通过动作指令直接修改
35531
- * 大纲 / 设定圣经 / 章节。流式渲染回复;工具调用显示为步骤卡片(中文名 +
35532
- * 状态 + 耗时),顶部状态条展示当前在做什么;支持清空对话记录。
35533
- */
35534
- /** 工具中文名 + 图标映射(作者看得懂)。 */
35535
- const TOOL_LABELS = {
35536
- book_overview: {
35537
- icon: "📖",
35538
- label: "读取全书上下文"
35717
+ "meta": "zE6uZW_meta",
35718
+ "navTabLabel": "zE6uZW_navTabLabel",
35719
+ "chapterList": "zE6uZW_chapterList",
35720
+ "badge": "zE6uZW_badge",
35721
+ "assetGroups": "zE6uZW_assetGroups",
35722
+ "todoWarning": "zE6uZW_todoWarning",
35723
+ "assetEditor": "zE6uZW_assetEditor",
35724
+ "progressBookBar": "zE6uZW_progressBookBar",
35725
+ "dropzone": "zE6uZW_dropzone",
35726
+ "readerGroupTitle": "zE6uZW_readerGroupTitle",
35727
+ "readerGroupCount": "zE6uZW_readerGroupCount",
35728
+ "legendNew": "zE6uZW_legendNew",
35729
+ "diffTagNew": "zE6uZW_diffTagNew",
35730
+ "cardTitle": "zE6uZW_cardTitle",
35731
+ "shelfEmpty": "zE6uZW_shelfEmpty",
35732
+ "statCardDLabel": "zE6uZW_statCardDLabel",
35733
+ "readerMain": "zE6uZW_readerMain",
35734
+ "importPreviewList": "zE6uZW_importPreviewList",
35735
+ "dashHeroActionTitle": "zE6uZW_dashHeroActionTitle",
35736
+ "bookCard": "zE6uZW_bookCard",
35737
+ "workflowList": "zE6uZW_workflowList",
35738
+ "bookCreateForm": "zE6uZW_bookCreateForm",
35739
+ "navTabIcon": "zE6uZW_navTabIcon",
35740
+ "navSpacer": "zE6uZW_navSpacer",
35741
+ "navGroup": "zE6uZW_navGroup",
35742
+ "workflowDotDone": "zE6uZW_workflowDotDone",
35743
+ "wsSelected": "zE6uZW_wsSelected",
35744
+ "progressBookName": "zE6uZW_progressBookName",
35745
+ "assetCardTop": "zE6uZW_assetCardTop",
35746
+ "progressOverviewNum": "zE6uZW_progressOverviewNum",
35747
+ "adaptTable": "zE6uZW_adaptTable",
35748
+ "bookSwitch": "zE6uZW_bookSwitch",
35749
+ "entryLabel": "zE6uZW_entryLabel",
35750
+ "adaptImpacts": "zE6uZW_adaptImpacts",
35751
+ "bookCardCoverFallback": "zE6uZW_bookCardCoverFallback",
35752
+ "importModalHead": "zE6uZW_importModalHead",
35753
+ "badgeGenerating": "zE6uZW_badgeGenerating",
35754
+ "badgeWritten": "zE6uZW_badgeWritten",
35755
+ "createBookIcon": "zE6uZW_createBookIcon",
35756
+ "tlSegTrack": "zE6uZW_tlSegTrack",
35757
+ "toolStepDetail": "zE6uZW_toolStepDetail",
35758
+ "bookSwitchName": "zE6uZW_bookSwitchName",
35759
+ "assetGrid": "zE6uZW_assetGrid",
35760
+ "panelNavCollapsed": "zE6uZW_panelNavCollapsed",
35761
+ "authorPageHero": "zE6uZW_authorPageHero",
35762
+ "chapter": "zE6uZW_chapter",
35763
+ "chatScroll": "zE6uZW_chatScroll",
35764
+ "iconBtn": "zE6uZW_iconBtn",
35765
+ "navTab": "zE6uZW_navTab",
35766
+ "bookCardProgressFill": "zE6uZW_bookCardProgressFill",
35767
+ "bookChipMeta": "zE6uZW_bookChipMeta",
35768
+ "readerSegActive": "zE6uZW_readerSegActive",
35769
+ "bookCardProgressBar": "zE6uZW_bookCardProgressBar",
35770
+ "readerGroup": "zE6uZW_readerGroup",
35771
+ "readerChapterMeta": "zE6uZW_readerChapterMeta",
35772
+ "dimCardSelected": "zE6uZW_dimCardSelected",
35773
+ "tabBar": "zE6uZW_tabBar",
35774
+ "button": "zE6uZW_button",
35775
+ "progressLine": "zE6uZW_progressLine",
35776
+ "dashStageDone": "zE6uZW_dashStageDone",
35777
+ "importModalBody": "zE6uZW_importModalBody",
35778
+ "assetTextarea": "zE6uZW_assetTextarea",
35779
+ "helpTip": "zE6uZW_helpTip",
35780
+ "authorHome": "zE6uZW_authorHome",
35781
+ "progressBar": "zE6uZW_progressBar",
35782
+ "importResult": "zE6uZW_importResult",
35783
+ "helpTipText": "zE6uZW_helpTipText",
35784
+ "wsPage": "zE6uZW_wsPage",
35785
+ "authorPageHeader": "zE6uZW_authorPageHeader",
35786
+ "coverPreview": "zE6uZW_coverPreview",
35787
+ "assetStat": "zE6uZW_assetStat"
35788
+ };
35789
+ //#endregion
35790
+ //#region src/client/panel/ModelManager.tsx
35791
+ /**
35792
+ * 模型管理(DSH 风格):两块分区——
35793
+ * ① 模型(提供方管理):提供方卡片(编辑/删除)+ 添加提供方 / 添加自定义提供方;
35794
+ * ② 当前写作模型:提供商/模型下拉 + 测试连通 + 推理强度。
35795
+ */
35796
+ /** 目录不可用时回退的内置预设(历史行为)。 */
35797
+ const FALLBACK_MODEL_PRESETS = [
35798
+ "deepseek-v4-flash",
35799
+ "deepseek-v4-pro",
35800
+ "deepseek-chat",
35801
+ "deepseek-reasoner"
35802
+ ];
35803
+ const CUSTOM = "__custom__";
35804
+ function fallbackVendors() {
35805
+ return LLM_VENDORS.map((v) => ({
35806
+ id: v.route,
35807
+ name: v.name,
35808
+ models: v.models,
35809
+ apiKeyEnv: v.apiKeyEnv,
35810
+ builtin: v.builtin
35811
+ }));
35812
+ }
35813
+ function ModelManager({ api, provider, model, onProvider, onModel }) {
35814
+ const [configuredProviders, setConfiguredProviders] = (0, react.useState)([]);
35815
+ const [providerModels, setProviderModels] = (0, react.useState)([]);
35816
+ const [modelsLoading, setModelsLoading] = (0, react.useState)(false);
35817
+ const [providerCustom, setProviderCustom] = (0, react.useState)(false);
35818
+ const [modelCustom, setModelCustom] = (0, react.useState)(false);
35819
+ const [test, setTest] = (0, react.useState)({ testing: false });
35820
+ const [vendors, setVendors] = (0, react.useState)(fallbackVendors());
35821
+ const [addPanel, setAddPanel] = (0, react.useState)("none");
35822
+ const [editTarget, setEditTarget] = (0, react.useState)("");
35823
+ const [vendorId, setVendorId] = (0, react.useState)("zai-coding-cn");
35824
+ const [addModel, setAddModel] = (0, react.useState)("");
35825
+ const [addApiKey, setAddApiKey] = (0, react.useState)("");
35826
+ const [addName, setAddName] = (0, react.useState)("");
35827
+ const [custProvider, setCustProvider] = (0, react.useState)("");
35828
+ const [custName, setCustName] = (0, react.useState)("");
35829
+ const [custBaseURL, setCustBaseURL] = (0, react.useState)("");
35830
+ const [custProtocol, setCustProtocol] = (0, react.useState)("openai-completions");
35831
+ const [custModel, setCustModel] = (0, react.useState)("");
35832
+ const [custApiKey, setCustApiKey] = (0, react.useState)("");
35833
+ const [savingAdd, setSavingAdd] = (0, react.useState)(false);
35834
+ const [addMsg, setAddMsg] = (0, react.useState)("");
35835
+ const [addErr, setAddErr] = (0, react.useState)("");
35836
+ const loadProviders = (0, react.useCallback)(async () => {
35837
+ try {
35838
+ const r = await api.llmProviders();
35839
+ if (r.providers.length > 0) setConfiguredProviders(r.providers);
35840
+ } catch {}
35841
+ }, [api]);
35842
+ const loadVendors = (0, react.useCallback)(async () => {
35843
+ try {
35844
+ const r = await api.llmVendors();
35845
+ if (r.vendors.length > 0) setVendors(r.vendors);
35846
+ } catch {}
35847
+ }, [api]);
35848
+ const loadProviderModels = (0, react.useCallback)(async (p) => {
35849
+ setModelsLoading(true);
35850
+ try {
35851
+ const r = await api.llmModels(p);
35852
+ setProviderModels(r.models);
35853
+ } catch {
35854
+ setProviderModels([]);
35855
+ } finally {
35856
+ setModelsLoading(false);
35857
+ }
35858
+ }, [api]);
35859
+ (0, react.useEffect)(() => {
35860
+ loadProviders();
35861
+ loadVendors();
35862
+ }, [
35863
+ api,
35864
+ loadProviders,
35865
+ loadVendors
35866
+ ]);
35867
+ (0, react.useEffect)(() => {
35868
+ if (provider !== "") loadProviderModels(provider);
35869
+ }, [provider, loadProviderModels]);
35870
+ const currentVendor = vendors.find((v) => v.id === vendorId);
35871
+ const runTest = async () => {
35872
+ const p = provider.trim();
35873
+ const m = model.trim();
35874
+ if (p === "" || m === "" || test.testing) return;
35875
+ setTest({ testing: true });
35876
+ try {
35877
+ const r = await api.llmTest(p, m);
35878
+ setTest({
35879
+ testing: false,
35880
+ ok: r.ok,
35881
+ ms: r.ms,
35882
+ message: r.message
35883
+ });
35884
+ } catch (err) {
35885
+ setTest({
35886
+ testing: false,
35887
+ ok: false,
35888
+ message: err.message
35889
+ });
35890
+ }
35891
+ };
35892
+ const openPanel = (panel, target = "") => {
35893
+ setAddPanel(panel);
35894
+ setEditTarget(target);
35895
+ setAddMsg("");
35896
+ setAddErr("");
35897
+ if (panel === "standard") {
35898
+ setVendorId(target !== "" ? target : "zai-coding-cn");
35899
+ setAddModel("");
35900
+ setAddApiKey("");
35901
+ setAddName("");
35902
+ } else if (panel === "custom") {
35903
+ setCustProvider(target);
35904
+ setCustName("");
35905
+ setCustBaseURL("");
35906
+ setCustModel("");
35907
+ setCustApiKey("");
35908
+ }
35909
+ };
35910
+ const saveStandard = async () => {
35911
+ if (vendorId.trim() === "") {
35912
+ setAddErr("请选择提供方");
35913
+ return;
35914
+ }
35915
+ if (addApiKey.trim() === "") {
35916
+ setAddErr("请填写 API 密钥(或留空使用环境认证)");
35917
+ return;
35918
+ }
35919
+ const modelId = addModel.trim();
35920
+ setSavingAdd(true);
35921
+ setAddMsg("");
35922
+ setAddErr("");
35923
+ try {
35924
+ const res = await api.addModel({
35925
+ mode: "vendor",
35926
+ vendor: vendorId,
35927
+ model: modelId || vendorId,
35928
+ apiKey: addApiKey.trim(),
35929
+ apiKeyEnv: currentVendor?.apiKeyEnv,
35930
+ name: addName.trim() || void 0
35931
+ });
35932
+ setAddMsg(res.message ?? "已保存");
35933
+ setAddPanel("none");
35934
+ setAddApiKey("");
35935
+ setAddModel("");
35936
+ setAddName("");
35937
+ setEditTarget("");
35938
+ await loadProviders();
35939
+ } catch (err) {
35940
+ setAddErr(err.message);
35941
+ } finally {
35942
+ setSavingAdd(false);
35943
+ }
35944
+ };
35945
+ const saveCustom = async () => {
35946
+ if (custProvider.trim() === "") {
35947
+ setAddErr("请填 Provider ID");
35948
+ return;
35949
+ }
35950
+ if (custBaseURL.trim() === "") {
35951
+ setAddErr("请填 API 地址");
35952
+ return;
35953
+ }
35954
+ if (custApiKey.trim() === "") {
35955
+ setAddErr("请填 API 密钥(或留空使用环境认证)");
35956
+ return;
35957
+ }
35958
+ if (custModel.trim() === "") {
35959
+ setAddErr("请填模型 id(或点“获取可用模型”)");
35960
+ return;
35961
+ }
35962
+ setSavingAdd(true);
35963
+ setAddMsg("");
35964
+ setAddErr("");
35965
+ try {
35966
+ const res = await api.addModel({
35967
+ mode: "custom",
35968
+ provider: custProvider.trim(),
35969
+ model: custModel.trim(),
35970
+ apiKey: custApiKey.trim(),
35971
+ baseURL: custBaseURL.trim(),
35972
+ name: custName.trim() || void 0
35973
+ });
35974
+ setAddMsg(res.message ?? "已创建提供方");
35975
+ setAddPanel("none");
35976
+ setCustProvider("");
35977
+ setCustName("");
35978
+ setCustBaseURL("");
35979
+ setCustModel("");
35980
+ setCustApiKey("");
35981
+ await loadProviders();
35982
+ } catch (err) {
35983
+ setAddErr(err.message);
35984
+ } finally {
35985
+ setSavingAdd(false);
35986
+ }
35987
+ };
35988
+ const removeProvider = async (p) => {
35989
+ if (!window.confirm("删除提供方「" + (p.name !== "" ? p.name : p.id) + "」?将移除 DSH 配置与 API 密钥。")) return;
35990
+ try {
35991
+ const vendor = vendors.find((v) => v.id === p.id);
35992
+ await api.removeProvider({
35993
+ provider: p.id,
35994
+ apiKeyEnv: vendor?.apiKeyEnv
35995
+ });
35996
+ await loadProviders();
35997
+ } catch (err) {
35998
+ setAddErr(err.message);
35999
+ }
36000
+ };
36001
+ const providerOptions = configuredProviders.some((p) => p.id === provider) ? configuredProviders : provider !== "" && provider !== CUSTOM ? [{
36002
+ id: provider,
36003
+ name: provider
36004
+ }, ...configuredProviders] : configuredProviders;
36005
+ const modelOptions = modelCustom ? [] : provider === "deepseek-official" ? [...FALLBACK_MODEL_PRESETS.map((id) => ({
36006
+ id,
36007
+ name: id
36008
+ })), ...providerModels.filter((m) => !FALLBACK_MODEL_PRESETS.includes(m.id))] : providerModels;
36009
+ const modelInList = modelOptions.some((m) => m.id === model);
36010
+ const modelValue = modelCustom || !modelInList && model !== "" && modelOptions.length > 0 ? CUSTOM : model;
36011
+ const providerValue = providerCustom ? CUSTOM : provider;
36012
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36013
+ style: {
36014
+ display: "flex",
36015
+ flexDirection: "column",
36016
+ gap: "var(--nf-space-24)"
36017
+ },
36018
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36019
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
36020
+ style: { gap: "var(--nf-space-16)" },
36021
+ children: [
36022
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
36023
+ className: panel_module_css_default.cardTitle,
36024
+ children: "模型"
36025
+ }),
36026
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
36027
+ className: panel_module_css_default.meta,
36028
+ children: "填入各提供方的 API 密钥即可使用其模型。"
36029
+ }),
36030
+ configuredProviders.map((p) => {
36031
+ const isBuiltin = p.id === "deepseek-official";
36032
+ const isKnownVendor = vendors.some((v) => v.id === p.id);
36033
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36034
+ style: {
36035
+ border: "1px solid var(--nf-border)",
36036
+ borderRadius: "var(--nf-radius-12)",
36037
+ padding: "var(--nf-space-12)",
36038
+ display: "flex",
36039
+ alignItems: "center",
36040
+ gap: "var(--nf-space-8)",
36041
+ flexWrap: "wrap",
36042
+ justifyContent: "space-between"
36043
+ },
36044
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36045
+ style: {
36046
+ display: "flex",
36047
+ alignItems: "center",
36048
+ gap: "var(--nf-space-8)"
36049
+ },
36050
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
36051
+ style: { fontWeight: 600 },
36052
+ children: p.name !== "" && p.name !== p.id ? p.name : p.id
36053
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
36054
+ width: 8,
36055
+ height: 8,
36056
+ borderRadius: "50%",
36057
+ background: "var(--nf-success)"
36058
+ } })]
36059
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36060
+ style: {
36061
+ display: "flex",
36062
+ gap: "var(--nf-space-6)",
36063
+ alignItems: "center"
36064
+ },
36065
+ children: [!isBuiltin && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
36066
+ type: "button",
36067
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36068
+ onClick: () => openPanel(isKnownVendor ? "standard" : "custom", p.id),
36069
+ children: tt("settings.edit")
36070
+ }), !isBuiltin && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
36071
+ type: "button",
36072
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36073
+ style: { color: "var(--nf-error)" },
36074
+ onClick: () => {
36075
+ removeProvider(p);
36076
+ },
36077
+ children: tt("settings.delete")
36078
+ })]
36079
+ })]
36080
+ }, p.id);
36081
+ }),
36082
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36083
+ className: panel_module_css_default.row,
36084
+ style: {
36085
+ gap: "var(--nf-space-10)",
36086
+ flexWrap: "wrap"
36087
+ },
36088
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
36089
+ type: "button",
36090
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36091
+ onClick: () => openPanel("standard"),
36092
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, {
36093
+ size: 13,
36094
+ style: { verticalAlign: -2 }
36095
+ }), " 添加提供方"]
36096
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
36097
+ type: "button",
36098
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36099
+ onClick: () => openPanel("custom"),
36100
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, {
36101
+ size: 13,
36102
+ style: { verticalAlign: -2 }
36103
+ }), " 添加自定义提供方"]
36104
+ })]
36105
+ }),
36106
+ addPanel !== "none" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36107
+ style: {
36108
+ border: "1px solid var(--nf-border)",
36109
+ borderRadius: "var(--nf-radius-12)",
36110
+ padding: "var(--nf-space-12)",
36111
+ display: "flex",
36112
+ flexDirection: "column",
36113
+ gap: "var(--nf-space-12)"
36114
+ },
36115
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36116
+ className: panel_module_css_default.row,
36117
+ style: {
36118
+ justifyContent: "space-between",
36119
+ alignItems: "center"
36120
+ },
36121
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
36122
+ className: panel_module_css_default.fieldLabel,
36123
+ children: addPanel === "standard" ? editTarget !== "" ? "编辑提供方" : "添加提供方" : "自定义提供方"
36124
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
36125
+ type: "button",
36126
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36127
+ onClick: () => openPanel("none"),
36128
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.X, {
36129
+ size: 13,
36130
+ style: { verticalAlign: -2 }
36131
+ }), " 关闭"]
36132
+ })]
36133
+ }), addPanel === "standard" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
36134
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36135
+ className: panel_module_css_default.field,
36136
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36137
+ className: panel_module_css_default.fieldLabel,
36138
+ children: "提供方"
36139
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
36140
+ className: panel_module_css_default.input,
36141
+ value: vendorId,
36142
+ onChange: (e) => setVendorId(e.target.value),
36143
+ children: vendors.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
36144
+ value: v.id,
36145
+ children: v.name
36146
+ }, v.id))
36147
+ })]
36148
+ }),
36149
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36150
+ className: panel_module_css_default.field,
36151
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36152
+ className: panel_module_css_default.fieldLabel,
36153
+ children: "API 密钥"
36154
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36155
+ className: panel_module_css_default.input,
36156
+ type: "password",
36157
+ value: addApiKey,
36158
+ onChange: (e) => setAddApiKey(e.target.value),
36159
+ placeholder: "输入 API 密钥,或留空使用环境认证"
36160
+ })]
36161
+ }),
36162
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36163
+ className: panel_module_css_default.field,
36164
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36165
+ className: panel_module_css_default.fieldLabel,
36166
+ children: "模型 id(可选)"
36167
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36168
+ className: panel_module_css_default.input,
36169
+ value: addModel,
36170
+ onChange: (e) => setAddModel(e.target.value),
36171
+ placeholder: "例如 glm-5.3-flash"
36172
+ })]
36173
+ }),
36174
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36175
+ className: panel_module_css_default.row,
36176
+ style: {
36177
+ justifyContent: "flex-end",
36178
+ gap: "var(--nf-space-8)"
36179
+ },
36180
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
36181
+ type: "button",
36182
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36183
+ onClick: () => openPanel("none"),
36184
+ children: "取消"
36185
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
36186
+ type: "button",
36187
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall + " " + panel_module_css_default.buttonPrimary,
36188
+ disabled: savingAdd,
36189
+ onClick: () => {
36190
+ saveStandard();
36191
+ },
36192
+ children: savingAdd ? "保存中…" : "保存"
36193
+ })]
36194
+ })
36195
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
36196
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36197
+ className: panel_module_css_default.field,
36198
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36199
+ className: panel_module_css_default.fieldLabel,
36200
+ children: "Provider ID"
36201
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36202
+ className: panel_module_css_default.input,
36203
+ value: custProvider,
36204
+ onChange: (e) => setCustProvider(e.target.value),
36205
+ placeholder: "acme-gateway"
36206
+ })]
36207
+ }),
36208
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36209
+ className: panel_module_css_default.field,
36210
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36211
+ className: panel_module_css_default.fieldLabel,
36212
+ children: "显示名称"
36213
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36214
+ className: panel_module_css_default.input,
36215
+ value: custName,
36216
+ onChange: (e) => setCustName(e.target.value),
36217
+ placeholder: "显示名称"
36218
+ })]
36219
+ }),
36220
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36221
+ className: panel_module_css_default.field,
36222
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36223
+ className: panel_module_css_default.fieldLabel,
36224
+ children: "API 地址"
36225
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36226
+ className: panel_module_css_default.input,
36227
+ value: custBaseURL,
36228
+ onChange: (e) => setCustBaseURL(e.target.value),
36229
+ placeholder: "https://gateway.example/v1"
36230
+ })]
36231
+ }),
36232
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36233
+ className: panel_module_css_default.field,
36234
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36235
+ className: panel_module_css_default.fieldLabel,
36236
+ children: "API 协议"
36237
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
36238
+ className: panel_module_css_default.input,
36239
+ value: custProtocol,
36240
+ onChange: (e) => setCustProtocol(e.target.value),
36241
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
36242
+ value: "openai-completions",
36243
+ children: "openai-completions"
36244
+ })
36245
+ })]
36246
+ }),
36247
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36248
+ className: panel_module_css_default.field,
36249
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36250
+ className: panel_module_css_default.fieldLabel,
36251
+ children: "API 密钥"
36252
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36253
+ className: panel_module_css_default.input,
36254
+ type: "password",
36255
+ value: custApiKey,
36256
+ onChange: (e) => setCustApiKey(e.target.value),
36257
+ placeholder: "输入 API 密钥"
36258
+ })]
36259
+ }),
36260
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36261
+ className: panel_module_css_default.field,
36262
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36263
+ className: panel_module_css_default.fieldLabel,
36264
+ children: "模型目录 / 模型 id"
36265
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36266
+ className: panel_module_css_default.input,
36267
+ value: custModel,
36268
+ onChange: (e) => setCustModel(e.target.value),
36269
+ placeholder: "例如 glm-5.3-flash"
36270
+ })]
36271
+ }),
36272
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36273
+ className: panel_module_css_default.row,
36274
+ style: {
36275
+ justifyContent: "flex-end",
36276
+ gap: "var(--nf-space-8)"
36277
+ },
36278
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
36279
+ type: "button",
36280
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36281
+ onClick: () => openPanel("none"),
36282
+ children: "取消"
36283
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
36284
+ type: "button",
36285
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall + " " + panel_module_css_default.buttonPrimary,
36286
+ disabled: savingAdd,
36287
+ onClick: () => {
36288
+ saveCustom();
36289
+ },
36290
+ children: savingAdd ? "创建中…" : "创建提供方"
36291
+ })]
36292
+ })
36293
+ ] })]
36294
+ }),
36295
+ addMsg !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
36296
+ className: panel_module_css_default.meta,
36297
+ style: { color: "var(--nf-success)" },
36298
+ children: ["✓ ", addMsg]
36299
+ }),
36300
+ addErr !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
36301
+ className: panel_module_css_default.meta,
36302
+ style: { color: "var(--nf-error)" },
36303
+ children: ["✗ ", addErr]
36304
+ })
36305
+ ]
36306
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36307
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
36308
+ style: { gap: "var(--nf-space-16)" },
36309
+ children: [
36310
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
36311
+ className: panel_module_css_default.cardTitle,
36312
+ children: "当前写作模型"
36313
+ }),
36314
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36315
+ className: panel_module_css_default.field,
36316
+ children: [
36317
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36318
+ className: panel_module_css_default.fieldLabel,
36319
+ children: tt("settings.provider")
36320
+ }),
36321
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
36322
+ className: panel_module_css_default.input,
36323
+ value: providerValue,
36324
+ onChange: (e) => {
36325
+ const v = e.target.value;
36326
+ if (v === CUSTOM) setProviderCustom(true);
36327
+ else {
36328
+ setProviderCustom(false);
36329
+ onProvider(v);
36330
+ }
36331
+ },
36332
+ children: [providerOptions.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
36333
+ value: p.id,
36334
+ children: p.name !== "" && p.name !== p.id ? p.name + "(" + p.id + ")" : p.id
36335
+ }, p.id)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
36336
+ value: CUSTOM,
36337
+ children: tt("settings.customProvider")
36338
+ })]
36339
+ }),
36340
+ providerCustom && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36341
+ className: panel_module_css_default.input,
36342
+ style: { marginTop: "var(--nf-space-6)" },
36343
+ value: provider,
36344
+ placeholder: "provider 路由 id",
36345
+ onChange: (e) => onProvider(e.target.value)
36346
+ })
36347
+ ]
36348
+ }),
36349
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36350
+ className: panel_module_css_default.field,
36351
+ children: [
36352
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36353
+ className: panel_module_css_default.fieldLabel,
36354
+ children: tt("settings.model")
36355
+ }),
36356
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36357
+ className: panel_module_css_default.row,
36358
+ style: {
36359
+ gap: "var(--nf-space-8)",
36360
+ flexWrap: "wrap"
36361
+ },
36362
+ children: [
36363
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
36364
+ className: panel_module_css_default.input,
36365
+ style: {
36366
+ flex: 1,
36367
+ minWidth: 200
36368
+ },
36369
+ value: modelValue,
36370
+ onChange: (e) => {
36371
+ const v = e.target.value;
36372
+ if (v === CUSTOM) setModelCustom(true);
36373
+ else {
36374
+ setModelCustom(false);
36375
+ onModel(v);
36376
+ }
36377
+ },
36378
+ children: [modelOptions.map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
36379
+ value: m.id,
36380
+ children: m.name !== "" && m.name !== m.id ? m.name + "(" + m.id + ")" : m.id
36381
+ }, m.id)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
36382
+ value: CUSTOM,
36383
+ children: tt("settings.modelCustom")
36384
+ })]
36385
+ }),
36386
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
36387
+ type: "button",
36388
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36389
+ disabled: modelsLoading || provider === "",
36390
+ title: "刷新模型",
36391
+ onClick: () => {
36392
+ loadProviderModels(provider);
36393
+ },
36394
+ children: [
36395
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.RefreshCw, {
36396
+ size: 13,
36397
+ style: { verticalAlign: -2 }
36398
+ }),
36399
+ " ",
36400
+ modelsLoading ? "…" : tt("settings.refreshModels")
36401
+ ]
36402
+ }),
36403
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
36404
+ type: "button",
36405
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
36406
+ disabled: test.testing || provider.trim() === "" || model.trim() === "",
36407
+ onClick: () => {
36408
+ runTest();
36409
+ },
36410
+ title: tt("settings.testHint"),
36411
+ children: [
36412
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.PlugZap, {
36413
+ size: 13,
36414
+ style: { verticalAlign: -2 }
36415
+ }),
36416
+ " ",
36417
+ test.testing ? tt("settings.testRunning") : tt("settings.testConnection")
36418
+ ]
36419
+ })
36420
+ ]
36421
+ }),
36422
+ modelCustom && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
36423
+ className: panel_module_css_default.input,
36424
+ style: { marginTop: "var(--nf-space-6)" },
36425
+ value: model,
36426
+ placeholder: tt("settings.modelCustomPlaceholder"),
36427
+ onChange: (e) => onModel(e.target.value)
36428
+ }),
36429
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
36430
+ className: panel_module_css_default.meta,
36431
+ style: { color: test.ok === true ? "var(--nf-success)" : test.ok === false ? "var(--nf-error)" : void 0 },
36432
+ children: test.testing ? tt("settings.testRunning") + "…" : test.ok === true ? "✓ " + tt("settings.testOk") + " · " + (test.ms ?? "?") + "ms" : test.ok === false ? "✗ " + tt("settings.testFail") + (test.message !== void 0 ? ":" + test.message : "") : tt("settings.testHint")
36433
+ })
36434
+ ]
36435
+ })
36436
+ ]
36437
+ })]
36438
+ });
36439
+ }
36440
+ //#endregion
36441
+ //#region src/client/panel/ReasoningSection.tsx
36442
+ /**
36443
+ * 推理强度(思考强度)独立容器:写作类/分析类两个 reasoningEffort 下拉。
36444
+ */
36445
+ const REASONING_OPTIONS = [
36446
+ "off",
36447
+ "low",
36448
+ "high",
36449
+ "max"
36450
+ ];
36451
+ const REASONING_LABEL = {
36452
+ off: tt("settings.reasoning.off"),
36453
+ low: tt("settings.reasoning.low"),
36454
+ high: tt("settings.reasoning.high"),
36455
+ max: tt("settings.reasoning.max")
36456
+ };
36457
+ function ReasoningSection({ reasoningEffort, analysisReasoning, onChange }) {
36458
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36459
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
36460
+ style: { gap: "var(--nf-space-24)" },
36461
+ children: [
36462
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
36463
+ className: panel_module_css_default.cardTitle,
36464
+ children: [
36465
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Brain, {
36466
+ size: 18,
36467
+ style: { verticalAlign: -3 }
36468
+ }),
36469
+ " ",
36470
+ tt("settings.reasoningSection")
36471
+ ]
36472
+ }),
36473
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36474
+ className: panel_module_css_default.field,
36475
+ children: [
36476
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36477
+ className: panel_module_css_default.fieldLabel,
36478
+ children: tt("settings.reasoningEffort")
36479
+ }),
36480
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
36481
+ className: panel_module_css_default.input,
36482
+ value: reasoningEffort ?? "off",
36483
+ onChange: (e) => onChange({ reasoningEffort: e.target.value }),
36484
+ children: REASONING_OPTIONS.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
36485
+ value: v,
36486
+ children: REASONING_LABEL[v]
36487
+ }, v))
36488
+ }),
36489
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
36490
+ className: panel_module_css_default.meta,
36491
+ children: tt("settings.reasoningHint")
36492
+ })
36493
+ ]
36494
+ }),
36495
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36496
+ className: panel_module_css_default.field,
36497
+ children: [
36498
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
36499
+ className: panel_module_css_default.fieldLabel,
36500
+ children: tt("settings.analysisReasoning")
36501
+ }),
36502
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
36503
+ className: panel_module_css_default.input,
36504
+ value: analysisReasoning ?? "low",
36505
+ onChange: (e) => onChange({ analysisReasoning: e.target.value }),
36506
+ children: REASONING_OPTIONS.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
36507
+ value: v,
36508
+ children: REASONING_LABEL[v]
36509
+ }, v))
36510
+ }),
36511
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
36512
+ className: panel_module_css_default.meta,
36513
+ children: tt("settings.analysisReasoningHint")
36514
+ })
36515
+ ]
36516
+ })
36517
+ ]
36518
+ });
36519
+ }
36520
+ //#endregion
36521
+ //#region src/client/panel/AssistantTab.tsx
36522
+ /**
36523
+ * AI 助手(编辑老师):与 AI 编辑对话讨论剧情,助手通过动作指令直接修改
36524
+ * 大纲 / 设定圣经 / 章节。流式渲染回复;工具调用显示为步骤卡片(中文名 +
36525
+ * 状态 + 耗时),顶部状态条展示当前在做什么;支持清空对话记录。
36526
+ */
36527
+ /** 工具中文名 + 图标映射(作者看得懂)。 */
36528
+ const TOOL_LABELS = {
36529
+ book_overview: {
36530
+ icon: "📖",
36531
+ label: "读取全书上下文"
35539
36532
  },
35540
36533
  impact_analysis: {
35541
36534
  icon: "🔗",
@@ -37126,6 +38119,2252 @@ window.__ModuleLoader__.load({
37126
38119
  });
37127
38120
  }
37128
38121
  //#endregion
38122
+ //#region src/client/text.ts
38123
+ /**
38124
+ * 客户端文件文本智能解码:兼容 UTF-8 BOM / UTF-16 / UTF-8 / GB18030(GBK)。
38125
+ * 浏览器 File.text() 固定按 UTF-8 解码,GBK 中文网文 txt 会乱码,这里兜底。
38126
+ */
38127
+ /**
38128
+ * 读取一个 File 的文本,按编码探测兜底解码。
38129
+ * @returns 解码后的文本。
38130
+ */
38131
+ async function readFileTextSmart(file) {
38132
+ const buf = await file.arrayBuffer();
38133
+ const u8 = new Uint8Array(buf);
38134
+ if (u8.length >= 3 && u8[0] === 239 && u8[1] === 187 && u8[2] === 191) return new TextDecoder("utf-8").decode(u8.subarray(3));
38135
+ if (u8.length >= 2 && u8[0] === 255 && u8[1] === 254) return new TextDecoder("utf-16le").decode(u8.subarray(2));
38136
+ if (u8.length >= 2 && u8[0] === 254 && u8[1] === 255) return new TextDecoder("utf-16be").decode(u8.subarray(2));
38137
+ const utf8 = new TextDecoder("utf-8", { fatal: false }).decode(u8);
38138
+ if (!utf8.includes("�")) return utf8;
38139
+ try {
38140
+ return new TextDecoder("gb18030").decode(u8);
38141
+ } catch {
38142
+ return utf8;
38143
+ }
38144
+ }
38145
+ //#endregion
38146
+ //#region src/client/panel/AdaptModeView.tsx
38147
+ /**
38148
+ * 改编模式:P0 分析 → P1 改编方案(勾选/填新值→映射表/规则/影响) → P2 术语替换执行。
38149
+ */
38150
+ const MUTABILITY_LABEL = {
38151
+ locked: "🔒 建议保留",
38152
+ big: "🟡 可改影响大",
38153
+ small: "🟢 可改影响小",
38154
+ free: "🟣 可自由改",
38155
+ visual: "📦 仅视觉包装"
38156
+ };
38157
+ const MUTABILITY_CLS = {
38158
+ locked: "var(--nf-muted)",
38159
+ big: "var(--nf-warn)",
38160
+ small: "var(--nf-info)",
38161
+ free: "var(--nf-accent)",
38162
+ visual: "var(--nf-muted)"
38163
+ };
38164
+ const RISK_LABEL = {
38165
+ high: "高风险",
38166
+ medium: "中风险",
38167
+ low: "低风险"
38168
+ };
38169
+ function AdaptModeView({ api }) {
38170
+ const [text, setText] = (0, react.useState)("");
38171
+ const [result, setResult] = (0, react.useState)(null);
38172
+ const [edits, setEdits] = (0, react.useState)({});
38173
+ const [proposal, setProposal] = (0, react.useState)(null);
38174
+ const [executed, setExecuted] = (0, react.useState)(null);
38175
+ const [busy, setBusy] = (0, react.useState)(false);
38176
+ const [busyLabel, setBusyLabel] = (0, react.useState)("");
38177
+ const [error, setError] = (0, react.useState)("");
38178
+ const fileRef = (0, react.useRef)(null);
38179
+ const onFile = async (e) => {
38180
+ const file = e.target.files?.[0];
38181
+ if (file === void 0) return;
38182
+ try {
38183
+ setText(await readFileTextSmart(file));
38184
+ } catch (err) {
38185
+ setError(err.message);
38186
+ }
38187
+ e.target.value = "";
38188
+ };
38189
+ const analyze = async () => {
38190
+ if (text.trim().length < 200) {
38191
+ setError("请粘贴或上传完整小说全文(至少 200 字符)");
38192
+ return;
38193
+ }
38194
+ setBusy(true);
38195
+ setBusyLabel("分析中…");
38196
+ setError("");
38197
+ setProposal(null);
38198
+ setExecuted(null);
38199
+ try {
38200
+ const res = await api.adaptAnalyze(text);
38201
+ setResult(res);
38202
+ const next = {};
38203
+ for (const d of res.dimensions) next[d.key] = {
38204
+ enabled: d.mutability !== "locked",
38205
+ target: d.candidates?.[0] ?? ""
38206
+ };
38207
+ setEdits(next);
38208
+ } catch (err) {
38209
+ setError(err.message);
38210
+ } finally {
38211
+ setBusy(false);
38212
+ setBusyLabel("");
38213
+ }
38214
+ };
38215
+ const setEdit = (key, patch) => {
38216
+ setEdits((prev) => ({
38217
+ ...prev,
38218
+ [key]: {
38219
+ ...prev[key],
38220
+ ...patch
38221
+ }
38222
+ }));
38223
+ };
38224
+ const selectedDims = result === null ? [] : result.dimensions.filter((d) => {
38225
+ const e = edits[d.key];
38226
+ return e?.enabled === true && (e.target ?? "").trim() !== "";
38227
+ });
38228
+ const buildSelections = () => selectedDims.map((d) => ({
38229
+ key: d.key,
38230
+ title: d.title,
38231
+ current: d.current,
38232
+ target: (edits[d.key]?.target ?? "").trim(),
38233
+ mutability: d.mutability
38234
+ }));
38235
+ const propose = async () => {
38236
+ if (result === null || text.trim().length < 200) {
38237
+ setError("请先分析");
38238
+ return;
38239
+ }
38240
+ const selections = buildSelections();
38241
+ if (selections.length === 0) {
38242
+ setError("请至少选择一条要改的维度并填写新值");
38243
+ return;
38244
+ }
38245
+ setBusy(true);
38246
+ setBusyLabel("生成改编方案…");
38247
+ setError("");
38248
+ setExecuted(null);
38249
+ try {
38250
+ const res = await api.adaptPropose({
38251
+ text,
38252
+ selections,
38253
+ dimensions: result.dimensions
38254
+ });
38255
+ setProposal(res.proposal);
38256
+ } catch (err) {
38257
+ setError(err.message);
38258
+ } finally {
38259
+ setBusy(false);
38260
+ setBusyLabel("");
38261
+ }
38262
+ };
38263
+ const execute = async () => {
38264
+ if (proposal === null || proposal.mappings.length === 0) {
38265
+ setError("请先生成改编方案");
38266
+ return;
38267
+ }
38268
+ setBusy(true);
38269
+ setBusyLabel("执行术语替换…");
38270
+ setError("");
38271
+ try {
38272
+ const res = await api.adaptExecute({
38273
+ text,
38274
+ mappings: proposal.mappings,
38275
+ mode: "replace"
38276
+ });
38277
+ setExecuted(res);
38278
+ } catch (err) {
38279
+ setError(err.message);
38280
+ } finally {
38281
+ setBusy(false);
38282
+ setBusyLabel("");
38283
+ }
38284
+ };
38285
+ const downloadAdapted = () => {
38286
+ if (executed === null) return;
38287
+ const blob = new Blob([executed.adaptedText], { type: "text/markdown;charset=utf-8" });
38288
+ const url = URL.createObjectURL(blob);
38289
+ const a = document.createElement("a");
38290
+ a.href = url;
38291
+ a.download = result?.bookName !== void 0 && result.bookName !== "" ? result.bookName + "·改编版.md" : "改编版.md";
38292
+ a.click();
38293
+ URL.revokeObjectURL(url);
38294
+ };
38295
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38296
+ className: panel_module_css_default.authorPageBody,
38297
+ children: [
38298
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38299
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
38300
+ style: { gap: "var(--nf-space-6)" },
38301
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
38302
+ className: panel_module_css_default.panelTitle,
38303
+ style: { margin: 0 },
38304
+ children: "🎬 改编模式"
38305
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38306
+ className: panel_module_css_default.meta,
38307
+ children: "上传全文 → 分析可改范围 → 勾选/填新值 → 生成映射表 → 术语替换执行。"
38308
+ })]
38309
+ }),
38310
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38311
+ className: panel_module_css_default.adaptInputCard,
38312
+ children: [
38313
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38314
+ className: panel_module_css_default.rowEnd,
38315
+ style: { justifyContent: "space-between" },
38316
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38317
+ className: panel_module_css_default.meta,
38318
+ children: "粘贴全文,或上传 txt/md 文件"
38319
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
38320
+ type: "button",
38321
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
38322
+ onClick: () => fileRef.current?.click(),
38323
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Upload, {
38324
+ size: 13,
38325
+ style: { verticalAlign: -2 }
38326
+ }), " 上传文件"]
38327
+ })]
38328
+ }),
38329
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
38330
+ ref: fileRef,
38331
+ type: "file",
38332
+ accept: ".txt,.md,text/plain,text/markdown",
38333
+ style: { display: "none" },
38334
+ onChange: (e) => {
38335
+ onFile(e);
38336
+ }
38337
+ }),
38338
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
38339
+ className: panel_module_css_default.input + " " + panel_module_css_default.adaptTextarea,
38340
+ value: text,
38341
+ onChange: (e) => setText(e.target.value),
38342
+ placeholder: "粘贴小说全文(含章节标题/分卷更好)…"
38343
+ }),
38344
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38345
+ className: panel_module_css_default.rowEnd,
38346
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
38347
+ className: panel_module_css_default.meta,
38348
+ children: [
38349
+ "已输入 ",
38350
+ text.length,
38351
+ " 字"
38352
+ ]
38353
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
38354
+ type: "button",
38355
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
38356
+ onClick: () => {
38357
+ analyze();
38358
+ },
38359
+ disabled: busy,
38360
+ children: [
38361
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wand2, {
38362
+ size: 14,
38363
+ style: { verticalAlign: -2 }
38364
+ }),
38365
+ " ",
38366
+ busy && busyLabel === "分析中…" ? "分析中…" : "开始分析"
38367
+ ]
38368
+ })]
38369
+ })
38370
+ ]
38371
+ }),
38372
+ error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38373
+ className: panel_module_css_default.noticeError,
38374
+ children: error
38375
+ }),
38376
+ result === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38377
+ className: panel_module_css_default.shelfEmpty,
38378
+ style: { minHeight: 160 },
38379
+ children: [
38380
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38381
+ className: panel_module_css_default.shelfEmptyIcon,
38382
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.FileText, { size: 30 })
38383
+ }),
38384
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38385
+ className: panel_module_css_default.shelfEmptyTitle,
38386
+ children: "等待分析"
38387
+ }),
38388
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38389
+ className: panel_module_css_default.meta,
38390
+ children: "分析会读取全文并提炼「原文设定卡片」与「可改范围矩阵」。"
38391
+ })
38392
+ ]
38393
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38394
+ className: panel_module_css_default.adaptResult,
38395
+ children: [
38396
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38397
+ className: panel_module_css_default.authorPageHeader,
38398
+ style: { alignItems: "center" },
38399
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h3", {
38400
+ style: { margin: 0 },
38401
+ children: [
38402
+ "《",
38403
+ result.bookName,
38404
+ "》 · ",
38405
+ result.chapters,
38406
+ " 章"
38407
+ ]
38408
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38409
+ className: panel_module_css_default.meta,
38410
+ children: result.note
38411
+ })]
38412
+ }),
38413
+ result.outline !== void 0 && result.outline !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
38414
+ className: panel_module_css_default.adaptOutline,
38415
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "反推大纲(点击展开)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
38416
+ className: panel_module_css_default.adaptOutlinePre,
38417
+ children: result.outline
38418
+ })]
38419
+ }),
38420
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38421
+ className: panel_module_css_default.authorPageHeader,
38422
+ style: { alignItems: "center" },
38423
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "可改范围矩阵(勾选要改 + 填新值)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
38424
+ type: "button",
38425
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
38426
+ onClick: () => {
38427
+ propose();
38428
+ },
38429
+ disabled: busy,
38430
+ children: [
38431
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ListChecks, {
38432
+ size: 13,
38433
+ style: { verticalAlign: -2 }
38434
+ }),
38435
+ " ",
38436
+ busy && busyLabel === "生成改编方案…" ? "生成中…" : "生成改编方案",
38437
+ " (",
38438
+ selectedDims.length,
38439
+ ")"
38440
+ ]
38441
+ })]
38442
+ }),
38443
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38444
+ className: panel_module_css_default.adaptMatrix,
38445
+ children: result.dimensions.map((d, i) => {
38446
+ const e = edits[d.key];
38447
+ const enabled = e?.enabled === true;
38448
+ const target = e?.target ?? "";
38449
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38450
+ className: panel_module_css_default.dimCard + (enabled ? " " + panel_module_css_default.dimCardSelected : ""),
38451
+ children: [
38452
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38453
+ className: panel_module_css_default.dimCardHead,
38454
+ children: [
38455
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38456
+ className: panel_module_css_default.dimTitle,
38457
+ children: d.title
38458
+ }),
38459
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38460
+ className: panel_module_css_default.badge,
38461
+ style: { color: MUTABILITY_CLS[d.mutability] ?? "var(--nf-muted)" },
38462
+ children: MUTABILITY_LABEL[d.mutability] ?? d.mutability
38463
+ }),
38464
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
38465
+ className: panel_module_css_default.meta,
38466
+ children: ["风险:", RISK_LABEL[d.risk] ?? d.risk]
38467
+ })
38468
+ ]
38469
+ }),
38470
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38471
+ className: panel_module_css_default.dimCurrent,
38472
+ children: [
38473
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "当前值" }),
38474
+ ":",
38475
+ d.current
38476
+ ]
38477
+ }),
38478
+ d.mutability !== "locked" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38479
+ className: panel_module_css_default.dimEdit,
38480
+ children: [
38481
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
38482
+ type: "checkbox",
38483
+ checked: enabled,
38484
+ onChange: (e2) => setEdit(d.key, { enabled: e2.target.checked })
38485
+ }),
38486
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
38487
+ className: panel_module_css_default.input,
38488
+ value: target,
38489
+ disabled: !enabled,
38490
+ placeholder: "改为什么?",
38491
+ onChange: (e2) => setEdit(d.key, { target: e2.target.value })
38492
+ }),
38493
+ (d.candidates ?? []).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
38494
+ className: panel_module_css_default.meta,
38495
+ children: ["候选:", (d.candidates ?? []).join(" / ")]
38496
+ })
38497
+ ]
38498
+ }),
38499
+ d.evidence !== void 0 && d.evidence !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38500
+ className: panel_module_css_default.meta,
38501
+ children: ["证据:", d.evidence]
38502
+ }),
38503
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38504
+ className: panel_module_css_default.meta,
38505
+ children: ["影响:", d.impact]
38506
+ })
38507
+ ]
38508
+ }, d.key + "-" + i);
38509
+ })
38510
+ }),
38511
+ proposal !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38512
+ className: panel_module_css_default.adaptProposal,
38513
+ children: [
38514
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38515
+ className: panel_module_css_default.authorPageHeader,
38516
+ style: { alignItems: "center" },
38517
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "改编方案" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
38518
+ type: "button",
38519
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
38520
+ onClick: () => {
38521
+ execute();
38522
+ },
38523
+ disabled: busy,
38524
+ children: [
38525
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Play, {
38526
+ size: 13,
38527
+ style: { verticalAlign: -2 }
38528
+ }),
38529
+ " ",
38530
+ busy && busyLabel === "执行术语替换…" ? "执行中…" : "执行改编(术语替换)"
38531
+ ]
38532
+ })]
38533
+ }),
38534
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
38535
+ style: { margin: "10px 0 4px" },
38536
+ children: "映射表"
38537
+ }),
38538
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
38539
+ className: panel_module_css_default.adaptTable,
38540
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
38541
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: "原值" }),
38542
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: "新值" }),
38543
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: "范围" })
38544
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: proposal.mappings.map((m, i2) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
38545
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: m.source }),
38546
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: m.target }),
38547
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: m.scope })
38548
+ ] }, i2)) })]
38549
+ }),
38550
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
38551
+ style: { margin: "10px 0 4px" },
38552
+ children: "改编规则"
38553
+ }),
38554
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38555
+ className: panel_module_css_default.meta,
38556
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "保留:" }), proposal.rules.preserve.join(";") || "—"]
38557
+ }),
38558
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38559
+ className: panel_module_css_default.meta,
38560
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "允许变:" }), proposal.rules.change.join(";") || "—"]
38561
+ }),
38562
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38563
+ className: panel_module_css_default.meta,
38564
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "红线:" }), proposal.rules.constraints.join(";") || "—"]
38565
+ }),
38566
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
38567
+ style: { margin: "10px 0 4px" },
38568
+ children: "联动影响"
38569
+ }),
38570
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38571
+ className: panel_module_css_default.adaptImpacts,
38572
+ children: proposal.impacts.map((im, i3) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38573
+ className: panel_module_css_default.adaptImpact,
38574
+ children: [
38575
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", {
38576
+ style: { color: im.risk === "high" ? "var(--nf-error)" : im.risk === "medium" ? "var(--nf-warn)" : "var(--nf-info)" },
38577
+ children: [
38578
+ "[",
38579
+ RISK_LABEL[im.risk] ?? im.risk,
38580
+ "]"
38581
+ ]
38582
+ }),
38583
+ " ",
38584
+ im.item,
38585
+ ":",
38586
+ im.detail,
38587
+ im.chapters !== void 0 && im.chapters.length > 0 ? `(章:${im.chapters.join(",")})` : ""
38588
+ ]
38589
+ }, i3))
38590
+ })
38591
+ ]
38592
+ }),
38593
+ executed !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38594
+ className: panel_module_css_default.adaptProposal,
38595
+ children: [
38596
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38597
+ className: panel_module_css_default.authorPageHeader,
38598
+ style: { alignItems: "center" },
38599
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "改编结果(术语替换)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
38600
+ type: "button",
38601
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
38602
+ onClick: downloadAdapted,
38603
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Download, {
38604
+ size: 13,
38605
+ style: { verticalAlign: -2 }
38606
+ }), " 下载改编版"]
38607
+ })]
38608
+ }),
38609
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38610
+ className: panel_module_css_default.meta,
38611
+ children: ["命中:", executed.hits.filter((h) => h.count > 0).map((h) => h.source + "→" + h.target + "×" + h.count).join(",") || "无命中"]
38612
+ }),
38613
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
38614
+ className: panel_module_css_default.adaptOutline,
38615
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "改编正文预览(点击展开)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
38616
+ className: panel_module_css_default.adaptOutlinePre,
38617
+ children: executed.adaptedText.slice(0, 8e3)
38618
+ })]
38619
+ })
38620
+ ]
38621
+ })
38622
+ ]
38623
+ })
38624
+ ]
38625
+ });
38626
+ }
38627
+ //#endregion
38628
+ //#region src/client/panel/AuthorAssetsView.tsx
38629
+ /**
38630
+ * 作者资产库/总数据页:跨书可复用的笔法/红线/套路/角色模板/世界观模板。
38631
+ * 支持 新增 / 编辑 / 删除;数据持久化到 ~/.dsh/dsh-novel-forge-author-assets.json。
38632
+ */
38633
+ const KIND_LABELS = {
38634
+ style: "笔法",
38635
+ antiAi: "红线/反AI",
38636
+ progression: "推进模式",
38637
+ genre: "题材",
38638
+ roleTemplate: "角色模板",
38639
+ worldTemplate: "世界观模板",
38640
+ custom: "自定义"
38641
+ };
38642
+ const KIND_OPTIONS = Object.keys(KIND_LABELS);
38643
+ const KIND_COLORS = {
38644
+ style: "var(--nf-info)",
38645
+ antiAi: "var(--nf-warn)",
38646
+ progression: "var(--nf-accent)",
38647
+ genre: "var(--nf-info)",
38648
+ roleTemplate: "var(--nf-accent)",
38649
+ worldTemplate: "var(--nf-warn)",
38650
+ custom: "var(--nf-muted)"
38651
+ };
38652
+ /** 计算资产的分组(分类):题材按顶层题材名('/' 之前),其余按类型。 */
38653
+ function assetCategory(a) {
38654
+ if (a.kind === "genre") {
38655
+ const top = a.name.split("/")[0]?.trim();
38656
+ return top !== void 0 && top !== "" ? top : "题材";
38657
+ }
38658
+ return KIND_LABELS[a.kind] ?? "其他";
38659
+ }
38660
+ function emptyEditor() {
38661
+ return {
38662
+ name: "",
38663
+ kind: "style",
38664
+ summary: "",
38665
+ content: "",
38666
+ tags: "",
38667
+ sourceBooks: ""
38668
+ };
38669
+ }
38670
+ function AuthorAssetsView({ api }) {
38671
+ const [assets, setAssets] = (0, react.useState)([]);
38672
+ const [editing, setEditing] = (0, react.useState)(null);
38673
+ const [error, setError] = (0, react.useState)("");
38674
+ const [busy, setBusy] = (0, react.useState)(false);
38675
+ const [kindFilter, setKindFilter] = (0, react.useState)("all");
38676
+ const load = async () => {
38677
+ try {
38678
+ const res = await api.authorAssets();
38679
+ setAssets(res.assets.items);
38680
+ } catch (err) {
38681
+ setError(err.message);
38682
+ }
38683
+ };
38684
+ /** 导入默认:把书架书的写作资产/角色 + 内置全局库批量沉淀到作者资产库。 */
38685
+ const importDefaults = async () => {
38686
+ setBusy(true);
38687
+ setError("");
38688
+ try {
38689
+ const res = await api.authorAssetsImportDefault();
38690
+ setAssets(res.assets.items);
38691
+ } catch (err) {
38692
+ setError(err.message);
38693
+ } finally {
38694
+ setBusy(false);
38695
+ }
38696
+ };
38697
+ (0, react.useEffect)(() => {
38698
+ let cancelled = false;
38699
+ (async () => {
38700
+ try {
38701
+ const res = await api.authorAssets();
38702
+ if (cancelled) return;
38703
+ if (res.assets.items.length === 0) {
38704
+ const imp = await api.authorAssetsImportDefault();
38705
+ if (!cancelled) setAssets(imp.assets.items);
38706
+ } else setAssets(res.assets.items);
38707
+ } catch (err) {
38708
+ if (!cancelled) setError(err.message);
38709
+ }
38710
+ })();
38711
+ return () => {
38712
+ cancelled = true;
38713
+ };
38714
+ }, [api]);
38715
+ const startNew = () => {
38716
+ setEditing(emptyEditor());
38717
+ setError("");
38718
+ };
38719
+ const startEdit = (a) => {
38720
+ setEditing({
38721
+ id: a.id,
38722
+ name: a.name,
38723
+ kind: a.kind,
38724
+ summary: a.summary,
38725
+ content: a.content,
38726
+ tags: a.tags.join("、"),
38727
+ sourceBooks: a.sourceBooks.join("、")
38728
+ });
38729
+ setError("");
38730
+ };
38731
+ const save = async () => {
38732
+ if (editing === null) return;
38733
+ if (editing.name.trim() === "") {
38734
+ setError("请填写资产名");
38735
+ return;
38736
+ }
38737
+ setBusy(true);
38738
+ setError("");
38739
+ try {
38740
+ const asset = {
38741
+ id: editing.id ?? "",
38742
+ name: editing.name.trim(),
38743
+ kind: editing.kind,
38744
+ summary: editing.summary.trim(),
38745
+ content: editing.content.trim(),
38746
+ sourceBooks: editing.sourceBooks.split(/[、,,\s]+/).map((s) => s.trim()).filter(Boolean),
38747
+ tags: editing.tags.split(/[、,,\s]+/).map((s) => s.trim()).filter(Boolean),
38748
+ createdAt: "",
38749
+ updatedAt: ""
38750
+ };
38751
+ await api.authorAssetsUpsert(asset);
38752
+ setEditing(null);
38753
+ await load();
38754
+ } catch (err) {
38755
+ setError(err.message);
38756
+ } finally {
38757
+ setBusy(false);
38758
+ }
38759
+ };
38760
+ const del = async (id) => {
38761
+ setBusy(true);
38762
+ setError("");
38763
+ try {
38764
+ await api.authorAssetsRemove(id);
38765
+ await load();
38766
+ } catch (err) {
38767
+ setError(err.message);
38768
+ } finally {
38769
+ setBusy(false);
38770
+ }
38771
+ };
38772
+ const visible = (0, react.useMemo)(() => kindFilter === "all" ? assets : assets.filter((a) => a.kind === kindFilter), [assets, kindFilter]);
38773
+ /** 按分类分组展示(题材按顶层题材名,其余按类型)。 */
38774
+ const grouped = (0, react.useMemo)(() => {
38775
+ const map = /* @__PURE__ */ new Map();
38776
+ for (const a of visible) {
38777
+ const cat = assetCategory(a);
38778
+ const arr = map.get(cat) ?? [];
38779
+ arr.push(a);
38780
+ map.set(cat, arr);
38781
+ }
38782
+ return Array.from(map.entries()).sort((x, y) => x[0].localeCompare(y[0], "zh"));
38783
+ }, [visible]);
38784
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38785
+ className: panel_module_css_default.authorPageBody,
38786
+ children: [
38787
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38788
+ className: panel_module_css_default.authorPageHero,
38789
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38790
+ className: panel_module_css_default.authorPageHeader,
38791
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
38792
+ className: panel_module_css_default.panelTitle,
38793
+ style: { margin: 0 },
38794
+ children: "🧬 作者资产库 · 总数据"
38795
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38796
+ className: panel_module_css_default.meta,
38797
+ children: "跨书可复用的笔法/红线/套路/角色模板/世界观模板。任意新书与改编都能调用。"
38798
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38799
+ className: panel_module_css_default.rowEnd,
38800
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
38801
+ type: "button",
38802
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
38803
+ onClick: () => {
38804
+ importDefaults();
38805
+ },
38806
+ disabled: busy,
38807
+ title: "把书架里所有书的写作资产/角色 + 内置题材/反AI/风格模板/推进模式批量导入",
38808
+ children: "导入默认资产"
38809
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
38810
+ type: "button",
38811
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
38812
+ onClick: startNew,
38813
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, {
38814
+ size: 14,
38815
+ style: { verticalAlign: -2 }
38816
+ }), " 新增资产"]
38817
+ })]
38818
+ })]
38819
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38820
+ className: panel_module_css_default.assetFilterBar,
38821
+ children: KIND_OPTIONS.map((k) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
38822
+ type: "button",
38823
+ className: panel_module_css_default.assetFilterChip + (kindFilter === k ? " " + panel_module_css_default.assetFilterChipActive : ""),
38824
+ onClick: () => setKindFilter(kindFilter === k ? "all" : k),
38825
+ children: [
38826
+ KIND_LABELS[k],
38827
+ " ",
38828
+ assets.filter((a) => a.kind === k).length
38829
+ ]
38830
+ }, k))
38831
+ })]
38832
+ }),
38833
+ error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38834
+ className: panel_module_css_default.noticeError,
38835
+ children: error
38836
+ }),
38837
+ editing !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38838
+ className: panel_module_css_default.assetEditor,
38839
+ children: [
38840
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
38841
+ style: { margin: 0 },
38842
+ children: editing.id !== "" && editing.id !== void 0 ? "编辑资产" : "新增资产"
38843
+ }),
38844
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38845
+ className: panel_module_css_default.assetEditorRow,
38846
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
38847
+ className: panel_module_css_default.assetLabel,
38848
+ children: ["资产名 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
38849
+ className: panel_module_css_default.input,
38850
+ value: editing.name,
38851
+ onChange: (e) => setEditing({
38852
+ ...editing,
38853
+ name: e.target.value
38854
+ }),
38855
+ placeholder: "如:短句快节奏爽文风"
38856
+ })]
38857
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
38858
+ className: panel_module_css_default.assetLabel,
38859
+ children: ["类型 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
38860
+ className: panel_module_css_default.input,
38861
+ value: editing.kind,
38862
+ onChange: (e) => setEditing({
38863
+ ...editing,
38864
+ kind: e.target.value
38865
+ }),
38866
+ children: KIND_OPTIONS.map((k) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
38867
+ value: k,
38868
+ children: KIND_LABELS[k]
38869
+ }, k))
38870
+ })]
38871
+ })]
38872
+ }),
38873
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
38874
+ className: panel_module_css_default.assetLabel,
38875
+ children: ["一句话摘要 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
38876
+ className: panel_module_css_default.input,
38877
+ value: editing.summary,
38878
+ onChange: (e) => setEditing({
38879
+ ...editing,
38880
+ summary: e.target.value
38881
+ }),
38882
+ placeholder: "这个资产解决什么问题 / 有什么特点"
38883
+ })]
38884
+ }),
38885
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
38886
+ className: panel_module_css_default.assetLabel,
38887
+ children: ["内容(按类型约定的描述 / 规则 / 结构化文本)", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
38888
+ className: `${panel_module_css_default.input} ${panel_module_css_default.assetTextarea}`,
38889
+ value: editing.content,
38890
+ onChange: (e) => setEditing({
38891
+ ...editing,
38892
+ content: e.target.value
38893
+ }),
38894
+ placeholder: "角色模板示例:\n姓名:林越\n定位:痞坏型主角\n口头禅:\"有点意思\"\n性格:表面懒散、内里狠辣\n成长弧线:从底层游街到一方枭雄"
38895
+ })]
38896
+ }),
38897
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38898
+ className: panel_module_css_default.assetEditorRow,
38899
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
38900
+ className: panel_module_css_default.assetLabel,
38901
+ children: ["标签(顿号分隔) ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
38902
+ className: panel_module_css_default.input,
38903
+ value: editing.tags,
38904
+ onChange: (e) => setEditing({
38905
+ ...editing,
38906
+ tags: e.target.value
38907
+ }),
38908
+ placeholder: "扮猪吃虎、快节奏、冷面"
38909
+ })]
38910
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
38911
+ className: panel_module_css_default.assetLabel,
38912
+ children: ["来源书(顿号分隔) ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
38913
+ className: panel_module_css_default.input,
38914
+ value: editing.sourceBooks,
38915
+ onChange: (e) => setEditing({
38916
+ ...editing,
38917
+ sourceBooks: e.target.value
38918
+ }),
38919
+ placeholder: "《某某传》《某某录》"
38920
+ })]
38921
+ })]
38922
+ }),
38923
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38924
+ className: panel_module_css_default.rowEnd,
38925
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
38926
+ type: "button",
38927
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
38928
+ onClick: save,
38929
+ disabled: busy,
38930
+ children: busy ? "保存中…" : "保存"
38931
+ }), editing.id !== "" && editing.id !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
38932
+ type: "button",
38933
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
38934
+ onClick: () => setEditing(null),
38935
+ children: "取消"
38936
+ })]
38937
+ })
38938
+ ]
38939
+ }) : null,
38940
+ visible.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38941
+ className: panel_module_css_default.shelfEmpty,
38942
+ style: { minHeight: 160 },
38943
+ children: [
38944
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38945
+ className: panel_module_css_default.shelfEmptyIcon,
38946
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, { size: 30 })
38947
+ }),
38948
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38949
+ className: panel_module_css_default.shelfEmptyTitle,
38950
+ children: "还没有资产"
38951
+ }),
38952
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38953
+ className: panel_module_css_default.meta,
38954
+ children: "点「新增资产」收藏你的笔法/角色模板/套路,跨书调用。"
38955
+ })
38956
+ ]
38957
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38958
+ className: panel_module_css_default.assetGroups,
38959
+ children: grouped.map(([cat, items]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38960
+ className: panel_module_css_default.assetGroup,
38961
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38962
+ className: panel_module_css_default.assetGroupHeader,
38963
+ children: [
38964
+ cat,
38965
+ " ",
38966
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38967
+ className: panel_module_css_default.meta,
38968
+ children: items.length
38969
+ })
38970
+ ]
38971
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38972
+ className: panel_module_css_default.assetGrid,
38973
+ children: items.map((a) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38974
+ className: panel_module_css_default.assetCard,
38975
+ children: [
38976
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38977
+ className: panel_module_css_default.assetCardTop,
38978
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
38979
+ className: panel_module_css_default.assetKind,
38980
+ style: { color: KIND_COLORS[a.kind] },
38981
+ children: KIND_LABELS[a.kind]
38982
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38983
+ className: panel_module_css_default.rowEnd,
38984
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
38985
+ type: "button",
38986
+ className: panel_module_css_default.iconBtn,
38987
+ title: "编辑",
38988
+ onClick: () => startEdit(a),
38989
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Pencil, { size: 13 })
38990
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
38991
+ type: "button",
38992
+ className: panel_module_css_default.iconBtn,
38993
+ title: "删除",
38994
+ onClick: () => {
38995
+ del(a.id);
38996
+ },
38997
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Trash2, { size: 13 })
38998
+ })]
38999
+ })]
39000
+ }),
39001
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39002
+ className: panel_module_css_default.assetCardName,
39003
+ children: a.name
39004
+ }),
39005
+ a.summary !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39006
+ className: panel_module_css_default.meta,
39007
+ children: a.summary
39008
+ }),
39009
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39010
+ className: panel_module_css_default.assetCardContent,
39011
+ children: a.content
39012
+ }),
39013
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39014
+ className: panel_module_css_default.assetCardFooter,
39015
+ children: [a.tags.map((t) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39016
+ className: panel_module_css_default.badge,
39017
+ children: t
39018
+ }, t)), a.sourceBooks.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39019
+ className: panel_module_css_default.meta,
39020
+ children: ["来源:", a.sourceBooks.join(" / ")]
39021
+ })]
39022
+ })
39023
+ ]
39024
+ }, a.id))
39025
+ })]
39026
+ }, cat))
39027
+ })
39028
+ ]
39029
+ });
39030
+ }
39031
+ //#endregion
39032
+ //#region src/client/panel/ProgressConsole.tsx
39033
+ /**
39034
+ * 共享「AI 进度」实时控制台:当前任务大进度条 + 全量活动日志。
39035
+ * 书内与首页共用一个表现,内容来自同一份进度状态。
39036
+ */
39037
+ function ProgressConsole({ progress, busy, busyLabel, liveBar, onClear }) {
39038
+ const endRef = (0, react.useRef)(null);
39039
+ (0, react.useEffect)(() => {
39040
+ endRef.current?.scrollIntoView({
39041
+ behavior: "smooth",
39042
+ block: "nearest"
39043
+ });
39044
+ }, [progress]);
39045
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39046
+ style: {
39047
+ display: "flex",
39048
+ flexDirection: "column",
39049
+ gap: "var(--nf-space-10)",
39050
+ height: "100%",
39051
+ minHeight: 0
39052
+ },
39053
+ children: [
39054
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39055
+ style: {
39056
+ display: "flex",
39057
+ alignItems: "center",
39058
+ justifyContent: "space-between"
39059
+ },
39060
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39061
+ style: { fontWeight: 600 },
39062
+ children: "📊 AI 进度"
39063
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
39064
+ type: "button",
39065
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
39066
+ onClick: onClear,
39067
+ title: "清空活动记录",
39068
+ children: "清空"
39069
+ })]
39070
+ }),
39071
+ busy && (busyLabel !== "" || liveBar !== null) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39072
+ style: {
39073
+ border: "1px solid var(--nf-accent)",
39074
+ borderRadius: "var(--nf-radius-10)",
39075
+ padding: "var(--nf-space-8) var(--nf-space-12)",
39076
+ display: "flex",
39077
+ flexDirection: "column",
39078
+ gap: "var(--nf-space-6)",
39079
+ background: "color-mix(in srgb, var(--nf-accent) 6%, transparent)"
39080
+ },
39081
+ children: [
39082
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39083
+ style: {
39084
+ fontSize: "var(--nf-fs-12)",
39085
+ fontWeight: 600,
39086
+ color: "var(--nf-accent)"
39087
+ },
39088
+ children: [
39089
+ "✍ ",
39090
+ busyLabel !== "" ? busyLabel : liveBar?.text ?? "任务进行中",
39091
+ "…"
39092
+ ]
39093
+ }),
39094
+ liveBar?.ratio !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39095
+ className: panel_module_css_default.bigProgressBar,
39096
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39097
+ className: panel_module_css_default.bigProgressBarFill,
39098
+ style: { width: Math.round(liveBar.ratio * 100) + "%" }
39099
+ })
39100
+ }),
39101
+ liveBar?.text !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39102
+ className: panel_module_css_default.liveText,
39103
+ children: liveBar.text
39104
+ })
39105
+ ]
39106
+ }),
39107
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39108
+ className: panel_module_css_default.progress,
39109
+ style: {
39110
+ flex: 1,
39111
+ minHeight: 0,
39112
+ overflowY: "auto",
39113
+ border: "1px solid var(--nf-border)",
39114
+ borderRadius: "var(--nf-radius-10)",
39115
+ background: "var(--nf-bg-inset)",
39116
+ padding: "var(--nf-space-8)",
39117
+ display: "flex",
39118
+ flexDirection: "column"
39119
+ },
39120
+ children: [progress.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39121
+ style: {
39122
+ flex: 1,
39123
+ display: "flex",
39124
+ flexDirection: "column",
39125
+ alignItems: "center",
39126
+ justifyContent: "center",
39127
+ gap: "var(--nf-space-4)",
39128
+ color: "var(--nf-text-3)",
39129
+ fontSize: "var(--nf-fs-12)",
39130
+ minHeight: 120
39131
+ },
39132
+ children: [
39133
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39134
+ style: { fontSize: "var(--nf-fs-22)" },
39135
+ children: "📭"
39136
+ }),
39137
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "暂无活动记录" }),
39138
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "生成、审稿等操作会显示在这里" })
39139
+ ]
39140
+ }) : progress.map((line) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39141
+ className: line.kind === "done" ? panel_module_css_default.progressLineDone : line.kind === "error" ? panel_module_css_default.progressLineError : line.live === true ? panel_module_css_default.progressLineLive : panel_module_css_default.progressLine,
39142
+ children: [line.live === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39143
+ className: panel_module_css_default.progressBar,
39144
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39145
+ className: panel_module_css_default.progressBarFill,
39146
+ style: { width: Math.round((line.ratio ?? 0) * 100) + "%" }
39147
+ })
39148
+ }), line.text]
39149
+ }, line.id)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref: endRef })]
39150
+ })
39151
+ ]
39152
+ });
39153
+ }
39154
+ //#endregion
39155
+ //#region src/client/panel/SettingsView.tsx
39156
+ /**
39157
+ * 共享设置页(作者首页「设置」与书内「设置」同入口)。
39158
+ * 自给自足:挂载时通过 api.status() 拉取全局配置,支持 model/writing/image/files/appearance 五组,
39159
+ * 保存走 api.patchConfig。不与某个书绑定,因此新装用户无书也能用。
39160
+ */
39161
+ const SETTINGS_SECTIONS$1 = [
39162
+ {
39163
+ id: "model",
39164
+ label: "模型与推理",
39165
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Brain, { size: 16 })
39166
+ },
39167
+ {
39168
+ id: "writing",
39169
+ label: "写作与审稿",
39170
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.PenLine, { size: 16 })
39171
+ },
39172
+ {
39173
+ id: "image",
39174
+ label: "生图模型",
39175
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Palette, { size: 16 })
39176
+ },
39177
+ {
39178
+ id: "files",
39179
+ label: "路径与文件",
39180
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Folder, { size: 16 })
39181
+ },
39182
+ {
39183
+ id: "appearance",
39184
+ label: "外观与主题",
39185
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Sparkles, { size: 16 })
39186
+ }
39187
+ ];
39188
+ function readLS(key, fallback, allowed) {
39189
+ try {
39190
+ const v = window.localStorage.getItem(key);
39191
+ return v !== null && allowed.includes(v) ? v : fallback;
39192
+ } catch {
39193
+ return fallback;
39194
+ }
39195
+ }
39196
+ function SettingsView({ api, onTheme, onSettingsTab, onEditorFontSize, onBackground, onOpacity }) {
39197
+ const [config, setConfig] = (0, react.useState)(null);
39198
+ const [configDraft, setConfigDraft] = (0, react.useState)(null);
39199
+ const [busy, setBusy] = (0, react.useState)(false);
39200
+ const [error, setError] = (0, react.useState)("");
39201
+ const [notice, setNotice] = (0, react.useState)("");
39202
+ const [settingsTab, setSettingsTabState] = (0, react.useState)(() => readLS("dsh-novel-forge.settings.tab", "model", [
39203
+ "model",
39204
+ "writing",
39205
+ "image",
39206
+ "files",
39207
+ "appearance"
39208
+ ]));
39209
+ const [imageTestState, setImageTestState] = (0, react.useState)({});
39210
+ const [editorFontSize, setEditorFontSize] = (0, react.useState)(() => {
39211
+ try {
39212
+ const v = Number(window.localStorage.getItem("dsh-novel-forge.editor.fontSize"));
39213
+ return v >= 12 && v <= 24 ? v : 14;
39214
+ } catch {
39215
+ return 14;
39216
+ }
39217
+ });
39218
+ const [panelTheme, setPanelTheme] = (0, react.useState)(() => readLS("dsh-novel-forge.theme", "liquid", [
39219
+ "liquid",
39220
+ "neumorph",
39221
+ "macos",
39222
+ "clay"
39223
+ ]));
39224
+ const [themeMode, setThemeMode] = (0, react.useState)(() => readLS("dsh-novel-forge.theme.mode", "system", [
39225
+ "system",
39226
+ "light",
39227
+ "dark"
39228
+ ]));
39229
+ const [themeDensity, setThemeDensity] = (0, react.useState)(() => readLS("dsh-novel-forge.theme.density", "comfort", [
39230
+ "comfort",
39231
+ "compact",
39232
+ "spacious"
39233
+ ]));
39234
+ const loadConfig = async () => {
39235
+ try {
39236
+ const res = await api.status();
39237
+ setConfig(res.config);
39238
+ setConfigDraft(res.config);
39239
+ } catch (err) {
39240
+ setError(err.message);
39241
+ }
39242
+ };
39243
+ (0, react.useEffect)(() => {
39244
+ loadConfig();
39245
+ }, []);
39246
+ (0, react.useEffect)(() => {
39247
+ try {
39248
+ window.localStorage.setItem("dsh-novel-forge.settings.tab", settingsTab);
39249
+ } catch {}
39250
+ }, [settingsTab]);
39251
+ const changeSettingsTab = (next) => {
39252
+ setSettingsTabState(next);
39253
+ onSettingsTab?.(next);
39254
+ };
39255
+ const save = async () => {
39256
+ if (configDraft === null) return;
39257
+ setBusy(true);
39258
+ setError("");
39259
+ setNotice("");
39260
+ try {
39261
+ const result = await api.patchConfig({
39262
+ outlinePath: configDraft.outlinePath,
39263
+ outputDir: configDraft.outputDir,
39264
+ provider: configDraft.provider,
39265
+ model: configDraft.model,
39266
+ reasoningEffort: configDraft.reasoningEffort ?? "off",
39267
+ chapterChars: configDraft.chapterChars,
39268
+ maxTokens: configDraft.maxTokens,
39269
+ reviewPassScore: configDraft.reviewPassScore,
39270
+ autoReview: configDraft.autoReview,
39271
+ autoAuthorReview: configDraft.autoAuthorReview,
39272
+ autoReviewAfterRevise: configDraft.autoReviewAfterRevise,
39273
+ imageApiKey: configDraft.imageApiKey,
39274
+ imageApiModel: configDraft.imageApiModel,
39275
+ imageApiEnabled: configDraft.imageApiEnabled ?? false,
39276
+ themeBackground: configDraft.themeBackground ?? "",
39277
+ themeBackgroundBlur: configDraft.themeBackgroundBlur ?? 0,
39278
+ themeOpacity: configDraft.themeOpacity ?? 100,
39279
+ imageModels: configDraft.imageModels ?? [],
39280
+ savedModels: configDraft.savedModels ?? []
39281
+ });
39282
+ setConfig(result.config);
39283
+ setConfigDraft(result.config);
39284
+ setNotice(tt("settings.saved"));
39285
+ } catch (err) {
39286
+ setError(err.message);
39287
+ } finally {
39288
+ setBusy(false);
39289
+ }
39290
+ };
39291
+ const patchImageModel = (id, patch) => {
39292
+ setConfigDraft((prev) => prev === null ? prev : {
39293
+ ...prev,
39294
+ imageModels: (prev.imageModels ?? []).map((m) => m.id === id ? {
39295
+ ...m,
39296
+ ...patch
39297
+ } : m)
39298
+ });
39299
+ };
39300
+ const addImageModel = () => {
39301
+ setConfigDraft((prev) => prev === null ? prev : {
39302
+ ...prev,
39303
+ imageModels: [...prev.imageModels ?? [], {
39304
+ id: "img-" + Date.now().toString(36),
39305
+ name: "",
39306
+ baseURL: "",
39307
+ apiKey: "",
39308
+ model: "",
39309
+ enabled: (prev.imageModels ?? []).length === 0
39310
+ }]
39311
+ });
39312
+ };
39313
+ const removeImageModel = (id) => {
39314
+ setConfigDraft((prev) => prev === null ? prev : {
39315
+ ...prev,
39316
+ imageModels: (prev.imageModels ?? []).filter((m) => m.id !== id)
39317
+ });
39318
+ };
39319
+ const enableImageModel = (id) => {
39320
+ setConfigDraft((prev) => prev === null ? prev : {
39321
+ ...prev,
39322
+ imageModels: (prev.imageModels ?? []).map((m) => ({
39323
+ ...m,
39324
+ enabled: m.id === id
39325
+ }))
39326
+ });
39327
+ };
39328
+ const testImageModel = async (m) => {
39329
+ if (m.baseURL.trim() === "" || m.apiKey.trim() === "") {
39330
+ setImageTestState((prev) => ({
39331
+ ...prev,
39332
+ [m.id]: {
39333
+ testing: false,
39334
+ ok: false,
39335
+ message: "请先填写接口地址和 API Key"
39336
+ }
39337
+ }));
39338
+ return;
39339
+ }
39340
+ setImageTestState((prev) => ({
39341
+ ...prev,
39342
+ [m.id]: { testing: true }
39343
+ }));
39344
+ try {
39345
+ const r = await api.imageTest({
39346
+ baseURL: m.baseURL,
39347
+ apiKey: m.apiKey,
39348
+ model: m.model
39349
+ });
39350
+ setImageTestState((prev) => ({
39351
+ ...prev,
39352
+ [m.id]: {
39353
+ testing: false,
39354
+ ok: r.ok,
39355
+ ms: r.ms,
39356
+ message: r.message
39357
+ }
39358
+ }));
39359
+ } catch (err) {
39360
+ setImageTestState((prev) => ({
39361
+ ...prev,
39362
+ [m.id]: {
39363
+ testing: false,
39364
+ ok: false,
39365
+ message: err.message
39366
+ }
39367
+ }));
39368
+ }
39369
+ };
39370
+ const changeTheme = (theme, mode, density) => {
39371
+ setPanelTheme(theme);
39372
+ setThemeMode(mode);
39373
+ setThemeDensity(density);
39374
+ try {
39375
+ window.localStorage.setItem("dsh-novel-forge.theme", theme);
39376
+ window.localStorage.setItem("dsh-novel-forge.theme.mode", mode);
39377
+ window.localStorage.setItem("dsh-novel-forge.theme.density", density);
39378
+ } catch {}
39379
+ onTheme?.(theme, mode, density);
39380
+ };
39381
+ const changeEditorFont = (n) => {
39382
+ const v = Math.min(24, Math.max(12, n));
39383
+ setEditorFontSize(v);
39384
+ try {
39385
+ window.localStorage.setItem("dsh-novel-forge.editor.fontSize", String(v));
39386
+ } catch {}
39387
+ onEditorFontSize?.(v);
39388
+ };
39389
+ const bgFileRef = (0, react.useRef)(null);
39390
+ const applyBackground = (bg) => {
39391
+ setConfigDraft((prev) => prev === null ? prev : {
39392
+ ...prev,
39393
+ themeBackground: bg ?? ""
39394
+ });
39395
+ onBackground?.(bg ?? void 0, configDraft?.themeBackgroundBlur ?? 0);
39396
+ };
39397
+ const applyBlur = (blur) => {
39398
+ setConfigDraft((prev) => prev === null ? prev : {
39399
+ ...prev,
39400
+ themeBackgroundBlur: blur
39401
+ });
39402
+ onBackground?.(configDraft?.themeBackground ?? void 0, blur);
39403
+ };
39404
+ const applyOpacity = (n) => {
39405
+ setConfigDraft((prev) => prev === null ? prev : {
39406
+ ...prev,
39407
+ themeOpacity: n
39408
+ });
39409
+ onOpacity?.(n);
39410
+ };
39411
+ const onBgFile = async (file) => {
39412
+ if (file === void 0) return;
39413
+ const dataUrl = await new Promise((resolve, reject) => {
39414
+ const fr = new FileReader();
39415
+ fr.onload = () => resolve(fr.result);
39416
+ fr.onerror = () => reject(fr.error ?? /* @__PURE__ */ new Error("读取失败"));
39417
+ fr.readAsDataURL(file);
39418
+ });
39419
+ try {
39420
+ const res = await api.themeBackgroundUpload(dataUrl);
39421
+ applyBackground(res.url);
39422
+ } catch (err) {
39423
+ setError(err.message);
39424
+ }
39425
+ };
39426
+ const resetTheme = () => {
39427
+ try {
39428
+ window.localStorage.removeItem("dsh-novel-forge.theme");
39429
+ window.localStorage.removeItem("dsh-novel-forge.theme.mode");
39430
+ window.localStorage.removeItem("dsh-novel-forge.theme.density");
39431
+ } catch {}
39432
+ changeTheme("liquid", "system", "comfort");
39433
+ };
39434
+ if (configDraft === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39435
+ className: panel_module_css_default.authorPageBody,
39436
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39437
+ className: panel_module_css_default.meta,
39438
+ children: "正在加载设置…"
39439
+ }), error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39440
+ className: panel_module_css_default.noticeError,
39441
+ children: error
39442
+ })]
39443
+ });
39444
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39445
+ className: panel_module_css_default.authorPageBody,
39446
+ "data-nf-theme": panelTheme,
39447
+ "data-nf-mode": themeMode === "system" ? void 0 : themeMode,
39448
+ "data-nf-density": themeDensity,
39449
+ children: [
39450
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39451
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
39452
+ style: { gap: "var(--nf-space-6)" },
39453
+ children: [
39454
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
39455
+ className: panel_module_css_default.panelTitle,
39456
+ style: { margin: 0 },
39457
+ children: "⚙️ 设置"
39458
+ }),
39459
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39460
+ className: panel_module_css_default.meta,
39461
+ children: [
39462
+ "当前模型:",
39463
+ config?.provider,
39464
+ " / ",
39465
+ config?.model
39466
+ ]
39467
+ }),
39468
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39469
+ className: panel_module_css_default.meta,
39470
+ children: ["输出目录:", config?.outputDir]
39471
+ })
39472
+ ]
39473
+ }),
39474
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39475
+ className: panel_module_css_default.row,
39476
+ style: {
39477
+ gap: "var(--nf-space-8)",
39478
+ flexWrap: "wrap"
39479
+ },
39480
+ children: SETTINGS_SECTIONS$1.map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
39481
+ type: "button",
39482
+ className: panel_module_css_default.button + (settingsTab === s.id ? " " + panel_module_css_default.buttonPrimary : ""),
39483
+ style: {
39484
+ flex: 1,
39485
+ minWidth: 104,
39486
+ justifyContent: "center"
39487
+ },
39488
+ onClick: () => changeSettingsTab(s.id),
39489
+ children: [
39490
+ s.icon,
39491
+ " ",
39492
+ s.label
39493
+ ]
39494
+ }, s.id))
39495
+ }),
39496
+ error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39497
+ className: panel_module_css_default.noticeError,
39498
+ children: error
39499
+ }),
39500
+ notice !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39501
+ className: panel_module_css_default.meta,
39502
+ children: notice
39503
+ }),
39504
+ settingsTab === "model" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39505
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
39506
+ style: { gap: "var(--nf-space-24)" },
39507
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39508
+ className: panel_module_css_default.cardTitle,
39509
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Brain, {
39510
+ size: 18,
39511
+ style: { verticalAlign: -3 }
39512
+ }), " 模型与推理"]
39513
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelManager, {
39514
+ api,
39515
+ provider: configDraft.provider,
39516
+ model: configDraft.model,
39517
+ savedModels: configDraft.savedModels ?? [],
39518
+ onProvider: (v) => setConfigDraft({
39519
+ ...configDraft,
39520
+ provider: v
39521
+ }),
39522
+ onModel: (v) => setConfigDraft({
39523
+ ...configDraft,
39524
+ model: v
39525
+ }),
39526
+ onSavedModels: (models) => setConfigDraft({
39527
+ ...configDraft,
39528
+ savedModels: models
39529
+ })
39530
+ })]
39531
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningSection, {
39532
+ reasoningEffort: configDraft.reasoningEffort ?? "off",
39533
+ analysisReasoning: configDraft.analysisReasoning ?? "low",
39534
+ onChange: (patch) => setConfigDraft({
39535
+ ...configDraft,
39536
+ ...patch
39537
+ })
39538
+ })] }),
39539
+ settingsTab === "writing" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39540
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
39541
+ style: { gap: "var(--nf-space-24)" },
39542
+ children: [
39543
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39544
+ className: panel_module_css_default.cardTitle,
39545
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.PenLine, {
39546
+ size: 18,
39547
+ style: { verticalAlign: -3 }
39548
+ }), " 写作与审稿"]
39549
+ }),
39550
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39551
+ className: panel_module_css_default.field,
39552
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39553
+ className: panel_module_css_default.fieldLabel,
39554
+ children: tt("settings.chapterChars")
39555
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39556
+ className: panel_module_css_default.input,
39557
+ type: "number",
39558
+ min: 1e3,
39559
+ max: 2e4,
39560
+ value: configDraft.chapterChars,
39561
+ onChange: (e) => setConfigDraft({
39562
+ ...configDraft,
39563
+ chapterChars: Number(e.target.value)
39564
+ })
39565
+ })]
39566
+ }),
39567
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39568
+ className: panel_module_css_default.field,
39569
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39570
+ className: panel_module_css_default.fieldLabel,
39571
+ children: tt("settings.maxTokens")
39572
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39573
+ className: panel_module_css_default.input,
39574
+ type: "number",
39575
+ min: 2e3,
39576
+ max: 64e3,
39577
+ value: configDraft.maxTokens,
39578
+ onChange: (e) => setConfigDraft({
39579
+ ...configDraft,
39580
+ maxTokens: Number(e.target.value)
39581
+ })
39582
+ })]
39583
+ }),
39584
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39585
+ className: panel_module_css_default.field,
39586
+ children: [
39587
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39588
+ className: panel_module_css_default.fieldLabel,
39589
+ children: tt("settings.reviewPassScore")
39590
+ }),
39591
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39592
+ className: panel_module_css_default.input,
39593
+ type: "number",
39594
+ min: 0,
39595
+ max: 100,
39596
+ value: configDraft.reviewPassScore,
39597
+ onChange: (e) => setConfigDraft({
39598
+ ...configDraft,
39599
+ reviewPassScore: Number(e.target.value)
39600
+ })
39601
+ }),
39602
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39603
+ className: panel_module_css_default.meta,
39604
+ children: "通过判定:综合评分 ≥ 此分数(默认 70),或无 high 级问题且评分 ≥ 60;建议设 60-80。"
39605
+ })
39606
+ ]
39607
+ }),
39608
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39609
+ className: panel_module_css_default.field,
39610
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39611
+ className: panel_module_css_default.fieldLabel,
39612
+ children: tt("settings.autoReview")
39613
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
39614
+ className: panel_module_css_default.input,
39615
+ value: configDraft.autoReview ? "1" : "0",
39616
+ onChange: (e) => setConfigDraft({
39617
+ ...configDraft,
39618
+ autoReview: e.target.value === "1"
39619
+ }),
39620
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39621
+ value: "1",
39622
+ children: "✓ 是"
39623
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39624
+ value: "0",
39625
+ children: "✗ 否"
39626
+ })]
39627
+ })]
39628
+ }),
39629
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39630
+ className: panel_module_css_default.field,
39631
+ children: [
39632
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39633
+ className: panel_module_css_default.fieldLabel,
39634
+ children: tt("settings.autoAuthorReview")
39635
+ }),
39636
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
39637
+ className: panel_module_css_default.input,
39638
+ value: configDraft.autoAuthorReview ? "1" : "0",
39639
+ onChange: (e) => setConfigDraft({
39640
+ ...configDraft,
39641
+ autoAuthorReview: e.target.value === "1"
39642
+ }),
39643
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39644
+ value: "1",
39645
+ children: "✓ 是"
39646
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39647
+ value: "0",
39648
+ children: "✗ 否"
39649
+ })]
39650
+ }),
39651
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39652
+ className: panel_module_css_default.meta,
39653
+ children: tt("settings.autoAuthorReviewHint")
39654
+ })
39655
+ ]
39656
+ }),
39657
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39658
+ className: panel_module_css_default.field,
39659
+ children: [
39660
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39661
+ className: panel_module_css_default.fieldLabel,
39662
+ children: tt("settings.autoReviewAfterRevise")
39663
+ }),
39664
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
39665
+ className: panel_module_css_default.input,
39666
+ value: configDraft.autoReviewAfterRevise ? "1" : "0",
39667
+ onChange: (e) => setConfigDraft({
39668
+ ...configDraft,
39669
+ autoReviewAfterRevise: e.target.value === "1"
39670
+ }),
39671
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39672
+ value: "1",
39673
+ children: "✓ 是"
39674
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39675
+ value: "0",
39676
+ children: "✗ 否"
39677
+ })]
39678
+ }),
39679
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39680
+ className: panel_module_css_default.meta,
39681
+ children: tt("settings.autoReviewAfterReviseHint")
39682
+ })
39683
+ ]
39684
+ }),
39685
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39686
+ className: panel_module_css_default.field,
39687
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39688
+ className: panel_module_css_default.fieldLabel,
39689
+ children: "编辑器字号(正文编辑 / 工作区)"
39690
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
39691
+ className: panel_module_css_default.input,
39692
+ value: editorFontSize,
39693
+ onChange: (e) => changeEditorFont(Number(e.target.value)),
39694
+ children: [
39695
+ 12,
39696
+ 13,
39697
+ 14,
39698
+ 15,
39699
+ 16,
39700
+ 18,
39701
+ 20,
39702
+ 22,
39703
+ 24
39704
+ ].map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
39705
+ value: v,
39706
+ children: [v, "px"]
39707
+ }, v))
39708
+ })]
39709
+ })
39710
+ ]
39711
+ }),
39712
+ settingsTab === "image" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39713
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
39714
+ style: { gap: "var(--nf-space-24)" },
39715
+ children: [
39716
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39717
+ className: panel_module_css_default.row,
39718
+ style: {
39719
+ justifyContent: "space-between",
39720
+ flexWrap: "wrap",
39721
+ alignItems: "center"
39722
+ },
39723
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39724
+ className: panel_module_css_default.cardTitle,
39725
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Palette, {
39726
+ size: 18,
39727
+ style: { verticalAlign: -3 }
39728
+ }), " 生图模型"]
39729
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39730
+ className: panel_module_css_default.row,
39731
+ style: {
39732
+ gap: "var(--nf-space-8)",
39733
+ alignItems: "center"
39734
+ },
39735
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39736
+ className: panel_module_css_default.meta,
39737
+ children: "启用生图功能"
39738
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
39739
+ type: "button",
39740
+ role: "switch",
39741
+ "aria-checked": configDraft.imageApiEnabled === true,
39742
+ className: `${panel_module_css_default.switch} ${configDraft.imageApiEnabled === true ? panel_module_css_default.switchOn : ""}`,
39743
+ onClick: () => {
39744
+ setConfigDraft((prev) => prev === null ? prev : {
39745
+ ...prev,
39746
+ imageApiEnabled: prev.imageApiEnabled !== true
39747
+ });
39748
+ },
39749
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: panel_module_css_default.switchKnob })
39750
+ })]
39751
+ })]
39752
+ }),
39753
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
39754
+ className: panel_module_css_default.meta,
39755
+ children: "支持多套 OpenAI 兼容生图接口(豆包 / 即梦 / 其他平台);启用一条作为生成模型。"
39756
+ }),
39757
+ (configDraft.imageModels ?? []).map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39758
+ style: {
39759
+ border: m.enabled ? "1px solid var(--nf-accent)" : "1px solid var(--nf-border)",
39760
+ borderRadius: "var(--nf-radius-12)",
39761
+ padding: "var(--nf-space-14)",
39762
+ display: "flex",
39763
+ flexDirection: "column",
39764
+ gap: "var(--nf-space-12)",
39765
+ background: m.enabled ? "var(--nf-accent-soft)" : "transparent"
39766
+ },
39767
+ children: [
39768
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39769
+ className: panel_module_css_default.row,
39770
+ style: {
39771
+ alignItems: "flex-end",
39772
+ flexWrap: "wrap"
39773
+ },
39774
+ children: [
39775
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39776
+ className: panel_module_css_default.field,
39777
+ style: {
39778
+ flex: 1,
39779
+ minWidth: 160
39780
+ },
39781
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39782
+ className: panel_module_css_default.fieldLabel,
39783
+ children: "名称"
39784
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39785
+ className: panel_module_css_default.input,
39786
+ value: m.name,
39787
+ onChange: (e) => patchImageModel(m.id, { name: e.target.value })
39788
+ })]
39789
+ }),
39790
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39791
+ className: panel_module_css_default.field,
39792
+ style: {
39793
+ flex: 1,
39794
+ minWidth: 150
39795
+ },
39796
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39797
+ className: panel_module_css_default.fieldLabel,
39798
+ children: "模型 id"
39799
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39800
+ className: panel_module_css_default.input,
39801
+ value: m.model,
39802
+ onChange: (e) => patchImageModel(m.id, { model: e.target.value })
39803
+ })]
39804
+ }),
39805
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39806
+ className: panel_module_css_default.field,
39807
+ style: {
39808
+ flex: 1,
39809
+ minWidth: 200
39810
+ },
39811
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39812
+ className: panel_module_css_default.fieldLabel,
39813
+ children: "接口地址"
39814
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39815
+ className: panel_module_css_default.input,
39816
+ value: m.baseURL,
39817
+ onChange: (e) => patchImageModel(m.id, { baseURL: e.target.value })
39818
+ })]
39819
+ })
39820
+ ]
39821
+ }),
39822
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39823
+ className: panel_module_css_default.field,
39824
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39825
+ className: panel_module_css_default.fieldLabel,
39826
+ children: "API Key"
39827
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39828
+ className: panel_module_css_default.input,
39829
+ type: "password",
39830
+ value: m.apiKey,
39831
+ onChange: (e) => patchImageModel(m.id, { apiKey: e.target.value })
39832
+ })]
39833
+ }),
39834
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39835
+ className: panel_module_css_default.row,
39836
+ style: {
39837
+ gap: "var(--nf-space-8)",
39838
+ flexWrap: "wrap",
39839
+ alignItems: "center"
39840
+ },
39841
+ children: [
39842
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
39843
+ type: "button",
39844
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall + (m.enabled ? " " + panel_module_css_default.buttonPrimary : ""),
39845
+ onClick: () => enableImageModel(m.id),
39846
+ children: m.enabled ? "✓ 已启用" : "设为启用"
39847
+ }),
39848
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
39849
+ type: "button",
39850
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
39851
+ disabled: imageTestState[m.id]?.testing === true,
39852
+ onClick: () => {
39853
+ testImageModel(m);
39854
+ },
39855
+ children: [
39856
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.PlugZap, {
39857
+ size: 13,
39858
+ style: { verticalAlign: -2 }
39859
+ }),
39860
+ " ",
39861
+ imageTestState[m.id]?.testing === true ? "测试中…" : "测试"
39862
+ ]
39863
+ }),
39864
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
39865
+ type: "button",
39866
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
39867
+ onClick: () => removeImageModel(m.id),
39868
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Trash2, {
39869
+ size: 13,
39870
+ style: { verticalAlign: -2 }
39871
+ }), " 删除"]
39872
+ })
39873
+ ]
39874
+ })
39875
+ ]
39876
+ }, m.id)),
39877
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39878
+ className: panel_module_css_default.row,
39879
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
39880
+ type: "button",
39881
+ className: panel_module_css_default.button,
39882
+ onClick: addImageModel,
39883
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, {
39884
+ size: 13,
39885
+ style: { verticalAlign: -2 }
39886
+ }), " 添加生图模型"]
39887
+ })
39888
+ })
39889
+ ]
39890
+ }),
39891
+ settingsTab === "files" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39892
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
39893
+ style: { gap: "var(--nf-space-24)" },
39894
+ children: [
39895
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39896
+ className: panel_module_css_default.cardTitle,
39897
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Folder, {
39898
+ size: 18,
39899
+ style: { verticalAlign: -3 }
39900
+ }), " 路径与文件"]
39901
+ }),
39902
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39903
+ className: panel_module_css_default.field,
39904
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39905
+ className: panel_module_css_default.fieldLabel,
39906
+ children: tt("settings.outlinePath")
39907
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39908
+ className: panel_module_css_default.input,
39909
+ value: configDraft.outlinePath,
39910
+ onChange: (e) => setConfigDraft({
39911
+ ...configDraft,
39912
+ outlinePath: e.target.value
39913
+ })
39914
+ })]
39915
+ }),
39916
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39917
+ className: panel_module_css_default.field,
39918
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39919
+ className: panel_module_css_default.fieldLabel,
39920
+ children: tt("settings.outputDir")
39921
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
39922
+ className: panel_module_css_default.input,
39923
+ value: configDraft.outputDir,
39924
+ onChange: (e) => setConfigDraft({
39925
+ ...configDraft,
39926
+ outputDir: e.target.value
39927
+ })
39928
+ })]
39929
+ }),
39930
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39931
+ className: panel_module_css_default.row,
39932
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
39933
+ type: "button",
39934
+ className: panel_module_css_default.button,
39935
+ onClick: () => {
39936
+ api.openFolder();
39937
+ },
39938
+ children: tt("settings.openFolder")
39939
+ })
39940
+ })
39941
+ ]
39942
+ }),
39943
+ settingsTab === "appearance" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39944
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
39945
+ children: [
39946
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
39947
+ className: panel_module_css_default.cardTitle,
39948
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Sparkles, {
39949
+ size: 18,
39950
+ style: { verticalAlign: -3 }
39951
+ }), " 外观与主题"]
39952
+ }),
39953
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39954
+ className: panel_module_css_default.field,
39955
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39956
+ className: panel_module_css_default.fieldLabel,
39957
+ children: "显示模式"
39958
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
39959
+ className: panel_module_css_default.input,
39960
+ value: themeMode,
39961
+ onChange: (e) => changeTheme(panelTheme, e.target.value, themeDensity),
39962
+ children: [
39963
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39964
+ value: "system",
39965
+ children: "跟随系统"
39966
+ }),
39967
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39968
+ value: "light",
39969
+ children: "浅色"
39970
+ }),
39971
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39972
+ value: "dark",
39973
+ children: "深色"
39974
+ })
39975
+ ]
39976
+ })]
39977
+ }),
39978
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
39979
+ className: panel_module_css_default.field,
39980
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
39981
+ className: panel_module_css_default.fieldLabel,
39982
+ children: "主题风格"
39983
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
39984
+ className: panel_module_css_default.input,
39985
+ value: panelTheme,
39986
+ onChange: (e) => changeTheme(e.target.value, themeMode, themeDensity),
39987
+ children: [
39988
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39989
+ value: "liquid",
39990
+ children: "液态玻璃 · 清新绿(默认)"
39991
+ }),
39992
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39993
+ value: "neumorph",
39994
+ children: "新拟物 · 柔和浅色"
39995
+ }),
39996
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
39997
+ value: "macos",
39998
+ children: "macOS · 玻璃(蓝,随外观浅/深)"
39999
+ }),
40000
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
40001
+ value: "clay",
40002
+ children: "粘土拟态 · 柔和黏土"
40003
+ })
40004
+ ]
40005
+ })]
40006
+ }),
40007
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40008
+ className: panel_module_css_default.field,
40009
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
40010
+ className: panel_module_css_default.fieldLabel,
40011
+ children: "界面密度"
40012
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
40013
+ className: panel_module_css_default.input,
40014
+ value: themeDensity,
40015
+ onChange: (e) => changeTheme(panelTheme, themeMode, e.target.value),
40016
+ children: [
40017
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
40018
+ value: "comfort",
40019
+ children: "舒适(默认)"
40020
+ }),
40021
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
40022
+ value: "compact",
40023
+ children: "紧凑"
40024
+ }),
40025
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
40026
+ value: "spacious",
40027
+ children: "宽松"
40028
+ })
40029
+ ]
40030
+ })]
40031
+ }),
40032
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40033
+ className: panel_module_css_default.field,
40034
+ children: [
40035
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
40036
+ className: panel_module_css_default.fieldLabel,
40037
+ children: "玻璃透明度(0-100)"
40038
+ }),
40039
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
40040
+ className: panel_module_css_default.input,
40041
+ type: "range",
40042
+ min: 0,
40043
+ max: 100,
40044
+ value: configDraft.themeOpacity ?? 100,
40045
+ onChange: (e) => applyOpacity(Number(e.target.value))
40046
+ }),
40047
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40048
+ className: panel_module_css_default.meta,
40049
+ children: "100=当前主题原样;调低会让玻璃/卡片变透,新拟态、黏土等实色主题能透出背景图。"
40050
+ })
40051
+ ]
40052
+ }),
40053
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40054
+ className: panel_module_css_default.row,
40055
+ style: { justifyContent: "flex-end" },
40056
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
40057
+ type: "button",
40058
+ className: panel_module_css_default.button,
40059
+ onClick: resetTheme,
40060
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.RotateCcw, {
40061
+ size: 14,
40062
+ style: { verticalAlign: -2 }
40063
+ }), " 恢复默认主题"]
40064
+ })
40065
+ })
40066
+ ]
40067
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40068
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
40069
+ style: { gap: "var(--nf-space-12)" },
40070
+ children: [
40071
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
40072
+ className: panel_module_css_default.cardTitle,
40073
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Image, {
40074
+ size: 18,
40075
+ style: { verticalAlign: -3 }
40076
+ }), " 自定义背景"]
40077
+ }),
40078
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40079
+ className: panel_module_css_default.meta,
40080
+ children: "填图片 URL 或上传图片作为小说工坊背景(首页 + 书内)。留空 = 使用主题默认背景。"
40081
+ }),
40082
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40083
+ className: panel_module_css_default.row,
40084
+ style: {
40085
+ gap: "var(--nf-space-8)",
40086
+ flexWrap: "wrap"
40087
+ },
40088
+ children: [
40089
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
40090
+ className: panel_module_css_default.input,
40091
+ style: {
40092
+ flex: 1,
40093
+ minWidth: 220
40094
+ },
40095
+ placeholder: "https://… 图片地址",
40096
+ value: (configDraft.themeBackground ?? "").startsWith("data:") ? "" : configDraft.themeBackground ?? "",
40097
+ onChange: (e) => applyBackground(e.target.value.trim() !== "" ? e.target.value.trim() : void 0)
40098
+ }),
40099
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
40100
+ type: "button",
40101
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
40102
+ onClick: () => bgFileRef.current?.click(),
40103
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Upload, {
40104
+ size: 13,
40105
+ style: { verticalAlign: -2 }
40106
+ }), " 上传图片"]
40107
+ }),
40108
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
40109
+ type: "button",
40110
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
40111
+ onClick: () => applyBackground(void 0),
40112
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.X, {
40113
+ size: 13,
40114
+ style: { verticalAlign: -2 }
40115
+ }), " 清除"]
40116
+ })
40117
+ ]
40118
+ }),
40119
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
40120
+ ref: bgFileRef,
40121
+ type: "file",
40122
+ accept: "image/*",
40123
+ style: { display: "none" },
40124
+ onChange: (e) => {
40125
+ onBgFile(e.target.files?.[0]);
40126
+ e.target.value = "";
40127
+ }
40128
+ }),
40129
+ (configDraft.themeBackground ?? "") !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40130
+ className: panel_module_css_default.adaptInputCard,
40131
+ style: { padding: 8 },
40132
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
40133
+ width: 180,
40134
+ height: 100,
40135
+ borderRadius: 10,
40136
+ backgroundImage: "url(" + configDraft.themeBackground + ")",
40137
+ backgroundSize: "cover",
40138
+ backgroundPosition: "center"
40139
+ } }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40140
+ className: panel_module_css_default.meta,
40141
+ children: "已设置背景(预览)"
40142
+ })]
40143
+ }),
40144
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40145
+ className: panel_module_css_default.field,
40146
+ children: [
40147
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
40148
+ className: panel_module_css_default.fieldLabel,
40149
+ children: "遮罩 / 模糊强度(0-80)"
40150
+ }),
40151
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
40152
+ className: panel_module_css_default.input,
40153
+ type: "range",
40154
+ min: 0,
40155
+ max: 80,
40156
+ value: configDraft.themeBackgroundBlur ?? 0,
40157
+ onChange: (e) => applyBlur(Number(e.target.value))
40158
+ }),
40159
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40160
+ className: panel_module_css_default.meta,
40161
+ children: "越大背景越暗,保证文字可读(图很花时调高)。"
40162
+ })
40163
+ ]
40164
+ })
40165
+ ]
40166
+ })] }),
40167
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40168
+ className: panel_module_css_default.row,
40169
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
40170
+ type: "button",
40171
+ className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
40172
+ disabled: busy,
40173
+ onClick: () => {
40174
+ save();
40175
+ },
40176
+ children: busy ? "保存中…" : tt("settings.save")
40177
+ })
40178
+ })
40179
+ ]
40180
+ });
40181
+ }
40182
+ //#endregion
40183
+ //#region src/client/panel/AuthorHome.tsx
40184
+ /**
40185
+ * 作者级首页容器:书架页左侧导航 + 内容区。
40186
+ * 导航复用工作区 .panelNav 玻璃卡片样式(同款),导航项为作者级:书架/改编/资产库/全局资产库/AI 进度/设置。
40187
+ */
40188
+ const PLUGIN_VERSION$1 = "1.9.0";
40189
+ const NAV_ITEMS = [
40190
+ {
40191
+ id: "shelf",
40192
+ label: "书架",
40193
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Library, { size: 18 }),
40194
+ hint: "我的书"
40195
+ },
40196
+ {
40197
+ id: "adapt",
40198
+ label: "改编模式",
40199
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wand2, { size: 18 }),
40200
+ hint: "上传全文→可改范围"
40201
+ },
40202
+ {
40203
+ id: "assets",
40204
+ label: "作者资产库",
40205
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Boxes, { size: 18 }),
40206
+ hint: "跨书总数据"
40207
+ },
40208
+ {
40209
+ id: "library",
40210
+ label: "全局写作资产库",
40211
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Brush, { size: 18 }),
40212
+ hint: "内置题材/规则/模板"
40213
+ },
40214
+ {
40215
+ id: "progress",
40216
+ label: "AI 进度",
40217
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BarChart3, { size: 18 }),
40218
+ hint: "书架级聚合进度"
40219
+ }
40220
+ ];
40221
+ function Placeholder({ title, hint }) {
40222
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40223
+ className: panel_module_css_default.authorPageBody,
40224
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40225
+ className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
40226
+ style: { gap: "var(--nf-space-6)" },
40227
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
40228
+ className: panel_module_css_default.panelTitle,
40229
+ style: { margin: 0 },
40230
+ children: title
40231
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40232
+ className: panel_module_css_default.meta,
40233
+ children: hint
40234
+ })]
40235
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40236
+ className: panel_module_css_default.shelfEmpty,
40237
+ style: { minHeight: 160 },
40238
+ children: [
40239
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40240
+ className: panel_module_css_default.shelfEmptyIcon,
40241
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Info, { size: 30 })
40242
+ }),
40243
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40244
+ className: panel_module_css_default.shelfEmptyTitle,
40245
+ children: "此入口为占位"
40246
+ }),
40247
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40248
+ className: panel_module_css_default.meta,
40249
+ children: "后续版本实现。当前「全局写作资产库」可进入某本书「创作资产」页查看内置题材库/反AI规则库/风格模板;「设置」为独立设置页。"
40250
+ })
40251
+ ]
40252
+ })]
40253
+ });
40254
+ }
40255
+ function AuthorHome({ api, shelf, onOpenBook, onReadBook, onAddBook, onImportBook, onOpenSettings, onTheme, onBackground, onOpacity, adaptEnabled, progress, busy, busyLabel, liveBar, onClearProgress }) {
40256
+ const [nav, setNav] = (0, react.useState)("shelf");
40257
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40258
+ className: panel_module_css_default.authorHome,
40259
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
40260
+ className: panel_module_css_default.panelNav,
40261
+ "aria-label": "作者级导航",
40262
+ children: [
40263
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40264
+ className: panel_module_css_default.navTitle,
40265
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40266
+ className: panel_module_css_default.navTitleLogo,
40267
+ children: "书"
40268
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40269
+ style: { minWidth: 0 },
40270
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40271
+ className: panel_module_css_default.navTitleName,
40272
+ children: "小说工坊"
40273
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40274
+ className: panel_module_css_default.navTitleBook,
40275
+ children: "作者级 · 跨书"
40276
+ })]
40277
+ })]
40278
+ }),
40279
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40280
+ className: panel_module_css_default.navGroup,
40281
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40282
+ className: panel_module_css_default.navGroupLabel,
40283
+ children: "作者"
40284
+ }), NAV_ITEMS.filter((item) => item.id !== "adapt" || adaptEnabled).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
40285
+ type: "button",
40286
+ role: "tab",
40287
+ "aria-selected": nav === item.id,
40288
+ "data-active": nav === item.id ? "" : void 0,
40289
+ className: panel_module_css_default.navTab,
40290
+ title: item.hint,
40291
+ onClick: () => setNav(item.id),
40292
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40293
+ className: panel_module_css_default.navTabIcon,
40294
+ children: item.icon
40295
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40296
+ className: panel_module_css_default.navTabLabel,
40297
+ children: item.label
40298
+ })]
40299
+ }, item.id))]
40300
+ }),
40301
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: panel_module_css_default.navSpacer }),
40302
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
40303
+ type: "button",
40304
+ role: "tab",
40305
+ "aria-selected": nav === "settings",
40306
+ "data-active": nav === "settings" ? "" : void 0,
40307
+ className: panel_module_css_default.navTab,
40308
+ title: "设置",
40309
+ onClick: () => setNav("settings"),
40310
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40311
+ className: panel_module_css_default.navTabIcon,
40312
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Settings, { size: 18 })
40313
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40314
+ className: panel_module_css_default.navTabLabel,
40315
+ children: "设置"
40316
+ })]
40317
+ }),
40318
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40319
+ className: panel_module_css_default.navAbout,
40320
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40321
+ className: panel_module_css_default.navAboutRow,
40322
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
40323
+ "ℹ️ v",
40324
+ PLUGIN_VERSION$1,
40325
+ " · 改编/资产库"
40326
+ ] })
40327
+ })
40328
+ })
40329
+ ]
40330
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40331
+ className: panel_module_css_default.authorContent,
40332
+ children: [
40333
+ nav === "shelf" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShelfView, {
40334
+ api,
40335
+ shelf,
40336
+ onOpenBook,
40337
+ onReadBook,
40338
+ onAddBook,
40339
+ onImportBook
40340
+ }),
40341
+ nav === "adapt" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdaptModeView, { api }),
40342
+ nav === "assets" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuthorAssetsView, { api }),
40343
+ nav === "library" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Placeholder, {
40344
+ title: "🎨 全局写作资产库",
40345
+ hint: "内置题材基底库 / 反AI规则库 / 风格模板 / 推进模式(跨书)"
40346
+ }),
40347
+ nav === "progress" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40348
+ className: panel_module_css_default.authorPageBody,
40349
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProgressConsole, {
40350
+ progress: progress ?? [],
40351
+ busy: busy ?? false,
40352
+ busyLabel: busyLabel ?? "",
40353
+ liveBar: liveBar ?? null,
40354
+ onClear: () => onClearProgress?.()
40355
+ })
40356
+ }),
40357
+ nav === "settings" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsView, {
40358
+ api,
40359
+ onTheme,
40360
+ onBackground,
40361
+ onOpacity
40362
+ })
40363
+ ]
40364
+ })]
40365
+ });
40366
+ }
40367
+ //#endregion
37129
40368
  //#region src/client/panel/ReaderView.tsx
37130
40369
  /**
37131
40370
  * 阅读页:沉浸式章节阅读(纯只读,零 LLM 消耗)。
@@ -38969,7 +42208,7 @@ window.__ModuleLoader__.load({
38969
42208
  setFileName(file.name);
38970
42209
  setPreviewing(true);
38971
42210
  try {
38972
- const text = await file.text();
42211
+ const text = await readFileTextSmart(file);
38973
42212
  setFileText(text);
38974
42213
  const p = await api.bookImportTextPreview(text, file.name);
38975
42214
  setPreview(p);
@@ -44927,32 +48166,32 @@ window.__ModuleLoader__.load({
44927
48166
  {
44928
48167
  id: "workflow",
44929
48168
  label: tt("tab.workflow"),
44930
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wrench, { size: 16 })
48169
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wrench, { size: 18 })
44931
48170
  },
44932
48171
  {
44933
48172
  id: "overview",
44934
48173
  label: tt("tab.overview"),
44935
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.FileText, { size: 16 })
48174
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.FileText, { size: 18 })
44936
48175
  },
44937
48176
  {
44938
48177
  id: "blurb",
44939
48178
  label: "简介 / 封面",
44940
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BookOpen, { size: 16 })
48179
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BookOpen, { size: 18 })
44941
48180
  },
44942
48181
  {
44943
48182
  id: "plan",
44944
48183
  label: tt("tab.plan"),
44945
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BookMarked, { size: 16 })
48184
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BookMarked, { size: 18 })
44946
48185
  },
44947
48186
  {
44948
48187
  id: "plotlines",
44949
48188
  label: "长线管理",
44950
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ScrollText, { size: 16 })
48189
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ScrollText, { size: 18 })
44951
48190
  },
44952
48191
  {
44953
48192
  id: "book",
44954
48193
  label: "本书设定",
44955
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Library, { size: 16 })
48194
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Library, { size: 18 })
44956
48195
  }
44957
48196
  ]
44958
48197
  },
@@ -44963,27 +48202,27 @@ window.__ModuleLoader__.load({
44963
48202
  {
44964
48203
  id: "assistant",
44965
48204
  label: tt("tab.assistant"),
44966
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.MessageSquare, { size: 16 })
48205
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.MessageSquare, { size: 18 })
44967
48206
  },
44968
48207
  {
44969
48208
  id: "progress",
44970
48209
  label: "AI 进度",
44971
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BarChart3, { size: 16 })
48210
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BarChart3, { size: 18 })
44972
48211
  },
44973
48212
  {
44974
48213
  id: "breakdown",
44975
48214
  label: "拆书分析",
44976
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Search, { size: 16 })
48215
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Search, { size: 18 })
44977
48216
  },
44978
48217
  {
44979
48218
  id: "manhua",
44980
48219
  label: "漫剧工作台",
44981
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Clapperboard, { size: 16 })
48220
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Clapperboard, { size: 18 })
44982
48221
  },
44983
48222
  {
44984
48223
  id: "run",
44985
48224
  label: "生产单",
44986
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Factory, { size: 16 })
48225
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Factory, { size: 18 })
44987
48226
  }
44988
48227
  ]
44989
48228
  },
@@ -44993,7 +48232,7 @@ window.__ModuleLoader__.load({
44993
48232
  items: [{
44994
48233
  id: "assets",
44995
48234
  label: "创作资产",
44996
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wrench, { size: 16 })
48235
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wrench, { size: 18 })
44997
48236
  }]
44998
48237
  }
44999
48238
  ];
@@ -45001,21 +48240,8 @@ window.__ModuleLoader__.load({
45001
48240
  const SETTINGS_TAB = {
45002
48241
  id: "settings",
45003
48242
  label: tt("tab.settings"),
45004
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Settings, { size: 16 })
48243
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Settings, { size: 18 })
45005
48244
  };
45006
- /** Common DeepSeek model presets shown in settings; users can also type any model id. */
45007
- const MODEL_PRESETS = [
45008
- "deepseek-v4-flash",
45009
- "deepseek-v4-pro",
45010
- "deepseek-chat",
45011
- "deepseek-reasoner"
45012
- ];
45013
- const REASONING_OPTIONS = [
45014
- "off",
45015
- "low",
45016
- "high",
45017
- "max"
45018
- ];
45019
48245
  /** 设置页内子导航分组。 */
45020
48246
  const SETTINGS_SECTIONS = [
45021
48247
  {
@@ -45044,7 +48270,7 @@ window.__ModuleLoader__.load({
45044
48270
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Sparkles, { size: 16 })
45045
48271
  }
45046
48272
  ];
45047
- const PLUGIN_VERSION = "1.7.3";
48273
+ const PLUGIN_VERSION = "1.9.0";
45048
48274
  /** GitHub 仓库地址(关于区块点击跳转)。 */
45049
48275
  const REPO_URL = "https://github.com/watersxya/dsh-novel-forge";
45050
48276
  /** Whether any chapter is being generated right now. */
@@ -45300,6 +48526,12 @@ window.__ModuleLoader__.load({
45300
48526
  function NovelPanel({ controller, api }) {
45301
48527
  const [activeTab, setActiveTab] = (0, react.useState)("workflow");
45302
48528
  const [config, setConfig] = (0, react.useState)(null);
48529
+ /** 自定义背景(URL / dataURL),覆盖主题默认背景。 */
48530
+ const [themeBg, setThemeBg] = (0, react.useState)(void 0);
48531
+ /** 自定义背景遮罩/模糊强度 0-80。 */
48532
+ const [themeBgBlur, setThemeBgBlur] = (0, react.useState)(0);
48533
+ /** 玻璃透明度 0-100(100=主题原样)。 */
48534
+ const [themeOpacity, setThemeOpacity] = (0, react.useState)(100);
45303
48535
  const [project, setProject] = (0, react.useState)(null);
45304
48536
  const [generatedFiles, setGeneratedFiles] = (0, react.useState)([]);
45305
48537
  const [outlineText, setOutlineText] = (0, react.useState)("");
@@ -45314,7 +48546,6 @@ window.__ModuleLoader__.load({
45314
48546
  const [notice, setNotice] = (0, react.useState)("");
45315
48547
  const [progress, setProgress] = (0, react.useState)([]);
45316
48548
  const [configDraft, setConfigDraft] = (0, react.useState)(null);
45317
- const [modelCustomMode, setModelCustomMode] = (0, react.useState)(false);
45318
48549
  const [expandedChapter, setExpandedChapter] = (0, react.useState)(null);
45319
48550
  /** 复盘记录页:当前展开的章节号。 */
45320
48551
  const [expandedReviewChapter, setExpandedReviewChapter] = (0, react.useState)(null);
@@ -45736,7 +48967,6 @@ window.__ModuleLoader__.load({
45736
48967
  const status = await api.status();
45737
48968
  setConfig(status.config);
45738
48969
  setConfigDraft(status.config);
45739
- setModelCustomMode(!MODEL_PRESETS.includes(status.config.model));
45740
48970
  setAuditStatus(status.audit ?? null);
45741
48971
  setProject(status.project ?? null);
45742
48972
  if (status.project?.roleStatus !== void 0) setCharCards(status.project.roleStatus);
@@ -45777,6 +49007,16 @@ window.__ModuleLoader__.load({
45777
49007
  refresh,
45778
49008
  refreshShelf
45779
49009
  ]);
49010
+ /** 首页「设置」与书内设置同入口:激活当前/首选书并跳到设置页。 */
49011
+ const openSettingsFromHome = async () => {
49012
+ const targetId = shelf?.activeBookId ?? shelf?.books[0]?.id ?? null;
49013
+ if (targetId === null || targetId === void 0) {
49014
+ setError("请先在书架开一本书;设置页以书籍工作台为入口");
49015
+ return;
49016
+ }
49017
+ await activateBook(targetId, "workspace");
49018
+ setActiveTab("settings");
49019
+ };
45780
49020
  /** Handle a docx file (pick or drag): parse locally, save outline. */
45781
49021
  const handleDocxFile = (0, react.useCallback)(async (file) => {
45782
49022
  setBusy(true);
@@ -47112,7 +50352,8 @@ window.__ModuleLoader__.load({
47112
50352
  imageApiKey: configDraft.imageApiKey,
47113
50353
  imageApiModel: configDraft.imageApiModel,
47114
50354
  imageApiEnabled: configDraft.imageApiEnabled ?? false,
47115
- imageModels: configDraft.imageModels ?? []
50355
+ imageModels: configDraft.imageModels ?? [],
50356
+ savedModels: configDraft.savedModels ?? []
47116
50357
  });
47117
50358
  setConfig(result.config);
47118
50359
  setConfigDraft(result.config);
@@ -47523,13 +50764,22 @@ window.__ModuleLoader__.load({
47523
50764
  n += assets?.antiAiRules?.length ?? 0;
47524
50765
  return n;
47525
50766
  })();
50767
+ /** 自定义背景:优先用户显式选择(themeBg),否则用 config 里的持久化值。 */
50768
+ const effectiveBg = themeBg !== void 0 && themeBg !== "" ? themeBg : config?.themeBackground ?? "";
50769
+ const effectiveBgBlur = themeBgBlur > 0 ? themeBgBlur : config?.themeBackgroundBlur ?? 0;
50770
+ const effectiveOpacity = themeOpacity > 0 ? themeOpacity : config?.themeOpacity ?? 100;
50771
+ const panelBgStyle = {};
50772
+ if (effectiveBg !== "") panelBgStyle["--nf-glass-bg-image"] = "url(" + effectiveBg + ")";
50773
+ if (effectiveBgBlur > 0) panelBgStyle["--nf-glass-bg-dim"] = String(effectiveBgBlur);
50774
+ panelBgStyle["--nf-glass-opacity"] = String(effectiveOpacity) + "%";
47526
50775
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
47527
50776
  className: panel_module_css_default.panel,
47528
50777
  "data-nf-theme": panelTheme,
47529
50778
  "data-nf-mode": themeMode === "system" ? void 0 : themeMode,
47530
50779
  "data-nf-density": themeDensity,
50780
+ style: panelBgStyle,
47531
50781
  children: [
47532
- viewMode === "shelf" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShelfView, {
50782
+ viewMode === "shelf" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuthorHome, {
47533
50783
  api,
47534
50784
  shelf: shelf ?? {
47535
50785
  books: [],
@@ -47546,6 +50796,29 @@ window.__ModuleLoader__.load({
47546
50796
  },
47547
50797
  onImportBook: () => {
47548
50798
  setShowImport(true);
50799
+ },
50800
+ onOpenSettings: () => {
50801
+ openSettingsFromHome();
50802
+ },
50803
+ onTheme: (t, m, d) => {
50804
+ changePanelTheme(t);
50805
+ changeThemeMode(m);
50806
+ changeThemeDensity(d);
50807
+ },
50808
+ onBackground: (bg, blur) => {
50809
+ setThemeBg(bg);
50810
+ setThemeBgBlur(blur);
50811
+ },
50812
+ onOpacity: (n) => {
50813
+ setThemeOpacity(n);
50814
+ },
50815
+ adaptEnabled: config?.enableAdaptMode === true,
50816
+ progress,
50817
+ busy,
50818
+ busyLabel,
50819
+ liveBar,
50820
+ onClearProgress: () => {
50821
+ setProgress([]);
47549
50822
  }
47550
50823
  }) : viewMode === "create" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreateBookView, {
47551
50824
  api,
@@ -50208,7 +53481,7 @@ window.__ModuleLoader__.load({
50208
53481
  }, s.id))
50209
53482
  })]
50210
53483
  }),
50211
- settingsTab === "model" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
53484
+ settingsTab === "model" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50212
53485
  className: `${panel_module_css_default.card} ${panel_module_css_default.settingsCard}`,
50213
53486
  style: { gap: "var(--nf-space-24)" },
50214
53487
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
@@ -50217,129 +53490,36 @@ window.__ModuleLoader__.load({
50217
53490
  size: 18,
50218
53491
  style: { verticalAlign: -3 }
50219
53492
  }), " 模型与推理"]
50220
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50221
- style: {
50222
- display: "flex",
50223
- flexDirection: "column",
50224
- gap: "var(--nf-space-24)"
53493
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelManager, {
53494
+ api,
53495
+ provider: configDraft.provider,
53496
+ model: configDraft.model,
53497
+ savedModels: configDraft.savedModels ?? [],
53498
+ onProvider: (v) => {
53499
+ setConfigDraft({
53500
+ ...configDraft,
53501
+ provider: v
53502
+ });
50225
53503
  },
50226
- children: [
50227
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50228
- className: panel_module_css_default.field,
50229
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
50230
- className: panel_module_css_default.fieldLabel,
50231
- children: tt("settings.provider")
50232
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
50233
- className: panel_module_css_default.input,
50234
- value: configDraft.provider,
50235
- onChange: (e) => {
50236
- setConfigDraft({
50237
- ...configDraft,
50238
- provider: e.target.value
50239
- });
50240
- }
50241
- })]
50242
- }),
50243
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50244
- className: panel_module_css_default.field,
50245
- children: [
50246
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
50247
- className: panel_module_css_default.fieldLabel,
50248
- children: tt("settings.model")
50249
- }),
50250
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
50251
- className: panel_module_css_default.input,
50252
- value: modelCustomMode ? "__custom__" : configDraft.model,
50253
- onChange: (e) => {
50254
- const v = e.target.value;
50255
- if (v === "__custom__") setModelCustomMode(true);
50256
- else {
50257
- setModelCustomMode(false);
50258
- setConfigDraft({
50259
- ...configDraft,
50260
- model: v
50261
- });
50262
- }
50263
- },
50264
- children: [MODEL_PRESETS.map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
50265
- value: m,
50266
- children: m
50267
- }, m)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
50268
- value: "__custom__",
50269
- children: tt("settings.modelCustom")
50270
- })]
50271
- }),
50272
- modelCustomMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
50273
- className: panel_module_css_default.input,
50274
- style: { marginTop: "var(--nf-space-6)" },
50275
- value: configDraft.model,
50276
- placeholder: tt("settings.modelCustomPlaceholder"),
50277
- onChange: (e) => {
50278
- setConfigDraft({
50279
- ...configDraft,
50280
- model: e.target.value
50281
- });
50282
- }
50283
- })
50284
- ]
50285
- }),
50286
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50287
- className: panel_module_css_default.field,
50288
- children: [
50289
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
50290
- className: panel_module_css_default.fieldLabel,
50291
- children: tt("settings.reasoningEffort")
50292
- }),
50293
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
50294
- className: panel_module_css_default.input,
50295
- value: configDraft.reasoningEffort ?? "off",
50296
- onChange: (e) => {
50297
- setConfigDraft({
50298
- ...configDraft,
50299
- reasoningEffort: e.target.value
50300
- });
50301
- },
50302
- children: REASONING_OPTIONS.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
50303
- value: v,
50304
- children: tt(`settings.reasoning.${v}`)
50305
- }, v))
50306
- }),
50307
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
50308
- className: panel_module_css_default.meta,
50309
- children: tt("settings.reasoningHint")
50310
- })
50311
- ]
50312
- }),
50313
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50314
- className: panel_module_css_default.field,
50315
- children: [
50316
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
50317
- className: panel_module_css_default.fieldLabel,
50318
- children: tt("settings.analysisReasoning")
50319
- }),
50320
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
50321
- className: panel_module_css_default.input,
50322
- value: configDraft.analysisReasoning ?? "low",
50323
- onChange: (e) => {
50324
- setConfigDraft({
50325
- ...configDraft,
50326
- analysisReasoning: e.target.value
50327
- });
50328
- },
50329
- children: REASONING_OPTIONS.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
50330
- value: v,
50331
- children: tt(`settings.reasoning.${v}`)
50332
- }, v))
50333
- }),
50334
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
50335
- className: panel_module_css_default.meta,
50336
- children: tt("settings.analysisReasoningHint")
50337
- })
50338
- ]
50339
- })
50340
- ]
53504
+ onModel: (v) => {
53505
+ setConfigDraft({
53506
+ ...configDraft,
53507
+ model: v
53508
+ });
53509
+ },
53510
+ onSavedModels: (models) => setConfigDraft({
53511
+ ...configDraft,
53512
+ savedModels: models
53513
+ })
50341
53514
  })]
50342
- }),
53515
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningSection, {
53516
+ reasoningEffort: configDraft.reasoningEffort ?? "off",
53517
+ analysisReasoning: configDraft.analysisReasoning ?? "low",
53518
+ onChange: (patch) => setConfigDraft({
53519
+ ...configDraft,
53520
+ ...patch
53521
+ })
53522
+ })] }),
50343
53523
  settingsTab === "writing" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50344
53524
  className: `${panel_module_css_default.card} ${panel_module_css_default.settingsCard}`,
50345
53525
  style: { gap: "var(--nf-space-24)" },
@@ -52406,7 +55586,7 @@ window.__ModuleLoader__.load({
52406
55586
  entry.className = panel_module_css_default.entry;
52407
55587
  entry.setAttribute("aria-label", tt("entry.label"));
52408
55588
  entry.setAttribute("title", tt("entry.tooltip"));
52409
- entry.innerHTML = "<span class=\"" + panel_module_css_default.entryIcon + "\"><svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M2.5 3.5h4a2 2 0 0 1 2 2v7a2 2 0 0 0-2-2h-4z\"/><path d=\"M13.5 3.5h-4a2 2 0 0 0-2 2v7a2 2 0 0 1 2-2h4z\"/><path d=\"M8 5.5v7\"/></svg></span><span class=\"" + panel_module_css_default.entryLabel + "\">" + tt("entry.label") + "</span>";
55589
+ entry.innerHTML = "<span class=\"" + panel_module_css_default.entryIcon + "\"><svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12.67 19a2 2 0 0 0 1.416-.588l6.154-6.172a6 6 0 0 0-8.49-8.49L5.586 9.914A2 2 0 0 0 5 11.328V18a1 1 0 0 0 1 1z\"/><path d=\"M16 8 2 22\"/><path d=\"M17.5 15H9\"/></svg></span><span class=\"" + panel_module_css_default.entryLabel + "\">" + tt("entry.label") + "</span>";
52410
55590
  entry.addEventListener("click", () => {
52411
55591
  controller.toggle();
52412
55592
  });