@waterwx/dsh-novel-forge 2.1.0-alpha → 2.1.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 (253) hide show
  1. package/README.md +368 -457
  2. package/lib/client.js +20495 -22316
  3. package/lib/index.js +4640 -3932
  4. package/lib/types/action-guard.d.ts +61 -0
  5. package/lib/types/ai-scan.d.ts +0 -6
  6. package/lib/types/assets.d.ts +7 -9
  7. package/lib/types/assistant.d.ts +25 -0
  8. package/lib/types/author-assets.d.ts +1 -3
  9. package/lib/types/bookshelf.d.ts +13 -3
  10. package/lib/types/client/api.d.ts +49 -29
  11. package/lib/types/client/chip-prefs.d.ts +36 -0
  12. package/lib/types/client/docx.d.ts +2 -2
  13. package/lib/types/client/llmLive.d.ts +12 -14
  14. package/lib/types/client/locales.d.ts +12 -67
  15. package/lib/types/client/mount.d.ts +0 -2
  16. package/lib/types/client/panel/AdaptModeView.d.ts +1 -1
  17. package/lib/types/client/panel/AiTag.d.ts +1 -0
  18. package/lib/types/client/panel/AssetsTab.d.ts +1 -1
  19. package/lib/types/client/panel/AssistantTab.d.ts +4 -1
  20. package/lib/types/client/panel/AuthorAssetsView.d.ts +1 -1
  21. package/lib/types/client/panel/AuthorHome.d.ts +12 -12
  22. package/lib/types/client/panel/CmdPalette.d.ts +12 -0
  23. package/lib/types/client/panel/CreateBookView.d.ts +1 -1
  24. package/lib/types/client/panel/GlobalAssetLibraryView.d.ts +1 -1
  25. package/lib/types/client/panel/ImportModal.d.ts +1 -1
  26. package/lib/types/client/panel/LiveFeedLog.d.ts +8 -0
  27. package/lib/types/client/panel/ModelManager.d.ts +2 -2
  28. package/lib/types/client/panel/NovelPanel.d.ts +7 -2
  29. package/lib/types/client/panel/PageHeader.d.ts +18 -0
  30. package/lib/types/client/panel/ProgressConsole.d.ts +1 -1
  31. package/lib/types/client/panel/PromptSlotsView.d.ts +11 -0
  32. package/lib/types/client/panel/ReaderView.d.ts +1 -1
  33. package/lib/types/client/panel/RunPanel.d.ts +1 -1
  34. package/lib/types/client/panel/SettingsView.d.ts +13 -10
  35. package/lib/types/client/panel/ShelfView.d.ts +11 -2
  36. package/lib/types/client/panel/SubPage.d.ts +27 -0
  37. package/lib/types/client/panel/TensionView.d.ts +18 -0
  38. package/lib/types/client/panel/TimelineView.d.ts +18 -0
  39. package/lib/types/client/panel/WorldTab.d.ts +1 -1
  40. package/lib/types/client/panel/helpers.d.ts +5 -3
  41. package/lib/types/client/panel/market-radar-state.d.ts +56 -0
  42. package/lib/types/client/panel/outline-markdown.d.ts +112 -0
  43. package/lib/types/client/panel/status-badge.d.ts +13 -0
  44. package/lib/types/client/panel/storage-parse.d.ts +46 -0
  45. package/lib/types/client/panel/toast.d.ts +2 -0
  46. package/lib/types/client/panel/usePersistentState.d.ts +17 -0
  47. package/lib/types/client/panel/views.d.ts +21 -35
  48. package/lib/types/client/run-status.d.ts +21 -0
  49. package/lib/types/client/sidebar-entry.d.ts +0 -2
  50. package/lib/types/digest-parse.d.ts +29 -0
  51. package/lib/types/docx-core.d.ts +16 -0
  52. package/lib/types/docx.d.ts +2 -3
  53. package/lib/types/engine.d.ts +122 -103
  54. package/lib/types/home.d.ts +11 -0
  55. package/lib/types/index.d.ts +21 -13
  56. package/lib/types/llm-live.d.ts +62 -36
  57. package/lib/types/llm-retry.d.ts +38 -0
  58. package/lib/types/market-radar-scan.d.ts +0 -1
  59. package/lib/types/market-radar-sources.d.ts +1 -1
  60. package/lib/types/migrate-output.d.ts +25 -0
  61. package/lib/types/model-capability.d.ts +119 -0
  62. package/lib/types/model-request.d.ts +36 -0
  63. package/lib/types/output-budget.d.ts +86 -0
  64. package/lib/types/plotline-align.d.ts +35 -0
  65. package/lib/types/prompt-slots.d.ts +57 -0
  66. package/lib/types/prompting.d.ts +2 -27
  67. package/lib/types/protocol.d.ts +479 -595
  68. package/lib/types/revision.d.ts +76 -0
  69. package/lib/types/routes.d.ts +9 -3
  70. package/lib/types/run-selection.d.ts +51 -0
  71. package/lib/types/run.d.ts +31 -0
  72. package/lib/types/settings-persist.d.ts +59 -0
  73. package/lib/types/snapshots.d.ts +46 -0
  74. package/lib/types/stage-contract.d.ts +58 -0
  75. package/lib/types/stream-fallback.d.ts +60 -0
  76. package/lib/types/strip-headings.d.ts +33 -0
  77. package/lib/types/tension.d.ts +53 -0
  78. package/lib/types/timeline.d.ts +37 -0
  79. package/package.json +50 -27
  80. package/assets/styles/arcane-thick-3d.webp +0 -0
  81. package/assets/styles/chinese-ink.webp +0 -0
  82. package/assets/styles/clay-stopmotion-3d.webp +0 -0
  83. package/assets/styles/dark-ghibli.webp +0 -0
  84. package/assets/styles/dark-gothic-3d.webp +0 -0
  85. package/assets/styles/film-photo.webp +0 -0
  86. package/assets/styles/guofeng-heavy.webp +0 -0
  87. package/assets/styles/guoman-2d-gufeng.webp +0 -0
  88. package/assets/styles/guoman-3d-tianyuan.webp +0 -0
  89. package/assets/styles/guoman-3d-xuanhuan.webp +0 -0
  90. package/assets/styles/horror-game-3d.webp +0 -0
  91. package/assets/styles/hyperreal-3d.webp +0 -0
  92. package/assets/styles/japan-cel-dark.webp +0 -0
  93. package/assets/styles/korean-webtoon.webp +0 -0
  94. package/assets/styles/low-cyberpunk-3d.webp +0 -0
  95. package/assets/styles/nextgen-cg.webp +0 -0
  96. package/assets/styles/noir-film.webp +0 -0
  97. package/assets/styles/openworld-survival.webp +0 -0
  98. package/assets/styles/paper-cut-3d.webp +0 -0
  99. package/assets/styles/pixar-adult-3d.webp +0 -0
  100. package/assets/styles/pop-marvel-2d.webp +0 -0
  101. package/assets/styles/sandiao-qban.webp +0 -0
  102. package/assets/styles/shinkai-anime.webp +0 -0
  103. package/assets/styles/tactical-stealth.webp +0 -0
  104. package/assets/styles/urban-lightreal-3d.webp +0 -0
  105. package/assets/styles/vaporwave-3d.webp +0 -0
  106. package/assets/styles/vhs90.webp +0 -0
  107. package/lib/types/client/panel/BookshelfBar.d.ts +0 -11
  108. package/lib/types/client/panel/FlowGuide.d.ts +0 -22
  109. package/lib/types/client/panel/MangaRoleLibrary.d.ts +0 -20
  110. package/lib/types/client/panel/MangaWorkspace.d.ts +0 -12
  111. package/lib/types/client/panel/ModelPicker.d.ts +0 -11
  112. package/lib/types/client/panel/ProgressHomeView.d.ts +0 -5
  113. package/lib/types/client/panel/PropLibrary.d.ts +0 -8
  114. package/lib/types/client/panel/SceneLibrary.d.ts +0 -16
  115. package/lib/types/client/panel/StoryboardTab.d.ts +0 -19
  116. package/lib/types/client/panel/StyleCard.d.ts +0 -8
  117. package/lib/types/client/panel/StyleGallery.d.ts +0 -1
  118. package/lib/types/comic-presets.d.ts +0 -12
  119. package/lib/types/manga-genre-rules.d.ts +0 -22
  120. package/lib/types/prompt-utils.d.ts +0 -35
  121. package/lib/types/review-policy.d.ts +0 -97
  122. package/lib/types/shot-language.d.ts +0 -46
  123. package/lib/types/src/ai-scan.d.ts +0 -36
  124. package/lib/types/src/assets.d.ts +0 -37
  125. package/lib/types/src/assistant.d.ts +0 -45
  126. package/lib/types/src/author-assets.d.ts +0 -25
  127. package/lib/types/src/bookshelf.d.ts +0 -42
  128. package/lib/types/src/client/api.d.ts +0 -234
  129. package/lib/types/src/client/docx.d.ts +0 -15
  130. package/lib/types/src/client/index.d.ts +0 -14
  131. package/lib/types/src/client/locales.d.ts +0 -212
  132. package/lib/types/src/client/mount.d.ts +0 -9
  133. package/lib/types/src/client/panel/AdaptModeView.d.ts +0 -5
  134. package/lib/types/src/client/panel/AssetsTab.d.ts +0 -12
  135. package/lib/types/src/client/panel/AssistantTab.d.ts +0 -7
  136. package/lib/types/src/client/panel/AuthorAssetsView.d.ts +0 -4
  137. package/lib/types/src/client/panel/AuthorHome.d.ts +0 -32
  138. package/lib/types/src/client/panel/BookshelfBar.d.ts +0 -11
  139. package/lib/types/src/client/panel/CreateBookView.d.ts +0 -9
  140. package/lib/types/src/client/panel/FlowGuide.d.ts +0 -22
  141. package/lib/types/src/client/panel/GlobalAssetLibraryView.d.ts +0 -4
  142. package/lib/types/src/client/panel/ImportModal.d.ts +0 -7
  143. package/lib/types/src/client/panel/MangaRoleLibrary.d.ts +0 -20
  144. package/lib/types/src/client/panel/MangaWorkspace.d.ts +0 -12
  145. package/lib/types/src/client/panel/ModelManager.d.ts +0 -14
  146. package/lib/types/src/client/panel/NovelPanel.d.ts +0 -13
  147. package/lib/types/src/client/panel/ProgressConsole.d.ts +0 -17
  148. package/lib/types/src/client/panel/ProgressHomeView.d.ts +0 -5
  149. package/lib/types/src/client/panel/PropLibrary.d.ts +0 -8
  150. package/lib/types/src/client/panel/ReaderView.d.ts +0 -8
  151. package/lib/types/src/client/panel/ReasoningSection.d.ts +0 -10
  152. package/lib/types/src/client/panel/RunPanel.d.ts +0 -5
  153. package/lib/types/src/client/panel/SceneLibrary.d.ts +0 -16
  154. package/lib/types/src/client/panel/SettingsView.d.ts +0 -16
  155. package/lib/types/src/client/panel/ShelfView.d.ts +0 -15
  156. package/lib/types/src/client/panel/StoryboardTab.d.ts +0 -19
  157. package/lib/types/src/client/panel/StyleCard.d.ts +0 -8
  158. package/lib/types/src/client/panel/StyleGallery.d.ts +0 -1
  159. package/lib/types/src/client/panel/WorldTab.d.ts +0 -10
  160. package/lib/types/src/client/panel/controller.d.ts +0 -19
  161. package/lib/types/src/client/panel/helpers.d.ts +0 -18
  162. package/lib/types/src/client/panel/views.d.ts +0 -77
  163. package/lib/types/src/client/sidebar-entry.d.ts +0 -13
  164. package/lib/types/src/client/text.d.ts +0 -9
  165. package/lib/types/src/comic-presets.d.ts +0 -12
  166. package/lib/types/src/docx.d.ts +0 -19
  167. package/lib/types/src/engine.d.ts +0 -402
  168. package/lib/types/src/index.d.ts +0 -79
  169. package/lib/types/src/manga-genre-rules.d.ts +0 -22
  170. package/lib/types/src/novel-context.d.ts +0 -80
  171. package/lib/types/src/prompt-utils.d.ts +0 -35
  172. package/lib/types/src/protocol.d.ts +0 -2176
  173. package/lib/types/src/review-policy.d.ts +0 -97
  174. package/lib/types/src/routes.d.ts +0 -29
  175. package/lib/types/src/run.d.ts +0 -32
  176. package/lib/types/src/shot-language.d.ts +0 -46
  177. package/lib/types/src/story-beat-language.d.ts +0 -35
  178. package/lib/types/src/style-library.d.ts +0 -33
  179. package/lib/types/story-beat-language.d.ts +0 -35
  180. package/lib/types/style-library.d.ts +0 -33
  181. package/src/ai-scan.ts +0 -179
  182. package/src/assets.ts +0 -1774
  183. package/src/assistant.ts +0 -915
  184. package/src/author-assets.ts +0 -147
  185. package/src/bookshelf.ts +0 -167
  186. package/src/client/api.ts +0 -716
  187. package/src/client/css-modules.d.ts +0 -8
  188. package/src/client/docx.ts +0 -69
  189. package/src/client/index.ts +0 -34
  190. package/src/client/llmLive.ts +0 -101
  191. package/src/client/locales.ts +0 -418
  192. package/src/client/mount.tsx +0 -97
  193. package/src/client/mount.tsx._new +0 -97
  194. package/src/client/mount.tsx._nf +0 -97
  195. package/src/client/mount.tsx._tmp +0 -97
  196. package/src/client/panel/AdaptModeView.tsx +0 -535
  197. package/src/client/panel/AssetsTab.tsx +0 -458
  198. package/src/client/panel/AssistantTab.tsx +0 -339
  199. package/src/client/panel/AuthorAssetsView.tsx +0 -208
  200. package/src/client/panel/AuthorHome.tsx +0 -235
  201. package/src/client/panel/BookAnalysisView.tsx +0 -60
  202. package/src/client/panel/BookshelfBar.tsx +0 -170
  203. package/src/client/panel/CreateBookView.tsx +0 -371
  204. package/src/client/panel/DirectorView.tsx +0 -200
  205. package/src/client/panel/FlowGuide.tsx +0 -84
  206. package/src/client/panel/GlobalAssetLibraryView.tsx +0 -172
  207. package/src/client/panel/IdeaInspirationView.tsx +0 -71
  208. package/src/client/panel/ImportModal.tsx +0 -303
  209. package/src/client/panel/KnowledgeBaseView.tsx +0 -73
  210. package/src/client/panel/LiveFeedLog.tsx +0 -76
  211. package/src/client/panel/MangaRoleLibrary.tsx +0 -1002
  212. package/src/client/panel/MangaWorkspace.tsx +0 -715
  213. package/src/client/panel/MarketRadarView.tsx +0 -374
  214. package/src/client/panel/ModelManager.tsx +0 -205
  215. package/src/client/panel/NovelPanel.tsx +0 -4721
  216. package/src/client/panel/ProgressConsole.tsx +0 -63
  217. package/src/client/panel/ProgressHomeView.tsx +0 -87
  218. package/src/client/panel/PropLibrary.tsx +0 -175
  219. package/src/client/panel/ReaderView.tsx +0 -306
  220. package/src/client/panel/ReasoningSection.tsx +0 -31
  221. package/src/client/panel/RunPanel.tsx +0 -204
  222. package/src/client/panel/SceneLibrary.tsx +0 -453
  223. package/src/client/panel/SettingsView.tsx +0 -289
  224. package/src/client/panel/ShelfView.tsx +0 -242
  225. package/src/client/panel/StoryboardTab.tsx +0 -472
  226. package/src/client/panel/StyleCard.tsx +0 -90
  227. package/src/client/panel/StyleGallery.tsx +0 -58
  228. package/src/client/panel/WorldTab.tsx +0 -202
  229. package/src/client/panel/controller.ts +0 -45
  230. package/src/client/panel/helpers.ts +0 -67
  231. package/src/client/panel/panel.module.css +0 -4359
  232. package/src/client/panel/views.tsx +0 -314
  233. package/src/client/sidebar-entry.ts +0 -122
  234. package/src/client/text.ts +0 -28
  235. package/src/comic-presets.ts +0 -67
  236. package/src/docx.ts +0 -83
  237. package/src/engine.ts +0 -5636
  238. package/src/global-assets.ts +0 -59
  239. package/src/index.ts +0 -345
  240. package/src/llm-live.ts +0 -68
  241. package/src/manga-genre-rules.ts +0 -87
  242. package/src/market-radar-scan.ts +0 -41
  243. package/src/market-radar-sources.ts +0 -173
  244. package/src/novel-context.ts +0 -287
  245. package/src/prompt-utils.ts +0 -73
  246. package/src/prompting.ts +0 -159
  247. package/src/protocol.ts +0 -2565
  248. package/src/review-policy.ts +0 -161
  249. package/src/routes.ts +0 -3939
  250. package/src/run.ts +0 -338
  251. package/src/shot-language.ts +0 -181
  252. package/src/story-beat-language.ts +0 -130
  253. package/src/style-library.ts +0 -84
@@ -1,4359 +0,0 @@
1
- /* dsh-novel-forge panel styles (CSS module — auto-injected by the client bundle).
2
- * Uses the real dsh theme alias variables (--dsw-alias-*) so both light and
3
- * dark mode render correctly. */
4
-
5
- /* ---------------------------------------------------------------- palette */
6
-
7
- /* Sidebar entry row (DOM-injected, mirroring family plugins). Lives outside
8
- * the panel root, so it defines its own minimal palette (inherits the shell's
9
- * theme via body[data-ds-dark-theme]). */
10
- .entry {
11
- display: flex;
12
- align-items: center;
13
- gap: var(--nf-space-8, 8px);
14
- width: 100%;
15
- padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
16
- border: none;
17
- background: transparent;
18
- color: var(--dsw-alias-label-primary, #1f1f23);
19
- cursor: pointer;
20
- /* 入口行在 .view 外,令牌不可达,用字面值对齐统一档(主文本 14px) */
21
- font-size: 14px;
22
- text-align: left;
23
- border-radius: var(--nf-radius-6, 6px);
24
- transition: background 0.15s ease;
25
- }
26
-
27
- body[data-ds-dark-theme] .entry {
28
- color: var(--dsw-alias-label-primary, #ececf1);
29
- }
30
-
31
- .entry:hover {
32
- background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.12));
33
- }
34
-
35
- .entry[data-active] {
36
- background: var(--dsw-alias-interactive-bg-active, rgba(127, 127, 127, 0.2));
37
- }
38
-
39
- .entryIcon {
40
- display: inline-flex;
41
- align-items: center;
42
- justify-content: center;
43
- flex-shrink: 0;
44
- width: 20px;
45
- height: 20px;
46
- }
47
-
48
- .entryLabel {
49
- overflow: hidden;
50
- text-overflow: ellipsis;
51
- white-space: nowrap;
52
- }
53
-
54
- /* Center-column overlay shell (mirrors family plugins' view pattern). */
55
- [data-pane="conversation"],
56
- [class*="centerCol"] {
57
- position: relative;
58
- }
59
-
60
- /* The panel root carries its own resolved palette so it never depends on
61
- * inherited alias variables (which live on body / body[data-ds-dark-theme]
62
- * and can be shadowed by the shell). We set local vars per theme here. */
63
- .view {
64
- z-index: 60;
65
- display: none;
66
- position: absolute;
67
- inset: 0;
68
- overflow: auto;
69
- color-scheme: light;
70
- /* 统一 iOS 字体栈:SF Pro + 苹方/冬青黑体中文回退,Windows 回落微软雅黑 */
71
- 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;
72
- --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;
73
- --nf-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
74
- /* iOS light palette (Liquid-Glass green, frosted translucency) */
75
- --nf-bg: rgba(242, 242, 247, 0.86);
76
- --nf-bg-raise: rgba(255, 255, 255, 0.72);
77
- --nf-bg-inset: rgba(118, 118, 128, 0.12);
78
- --nf-border: rgba(60, 60, 67, 0.16);
79
- --nf-border-strong: rgba(60, 60, 67, 0.32);
80
- --nf-text: #1c1c1e;
81
- --nf-text-2: #3c3c43;
82
- --nf-text-2-alpha: rgba(60, 60, 67, 0.68);
83
- --nf-text-3: #8e8e93;
84
- --nf-accent: #00b85c;
85
- --nf-accent-hover: #00a04e;
86
- --nf-accent-soft: rgba(0, 184, 92, 0.12);
87
- --nf-accent-fg: #ffffff;
88
- --nf-hover: rgba(0, 0, 0, 0.05);
89
- --nf-success: #34c759;
90
- --nf-error: #ff3b30;
91
- --nf-warn: #ff9500;
92
- --nf-info: #00b85c;
93
- --nf-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 12px 32px rgba(0, 0, 0, 0.08);
94
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.07), 0 20px 48px rgba(0, 0, 0, 0.12);
95
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.06), 0 14px 38px rgba(0, 0, 0, 0.14);
96
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.08), 0 22px 52px rgba(0, 0, 0, 0.20);
97
- /* Liquid Glass: 薄透玻璃面(透明度以文字清晰为先,保留壁纸透色但不干扰阅读)+ 顶部高光 + 淡描边 */
98
- --nf-glass-face: linear-gradient(180deg, rgba(255, 255, 255, 0.40) 0%, rgba(255, 255, 255, 0.30) 26%, rgba(255, 255, 255, 0.24) 52%, rgba(255, 255, 255, 0.20) 78%, rgba(255, 255, 255, 0.18) 100%);
99
- --nf-glass-core: radial-gradient(60% 40% at 30% 0%, rgba(255, 255, 255, 0.60) 0%, rgba(255, 255, 255, 0.20) 42%, rgba(255, 255, 255, 0) 78%);
100
- --nf-glass-sheen: rgba(255, 255, 255, 0.55);
101
- --nf-glass-border: rgba(255, 255, 255, 0.5);
102
- --nf-glass-inset: rgba(255, 255, 255, 0.4);
103
- --nf-glass-orb-a: rgba(0, 184, 92, 0.24);
104
- --nf-glass-orb-b: rgba(120, 160, 255, 0.20);
105
- --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");
106
- /* 容器形态(主题可覆盖,用于区分 液态玻璃/毛玻璃 等):液态=适圆角+薄玻璃+彩色流光 */
107
- --nf-card-radius: 20px;
108
- --nf-card-blur: 26px;
109
- --nf-card-saturate: 170%;
110
- --nf-card-brightness: 1.04;
111
- --nf-card-sheen: rgba(255, 255, 255, 0.5);
112
- --nf-card-border: 1px solid rgba(255, 255, 255, 0.35);
113
- /* 控件形态(液态:圆润 + 玻璃底 + 强内高光 + 绿色箭头) */
114
- --nf-ctrl-radius: 14px;
115
- --nf-ctrl-bg: var(--nf-bg-raise);
116
- --nf-ctrl-border: 1px solid rgba(255, 255, 255, 0.7);
117
- --nf-ctrl-sheen: rgba(255, 255, 255, 0.5);
118
- --nf-ctrl-caret: var(--nf-accent);
119
- /* 液态:绿→蓝 流光壁纸底 */
120
- --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");
121
- background: var(--nf-bg);
122
- /* Frosted glass: blur whatever is behind the panel (the chat dialog),
123
- * so translucency shows a soft blur instead of readable content. */
124
- -webkit-backdrop-filter: blur(30px) saturate(170%) brightness(1.04);
125
- backdrop-filter: blur(30px) saturate(170%) brightness(1.04);
126
- color: var(--nf-text);
127
- /* ------------------------------------------------------------------
128
- * Unified size tokens (单一尺寸来源).
129
- * 约定:主题(data-nf-theme/data-nf-mode)只改颜色/质感,永不覆盖这些
130
- * 尺寸令牌;界面密度(data-nf-density)是唯一允许重定义尺寸的开关。
131
- * ------------------------------------------------------------------ */
132
- /* 字号档:12=次要文本 / 14=主文本 / 16+ = 标题与大数字 */
133
- --nf-fs-10: 10px;
134
- --nf-fs-12: 12px;
135
- --nf-fs-14: 14px;
136
- --nf-fs-16: 16px;
137
- --nf-fs-18: 18px;
138
- --nf-fs-20: 20px;
139
- --nf-fs-22: 22px;
140
- --nf-fs-24: 24px;
141
- --nf-fs-34: 34px;
142
- --nf-fs-42: 42px;
143
- /* 图标尺寸档 */
144
- --nf-icon-s: 14px;
145
- --nf-icon-m: 16px;
146
- --nf-icon-l: 18px;
147
- --nf-icon-xl: 22px;
148
- /* 间距档 */
149
- --nf-space-2: 2px;
150
- --nf-space-4: 4px;
151
- --nf-space-6: 6px;
152
- --nf-space-8: 8px;
153
- --nf-space-10: 10px;
154
- --nf-space-12: 12px;
155
- --nf-space-14: 14px;
156
- --nf-space-16: 16px;
157
- --nf-space-18: 18px;
158
- --nf-space-20: 20px;
159
- --nf-space-24: 24px;
160
- --nf-space-28: 28px;
161
- --nf-space-32: 32px;
162
- /* 圆角档 */
163
- --nf-radius-2: 2px;
164
- --nf-radius-4: 4px;
165
- --nf-radius-6: 6px;
166
- --nf-radius-8: 8px;
167
- --nf-radius-10: 10px;
168
- --nf-radius-12: 12px;
169
- --nf-radius-14: 14px;
170
- --nf-radius-16: 16px;
171
- --nf-radius-20: 20px;
172
- --nf-radius-22: 22px;
173
- --nf-radius-999: 999px;
174
- /* 控件高度档 */
175
- --nf-ctrl-s: 28px;
176
- --nf-ctrl-m: 32px;
177
- --nf-ctrl-l: 38px;
178
- /* 页面主容器(以设置页为基准)与卡片 */
179
- --nf-container-pad: 20px 22px;
180
- --nf-container-gap: var(--nf-space-14, 14px);
181
- --nf-card-pad: 20px 22px;
182
- --nf-nav-pad: 16px 12px 14px;
183
- }
184
-
185
- /* 深色基准:由面板显示模式驱动(强制 dark / system 跟随宿主深色)。
186
- * 注意 .view 是 .panel 的父容器,承载 background 与 color-scheme,必须同步设深色变量,
187
- * 否则 .panel 设了深色也无法回传给父级 .view → 面板背景永远浅色。
188
- * :has() 用于让 .view 跟随显式强制 dark/light(宿主深色时排除强制 light)。 */
189
- .panel[data-nf-mode='dark'],
190
- body[data-ds-dark-theme] .panel:not([data-nf-mode]),
191
- .view:has(> .panel[data-nf-mode='dark']),
192
- body[data-ds-dark-theme] .view:not(:has(> .panel[data-nf-mode='light'])) {
193
- color-scheme: dark;
194
- /* iOS dark palette — near-black canvas with green Liquid-Glass accents */
195
- --nf-bg: rgba(10, 11, 13, 0.86);
196
- --nf-bg-raise: rgba(28, 28, 30, 0.78);
197
- --nf-bg-inset: rgba(118, 118, 128, 0.18);
198
- --nf-border: rgba(255, 255, 255, 0.12);
199
- --nf-border-strong: rgba(255, 255, 255, 0.28);
200
- --nf-text: #f2f2f7;
201
- --nf-text-2: #d1d1d6;
202
- --nf-text-2-alpha: rgba(209, 209, 214, 0.72);
203
- --nf-text-3: #8e8e93;
204
- --nf-accent: #35d07a;
205
- --nf-accent-hover: #5ce695;
206
- --nf-accent-soft: rgba(53, 208, 122, 0.2);
207
- --nf-accent-fg: #062b18;
208
- --nf-hover: rgba(255, 255, 255, 0.09);
209
- --nf-success: #30d158;
210
- --nf-error: #ff453a;
211
- --nf-warn: #ff9f0a;
212
- --nf-info: #35d07a;
213
- --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px rgba(0, 0, 0, 0.4);
214
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.4), 0 20px 48px rgba(0, 0, 0, 0.55);
215
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 14px 38px rgba(0, 0, 0, 0.45);
216
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.4), 0 22px 52px rgba(0, 0, 0, 0.55);
217
- /* Liquid Glass (dark): 薄透玻璃面(透明度以文字清晰为先)+ 顶部高光 + 淡描边 */
218
- --nf-glass-face: linear-gradient(180deg, rgba(62, 66, 74, 0.52) 0%, rgba(54, 58, 66, 0.46) 26%, rgba(48, 52, 60, 0.40) 52%, rgba(42, 46, 54, 0.36) 78%, rgba(38, 42, 50, 0.34) 100%);
219
- --nf-glass-core: radial-gradient(60% 40% at 30% 0%, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0.08) 42%, rgba(255, 255, 255, 0) 78%);
220
- --nf-glass-sheen: rgba(255, 255, 255, 0.24);
221
- --nf-glass-border: rgba(255, 255, 255, 0.14);
222
- --nf-glass-inset: rgba(255, 255, 255, 0.08);
223
- --nf-glass-orb-a: rgba(0, 202, 82, 0.36);
224
- --nf-glass-orb-b: rgba(120, 160, 255, 0.28);
225
- --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");
226
- /* 深色液态容器形态 */
227
- --nf-card-radius: 20px;
228
- --nf-card-blur: 28px;
229
- --nf-card-saturate: 165%;
230
- --nf-card-brightness: 1;
231
- --nf-card-border: 1px solid rgba(255, 255, 255, 0.14);
232
- --nf-card-sheen: rgba(255, 255, 255, 0.22);
233
- /* 深色液态专用壁纸:压暗浓郁光斑(仅默认液态,macos/neumorph 在各自块覆盖) */
234
- --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");
235
- /* 深色液态控件 */
236
- --nf-ctrl-radius: 14px;
237
- --nf-ctrl-bg: var(--nf-bg-raise);
238
- --nf-ctrl-border: 1px solid rgba(255, 255, 255, 0.18);
239
- --nf-ctrl-sheen: rgba(255, 255, 255, 0.2);
240
- --nf-ctrl-caret: var(--nf-accent);
241
- }
242
-
243
- html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .view {
244
- display: block;
245
- }
246
-
247
- /* ------------------------------------------------------------ themes
248
- * 'liquid' (default): iOS Liquid Glass, green accent — set on .view above.
249
- * 'macos' / 'neumorph' / 'clay' / 'endfield' override below.
250
- */
251
-
252
- /* ------------------------------------------------------------
253
- * 'macos': macOS 玻璃(浅色默认 / 深色亮蓝),强调色随外观自动切换 #007aff / #0a84ff。
254
- * 第二个选择器:深色系统下强制「浅色」显示模式时也能覆盖宿主的深色规则。
255
- * ------------------------------------------------------------ */
256
- .panel[data-nf-theme='macos'],
257
- body[data-ds-dark-theme] .panel[data-nf-mode='light'][data-nf-theme='macos'] {
258
- --nf-bg: rgba(245, 246, 248, 0.92);
259
- --nf-bg-raise: rgba(255, 255, 255, 0.78);
260
- --nf-bg-inset: rgba(118, 118, 128, 0.1);
261
- --nf-border: rgba(60, 60, 67, 0.14);
262
- --nf-border-strong: rgba(60, 60, 67, 0.3);
263
- --nf-text: #1d1d1f;
264
- --nf-text-2: #3a3a3c;
265
- --nf-text-2-alpha: rgba(58, 58, 60, 0.7);
266
- --nf-text-3: #86868b;
267
- --nf-accent: #007aff;
268
- --nf-accent-hover: #0071e3;
269
- --nf-accent-soft: rgba(0, 122, 255, 0.12);
270
- --nf-accent-fg: #ffffff;
271
- --nf-hover: rgba(0, 0, 0, 0.04);
272
- --nf-info: #5856d6;
273
- --nf-shadow: 0 1px 3px rgba(0, 0, 0, 0.05), 0 10px 28px rgba(0, 0, 0, 0.07);
274
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.06), 0 18px 44px rgba(0, 0, 0, 0.11);
275
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.05), 0 12px 34px rgba(0, 0, 0, 0.09);
276
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.07), 0 20px 48px rgba(0, 0, 0, 0.14);
277
- --nf-glass-face: rgba(255, 255, 255, 0.7);
278
- --nf-glass-core: transparent;
279
- --nf-glass-sheen: rgba(255, 255, 255, 0.8);
280
- --nf-glass-border: rgba(255, 255, 255, 0.9);
281
- --nf-glass-inset: rgba(255, 255, 255, 0.6);
282
- --nf-glass-orb-a: rgba(0, 122, 255, 0.08);
283
- --nf-glass-orb-b: rgba(88, 86, 214, 0.07);
284
- --nf-glass-noise: none;
285
- /* macOS 容器:小圆角 + 高模糊低饱和 + 冷描边,玻璃面板质感 */
286
- --nf-card-radius: 12px;
287
- --nf-card-blur: 42px;
288
- --nf-card-saturate: 150%;
289
- --nf-card-border: 1px solid var(--nf-border);
290
- --nf-card-sheen: rgba(255, 255, 255, 0.35);
291
- /* macOS 控件:小圆角 + 玻璃底 + 冷描边 + 蓝色箭头(focus 蓝环见特写) */
292
- --nf-ctrl-radius: 8px;
293
- --nf-ctrl-bg: var(--nf-bg-raise);
294
- --nf-ctrl-border: 1px solid var(--nf-border-strong);
295
- --nf-ctrl-sheen: rgba(255, 255, 255, 0.35);
296
- --nf-ctrl-caret: var(--nf-accent);
297
- }
298
-
299
- .panel[data-nf-mode='dark'][data-nf-theme='macos'],
300
- body[data-ds-dark-theme] .panel[data-nf-theme='macos']:not([data-nf-mode]) {
301
- --nf-bg: rgba(28, 28, 30, 0.9);
302
- --nf-bg-raise: rgba(44, 44, 46, 0.82);
303
- --nf-bg-inset: rgba(118, 118, 128, 0.18);
304
- --nf-border: rgba(255, 255, 255, 0.12);
305
- --nf-border-strong: rgba(255, 255, 255, 0.26);
306
- --nf-text: #f5f5f7;
307
- --nf-text-2: #d1d1d6;
308
- --nf-text-2-alpha: rgba(209, 209, 214, 0.7);
309
- --nf-text-3: #98989d;
310
- --nf-accent: #0a84ff;
311
- --nf-accent-hover: #3a9bff;
312
- --nf-accent-soft: rgba(10, 132, 255, 0.2);
313
- --nf-accent-fg: #ffffff;
314
- --nf-hover: rgba(255, 255, 255, 0.06);
315
- --nf-info: #bf5af2;
316
- --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.45);
317
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45), 0 18px 44px rgba(0, 0, 0, 0.6);
318
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.4), 0 14px 38px rgba(0, 0, 0, 0.5);
319
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.45), 0 22px 52px rgba(0, 0, 0, 0.6);
320
- --nf-glass-face: rgba(44, 44, 46, 0.85);
321
- --nf-glass-core: transparent;
322
- --nf-glass-sheen: rgba(255, 255, 255, 0.2);
323
- --nf-glass-border: rgba(255, 255, 255, 0.18);
324
- --nf-glass-inset: rgba(255, 255, 255, 0.06);
325
- --nf-glass-orb-a: rgba(10, 132, 255, 0.16);
326
- --nf-glass-orb-b: rgba(191, 90, 242, 0.08);
327
- --nf-glass-noise: none;
328
- }
329
-
330
- /* macOS 按钮 / 输入框玻璃化(圆角由基础 .button/.input 引用 --nf-ctrl-radius 形态令牌提供) */
331
- .panel[data-nf-theme='macos'] .button {
332
- border: 1px solid var(--nf-border-strong);
333
- background: color-mix(in srgb, var(--nf-bg-raise) 82%, #fff);
334
- box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.6);
335
- }
336
- .panel[data-nf-theme='macos'] .buttonPrimary {
337
- background: linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 90%, #fff), var(--nf-accent));
338
- border-color: transparent;
339
- color: var(--nf-accent-fg);
340
- box-shadow: 0 1px 3px color-mix(in srgb, var(--nf-accent) 45%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.35);
341
- }
342
- .panel[data-nf-theme='macos'] .input,
343
- .panel[data-nf-theme='macos'] .textarea {
344
- border: 1px solid var(--nf-border-strong);
345
- background: var(--nf-bg-raise);
346
- }
347
- .panel[data-nf-theme='macos'] .input:focus,
348
- .panel[data-nf-theme='macos'] .textarea:focus {
349
- border-color: var(--nf-accent);
350
- box-shadow: 0 0 0 3px var(--nf-accent-soft);
351
- }
352
-
353
- /* ------------------------------------------------------------
354
- * 'neumorph': Neumorphism (dual-shadow soft UI).
355
- * Light variant in light mode; a dark dual-shadow variant in dark
356
- * mode so switching always has a visible effect.
357
- * ------------------------------------------------------------ */
358
- /* 新拟物容器:实色无模糊、较大圆角、无内高光(不依赖深浅,任何模式一致) */
359
- .panel[data-nf-theme='neumorph'] {
360
- --nf-card-radius: 20px;
361
- --nf-card-blur: 0px;
362
- --nf-card-saturate: 100%;
363
- --nf-card-border: none;
364
- --nf-card-sheen: rgba(255, 255, 255, 0);
365
- /* 新拟物控件:实色无模糊 + 较大圆角 + 无内高光(深浅一致) */
366
- --nf-ctrl-radius: 10px;
367
- --nf-ctrl-bg: var(--nf-bg-inset);
368
- --nf-ctrl-border: none;
369
- --nf-ctrl-sheen: rgba(255, 255, 255, 0);
370
- --nf-ctrl-caret: var(--nf-text-3);
371
- /* 新拟物:实色,无玻璃底图 */
372
- --nf-glass-bg-image: none;
373
- }
374
-
375
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] {
376
- --nf-bg: #e4e9f2;
377
- --nf-bg-raise: #e4e9f2;
378
- --nf-bg-inset: #d9dfe8;
379
- --nf-border: rgba(140, 155, 175, 0.35);
380
- --nf-border-strong: rgba(120, 135, 158, 0.5);
381
- --nf-text: #3a4250;
382
- --nf-text-2: #5b6472;
383
- --nf-text-2-alpha: rgba(70, 80, 96, 0.7);
384
- --nf-text-3: #8b94a3;
385
- --nf-hover: rgba(90, 105, 125, 0.08);
386
- --nf-shadow: 4px 4px 10px rgba(163, 177, 198, 0.55), -4px -4px 10px rgba(255, 255, 255, 0.85);
387
- --nf-shadow-lg: 6px 6px 14px rgba(163, 177, 198, 0.6), -6px -6px 14px rgba(255, 255, 255, 0.9);
388
- --nf-card-shadow: 9px 9px 18px rgba(163, 177, 198, 0.55), -9px -9px 18px rgba(255, 255, 255, 0.85);
389
- --nf-card-shadow-hover: 12px 12px 24px rgba(163, 177, 198, 0.65), -12px -12px 24px rgba(255, 255, 255, 0.95);
390
- --nf-glass-face: #e4e9f2;
391
- --nf-glass-core: transparent;
392
- --nf-glass-sheen: rgba(255, 255, 255, 0);
393
- --nf-glass-border: rgba(163, 177, 198, 0.4);
394
- --nf-glass-inset: #d9dfe8;
395
- --nf-glass-orb-a: transparent;
396
- --nf-glass-orb-b: transparent;
397
- --nf-glass-noise: none;
398
- }
399
-
400
- .panel[data-nf-mode='dark'][data-nf-theme='neumorph'],
401
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph']:not([data-nf-mode]) {
402
- --nf-bg: #2b2f36;
403
- --nf-bg-raise: #2b2f36;
404
- --nf-bg-inset: #25292f;
405
- --nf-border: rgba(10, 12, 16, 0.5);
406
- --nf-border-strong: rgba(8, 10, 14, 0.6);
407
- --nf-text: #d6dae1;
408
- --nf-text-2: #a8aeb8;
409
- --nf-text-2-alpha: rgba(168, 174, 184, 0.7);
410
- --nf-text-3: #757c88;
411
- --nf-hover: rgba(255, 255, 255, 0.05);
412
- --nf-shadow: 4px 4px 10px rgba(0, 0, 0, 0.5), -4px -4px 10px rgba(96, 104, 118, 0.24);
413
- --nf-shadow-lg: 6px 6px 14px rgba(0, 0, 0, 0.55), -6px -6px 14px rgba(96, 104, 118, 0.26);
414
- --nf-card-shadow: 9px 9px 18px rgba(0, 0, 0, 0.5), -9px -9px 18px rgba(96, 104, 118, 0.24);
415
- --nf-card-shadow-hover: 12px 12px 24px rgba(0, 0, 0, 0.6), -12px -12px 24px rgba(96, 104, 118, 0.28);
416
- --nf-glass-face: #2b2f36;
417
- --nf-glass-core: transparent;
418
- --nf-glass-sheen: rgba(255, 255, 255, 0);
419
- --nf-glass-border: rgba(12, 14, 18, 0.45);
420
- --nf-glass-inset: #25292f;
421
- --nf-glass-orb-a: transparent;
422
- --nf-glass-orb-b: transparent;
423
- --nf-glass-noise: none;
424
- }
425
- /* ------------------------------------------------------------
426
- * 'clay': Claymorphism(粘土拟态)—— 柔软圆润、同色系软阴影、奶油底色。
427
- * 实心(无 backdrop 模糊)、大圆角、双阴影制造"黏土鼓起"感。
428
- * ------------------------------------------------------------ */
429
- /* 粘土形态(深浅一致):大圆角、无模糊、奶油高光描边、软阴影 */
430
- .panel[data-nf-theme='clay'] {
431
- /* 容器:大圆角 + 实心(关闭玻璃模糊)+ 顶部奶油高光 */
432
- --nf-card-radius: 28px;
433
- --nf-card-blur: 0px;
434
- --nf-card-saturate: 100%;
435
- --nf-card-brightness: 1;
436
- --nf-card-border: 1px solid rgba(255, 255, 255, 0.6);
437
- --nf-card-sheen: rgba(255, 255, 255, 0.85);
438
- /* 控件:圆润 + 同色系软阴影 + 顶部高光 */
439
- --nf-ctrl-radius: 16px;
440
- --nf-ctrl-bg: var(--nf-bg-raise);
441
- --nf-ctrl-border: 1px solid rgba(255, 255, 255, 0.55);
442
- --nf-ctrl-sheen: rgba(255, 255, 255, 0.7);
443
- --nf-ctrl-caret: var(--nf-accent);
444
- /* 粘土为实心:无玻璃壁纸 */
445
- --nf-glass-bg-image: none;
446
- }
447
-
448
- /* 浅色粘土(默认浅色系统 / 强制浅色) */
449
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'],
450
- .panel[data-nf-mode='light'][data-nf-theme='clay'] {
451
- --nf-bg: #f2eae0;
452
- --nf-bg-raise: #efe4d6;
453
- --nf-bg-inset: #e6d8c6;
454
- --nf-border: rgba(120, 96, 72, 0.16);
455
- --nf-border-strong: rgba(120, 96, 72, 0.28);
456
- --nf-text: #3a3330;
457
- --nf-text-2: #5a4f48;
458
- --nf-text-2-alpha: rgba(90, 79, 72, 0.7);
459
- --nf-text-3: #9a8c80;
460
- --nf-accent: #e08a5c;
461
- --nf-accent-hover: #d67a4a;
462
- --nf-accent-soft: rgba(224, 138, 92, 0.16);
463
- --nf-accent-fg: #ffffff;
464
- --nf-hover: rgba(120, 96, 72, 0.08);
465
- --nf-success: #7fae6a;
466
- --nf-error: #c96b63;
467
- --nf-warn: #d9a660;
468
- --nf-info: #e08a5c;
469
- --nf-shadow: 0 8px 16px -6px rgba(90, 70, 50, 0.28), inset 0 6px 10px rgba(255, 255, 255, 0.55), inset 0 -6px 10px rgba(120, 96, 72, 0.12);
470
- --nf-shadow-lg: 0 16px 28px -10px rgba(90, 70, 50, 0.34), inset 0 6px 10px rgba(255, 255, 255, 0.55), inset 0 -6px 10px rgba(120, 96, 72, 0.14);
471
- --nf-card-shadow: 0 16px 28px -10px rgba(90, 70, 50, 0.34), inset 0 -8px 12px rgba(120, 96, 72, 0.14), inset 0 8px 12px rgba(255, 255, 255, 0.6);
472
- --nf-card-shadow-hover: 0 22px 36px -12px rgba(90, 70, 50, 0.38), inset 0 -8px 12px rgba(120, 96, 72, 0.16), inset 0 8px 12px rgba(255, 255, 255, 0.7);
473
- --nf-glass-face: #efe4d6;
474
- --nf-glass-core: transparent;
475
- --nf-glass-sheen: rgba(255, 255, 255, 0.85);
476
- --nf-glass-border: rgba(255, 255, 255, 0.6);
477
- --nf-glass-inset: #e6d8c6;
478
- --nf-glass-orb-a: transparent;
479
- --nf-glass-orb-b: transparent;
480
- --nf-glass-noise: none;
481
- }
482
-
483
- /* 深色粘土(强制深色 / system 深色系统) */
484
- .panel[data-nf-mode='dark'][data-nf-theme='clay'],
485
- body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) {
486
- --nf-bg: #2a2522;
487
- --nf-bg-raise: #37302b;
488
- --nf-bg-inset: #2f2925;
489
- --nf-border: rgba(255, 255, 255, 0.08);
490
- --nf-border-strong: rgba(255, 255, 255, 0.18);
491
- --nf-text: #efe9e3;
492
- --nf-text-2: #c7beb5;
493
- --nf-text-2-alpha: rgba(199, 190, 181, 0.7);
494
- --nf-text-3: #8a8078;
495
- --nf-accent: #e69a6c;
496
- --nf-accent-hover: #f0ac82;
497
- --nf-accent-soft: rgba(230, 154, 108, 0.2);
498
- --nf-accent-fg: #241b16;
499
- --nf-hover: rgba(255, 255, 255, 0.06);
500
- --nf-success: #9cba82;
501
- --nf-error: #d98f86;
502
- --nf-warn: #d9a660;
503
- --nf-info: #e69a6c;
504
- --nf-shadow: 0 8px 16px -6px rgba(0, 0, 0, 0.55), inset 0 6px 10px rgba(255, 255, 255, 0.12), inset 0 -6px 10px rgba(0, 0, 0, 0.35);
505
- --nf-shadow-lg: 0 16px 28px -10px rgba(0, 0, 0, 0.62), inset 0 6px 10px rgba(255, 255, 255, 0.12), inset 0 -6px 10px rgba(0, 0, 0, 0.4);
506
- --nf-card-shadow: 0 16px 28px -10px rgba(0, 0, 0, 0.62), inset 0 -8px 12px rgba(0, 0, 0, 0.4), inset 0 8px 12px rgba(255, 255, 255, 0.14);
507
- --nf-card-shadow-hover: 0 22px 36px -12px rgba(0, 0, 0, 0.68), inset 0 -8px 12px rgba(0, 0, 0, 0.44), inset 0 8px 12px rgba(255, 255, 255, 0.18);
508
- --nf-glass-face: #37302b;
509
- --nf-glass-core: transparent;
510
- --nf-glass-sheen: rgba(255, 255, 255, 0.16);
511
- --nf-glass-border: rgba(255, 255, 255, 0.16);
512
- --nf-glass-inset: #2f2925;
513
- --nf-glass-orb-a: transparent;
514
- --nf-glass-orb-b: transparent;
515
- --nf-glass-noise: none;
516
- }
517
-
518
- /* 粘土输入框:凹陷黏土内阴影(深浅一致,深色下另覆盖) */
519
- .panel[data-nf-theme='clay'] .input,
520
- .panel[data-nf-theme='clay'] .textarea {
521
- background: var(--nf-bg-inset);
522
- border-color: var(--nf-border-strong);
523
- box-shadow: inset 3px 3px 7px rgba(120, 96, 72, 0.14), inset -3px -3px 7px rgba(255, 255, 255, 0.5);
524
- }
525
-
526
- /* 粘土按钮:柔和的"黏土凸起"——外围软投影 + 顶部奶油高光 + 底部厚影 */
527
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'] .button {
528
- border-color: rgba(255, 255, 255, 0.6);
529
- background: linear-gradient(180deg, #f6ecdf, #eee0cf);
530
- box-shadow: 0 8px 16px -6px rgba(90, 70, 50, 0.35), inset 0 3px 4px rgba(255, 255, 255, 0.8), inset 0 -3px 5px rgba(120, 96, 72, 0.2);
531
- }
532
-
533
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'] .button:hover:not([disabled]) {
534
- box-shadow: 0 12px 22px -8px rgba(90, 70, 50, 0.42), inset 0 3px 4px rgba(255, 255, 255, 0.85), inset 0 -3px 5px rgba(120, 96, 72, 0.22);
535
- }
536
-
537
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'] .buttonPrimary {
538
- background: linear-gradient(180deg, #eda178, #e08a5c);
539
- border-color: transparent;
540
- color: var(--nf-accent-fg);
541
- box-shadow: 0 8px 16px -6px rgba(224, 138, 92, 0.55), inset 0 3px 4px rgba(255, 255, 255, 0.5), inset 0 -3px 5px rgba(150, 70, 40, 0.3);
542
- }
543
-
544
- /* 深色粘土按钮 */
545
- .panel[data-nf-mode='dark'][data-nf-theme='clay'] .button,
546
- body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .button {
547
- border-color: rgba(255, 255, 255, 0.16);
548
- background: linear-gradient(180deg, #403731, #332c27);
549
- box-shadow: 0 8px 16px -6px rgba(0, 0, 0, 0.55), inset 0 3px 4px rgba(255, 255, 255, 0.14), inset 0 -3px 5px rgba(0, 0, 0, 0.4);
550
- }
551
-
552
- .panel[data-nf-mode='dark'][data-nf-theme='clay'] .button:hover:not([disabled]),
553
- body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .button:hover:not([disabled]) {
554
- box-shadow: 0 12px 22px -8px rgba(0, 0, 0, 0.6), inset 0 3px 4px rgba(255, 255, 255, 0.16), inset 0 -3px 5px rgba(0, 0, 0, 0.44);
555
- }
556
-
557
- .panel[data-nf-mode='dark'][data-nf-theme='clay'] .buttonPrimary,
558
- body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .buttonPrimary {
559
- background: linear-gradient(180deg, #f0ac82, #d67a4a);
560
- border-color: transparent;
561
- color: var(--nf-accent-fg);
562
- box-shadow: 0 8px 16px -6px rgba(230, 154, 108, 0.5), inset 0 3px 4px rgba(255, 255, 255, 0.4), inset 0 -3px 5px rgba(120, 50, 20, 0.3);
563
- }
564
-
565
- .panel[data-nf-mode='dark'][data-nf-theme='clay'] .input,
566
- .panel[data-nf-mode='dark'][data-nf-theme='clay'] .textarea,
567
- body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .input,
568
- body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) .textarea {
569
- box-shadow: inset 3px 3px 7px rgba(0, 0, 0, 0.45), inset -3px -3px 7px rgba(255, 255, 255, 0.08);
570
- }
571
-
572
-
573
- /* Neumorphic inset inputs (sunken). */
574
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .input,
575
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .textarea {
576
- background: var(--nf-bg-inset);
577
- border-color: transparent;
578
- box-shadow: inset 3px 3px 7px rgba(163, 177, 198, 0.55), inset -3px -3px 7px rgba(255, 255, 255, 0.9);
579
- }
580
-
581
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .input:focus,
582
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .textarea:focus {
583
- border-color: var(--nf-accent);
584
- box-shadow: inset 2px 2px 6px rgba(163, 177, 198, 0.5), inset -2px -2px 6px rgba(255, 255, 255, 0.85), 0 0 0 3px var(--nf-accent-soft);
585
- }
586
-
587
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .input,
588
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .textarea {
589
- background: var(--nf-bg-inset);
590
- border-color: transparent;
591
- box-shadow: inset 3px 3px 7px rgba(0, 0, 0, 0.55), inset -3px -3px 7px rgba(96, 104, 118, 0.24);
592
- }
593
-
594
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .input:focus,
595
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .textarea:focus {
596
- border-color: var(--nf-accent);
597
- box-shadow: inset 2px 2px 6px rgba(0, 0, 0, 0.5), inset -2px -2px 6px rgba(96, 104, 118, 0.22), 0 0 0 3px var(--nf-accent-soft);
598
- }
599
-
600
- /* Neumorphic raised buttons. */
601
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .button {
602
- border-color: transparent;
603
- background: var(--nf-bg-raise);
604
- box-shadow: 5px 5px 10px rgba(163, 177, 198, 0.55), -5px -5px 10px rgba(255, 255, 255, 0.9);
605
- }
606
-
607
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .button:hover:not([disabled]) {
608
- background: var(--nf-bg-raise);
609
- border-color: transparent;
610
- box-shadow: 7px 7px 14px rgba(163, 177, 198, 0.6), -7px -7px 14px rgba(255, 255, 255, 0.95);
611
- }
612
-
613
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .button:active:not([disabled]) {
614
- box-shadow: inset 3px 3px 7px rgba(163, 177, 198, 0.55), inset -3px -3px 7px rgba(255, 255, 255, 0.9);
615
- }
616
-
617
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .buttonPrimary {
618
- background: linear-gradient(180deg, #00c563, #00a952);
619
- box-shadow: 5px 5px 10px rgba(163, 177, 198, 0.6), -5px -5px 10px rgba(255, 255, 255, 0.85);
620
- }
621
-
622
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .button {
623
- border-color: transparent;
624
- background: var(--nf-bg-raise);
625
- box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5), -5px -5px 10px rgba(96, 104, 118, 0.24);
626
- }
627
-
628
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .button:hover:not([disabled]) {
629
- background: var(--nf-bg-raise);
630
- border-color: transparent;
631
- box-shadow: 7px 7px 14px rgba(0, 0, 0, 0.55), -7px -7px 14px rgba(96, 104, 118, 0.26);
632
- }
633
-
634
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .button:active:not([disabled]) {
635
- box-shadow: inset 3px 3px 7px rgba(0, 0, 0, 0.55), inset -3px -3px 7px rgba(96, 104, 118, 0.24);
636
- }
637
-
638
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph'] .buttonPrimary {
639
- background: linear-gradient(180deg, #3ddc86, #27b96a);
640
- box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5), -5px -5px 10px rgba(96, 104, 118, 0.24);
641
- }
642
-
643
- /* ------------------------------------------------------------
644
- * 'endfield': 终末地 / Arknights: Endfield 官网风 —— 奶油纸底、
645
- * 墨黑文字、信号黄/武陵青强调色、全直角工业编辑风。
646
- * 对应 dsh-theme-endfield 插件的设计语言,适配小说工坊的 --nf-* 令牌。
647
- * 强调色由 data-nf-endfield-accent 切换(valley=谷地黄默认 / wuling=武陵青)。
648
- * ------------------------------------------------------------ */
649
- .panel[data-nf-theme='endfield'] {
650
- /* 终末地强调色派生(默认谷地黄) */
651
- --edge-accent: #fff500;
652
- --edge-accent-rgb: 255, 245, 0;
653
- --edge-accent-deep: #e8e000;
654
- --edge-accent-onpaper: #d9c700;
655
- --edge-status-light: #6b5d00;
656
- --edge-status-dark: #fff500;
657
- --edge-status-dark-mid: #a08a00;
658
- /* 全直角工业编辑风 */
659
- --nf-radius-2: 0px;
660
- --nf-radius-4: 0px;
661
- --nf-radius-6: 0px;
662
- --nf-radius-8: 0px;
663
- --nf-radius-10: 0px;
664
- --nf-radius-12: 0px;
665
- --nf-radius-14: 0px;
666
- --nf-radius-16: 0px;
667
- --nf-radius-20: 0px;
668
- --nf-radius-22: 0px;
669
- --nf-radius-999: 0px;
670
- --nf-card-radius: 0px;
671
- --nf-card-blur: 0px;
672
- --nf-card-saturate: 100%;
673
- --nf-card-brightness: 1;
674
- --nf-card-sheen: rgba(0, 0, 0, 0);
675
- --nf-card-border: 1px solid var(--nf-border);
676
- --nf-ctrl-radius: 0px;
677
- --nf-ctrl-sheen: rgba(0, 0, 0, 0);
678
- --nf-ctrl-caret: var(--nf-accent);
679
- --nf-glass-bg-image: none;
680
- --nf-glass-noise: none;
681
- --nf-glass-orb-a: transparent;
682
- --nf-glass-orb-b: transparent;
683
- }
684
-
685
- .panel[data-nf-theme='endfield'][data-nf-endfield-accent='wuling'] {
686
- --edge-accent: #14d0d0;
687
- --edge-accent-rgb: 20, 208, 208;
688
- --edge-accent-deep: #10b8b8;
689
- --edge-accent-onpaper: #14d0d0;
690
- --edge-status-light: #006a6a;
691
- --edge-status-dark: #14d0d0;
692
- --edge-status-dark-mid: #7ee7e7;
693
- }
694
-
695
- /* 浅色:奶油纸 + 墨黑 + 强调色深档(可读性达标) */
696
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='endfield'],
697
- .panel[data-nf-mode='light'][data-nf-theme='endfield'] {
698
- --nf-bg: #e8e8e2;
699
- --nf-bg-raise: #f2f2ec;
700
- --nf-bg-inset: #dcddd6;
701
- --nf-border: #d8d9d5;
702
- --nf-border-strong: #b6b8b3;
703
- --nf-text: #101110;
704
- --nf-text-2: #4a4c48;
705
- --nf-text-2-alpha: rgba(74, 76, 72, 0.7);
706
- --nf-text-3: #7a7d78;
707
- --nf-accent: var(--edge-accent-onpaper);
708
- --nf-accent-hover: var(--edge-accent-deep);
709
- --nf-accent-soft: rgba(var(--edge-accent-rgb), 0.14);
710
- --nf-accent-fg: #101110;
711
- --nf-hover: rgba(var(--edge-accent-rgb), 0.10);
712
- --nf-success: #2f9e44;
713
- --nf-error: #ff3b30;
714
- --nf-warn: #d9822b;
715
- --nf-info: var(--edge-accent-onpaper);
716
- --nf-shadow: 0 1px 3px rgba(0, 0, 0, 0.10), 0 10px 28px rgba(0, 0, 0, 0.08);
717
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.10), 0 18px 44px rgba(0, 0, 0, 0.12);
718
- --nf-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.10), 0 12px 34px rgba(0, 0, 0, 0.08);
719
- --nf-card-shadow-hover: 0 2px 6px rgba(0, 0, 0, 0.12), 0 20px 48px rgba(0, 0, 0, 0.12);
720
- --nf-glass-face: var(--nf-bg-raise);
721
- --nf-glass-core: transparent;
722
- --nf-glass-sheen: rgba(0, 0, 0, 0);
723
- --nf-glass-border: var(--nf-card-border);
724
- --nf-glass-inset: var(--nf-bg-inset);
725
- }
726
-
727
- /* 深色:墨底 + 亮纸字 + 强调色直接使用信号色 */
728
- .panel[data-nf-mode='dark'][data-nf-theme='endfield'],
729
- body[data-ds-dark-theme] .panel[data-nf-theme='endfield']:not([data-nf-mode]) {
730
- --nf-bg: #101110;
731
- --nf-bg-raise: #181a18;
732
- --nf-bg-inset: #1e201d;
733
- --nf-border: #343633;
734
- --nf-border-strong: #4a4d49;
735
- --nf-text: #f5f5f0;
736
- --nf-text-2: #898d89;
737
- --nf-text-2-alpha: rgba(137, 141, 137, 0.7);
738
- --nf-text-3: #6a6d68;
739
- --nf-accent: var(--edge-accent);
740
- --nf-accent-hover: var(--edge-accent-deep);
741
- --nf-accent-soft: rgba(var(--edge-accent-rgb), 0.22);
742
- --nf-accent-fg: #101110;
743
- --nf-hover: rgba(var(--edge-accent-rgb), 0.16);
744
- --nf-success: #4fbf5c;
745
- --nf-error: #ff6b61;
746
- --nf-warn: #ffb700;
747
- --nf-info: var(--edge-accent);
748
- --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.45);
749
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45), 0 18px 44px rgba(0, 0, 0, 0.6);
750
- --nf-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 14px 38px rgba(0, 0, 0, 0.5);
751
- --nf-card-shadow-hover: 0 2px 6px rgba(0, 0, 0, 0.45), 0 22px 52px rgba(0, 0, 0, 0.6);
752
- --nf-glass-face: var(--nf-bg-raise);
753
- --nf-glass-core: transparent;
754
- --nf-glass-sheen: rgba(0, 0, 0, 0);
755
- --nf-glass-border: var(--nf-card-border);
756
- --nf-glass-inset: var(--nf-bg-inset);
757
- }
758
-
759
- /* 终末地输入/按钮:纸墨工业风,无玻璃高光(直角通过 --nf-radius-* 令牌实现) */
760
- .panel[data-nf-theme='endfield'] .button,
761
- .panel[data-nf-theme='endfield'] .input,
762
- .panel[data-nf-theme='endfield'] .textarea {
763
- box-shadow: none;
764
- }
765
-
766
- .panel[data-nf-theme='endfield'] .buttonPrimary {
767
- background: var(--nf-accent);
768
- border-color: transparent;
769
- color: var(--nf-accent-fg);
770
- box-shadow: none;
771
- }
772
-
773
- .panel[data-nf-theme='endfield'] .buttonPrimary:hover:not([disabled]) {
774
- background: var(--nf-accent-hover);
775
- border-color: transparent;
776
- }
777
-
778
- .panel[data-nf-theme='endfield'] .input:focus,
779
- .panel[data-nf-theme='endfield'] .textarea:focus {
780
- border-color: var(--nf-accent);
781
- box-shadow: 0 0 0 2px var(--nf-accent-soft);
782
- }
783
-
784
- /* ------------------------------------------------------------ panel shell */
785
-
786
- .panel {
787
- display: flex;
788
- flex-direction: column;
789
- height: 100%;
790
- min-width: 0;
791
- font-size: var(--nf-fs-14, 14px);
792
- line-height: 1.6;
793
- position: relative;
794
- overflow: hidden;
795
- }
796
-
797
- /* Liquid-Glass backdrop: themed abstract image + colored orbs + vignette behind the frosted cards. */
798
- .panel::before {
799
- content: '';
800
- position: absolute;
801
- inset: 0;
802
- z-index: 0;
803
- pointer-events: none;
804
- background:
805
- 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))),
806
- var(--nf-glass-bg-image, none) center / cover no-repeat,
807
- radial-gradient(46% 36% at 18% 12%, var(--nf-glass-orb-a), transparent 70%),
808
- radial-gradient(52% 42% at 88% 22%, var(--nf-glass-orb-b), transparent 72%),
809
- radial-gradient(120% 95% at 50% 42%, transparent 55%, rgba(2, 2, 3, 0.10) 100%);
810
- }
811
-
812
- /* --- 玻璃主题背后的「抽象壁纸」底图(每主题一种色调,供卡片 blur 出真实玻璃感) --- */
813
- .panel[data-nf-theme='macos'] {
814
- --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");
815
- }
816
-
817
- .panelTitle {
818
- margin: 0;
819
- font-size: var(--nf-fs-16, 16px);
820
- font-weight: 700;
821
- letter-spacing: 0.2px;
822
- display: flex;
823
- align-items: center;
824
- gap: var(--nf-space-8, 8px);
825
- }
826
-
827
- .panelTitle::before {
828
- content: '';
829
- width: 4px;
830
- height: 16px;
831
- border-radius: var(--nf-radius-2, 2px);
832
- background: linear-gradient(180deg, var(--nf-accent), var(--nf-info));
833
- }
834
-
835
- .iconButton {
836
- border: none;
837
- background: transparent;
838
- cursor: pointer;
839
- font-size: var(--nf-fs-16, 16px);
840
- color: var(--nf-text-2);
841
- padding: var(--nf-space-4, 4px) var(--nf-space-10, 9px);
842
- border-radius: var(--nf-radius-10, 9px);
843
- transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
844
- }
845
-
846
- .iconButton:hover {
847
- background: var(--nf-hover);
848
- color: var(--nf-text);
849
- transform: translateY(-1px);
850
- }
851
-
852
- /* ------------------------------------------------------------ tab bar */
853
-
854
- .tabBar {
855
- display: flex;
856
- gap: var(--nf-space-2, 2px);
857
- padding: var(--nf-space-8, 8px) var(--nf-space-14, 14px) 0;
858
- border-bottom: 1px solid var(--nf-border);
859
- flex-shrink: 0;
860
- background: var(--nf-bg-raise);
861
- position: sticky;
862
- top: 45px;
863
- z-index: 4;
864
- }
865
-
866
- .tab {
867
- border: none;
868
- background: transparent;
869
- padding: var(--nf-space-8, 7px) var(--nf-space-14, 13px);
870
- cursor: pointer;
871
- border-radius: var(--nf-radius-8, 8px) var(--nf-radius-8, 8px) 0 0;
872
- font-size: var(--nf-fs-14, 13.5px);
873
- color: var(--nf-text-2);
874
- transition: color 0.15s ease, background 0.15s ease;
875
- position: relative;
876
- font-weight: 500;
877
- }
878
-
879
- .tab:hover {
880
- color: var(--nf-text);
881
- background: var(--nf-hover);
882
- }
883
-
884
- .tab[data-active] {
885
- color: var(--nf-accent);
886
- font-weight: 600;
887
- }
888
-
889
- .tab[data-active]::after {
890
- content: '';
891
- position: absolute;
892
- left: 10px;
893
- right: 10px;
894
- bottom: -1px;
895
- height: 2.5px;
896
- border-radius: var(--nf-radius-2, 2px) var(--nf-radius-2, 2px) 0 0;
897
- background: var(--nf-accent);
898
- }
899
-
900
- .panelContent {
901
- min-width: 0;
902
- flex: 1;
903
- overflow: auto;
904
- padding: var(--nf-container-pad, 20px 22px);
905
- display: flex;
906
- flex-direction: column;
907
- gap: var(--nf-container-gap, 14px);
908
- position: relative;
909
- z-index: 1;
910
- }
911
-
912
- /* ------------------------------------------- body: left nav + content */
913
-
914
- .panelBody {
915
- flex: 1;
916
- min-height: 0;
917
- display: flex;
918
- position: relative;
919
- z-index: 1;
920
- }
921
-
922
- .panelNav {
923
- flex: none;
924
- align-self: stretch;
925
- width: 216px;
926
- display: flex;
927
- flex-direction: column;
928
- gap: var(--nf-space-6, 6px);
929
- margin: 10px 0 10px 12px;
930
- padding: var(--nf-nav-pad, 16px 12px 14px);
931
- border: 1px solid var(--nf-glass-border);
932
- border-radius: var(--nf-radius-16, 18px);
933
- background: var(--nf-glass-face);
934
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
935
- -webkit-backdrop-filter: blur(28px) saturate(175%);
936
- backdrop-filter: blur(28px) saturate(175%);
937
- overflow-y: auto;
938
- transition: width 0.18s ease;
939
- }
940
-
941
- .panelNavCollapsed {
942
- width: 52px;
943
- padding: var(--nf-space-10, 10px) var(--nf-space-6, 6px);
944
- }
945
-
946
- .navGroup {
947
- display: flex;
948
- flex-direction: column;
949
- gap: var(--nf-space-6, 6px);
950
- }
951
-
952
- .navGroupLabel {
953
- font-size: var(--nf-fs-12, 12px);
954
- font-weight: 600;
955
- letter-spacing: 0.8px;
956
- text-transform: uppercase;
957
- color: var(--nf-text-3);
958
- padding: var(--nf-space-12, 12px) var(--nf-space-10, 10px) var(--nf-space-6, 6px);
959
- user-select: none;
960
- }
961
-
962
- .navGroupSep {
963
- height: 1px;
964
- margin: 6px 8px 4px;
965
- background: var(--nf-border);
966
- }
967
-
968
- .navSpacer {
969
- flex: 1;
970
- min-height: 8px;
971
- /* 导航卡片不再拉满全高(align-self: flex-start),此占位仅保留最小间距 */
972
- }
973
-
974
- /* 导航底部:关于(版本 + GitHub + 更新) */
975
- .navAbout {
976
- flex: none;
977
- display: flex;
978
- flex-direction: column;
979
- gap: var(--nf-space-4, 4px);
980
- padding: var(--nf-space-8, 8px) var(--nf-space-6, 6px) var(--nf-space-4, 4px);
981
- border-top: 1px solid var(--nf-border);
982
- margin-top: 4px;
983
- }
984
-
985
- .navAboutRow {
986
- display: flex;
987
- align-items: center;
988
- justify-content: space-between;
989
- gap: var(--nf-space-4, 4px);
990
- border: none;
991
- background: transparent;
992
- cursor: pointer;
993
- font-size: var(--nf-fs-12, 11px);
994
- color: var(--nf-text-3);
995
- padding: var(--nf-space-4, 4px) var(--nf-space-6, 6px);
996
- border-radius: var(--nf-radius-8, 8px);
997
- transition: color 0.15s ease, background 0.15s ease;
998
- text-align: left;
999
- white-space: nowrap;
1000
- }
1001
-
1002
- .navAboutRow:hover {
1003
- color: var(--nf-text);
1004
- background: var(--nf-hover);
1005
- }
1006
-
1007
- .navAboutUpdate {
1008
- border: none;
1009
- background: var(--nf-accent-soft);
1010
- color: var(--nf-accent);
1011
- cursor: pointer;
1012
- font-size: var(--nf-fs-12, 10.5px);
1013
- font-weight: 600;
1014
- padding: var(--nf-space-4, 4px) var(--nf-space-6, 6px);
1015
- border-radius: var(--nf-radius-8, 8px);
1016
- text-align: left;
1017
- white-space: nowrap;
1018
- }
1019
-
1020
- .navAboutUpdate:hover {
1021
- color: var(--nf-accent-hover);
1022
- }
1023
-
1024
- .panelNavCollapsed .navAbout {
1025
- padding: var(--nf-space-6, 6px) var(--nf-space-2, 2px) var(--nf-space-2, 2px);
1026
- align-items: center;
1027
- }
1028
-
1029
- .panelNavCollapsed .navAboutRow {
1030
- justify-content: center;
1031
- padding: var(--nf-space-4, 4px) 0;
1032
- width: 100%;
1033
- }
1034
-
1035
- .navTabBadge {
1036
- margin-left: auto;
1037
- flex: none;
1038
- min-width: 18px;
1039
- height: 18px;
1040
- padding: 0 var(--nf-space-6, 5px);
1041
- border-radius: var(--nf-radius-999, 999px);
1042
- background: var(--nf-accent);
1043
- color: #fff;
1044
- font-size: var(--nf-fs-12, 10.5px);
1045
- font-weight: 700;
1046
- line-height: 18px;
1047
- text-align: center;
1048
- display: inline-block;
1049
- }
1050
-
1051
- .panelNavCollapsed .navTabBadge {
1052
- position: absolute;
1053
- top: 2px;
1054
- right: 2px;
1055
- /* 字号统一为 12px 后,徽标容器同步放大到 18px 避免溢出 */
1056
- min-width: 18px;
1057
- height: 18px;
1058
- line-height: 18px;
1059
- font-size: var(--nf-fs-12, 9px);
1060
- padding: 0 var(--nf-space-6, 5px);
1061
- }
1062
-
1063
- .navTabBadgeDanger {
1064
- background: var(--nf-error);
1065
- }
1066
-
1067
- .navTabBadgeWarn {
1068
- background: var(--nf-warn);
1069
- }
1070
-
1071
- .navTabBadgeDone {
1072
- background: var(--nf-success);
1073
- }
1074
-
1075
- /* 任务进行中:AI进度导航呼吸绿点(不自动弹窗,点击导航查看悬浮窗) */
1076
- .navTabBadgeLive {
1077
- background: var(--nf-success);
1078
- animation: navBadgePulse 1.2s ease-in-out infinite;
1079
- }
1080
- .navTabDot {
1081
- display: inline-block;
1082
- width: 7px;
1083
- height: 7px;
1084
- margin-left: var(--nf-space-4, 4px);
1085
- border-radius: 50%;
1086
- background: var(--nf-success);
1087
- animation: navBadgePulse 1.2s ease-in-out infinite;
1088
- }
1089
-
1090
- @keyframes navBadgePulse {
1091
- 0%, 100% { opacity: 1; transform: scale(1); }
1092
- 50% { opacity: 0.35; transform: scale(0.8); }
1093
- }
1094
-
1095
- .navTab {
1096
- display: flex;
1097
- align-items: center;
1098
- gap: var(--nf-space-10, 10px);
1099
- width: 100%;
1100
- border: 1px solid transparent;
1101
- background: transparent;
1102
- cursor: pointer;
1103
- border-radius: var(--nf-radius-10, 10px);
1104
- padding: var(--nf-space-12, 11px) var(--nf-space-12, 12px);
1105
- font-size: var(--nf-fs-14, 14px);
1106
- color: var(--nf-text-2-alpha, var(--nf-text-2));
1107
- font-weight: 500;
1108
- transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
1109
- position: relative;
1110
- text-align: left;
1111
- white-space: nowrap;
1112
- }
1113
-
1114
- .panelNavCollapsed .navTab {
1115
- justify-content: center;
1116
- padding: var(--nf-space-8, 8px) 0;
1117
- }
1118
-
1119
- .navTab:hover {
1120
- color: var(--nf-text);
1121
- background: var(--nf-hover);
1122
- }
1123
-
1124
- .navTab[data-active] {
1125
- color: var(--nf-accent);
1126
- font-weight: 600;
1127
- background: color-mix(in srgb, var(--nf-text) 8%, transparent);
1128
- border-color: color-mix(in srgb, var(--nf-text) 16%, transparent);
1129
- box-shadow: inset 0 1px 0 color-mix(in srgb, var(--nf-text) 6%, transparent);
1130
- }
1131
-
1132
- .navTab[data-active] .navTabIcon {
1133
- color: var(--nf-accent);
1134
- }
1135
-
1136
- .navTabIcon {
1137
- flex: none;
1138
- width: 22px;
1139
- height: 22px;
1140
- display: inline-flex;
1141
- align-items: center;
1142
- justify-content: center;
1143
- text-align: center;
1144
- font-size: var(--nf-fs-16, 17px);
1145
- line-height: 1;
1146
- }
1147
-
1148
- .navTabLabel {
1149
- overflow: hidden;
1150
- text-overflow: ellipsis;
1151
- }
1152
-
1153
- /* demo 风格:侧栏标题区(Logo + 小说工坊 + 当前书名) */
1154
- .navTitle {
1155
- display: flex;
1156
- align-items: center;
1157
- gap: var(--nf-space-10, 10px);
1158
- padding: var(--nf-space-2, 2px) var(--nf-space-6, 6px) var(--nf-space-12, 12px);
1159
- border-bottom: 1px solid var(--nf-border);
1160
- margin-bottom: 6px;
1161
- flex: none;
1162
- min-width: 0;
1163
- }
1164
-
1165
- .navTitleLogo {
1166
- width: 34px;
1167
- height: 34px;
1168
- border-radius: var(--nf-radius-10, 10px);
1169
- background: linear-gradient(145deg, var(--nf-accent), var(--nf-accent-hover));
1170
- color: var(--nf-accent-fg);
1171
- font-weight: 800;
1172
- font-size: var(--nf-fs-14, 15px);
1173
- display: flex;
1174
- align-items: center;
1175
- justify-content: center;
1176
- flex: none;
1177
- box-shadow: 0 6px 16px var(--nf-accent-soft);
1178
- }
1179
-
1180
- .navTitleName {
1181
- font-weight: 700;
1182
- font-size: var(--nf-fs-14, 15px);
1183
- letter-spacing: 0.2px;
1184
- white-space: nowrap;
1185
- overflow: hidden;
1186
- text-overflow: ellipsis;
1187
- }
1188
-
1189
- .navTitleBook {
1190
- font-size: var(--nf-fs-12, 11px);
1191
- color: var(--nf-text-3);
1192
- white-space: nowrap;
1193
- overflow: hidden;
1194
- text-overflow: ellipsis;
1195
- }
1196
-
1197
- .panelNavCollapsed .navTitle {
1198
- justify-content: center;
1199
- padding: var(--nf-space-2, 2px) 0 var(--nf-space-10, 10px);
1200
- }
1201
-
1202
- .panelNavCollapsed .navTitleLogo {
1203
- width: 32px;
1204
- height: var(--nf-ctrl-m, 32px);
1205
- }
1206
-
1207
- /* 操作行:收起导航 / 关闭面板 */
1208
- .navActions {
1209
- flex: none;
1210
- display: flex;
1211
- gap: var(--nf-space-6, 6px);
1212
- margin-top: 8px;
1213
- padding-top: var(--nf-space-8, 8px);
1214
- border-top: 1px solid var(--nf-border);
1215
- }
1216
-
1217
- .navActionBtn {
1218
- flex: 1;
1219
- border: 1px solid var(--nf-border);
1220
- background: rgba(0, 0, 0, 0);
1221
- color: var(--nf-text-2);
1222
- cursor: pointer;
1223
- border-radius: var(--nf-radius-10, 10px);
1224
- height: var(--nf-ctrl-m, 32px);
1225
- font-size: var(--nf-fs-14, 14px);
1226
- line-height: 1;
1227
- display: inline-flex;
1228
- align-items: center;
1229
- justify-content: center;
1230
- transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
1231
- }
1232
-
1233
- .navActionBtn:hover {
1234
- background: var(--nf-hover);
1235
- color: var(--nf-text);
1236
- border-color: var(--nf-border-strong);
1237
- }
1238
-
1239
- .panelNavCollapsed .navActions {
1240
- flex-direction: column;
1241
- align-items: stretch;
1242
- }
1243
-
1244
- /* demo 风格:底部当前书切换卡(封面首字 + 书名/进度 + 箭头) */
1245
- .bookSwitch {
1246
- flex: none;
1247
- display: flex;
1248
- align-items: center;
1249
- gap: var(--nf-space-8, 8px);
1250
- margin-top: 4px;
1251
- padding: var(--nf-space-10, 9px);
1252
- border-radius: var(--nf-radius-12, 12px);
1253
- background: var(--nf-bg-inset);
1254
- border: 1px solid var(--nf-border);
1255
- cursor: pointer;
1256
- text-align: left;
1257
- font: inherit;
1258
- color: var(--nf-text);
1259
- min-width: 0;
1260
- transition: background 0.15s ease, border-color 0.15s ease;
1261
- }
1262
-
1263
- .bookSwitch:hover {
1264
- background: var(--nf-hover);
1265
- border-color: var(--nf-border-strong);
1266
- }
1267
-
1268
- .bookSwitchCover {
1269
- width: 26px;
1270
- height: 34px;
1271
- border-radius: var(--nf-radius-6, 5px);
1272
- background: linear-gradient(160deg, var(--nf-accent), color-mix(in srgb, var(--nf-accent) 45%, #000));
1273
- color: var(--nf-accent-fg);
1274
- display: flex;
1275
- align-items: center;
1276
- justify-content: center;
1277
- font-size: var(--nf-fs-12, 11px);
1278
- font-weight: 700;
1279
- flex: none;
1280
- }
1281
-
1282
- .bookSwitchName {
1283
- font-size: var(--nf-fs-12, 12.5px);
1284
- font-weight: 600;
1285
- overflow: hidden;
1286
- text-overflow: ellipsis;
1287
- white-space: nowrap;
1288
- }
1289
-
1290
- .bookSwitchMeta {
1291
- font-size: var(--nf-fs-12, 11px);
1292
- color: var(--nf-text-3);
1293
- overflow: hidden;
1294
- text-overflow: ellipsis;
1295
- white-space: nowrap;
1296
- }
1297
-
1298
- .bookSwitchArrow {
1299
- margin-left: auto;
1300
- color: var(--nf-text-3);
1301
- font-size: var(--nf-fs-12, 12px);
1302
- flex: none;
1303
- }
1304
-
1305
- /* demo 风格统计卡(今日待写 / 写作中 / 已通过 / 待审稿) */
1306
- .statRowD { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--nf-space-12, 12px); }
1307
- .statCardD { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--nf-space-10, 10px); padding: var(--nf-space-14, 14px) var(--nf-space-16, 16px); border-radius: var(--nf-radius-16, 16px); background: var(--nf-bg-inset); border: 1px solid var(--nf-border); min-width: 0; }
1308
- .statCardDLabel { font-size: var(--nf-fs-12, 12px); color: var(--nf-text-3); }
1309
- .statCardDValue { font-size: var(--nf-fs-22, 22px); font-weight: 700; margin-top: 2px; color: var(--nf-text); }
1310
- .statCardDUnit { font-size: var(--nf-fs-12, 12px); color: var(--nf-text-3); font-weight: 400; }
1311
- .statCardDDetail { font-size: var(--nf-fs-12, 11.5px); color: var(--nf-text-3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1312
- .statCardDDown { color: var(--nf-error); }
1313
- .statCardDIcon { width: 38px; height: var(--nf-ctrl-l, 38px); border-radius: var(--nf-radius-12, 12px); display: flex; align-items: center; justify-content: center; font-size: var(--nf-fs-18, 18px); flex: none; background: var(--nf-accent-soft); }
1314
- .statCardDIconRed { background: color-mix(in srgb, var(--nf-error) 13%, transparent); }
1315
-
1316
- /* demo 风格创作时间线(6 阶段分段条,点击跳转对应 tab) */
1317
- .tlBar { display: flex; gap: var(--nf-space-6, 6px); margin-top: 8px; }
1318
- .tlSeg { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--nf-space-4, 4px); border: none; background: transparent; padding: 0; cursor: pointer; font: inherit; }
1319
- .tlSegTrack { height: 8px; border-radius: var(--nf-radius-999, 999px); background: var(--nf-hover); border: 1px solid var(--nf-border); overflow: hidden; }
1320
- .tlSegFill { display: block; height: 100%; width: 100%; border-radius: var(--nf-radius-999, 999px); background: var(--nf-accent); }
1321
- .tlSegTodo .tlSegFill { opacity: 0; }
1322
- .tlSegTodo .tlSegTrack { background: transparent; }
1323
- .tlSegCurrent .tlSegTrack { border-color: var(--nf-accent); box-shadow: 0 0 0 2px var(--nf-accent-soft); }
1324
- .tlSegCurrent .tlSegFill { opacity: 0.45; }
1325
- .tlSegLabel { font-size: var(--nf-fs-12, 10.5px); color: var(--nf-text-3); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
1326
- .tlSegDone .tlSegLabel { color: var(--nf-accent); font-weight: 600; }
1327
- .tlSeg:hover .tlSegTrack { border-color: var(--nf-border-strong); }
1328
-
1329
-
1330
- /* ------------------------------------------------------------ cards */
1331
-
1332
- .card {
1333
- position: relative;
1334
- border: var(--nf-card-border, 1px solid var(--nf-glass-border));
1335
- border-radius: var(--nf-card-radius, 22px);
1336
- padding: var(--nf-card-pad, 20px 22px);
1337
- display: flex;
1338
- flex-direction: column;
1339
- gap: var(--nf-space-10, 10px);
1340
- background: var(--nf-glass-face);
1341
- box-shadow:
1342
- var(--nf-card-shadow),
1343
- inset 0 1.5px 0 var(--nf-card-sheen, var(--nf-glass-sheen)),
1344
- inset 0 -1px 0 rgba(255, 255, 255, 0.10);
1345
- -webkit-backdrop-filter: blur(var(--nf-card-blur, 30px)) saturate(var(--nf-card-saturate, 180%)) brightness(var(--nf-card-brightness, 1.06));
1346
- backdrop-filter: blur(var(--nf-card-blur, 30px)) saturate(var(--nf-card-saturate, 180%)) brightness(var(--nf-card-brightness, 1.06));
1347
- transition: transform 0.22s ease, box-shadow 0.22s ease;
1348
- }
1349
-
1350
- /* Liquid-Glass surface: bright core highlight + hairline sheen. */
1351
- .card::before {
1352
- content: '';
1353
- position: absolute;
1354
- inset: 0;
1355
- border-radius: inherit;
1356
- pointer-events: none;
1357
- background:
1358
- var(--nf-glass-core),
1359
- linear-gradient(90deg, transparent, var(--nf-card-sheen, var(--nf-glass-sheen)), transparent) no-repeat 10% 0 / 80% 1px,
1360
- linear-gradient(156deg, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0) 55%);
1361
- z-index: 0;
1362
- }
1363
-
1364
- /* Subtle grain, barely visible. */
1365
- .card::after {
1366
- content: '';
1367
- position: absolute;
1368
- inset: 0;
1369
- border-radius: inherit;
1370
- pointer-events: none;
1371
- background: var(--nf-glass-noise);
1372
- opacity: 0.06;
1373
- z-index: 0;
1374
- }
1375
-
1376
- .card:hover {
1377
- transform: translateY(-3px);
1378
- box-shadow:
1379
- var(--nf-card-shadow-hover),
1380
- inset 0 1.5px 0 var(--nf-card-sheen, var(--nf-glass-sheen)),
1381
- inset 0 -1px 0 rgba(255, 255, 255, 0.25);
1382
- }
1383
-
1384
- .card > * {
1385
- position: relative;
1386
- z-index: 1;
1387
- }
1388
-
1389
- .cardTitle {
1390
- margin: 0;
1391
- font-size: var(--nf-fs-14, 14px);
1392
- font-weight: 650;
1393
- color: var(--nf-text);
1394
- display: flex;
1395
- align-items: center;
1396
- gap: var(--nf-space-8, 8px);
1397
- }
1398
-
1399
- /* ------------------------------------------------------------ buttons */
1400
-
1401
- .button {
1402
- /* 控件形态令牌:按钮与 input/textarea 一致,随主题(液态/粘土/macOS/新拟物)走形状 */
1403
- border: 1px solid var(--nf-ctrl-border, var(--nf-border-strong));
1404
- background: var(--nf-ctrl-bg, var(--nf-bg-inset));
1405
- color: var(--nf-text);
1406
- padding: var(--nf-space-8, 7px) var(--nf-space-16, 15px);
1407
- border-radius: var(--nf-ctrl-radius, 10px);
1408
- cursor: pointer;
1409
- font-size: var(--nf-fs-14, 13px);
1410
- font-weight: 500;
1411
- box-shadow: inset 0 1px 0 var(--nf-ctrl-sheen, rgba(255, 255, 255, 0.09));
1412
- transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
1413
- white-space: nowrap;
1414
- }
1415
-
1416
- .button:hover:not([disabled]) {
1417
- background: var(--nf-hover);
1418
- border-color: var(--nf-border-strong);
1419
- transform: translateY(-1px);
1420
- }
1421
-
1422
- .button:active:not([disabled]) {
1423
- transform: translateY(0) scale(0.97);
1424
- }
1425
-
1426
- .button[disabled] {
1427
- opacity: 0.45;
1428
- cursor: not-allowed;
1429
- }
1430
-
1431
- .buttonPrimary {
1432
- border-color: transparent;
1433
- background: linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #ffffff), var(--nf-accent));
1434
- color: var(--nf-accent-fg);
1435
- border-radius: var(--nf-radius-10, 10px);
1436
- box-shadow: 0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 0.5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.45);
1437
- }
1438
-
1439
- .buttonPrimary:hover:not([disabled]) {
1440
- background: linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000000));
1441
- border-color: transparent;
1442
- transform: translateY(-1px);
1443
- box-shadow: 0 12px 30px color-mix(in srgb, var(--nf-accent) 50%, transparent), 0 0 0 0.5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.45);
1444
- }
1445
-
1446
- .buttonDanger {
1447
- border-color: var(--nf-error);
1448
- color: var(--nf-error);
1449
- }
1450
-
1451
- .buttonDanger:hover:not([disabled]) {
1452
- background: rgba(255, 59, 48, 0.1);
1453
- }
1454
-
1455
- .buttonSmall {
1456
- padding: var(--nf-space-4, 4px) var(--nf-space-10, 10px);
1457
- font-size: var(--nf-fs-12, 12px);
1458
- /* 与常规按钮同一控件形态令牌,保证主题一致 */
1459
- border-radius: var(--nf-ctrl-radius, 8px);
1460
- }
1461
-
1462
- /* ------------------------------------------------------------ forms */
1463
-
1464
- .field {
1465
- display: flex;
1466
- flex-direction: column;
1467
- gap: var(--nf-space-6, 5px);
1468
- }
1469
-
1470
- .fieldLabel {
1471
- font-size: var(--nf-fs-12, 12px);
1472
- color: var(--nf-text-2);
1473
- font-weight: 500;
1474
- }
1475
-
1476
- .input {
1477
- border: var(--nf-ctrl-border, 1px solid var(--nf-border-strong));
1478
- background: var(--nf-ctrl-bg, var(--nf-bg-inset));
1479
- color: var(--nf-text);
1480
- color-scheme: light;
1481
- border-radius: var(--nf-ctrl-radius, 12px);
1482
- padding: var(--nf-space-8, 7px) var(--nf-space-12, 11px);
1483
- font-size: var(--nf-fs-14, 13px);
1484
- width: 100%;
1485
- box-sizing: border-box;
1486
- box-shadow: inset 0 1px 0 var(--nf-ctrl-sheen, rgba(255, 255, 255, 0.09));
1487
- transition: border-color 0.15s ease, box-shadow 0.15s ease;
1488
- }
1489
-
1490
- /* 原生下拉浮层配色跟随主题(防白底白字) */
1491
- body[data-ds-dark-theme] .input {
1492
- color-scheme: dark;
1493
- }
1494
- .panel[data-nf-mode='dark'] .input {
1495
- color-scheme: dark;
1496
- }
1497
- .panel[data-nf-mode='light'] .input {
1498
- color-scheme: light;
1499
- }
1500
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'] .input {
1501
- color-scheme: light;
1502
- }
1503
- select.input {
1504
- cursor: pointer;
1505
- appearance: none;
1506
- -webkit-appearance: none;
1507
- /* 自绘下拉箭头(跟随主题色),去掉浏览器默认黑色 caret */
1508
- background-image:
1509
- linear-gradient(45deg, transparent 50%, var(--nf-ctrl-caret, var(--nf-text-3)) 50%),
1510
- linear-gradient(135deg, var(--nf-ctrl-caret, var(--nf-text-3)) 50%, transparent 50%);
1511
- background-position: calc(100% - 18px) 50%, calc(100% - 12px) 50%;
1512
- background-size: 6px 6px, 6px 6px;
1513
- background-repeat: no-repeat;
1514
- padding-right: 30px;
1515
- }
1516
- .input option {
1517
- color: var(--nf-text);
1518
- background: var(--nf-bg-raise);
1519
- font-size: var(--nf-fs-14, 15px);
1520
- }
1521
-
1522
- .input:focus,
1523
- .textarea:focus {
1524
- outline: none;
1525
- border-color: var(--nf-accent);
1526
- box-shadow: 0 0 0 3px var(--nf-accent-soft);
1527
- }
1528
-
1529
- .input::placeholder,
1530
- .textarea::placeholder {
1531
- color: var(--nf-text-3);
1532
- }
1533
-
1534
- .textarea {
1535
- border: var(--nf-ctrl-border, 1px solid var(--nf-border-strong));
1536
- background: var(--nf-ctrl-bg, var(--nf-bg-inset));
1537
- color: var(--nf-text);
1538
- border-radius: var(--nf-ctrl-radius, 12px);
1539
- padding: var(--nf-space-10, 9px) var(--nf-space-12, 11px);
1540
- font-size: var(--nf-fs-14, 13px);
1541
- width: 100%;
1542
- box-sizing: border-box;
1543
- min-height: 200px;
1544
- font-family: inherit;
1545
- resize: vertical;
1546
- transition: border-color 0.15s ease, box-shadow 0.15s ease;
1547
- line-height: 1.7;
1548
- }
1549
-
1550
- .row {
1551
- display: flex;
1552
- align-items: center;
1553
- gap: var(--nf-space-8, 8px);
1554
- flex-wrap: wrap;
1555
- }
1556
-
1557
- .spaceBetween {
1558
- justify-content: space-between;
1559
- }
1560
-
1561
- /* ------------------------------------------------------------ chapter list */
1562
-
1563
- .chapterList {
1564
- display: flex;
1565
- flex-direction: column;
1566
- gap: var(--nf-space-8, 8px);
1567
- }
1568
-
1569
- /* 章节按卷分组 */
1570
- .volumeGroup {
1571
- display: flex;
1572
- flex-direction: column;
1573
- gap: var(--nf-space-6, 6px);
1574
- }
1575
-
1576
- .volumeGroupHeader {
1577
- display: flex;
1578
- align-items: center;
1579
- gap: var(--nf-space-8, 8px);
1580
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
1581
- border-radius: var(--nf-radius-10, 10px);
1582
- background: var(--nf-bg-inset);
1583
- border: 1px solid var(--nf-border);
1584
- cursor: pointer;
1585
- user-select: none;
1586
- font-size: var(--nf-fs-14, 13px);
1587
- transition: border-color 0.15s ease;
1588
- }
1589
-
1590
- .volumeGroupHeader:hover {
1591
- border-color: var(--nf-accent);
1592
- }
1593
-
1594
- .volumeGroupToggle {
1595
- flex: none;
1596
- font-size: var(--nf-fs-12, 11px);
1597
- color: var(--nf-text-2);
1598
- }
1599
-
1600
- .chapter {
1601
- display: flex;
1602
- align-items: center;
1603
- gap: var(--nf-space-10, 10px);
1604
- padding: var(--nf-space-10, 9px) var(--nf-space-12, 12px);
1605
- border: 1px solid var(--nf-border);
1606
- border-radius: var(--nf-radius-10, 10px);
1607
- background: var(--nf-bg);
1608
- transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
1609
- }
1610
-
1611
- .chapter:hover {
1612
- border-color: var(--nf-border-strong);
1613
- box-shadow: var(--nf-shadow);
1614
- }
1615
-
1616
- /* 待办/主行动卡「定位章节」的目标章:短暂呼吸高亮(3 秒后由 JS 移除)。 */
1617
- .chapterFocus {
1618
- animation: chapterFocusPulse 0.9s ease-in-out 3;
1619
- border-color: var(--nf-accent) !important;
1620
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--nf-accent) 35%, transparent) !important;
1621
- }
1622
-
1623
- @keyframes chapterFocusPulse {
1624
- 0%, 100% { background: var(--nf-bg); }
1625
- 50% { background: color-mix(in srgb, var(--nf-accent) 18%, var(--nf-bg)); }
1626
- }
1627
-
1628
- .chapterNum {
1629
- display: inline-flex;
1630
- align-items: center;
1631
- justify-content: center;
1632
- min-width: 28px;
1633
- height: var(--nf-ctrl-s, 28px);
1634
- padding: 0 var(--nf-space-8, 8px);
1635
- border-radius: var(--nf-radius-8, 8px);
1636
- background: var(--nf-bg-inset);
1637
- border: 1px solid var(--nf-border);
1638
- font-size: var(--nf-fs-12, 12px);
1639
- font-weight: 700;
1640
- color: var(--nf-text-2);
1641
- flex-shrink: 0;
1642
- }
1643
-
1644
- .chapterMain {
1645
- flex: 1;
1646
- min-width: 0;
1647
- }
1648
-
1649
- .chapterTitle {
1650
- font-weight: 600;
1651
- font-size: var(--nf-fs-14, 13px);
1652
- display: flex;
1653
- align-items: center;
1654
- gap: var(--nf-space-8, 8px);
1655
- color: var(--nf-text);
1656
- }
1657
-
1658
- .chapterBeats {
1659
- font-size: var(--nf-fs-12, 12px);
1660
- color: var(--nf-text-2);
1661
- opacity: 0.85;
1662
- overflow: hidden;
1663
- text-overflow: ellipsis;
1664
- white-space: nowrap;
1665
- }
1666
-
1667
- .chapterActions {
1668
- display: flex;
1669
- gap: var(--nf-space-4, 4px);
1670
- flex-shrink: 0;
1671
- opacity: 0.85;
1672
- transition: opacity 0.15s ease;
1673
- }
1674
-
1675
- .chapter:hover .chapterActions {
1676
- opacity: 1;
1677
- }
1678
-
1679
- /* ------------------------------------------------------------ badges */
1680
-
1681
- .badge {
1682
- font-size: var(--nf-fs-12, 11px);
1683
- padding: var(--nf-space-2, 2px) var(--nf-space-10, 9px);
1684
- border-radius: var(--nf-radius-999, 999px);
1685
- border: 1px solid;
1686
- white-space: nowrap;
1687
- font-weight: 600;
1688
- letter-spacing: 0.2px;
1689
- }
1690
-
1691
- .badgePending {
1692
- color: var(--nf-info);
1693
- border-color: var(--nf-info);
1694
- background: color-mix(in srgb, var(--nf-info) 10%, transparent);
1695
- }
1696
-
1697
- .badgeGenerating {
1698
- color: var(--nf-accent);
1699
- border-color: var(--nf-accent);
1700
- background: color-mix(in srgb, var(--nf-accent) 12%, transparent);
1701
- animation: pulse 1.2s ease-in-out infinite;
1702
- }
1703
-
1704
- .badgeWritten {
1705
- color: var(--nf-warn);
1706
- border-color: var(--nf-warn);
1707
- background: color-mix(in srgb, var(--nf-warn) 10%, transparent);
1708
- }
1709
-
1710
- .badgeRejected {
1711
- color: var(--nf-error);
1712
- border-color: var(--nf-error);
1713
- background: color-mix(in srgb, var(--nf-error) 10%, transparent);
1714
- }
1715
-
1716
- .badgeDone {
1717
- color: var(--nf-success);
1718
- border-color: var(--nf-success);
1719
- background: color-mix(in srgb, var(--nf-success) 10%, transparent);
1720
- }
1721
-
1722
- .badgeError {
1723
- color: var(--nf-error);
1724
- border-color: var(--nf-error);
1725
- background: color-mix(in srgb, var(--nf-error) 10%, transparent);
1726
- }
1727
-
1728
- /* ------------------------------------------------------------ review & preview */
1729
-
1730
- .reviewBox {
1731
- border: 1px solid var(--nf-border);
1732
- border-radius: var(--nf-radius-10, 10px);
1733
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
1734
- background: var(--nf-bg-inset);
1735
- display: flex;
1736
- flex-direction: column;
1737
- gap: var(--nf-space-6, 6px);
1738
- font-size: var(--nf-fs-12, 12.5px);
1739
- }
1740
-
1741
- .chapterPreview {
1742
- max-height: 320px;
1743
- overflow: auto;
1744
- white-space: pre-wrap;
1745
- word-break: break-all;
1746
- font-size: var(--nf-fs-12, 12.5px);
1747
- line-height: 1.8;
1748
- font-family: inherit;
1749
- color: var(--nf-text);
1750
- background: var(--nf-bg-inset);
1751
- border: 1px solid var(--nf-border);
1752
- border-radius: var(--nf-radius-10, 10px);
1753
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
1754
- margin: 0;
1755
- }
1756
-
1757
- /* ------------------------------------------------------------ assistant chat */
1758
-
1759
- .chatScroll {
1760
- flex: 1;
1761
- min-height: 0;
1762
- overflow-y: auto;
1763
- display: flex;
1764
- flex-direction: column;
1765
- gap: var(--nf-space-10, 10px);
1766
- padding: var(--nf-space-14, 14px);
1767
- border: 1px solid var(--nf-border);
1768
- border-radius: var(--nf-radius-12, 12px);
1769
- background: var(--nf-bg-inset);
1770
- }
1771
-
1772
- .chatBubbleUser {
1773
- align-self: flex-end;
1774
- max-width: 72%;
1775
- background: linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));
1776
- color: var(--nf-accent-fg);
1777
- border-radius: var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-4, 4px) var(--nf-radius-14, 14px);
1778
- padding: var(--nf-space-10, 9px) var(--nf-space-14, 14px);
1779
- font-size: var(--nf-fs-14, 13px);
1780
- box-shadow: 0 2px 6px rgba(77, 107, 254, 0.2);
1781
- }
1782
-
1783
- .chatBubbleAssistant {
1784
- align-self: flex-start;
1785
- max-width: 92%;
1786
- background: var(--nf-bg-raise);
1787
- color: var(--nf-text);
1788
- border: 1px solid var(--nf-border);
1789
- border-radius: var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-4, 4px);
1790
- padding: var(--nf-space-10, 9px) var(--nf-space-14, 14px);
1791
- font-size: var(--nf-fs-14, 13px);
1792
- box-shadow: var(--nf-shadow);
1793
- }
1794
-
1795
- .chatRole {
1796
- font-size: var(--nf-fs-12, 11px);
1797
- color: var(--nf-text-3);
1798
- margin-bottom: 3px;
1799
- font-weight: 600;
1800
- }
1801
-
1802
- /* Live tool output (text streaming while a chapter is generated/rewritten). */
1803
- .toolLive {
1804
- margin-top: 6px;
1805
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
1806
- border-radius: var(--nf-radius-8, 8px);
1807
- background: var(--nf-bg-inset);
1808
- border: 1px dashed var(--nf-border-strong);
1809
- font-size: var(--nf-fs-12, 12px);
1810
- line-height: 1.7;
1811
- white-space: pre-wrap;
1812
- word-break: break-all;
1813
- color: var(--nf-text-2);
1814
- max-height: 180px;
1815
- overflow-y: auto;
1816
- }
1817
-
1818
- /* 助手状态条:编辑老师正在做什么 */
1819
- .assistantStatus {
1820
- flex: none;
1821
- margin-top: 6px;
1822
- padding: var(--nf-space-6, 6px) var(--nf-space-12, 12px);
1823
- border-radius: var(--nf-radius-999, 999px);
1824
- font-size: var(--nf-fs-12, 12px);
1825
- color: var(--nf-text-2);
1826
- background: var(--nf-bg-inset);
1827
- border: 1px solid var(--nf-border);
1828
- display: flex;
1829
- align-items: center;
1830
- gap: var(--nf-space-6, 6px);
1831
- }
1832
-
1833
- .assistantStatusBusy {
1834
- color: var(--nf-accent);
1835
- border-color: var(--nf-accent);
1836
- background: var(--nf-accent-soft);
1837
- font-weight: 600;
1838
- }
1839
-
1840
- /* 工具步骤卡片 */
1841
- .toolSteps {
1842
- display: flex;
1843
- flex-direction: column;
1844
- gap: var(--nf-space-4, 4px);
1845
- margin-top: 6px;
1846
- }
1847
-
1848
- .toolStep {
1849
- display: flex;
1850
- align-items: center;
1851
- gap: var(--nf-space-8, 8px);
1852
- padding: var(--nf-space-6, 5px) var(--nf-space-10, 10px);
1853
- border-radius: var(--nf-radius-8, 8px);
1854
- font-size: var(--nf-fs-12, 12px);
1855
- background: var(--nf-bg-inset);
1856
- border: 1px solid var(--nf-border);
1857
- }
1858
-
1859
- .toolStepActive {
1860
- border-color: var(--nf-accent);
1861
- background: var(--nf-accent-soft);
1862
- }
1863
-
1864
- .toolStepError {
1865
- border-color: var(--nf-error);
1866
- background: color-mix(in srgb, var(--nf-error) 8%, transparent);
1867
- }
1868
-
1869
- .toolStepIcon {
1870
- flex: none;
1871
- font-size: var(--nf-fs-14, 13px);
1872
- }
1873
-
1874
- .toolStepName {
1875
- flex: 1;
1876
- min-width: 0;
1877
- font-weight: 600;
1878
- overflow: hidden;
1879
- text-overflow: ellipsis;
1880
- white-space: nowrap;
1881
- }
1882
-
1883
- .toolStepStatus {
1884
- flex: none;
1885
- color: var(--nf-text-2);
1886
- font-size: var(--nf-fs-12, 11px);
1887
- }
1888
-
1889
- .toolStepActive .toolStepStatus {
1890
- color: var(--nf-accent);
1891
- }
1892
-
1893
- .toolStepError .toolStepStatus {
1894
- color: var(--nf-error);
1895
- }
1896
-
1897
- .toolStepDetail {
1898
- width: 100%;
1899
- color: var(--nf-error);
1900
- font-size: var(--nf-fs-12, 11px);
1901
- word-break: break-all;
1902
- }
1903
-
1904
- /* ------------------------------------------------------------ progress console */
1905
-
1906
- .progress {
1907
- border: 1px solid var(--nf-border);
1908
- border-radius: var(--nf-radius-10, 10px);
1909
- padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
1910
- font-size: var(--nf-fs-12, 12px);
1911
- min-height: 60px;
1912
- max-height: 220px;
1913
- overflow: auto;
1914
- white-space: pre-wrap;
1915
- word-break: break-all;
1916
- color: var(--nf-text-2);
1917
- font-family: var(--nf-font-mono);
1918
- background: var(--nf-bg-inset);
1919
- line-height: 1.8;
1920
- }
1921
-
1922
- .progressLine {
1923
- color: var(--nf-text-2);
1924
- opacity: 0.9;
1925
- }
1926
-
1927
- .progressLineLive {
1928
- color: var(--nf-accent);
1929
- font-weight: 600;
1930
- display: flex;
1931
- align-items: center;
1932
- gap: var(--nf-space-8, 8px);
1933
- }
1934
-
1935
- .progressBar {
1936
- display: inline-block;
1937
- flex: none;
1938
- width: 110px;
1939
- height: 6px;
1940
- border-radius: var(--nf-radius-999, 999px);
1941
- background: var(--nf-border);
1942
- overflow: hidden;
1943
- }
1944
-
1945
- .progressBarFill {
1946
- display: block;
1947
- height: 100%;
1948
- border-radius: var(--nf-radius-4, 3px);
1949
- background: var(--nf-accent);
1950
- transition: width 0.3s ease;
1951
- }
1952
-
1953
- /* Prominent top-of-panel generation progress (visible on every tab). */
1954
- .busyRow {
1955
- display: flex;
1956
- align-items: center;
1957
- justify-content: space-between;
1958
- gap: var(--nf-space-12, 12px);
1959
- flex-wrap: wrap;
1960
- }
1961
-
1962
- .liveText {
1963
- font-size: var(--nf-fs-12, 12px);
1964
- font-variant-numeric: tabular-nums;
1965
- color: var(--nf-text-2);
1966
- }
1967
-
1968
- .bigProgressBar {
1969
- margin-top: 10px;
1970
- height: 8px;
1971
- border-radius: var(--nf-radius-999, 999px);
1972
- background: var(--nf-border);
1973
- overflow: hidden;
1974
- }
1975
-
1976
- .bigProgressBarFill {
1977
- display: block;
1978
- height: 100%;
1979
- border-radius: var(--nf-radius-999, 999px);
1980
- background: linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2, var(--nf-accent)));
1981
- transition: width 0.3s ease;
1982
- }
1983
-
1984
- /* Draft-vs-original diff view (polish / rewrite comparison). */
1985
- .diffLegend {
1986
- display: flex;
1987
- align-items: center;
1988
- gap: var(--nf-space-14, 14px);
1989
- flex-wrap: wrap;
1990
- margin: 6px 0 8px;
1991
- font-size: var(--nf-fs-12, 12px);
1992
- }
1993
-
1994
- .legendOld {
1995
- color: var(--nf-error);
1996
- font-weight: 700;
1997
- }
1998
-
1999
- .legendNew {
2000
- color: var(--nf-success);
2001
- font-weight: 700;
2002
- }
2003
-
2004
- .onlyChanges {
2005
- display: inline-flex;
2006
- align-items: center;
2007
- gap: var(--nf-space-4, 4px);
2008
- color: var(--nf-text-2);
2009
- cursor: pointer;
2010
- margin-left: auto;
2011
- }
2012
-
2013
- .diffList {
2014
- flex: 1;
2015
- min-height: 0;
2016
- overflow-y: auto;
2017
- border: 1px solid var(--nf-border);
2018
- border-radius: var(--nf-radius-8, 8px);
2019
- background: var(--nf-bg-inset);
2020
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
2021
- display: flex;
2022
- flex-direction: column;
2023
- gap: var(--nf-space-8, 8px);
2024
- font-size: var(--nf-fs-14, 13px);
2025
- line-height: 1.7;
2026
- }
2027
-
2028
- .diffSame {
2029
- border: 1px dashed var(--nf-border);
2030
- border-radius: var(--nf-radius-6, 6px);
2031
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
2032
- color: var(--nf-text-2);
2033
- opacity: 0.85;
2034
- }
2035
-
2036
- .diffSame summary {
2037
- cursor: pointer;
2038
- font-size: var(--nf-fs-12, 12px);
2039
- user-select: none;
2040
- }
2041
-
2042
- .diffSameBody {
2043
- margin-top: 6px;
2044
- white-space: pre-wrap;
2045
- }
2046
-
2047
- /* change 块:左右两栏(左原稿 / 右新稿),带标签徽标 */
2048
- .diffChange {
2049
- display: grid;
2050
- grid-template-columns: 1fr 1fr;
2051
- border: 1px solid var(--nf-border);
2052
- border-radius: var(--nf-radius-8, 8px);
2053
- overflow: hidden;
2054
- }
2055
-
2056
- .diffColumn {
2057
- display: flex;
2058
- flex-direction: column;
2059
- gap: var(--nf-space-6, 6px);
2060
- min-width: 0;
2061
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
2062
- }
2063
-
2064
- .diffColumn:first-child {
2065
- border-right: 1px solid var(--nf-border);
2066
- }
2067
-
2068
- .diffTagOld,
2069
- .diffTagNew {
2070
- align-self: flex-start;
2071
- flex: none;
2072
- font-size: var(--nf-fs-12, 11px);
2073
- font-weight: 700;
2074
- border-radius: var(--nf-radius-4, 4px);
2075
- padding: var(--nf-space-2, 1px) var(--nf-space-8, 7px);
2076
- letter-spacing: 0.5px;
2077
- }
2078
-
2079
- .diffTagOld {
2080
- color: var(--nf-error);
2081
- background: color-mix(in srgb, var(--nf-error) 16%, transparent);
2082
- border: 1px solid color-mix(in srgb, var(--nf-error) 45%, transparent);
2083
- }
2084
-
2085
- .diffTagNew {
2086
- color: var(--nf-success);
2087
- background: color-mix(in srgb, var(--nf-success) 16%, transparent);
2088
- border: 1px solid color-mix(in srgb, var(--nf-success) 45%, transparent);
2089
- }
2090
-
2091
- .diffOld {
2092
- color: var(--nf-error);
2093
- white-space: pre-wrap;
2094
- text-decoration: line-through;
2095
- text-decoration-color: color-mix(in srgb, var(--nf-error) 55%, transparent);
2096
- }
2097
-
2098
- .diffNew {
2099
- color: var(--nf-success);
2100
- white-space: pre-wrap;
2101
- font-weight: 500;
2102
- }
2103
-
2104
- .diffDel {
2105
- display: flex;
2106
- flex-direction: column;
2107
- gap: var(--nf-space-4, 4px);
2108
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
2109
- border-radius: var(--nf-radius-6, 6px);
2110
- border: 1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);
2111
- background: color-mix(in srgb, var(--nf-error) 7%, transparent);
2112
- }
2113
-
2114
- .diffAdd {
2115
- display: flex;
2116
- flex-direction: column;
2117
- gap: var(--nf-space-4, 4px);
2118
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
2119
- border-radius: var(--nf-radius-6, 6px);
2120
- border: 1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);
2121
- background: color-mix(in srgb, var(--nf-success) 7%, transparent);
2122
- }
2123
-
2124
- .diffText {
2125
- white-space: pre-wrap;
2126
- }
2127
-
2128
- .diffDel .diffText {
2129
- color: var(--nf-error);
2130
- text-decoration: line-through;
2131
- text-decoration-color: color-mix(in srgb, var(--nf-error) 50%, transparent);
2132
- }
2133
-
2134
- .diffAdd .diffText {
2135
- color: var(--nf-success);
2136
- }
2137
-
2138
- /* Chapter editor page: full-bleed, flex-fills the content pane (no card box). */
2139
- .wsPage {
2140
- display: flex;
2141
- flex-direction: column;
2142
- flex: 1;
2143
- min-height: 0;
2144
- gap: var(--nf-space-10, 10px);
2145
- }
2146
-
2147
- .wsPageHeader {
2148
- display: flex;
2149
- align-items: center;
2150
- gap: var(--nf-space-8, 8px);
2151
- flex: none;
2152
- flex-wrap: wrap;
2153
- }
2154
-
2155
- /* 已采纳草稿的结论横幅(工作区顶部)。 */
2156
- .wsAppliedBanner {
2157
- flex: none;
2158
- display: flex;
2159
- align-items: center;
2160
- gap: var(--nf-space-8, 8px);
2161
- flex-wrap: wrap;
2162
- padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
2163
- border: 1px solid var(--nf-success);
2164
- border-radius: var(--nf-radius-10, 10px);
2165
- background: color-mix(in srgb, var(--nf-success) 8%, transparent);
2166
- font-size: var(--nf-fs-12, 12px);
2167
- font-weight: 600;
2168
- }
2169
-
2170
- .wsColumns {
2171
- display: grid;
2172
- grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
2173
- gap: var(--nf-space-14, 14px);
2174
- flex: 1;
2175
- min-height: 0;
2176
- }
2177
-
2178
- .wsColumn {
2179
- display: flex;
2180
- flex-direction: column;
2181
- gap: var(--nf-space-8, 8px);
2182
- min-width: 0;
2183
- min-height: 0;
2184
- }
2185
-
2186
- .wsEditor {
2187
- flex: 1;
2188
- min-height: 0;
2189
- resize: vertical;
2190
- font-family: var(--nf-font);
2191
- font-size: var(--nf-fs-14, 13px);
2192
- line-height: 1.75;
2193
- white-space: pre-wrap;
2194
- }
2195
-
2196
- .wsSelected {
2197
- border: 1px solid var(--nf-accent);
2198
- border-radius: var(--nf-radius-6, 6px);
2199
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
2200
- background: color-mix(in srgb, var(--nf-accent) 8%, transparent);
2201
- max-height: 120px;
2202
- overflow: auto;
2203
- }
2204
-
2205
- .wsSelectedText {
2206
- margin-top: 4px;
2207
- font-size: var(--nf-fs-12, 12px);
2208
- color: var(--nf-text-2);
2209
- white-space: pre-wrap;
2210
- }
2211
-
2212
- .wsPreview {
2213
- border: 1px solid var(--nf-border);
2214
- border-radius: var(--nf-radius-8, 8px);
2215
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
2216
- display: flex;
2217
- flex-direction: column;
2218
- gap: var(--nf-space-8, 8px);
2219
- background: var(--nf-bg-inset);
2220
- }
2221
-
2222
- .wsPreviewText {
2223
- margin: 0;
2224
- flex: 1;
2225
- min-height: 0;
2226
- overflow: auto;
2227
- font-size: var(--nf-fs-14, 13px);
2228
- line-height: 1.7;
2229
- white-space: pre-wrap;
2230
- color: var(--nf-text);
2231
- }
2232
-
2233
- /* Assets overview status grid (AI-Novel-Writing-Assistant AssetLibraryStatusGrid). */
2234
- .assetGrid {
2235
- display: grid;
2236
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
2237
- gap: var(--nf-space-10, 10px);
2238
- }
2239
-
2240
- /* 按分类分组的资产列表 */
2241
- .assetGroups {
2242
- display: flex;
2243
- flex-direction: column;
2244
- gap: var(--nf-space-14, 14px);
2245
- }
2246
- .assetGroup {
2247
- display: flex;
2248
- flex-direction: column;
2249
- gap: var(--nf-space-10, 10px);
2250
- }
2251
- .assetGroupHeader {
2252
- font-size: 14px;
2253
- font-weight: 600;
2254
- color: var(--nf-accent);
2255
- padding-bottom: 2px;
2256
- border-bottom: 1px solid var(--nf-glass-border);
2257
- display: flex;
2258
- align-items: center;
2259
- gap: 8px;
2260
- }
2261
-
2262
- .assetStat {
2263
- border: 1px solid var(--nf-glass-border);
2264
- border-radius: var(--nf-radius-14, 14px);
2265
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
2266
- display: flex;
2267
- flex-direction: column;
2268
- gap: var(--nf-space-4, 4px);
2269
- background: var(--nf-glass-face);
2270
- box-shadow: var(--nf-card-shadow), inset 0 1px 0 var(--nf-glass-sheen);
2271
- -webkit-backdrop-filter: blur(30px) saturate(180%);
2272
- backdrop-filter: blur(30px) saturate(180%);
2273
- transition: transform 0.22s ease, box-shadow 0.22s ease;
2274
- }
2275
-
2276
- .assetStat:hover {
2277
- transform: translateY(-3px);
2278
- box-shadow: var(--nf-card-shadow-hover), inset 0 1px 0 var(--nf-glass-sheen);
2279
- }
2280
-
2281
- .assetStatLabel {
2282
- font-size: var(--nf-fs-12, 11px);
2283
- color: var(--nf-text-2);
2284
- opacity: 0.9;
2285
- }
2286
-
2287
- .assetStatValue {
2288
- font-size: var(--nf-fs-14, 15px);
2289
- font-weight: 700;
2290
- line-height: 1.2;
2291
- color: var(--nf-text);
2292
- }
2293
-
2294
- .assetStatDetail {
2295
- font-size: var(--nf-fs-12, 11px);
2296
- color: var(--nf-text-2);
2297
- opacity: 0.85;
2298
- overflow: hidden;
2299
- text-overflow: ellipsis;
2300
- white-space: nowrap;
2301
- }
2302
-
2303
- /* ------------------------------------------------ dashboard (workflow tab) */
2304
-
2305
- .dashHero {
2306
- position: relative;
2307
- border: 1px solid var(--nf-glass-border);
2308
- border-radius: var(--nf-radius-22, 22px);
2309
- /* 主容器统一:与设置页卡片同一 --nf-card-pad */
2310
- padding: var(--nf-card-pad, 20px 22px);
2311
- background: var(--nf-glass-face);
2312
- box-shadow:
2313
- var(--nf-card-shadow),
2314
- inset 0 1.5px 0 var(--nf-glass-sheen),
2315
- inset 0 -1px 0 rgba(255, 255, 255, 0.25);
2316
- -webkit-backdrop-filter: blur(30px) saturate(180%);
2317
- backdrop-filter: blur(30px) saturate(180%);
2318
- display: flex;
2319
- flex-direction: column;
2320
- gap: var(--nf-space-14, 14px);
2321
- transition: transform 0.22s ease, box-shadow 0.22s ease;
2322
- }
2323
-
2324
- /* Same Liquid-Glass surface as .card: bright core + hairline + green tint. */
2325
- .dashHero::before {
2326
- content: '';
2327
- position: absolute;
2328
- inset: 0;
2329
- border-radius: inherit;
2330
- pointer-events: none;
2331
- background:
2332
- radial-gradient(46% 40% at 92% -10%, color-mix(in srgb, var(--nf-accent) 13%, transparent), transparent 62%),
2333
- var(--nf-glass-core),
2334
- linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px,
2335
- linear-gradient(156deg, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0) 55%);
2336
- z-index: 0;
2337
- }
2338
-
2339
- .dashHero::after {
2340
- content: '';
2341
- position: absolute;
2342
- inset: 0;
2343
- border-radius: inherit;
2344
- pointer-events: none;
2345
- background: var(--nf-glass-noise);
2346
- opacity: 0.06;
2347
- z-index: 0;
2348
- }
2349
-
2350
- .dashHero:hover {
2351
- transform: translateY(-3px);
2352
- box-shadow:
2353
- var(--nf-card-shadow-hover),
2354
- inset 0 1.5px 0 var(--nf-glass-sheen),
2355
- inset 0 -1px 0 rgba(255, 255, 255, 0.25);
2356
- }
2357
-
2358
- .dashHero > * {
2359
- position: relative;
2360
- z-index: 1;
2361
- }
2362
-
2363
- .dashHeroEyebrow {
2364
- display: inline-flex;
2365
- align-items: center;
2366
- gap: var(--nf-space-6, 6px);
2367
- font-size: var(--nf-fs-14, 13px);
2368
- font-weight: 600;
2369
- color: var(--nf-accent);
2370
- }
2371
-
2372
- .dashHeroSparkle {
2373
- font-size: var(--nf-fs-14, 14px);
2374
- }
2375
-
2376
- .dashHeroTitle {
2377
- display: flex;
2378
- flex-direction: column;
2379
- gap: var(--nf-space-2, 2px);
2380
- }
2381
-
2382
- .dashHeroBook {
2383
- margin: 0;
2384
- font-size: var(--nf-fs-24, 24px);
2385
- font-weight: 700;
2386
- letter-spacing: -0.3px;
2387
- line-height: 1.25;
2388
- }
2389
-
2390
- .dashHeroAction {
2391
- display: flex;
2392
- align-items: center;
2393
- gap: var(--nf-space-12, 12px);
2394
- border: 1px solid var(--nf-glass-border);
2395
- border-radius: var(--nf-radius-14, 14px);
2396
- background: var(--nf-glass-inset);
2397
- box-shadow: inset 0 1px 0 var(--nf-glass-sheen);
2398
- padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
2399
- }
2400
-
2401
- .dashHeroArrow {
2402
- flex: none;
2403
- width: 28px;
2404
- height: var(--nf-ctrl-s, 28px);
2405
- border-radius: 50%;
2406
- background: var(--nf-accent);
2407
- color: #fff;
2408
- display: inline-flex;
2409
- align-items: center;
2410
- justify-content: center;
2411
- font-size: var(--nf-fs-14, 14px);
2412
- }
2413
-
2414
- .dashHeroActionBody {
2415
- flex: 1;
2416
- min-width: 0;
2417
- display: flex;
2418
- flex-direction: column;
2419
- gap: var(--nf-space-2, 2px);
2420
- }
2421
-
2422
- .dashHeroActionTitle {
2423
- font-size: var(--nf-fs-14, 14px);
2424
- font-weight: 600;
2425
- }
2426
-
2427
- .dashJourney {
2428
- display: flex;
2429
- flex-direction: column;
2430
- gap: var(--nf-space-6, 6px);
2431
- }
2432
-
2433
- .dashJourneyBar {
2434
- height: 6px;
2435
- border-radius: var(--nf-radius-999, 999px);
2436
- background: var(--nf-border);
2437
- overflow: hidden;
2438
- }
2439
-
2440
- .dashJourneyFill {
2441
- display: block;
2442
- height: 100%;
2443
- border-radius: var(--nf-radius-999, 999px);
2444
- background: linear-gradient(90deg, var(--nf-info), var(--nf-accent));
2445
- transition: width 0.4s ease;
2446
- }
2447
-
2448
- .dashJourneyStages {
2449
- display: grid;
2450
- grid-template-columns: repeat(6, minmax(0, 1fr));
2451
- gap: var(--nf-space-4, 4px);
2452
- }
2453
-
2454
- .dashStage {
2455
- display: flex;
2456
- flex-direction: column;
2457
- align-items: center;
2458
- gap: var(--nf-space-4, 3px);
2459
- font-size: var(--nf-fs-12, 11px);
2460
- color: var(--nf-text-3);
2461
- text-align: center;
2462
- white-space: nowrap;
2463
- }
2464
-
2465
- .dashStageDot {
2466
- width: 18px;
2467
- height: 18px;
2468
- border-radius: 50%;
2469
- border: 1px solid var(--nf-border-strong, var(--nf-text-3));
2470
- display: inline-flex;
2471
- align-items: center;
2472
- justify-content: center;
2473
- font-size: var(--nf-fs-12, 10px);
2474
- background: var(--nf-bg-base);
2475
- }
2476
-
2477
- .dashStageDone {
2478
- color: var(--nf-text-2);
2479
- }
2480
-
2481
- .dashStageDone .dashStageDot {
2482
- background: var(--nf-success);
2483
- border-color: var(--nf-success);
2484
- color: #fff;
2485
- }
2486
-
2487
- .dashStageCurrent {
2488
- color: var(--nf-accent);
2489
- font-weight: 600;
2490
- }
2491
-
2492
- .dashStageCurrent .dashStageDot {
2493
- border-color: var(--nf-accent);
2494
- color: var(--nf-accent);
2495
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--nf-accent) 18%, transparent);
2496
- }
2497
-
2498
- .dashFacts {
2499
- display: grid;
2500
- grid-template-columns: repeat(4, minmax(0, 1fr));
2501
- gap: var(--nf-space-8, 8px);
2502
- border-top: 1px solid var(--nf-border);
2503
- padding-top: var(--nf-space-12, 12px);
2504
- }
2505
-
2506
- .dashFact {
2507
- display: flex;
2508
- flex-direction: column;
2509
- gap: var(--nf-space-2, 2px);
2510
- min-width: 0;
2511
- }
2512
-
2513
- .dashFact b {
2514
- font-size: var(--nf-fs-14, 13px);
2515
- white-space: nowrap;
2516
- overflow: hidden;
2517
- text-overflow: ellipsis;
2518
- }
2519
-
2520
- .dashGrid {
2521
- display: grid;
2522
- grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
2523
- gap: var(--nf-space-14, 14px);
2524
- align-items: start;
2525
- }
2526
-
2527
- .todoItem {
2528
- display: flex;
2529
- align-items: center;
2530
- gap: var(--nf-space-10, 10px);
2531
- border-radius: var(--nf-radius-8, 8px);
2532
- padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
2533
- font-size: var(--nf-fs-12, 12.5px);
2534
- border: 1px solid var(--nf-border);
2535
- }
2536
-
2537
- .todoDanger {
2538
- border-color: color-mix(in srgb, var(--nf-error) 40%, transparent);
2539
- background: color-mix(in srgb, var(--nf-error) 8%, transparent);
2540
- }
2541
-
2542
- .todoWarning {
2543
- border-color: color-mix(in srgb, var(--nf-warn) 40%, transparent);
2544
- background: color-mix(in srgb, var(--nf-warn) 8%, transparent);
2545
- }
2546
-
2547
- .todoInfo {
2548
- border-color: color-mix(in srgb, var(--nf-info) 40%, transparent);
2549
- background: color-mix(in srgb, var(--nf-info) 7%, transparent);
2550
- }
2551
-
2552
- .todoText {
2553
- flex: 1;
2554
- min-width: 0;
2555
- display: flex;
2556
- flex-direction: column;
2557
- gap: var(--nf-space-2, 2px);
2558
- }
2559
-
2560
- /* 只读大纲(开书后的出生证明) */
2561
- .outlineReadonly {
2562
- margin: 0;
2563
- padding: var(--nf-space-12, 12px) var(--nf-space-14, 14px);
2564
- border: 1px solid var(--nf-border);
2565
- border-radius: var(--nf-radius-12, 12px);
2566
- background: var(--nf-bg-inset);
2567
- font-size: var(--nf-fs-12, 12.5px);
2568
- line-height: 1.8;
2569
- white-space: pre-wrap;
2570
- max-height: 480px;
2571
- overflow: auto;
2572
- user-select: text;
2573
- }
2574
-
2575
- /* 开书向导表单 */
2576
- .bookCreateOutline {
2577
- display: flex;
2578
- flex-direction: column;
2579
- gap: var(--nf-space-6, 6px);
2580
- align-items: flex-start;
2581
- }
2582
-
2583
- /* AI 助手悬浮窗:可拖动移动 + 右下角拉大小 */
2584
- .assistantFloat {
2585
- position: absolute;
2586
- z-index: 80;
2587
- display: flex;
2588
- flex-direction: column;
2589
- border: 1px solid var(--nf-border);
2590
- border-radius: var(--nf-radius-16, 16px);
2591
- background: var(--nf-bg-raise);
2592
- -webkit-backdrop-filter: blur(24px) saturate(180%);
2593
- backdrop-filter: blur(24px) saturate(180%);
2594
- box-shadow: var(--nf-shadow-lg);
2595
- overflow: hidden;
2596
- min-width: 320px;
2597
- min-height: 220px;
2598
- }
2599
-
2600
- .assistantFloatHeader {
2601
- flex: none;
2602
- display: flex;
2603
- align-items: center;
2604
- justify-content: space-between;
2605
- gap: var(--nf-space-8, 8px);
2606
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px) var(--nf-space-8, 8px) var(--nf-space-14, 14px);
2607
- cursor: grab;
2608
- user-select: none;
2609
- font-size: var(--nf-fs-14, 13px);
2610
- font-weight: 600;
2611
- border-bottom: 1px solid var(--nf-border);
2612
- background: var(--nf-bg-inset);
2613
- }
2614
-
2615
- .assistantFloatHeader:active {
2616
- cursor: grabbing;
2617
- }
2618
-
2619
- .assistantFloatBody {
2620
- flex: 1;
2621
- min-height: 0;
2622
- overflow: hidden;
2623
- display: flex;
2624
- padding: var(--nf-space-10, 10px);
2625
- }
2626
-
2627
- .assistantFloatBody > * {
2628
- flex: 1;
2629
- min-width: 0;
2630
- }
2631
-
2632
- .assistantResize {
2633
- position: absolute;
2634
- right: 0;
2635
- bottom: 0;
2636
- width: 20px;
2637
- height: 20px;
2638
- cursor: nwse-resize;
2639
- background:
2640
- linear-gradient(135deg, transparent 0 55%, var(--nf-border-strong) 55% 62%, transparent 62%) no-repeat 4px 4px / 12px 12px;
2641
- }
2642
-
2643
- /* 封面预览:完整显示(contain),不裁剪 */
2644
- .coverPreview {
2645
- flex: none;
2646
- width: 150px;
2647
- height: 200px;
2648
- border: 1px solid var(--nf-border);
2649
- border-radius: var(--nf-radius-12, 12px);
2650
- overflow: hidden;
2651
- background: var(--nf-bg-inset);
2652
- display: flex;
2653
- align-items: center;
2654
- justify-content: center;
2655
- }
2656
-
2657
- .coverPreview img {
2658
- width: 100%;
2659
- height: 100%;
2660
- object-fit: contain;
2661
- display: block;
2662
- }
2663
-
2664
- .coverPlaceholder {
2665
- font-size: var(--nf-fs-12, 12px);
2666
- color: var(--nf-text-3);
2667
- }
2668
-
2669
- /* ------------------------------------------------------------ shelf view */
2670
-
2671
- .shelfView {
2672
- flex: 1;
2673
- min-height: 0;
2674
- overflow: auto;
2675
- padding: var(--nf-container-pad, 20px 22px);
2676
- display: flex;
2677
- flex-direction: column;
2678
- gap: var(--nf-container-gap, 14px);
2679
- }
2680
-
2681
- /* ---- 作者级首页(书架左侧导航 + 内容区) ---- */
2682
- .authorHome {
2683
- display: flex;
2684
- flex: 1;
2685
- min-height: 0;
2686
- overflow: hidden;
2687
- position: relative;
2688
- z-index: 1;
2689
- }
2690
- .authorRail {
2691
- width: 180px;
2692
- flex-shrink: 0;
2693
- display: flex;
2694
- flex-direction: column;
2695
- gap: 4px;
2696
- padding: 14px 10px;
2697
- border-right: 1px solid var(--nf-glass-border);
2698
- background: var(--nf-glass-face);
2699
- }
2700
- .authorRailTitle {
2701
- display: flex;
2702
- align-items: center;
2703
- gap: 8px;
2704
- font-weight: 600;
2705
- padding: 4px 8px 12px;
2706
- color: var(--nf-accent);
2707
- }
2708
- .authorRailBtn {
2709
- display: flex;
2710
- align-items: center;
2711
- gap: 10px;
2712
- padding: 8px 12px;
2713
- border-radius: 10px;
2714
- background: transparent;
2715
- border: 1px solid transparent;
2716
- color: var(--nf-text);
2717
- cursor: pointer;
2718
- text-align: left;
2719
- width: 100%;
2720
- font-size: 14px;
2721
- }
2722
- .authorRailBtn:hover { background: color-mix(in srgb, var(--nf-accent) 12%, transparent); color: var(--nf-text); }
2723
- .authorRailBtnActive {
2724
- background: color-mix(in srgb, var(--nf-accent) 16%, var(--nf-glass-face));
2725
- border-color: var(--nf-accent);
2726
- color: var(--nf-accent);
2727
- font-weight: 600;
2728
- box-shadow: inset 0 0 0 1px var(--nf-accent);
2729
- }
2730
- .authorRailAbout { padding: 8px 12px; }
2731
- .authorContent { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
2732
-
2733
- /* ---- 作者级页面通用 ---- */
2734
- .authorPageBody {
2735
- display: flex;
2736
- flex-direction: column;
2737
- gap: 14px;
2738
- padding: var(--nf-container-pad, 20px 22px);
2739
- overflow: auto;
2740
- flex: 1;
2741
- min-height: 0;
2742
- }
2743
- .authorPageHeader {
2744
- display: flex;
2745
- align-items: flex-end;
2746
- justify-content: space-between;
2747
- gap: 14px;
2748
- flex-wrap: wrap;
2749
- }
2750
- .authorPageHero {
2751
- display: flex;
2752
- flex-direction: column;
2753
- gap: var(--nf-space-12, 12px);
2754
- padding: var(--nf-card-pad, 20px 22px);
2755
- border: 1px solid var(--nf-glass-border);
2756
- border-radius: var(--nf-radius-22, 22px);
2757
- background: var(--nf-glass-face);
2758
- box-shadow: var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);
2759
- -webkit-backdrop-filter: blur(26px) saturate(175%);
2760
- backdrop-filter: blur(26px) saturate(175%);
2761
- }
2762
- .noticeError {
2763
- padding: 10px 14px;
2764
- border-radius: 10px;
2765
- background: color-mix(in srgb, var(--nf-error) 14%, transparent);
2766
- color: var(--nf-error);
2767
- border: 1px solid var(--nf-error);
2768
- }
2769
- .noticeSuccess {
2770
- display: flex;
2771
- align-items: center;
2772
- gap: 10px;
2773
- flex-wrap: wrap;
2774
- padding: 10px 14px;
2775
- border-radius: 10px;
2776
- background: color-mix(in srgb, var(--nf-accent) 14%, transparent);
2777
- color: var(--nf-accent);
2778
- border: 1px solid var(--nf-accent);
2779
- }
2780
- .rowEnd { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
2781
-
2782
- /* ---- 作者资产库 ---- */
2783
- .assetFilterBar { display: flex; flex-wrap: wrap; gap: 8px; }
2784
- .assetFilterChip {
2785
- padding: 4px 10px;
2786
- border-radius: 999px;
2787
- border: 1px solid var(--nf-glass-border);
2788
- background: transparent;
2789
- color: var(--nf-text);
2790
- cursor: pointer;
2791
- }
2792
- .assetFilterChipActive { background: var(--nf-accent); color: #fff; border-color: transparent; }
2793
- .assetEditor {
2794
- display: flex;
2795
- flex-direction: column;
2796
- gap: 12px;
2797
- padding: 16px;
2798
- border: 1px solid var(--nf-glass-border);
2799
- border-radius: 14px;
2800
- background: var(--nf-glass-face);
2801
- }
2802
- .assetEditorRow { display: flex; gap: 12px; flex-wrap: wrap; }
2803
- .assetLabel {
2804
- display: flex;
2805
- flex-direction: column;
2806
- gap: 4px;
2807
- font-size: 12px;
2808
- color: var(--nf-muted);
2809
- flex: 1;
2810
- min-width: 180px;
2811
- }
2812
- .assetTextarea { min-height: 160px; resize: vertical; font-family: inherit; }
2813
- .assetGrid {
2814
- display: grid;
2815
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
2816
- gap: 14px;
2817
- }
2818
- .assetCard {
2819
- display: flex;
2820
- flex-direction: column;
2821
- gap: 8px;
2822
- padding: 14px;
2823
- border: 1px solid var(--nf-glass-border);
2824
- border-radius: 14px;
2825
- background: var(--nf-glass-face);
2826
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
2827
- }
2828
- .assetCardTop { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
2829
- .assetKind { font-size: 12px; font-weight: 600; }
2830
- .assetCardName { font-weight: 600; }
2831
- .assetCardContent { white-space: pre-wrap; font-size: 13px; color: var(--nf-text); max-height: 150px; overflow: auto; }
2832
- .assetCardFooter { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
2833
- .iconBtn {
2834
- display: inline-flex;
2835
- align-items: center;
2836
- justify-content: center;
2837
- padding: 4px;
2838
- border: 1px solid transparent;
2839
- background: transparent;
2840
- border-radius: 8px;
2841
- color: var(--nf-text);
2842
- cursor: pointer;
2843
- }
2844
- .iconBtn:hover { background: rgba(0,0,0,0.06); }
2845
-
2846
- /* ---- 改编模式 ---- */
2847
- .adaptInputCard {
2848
- display: flex;
2849
- flex-direction: column;
2850
- gap: 12px;
2851
- padding: 16px;
2852
- border: 1px solid var(--nf-glass-border);
2853
- border-radius: 14px;
2854
- background: var(--nf-glass-face);
2855
- }
2856
- .adaptTextarea { min-height: 220px; resize: vertical; }
2857
- .adaptResult { display: flex; flex-direction: column; gap: 14px; }
2858
- .adaptOutline {
2859
- padding: 10px 14px;
2860
- border-radius: 12px;
2861
- background: var(--nf-glass-face);
2862
- border: 1px solid var(--nf-glass-border);
2863
- }
2864
- .adaptMatrix {
2865
- display: grid;
2866
- grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
2867
- gap: 12px;
2868
- }
2869
- .dimCard {
2870
- display: flex;
2871
- flex-direction: column;
2872
- gap: 8px;
2873
- padding: 14px;
2874
- border: 1px solid var(--nf-glass-border);
2875
- border-radius: 14px;
2876
- background: var(--nf-glass-face);
2877
- }
2878
- .dimCardHead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
2879
- .dimTitle { font-weight: 600; }
2880
- .dimCurrent { font-size: 13px; white-space: pre-wrap; }
2881
- .dimCardSelected { border-color: var(--nf-accent); box-shadow: 0 0 0 1px var(--nf-accent); }
2882
- .dimEdit { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
2883
- .adaptOutlinePre { white-space: pre-wrap; font-size: 13px; max-height: 260px; overflow: auto; margin: 0; font-family: inherit; }
2884
- .adaptProposal {
2885
- display: flex;
2886
- flex-direction: column;
2887
- gap: 8px;
2888
- padding: 14px;
2889
- border: 1px solid var(--nf-glass-border);
2890
- border-radius: 14px;
2891
- background: var(--nf-glass-face);
2892
- }
2893
- .adaptTable { width: 100%; border-collapse: collapse; font-size: 13px; }
2894
- .adaptTable th, .adaptTable td { border: 1px solid var(--nf-glass-border); padding: 6px 8px; text-align: left; }
2895
- .adaptImpacts { display: flex; flex-direction: column; gap: 4px; }
2896
- .adaptImpact { font-size: 13px; }
2897
- .adaptTableScroll { overflow-x: auto; }
2898
- .adaptCell { min-width: 90px; width: 100%; }
2899
- .adaptRules { display: flex; flex-direction: column; gap: 10px; }
2900
- .adaptRule { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border: 1px solid var(--nf-glass-border); border-radius: 12px; background: var(--nf-glass-face); }
2901
- .adaptRuleRow { display: flex; align-items: center; gap: 8px; }
2902
-
2903
- /* ---- 首页 AI 进度 ---- */
2904
- .progressOverview {
2905
- display: grid;
2906
- grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
2907
- gap: 12px;
2908
- }
2909
- .progressOverviewCard {
2910
- display: flex;
2911
- flex-direction: column;
2912
- gap: 4px;
2913
- padding: 14px;
2914
- border: 1px solid var(--nf-glass-border);
2915
- border-radius: 14px;
2916
- background: var(--nf-glass-face);
2917
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
2918
- }
2919
- .progressOverviewNum {
2920
- font-size: 24px;
2921
- font-weight: 700;
2922
- color: var(--nf-accent);
2923
- }
2924
- .progressTotalBar {
2925
- position: relative;
2926
- height: 14px;
2927
- border-radius: 999px;
2928
- background: var(--nf-glass-face);
2929
- border: 1px solid var(--nf-glass-border);
2930
- overflow: hidden;
2931
- }
2932
- .progressTotalFill {
2933
- position: absolute;
2934
- inset: 0 auto 0 0;
2935
- height: 100%;
2936
- background: linear-gradient(90deg, var(--nf-accent), var(--nf-info));
2937
- border-radius: 999px;
2938
- }
2939
- .progressTotalBar .meta {
2940
- position: absolute;
2941
- inset: 0;
2942
- display: flex;
2943
- align-items: center;
2944
- justify-content: center;
2945
- font-size: 11px;
2946
- font-weight: 600;
2947
- color: var(--nf-text);
2948
- }
2949
- .progressBookList {
2950
- display: flex;
2951
- flex-direction: column;
2952
- gap: 12px;
2953
- }
2954
- .progressBook {
2955
- display: flex;
2956
- flex-direction: column;
2957
- gap: 8px;
2958
- padding: 14px;
2959
- border: 1px solid var(--nf-glass-border);
2960
- border-radius: 14px;
2961
- background: var(--nf-glass-face);
2962
- }
2963
- .progressBookActive { border-color: var(--nf-accent); box-shadow: 0 0 0 1px var(--nf-accent); }
2964
- .progressBookHead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
2965
- .progressBookName { font-weight: 600; }
2966
- .progressLive { color: var(--nf-accent); font-weight: 600; }
2967
- .progressBookBar { height: 8px; border-radius: 999px; background: var(--nf-glass-face-hover, rgba(0,0,0,0.05)); overflow: hidden; }
2968
- .progressBookFill { height: 100%; background: var(--nf-accent); border-radius: 999px; }
2969
-
2970
- .shelfHeader {
2971
- display: flex;
2972
- flex-direction: column;
2973
- gap: var(--nf-space-10, 10px);
2974
- }
2975
-
2976
- /* 书架顶部主容器:加高玻璃卡 */
2977
- .shelfHero {
2978
- display: flex;
2979
- flex-direction: column;
2980
- gap: var(--nf-space-14, 14px);
2981
- padding: var(--nf-card-pad, 20px 22px);
2982
- border: 1px solid var(--nf-glass-border);
2983
- border-radius: var(--nf-radius-22, 22px);
2984
- background: var(--nf-glass-face);
2985
- box-shadow: var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);
2986
- }
2987
-
2988
- .shelfHero .panelTitle {
2989
- font-size: var(--nf-fs-22, 22px);
2990
- letter-spacing: 0.3px;
2991
- }
2992
-
2993
- .shelfTitleRow {
2994
- display: flex;
2995
- align-items: center;
2996
- justify-content: space-between;
2997
- gap: var(--nf-space-10, 10px);
2998
- flex-wrap: wrap;
2999
- }
3000
-
3001
- .shelfToolbar {
3002
- display: flex;
3003
- align-items: center;
3004
- gap: var(--nf-space-10, 10px);
3005
- flex-wrap: wrap;
3006
- }
3007
-
3008
- .shelfSearch {
3009
- flex: 1;
3010
- min-width: 180px;
3011
- max-width: 320px;
3012
- }
3013
-
3014
- .shelfStats {
3015
- display: grid;
3016
- grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
3017
- gap: var(--nf-space-10, 10px);
3018
- }
3019
-
3020
- .shelfStat {
3021
- display: flex;
3022
- align-items: baseline;
3023
- justify-content: space-between;
3024
- gap: var(--nf-space-8, 8px);
3025
- padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
3026
- border: 1px solid var(--nf-glass-border);
3027
- border-radius: var(--nf-radius-14, 14px);
3028
- background: var(--nf-glass-face);
3029
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
3030
- cursor: pointer;
3031
- user-select: none;
3032
- transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
3033
- }
3034
-
3035
- .shelfStat:hover {
3036
- border-color: var(--nf-accent);
3037
- transform: translateY(-1px);
3038
- }
3039
-
3040
- .shelfStatActive {
3041
- border-color: var(--nf-accent);
3042
- background: var(--nf-accent-soft);
3043
- box-shadow: 0 0 0 2px var(--nf-accent-soft), var(--nf-shadow);
3044
- }
3045
-
3046
- .shelfStat b {
3047
- font-size: var(--nf-fs-20, 20px);
3048
- font-weight: 800;
3049
- color: var(--nf-accent);
3050
- }
3051
-
3052
- .shelfStat span {
3053
- font-size: var(--nf-fs-12, 12px);
3054
- color: var(--nf-text-2);
3055
- }
3056
-
3057
- /* 筛选:胶囊分段控件 */
3058
- .shelfFilters {
3059
- display: inline-flex;
3060
- gap: var(--nf-space-2, 2px);
3061
- padding: var(--nf-space-4, 3px);
3062
- border: 1px solid var(--nf-border);
3063
- border-radius: var(--nf-radius-999, 999px);
3064
- background: var(--nf-bg-inset);
3065
- }
3066
-
3067
- .shelfFilter {
3068
- border: none;
3069
- background: transparent;
3070
- color: var(--nf-text-2);
3071
- font-size: var(--nf-fs-12, 12.5px);
3072
- font-weight: 600;
3073
- padding: var(--nf-space-6, 5px) var(--nf-space-12, 12px);
3074
- border-radius: var(--nf-radius-999, 999px);
3075
- cursor: pointer;
3076
- display: inline-flex;
3077
- align-items: center;
3078
- gap: var(--nf-space-6, 5px);
3079
- white-space: nowrap;
3080
- transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
3081
- }
3082
-
3083
- .shelfFilter:hover {
3084
- color: var(--nf-text);
3085
- }
3086
-
3087
- .shelfFilterActive {
3088
- background: linear-gradient(135deg, var(--nf-accent), var(--nf-accent-hover));
3089
- color: var(--nf-accent-fg);
3090
- box-shadow: 0 3px 12px color-mix(in srgb, var(--nf-accent) 40%, transparent);
3091
- }
3092
-
3093
- .shelfFilterCount {
3094
- font-size: var(--nf-fs-12, 10.5px);
3095
- opacity: 0.8;
3096
- background: color-mix(in srgb, currentColor 14%, transparent);
3097
- border-radius: var(--nf-radius-999, 999px);
3098
- padding: 0 var(--nf-space-6, 6px);
3099
- }
3100
-
3101
- /* 书架空态 / 无结果引导卡 */
3102
- .shelfEmpty {
3103
- flex: 1;
3104
- display: flex;
3105
- flex-direction: column;
3106
- align-items: center;
3107
- justify-content: center;
3108
- gap: var(--nf-space-10, 10px);
3109
- padding: var(--nf-space-40, 40px) var(--nf-space-20, 20px);
3110
- border: 1px dashed var(--nf-border-strong);
3111
- border-radius: var(--nf-radius-16, 16px);
3112
- background: var(--nf-bg-raise);
3113
- -webkit-backdrop-filter: blur(24px) saturate(180%);
3114
- backdrop-filter: blur(24px) saturate(180%);
3115
- text-align: center;
3116
- }
3117
-
3118
- .shelfEmptyIcon {
3119
- font-size: var(--nf-fs-42, 42px);
3120
- }
3121
-
3122
- .shelfEmptyTitle {
3123
- font-size: var(--nf-fs-16, 16px);
3124
- font-weight: 700;
3125
- }
3126
-
3127
- .shelfGrid {
3128
- display: grid;
3129
- grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
3130
- gap: var(--nf-container-gap, 14px);
3131
- align-content: start;
3132
- }
3133
-
3134
- /* ------------------------------------------------------------
3135
- * 外观设置扩展:强制显示模式 + 界面密度 + 主题暗色覆盖
3136
- * ------------------------------------------------------------ */
3137
- /* 界面密度:唯一允许重定义尺寸的开关(主题永不触碰这些令牌)。
3138
- * comfort = 设置页主容器基准;compact/spacious 只缩放令牌,不改组件。 */
3139
- .panel {
3140
- --nf-container-pad: 20px 22px;
3141
- --nf-container-gap: var(--nf-space-14, 14px);
3142
- --nf-card-pad: 20px 22px;
3143
- --nf-nav-pad: 16px 12px 14px;
3144
- }
3145
-
3146
- .panel[data-nf-density='compact'] {
3147
- --nf-container-pad: 12px 14px;
3148
- --nf-container-gap: var(--nf-space-8, 8px);
3149
- --nf-card-pad: 12px 14px;
3150
- --nf-nav-pad: 8px 8px;
3151
- }
3152
-
3153
- .panel[data-nf-density='spacious'] {
3154
- --nf-container-pad: 24px 28px;
3155
- --nf-container-gap: var(--nf-space-18, 18px);
3156
- --nf-card-pad: 22px 26px;
3157
- --nf-nav-pad: 18px 14px;
3158
- }
3159
-
3160
- /* 强制浅色(不跟随系统时覆盖 .view 的明暗变量) */
3161
- .panel[data-nf-mode='light'] {
3162
- color-scheme: light;
3163
- --nf-bg: rgba(242, 242, 247, 0.86);
3164
- --nf-bg-raise: rgba(255, 255, 255, 0.72);
3165
- --nf-bg-inset: rgba(118, 118, 128, 0.12);
3166
- --nf-border: rgba(60, 60, 67, 0.16);
3167
- --nf-border-strong: rgba(60, 60, 67, 0.32);
3168
- --nf-text: #1c1c1e;
3169
- --nf-text-2: #3c3c43;
3170
- --nf-text-2-alpha: rgba(60, 60, 67, 0.68);
3171
- --nf-text-3: #8e8e93;
3172
- --nf-accent: #00b85c;
3173
- --nf-accent-hover: #00a04e;
3174
- --nf-accent-soft: rgba(0, 184, 92, 0.12);
3175
- --nf-accent-fg: #ffffff;
3176
- --nf-hover: rgba(0, 0, 0, 0.05);
3177
- --nf-success: #34c759;
3178
- --nf-error: #ff3b30;
3179
- --nf-warn: #ff9500;
3180
- --nf-info: #00b85c;
3181
- --nf-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 12px 32px rgba(0, 0, 0, 0.08);
3182
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.07), 0 20px 48px rgba(0, 0, 0, 0.12);
3183
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.06), 0 14px 38px rgba(0, 0, 0, 0.14);
3184
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.08), 0 22px 52px rgba(0, 0, 0, 0.20);
3185
- --nf-glass-face: linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);
3186
- --nf-glass-core: radial-gradient(30% 24% at 36% 28%, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.22) 45%, rgba(255, 255, 255, 0) 78%);
3187
- --nf-glass-sheen: rgba(255, 255, 255, 0.55);
3188
- --nf-glass-border: rgba(255, 255, 255, 0.65);
3189
- --nf-glass-inset: rgba(255, 255, 255, 0.55);
3190
- --nf-glass-orb-a: rgba(0, 184, 92, 0.18);
3191
- --nf-glass-orb-b: rgba(120, 160, 255, 0.13);
3192
- }
3193
-
3194
- /* 强制深色 */
3195
- .panel[data-nf-mode='dark'] {
3196
- color-scheme: dark;
3197
- --nf-bg: rgba(10, 11, 13, 0.86);
3198
- --nf-bg-raise: rgba(28, 28, 30, 0.78);
3199
- --nf-bg-inset: rgba(118, 118, 128, 0.18);
3200
- --nf-border: rgba(255, 255, 255, 0.12);
3201
- --nf-border-strong: rgba(255, 255, 255, 0.28);
3202
- --nf-text: #f2f2f7;
3203
- --nf-text-2: #d1d1d6;
3204
- --nf-text-2-alpha: rgba(209, 209, 214, 0.72);
3205
- --nf-text-3: #8e8e93;
3206
- --nf-accent: #35d07a;
3207
- --nf-accent-hover: #5ce695;
3208
- --nf-accent-soft: rgba(53, 208, 122, 0.2);
3209
- --nf-accent-fg: #062b18;
3210
- --nf-hover: rgba(255, 255, 255, 0.09);
3211
- --nf-success: #30d158;
3212
- --nf-error: #ff453a;
3213
- --nf-warn: #ff9f0a;
3214
- --nf-info: #35d07a;
3215
- --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px rgba(0, 0, 0, 0.4);
3216
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.4), 0 20px 48px rgba(0, 0, 0, 0.55);
3217
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 14px 38px rgba(0, 0, 0, 0.45);
3218
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.4), 0 22px 52px rgba(0, 0, 0, 0.55);
3219
- --nf-glass-face: linear-gradient(180deg, rgba(112, 116, 122, 0.42) 0%, rgba(96, 100, 106, 0.42) 26%, rgba(82, 85, 90, 0.42) 52%, rgba(68, 71, 76, 0.42) 78%, rgba(56, 58, 63, 0.42) 100%);
3220
- --nf-glass-core: radial-gradient(30% 24% at 36% 28%, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0.10) 45%, rgba(255, 255, 255, 0) 78%);
3221
- --nf-glass-sheen: rgba(255, 255, 255, 0.26);
3222
- --nf-glass-border: rgba(255, 255, 255, 0.14);
3223
- --nf-glass-inset: rgba(255, 255, 255, 0.07);
3224
- --nf-glass-orb-a: rgba(0, 202, 82, 0.28);
3225
- --nf-glass-orb-b: rgba(190, 200, 215, 0.10);
3226
- }
3227
-
3228
- /* 强制深色时:新拟物 的暗色变体 */
3229
-
3230
- .panel[data-nf-mode='dark'][data-nf-theme='macos'] {
3231
- --nf-bg: rgba(28, 28, 30, 0.9);
3232
- --nf-bg-raise: rgba(44, 44, 46, 0.82);
3233
- --nf-bg-inset: rgba(118, 118, 128, 0.18);
3234
- --nf-border: rgba(255, 255, 255, 0.12);
3235
- --nf-border-strong: rgba(255, 255, 255, 0.26);
3236
- --nf-text: #f5f5f7;
3237
- --nf-text-2: #d1d1d6;
3238
- --nf-text-2-alpha: rgba(209, 209, 214, 0.7);
3239
- --nf-text-3: #98989d;
3240
- --nf-accent: #0a84ff;
3241
- --nf-accent-hover: #3a9bff;
3242
- --nf-accent-soft: rgba(10, 132, 255, 0.2);
3243
- --nf-accent-fg: #ffffff;
3244
- --nf-hover: rgba(255, 255, 255, 0.06);
3245
- --nf-info: #bf5af2;
3246
- --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.45);
3247
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45), 0 18px 44px rgba(0, 0, 0, 0.6);
3248
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.4), 0 14px 38px rgba(0, 0, 0, 0.5);
3249
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.45), 0 22px 52px rgba(0, 0, 0, 0.6);
3250
- --nf-glass-face: rgba(44, 44, 46, 0.85);
3251
- --nf-glass-core: transparent;
3252
- --nf-glass-sheen: rgba(255, 255, 255, 0.2);
3253
- --nf-glass-border: rgba(255, 255, 255, 0.18);
3254
- --nf-glass-inset: rgba(255, 255, 255, 0.06);
3255
- --nf-glass-orb-a: rgba(10, 132, 255, 0.16);
3256
- --nf-glass-orb-b: rgba(191, 90, 242, 0.08);
3257
- --nf-glass-noise: none;
3258
- }
3259
-
3260
- .panel[data-nf-mode='dark'][data-nf-theme='neumorph'] {
3261
- --nf-bg: #2b2f36;
3262
- --nf-bg-raise: #2b2f36;
3263
- --nf-bg-inset: #25292f;
3264
- --nf-border: rgba(10, 12, 16, 0.5);
3265
- --nf-border-strong: rgba(8, 10, 14, 0.6);
3266
- --nf-text: #d6dae1;
3267
- --nf-text-2: #a8aeb8;
3268
- --nf-text-2-alpha: rgba(168, 174, 184, 0.7);
3269
- --nf-text-3: #757c88;
3270
- --nf-hover: rgba(255, 255, 255, 0.05);
3271
- --nf-shadow: 4px 4px 10px rgba(0, 0, 0, 0.5), -4px -4px 10px rgba(96, 104, 118, 0.24);
3272
- --nf-shadow-lg: 6px 6px 14px rgba(0, 0, 0, 0.55), -6px -6px 14px rgba(96, 104, 118, 0.26);
3273
- --nf-card-shadow: 9px 9px 18px rgba(0, 0, 0, 0.5), -9px -9px 18px rgba(96, 104, 118, 0.24);
3274
- --nf-card-shadow-hover: 12px 12px 24px rgba(0, 0, 0, 0.6), -12px -12px 24px rgba(96, 104, 118, 0.28);
3275
- --nf-glass-face: #2b2f36;
3276
- --nf-glass-core: transparent;
3277
- --nf-glass-sheen: rgba(255, 255, 255, 0);
3278
- --nf-glass-border: rgba(12, 14, 18, 0.45);
3279
- --nf-glass-inset: #25292f;
3280
- --nf-glass-orb-a: transparent;
3281
- --nf-glass-orb-b: transparent;
3282
- --nf-glass-noise: none;
3283
- }
3284
-
3285
- /* 强制浅色时:新拟物 的浅色变体(深色系统下也能用) */
3286
- .panel[data-nf-mode='light'][data-nf-theme='neumorph'] {
3287
- --nf-bg: #e4e9f2;
3288
- --nf-bg-raise: #e4e9f2;
3289
- --nf-bg-inset: #d9dfe8;
3290
- --nf-border: rgba(140, 155, 175, 0.35);
3291
- --nf-border-strong: rgba(120, 135, 158, 0.5);
3292
- --nf-text: #3a4250;
3293
- --nf-text-2: #5b6472;
3294
- --nf-text-2-alpha: rgba(70, 80, 96, 0.7);
3295
- --nf-text-3: #8b94a3;
3296
- --nf-hover: rgba(90, 105, 125, 0.08);
3297
- --nf-shadow: 4px 4px 10px rgba(163, 177, 198, 0.55), -4px -4px 10px rgba(255, 255, 255, 0.85);
3298
- --nf-shadow-lg: 6px 6px 14px rgba(163, 177, 198, 0.6), -6px -6px 14px rgba(255, 255, 255, 0.9);
3299
- --nf-card-shadow: 9px 9px 18px rgba(163, 177, 198, 0.55), -9px -9px 18px rgba(255, 255, 255, 0.85);
3300
- --nf-card-shadow-hover: 12px 12px 24px rgba(163, 177, 198, 0.65), -12px -12px 24px rgba(255, 255, 255, 0.95);
3301
- --nf-glass-face: #e4e9f2;
3302
- --nf-glass-core: transparent;
3303
- --nf-glass-sheen: rgba(255, 255, 255, 0);
3304
- --nf-glass-border: rgba(163, 177, 198, 0.4);
3305
- --nf-glass-inset: #d9dfe8;
3306
- --nf-glass-orb-a: transparent;
3307
- --nf-glass-orb-b: transparent;
3308
- --nf-glass-noise: none;
3309
- }
3310
-
3311
-
3312
- .bookCard {
3313
- display: flex;
3314
- flex-direction: column;
3315
- gap: var(--nf-space-8, 8px);
3316
- border: 1px solid var(--nf-border);
3317
- border-radius: var(--nf-radius-16, 16px);
3318
- padding: var(--nf-space-12, 12px);
3319
- background: var(--nf-bg-raise);
3320
- -webkit-backdrop-filter: blur(24px) saturate(180%);
3321
- backdrop-filter: blur(24px) saturate(180%);
3322
- box-shadow: var(--nf-shadow);
3323
- cursor: pointer;
3324
- transition: border-color 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
3325
- }
3326
-
3327
- .bookCard:hover {
3328
- border-color: var(--nf-accent);
3329
- transform: translateY(-2px);
3330
- box-shadow: var(--nf-shadow-lg);
3331
- }
3332
-
3333
- .bookCardActive {
3334
- border-color: var(--nf-accent);
3335
- box-shadow: 0 0 0 3px var(--nf-accent-soft);
3336
- }
3337
-
3338
- .bookCardCover {
3339
- flex: none;
3340
- aspect-ratio: 3 / 4;
3341
- border-radius: var(--nf-radius-12, 12px);
3342
- overflow: hidden;
3343
- background: var(--nf-bg-inset);
3344
- border: 1px solid var(--nf-border);
3345
- display: flex;
3346
- align-items: center;
3347
- justify-content: center;
3348
- position: relative;
3349
- }
3350
-
3351
- .bookCardCover img {
3352
- width: 100%;
3353
- height: 100%;
3354
- object-fit: cover;
3355
- display: block;
3356
- transition: transform 0.35s ease;
3357
- }
3358
-
3359
- .bookCard:hover .bookCardCover img {
3360
- transform: scale(1.06);
3361
- }
3362
-
3363
- /* 封面底部渐暗(hover 出现,突出书名区) */
3364
- .bookCardCover::after {
3365
- content: '';
3366
- position: absolute;
3367
- inset: 0;
3368
- border-radius: inherit;
3369
- pointer-events: none;
3370
- background: linear-gradient(180deg, transparent 55%, rgba(0, 0, 0, 0.28));
3371
- opacity: 0;
3372
- transition: opacity 0.25s ease;
3373
- }
3374
-
3375
- .bookCard:hover .bookCardCover::after {
3376
- opacity: 1;
3377
- }
3378
-
3379
- .bookCardCoverFallback {
3380
- display: flex;
3381
- flex-direction: column;
3382
- align-items: center;
3383
- justify-content: center;
3384
- gap: var(--nf-space-6, 6px);
3385
- width: 100%;
3386
- height: 100%;
3387
- background:
3388
- radial-gradient(400px 200px at 80% -20%, color-mix(in srgb, var(--nf-accent) 25%, transparent), transparent 70%),
3389
- linear-gradient(155deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 10%, var(--nf-bg-inset)));
3390
- }
3391
-
3392
- .bookCardCoverTitle {
3393
- font-size: var(--nf-fs-22, 22px);
3394
- font-weight: 800;
3395
- color: var(--nf-accent);
3396
- letter-spacing: 2px;
3397
- }
3398
-
3399
- .bookCardBody {
3400
- display: flex;
3401
- flex-direction: column;
3402
- gap: var(--nf-space-6, 5px);
3403
- min-width: 0;
3404
- flex: 1;
3405
- }
3406
-
3407
- .bookCardTitleRow {
3408
- display: flex;
3409
- align-items: center;
3410
- justify-content: space-between;
3411
- gap: var(--nf-space-6, 6px);
3412
- }
3413
-
3414
- .bookCardName {
3415
- font-weight: 700;
3416
- font-size: var(--nf-fs-14, 13.5px);
3417
- overflow: hidden;
3418
- text-overflow: ellipsis;
3419
- white-space: nowrap;
3420
- }
3421
-
3422
- .bookCardBlurb {
3423
- display: -webkit-box;
3424
- -webkit-line-clamp: 2;
3425
- -webkit-box-orient: vertical;
3426
- overflow: hidden;
3427
- min-height: 34px;
3428
- }
3429
-
3430
- .bookCardMetaRow {
3431
- display: flex;
3432
- align-items: center;
3433
- justify-content: space-between;
3434
- gap: var(--nf-space-6, 6px);
3435
- flex-wrap: wrap;
3436
- }
3437
-
3438
- .bookCardProgressBar {
3439
- height: 6px;
3440
- border-radius: var(--nf-radius-999, 999px);
3441
- background: var(--nf-border);
3442
- overflow: hidden;
3443
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
3444
- }
3445
-
3446
- .bookCardProgressFill {
3447
- display: block;
3448
- height: 100%;
3449
- border-radius: var(--nf-radius-999, 999px);
3450
- background: linear-gradient(90deg, var(--nf-info), var(--nf-accent));
3451
- transition: width 0.3s ease;
3452
- }
3453
-
3454
- .bookAddCard {
3455
- align-items: center;
3456
- justify-content: center;
3457
- gap: var(--nf-space-8, 8px);
3458
- text-align: center;
3459
- border-style: dashed;
3460
- color: var(--nf-text-2);
3461
- min-height: 260px;
3462
- transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease, transform 0.15s ease;
3463
- }
3464
-
3465
- .bookAddCard:hover {
3466
- border-color: var(--nf-accent);
3467
- background: var(--nf-accent-soft);
3468
- color: var(--nf-accent);
3469
- transform: translateY(-2px);
3470
- }
3471
-
3472
- .bookAddIcon {
3473
- font-size: var(--nf-fs-34, 34px);
3474
- line-height: 1;
3475
- color: var(--nf-accent);
3476
- transition: transform 0.15s ease;
3477
- }
3478
-
3479
- .bookAddCard:hover .bookAddIcon {
3480
- transform: scale(1.12);
3481
- }
3482
-
3483
- .bookCreateCard {
3484
- min-height: 260px;
3485
- border-color: var(--nf-accent);
3486
- }
3487
-
3488
- /* -------------------------------------------------------- create book view */
3489
-
3490
- .createBookView {
3491
- flex: 1;
3492
- min-height: 0;
3493
- overflow: auto;
3494
- /* 主容器统一:与工作台/书架/设置页同一令牌 */
3495
- padding: var(--nf-container-pad, 20px 22px);
3496
- display: flex;
3497
- flex-direction: column;
3498
- gap: var(--nf-container-gap, 14px);
3499
- }
3500
-
3501
- .createBookTop {
3502
- display: flex;
3503
- align-items: center;
3504
- }
3505
-
3506
- .createBookCard {
3507
- align-self: center;
3508
- width: min(520px, 100%);
3509
- display: flex;
3510
- flex-direction: column;
3511
- gap: var(--nf-space-12, 12px);
3512
- border: 1px solid var(--nf-border);
3513
- border-radius: var(--nf-radius-20, 20px);
3514
- /* 主容器统一:与设置页卡片同一 --nf-card-pad */
3515
- padding: var(--nf-card-pad, 20px 22px);
3516
- background: var(--nf-bg-raise);
3517
- -webkit-backdrop-filter: blur(24px) saturate(180%);
3518
- backdrop-filter: blur(24px) saturate(180%);
3519
- box-shadow: var(--nf-shadow-lg);
3520
- }
3521
-
3522
- .createBookIcon {
3523
- font-size: var(--nf-fs-34, 34px);
3524
- line-height: 1;
3525
- }
3526
-
3527
- .createBookTitle {
3528
- margin: 0;
3529
- font-size: var(--nf-fs-22, 22px);
3530
- font-weight: 800;
3531
- letter-spacing: -0.3px;
3532
- }
3533
-
3534
- /* 想法 → AI 大纲区块 */
3535
- .ideaCard {
3536
- display: flex;
3537
- flex-direction: column;
3538
- gap: var(--nf-space-8, 8px);
3539
- border: 1px dashed var(--nf-border-strong);
3540
- border-radius: var(--nf-radius-14, 14px);
3541
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
3542
- background: color-mix(in srgb, var(--nf-accent) 3%, transparent);
3543
- }
3544
-
3545
- .ideaToggle {
3546
- display: flex;
3547
- align-items: center;
3548
- gap: var(--nf-space-6, 6px);
3549
- border: none;
3550
- background: none;
3551
- color: var(--nf-accent);
3552
- font-size: var(--nf-fs-14, 13px);
3553
- font-weight: 700;
3554
- cursor: pointer;
3555
- text-align: left;
3556
- padding: 0;
3557
- }
3558
-
3559
- .ideaCandidate {
3560
- display: flex;
3561
- flex-direction: column;
3562
- gap: var(--nf-space-6, 6px);
3563
- border: 1px solid var(--nf-border);
3564
- border-radius: var(--nf-radius-12, 12px);
3565
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
3566
- background: var(--nf-bg);
3567
- }
3568
-
3569
- .progressLineDone {
3570
- color: var(--nf-success);
3571
- font-weight: 600;
3572
- }
3573
-
3574
- .progressLineError {
3575
- color: var(--nf-error);
3576
- font-weight: 600;
3577
- }
3578
-
3579
- /* ------------------------------------------------------------ misc */
3580
-
3581
- .meta {
3582
- font-size: var(--nf-fs-12, 12px);
3583
- color: var(--nf-text-2);
3584
- opacity: 0.9;
3585
- }
3586
-
3587
- /* 题材基底:描述两行截断(悬停 title 看全文),保持列表紧凑自然展开 */
3588
- .genreDesc {
3589
- display: -webkit-box;
3590
- -webkit-line-clamp: 2;
3591
- -webkit-box-orient: vertical;
3592
- overflow: hidden;
3593
- max-width: 560px;
3594
- }
3595
-
3596
- .fileList {
3597
- display: flex;
3598
- flex-direction: column;
3599
- gap: var(--nf-space-4, 3px);
3600
- font-size: var(--nf-fs-12, 12px);
3601
- color: var(--nf-text-2);
3602
- opacity: 0.9;
3603
- word-break: break-all;
3604
- }
3605
-
3606
- /* Custom scrollbar (webkit) */
3607
- .panelContent::-webkit-scrollbar,
3608
- .chatScroll::-webkit-scrollbar,
3609
- .chapterPreview::-webkit-scrollbar,
3610
- .progress::-webkit-scrollbar,
3611
- .toolLive::-webkit-scrollbar {
3612
- width: 8px;
3613
- height: 8px;
3614
- }
3615
-
3616
- .panelContent::-webkit-scrollbar-thumb,
3617
- .chatScroll::-webkit-scrollbar-thumb,
3618
- .chapterPreview::-webkit-scrollbar-thumb,
3619
- .progress::-webkit-scrollbar-thumb,
3620
- .toolLive::-webkit-scrollbar-thumb {
3621
- background: var(--nf-border-strong);
3622
- border-radius: var(--nf-radius-4, 4px);
3623
- }
3624
-
3625
- .panelContent::-webkit-scrollbar-thumb:hover,
3626
- .chatScroll::-webkit-scrollbar-thumb:hover,
3627
- .chapterPreview::-webkit-scrollbar-thumb:hover,
3628
- .progress::-webkit-scrollbar-thumb:hover,
3629
- .toolLive::-webkit-scrollbar-thumb:hover {
3630
- background: var(--nf-text-3);
3631
- }
3632
-
3633
- /* Workflow timeline */
3634
- .workflowList {
3635
- display: flex;
3636
- flex-direction: column;
3637
- gap: 0;
3638
- }
3639
-
3640
- .workflowRow {
3641
- display: flex;
3642
- align-items: flex-start;
3643
- gap: var(--nf-space-12, 12px);
3644
- padding: var(--nf-space-8, 8px) var(--nf-space-4, 4px);
3645
- position: relative;
3646
- }
3647
-
3648
- .workflowRow::before {
3649
- content: '';
3650
- position: absolute;
3651
- left: 13px;
3652
- top: 34px;
3653
- bottom: -8px;
3654
- width: 2px;
3655
- background: var(--nf-border);
3656
- }
3657
-
3658
- .workflowRow:last-child::before {
3659
- display: none;
3660
- }
3661
-
3662
- .workflowDot {
3663
- width: 28px;
3664
- height: var(--nf-ctrl-s, 28px);
3665
- border-radius: 50%;
3666
- display: inline-flex;
3667
- align-items: center;
3668
- justify-content: center;
3669
- font-size: var(--nf-fs-12, 12px);
3670
- font-weight: 700;
3671
- flex-shrink: 0;
3672
- border: 2px solid var(--nf-border-strong);
3673
- background: var(--nf-bg-raise);
3674
- color: var(--nf-text-2);
3675
- z-index: 1;
3676
- }
3677
-
3678
- .workflowDotDone {
3679
- border-color: var(--nf-success);
3680
- background: color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));
3681
- color: var(--nf-success);
3682
- }
3683
-
3684
- .workflowDotActive {
3685
- border-color: var(--nf-accent);
3686
- background: var(--nf-accent);
3687
- color: var(--nf-accent-fg);
3688
- box-shadow: 0 0 0 4px var(--nf-accent-soft);
3689
- }
3690
-
3691
- .workflowBody {
3692
- flex: 1;
3693
- min-width: 0;
3694
- display: flex;
3695
- flex-direction: column;
3696
- gap: var(--nf-space-4, 4px);
3697
- padding-top: var(--nf-space-2, 2px);
3698
- }
3699
-
3700
- .workflowLabel {
3701
- font-size: var(--nf-fs-14, 13px);
3702
- font-weight: 600;
3703
- color: var(--nf-text);
3704
- }
3705
-
3706
- .workflowHint {
3707
- font-size: var(--nf-fs-12, 12px);
3708
- color: var(--nf-text-2);
3709
- }
3710
-
3711
- @keyframes pulse {
3712
- 0%, 100% { opacity: 1; }
3713
- 50% { opacity: 0.45; }
3714
- }
3715
-
3716
- @keyframes fadeIn {
3717
- from { opacity: 0; transform: translateY(4px); }
3718
- to { opacity: 1; transform: translateY(0); }
3719
- }
3720
-
3721
- .card {
3722
- animation: fadeIn 0.2s ease;
3723
- }
3724
-
3725
- /* ------------------------------------------------------------ bookshelf */
3726
-
3727
- .bookshelf {
3728
- display: flex;
3729
- align-items: center;
3730
- gap: var(--nf-space-10, 10px);
3731
- margin: 10px 12px 0;
3732
- padding: var(--nf-space-8, 8px) var(--nf-space-14, 14px);
3733
- border: 1px solid var(--nf-glass-border);
3734
- border-radius: var(--nf-radius-16, 16px);
3735
- background: var(--nf-glass-face);
3736
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
3737
- -webkit-backdrop-filter: blur(26px) saturate(175%);
3738
- backdrop-filter: blur(26px) saturate(175%);
3739
- flex-shrink: 0;
3740
- flex-wrap: wrap;
3741
- position: relative;
3742
- z-index: 1;
3743
- }
3744
-
3745
- .bookshelfLabel {
3746
- font-size: var(--nf-fs-12, 12px);
3747
- font-weight: 700;
3748
- color: var(--nf-text-3);
3749
- letter-spacing: 1px;
3750
- flex-shrink: 0;
3751
- }
3752
-
3753
- .bookshelfList {
3754
- display: flex;
3755
- align-items: center;
3756
- gap: var(--nf-space-6, 6px);
3757
- flex-wrap: wrap;
3758
- flex: 1;
3759
- min-width: 0;
3760
- }
3761
-
3762
- .bookChip {
3763
- display: flex;
3764
- align-items: center;
3765
- gap: var(--nf-space-6, 6px);
3766
- padding: var(--nf-space-4, 4px) var(--nf-space-8, 8px) var(--nf-space-4, 4px) var(--nf-space-10, 10px);
3767
- border: 1px solid var(--nf-border);
3768
- border-radius: var(--nf-radius-999, 999px);
3769
- background: var(--nf-bg-inset);
3770
- cursor: pointer;
3771
- font-size: var(--nf-fs-12, 12px);
3772
- transition: border-color 0.15s ease, background 0.15s ease;
3773
- max-width: 220px;
3774
- }
3775
-
3776
- .bookChip:hover {
3777
- border-color: var(--nf-border-strong);
3778
- }
3779
-
3780
- .bookChipActive {
3781
- border-color: var(--nf-accent);
3782
- background: var(--nf-accent-soft);
3783
- color: var(--nf-accent);
3784
- }
3785
-
3786
- .bookChipName {
3787
- font-weight: 600;
3788
- overflow: hidden;
3789
- text-overflow: ellipsis;
3790
- white-space: nowrap;
3791
- }
3792
-
3793
- .bookChipMeta {
3794
- font-size: var(--nf-fs-12, 11px);
3795
- opacity: 0.7;
3796
- white-space: nowrap;
3797
- }
3798
-
3799
- .bookChipRemove {
3800
- border: none;
3801
- background: transparent;
3802
- color: var(--nf-text-3);
3803
- cursor: pointer;
3804
- font-size: var(--nf-fs-14, 13px);
3805
- line-height: 1;
3806
- padding: 0 var(--nf-space-2, 2px);
3807
- border-radius: var(--nf-radius-4, 4px);
3808
- }
3809
-
3810
- .bookChipRemove:hover {
3811
- color: var(--nf-error);
3812
- }
3813
-
3814
- .bookAdd {
3815
- border: 1px dashed var(--nf-border-strong);
3816
- background: transparent;
3817
- color: var(--nf-text-2);
3818
- cursor: pointer;
3819
- font-size: var(--nf-fs-12, 12px);
3820
- padding: var(--nf-space-4, 4px) var(--nf-space-12, 12px);
3821
- border-radius: var(--nf-radius-999, 999px);
3822
- transition: border-color 0.15s ease, color 0.15s ease;
3823
- }
3824
-
3825
- .bookAdd:hover {
3826
- border-color: var(--nf-accent);
3827
- color: var(--nf-accent);
3828
- }
3829
-
3830
- .bookCreateForm {
3831
- display: flex;
3832
- align-items: center;
3833
- gap: var(--nf-space-6, 6px);
3834
- }
3835
-
3836
- /* ------------------------------------------------------------ dropzone */
3837
-
3838
- .dropzone {
3839
- border: 2px dashed var(--nf-border-strong);
3840
- border-radius: var(--nf-radius-10, 10px);
3841
- padding: var(--nf-space-18, 18px) var(--nf-space-14, 14px);
3842
- text-align: center;
3843
- font-size: var(--nf-fs-14, 13px);
3844
- color: var(--nf-text-2);
3845
- cursor: pointer;
3846
- transition: border-color 0.15s ease, background 0.15s ease;
3847
- display: flex;
3848
- flex-direction: column;
3849
- align-items: center;
3850
- gap: var(--nf-space-6, 6px);
3851
- }
3852
-
3853
- .dropzone:hover,
3854
- .dropzoneActive {
3855
- border-color: var(--nf-accent);
3856
- background: var(--nf-accent-soft);
3857
- color: var(--nf-accent);
3858
- }
3859
-
3860
- .dropzoneIcon {
3861
- font-size: var(--nf-fs-22, 22px);
3862
- line-height: 1;
3863
- }
3864
-
3865
- /* ================= 书架书卡操作行 ================= */
3866
-
3867
- .bookCardActions {
3868
- display: flex;
3869
- align-items: center;
3870
- gap: var(--nf-space-6, 6px);
3871
- margin-top: auto;
3872
- padding-top: var(--nf-space-8, 8px);
3873
- }
3874
-
3875
- .bookCardActions .button {
3876
- flex: 1;
3877
- justify-content: center;
3878
- }
3879
-
3880
- /* ================= 阅读页(沉浸式) ================= */
3881
-
3882
- .readerView {
3883
- position: absolute;
3884
- inset: 0;
3885
- display: flex;
3886
- flex-direction: column;
3887
- overflow: hidden;
3888
- transition: background 0.2s ease, color 0.2s ease;
3889
- }
3890
-
3891
- .readerHeader {
3892
- flex: none;
3893
- display: flex;
3894
- align-items: center;
3895
- gap: var(--nf-space-8, 8px);
3896
- padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
3897
- border-bottom: 1px solid;
3898
- flex-wrap: wrap;
3899
- }
3900
-
3901
- .readerTitle {
3902
- font-weight: 700;
3903
- font-size: var(--nf-fs-14, 14px);
3904
- }
3905
-
3906
- .readerSeg {
3907
- display: flex;
3908
- align-items: center;
3909
- gap: var(--nf-space-2, 2px);
3910
- border-radius: var(--nf-radius-8, 8px);
3911
- overflow: hidden;
3912
- }
3913
-
3914
- .readerSegBtn {
3915
- border: none;
3916
- background: transparent;
3917
- font-size: var(--nf-fs-12, 12px);
3918
- padding: var(--nf-space-4, 3px) var(--nf-space-8, 8px);
3919
- border-radius: var(--nf-radius-6, 6px);
3920
- cursor: pointer;
3921
- opacity: 0.75;
3922
- }
3923
-
3924
- .readerSegBtn:hover {
3925
- opacity: 1;
3926
- }
3927
-
3928
- .readerSegActive {
3929
- opacity: 1;
3930
- }
3931
-
3932
- .readerBody {
3933
- flex: 1;
3934
- min-height: 0;
3935
- display: flex;
3936
- align-items: stretch;
3937
- }
3938
-
3939
- .readerSidebar {
3940
- flex: none;
3941
- width: 220px;
3942
- min-width: 220px;
3943
- overflow-y: auto;
3944
- padding: var(--nf-space-8, 8px) var(--nf-space-6, 6px) var(--nf-space-24, 24px);
3945
- border-right: 1px solid;
3946
- scrollbar-width: thin;
3947
- display: flex;
3948
- flex-direction: column;
3949
- gap: var(--nf-space-10, 10px);
3950
- }
3951
-
3952
- .readerGroup {
3953
- display: flex;
3954
- flex-direction: column;
3955
- gap: var(--nf-space-2, 1px);
3956
- }
3957
-
3958
- .readerGroupTitle {
3959
- display: flex;
3960
- align-items: center;
3961
- gap: var(--nf-space-6, 6px);
3962
- width: 100%;
3963
- border: none;
3964
- background: transparent;
3965
- font-size: var(--nf-fs-12, 12px);
3966
- font-weight: 700;
3967
- padding: var(--nf-space-6, 6px) var(--nf-space-8, 8px) var(--nf-space-4, 4px);
3968
- opacity: 0.9;
3969
- cursor: pointer;
3970
- text-align: left;
3971
- border-radius: var(--nf-radius-6, 6px);
3972
- }
3973
-
3974
- .readerGroupTitle:hover {
3975
- opacity: 1;
3976
- background: rgba(128, 128, 128, 0.12);
3977
- }
3978
-
3979
- .readerGroupArrow {
3980
- flex: none;
3981
- font-size: var(--nf-fs-12, 10px);
3982
- width: 12px;
3983
- text-align: center;
3984
- }
3985
-
3986
- .readerGroupCount {
3987
- flex: none;
3988
- font-size: var(--nf-fs-12, 11px);
3989
- font-weight: 400;
3990
- opacity: 0.6;
3991
- margin-left: auto;
3992
- padding-right: var(--nf-space-2, 2px);
3993
- }
3994
-
3995
- .readerItem {
3996
- display: flex;
3997
- align-items: center;
3998
- gap: var(--nf-space-6, 6px);
3999
- border: 1px solid;
4000
- border-radius: var(--nf-radius-8, 8px);
4001
- background: transparent;
4002
- font-size: var(--nf-fs-12, 12px);
4003
- text-align: left;
4004
- padding: var(--nf-space-4, 4px) var(--nf-space-8, 8px);
4005
- cursor: pointer;
4006
- opacity: 0.8;
4007
- transition: opacity 0.15s ease, background 0.15s ease;
4008
- min-width: 0;
4009
- }
4010
-
4011
- .readerItem:hover {
4012
- opacity: 1;
4013
- }
4014
-
4015
- .readerItemActive {
4016
- opacity: 1;
4017
- font-weight: 700;
4018
- }
4019
-
4020
- .readerItemNo {
4021
- flex: none;
4022
- font-weight: 700;
4023
- min-width: 26px;
4024
- text-align: right;
4025
- opacity: 0.75;
4026
- }
4027
-
4028
- .readerItemTitle {
4029
- flex: 1;
4030
- min-width: 0;
4031
- overflow: hidden;
4032
- text-overflow: ellipsis;
4033
- white-space: nowrap;
4034
- }
4035
-
4036
- .readerItemBadge {
4037
- flex: none;
4038
- font-size: var(--nf-fs-12, 11px);
4039
- }
4040
-
4041
- .readerMain {
4042
- flex: 1;
4043
- min-height: 0;
4044
- overflow-y: auto;
4045
- padding: var(--nf-space-20, 20px) var(--nf-space-16, 16px) var(--nf-space-48, 48px);
4046
- display: flex;
4047
- justify-content: center;
4048
- scrollbar-width: thin;
4049
- }
4050
-
4051
- .readerArticle {
4052
- width: 100%;
4053
- display: flex;
4054
- flex-direction: column;
4055
- gap: var(--nf-space-12, 12px);
4056
- }
4057
-
4058
- .readerChapterTitle {
4059
- margin: 0;
4060
- font-size: var(--nf-fs-24, 24px);
4061
- font-weight: 800;
4062
- letter-spacing: 1px;
4063
- }
4064
-
4065
- .readerChapterMeta {
4066
- display: flex;
4067
- align-items: center;
4068
- gap: var(--nf-space-8, 8px);
4069
- font-size: var(--nf-fs-12, 12px);
4070
- }
4071
-
4072
- .readerText {
4073
- text-align: justify;
4074
- letter-spacing: 0.02em;
4075
- }
4076
-
4077
- .readerPara {
4078
- margin: 0 0 0.85em;
4079
- text-indent: 2em;
4080
- }
4081
-
4082
- .readerFoot {
4083
- display: flex;
4084
- align-items: center;
4085
- justify-content: space-between;
4086
- gap: var(--nf-space-8, 8px);
4087
- margin-top: 12px;
4088
- padding-top: var(--nf-space-12, 12px);
4089
- border-top: 1px dashed;
4090
- }
4091
-
4092
- .readerLoading,
4093
- .readerError {
4094
- align-self: center;
4095
- padding: var(--nf-space-32, 32px) 0;
4096
- font-size: var(--nf-fs-14, 13px);
4097
- opacity: 0.7;
4098
- }
4099
-
4100
- .readerError {
4101
- color: var(--nf-error);
4102
- }
4103
-
4104
- /* ---------------------------------------------------------- import modal */
4105
-
4106
- .importModalOverlay {
4107
- position: fixed;
4108
- inset: 0;
4109
- z-index: 1000;
4110
- display: flex;
4111
- align-items: center;
4112
- justify-content: center;
4113
- background: rgba(0, 0, 0, 0.45);
4114
- -webkit-backdrop-filter: blur(4px);
4115
- backdrop-filter: blur(4px);
4116
- padding: var(--nf-space-24, 24px);
4117
- }
4118
-
4119
- .importModal {
4120
- width: min(520px, 100%);
4121
- max-height: 85vh;
4122
- overflow: auto;
4123
- display: flex;
4124
- flex-direction: column;
4125
- gap: var(--nf-space-12, 12px);
4126
- border: 1px solid var(--nf-border-strong);
4127
- border-radius: var(--nf-radius-16, 16px);
4128
- /* 主容器统一:与设置页卡片同一 --nf-card-pad */
4129
- padding: var(--nf-card-pad, 20px 22px);
4130
- background: var(--nf-bg-raise);
4131
- -webkit-backdrop-filter: blur(28px) saturate(180%);
4132
- backdrop-filter: blur(28px) saturate(180%);
4133
- box-shadow: var(--nf-shadow-lg);
4134
- }
4135
-
4136
- .importModalHead {
4137
- display: flex;
4138
- align-items: center;
4139
- justify-content: space-between;
4140
- gap: var(--nf-space-10, 10px);
4141
- }
4142
-
4143
- .importModalTabs {
4144
- display: flex;
4145
- gap: var(--nf-space-8, 8px);
4146
- }
4147
-
4148
- .importModalTabs .button {
4149
- flex: 1;
4150
- }
4151
-
4152
- .importModalBody {
4153
- display: flex;
4154
- flex-direction: column;
4155
- gap: var(--nf-space-10, 10px);
4156
- }
4157
-
4158
- .importField {
4159
- display: flex;
4160
- flex-direction: column;
4161
- gap: var(--nf-space-6, 5px);
4162
- font-size: var(--nf-fs-14, 13px);
4163
- color: var(--nf-text-2);
4164
- }
4165
-
4166
- .importHint {
4167
- font-size: var(--nf-fs-12, 12px);
4168
- color: var(--nf-text-3);
4169
- line-height: 1.5;
4170
- }
4171
-
4172
- .importError {
4173
- border: 1px solid color-mix(in srgb, var(--nf-danger, #e5484d) 55%, transparent);
4174
- border-radius: var(--nf-radius-10, 10px);
4175
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
4176
- font-size: var(--nf-fs-12, 12.5px);
4177
- color: var(--nf-danger, #e5484d);
4178
- background: color-mix(in srgb, var(--nf-danger, #e5484d) 10%, transparent);
4179
- white-space: pre-wrap;
4180
- word-break: break-all;
4181
- }
4182
-
4183
- .importResult {
4184
- display: flex;
4185
- flex-direction: column;
4186
- gap: var(--nf-space-4, 4px);
4187
- border: 1px solid color-mix(in srgb, var(--nf-ok, #46a758) 45%, transparent);
4188
- border-radius: var(--nf-radius-10, 10px);
4189
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
4190
- font-size: var(--nf-fs-14, 13px);
4191
- background: color-mix(in srgb, var(--nf-ok, #46a758) 9%, transparent);
4192
- word-break: break-all;
4193
- }
4194
-
4195
- .importModalActions {
4196
- display: flex;
4197
- justify-content: flex-end;
4198
- gap: var(--nf-space-8, 8px);
4199
- }
4200
-
4201
- .importFileInfo {
4202
- display: flex;
4203
- align-items: center;
4204
- gap: var(--nf-space-8, 8px);
4205
- font-size: var(--nf-fs-14, 13px);
4206
- color: var(--nf-text-1);
4207
- flex-wrap: wrap;
4208
- }
4209
-
4210
- .importPreview {
4211
- display: flex;
4212
- flex-direction: column;
4213
- gap: var(--nf-space-4, 4px);
4214
- border: 1px solid var(--nf-border-strong);
4215
- border-radius: var(--nf-radius-10, 10px);
4216
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
4217
- font-size: var(--nf-fs-14, 13px);
4218
- background: var(--nf-bg-inset);
4219
- }
4220
-
4221
- .importPreviewList {
4222
- margin: 0;
4223
- padding-left: var(--nf-space-18, 18px);
4224
- display: flex;
4225
- flex-direction: column;
4226
- gap: var(--nf-space-2, 2px);
4227
- font-size: var(--nf-fs-12, 12.5px);
4228
- color: var(--nf-text-2);
4229
- max-height: 140px;
4230
- overflow: auto;
4231
- }
4232
-
4233
- /* 设置页卡片:label 单行、行内顶部对齐,保证输入框水平对齐 */
4234
- /* 设置页卡片:防止内层卡片/长内容在 flex 容器中撑破外层卡片 */
4235
- .settingsCard {
4236
- min-width: 0;
4237
- max-width: 100%;
4238
- }
4239
-
4240
- .settingsCard > * {
4241
- min-width: 0;
4242
- }
4243
-
4244
- /* ModelManager 等组件会在设置卡片内再渲染 .card 子卡片,也必须允许收缩 */
4245
- .settingsCard .card {
4246
- min-width: 0;
4247
- width: 100%;
4248
- max-width: 100%;
4249
- }
4250
-
4251
- .settingsCard .fieldLabel {
4252
- min-height: 18px;
4253
- line-height: 18px;
4254
- white-space: nowrap;
4255
- overflow: hidden;
4256
- text-overflow: ellipsis;
4257
- max-width: 100%;
4258
- }
4259
-
4260
- .settingsCard .row {
4261
- align-items: flex-start;
4262
- }
4263
-
4264
-
4265
-
4266
- .helpTipText {
4267
- display: none;
4268
- position: absolute;
4269
- left: 50%;
4270
- bottom: calc(100% + 8px);
4271
- transform: translateX(-50%);
4272
- width: 280px;
4273
- max-width: 70vw;
4274
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
4275
- border-radius: var(--nf-radius-10, 10px);
4276
- background: var(--nf-bg-raise);
4277
- border: 1px solid var(--nf-border-strong);
4278
- box-shadow: var(--nf-shadow-lg);
4279
- font-size: var(--nf-fs-12, 12px);
4280
- font-weight: 400;
4281
- line-height: 1.7;
4282
- color: var(--nf-text-2);
4283
- white-space: normal;
4284
- z-index: 20;
4285
- text-align: left;
4286
- pointer-events: none;
4287
- }
4288
-
4289
- .helpTip:hover .helpTipText,
4290
- .helpTip:focus .helpTipText,
4291
- .helpTip:focus-within .helpTipText {
4292
- display: block;
4293
- }
4294
-
4295
- /* 设置页:字号已统一为全局档(次要 12 / 主 14 / 标题 16+),不再放大;
4296
- * 主容器由 .card 的 --nf-card-pad 统一提供(舒适 20px 22px)。 */
4297
- .settingsCard + .settingsCard {
4298
- /* 不再强制拉伸/压缩:设置卡片按内容自适应高度,避免内层分类跑出容器 */
4299
- flex: 0 0 auto;
4300
- min-height: auto;
4301
- }
4302
-
4303
- /* 设置页开关(滑块) */
4304
- .switch {
4305
- position: relative;
4306
- width: 42px;
4307
- height: 24px;
4308
- border-radius: var(--nf-radius-999, 999px);
4309
- border: 1px solid var(--nf-border-strong);
4310
- background: var(--nf-bg-inset);
4311
- cursor: pointer;
4312
- padding: 0;
4313
- flex: none;
4314
- transition: background 0.18s ease, border-color 0.18s ease;
4315
- }
4316
-
4317
- .switchKnob {
4318
- position: absolute;
4319
- top: 3px;
4320
- left: 3px;
4321
- width: 16px;
4322
- height: 16px;
4323
- border-radius: 50%;
4324
- background: #fff;
4325
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
4326
- transition: transform 0.18s ease;
4327
- }
4328
-
4329
- .switchOn {
4330
- background: var(--nf-accent);
4331
- border-color: var(--nf-accent);
4332
- }
4333
-
4334
- .switchOn .switchKnob {
4335
- transform: translateX(18px);
4336
- }
4337
-
4338
- /* ---- 玻璃透明度滑块:实色主题(新拟态/黏土)调低时变透,透出背景图 ---- */
4339
- /* 默认 --nf-glass-opacity=100%,color-mix 透明 0% → 与主题原值一致,不改动现有效果。 */
4340
- .panel[data-nf-theme='neumorph']:not([data-nf-mode='dark']),
4341
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'][data-nf-mode='light'] {
4342
- --nf-glass-face: color-mix(in srgb, #e4e9f2, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4343
- --nf-bg-raise: color-mix(in srgb, #e4e9f2, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4344
- }
4345
- .panel[data-nf-mode='dark'][data-nf-theme='neumorph'],
4346
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph']:not([data-nf-mode]) {
4347
- --nf-glass-face: color-mix(in srgb, #2b2f36, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4348
- --nf-bg-raise: color-mix(in srgb, #2b2f36, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4349
- }
4350
- .panel[data-nf-theme='clay']:not([data-nf-mode='dark']),
4351
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'][data-nf-mode='light'] {
4352
- --nf-glass-face: color-mix(in srgb, #efe4d6, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4353
- --nf-bg-raise: color-mix(in srgb, #efe4d6, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4354
- }
4355
- .panel[data-nf-mode='dark'][data-nf-theme='clay'],
4356
- body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) {
4357
- --nf-glass-face: color-mix(in srgb, #37302b, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4358
- --nf-bg-raise: color-mix(in srgb, #37302b, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4359
- }