@waterwx/dsh-novel-forge 2.0.1-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 (183) hide show
  1. package/README.md +368 -362
  2. package/lib/client.js +20340 -19622
  3. package/lib/index.js +11313 -7285
  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 +20 -9
  7. package/lib/types/assistant.d.ts +29 -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 +136 -27
  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 +31 -0
  14. package/lib/types/client/locales.d.ts +15 -70
  15. package/lib/types/client/mount.d.ts +0 -2
  16. package/lib/types/client/panel/AiTag.d.ts +1 -0
  17. package/lib/types/client/panel/AssistantTab.d.ts +4 -1
  18. package/lib/types/client/panel/AuthorHome.d.ts +13 -11
  19. package/lib/types/client/panel/BookAnalysisView.d.ts +4 -0
  20. package/lib/types/client/panel/CmdPalette.d.ts +12 -0
  21. package/lib/types/client/panel/CreateBookView.d.ts +5 -1
  22. package/lib/types/client/panel/DirectorView.d.ts +7 -0
  23. package/lib/types/client/panel/IdeaInspirationView.d.ts +6 -0
  24. package/lib/types/client/panel/KnowledgeBaseView.d.ts +4 -0
  25. package/lib/types/client/panel/LiveFeedLog.d.ts +13 -0
  26. package/lib/types/client/panel/MarketRadarView.d.ts +5 -0
  27. package/lib/types/client/panel/ModelManager.d.ts +2 -2
  28. package/lib/types/client/panel/NovelPanel.d.ts +6 -1
  29. package/lib/types/client/panel/PageHeader.d.ts +18 -0
  30. package/lib/types/client/panel/PromptSlotsView.d.ts +11 -0
  31. package/lib/types/client/panel/SettingsView.d.ts +12 -9
  32. package/lib/types/client/panel/ShelfView.d.ts +10 -1
  33. package/lib/types/client/panel/SubPage.d.ts +27 -0
  34. package/lib/types/client/panel/TensionView.d.ts +18 -0
  35. package/lib/types/client/panel/TimelineView.d.ts +18 -0
  36. package/lib/types/client/panel/helpers.d.ts +5 -3
  37. package/lib/types/client/panel/market-radar-state.d.ts +56 -0
  38. package/lib/types/client/panel/outline-markdown.d.ts +112 -0
  39. package/lib/types/client/panel/status-badge.d.ts +13 -0
  40. package/lib/types/client/panel/storage-parse.d.ts +46 -0
  41. package/lib/types/client/panel/toast.d.ts +2 -0
  42. package/lib/types/client/panel/usePersistentState.d.ts +17 -0
  43. package/lib/types/client/panel/views.d.ts +21 -35
  44. package/lib/types/client/run-status.d.ts +21 -0
  45. package/lib/types/client/sidebar-entry.d.ts +0 -2
  46. package/lib/types/digest-parse.d.ts +29 -0
  47. package/lib/types/docx-core.d.ts +16 -0
  48. package/lib/types/docx.d.ts +2 -3
  49. package/lib/types/engine.d.ts +150 -103
  50. package/lib/types/global-assets.d.ts +6 -0
  51. package/lib/types/home.d.ts +11 -0
  52. package/lib/types/index.d.ts +26 -12
  53. package/lib/types/llm-live.d.ts +70 -0
  54. package/lib/types/llm-retry.d.ts +38 -0
  55. package/lib/types/market-radar-scan.d.ts +18 -0
  56. package/lib/types/market-radar-sources.d.ts +31 -0
  57. package/lib/types/migrate-output.d.ts +25 -0
  58. package/lib/types/model-capability.d.ts +119 -0
  59. package/lib/types/model-request.d.ts +36 -0
  60. package/lib/types/output-budget.d.ts +86 -0
  61. package/lib/types/plotline-align.d.ts +35 -0
  62. package/lib/types/prompt-slots.d.ts +57 -0
  63. package/lib/types/prompting.d.ts +10 -0
  64. package/lib/types/protocol.d.ts +841 -601
  65. package/lib/types/revision.d.ts +76 -0
  66. package/lib/types/routes.d.ts +9 -3
  67. package/lib/types/run-selection.d.ts +51 -0
  68. package/lib/types/run.d.ts +32 -1
  69. package/lib/types/settings-persist.d.ts +59 -0
  70. package/lib/types/snapshots.d.ts +46 -0
  71. package/lib/types/stage-contract.d.ts +58 -0
  72. package/lib/types/stream-fallback.d.ts +60 -0
  73. package/lib/types/strip-headings.d.ts +33 -0
  74. package/lib/types/tension.d.ts +53 -0
  75. package/lib/types/timeline.d.ts +37 -0
  76. package/package.json +50 -27
  77. package/assets/styles/arcane-thick-3d.webp +0 -0
  78. package/assets/styles/chinese-ink.webp +0 -0
  79. package/assets/styles/clay-stopmotion-3d.webp +0 -0
  80. package/assets/styles/dark-ghibli.webp +0 -0
  81. package/assets/styles/dark-gothic-3d.webp +0 -0
  82. package/assets/styles/film-photo.webp +0 -0
  83. package/assets/styles/guofeng-heavy.webp +0 -0
  84. package/assets/styles/guoman-2d-gufeng.webp +0 -0
  85. package/assets/styles/guoman-3d-tianyuan.webp +0 -0
  86. package/assets/styles/guoman-3d-xuanhuan.webp +0 -0
  87. package/assets/styles/horror-game-3d.webp +0 -0
  88. package/assets/styles/hyperreal-3d.webp +0 -0
  89. package/assets/styles/japan-cel-dark.webp +0 -0
  90. package/assets/styles/korean-webtoon.webp +0 -0
  91. package/assets/styles/low-cyberpunk-3d.webp +0 -0
  92. package/assets/styles/nextgen-cg.webp +0 -0
  93. package/assets/styles/noir-film.webp +0 -0
  94. package/assets/styles/openworld-survival.webp +0 -0
  95. package/assets/styles/paper-cut-3d.webp +0 -0
  96. package/assets/styles/pixar-adult-3d.webp +0 -0
  97. package/assets/styles/pop-marvel-2d.webp +0 -0
  98. package/assets/styles/sandiao-qban.webp +0 -0
  99. package/assets/styles/shinkai-anime.webp +0 -0
  100. package/assets/styles/tactical-stealth.webp +0 -0
  101. package/assets/styles/urban-lightreal-3d.webp +0 -0
  102. package/assets/styles/vaporwave-3d.webp +0 -0
  103. package/assets/styles/vhs90.webp +0 -0
  104. package/lib/types/client/panel/BookshelfBar.d.ts +0 -11
  105. package/lib/types/client/panel/FlowGuide.d.ts +0 -22
  106. package/lib/types/client/panel/MangaRoleLibrary.d.ts +0 -20
  107. package/lib/types/client/panel/MangaWorkspace.d.ts +0 -12
  108. package/lib/types/client/panel/ModelPicker.d.ts +0 -11
  109. package/lib/types/client/panel/ProgressHomeView.d.ts +0 -5
  110. package/lib/types/client/panel/PropLibrary.d.ts +0 -8
  111. package/lib/types/client/panel/SceneLibrary.d.ts +0 -16
  112. package/lib/types/client/panel/StoryboardTab.d.ts +0 -19
  113. package/lib/types/client/panel/StyleCard.d.ts +0 -8
  114. package/lib/types/client/panel/StyleGallery.d.ts +0 -1
  115. package/lib/types/comic-presets.d.ts +0 -12
  116. package/lib/types/manga-genre-rules.d.ts +0 -22
  117. package/lib/types/prompt-utils.d.ts +0 -35
  118. package/lib/types/review-policy.d.ts +0 -97
  119. package/lib/types/shot-language.d.ts +0 -46
  120. package/lib/types/story-beat-language.d.ts +0 -35
  121. package/lib/types/style-library.d.ts +0 -33
  122. package/skills/chapter-batch/SKILL.md +0 -81
  123. package/src/ai-scan.ts +0 -179
  124. package/src/assets.ts +0 -879
  125. package/src/assistant.ts +0 -770
  126. package/src/author-assets.ts +0 -147
  127. package/src/bookshelf.ts +0 -167
  128. package/src/client/api.ts +0 -617
  129. package/src/client/css-modules.d.ts +0 -8
  130. package/src/client/docx.ts +0 -69
  131. package/src/client/index.ts +0 -34
  132. package/src/client/locales.ts +0 -418
  133. package/src/client/mount.tsx +0 -97
  134. package/src/client/mount.tsx._new +0 -97
  135. package/src/client/mount.tsx._nf +0 -97
  136. package/src/client/mount.tsx._tmp +0 -97
  137. package/src/client/panel/AdaptModeView.tsx +0 -520
  138. package/src/client/panel/AssetsTab.tsx +0 -458
  139. package/src/client/panel/AssistantTab.tsx +0 -301
  140. package/src/client/panel/AuthorAssetsView.tsx +0 -208
  141. package/src/client/panel/AuthorHome.tsx +0 -204
  142. package/src/client/panel/BookshelfBar.tsx +0 -170
  143. package/src/client/panel/CreateBookView.tsx +0 -352
  144. package/src/client/panel/FlowGuide.tsx +0 -84
  145. package/src/client/panel/GlobalAssetLibraryView.tsx +0 -172
  146. package/src/client/panel/ImportModal.tsx +0 -303
  147. package/src/client/panel/MangaRoleLibrary.tsx +0 -1002
  148. package/src/client/panel/MangaWorkspace.tsx +0 -715
  149. package/src/client/panel/ModelManager.tsx +0 -205
  150. package/src/client/panel/NovelPanel.tsx +0 -4620
  151. package/src/client/panel/ProgressConsole.tsx +0 -64
  152. package/src/client/panel/ProgressHomeView.tsx +0 -87
  153. package/src/client/panel/PropLibrary.tsx +0 -175
  154. package/src/client/panel/ReaderView.tsx +0 -306
  155. package/src/client/panel/ReasoningSection.tsx +0 -31
  156. package/src/client/panel/RunPanel.tsx +0 -204
  157. package/src/client/panel/SceneLibrary.tsx +0 -453
  158. package/src/client/panel/SettingsView.tsx +0 -286
  159. package/src/client/panel/ShelfView.tsx +0 -242
  160. package/src/client/panel/StoryboardTab.tsx +0 -472
  161. package/src/client/panel/StyleCard.tsx +0 -90
  162. package/src/client/panel/StyleGallery.tsx +0 -58
  163. package/src/client/panel/WorldTab.tsx +0 -202
  164. package/src/client/panel/controller.ts +0 -45
  165. package/src/client/panel/helpers.ts +0 -67
  166. package/src/client/panel/panel.module.css +0 -4360
  167. package/src/client/panel/views.tsx +0 -314
  168. package/src/client/sidebar-entry.ts +0 -122
  169. package/src/client/text.ts +0 -28
  170. package/src/comic-presets.ts +0 -67
  171. package/src/docx.ts +0 -83
  172. package/src/engine.ts +0 -5200
  173. package/src/index.ts +0 -329
  174. package/src/manga-genre-rules.ts +0 -87
  175. package/src/novel-context.ts +0 -287
  176. package/src/prompt-utils.ts +0 -73
  177. package/src/protocol.ts +0 -2233
  178. package/src/review-policy.ts +0 -161
  179. package/src/routes.ts +0 -3419
  180. package/src/run.ts +0 -331
  181. package/src/shot-language.ts +0 -181
  182. package/src/story-beat-language.ts +0 -130
  183. package/src/style-library.ts +0 -84
@@ -1,4360 +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: 240px;
1762
- max-height: 480px;
1763
- overflow-y: auto;
1764
- display: flex;
1765
- flex-direction: column;
1766
- gap: var(--nf-space-10, 10px);
1767
- padding: var(--nf-space-14, 14px);
1768
- border: 1px solid var(--nf-border);
1769
- border-radius: var(--nf-radius-12, 12px);
1770
- background: var(--nf-bg-inset);
1771
- }
1772
-
1773
- .chatBubbleUser {
1774
- align-self: flex-end;
1775
- max-width: 90%;
1776
- background: linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));
1777
- color: var(--nf-accent-fg);
1778
- border-radius: var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-4, 4px) var(--nf-radius-14, 14px);
1779
- padding: var(--nf-space-10, 9px) var(--nf-space-14, 14px);
1780
- font-size: var(--nf-fs-14, 13px);
1781
- box-shadow: 0 2px 6px rgba(77, 107, 254, 0.2);
1782
- }
1783
-
1784
- .chatBubbleAssistant {
1785
- align-self: flex-start;
1786
- max-width: 92%;
1787
- background: var(--nf-bg-raise);
1788
- color: var(--nf-text);
1789
- border: 1px solid var(--nf-border);
1790
- border-radius: var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-14, 14px) var(--nf-radius-4, 4px);
1791
- padding: var(--nf-space-10, 9px) var(--nf-space-14, 14px);
1792
- font-size: var(--nf-fs-14, 13px);
1793
- box-shadow: var(--nf-shadow);
1794
- }
1795
-
1796
- .chatRole {
1797
- font-size: var(--nf-fs-12, 11px);
1798
- color: var(--nf-text-3);
1799
- margin-bottom: 3px;
1800
- font-weight: 600;
1801
- }
1802
-
1803
- /* Live tool output (text streaming while a chapter is generated/rewritten). */
1804
- .toolLive {
1805
- margin-top: 6px;
1806
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
1807
- border-radius: var(--nf-radius-8, 8px);
1808
- background: var(--nf-bg-inset);
1809
- border: 1px dashed var(--nf-border-strong);
1810
- font-size: var(--nf-fs-12, 12px);
1811
- line-height: 1.7;
1812
- white-space: pre-wrap;
1813
- word-break: break-all;
1814
- color: var(--nf-text-2);
1815
- max-height: 180px;
1816
- overflow-y: auto;
1817
- }
1818
-
1819
- /* 助手状态条:编辑老师正在做什么 */
1820
- .assistantStatus {
1821
- flex: none;
1822
- margin-top: 6px;
1823
- padding: var(--nf-space-6, 6px) var(--nf-space-12, 12px);
1824
- border-radius: var(--nf-radius-999, 999px);
1825
- font-size: var(--nf-fs-12, 12px);
1826
- color: var(--nf-text-2);
1827
- background: var(--nf-bg-inset);
1828
- border: 1px solid var(--nf-border);
1829
- display: flex;
1830
- align-items: center;
1831
- gap: var(--nf-space-6, 6px);
1832
- }
1833
-
1834
- .assistantStatusBusy {
1835
- color: var(--nf-accent);
1836
- border-color: var(--nf-accent);
1837
- background: var(--nf-accent-soft);
1838
- font-weight: 600;
1839
- }
1840
-
1841
- /* 工具步骤卡片 */
1842
- .toolSteps {
1843
- display: flex;
1844
- flex-direction: column;
1845
- gap: var(--nf-space-4, 4px);
1846
- margin-top: 6px;
1847
- }
1848
-
1849
- .toolStep {
1850
- display: flex;
1851
- align-items: center;
1852
- gap: var(--nf-space-8, 8px);
1853
- padding: var(--nf-space-6, 5px) var(--nf-space-10, 10px);
1854
- border-radius: var(--nf-radius-8, 8px);
1855
- font-size: var(--nf-fs-12, 12px);
1856
- background: var(--nf-bg-inset);
1857
- border: 1px solid var(--nf-border);
1858
- }
1859
-
1860
- .toolStepActive {
1861
- border-color: var(--nf-accent);
1862
- background: var(--nf-accent-soft);
1863
- }
1864
-
1865
- .toolStepError {
1866
- border-color: var(--nf-error);
1867
- background: color-mix(in srgb, var(--nf-error) 8%, transparent);
1868
- }
1869
-
1870
- .toolStepIcon {
1871
- flex: none;
1872
- font-size: var(--nf-fs-14, 13px);
1873
- }
1874
-
1875
- .toolStepName {
1876
- flex: 1;
1877
- min-width: 0;
1878
- font-weight: 600;
1879
- overflow: hidden;
1880
- text-overflow: ellipsis;
1881
- white-space: nowrap;
1882
- }
1883
-
1884
- .toolStepStatus {
1885
- flex: none;
1886
- color: var(--nf-text-2);
1887
- font-size: var(--nf-fs-12, 11px);
1888
- }
1889
-
1890
- .toolStepActive .toolStepStatus {
1891
- color: var(--nf-accent);
1892
- }
1893
-
1894
- .toolStepError .toolStepStatus {
1895
- color: var(--nf-error);
1896
- }
1897
-
1898
- .toolStepDetail {
1899
- width: 100%;
1900
- color: var(--nf-error);
1901
- font-size: var(--nf-fs-12, 11px);
1902
- word-break: break-all;
1903
- }
1904
-
1905
- /* ------------------------------------------------------------ progress console */
1906
-
1907
- .progress {
1908
- border: 1px solid var(--nf-border);
1909
- border-radius: var(--nf-radius-10, 10px);
1910
- padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
1911
- font-size: var(--nf-fs-12, 12px);
1912
- min-height: 60px;
1913
- max-height: 220px;
1914
- overflow: auto;
1915
- white-space: pre-wrap;
1916
- word-break: break-all;
1917
- color: var(--nf-text-2);
1918
- font-family: var(--nf-font-mono);
1919
- background: var(--nf-bg-inset);
1920
- line-height: 1.8;
1921
- }
1922
-
1923
- .progressLine {
1924
- color: var(--nf-text-2);
1925
- opacity: 0.9;
1926
- }
1927
-
1928
- .progressLineLive {
1929
- color: var(--nf-accent);
1930
- font-weight: 600;
1931
- display: flex;
1932
- align-items: center;
1933
- gap: var(--nf-space-8, 8px);
1934
- }
1935
-
1936
- .progressBar {
1937
- display: inline-block;
1938
- flex: none;
1939
- width: 110px;
1940
- height: 6px;
1941
- border-radius: var(--nf-radius-999, 999px);
1942
- background: var(--nf-border);
1943
- overflow: hidden;
1944
- }
1945
-
1946
- .progressBarFill {
1947
- display: block;
1948
- height: 100%;
1949
- border-radius: var(--nf-radius-4, 3px);
1950
- background: var(--nf-accent);
1951
- transition: width 0.3s ease;
1952
- }
1953
-
1954
- /* Prominent top-of-panel generation progress (visible on every tab). */
1955
- .busyRow {
1956
- display: flex;
1957
- align-items: center;
1958
- justify-content: space-between;
1959
- gap: var(--nf-space-12, 12px);
1960
- flex-wrap: wrap;
1961
- }
1962
-
1963
- .liveText {
1964
- font-size: var(--nf-fs-12, 12px);
1965
- font-variant-numeric: tabular-nums;
1966
- color: var(--nf-text-2);
1967
- }
1968
-
1969
- .bigProgressBar {
1970
- margin-top: 10px;
1971
- height: 8px;
1972
- border-radius: var(--nf-radius-999, 999px);
1973
- background: var(--nf-border);
1974
- overflow: hidden;
1975
- }
1976
-
1977
- .bigProgressBarFill {
1978
- display: block;
1979
- height: 100%;
1980
- border-radius: var(--nf-radius-999, 999px);
1981
- background: linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2, var(--nf-accent)));
1982
- transition: width 0.3s ease;
1983
- }
1984
-
1985
- /* Draft-vs-original diff view (polish / rewrite comparison). */
1986
- .diffLegend {
1987
- display: flex;
1988
- align-items: center;
1989
- gap: var(--nf-space-14, 14px);
1990
- flex-wrap: wrap;
1991
- margin: 6px 0 8px;
1992
- font-size: var(--nf-fs-12, 12px);
1993
- }
1994
-
1995
- .legendOld {
1996
- color: var(--nf-error);
1997
- font-weight: 700;
1998
- }
1999
-
2000
- .legendNew {
2001
- color: var(--nf-success);
2002
- font-weight: 700;
2003
- }
2004
-
2005
- .onlyChanges {
2006
- display: inline-flex;
2007
- align-items: center;
2008
- gap: var(--nf-space-4, 4px);
2009
- color: var(--nf-text-2);
2010
- cursor: pointer;
2011
- margin-left: auto;
2012
- }
2013
-
2014
- .diffList {
2015
- flex: 1;
2016
- min-height: 0;
2017
- overflow-y: auto;
2018
- border: 1px solid var(--nf-border);
2019
- border-radius: var(--nf-radius-8, 8px);
2020
- background: var(--nf-bg-inset);
2021
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
2022
- display: flex;
2023
- flex-direction: column;
2024
- gap: var(--nf-space-8, 8px);
2025
- font-size: var(--nf-fs-14, 13px);
2026
- line-height: 1.7;
2027
- }
2028
-
2029
- .diffSame {
2030
- border: 1px dashed var(--nf-border);
2031
- border-radius: var(--nf-radius-6, 6px);
2032
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
2033
- color: var(--nf-text-2);
2034
- opacity: 0.85;
2035
- }
2036
-
2037
- .diffSame summary {
2038
- cursor: pointer;
2039
- font-size: var(--nf-fs-12, 12px);
2040
- user-select: none;
2041
- }
2042
-
2043
- .diffSameBody {
2044
- margin-top: 6px;
2045
- white-space: pre-wrap;
2046
- }
2047
-
2048
- /* change 块:左右两栏(左原稿 / 右新稿),带标签徽标 */
2049
- .diffChange {
2050
- display: grid;
2051
- grid-template-columns: 1fr 1fr;
2052
- border: 1px solid var(--nf-border);
2053
- border-radius: var(--nf-radius-8, 8px);
2054
- overflow: hidden;
2055
- }
2056
-
2057
- .diffColumn {
2058
- display: flex;
2059
- flex-direction: column;
2060
- gap: var(--nf-space-6, 6px);
2061
- min-width: 0;
2062
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
2063
- }
2064
-
2065
- .diffColumn:first-child {
2066
- border-right: 1px solid var(--nf-border);
2067
- }
2068
-
2069
- .diffTagOld,
2070
- .diffTagNew {
2071
- align-self: flex-start;
2072
- flex: none;
2073
- font-size: var(--nf-fs-12, 11px);
2074
- font-weight: 700;
2075
- border-radius: var(--nf-radius-4, 4px);
2076
- padding: var(--nf-space-2, 1px) var(--nf-space-8, 7px);
2077
- letter-spacing: 0.5px;
2078
- }
2079
-
2080
- .diffTagOld {
2081
- color: var(--nf-error);
2082
- background: color-mix(in srgb, var(--nf-error) 16%, transparent);
2083
- border: 1px solid color-mix(in srgb, var(--nf-error) 45%, transparent);
2084
- }
2085
-
2086
- .diffTagNew {
2087
- color: var(--nf-success);
2088
- background: color-mix(in srgb, var(--nf-success) 16%, transparent);
2089
- border: 1px solid color-mix(in srgb, var(--nf-success) 45%, transparent);
2090
- }
2091
-
2092
- .diffOld {
2093
- color: var(--nf-error);
2094
- white-space: pre-wrap;
2095
- text-decoration: line-through;
2096
- text-decoration-color: color-mix(in srgb, var(--nf-error) 55%, transparent);
2097
- }
2098
-
2099
- .diffNew {
2100
- color: var(--nf-success);
2101
- white-space: pre-wrap;
2102
- font-weight: 500;
2103
- }
2104
-
2105
- .diffDel {
2106
- display: flex;
2107
- flex-direction: column;
2108
- gap: var(--nf-space-4, 4px);
2109
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
2110
- border-radius: var(--nf-radius-6, 6px);
2111
- border: 1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);
2112
- background: color-mix(in srgb, var(--nf-error) 7%, transparent);
2113
- }
2114
-
2115
- .diffAdd {
2116
- display: flex;
2117
- flex-direction: column;
2118
- gap: var(--nf-space-4, 4px);
2119
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
2120
- border-radius: var(--nf-radius-6, 6px);
2121
- border: 1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);
2122
- background: color-mix(in srgb, var(--nf-success) 7%, transparent);
2123
- }
2124
-
2125
- .diffText {
2126
- white-space: pre-wrap;
2127
- }
2128
-
2129
- .diffDel .diffText {
2130
- color: var(--nf-error);
2131
- text-decoration: line-through;
2132
- text-decoration-color: color-mix(in srgb, var(--nf-error) 50%, transparent);
2133
- }
2134
-
2135
- .diffAdd .diffText {
2136
- color: var(--nf-success);
2137
- }
2138
-
2139
- /* Chapter editor page: full-bleed, flex-fills the content pane (no card box). */
2140
- .wsPage {
2141
- display: flex;
2142
- flex-direction: column;
2143
- flex: 1;
2144
- min-height: 0;
2145
- gap: var(--nf-space-10, 10px);
2146
- }
2147
-
2148
- .wsPageHeader {
2149
- display: flex;
2150
- align-items: center;
2151
- gap: var(--nf-space-8, 8px);
2152
- flex: none;
2153
- flex-wrap: wrap;
2154
- }
2155
-
2156
- /* 已采纳草稿的结论横幅(工作区顶部)。 */
2157
- .wsAppliedBanner {
2158
- flex: none;
2159
- display: flex;
2160
- align-items: center;
2161
- gap: var(--nf-space-8, 8px);
2162
- flex-wrap: wrap;
2163
- padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
2164
- border: 1px solid var(--nf-success);
2165
- border-radius: var(--nf-radius-10, 10px);
2166
- background: color-mix(in srgb, var(--nf-success) 8%, transparent);
2167
- font-size: var(--nf-fs-12, 12px);
2168
- font-weight: 600;
2169
- }
2170
-
2171
- .wsColumns {
2172
- display: grid;
2173
- grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
2174
- gap: var(--nf-space-14, 14px);
2175
- flex: 1;
2176
- min-height: 0;
2177
- }
2178
-
2179
- .wsColumn {
2180
- display: flex;
2181
- flex-direction: column;
2182
- gap: var(--nf-space-8, 8px);
2183
- min-width: 0;
2184
- min-height: 0;
2185
- }
2186
-
2187
- .wsEditor {
2188
- flex: 1;
2189
- min-height: 0;
2190
- resize: vertical;
2191
- font-family: var(--nf-font);
2192
- font-size: var(--nf-fs-14, 13px);
2193
- line-height: 1.75;
2194
- white-space: pre-wrap;
2195
- }
2196
-
2197
- .wsSelected {
2198
- border: 1px solid var(--nf-accent);
2199
- border-radius: var(--nf-radius-6, 6px);
2200
- padding: var(--nf-space-6, 6px) var(--nf-space-10, 10px);
2201
- background: color-mix(in srgb, var(--nf-accent) 8%, transparent);
2202
- max-height: 120px;
2203
- overflow: auto;
2204
- }
2205
-
2206
- .wsSelectedText {
2207
- margin-top: 4px;
2208
- font-size: var(--nf-fs-12, 12px);
2209
- color: var(--nf-text-2);
2210
- white-space: pre-wrap;
2211
- }
2212
-
2213
- .wsPreview {
2214
- border: 1px solid var(--nf-border);
2215
- border-radius: var(--nf-radius-8, 8px);
2216
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
2217
- display: flex;
2218
- flex-direction: column;
2219
- gap: var(--nf-space-8, 8px);
2220
- background: var(--nf-bg-inset);
2221
- }
2222
-
2223
- .wsPreviewText {
2224
- margin: 0;
2225
- flex: 1;
2226
- min-height: 0;
2227
- overflow: auto;
2228
- font-size: var(--nf-fs-14, 13px);
2229
- line-height: 1.7;
2230
- white-space: pre-wrap;
2231
- color: var(--nf-text);
2232
- }
2233
-
2234
- /* Assets overview status grid (AI-Novel-Writing-Assistant AssetLibraryStatusGrid). */
2235
- .assetGrid {
2236
- display: grid;
2237
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
2238
- gap: var(--nf-space-10, 10px);
2239
- }
2240
-
2241
- /* 按分类分组的资产列表 */
2242
- .assetGroups {
2243
- display: flex;
2244
- flex-direction: column;
2245
- gap: var(--nf-space-14, 14px);
2246
- }
2247
- .assetGroup {
2248
- display: flex;
2249
- flex-direction: column;
2250
- gap: var(--nf-space-10, 10px);
2251
- }
2252
- .assetGroupHeader {
2253
- font-size: 14px;
2254
- font-weight: 600;
2255
- color: var(--nf-accent);
2256
- padding-bottom: 2px;
2257
- border-bottom: 1px solid var(--nf-glass-border);
2258
- display: flex;
2259
- align-items: center;
2260
- gap: 8px;
2261
- }
2262
-
2263
- .assetStat {
2264
- border: 1px solid var(--nf-glass-border);
2265
- border-radius: var(--nf-radius-14, 14px);
2266
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
2267
- display: flex;
2268
- flex-direction: column;
2269
- gap: var(--nf-space-4, 4px);
2270
- background: var(--nf-glass-face);
2271
- box-shadow: var(--nf-card-shadow), inset 0 1px 0 var(--nf-glass-sheen);
2272
- -webkit-backdrop-filter: blur(30px) saturate(180%);
2273
- backdrop-filter: blur(30px) saturate(180%);
2274
- transition: transform 0.22s ease, box-shadow 0.22s ease;
2275
- }
2276
-
2277
- .assetStat:hover {
2278
- transform: translateY(-3px);
2279
- box-shadow: var(--nf-card-shadow-hover), inset 0 1px 0 var(--nf-glass-sheen);
2280
- }
2281
-
2282
- .assetStatLabel {
2283
- font-size: var(--nf-fs-12, 11px);
2284
- color: var(--nf-text-2);
2285
- opacity: 0.9;
2286
- }
2287
-
2288
- .assetStatValue {
2289
- font-size: var(--nf-fs-14, 15px);
2290
- font-weight: 700;
2291
- line-height: 1.2;
2292
- color: var(--nf-text);
2293
- }
2294
-
2295
- .assetStatDetail {
2296
- font-size: var(--nf-fs-12, 11px);
2297
- color: var(--nf-text-2);
2298
- opacity: 0.85;
2299
- overflow: hidden;
2300
- text-overflow: ellipsis;
2301
- white-space: nowrap;
2302
- }
2303
-
2304
- /* ------------------------------------------------ dashboard (workflow tab) */
2305
-
2306
- .dashHero {
2307
- position: relative;
2308
- border: 1px solid var(--nf-glass-border);
2309
- border-radius: var(--nf-radius-22, 22px);
2310
- /* 主容器统一:与设置页卡片同一 --nf-card-pad */
2311
- padding: var(--nf-card-pad, 20px 22px);
2312
- background: var(--nf-glass-face);
2313
- box-shadow:
2314
- var(--nf-card-shadow),
2315
- inset 0 1.5px 0 var(--nf-glass-sheen),
2316
- inset 0 -1px 0 rgba(255, 255, 255, 0.25);
2317
- -webkit-backdrop-filter: blur(30px) saturate(180%);
2318
- backdrop-filter: blur(30px) saturate(180%);
2319
- display: flex;
2320
- flex-direction: column;
2321
- gap: var(--nf-space-14, 14px);
2322
- transition: transform 0.22s ease, box-shadow 0.22s ease;
2323
- }
2324
-
2325
- /* Same Liquid-Glass surface as .card: bright core + hairline + green tint. */
2326
- .dashHero::before {
2327
- content: '';
2328
- position: absolute;
2329
- inset: 0;
2330
- border-radius: inherit;
2331
- pointer-events: none;
2332
- background:
2333
- radial-gradient(46% 40% at 92% -10%, color-mix(in srgb, var(--nf-accent) 13%, transparent), transparent 62%),
2334
- var(--nf-glass-core),
2335
- linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px,
2336
- linear-gradient(156deg, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0) 55%);
2337
- z-index: 0;
2338
- }
2339
-
2340
- .dashHero::after {
2341
- content: '';
2342
- position: absolute;
2343
- inset: 0;
2344
- border-radius: inherit;
2345
- pointer-events: none;
2346
- background: var(--nf-glass-noise);
2347
- opacity: 0.06;
2348
- z-index: 0;
2349
- }
2350
-
2351
- .dashHero:hover {
2352
- transform: translateY(-3px);
2353
- box-shadow:
2354
- var(--nf-card-shadow-hover),
2355
- inset 0 1.5px 0 var(--nf-glass-sheen),
2356
- inset 0 -1px 0 rgba(255, 255, 255, 0.25);
2357
- }
2358
-
2359
- .dashHero > * {
2360
- position: relative;
2361
- z-index: 1;
2362
- }
2363
-
2364
- .dashHeroEyebrow {
2365
- display: inline-flex;
2366
- align-items: center;
2367
- gap: var(--nf-space-6, 6px);
2368
- font-size: var(--nf-fs-14, 13px);
2369
- font-weight: 600;
2370
- color: var(--nf-accent);
2371
- }
2372
-
2373
- .dashHeroSparkle {
2374
- font-size: var(--nf-fs-14, 14px);
2375
- }
2376
-
2377
- .dashHeroTitle {
2378
- display: flex;
2379
- flex-direction: column;
2380
- gap: var(--nf-space-2, 2px);
2381
- }
2382
-
2383
- .dashHeroBook {
2384
- margin: 0;
2385
- font-size: var(--nf-fs-24, 24px);
2386
- font-weight: 700;
2387
- letter-spacing: -0.3px;
2388
- line-height: 1.25;
2389
- }
2390
-
2391
- .dashHeroAction {
2392
- display: flex;
2393
- align-items: center;
2394
- gap: var(--nf-space-12, 12px);
2395
- border: 1px solid var(--nf-glass-border);
2396
- border-radius: var(--nf-radius-14, 14px);
2397
- background: var(--nf-glass-inset);
2398
- box-shadow: inset 0 1px 0 var(--nf-glass-sheen);
2399
- padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
2400
- }
2401
-
2402
- .dashHeroArrow {
2403
- flex: none;
2404
- width: 28px;
2405
- height: var(--nf-ctrl-s, 28px);
2406
- border-radius: 50%;
2407
- background: var(--nf-accent);
2408
- color: #fff;
2409
- display: inline-flex;
2410
- align-items: center;
2411
- justify-content: center;
2412
- font-size: var(--nf-fs-14, 14px);
2413
- }
2414
-
2415
- .dashHeroActionBody {
2416
- flex: 1;
2417
- min-width: 0;
2418
- display: flex;
2419
- flex-direction: column;
2420
- gap: var(--nf-space-2, 2px);
2421
- }
2422
-
2423
- .dashHeroActionTitle {
2424
- font-size: var(--nf-fs-14, 14px);
2425
- font-weight: 600;
2426
- }
2427
-
2428
- .dashJourney {
2429
- display: flex;
2430
- flex-direction: column;
2431
- gap: var(--nf-space-6, 6px);
2432
- }
2433
-
2434
- .dashJourneyBar {
2435
- height: 6px;
2436
- border-radius: var(--nf-radius-999, 999px);
2437
- background: var(--nf-border);
2438
- overflow: hidden;
2439
- }
2440
-
2441
- .dashJourneyFill {
2442
- display: block;
2443
- height: 100%;
2444
- border-radius: var(--nf-radius-999, 999px);
2445
- background: linear-gradient(90deg, var(--nf-info), var(--nf-accent));
2446
- transition: width 0.4s ease;
2447
- }
2448
-
2449
- .dashJourneyStages {
2450
- display: grid;
2451
- grid-template-columns: repeat(6, minmax(0, 1fr));
2452
- gap: var(--nf-space-4, 4px);
2453
- }
2454
-
2455
- .dashStage {
2456
- display: flex;
2457
- flex-direction: column;
2458
- align-items: center;
2459
- gap: var(--nf-space-4, 3px);
2460
- font-size: var(--nf-fs-12, 11px);
2461
- color: var(--nf-text-3);
2462
- text-align: center;
2463
- white-space: nowrap;
2464
- }
2465
-
2466
- .dashStageDot {
2467
- width: 18px;
2468
- height: 18px;
2469
- border-radius: 50%;
2470
- border: 1px solid var(--nf-border-strong, var(--nf-text-3));
2471
- display: inline-flex;
2472
- align-items: center;
2473
- justify-content: center;
2474
- font-size: var(--nf-fs-12, 10px);
2475
- background: var(--nf-bg-base);
2476
- }
2477
-
2478
- .dashStageDone {
2479
- color: var(--nf-text-2);
2480
- }
2481
-
2482
- .dashStageDone .dashStageDot {
2483
- background: var(--nf-success);
2484
- border-color: var(--nf-success);
2485
- color: #fff;
2486
- }
2487
-
2488
- .dashStageCurrent {
2489
- color: var(--nf-accent);
2490
- font-weight: 600;
2491
- }
2492
-
2493
- .dashStageCurrent .dashStageDot {
2494
- border-color: var(--nf-accent);
2495
- color: var(--nf-accent);
2496
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--nf-accent) 18%, transparent);
2497
- }
2498
-
2499
- .dashFacts {
2500
- display: grid;
2501
- grid-template-columns: repeat(4, minmax(0, 1fr));
2502
- gap: var(--nf-space-8, 8px);
2503
- border-top: 1px solid var(--nf-border);
2504
- padding-top: var(--nf-space-12, 12px);
2505
- }
2506
-
2507
- .dashFact {
2508
- display: flex;
2509
- flex-direction: column;
2510
- gap: var(--nf-space-2, 2px);
2511
- min-width: 0;
2512
- }
2513
-
2514
- .dashFact b {
2515
- font-size: var(--nf-fs-14, 13px);
2516
- white-space: nowrap;
2517
- overflow: hidden;
2518
- text-overflow: ellipsis;
2519
- }
2520
-
2521
- .dashGrid {
2522
- display: grid;
2523
- grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
2524
- gap: var(--nf-space-14, 14px);
2525
- align-items: start;
2526
- }
2527
-
2528
- .todoItem {
2529
- display: flex;
2530
- align-items: center;
2531
- gap: var(--nf-space-10, 10px);
2532
- border-radius: var(--nf-radius-8, 8px);
2533
- padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
2534
- font-size: var(--nf-fs-12, 12.5px);
2535
- border: 1px solid var(--nf-border);
2536
- }
2537
-
2538
- .todoDanger {
2539
- border-color: color-mix(in srgb, var(--nf-error) 40%, transparent);
2540
- background: color-mix(in srgb, var(--nf-error) 8%, transparent);
2541
- }
2542
-
2543
- .todoWarning {
2544
- border-color: color-mix(in srgb, var(--nf-warn) 40%, transparent);
2545
- background: color-mix(in srgb, var(--nf-warn) 8%, transparent);
2546
- }
2547
-
2548
- .todoInfo {
2549
- border-color: color-mix(in srgb, var(--nf-info) 40%, transparent);
2550
- background: color-mix(in srgb, var(--nf-info) 7%, transparent);
2551
- }
2552
-
2553
- .todoText {
2554
- flex: 1;
2555
- min-width: 0;
2556
- display: flex;
2557
- flex-direction: column;
2558
- gap: var(--nf-space-2, 2px);
2559
- }
2560
-
2561
- /* 只读大纲(开书后的出生证明) */
2562
- .outlineReadonly {
2563
- margin: 0;
2564
- padding: var(--nf-space-12, 12px) var(--nf-space-14, 14px);
2565
- border: 1px solid var(--nf-border);
2566
- border-radius: var(--nf-radius-12, 12px);
2567
- background: var(--nf-bg-inset);
2568
- font-size: var(--nf-fs-12, 12.5px);
2569
- line-height: 1.8;
2570
- white-space: pre-wrap;
2571
- max-height: 480px;
2572
- overflow: auto;
2573
- user-select: text;
2574
- }
2575
-
2576
- /* 开书向导表单 */
2577
- .bookCreateOutline {
2578
- display: flex;
2579
- flex-direction: column;
2580
- gap: var(--nf-space-6, 6px);
2581
- align-items: flex-start;
2582
- }
2583
-
2584
- /* AI 助手悬浮窗:可拖动移动 + 右下角拉大小 */
2585
- .assistantFloat {
2586
- position: absolute;
2587
- z-index: 80;
2588
- display: flex;
2589
- flex-direction: column;
2590
- border: 1px solid var(--nf-border);
2591
- border-radius: var(--nf-radius-16, 16px);
2592
- background: var(--nf-bg-raise);
2593
- -webkit-backdrop-filter: blur(24px) saturate(180%);
2594
- backdrop-filter: blur(24px) saturate(180%);
2595
- box-shadow: var(--nf-shadow-lg);
2596
- overflow: hidden;
2597
- min-width: 320px;
2598
- min-height: 220px;
2599
- }
2600
-
2601
- .assistantFloatHeader {
2602
- flex: none;
2603
- display: flex;
2604
- align-items: center;
2605
- justify-content: space-between;
2606
- gap: var(--nf-space-8, 8px);
2607
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px) var(--nf-space-8, 8px) var(--nf-space-14, 14px);
2608
- cursor: grab;
2609
- user-select: none;
2610
- font-size: var(--nf-fs-14, 13px);
2611
- font-weight: 600;
2612
- border-bottom: 1px solid var(--nf-border);
2613
- background: var(--nf-bg-inset);
2614
- }
2615
-
2616
- .assistantFloatHeader:active {
2617
- cursor: grabbing;
2618
- }
2619
-
2620
- .assistantFloatBody {
2621
- flex: 1;
2622
- min-height: 0;
2623
- overflow: hidden;
2624
- display: flex;
2625
- padding: var(--nf-space-10, 10px);
2626
- }
2627
-
2628
- .assistantFloatBody > * {
2629
- flex: 1;
2630
- min-width: 0;
2631
- }
2632
-
2633
- .assistantResize {
2634
- position: absolute;
2635
- right: 0;
2636
- bottom: 0;
2637
- width: 20px;
2638
- height: 20px;
2639
- cursor: nwse-resize;
2640
- background:
2641
- linear-gradient(135deg, transparent 0 55%, var(--nf-border-strong) 55% 62%, transparent 62%) no-repeat 4px 4px / 12px 12px;
2642
- }
2643
-
2644
- /* 封面预览:完整显示(contain),不裁剪 */
2645
- .coverPreview {
2646
- flex: none;
2647
- width: 150px;
2648
- height: 200px;
2649
- border: 1px solid var(--nf-border);
2650
- border-radius: var(--nf-radius-12, 12px);
2651
- overflow: hidden;
2652
- background: var(--nf-bg-inset);
2653
- display: flex;
2654
- align-items: center;
2655
- justify-content: center;
2656
- }
2657
-
2658
- .coverPreview img {
2659
- width: 100%;
2660
- height: 100%;
2661
- object-fit: contain;
2662
- display: block;
2663
- }
2664
-
2665
- .coverPlaceholder {
2666
- font-size: var(--nf-fs-12, 12px);
2667
- color: var(--nf-text-3);
2668
- }
2669
-
2670
- /* ------------------------------------------------------------ shelf view */
2671
-
2672
- .shelfView {
2673
- flex: 1;
2674
- min-height: 0;
2675
- overflow: auto;
2676
- padding: var(--nf-container-pad, 20px 22px);
2677
- display: flex;
2678
- flex-direction: column;
2679
- gap: var(--nf-container-gap, 14px);
2680
- }
2681
-
2682
- /* ---- 作者级首页(书架左侧导航 + 内容区) ---- */
2683
- .authorHome {
2684
- display: flex;
2685
- flex: 1;
2686
- min-height: 0;
2687
- overflow: hidden;
2688
- position: relative;
2689
- z-index: 1;
2690
- }
2691
- .authorRail {
2692
- width: 180px;
2693
- flex-shrink: 0;
2694
- display: flex;
2695
- flex-direction: column;
2696
- gap: 4px;
2697
- padding: 14px 10px;
2698
- border-right: 1px solid var(--nf-glass-border);
2699
- background: var(--nf-glass-face);
2700
- }
2701
- .authorRailTitle {
2702
- display: flex;
2703
- align-items: center;
2704
- gap: 8px;
2705
- font-weight: 600;
2706
- padding: 4px 8px 12px;
2707
- color: var(--nf-accent);
2708
- }
2709
- .authorRailBtn {
2710
- display: flex;
2711
- align-items: center;
2712
- gap: 10px;
2713
- padding: 8px 12px;
2714
- border-radius: 10px;
2715
- background: transparent;
2716
- border: 1px solid transparent;
2717
- color: var(--nf-text);
2718
- cursor: pointer;
2719
- text-align: left;
2720
- width: 100%;
2721
- font-size: 14px;
2722
- }
2723
- .authorRailBtn:hover { background: color-mix(in srgb, var(--nf-accent) 12%, transparent); color: var(--nf-text); }
2724
- .authorRailBtnActive {
2725
- background: color-mix(in srgb, var(--nf-accent) 16%, var(--nf-glass-face));
2726
- border-color: var(--nf-accent);
2727
- color: var(--nf-accent);
2728
- font-weight: 600;
2729
- box-shadow: inset 0 0 0 1px var(--nf-accent);
2730
- }
2731
- .authorRailAbout { padding: 8px 12px; }
2732
- .authorContent { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
2733
-
2734
- /* ---- 作者级页面通用 ---- */
2735
- .authorPageBody {
2736
- display: flex;
2737
- flex-direction: column;
2738
- gap: 14px;
2739
- padding: var(--nf-container-pad, 20px 22px);
2740
- overflow: auto;
2741
- flex: 1;
2742
- min-height: 0;
2743
- }
2744
- .authorPageHeader {
2745
- display: flex;
2746
- align-items: flex-end;
2747
- justify-content: space-between;
2748
- gap: 14px;
2749
- flex-wrap: wrap;
2750
- }
2751
- .authorPageHero {
2752
- display: flex;
2753
- flex-direction: column;
2754
- gap: var(--nf-space-12, 12px);
2755
- padding: var(--nf-card-pad, 20px 22px);
2756
- border: 1px solid var(--nf-glass-border);
2757
- border-radius: var(--nf-radius-22, 22px);
2758
- background: var(--nf-glass-face);
2759
- box-shadow: var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);
2760
- -webkit-backdrop-filter: blur(26px) saturate(175%);
2761
- backdrop-filter: blur(26px) saturate(175%);
2762
- }
2763
- .noticeError {
2764
- padding: 10px 14px;
2765
- border-radius: 10px;
2766
- background: color-mix(in srgb, var(--nf-error) 14%, transparent);
2767
- color: var(--nf-error);
2768
- border: 1px solid var(--nf-error);
2769
- }
2770
- .noticeSuccess {
2771
- display: flex;
2772
- align-items: center;
2773
- gap: 10px;
2774
- flex-wrap: wrap;
2775
- padding: 10px 14px;
2776
- border-radius: 10px;
2777
- background: color-mix(in srgb, var(--nf-accent) 14%, transparent);
2778
- color: var(--nf-accent);
2779
- border: 1px solid var(--nf-accent);
2780
- }
2781
- .rowEnd { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
2782
-
2783
- /* ---- 作者资产库 ---- */
2784
- .assetFilterBar { display: flex; flex-wrap: wrap; gap: 8px; }
2785
- .assetFilterChip {
2786
- padding: 4px 10px;
2787
- border-radius: 999px;
2788
- border: 1px solid var(--nf-glass-border);
2789
- background: transparent;
2790
- color: var(--nf-text);
2791
- cursor: pointer;
2792
- }
2793
- .assetFilterChipActive { background: var(--nf-accent); color: #fff; border-color: transparent; }
2794
- .assetEditor {
2795
- display: flex;
2796
- flex-direction: column;
2797
- gap: 12px;
2798
- padding: 16px;
2799
- border: 1px solid var(--nf-glass-border);
2800
- border-radius: 14px;
2801
- background: var(--nf-glass-face);
2802
- }
2803
- .assetEditorRow { display: flex; gap: 12px; flex-wrap: wrap; }
2804
- .assetLabel {
2805
- display: flex;
2806
- flex-direction: column;
2807
- gap: 4px;
2808
- font-size: 12px;
2809
- color: var(--nf-muted);
2810
- flex: 1;
2811
- min-width: 180px;
2812
- }
2813
- .assetTextarea { min-height: 160px; resize: vertical; font-family: inherit; }
2814
- .assetGrid {
2815
- display: grid;
2816
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
2817
- gap: 14px;
2818
- }
2819
- .assetCard {
2820
- display: flex;
2821
- flex-direction: column;
2822
- gap: 8px;
2823
- padding: 14px;
2824
- border: 1px solid var(--nf-glass-border);
2825
- border-radius: 14px;
2826
- background: var(--nf-glass-face);
2827
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
2828
- }
2829
- .assetCardTop { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
2830
- .assetKind { font-size: 12px; font-weight: 600; }
2831
- .assetCardName { font-weight: 600; }
2832
- .assetCardContent { white-space: pre-wrap; font-size: 13px; color: var(--nf-text); max-height: 150px; overflow: auto; }
2833
- .assetCardFooter { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
2834
- .iconBtn {
2835
- display: inline-flex;
2836
- align-items: center;
2837
- justify-content: center;
2838
- padding: 4px;
2839
- border: 1px solid transparent;
2840
- background: transparent;
2841
- border-radius: 8px;
2842
- color: var(--nf-text);
2843
- cursor: pointer;
2844
- }
2845
- .iconBtn:hover { background: rgba(0,0,0,0.06); }
2846
-
2847
- /* ---- 改编模式 ---- */
2848
- .adaptInputCard {
2849
- display: flex;
2850
- flex-direction: column;
2851
- gap: 12px;
2852
- padding: 16px;
2853
- border: 1px solid var(--nf-glass-border);
2854
- border-radius: 14px;
2855
- background: var(--nf-glass-face);
2856
- }
2857
- .adaptTextarea { min-height: 220px; resize: vertical; }
2858
- .adaptResult { display: flex; flex-direction: column; gap: 14px; }
2859
- .adaptOutline {
2860
- padding: 10px 14px;
2861
- border-radius: 12px;
2862
- background: var(--nf-glass-face);
2863
- border: 1px solid var(--nf-glass-border);
2864
- }
2865
- .adaptMatrix {
2866
- display: grid;
2867
- grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
2868
- gap: 12px;
2869
- }
2870
- .dimCard {
2871
- display: flex;
2872
- flex-direction: column;
2873
- gap: 8px;
2874
- padding: 14px;
2875
- border: 1px solid var(--nf-glass-border);
2876
- border-radius: 14px;
2877
- background: var(--nf-glass-face);
2878
- }
2879
- .dimCardHead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
2880
- .dimTitle { font-weight: 600; }
2881
- .dimCurrent { font-size: 13px; white-space: pre-wrap; }
2882
- .dimCardSelected { border-color: var(--nf-accent); box-shadow: 0 0 0 1px var(--nf-accent); }
2883
- .dimEdit { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
2884
- .adaptOutlinePre { white-space: pre-wrap; font-size: 13px; max-height: 260px; overflow: auto; margin: 0; font-family: inherit; }
2885
- .adaptProposal {
2886
- display: flex;
2887
- flex-direction: column;
2888
- gap: 8px;
2889
- padding: 14px;
2890
- border: 1px solid var(--nf-glass-border);
2891
- border-radius: 14px;
2892
- background: var(--nf-glass-face);
2893
- }
2894
- .adaptTable { width: 100%; border-collapse: collapse; font-size: 13px; }
2895
- .adaptTable th, .adaptTable td { border: 1px solid var(--nf-glass-border); padding: 6px 8px; text-align: left; }
2896
- .adaptImpacts { display: flex; flex-direction: column; gap: 4px; }
2897
- .adaptImpact { font-size: 13px; }
2898
- .adaptTableScroll { overflow-x: auto; }
2899
- .adaptCell { min-width: 90px; width: 100%; }
2900
- .adaptRules { display: flex; flex-direction: column; gap: 10px; }
2901
- .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); }
2902
- .adaptRuleRow { display: flex; align-items: center; gap: 8px; }
2903
-
2904
- /* ---- 首页 AI 进度 ---- */
2905
- .progressOverview {
2906
- display: grid;
2907
- grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
2908
- gap: 12px;
2909
- }
2910
- .progressOverviewCard {
2911
- display: flex;
2912
- flex-direction: column;
2913
- gap: 4px;
2914
- padding: 14px;
2915
- border: 1px solid var(--nf-glass-border);
2916
- border-radius: 14px;
2917
- background: var(--nf-glass-face);
2918
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
2919
- }
2920
- .progressOverviewNum {
2921
- font-size: 24px;
2922
- font-weight: 700;
2923
- color: var(--nf-accent);
2924
- }
2925
- .progressTotalBar {
2926
- position: relative;
2927
- height: 14px;
2928
- border-radius: 999px;
2929
- background: var(--nf-glass-face);
2930
- border: 1px solid var(--nf-glass-border);
2931
- overflow: hidden;
2932
- }
2933
- .progressTotalFill {
2934
- position: absolute;
2935
- inset: 0 auto 0 0;
2936
- height: 100%;
2937
- background: linear-gradient(90deg, var(--nf-accent), var(--nf-info));
2938
- border-radius: 999px;
2939
- }
2940
- .progressTotalBar .meta {
2941
- position: absolute;
2942
- inset: 0;
2943
- display: flex;
2944
- align-items: center;
2945
- justify-content: center;
2946
- font-size: 11px;
2947
- font-weight: 600;
2948
- color: var(--nf-text);
2949
- }
2950
- .progressBookList {
2951
- display: flex;
2952
- flex-direction: column;
2953
- gap: 12px;
2954
- }
2955
- .progressBook {
2956
- display: flex;
2957
- flex-direction: column;
2958
- gap: 8px;
2959
- padding: 14px;
2960
- border: 1px solid var(--nf-glass-border);
2961
- border-radius: 14px;
2962
- background: var(--nf-glass-face);
2963
- }
2964
- .progressBookActive { border-color: var(--nf-accent); box-shadow: 0 0 0 1px var(--nf-accent); }
2965
- .progressBookHead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
2966
- .progressBookName { font-weight: 600; }
2967
- .progressLive { color: var(--nf-accent); font-weight: 600; }
2968
- .progressBookBar { height: 8px; border-radius: 999px; background: var(--nf-glass-face-hover, rgba(0,0,0,0.05)); overflow: hidden; }
2969
- .progressBookFill { height: 100%; background: var(--nf-accent); border-radius: 999px; }
2970
-
2971
- .shelfHeader {
2972
- display: flex;
2973
- flex-direction: column;
2974
- gap: var(--nf-space-10, 10px);
2975
- }
2976
-
2977
- /* 书架顶部主容器:加高玻璃卡 */
2978
- .shelfHero {
2979
- display: flex;
2980
- flex-direction: column;
2981
- gap: var(--nf-space-14, 14px);
2982
- padding: var(--nf-card-pad, 20px 22px);
2983
- border: 1px solid var(--nf-glass-border);
2984
- border-radius: var(--nf-radius-22, 22px);
2985
- background: var(--nf-glass-face);
2986
- box-shadow: var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);
2987
- }
2988
-
2989
- .shelfHero .panelTitle {
2990
- font-size: var(--nf-fs-22, 22px);
2991
- letter-spacing: 0.3px;
2992
- }
2993
-
2994
- .shelfTitleRow {
2995
- display: flex;
2996
- align-items: center;
2997
- justify-content: space-between;
2998
- gap: var(--nf-space-10, 10px);
2999
- flex-wrap: wrap;
3000
- }
3001
-
3002
- .shelfToolbar {
3003
- display: flex;
3004
- align-items: center;
3005
- gap: var(--nf-space-10, 10px);
3006
- flex-wrap: wrap;
3007
- }
3008
-
3009
- .shelfSearch {
3010
- flex: 1;
3011
- min-width: 180px;
3012
- max-width: 320px;
3013
- }
3014
-
3015
- .shelfStats {
3016
- display: grid;
3017
- grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
3018
- gap: var(--nf-space-10, 10px);
3019
- }
3020
-
3021
- .shelfStat {
3022
- display: flex;
3023
- align-items: baseline;
3024
- justify-content: space-between;
3025
- gap: var(--nf-space-8, 8px);
3026
- padding: var(--nf-space-10, 10px) var(--nf-space-14, 14px);
3027
- border: 1px solid var(--nf-glass-border);
3028
- border-radius: var(--nf-radius-14, 14px);
3029
- background: var(--nf-glass-face);
3030
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
3031
- cursor: pointer;
3032
- user-select: none;
3033
- transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
3034
- }
3035
-
3036
- .shelfStat:hover {
3037
- border-color: var(--nf-accent);
3038
- transform: translateY(-1px);
3039
- }
3040
-
3041
- .shelfStatActive {
3042
- border-color: var(--nf-accent);
3043
- background: var(--nf-accent-soft);
3044
- box-shadow: 0 0 0 2px var(--nf-accent-soft), var(--nf-shadow);
3045
- }
3046
-
3047
- .shelfStat b {
3048
- font-size: var(--nf-fs-20, 20px);
3049
- font-weight: 800;
3050
- color: var(--nf-accent);
3051
- }
3052
-
3053
- .shelfStat span {
3054
- font-size: var(--nf-fs-12, 12px);
3055
- color: var(--nf-text-2);
3056
- }
3057
-
3058
- /* 筛选:胶囊分段控件 */
3059
- .shelfFilters {
3060
- display: inline-flex;
3061
- gap: var(--nf-space-2, 2px);
3062
- padding: var(--nf-space-4, 3px);
3063
- border: 1px solid var(--nf-border);
3064
- border-radius: var(--nf-radius-999, 999px);
3065
- background: var(--nf-bg-inset);
3066
- }
3067
-
3068
- .shelfFilter {
3069
- border: none;
3070
- background: transparent;
3071
- color: var(--nf-text-2);
3072
- font-size: var(--nf-fs-12, 12.5px);
3073
- font-weight: 600;
3074
- padding: var(--nf-space-6, 5px) var(--nf-space-12, 12px);
3075
- border-radius: var(--nf-radius-999, 999px);
3076
- cursor: pointer;
3077
- display: inline-flex;
3078
- align-items: center;
3079
- gap: var(--nf-space-6, 5px);
3080
- white-space: nowrap;
3081
- transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
3082
- }
3083
-
3084
- .shelfFilter:hover {
3085
- color: var(--nf-text);
3086
- }
3087
-
3088
- .shelfFilterActive {
3089
- background: linear-gradient(135deg, var(--nf-accent), var(--nf-accent-hover));
3090
- color: var(--nf-accent-fg);
3091
- box-shadow: 0 3px 12px color-mix(in srgb, var(--nf-accent) 40%, transparent);
3092
- }
3093
-
3094
- .shelfFilterCount {
3095
- font-size: var(--nf-fs-12, 10.5px);
3096
- opacity: 0.8;
3097
- background: color-mix(in srgb, currentColor 14%, transparent);
3098
- border-radius: var(--nf-radius-999, 999px);
3099
- padding: 0 var(--nf-space-6, 6px);
3100
- }
3101
-
3102
- /* 书架空态 / 无结果引导卡 */
3103
- .shelfEmpty {
3104
- flex: 1;
3105
- display: flex;
3106
- flex-direction: column;
3107
- align-items: center;
3108
- justify-content: center;
3109
- gap: var(--nf-space-10, 10px);
3110
- padding: var(--nf-space-40, 40px) var(--nf-space-20, 20px);
3111
- border: 1px dashed var(--nf-border-strong);
3112
- border-radius: var(--nf-radius-16, 16px);
3113
- background: var(--nf-bg-raise);
3114
- -webkit-backdrop-filter: blur(24px) saturate(180%);
3115
- backdrop-filter: blur(24px) saturate(180%);
3116
- text-align: center;
3117
- }
3118
-
3119
- .shelfEmptyIcon {
3120
- font-size: var(--nf-fs-42, 42px);
3121
- }
3122
-
3123
- .shelfEmptyTitle {
3124
- font-size: var(--nf-fs-16, 16px);
3125
- font-weight: 700;
3126
- }
3127
-
3128
- .shelfGrid {
3129
- display: grid;
3130
- grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
3131
- gap: var(--nf-container-gap, 14px);
3132
- align-content: start;
3133
- }
3134
-
3135
- /* ------------------------------------------------------------
3136
- * 外观设置扩展:强制显示模式 + 界面密度 + 主题暗色覆盖
3137
- * ------------------------------------------------------------ */
3138
- /* 界面密度:唯一允许重定义尺寸的开关(主题永不触碰这些令牌)。
3139
- * comfort = 设置页主容器基准;compact/spacious 只缩放令牌,不改组件。 */
3140
- .panel {
3141
- --nf-container-pad: 20px 22px;
3142
- --nf-container-gap: var(--nf-space-14, 14px);
3143
- --nf-card-pad: 20px 22px;
3144
- --nf-nav-pad: 16px 12px 14px;
3145
- }
3146
-
3147
- .panel[data-nf-density='compact'] {
3148
- --nf-container-pad: 12px 14px;
3149
- --nf-container-gap: var(--nf-space-8, 8px);
3150
- --nf-card-pad: 12px 14px;
3151
- --nf-nav-pad: 8px 8px;
3152
- }
3153
-
3154
- .panel[data-nf-density='spacious'] {
3155
- --nf-container-pad: 24px 28px;
3156
- --nf-container-gap: var(--nf-space-18, 18px);
3157
- --nf-card-pad: 22px 26px;
3158
- --nf-nav-pad: 18px 14px;
3159
- }
3160
-
3161
- /* 强制浅色(不跟随系统时覆盖 .view 的明暗变量) */
3162
- .panel[data-nf-mode='light'] {
3163
- color-scheme: light;
3164
- --nf-bg: rgba(242, 242, 247, 0.86);
3165
- --nf-bg-raise: rgba(255, 255, 255, 0.72);
3166
- --nf-bg-inset: rgba(118, 118, 128, 0.12);
3167
- --nf-border: rgba(60, 60, 67, 0.16);
3168
- --nf-border-strong: rgba(60, 60, 67, 0.32);
3169
- --nf-text: #1c1c1e;
3170
- --nf-text-2: #3c3c43;
3171
- --nf-text-2-alpha: rgba(60, 60, 67, 0.68);
3172
- --nf-text-3: #8e8e93;
3173
- --nf-accent: #00b85c;
3174
- --nf-accent-hover: #00a04e;
3175
- --nf-accent-soft: rgba(0, 184, 92, 0.12);
3176
- --nf-accent-fg: #ffffff;
3177
- --nf-hover: rgba(0, 0, 0, 0.05);
3178
- --nf-success: #34c759;
3179
- --nf-error: #ff3b30;
3180
- --nf-warn: #ff9500;
3181
- --nf-info: #00b85c;
3182
- --nf-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 12px 32px rgba(0, 0, 0, 0.08);
3183
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.07), 0 20px 48px rgba(0, 0, 0, 0.12);
3184
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.06), 0 14px 38px rgba(0, 0, 0, 0.14);
3185
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.08), 0 22px 52px rgba(0, 0, 0, 0.20);
3186
- --nf-glass-face: linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);
3187
- --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%);
3188
- --nf-glass-sheen: rgba(255, 255, 255, 0.55);
3189
- --nf-glass-border: rgba(255, 255, 255, 0.65);
3190
- --nf-glass-inset: rgba(255, 255, 255, 0.55);
3191
- --nf-glass-orb-a: rgba(0, 184, 92, 0.18);
3192
- --nf-glass-orb-b: rgba(120, 160, 255, 0.13);
3193
- }
3194
-
3195
- /* 强制深色 */
3196
- .panel[data-nf-mode='dark'] {
3197
- color-scheme: dark;
3198
- --nf-bg: rgba(10, 11, 13, 0.86);
3199
- --nf-bg-raise: rgba(28, 28, 30, 0.78);
3200
- --nf-bg-inset: rgba(118, 118, 128, 0.18);
3201
- --nf-border: rgba(255, 255, 255, 0.12);
3202
- --nf-border-strong: rgba(255, 255, 255, 0.28);
3203
- --nf-text: #f2f2f7;
3204
- --nf-text-2: #d1d1d6;
3205
- --nf-text-2-alpha: rgba(209, 209, 214, 0.72);
3206
- --nf-text-3: #8e8e93;
3207
- --nf-accent: #35d07a;
3208
- --nf-accent-hover: #5ce695;
3209
- --nf-accent-soft: rgba(53, 208, 122, 0.2);
3210
- --nf-accent-fg: #062b18;
3211
- --nf-hover: rgba(255, 255, 255, 0.09);
3212
- --nf-success: #30d158;
3213
- --nf-error: #ff453a;
3214
- --nf-warn: #ff9f0a;
3215
- --nf-info: #35d07a;
3216
- --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px rgba(0, 0, 0, 0.4);
3217
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.4), 0 20px 48px rgba(0, 0, 0, 0.55);
3218
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 14px 38px rgba(0, 0, 0, 0.45);
3219
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.4), 0 22px 52px rgba(0, 0, 0, 0.55);
3220
- --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%);
3221
- --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%);
3222
- --nf-glass-sheen: rgba(255, 255, 255, 0.26);
3223
- --nf-glass-border: rgba(255, 255, 255, 0.14);
3224
- --nf-glass-inset: rgba(255, 255, 255, 0.07);
3225
- --nf-glass-orb-a: rgba(0, 202, 82, 0.28);
3226
- --nf-glass-orb-b: rgba(190, 200, 215, 0.10);
3227
- }
3228
-
3229
- /* 强制深色时:新拟物 的暗色变体 */
3230
-
3231
- .panel[data-nf-mode='dark'][data-nf-theme='macos'] {
3232
- --nf-bg: rgba(28, 28, 30, 0.9);
3233
- --nf-bg-raise: rgba(44, 44, 46, 0.82);
3234
- --nf-bg-inset: rgba(118, 118, 128, 0.18);
3235
- --nf-border: rgba(255, 255, 255, 0.12);
3236
- --nf-border-strong: rgba(255, 255, 255, 0.26);
3237
- --nf-text: #f5f5f7;
3238
- --nf-text-2: #d1d1d6;
3239
- --nf-text-2-alpha: rgba(209, 209, 214, 0.7);
3240
- --nf-text-3: #98989d;
3241
- --nf-accent: #0a84ff;
3242
- --nf-accent-hover: #3a9bff;
3243
- --nf-accent-soft: rgba(10, 132, 255, 0.2);
3244
- --nf-accent-fg: #ffffff;
3245
- --nf-hover: rgba(255, 255, 255, 0.06);
3246
- --nf-info: #bf5af2;
3247
- --nf-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.45);
3248
- --nf-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45), 0 18px 44px rgba(0, 0, 0, 0.6);
3249
- --nf-card-shadow: 0 2px 6px rgba(0, 0, 0, 0.4), 0 14px 38px rgba(0, 0, 0, 0.5);
3250
- --nf-card-shadow-hover: 0 4px 10px rgba(0, 0, 0, 0.45), 0 22px 52px rgba(0, 0, 0, 0.6);
3251
- --nf-glass-face: rgba(44, 44, 46, 0.85);
3252
- --nf-glass-core: transparent;
3253
- --nf-glass-sheen: rgba(255, 255, 255, 0.2);
3254
- --nf-glass-border: rgba(255, 255, 255, 0.18);
3255
- --nf-glass-inset: rgba(255, 255, 255, 0.06);
3256
- --nf-glass-orb-a: rgba(10, 132, 255, 0.16);
3257
- --nf-glass-orb-b: rgba(191, 90, 242, 0.08);
3258
- --nf-glass-noise: none;
3259
- }
3260
-
3261
- .panel[data-nf-mode='dark'][data-nf-theme='neumorph'] {
3262
- --nf-bg: #2b2f36;
3263
- --nf-bg-raise: #2b2f36;
3264
- --nf-bg-inset: #25292f;
3265
- --nf-border: rgba(10, 12, 16, 0.5);
3266
- --nf-border-strong: rgba(8, 10, 14, 0.6);
3267
- --nf-text: #d6dae1;
3268
- --nf-text-2: #a8aeb8;
3269
- --nf-text-2-alpha: rgba(168, 174, 184, 0.7);
3270
- --nf-text-3: #757c88;
3271
- --nf-hover: rgba(255, 255, 255, 0.05);
3272
- --nf-shadow: 4px 4px 10px rgba(0, 0, 0, 0.5), -4px -4px 10px rgba(96, 104, 118, 0.24);
3273
- --nf-shadow-lg: 6px 6px 14px rgba(0, 0, 0, 0.55), -6px -6px 14px rgba(96, 104, 118, 0.26);
3274
- --nf-card-shadow: 9px 9px 18px rgba(0, 0, 0, 0.5), -9px -9px 18px rgba(96, 104, 118, 0.24);
3275
- --nf-card-shadow-hover: 12px 12px 24px rgba(0, 0, 0, 0.6), -12px -12px 24px rgba(96, 104, 118, 0.28);
3276
- --nf-glass-face: #2b2f36;
3277
- --nf-glass-core: transparent;
3278
- --nf-glass-sheen: rgba(255, 255, 255, 0);
3279
- --nf-glass-border: rgba(12, 14, 18, 0.45);
3280
- --nf-glass-inset: #25292f;
3281
- --nf-glass-orb-a: transparent;
3282
- --nf-glass-orb-b: transparent;
3283
- --nf-glass-noise: none;
3284
- }
3285
-
3286
- /* 强制浅色时:新拟物 的浅色变体(深色系统下也能用) */
3287
- .panel[data-nf-mode='light'][data-nf-theme='neumorph'] {
3288
- --nf-bg: #e4e9f2;
3289
- --nf-bg-raise: #e4e9f2;
3290
- --nf-bg-inset: #d9dfe8;
3291
- --nf-border: rgba(140, 155, 175, 0.35);
3292
- --nf-border-strong: rgba(120, 135, 158, 0.5);
3293
- --nf-text: #3a4250;
3294
- --nf-text-2: #5b6472;
3295
- --nf-text-2-alpha: rgba(70, 80, 96, 0.7);
3296
- --nf-text-3: #8b94a3;
3297
- --nf-hover: rgba(90, 105, 125, 0.08);
3298
- --nf-shadow: 4px 4px 10px rgba(163, 177, 198, 0.55), -4px -4px 10px rgba(255, 255, 255, 0.85);
3299
- --nf-shadow-lg: 6px 6px 14px rgba(163, 177, 198, 0.6), -6px -6px 14px rgba(255, 255, 255, 0.9);
3300
- --nf-card-shadow: 9px 9px 18px rgba(163, 177, 198, 0.55), -9px -9px 18px rgba(255, 255, 255, 0.85);
3301
- --nf-card-shadow-hover: 12px 12px 24px rgba(163, 177, 198, 0.65), -12px -12px 24px rgba(255, 255, 255, 0.95);
3302
- --nf-glass-face: #e4e9f2;
3303
- --nf-glass-core: transparent;
3304
- --nf-glass-sheen: rgba(255, 255, 255, 0);
3305
- --nf-glass-border: rgba(163, 177, 198, 0.4);
3306
- --nf-glass-inset: #d9dfe8;
3307
- --nf-glass-orb-a: transparent;
3308
- --nf-glass-orb-b: transparent;
3309
- --nf-glass-noise: none;
3310
- }
3311
-
3312
-
3313
- .bookCard {
3314
- display: flex;
3315
- flex-direction: column;
3316
- gap: var(--nf-space-8, 8px);
3317
- border: 1px solid var(--nf-border);
3318
- border-radius: var(--nf-radius-16, 16px);
3319
- padding: var(--nf-space-12, 12px);
3320
- background: var(--nf-bg-raise);
3321
- -webkit-backdrop-filter: blur(24px) saturate(180%);
3322
- backdrop-filter: blur(24px) saturate(180%);
3323
- box-shadow: var(--nf-shadow);
3324
- cursor: pointer;
3325
- transition: border-color 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
3326
- }
3327
-
3328
- .bookCard:hover {
3329
- border-color: var(--nf-accent);
3330
- transform: translateY(-2px);
3331
- box-shadow: var(--nf-shadow-lg);
3332
- }
3333
-
3334
- .bookCardActive {
3335
- border-color: var(--nf-accent);
3336
- box-shadow: 0 0 0 3px var(--nf-accent-soft);
3337
- }
3338
-
3339
- .bookCardCover {
3340
- flex: none;
3341
- aspect-ratio: 3 / 4;
3342
- border-radius: var(--nf-radius-12, 12px);
3343
- overflow: hidden;
3344
- background: var(--nf-bg-inset);
3345
- border: 1px solid var(--nf-border);
3346
- display: flex;
3347
- align-items: center;
3348
- justify-content: center;
3349
- position: relative;
3350
- }
3351
-
3352
- .bookCardCover img {
3353
- width: 100%;
3354
- height: 100%;
3355
- object-fit: cover;
3356
- display: block;
3357
- transition: transform 0.35s ease;
3358
- }
3359
-
3360
- .bookCard:hover .bookCardCover img {
3361
- transform: scale(1.06);
3362
- }
3363
-
3364
- /* 封面底部渐暗(hover 出现,突出书名区) */
3365
- .bookCardCover::after {
3366
- content: '';
3367
- position: absolute;
3368
- inset: 0;
3369
- border-radius: inherit;
3370
- pointer-events: none;
3371
- background: linear-gradient(180deg, transparent 55%, rgba(0, 0, 0, 0.28));
3372
- opacity: 0;
3373
- transition: opacity 0.25s ease;
3374
- }
3375
-
3376
- .bookCard:hover .bookCardCover::after {
3377
- opacity: 1;
3378
- }
3379
-
3380
- .bookCardCoverFallback {
3381
- display: flex;
3382
- flex-direction: column;
3383
- align-items: center;
3384
- justify-content: center;
3385
- gap: var(--nf-space-6, 6px);
3386
- width: 100%;
3387
- height: 100%;
3388
- background:
3389
- radial-gradient(400px 200px at 80% -20%, color-mix(in srgb, var(--nf-accent) 25%, transparent), transparent 70%),
3390
- linear-gradient(155deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 10%, var(--nf-bg-inset)));
3391
- }
3392
-
3393
- .bookCardCoverTitle {
3394
- font-size: var(--nf-fs-22, 22px);
3395
- font-weight: 800;
3396
- color: var(--nf-accent);
3397
- letter-spacing: 2px;
3398
- }
3399
-
3400
- .bookCardBody {
3401
- display: flex;
3402
- flex-direction: column;
3403
- gap: var(--nf-space-6, 5px);
3404
- min-width: 0;
3405
- flex: 1;
3406
- }
3407
-
3408
- .bookCardTitleRow {
3409
- display: flex;
3410
- align-items: center;
3411
- justify-content: space-between;
3412
- gap: var(--nf-space-6, 6px);
3413
- }
3414
-
3415
- .bookCardName {
3416
- font-weight: 700;
3417
- font-size: var(--nf-fs-14, 13.5px);
3418
- overflow: hidden;
3419
- text-overflow: ellipsis;
3420
- white-space: nowrap;
3421
- }
3422
-
3423
- .bookCardBlurb {
3424
- display: -webkit-box;
3425
- -webkit-line-clamp: 2;
3426
- -webkit-box-orient: vertical;
3427
- overflow: hidden;
3428
- min-height: 34px;
3429
- }
3430
-
3431
- .bookCardMetaRow {
3432
- display: flex;
3433
- align-items: center;
3434
- justify-content: space-between;
3435
- gap: var(--nf-space-6, 6px);
3436
- flex-wrap: wrap;
3437
- }
3438
-
3439
- .bookCardProgressBar {
3440
- height: 6px;
3441
- border-radius: var(--nf-radius-999, 999px);
3442
- background: var(--nf-border);
3443
- overflow: hidden;
3444
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
3445
- }
3446
-
3447
- .bookCardProgressFill {
3448
- display: block;
3449
- height: 100%;
3450
- border-radius: var(--nf-radius-999, 999px);
3451
- background: linear-gradient(90deg, var(--nf-info), var(--nf-accent));
3452
- transition: width 0.3s ease;
3453
- }
3454
-
3455
- .bookAddCard {
3456
- align-items: center;
3457
- justify-content: center;
3458
- gap: var(--nf-space-8, 8px);
3459
- text-align: center;
3460
- border-style: dashed;
3461
- color: var(--nf-text-2);
3462
- min-height: 260px;
3463
- transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease, transform 0.15s ease;
3464
- }
3465
-
3466
- .bookAddCard:hover {
3467
- border-color: var(--nf-accent);
3468
- background: var(--nf-accent-soft);
3469
- color: var(--nf-accent);
3470
- transform: translateY(-2px);
3471
- }
3472
-
3473
- .bookAddIcon {
3474
- font-size: var(--nf-fs-34, 34px);
3475
- line-height: 1;
3476
- color: var(--nf-accent);
3477
- transition: transform 0.15s ease;
3478
- }
3479
-
3480
- .bookAddCard:hover .bookAddIcon {
3481
- transform: scale(1.12);
3482
- }
3483
-
3484
- .bookCreateCard {
3485
- min-height: 260px;
3486
- border-color: var(--nf-accent);
3487
- }
3488
-
3489
- /* -------------------------------------------------------- create book view */
3490
-
3491
- .createBookView {
3492
- flex: 1;
3493
- min-height: 0;
3494
- overflow: auto;
3495
- /* 主容器统一:与工作台/书架/设置页同一令牌 */
3496
- padding: var(--nf-container-pad, 20px 22px);
3497
- display: flex;
3498
- flex-direction: column;
3499
- gap: var(--nf-container-gap, 14px);
3500
- }
3501
-
3502
- .createBookTop {
3503
- display: flex;
3504
- align-items: center;
3505
- }
3506
-
3507
- .createBookCard {
3508
- align-self: center;
3509
- width: min(520px, 100%);
3510
- display: flex;
3511
- flex-direction: column;
3512
- gap: var(--nf-space-12, 12px);
3513
- border: 1px solid var(--nf-border);
3514
- border-radius: var(--nf-radius-20, 20px);
3515
- /* 主容器统一:与设置页卡片同一 --nf-card-pad */
3516
- padding: var(--nf-card-pad, 20px 22px);
3517
- background: var(--nf-bg-raise);
3518
- -webkit-backdrop-filter: blur(24px) saturate(180%);
3519
- backdrop-filter: blur(24px) saturate(180%);
3520
- box-shadow: var(--nf-shadow-lg);
3521
- }
3522
-
3523
- .createBookIcon {
3524
- font-size: var(--nf-fs-34, 34px);
3525
- line-height: 1;
3526
- }
3527
-
3528
- .createBookTitle {
3529
- margin: 0;
3530
- font-size: var(--nf-fs-22, 22px);
3531
- font-weight: 800;
3532
- letter-spacing: -0.3px;
3533
- }
3534
-
3535
- /* 想法 → AI 大纲区块 */
3536
- .ideaCard {
3537
- display: flex;
3538
- flex-direction: column;
3539
- gap: var(--nf-space-8, 8px);
3540
- border: 1px dashed var(--nf-border-strong);
3541
- border-radius: var(--nf-radius-14, 14px);
3542
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
3543
- background: color-mix(in srgb, var(--nf-accent) 3%, transparent);
3544
- }
3545
-
3546
- .ideaToggle {
3547
- display: flex;
3548
- align-items: center;
3549
- gap: var(--nf-space-6, 6px);
3550
- border: none;
3551
- background: none;
3552
- color: var(--nf-accent);
3553
- font-size: var(--nf-fs-14, 13px);
3554
- font-weight: 700;
3555
- cursor: pointer;
3556
- text-align: left;
3557
- padding: 0;
3558
- }
3559
-
3560
- .ideaCandidate {
3561
- display: flex;
3562
- flex-direction: column;
3563
- gap: var(--nf-space-6, 6px);
3564
- border: 1px solid var(--nf-border);
3565
- border-radius: var(--nf-radius-12, 12px);
3566
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
3567
- background: var(--nf-bg);
3568
- }
3569
-
3570
- .progressLineDone {
3571
- color: var(--nf-success);
3572
- font-weight: 600;
3573
- }
3574
-
3575
- .progressLineError {
3576
- color: var(--nf-error);
3577
- font-weight: 600;
3578
- }
3579
-
3580
- /* ------------------------------------------------------------ misc */
3581
-
3582
- .meta {
3583
- font-size: var(--nf-fs-12, 12px);
3584
- color: var(--nf-text-2);
3585
- opacity: 0.9;
3586
- }
3587
-
3588
- /* 题材基底:描述两行截断(悬停 title 看全文),保持列表紧凑自然展开 */
3589
- .genreDesc {
3590
- display: -webkit-box;
3591
- -webkit-line-clamp: 2;
3592
- -webkit-box-orient: vertical;
3593
- overflow: hidden;
3594
- max-width: 560px;
3595
- }
3596
-
3597
- .fileList {
3598
- display: flex;
3599
- flex-direction: column;
3600
- gap: var(--nf-space-4, 3px);
3601
- font-size: var(--nf-fs-12, 12px);
3602
- color: var(--nf-text-2);
3603
- opacity: 0.9;
3604
- word-break: break-all;
3605
- }
3606
-
3607
- /* Custom scrollbar (webkit) */
3608
- .panelContent::-webkit-scrollbar,
3609
- .chatScroll::-webkit-scrollbar,
3610
- .chapterPreview::-webkit-scrollbar,
3611
- .progress::-webkit-scrollbar,
3612
- .toolLive::-webkit-scrollbar {
3613
- width: 8px;
3614
- height: 8px;
3615
- }
3616
-
3617
- .panelContent::-webkit-scrollbar-thumb,
3618
- .chatScroll::-webkit-scrollbar-thumb,
3619
- .chapterPreview::-webkit-scrollbar-thumb,
3620
- .progress::-webkit-scrollbar-thumb,
3621
- .toolLive::-webkit-scrollbar-thumb {
3622
- background: var(--nf-border-strong);
3623
- border-radius: var(--nf-radius-4, 4px);
3624
- }
3625
-
3626
- .panelContent::-webkit-scrollbar-thumb:hover,
3627
- .chatScroll::-webkit-scrollbar-thumb:hover,
3628
- .chapterPreview::-webkit-scrollbar-thumb:hover,
3629
- .progress::-webkit-scrollbar-thumb:hover,
3630
- .toolLive::-webkit-scrollbar-thumb:hover {
3631
- background: var(--nf-text-3);
3632
- }
3633
-
3634
- /* Workflow timeline */
3635
- .workflowList {
3636
- display: flex;
3637
- flex-direction: column;
3638
- gap: 0;
3639
- }
3640
-
3641
- .workflowRow {
3642
- display: flex;
3643
- align-items: flex-start;
3644
- gap: var(--nf-space-12, 12px);
3645
- padding: var(--nf-space-8, 8px) var(--nf-space-4, 4px);
3646
- position: relative;
3647
- }
3648
-
3649
- .workflowRow::before {
3650
- content: '';
3651
- position: absolute;
3652
- left: 13px;
3653
- top: 34px;
3654
- bottom: -8px;
3655
- width: 2px;
3656
- background: var(--nf-border);
3657
- }
3658
-
3659
- .workflowRow:last-child::before {
3660
- display: none;
3661
- }
3662
-
3663
- .workflowDot {
3664
- width: 28px;
3665
- height: var(--nf-ctrl-s, 28px);
3666
- border-radius: 50%;
3667
- display: inline-flex;
3668
- align-items: center;
3669
- justify-content: center;
3670
- font-size: var(--nf-fs-12, 12px);
3671
- font-weight: 700;
3672
- flex-shrink: 0;
3673
- border: 2px solid var(--nf-border-strong);
3674
- background: var(--nf-bg-raise);
3675
- color: var(--nf-text-2);
3676
- z-index: 1;
3677
- }
3678
-
3679
- .workflowDotDone {
3680
- border-color: var(--nf-success);
3681
- background: color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));
3682
- color: var(--nf-success);
3683
- }
3684
-
3685
- .workflowDotActive {
3686
- border-color: var(--nf-accent);
3687
- background: var(--nf-accent);
3688
- color: var(--nf-accent-fg);
3689
- box-shadow: 0 0 0 4px var(--nf-accent-soft);
3690
- }
3691
-
3692
- .workflowBody {
3693
- flex: 1;
3694
- min-width: 0;
3695
- display: flex;
3696
- flex-direction: column;
3697
- gap: var(--nf-space-4, 4px);
3698
- padding-top: var(--nf-space-2, 2px);
3699
- }
3700
-
3701
- .workflowLabel {
3702
- font-size: var(--nf-fs-14, 13px);
3703
- font-weight: 600;
3704
- color: var(--nf-text);
3705
- }
3706
-
3707
- .workflowHint {
3708
- font-size: var(--nf-fs-12, 12px);
3709
- color: var(--nf-text-2);
3710
- }
3711
-
3712
- @keyframes pulse {
3713
- 0%, 100% { opacity: 1; }
3714
- 50% { opacity: 0.45; }
3715
- }
3716
-
3717
- @keyframes fadeIn {
3718
- from { opacity: 0; transform: translateY(4px); }
3719
- to { opacity: 1; transform: translateY(0); }
3720
- }
3721
-
3722
- .card {
3723
- animation: fadeIn 0.2s ease;
3724
- }
3725
-
3726
- /* ------------------------------------------------------------ bookshelf */
3727
-
3728
- .bookshelf {
3729
- display: flex;
3730
- align-items: center;
3731
- gap: var(--nf-space-10, 10px);
3732
- margin: 10px 12px 0;
3733
- padding: var(--nf-space-8, 8px) var(--nf-space-14, 14px);
3734
- border: 1px solid var(--nf-glass-border);
3735
- border-radius: var(--nf-radius-16, 16px);
3736
- background: var(--nf-glass-face);
3737
- box-shadow: var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);
3738
- -webkit-backdrop-filter: blur(26px) saturate(175%);
3739
- backdrop-filter: blur(26px) saturate(175%);
3740
- flex-shrink: 0;
3741
- flex-wrap: wrap;
3742
- position: relative;
3743
- z-index: 1;
3744
- }
3745
-
3746
- .bookshelfLabel {
3747
- font-size: var(--nf-fs-12, 12px);
3748
- font-weight: 700;
3749
- color: var(--nf-text-3);
3750
- letter-spacing: 1px;
3751
- flex-shrink: 0;
3752
- }
3753
-
3754
- .bookshelfList {
3755
- display: flex;
3756
- align-items: center;
3757
- gap: var(--nf-space-6, 6px);
3758
- flex-wrap: wrap;
3759
- flex: 1;
3760
- min-width: 0;
3761
- }
3762
-
3763
- .bookChip {
3764
- display: flex;
3765
- align-items: center;
3766
- gap: var(--nf-space-6, 6px);
3767
- padding: var(--nf-space-4, 4px) var(--nf-space-8, 8px) var(--nf-space-4, 4px) var(--nf-space-10, 10px);
3768
- border: 1px solid var(--nf-border);
3769
- border-radius: var(--nf-radius-999, 999px);
3770
- background: var(--nf-bg-inset);
3771
- cursor: pointer;
3772
- font-size: var(--nf-fs-12, 12px);
3773
- transition: border-color 0.15s ease, background 0.15s ease;
3774
- max-width: 220px;
3775
- }
3776
-
3777
- .bookChip:hover {
3778
- border-color: var(--nf-border-strong);
3779
- }
3780
-
3781
- .bookChipActive {
3782
- border-color: var(--nf-accent);
3783
- background: var(--nf-accent-soft);
3784
- color: var(--nf-accent);
3785
- }
3786
-
3787
- .bookChipName {
3788
- font-weight: 600;
3789
- overflow: hidden;
3790
- text-overflow: ellipsis;
3791
- white-space: nowrap;
3792
- }
3793
-
3794
- .bookChipMeta {
3795
- font-size: var(--nf-fs-12, 11px);
3796
- opacity: 0.7;
3797
- white-space: nowrap;
3798
- }
3799
-
3800
- .bookChipRemove {
3801
- border: none;
3802
- background: transparent;
3803
- color: var(--nf-text-3);
3804
- cursor: pointer;
3805
- font-size: var(--nf-fs-14, 13px);
3806
- line-height: 1;
3807
- padding: 0 var(--nf-space-2, 2px);
3808
- border-radius: var(--nf-radius-4, 4px);
3809
- }
3810
-
3811
- .bookChipRemove:hover {
3812
- color: var(--nf-error);
3813
- }
3814
-
3815
- .bookAdd {
3816
- border: 1px dashed var(--nf-border-strong);
3817
- background: transparent;
3818
- color: var(--nf-text-2);
3819
- cursor: pointer;
3820
- font-size: var(--nf-fs-12, 12px);
3821
- padding: var(--nf-space-4, 4px) var(--nf-space-12, 12px);
3822
- border-radius: var(--nf-radius-999, 999px);
3823
- transition: border-color 0.15s ease, color 0.15s ease;
3824
- }
3825
-
3826
- .bookAdd:hover {
3827
- border-color: var(--nf-accent);
3828
- color: var(--nf-accent);
3829
- }
3830
-
3831
- .bookCreateForm {
3832
- display: flex;
3833
- align-items: center;
3834
- gap: var(--nf-space-6, 6px);
3835
- }
3836
-
3837
- /* ------------------------------------------------------------ dropzone */
3838
-
3839
- .dropzone {
3840
- border: 2px dashed var(--nf-border-strong);
3841
- border-radius: var(--nf-radius-10, 10px);
3842
- padding: var(--nf-space-18, 18px) var(--nf-space-14, 14px);
3843
- text-align: center;
3844
- font-size: var(--nf-fs-14, 13px);
3845
- color: var(--nf-text-2);
3846
- cursor: pointer;
3847
- transition: border-color 0.15s ease, background 0.15s ease;
3848
- display: flex;
3849
- flex-direction: column;
3850
- align-items: center;
3851
- gap: var(--nf-space-6, 6px);
3852
- }
3853
-
3854
- .dropzone:hover,
3855
- .dropzoneActive {
3856
- border-color: var(--nf-accent);
3857
- background: var(--nf-accent-soft);
3858
- color: var(--nf-accent);
3859
- }
3860
-
3861
- .dropzoneIcon {
3862
- font-size: var(--nf-fs-22, 22px);
3863
- line-height: 1;
3864
- }
3865
-
3866
- /* ================= 书架书卡操作行 ================= */
3867
-
3868
- .bookCardActions {
3869
- display: flex;
3870
- align-items: center;
3871
- gap: var(--nf-space-6, 6px);
3872
- margin-top: auto;
3873
- padding-top: var(--nf-space-8, 8px);
3874
- }
3875
-
3876
- .bookCardActions .button {
3877
- flex: 1;
3878
- justify-content: center;
3879
- }
3880
-
3881
- /* ================= 阅读页(沉浸式) ================= */
3882
-
3883
- .readerView {
3884
- position: absolute;
3885
- inset: 0;
3886
- display: flex;
3887
- flex-direction: column;
3888
- overflow: hidden;
3889
- transition: background 0.2s ease, color 0.2s ease;
3890
- }
3891
-
3892
- .readerHeader {
3893
- flex: none;
3894
- display: flex;
3895
- align-items: center;
3896
- gap: var(--nf-space-8, 8px);
3897
- padding: var(--nf-space-8, 8px) var(--nf-space-12, 12px);
3898
- border-bottom: 1px solid;
3899
- flex-wrap: wrap;
3900
- }
3901
-
3902
- .readerTitle {
3903
- font-weight: 700;
3904
- font-size: var(--nf-fs-14, 14px);
3905
- }
3906
-
3907
- .readerSeg {
3908
- display: flex;
3909
- align-items: center;
3910
- gap: var(--nf-space-2, 2px);
3911
- border-radius: var(--nf-radius-8, 8px);
3912
- overflow: hidden;
3913
- }
3914
-
3915
- .readerSegBtn {
3916
- border: none;
3917
- background: transparent;
3918
- font-size: var(--nf-fs-12, 12px);
3919
- padding: var(--nf-space-4, 3px) var(--nf-space-8, 8px);
3920
- border-radius: var(--nf-radius-6, 6px);
3921
- cursor: pointer;
3922
- opacity: 0.75;
3923
- }
3924
-
3925
- .readerSegBtn:hover {
3926
- opacity: 1;
3927
- }
3928
-
3929
- .readerSegActive {
3930
- opacity: 1;
3931
- }
3932
-
3933
- .readerBody {
3934
- flex: 1;
3935
- min-height: 0;
3936
- display: flex;
3937
- align-items: stretch;
3938
- }
3939
-
3940
- .readerSidebar {
3941
- flex: none;
3942
- width: 220px;
3943
- min-width: 220px;
3944
- overflow-y: auto;
3945
- padding: var(--nf-space-8, 8px) var(--nf-space-6, 6px) var(--nf-space-24, 24px);
3946
- border-right: 1px solid;
3947
- scrollbar-width: thin;
3948
- display: flex;
3949
- flex-direction: column;
3950
- gap: var(--nf-space-10, 10px);
3951
- }
3952
-
3953
- .readerGroup {
3954
- display: flex;
3955
- flex-direction: column;
3956
- gap: var(--nf-space-2, 1px);
3957
- }
3958
-
3959
- .readerGroupTitle {
3960
- display: flex;
3961
- align-items: center;
3962
- gap: var(--nf-space-6, 6px);
3963
- width: 100%;
3964
- border: none;
3965
- background: transparent;
3966
- font-size: var(--nf-fs-12, 12px);
3967
- font-weight: 700;
3968
- padding: var(--nf-space-6, 6px) var(--nf-space-8, 8px) var(--nf-space-4, 4px);
3969
- opacity: 0.9;
3970
- cursor: pointer;
3971
- text-align: left;
3972
- border-radius: var(--nf-radius-6, 6px);
3973
- }
3974
-
3975
- .readerGroupTitle:hover {
3976
- opacity: 1;
3977
- background: rgba(128, 128, 128, 0.12);
3978
- }
3979
-
3980
- .readerGroupArrow {
3981
- flex: none;
3982
- font-size: var(--nf-fs-12, 10px);
3983
- width: 12px;
3984
- text-align: center;
3985
- }
3986
-
3987
- .readerGroupCount {
3988
- flex: none;
3989
- font-size: var(--nf-fs-12, 11px);
3990
- font-weight: 400;
3991
- opacity: 0.6;
3992
- margin-left: auto;
3993
- padding-right: var(--nf-space-2, 2px);
3994
- }
3995
-
3996
- .readerItem {
3997
- display: flex;
3998
- align-items: center;
3999
- gap: var(--nf-space-6, 6px);
4000
- border: 1px solid;
4001
- border-radius: var(--nf-radius-8, 8px);
4002
- background: transparent;
4003
- font-size: var(--nf-fs-12, 12px);
4004
- text-align: left;
4005
- padding: var(--nf-space-4, 4px) var(--nf-space-8, 8px);
4006
- cursor: pointer;
4007
- opacity: 0.8;
4008
- transition: opacity 0.15s ease, background 0.15s ease;
4009
- min-width: 0;
4010
- }
4011
-
4012
- .readerItem:hover {
4013
- opacity: 1;
4014
- }
4015
-
4016
- .readerItemActive {
4017
- opacity: 1;
4018
- font-weight: 700;
4019
- }
4020
-
4021
- .readerItemNo {
4022
- flex: none;
4023
- font-weight: 700;
4024
- min-width: 26px;
4025
- text-align: right;
4026
- opacity: 0.75;
4027
- }
4028
-
4029
- .readerItemTitle {
4030
- flex: 1;
4031
- min-width: 0;
4032
- overflow: hidden;
4033
- text-overflow: ellipsis;
4034
- white-space: nowrap;
4035
- }
4036
-
4037
- .readerItemBadge {
4038
- flex: none;
4039
- font-size: var(--nf-fs-12, 11px);
4040
- }
4041
-
4042
- .readerMain {
4043
- flex: 1;
4044
- min-height: 0;
4045
- overflow-y: auto;
4046
- padding: var(--nf-space-20, 20px) var(--nf-space-16, 16px) var(--nf-space-48, 48px);
4047
- display: flex;
4048
- justify-content: center;
4049
- scrollbar-width: thin;
4050
- }
4051
-
4052
- .readerArticle {
4053
- width: 100%;
4054
- display: flex;
4055
- flex-direction: column;
4056
- gap: var(--nf-space-12, 12px);
4057
- }
4058
-
4059
- .readerChapterTitle {
4060
- margin: 0;
4061
- font-size: var(--nf-fs-24, 24px);
4062
- font-weight: 800;
4063
- letter-spacing: 1px;
4064
- }
4065
-
4066
- .readerChapterMeta {
4067
- display: flex;
4068
- align-items: center;
4069
- gap: var(--nf-space-8, 8px);
4070
- font-size: var(--nf-fs-12, 12px);
4071
- }
4072
-
4073
- .readerText {
4074
- text-align: justify;
4075
- letter-spacing: 0.02em;
4076
- }
4077
-
4078
- .readerPara {
4079
- margin: 0 0 0.85em;
4080
- text-indent: 2em;
4081
- }
4082
-
4083
- .readerFoot {
4084
- display: flex;
4085
- align-items: center;
4086
- justify-content: space-between;
4087
- gap: var(--nf-space-8, 8px);
4088
- margin-top: 12px;
4089
- padding-top: var(--nf-space-12, 12px);
4090
- border-top: 1px dashed;
4091
- }
4092
-
4093
- .readerLoading,
4094
- .readerError {
4095
- align-self: center;
4096
- padding: var(--nf-space-32, 32px) 0;
4097
- font-size: var(--nf-fs-14, 13px);
4098
- opacity: 0.7;
4099
- }
4100
-
4101
- .readerError {
4102
- color: var(--nf-error);
4103
- }
4104
-
4105
- /* ---------------------------------------------------------- import modal */
4106
-
4107
- .importModalOverlay {
4108
- position: fixed;
4109
- inset: 0;
4110
- z-index: 1000;
4111
- display: flex;
4112
- align-items: center;
4113
- justify-content: center;
4114
- background: rgba(0, 0, 0, 0.45);
4115
- -webkit-backdrop-filter: blur(4px);
4116
- backdrop-filter: blur(4px);
4117
- padding: var(--nf-space-24, 24px);
4118
- }
4119
-
4120
- .importModal {
4121
- width: min(520px, 100%);
4122
- max-height: 85vh;
4123
- overflow: auto;
4124
- display: flex;
4125
- flex-direction: column;
4126
- gap: var(--nf-space-12, 12px);
4127
- border: 1px solid var(--nf-border-strong);
4128
- border-radius: var(--nf-radius-16, 16px);
4129
- /* 主容器统一:与设置页卡片同一 --nf-card-pad */
4130
- padding: var(--nf-card-pad, 20px 22px);
4131
- background: var(--nf-bg-raise);
4132
- -webkit-backdrop-filter: blur(28px) saturate(180%);
4133
- backdrop-filter: blur(28px) saturate(180%);
4134
- box-shadow: var(--nf-shadow-lg);
4135
- }
4136
-
4137
- .importModalHead {
4138
- display: flex;
4139
- align-items: center;
4140
- justify-content: space-between;
4141
- gap: var(--nf-space-10, 10px);
4142
- }
4143
-
4144
- .importModalTabs {
4145
- display: flex;
4146
- gap: var(--nf-space-8, 8px);
4147
- }
4148
-
4149
- .importModalTabs .button {
4150
- flex: 1;
4151
- }
4152
-
4153
- .importModalBody {
4154
- display: flex;
4155
- flex-direction: column;
4156
- gap: var(--nf-space-10, 10px);
4157
- }
4158
-
4159
- .importField {
4160
- display: flex;
4161
- flex-direction: column;
4162
- gap: var(--nf-space-6, 5px);
4163
- font-size: var(--nf-fs-14, 13px);
4164
- color: var(--nf-text-2);
4165
- }
4166
-
4167
- .importHint {
4168
- font-size: var(--nf-fs-12, 12px);
4169
- color: var(--nf-text-3);
4170
- line-height: 1.5;
4171
- }
4172
-
4173
- .importError {
4174
- border: 1px solid color-mix(in srgb, var(--nf-danger, #e5484d) 55%, transparent);
4175
- border-radius: var(--nf-radius-10, 10px);
4176
- padding: var(--nf-space-8, 8px) var(--nf-space-10, 10px);
4177
- font-size: var(--nf-fs-12, 12.5px);
4178
- color: var(--nf-danger, #e5484d);
4179
- background: color-mix(in srgb, var(--nf-danger, #e5484d) 10%, transparent);
4180
- white-space: pre-wrap;
4181
- word-break: break-all;
4182
- }
4183
-
4184
- .importResult {
4185
- display: flex;
4186
- flex-direction: column;
4187
- gap: var(--nf-space-4, 4px);
4188
- border: 1px solid color-mix(in srgb, var(--nf-ok, #46a758) 45%, transparent);
4189
- border-radius: var(--nf-radius-10, 10px);
4190
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
4191
- font-size: var(--nf-fs-14, 13px);
4192
- background: color-mix(in srgb, var(--nf-ok, #46a758) 9%, transparent);
4193
- word-break: break-all;
4194
- }
4195
-
4196
- .importModalActions {
4197
- display: flex;
4198
- justify-content: flex-end;
4199
- gap: var(--nf-space-8, 8px);
4200
- }
4201
-
4202
- .importFileInfo {
4203
- display: flex;
4204
- align-items: center;
4205
- gap: var(--nf-space-8, 8px);
4206
- font-size: var(--nf-fs-14, 13px);
4207
- color: var(--nf-text-1);
4208
- flex-wrap: wrap;
4209
- }
4210
-
4211
- .importPreview {
4212
- display: flex;
4213
- flex-direction: column;
4214
- gap: var(--nf-space-4, 4px);
4215
- border: 1px solid var(--nf-border-strong);
4216
- border-radius: var(--nf-radius-10, 10px);
4217
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
4218
- font-size: var(--nf-fs-14, 13px);
4219
- background: var(--nf-bg-inset);
4220
- }
4221
-
4222
- .importPreviewList {
4223
- margin: 0;
4224
- padding-left: var(--nf-space-18, 18px);
4225
- display: flex;
4226
- flex-direction: column;
4227
- gap: var(--nf-space-2, 2px);
4228
- font-size: var(--nf-fs-12, 12.5px);
4229
- color: var(--nf-text-2);
4230
- max-height: 140px;
4231
- overflow: auto;
4232
- }
4233
-
4234
- /* 设置页卡片:label 单行、行内顶部对齐,保证输入框水平对齐 */
4235
- /* 设置页卡片:防止内层卡片/长内容在 flex 容器中撑破外层卡片 */
4236
- .settingsCard {
4237
- min-width: 0;
4238
- max-width: 100%;
4239
- }
4240
-
4241
- .settingsCard > * {
4242
- min-width: 0;
4243
- }
4244
-
4245
- /* ModelManager 等组件会在设置卡片内再渲染 .card 子卡片,也必须允许收缩 */
4246
- .settingsCard .card {
4247
- min-width: 0;
4248
- width: 100%;
4249
- max-width: 100%;
4250
- }
4251
-
4252
- .settingsCard .fieldLabel {
4253
- min-height: 18px;
4254
- line-height: 18px;
4255
- white-space: nowrap;
4256
- overflow: hidden;
4257
- text-overflow: ellipsis;
4258
- max-width: 100%;
4259
- }
4260
-
4261
- .settingsCard .row {
4262
- align-items: flex-start;
4263
- }
4264
-
4265
-
4266
-
4267
- .helpTipText {
4268
- display: none;
4269
- position: absolute;
4270
- left: 50%;
4271
- bottom: calc(100% + 8px);
4272
- transform: translateX(-50%);
4273
- width: 280px;
4274
- max-width: 70vw;
4275
- padding: var(--nf-space-10, 10px) var(--nf-space-12, 12px);
4276
- border-radius: var(--nf-radius-10, 10px);
4277
- background: var(--nf-bg-raise);
4278
- border: 1px solid var(--nf-border-strong);
4279
- box-shadow: var(--nf-shadow-lg);
4280
- font-size: var(--nf-fs-12, 12px);
4281
- font-weight: 400;
4282
- line-height: 1.7;
4283
- color: var(--nf-text-2);
4284
- white-space: normal;
4285
- z-index: 20;
4286
- text-align: left;
4287
- pointer-events: none;
4288
- }
4289
-
4290
- .helpTip:hover .helpTipText,
4291
- .helpTip:focus .helpTipText,
4292
- .helpTip:focus-within .helpTipText {
4293
- display: block;
4294
- }
4295
-
4296
- /* 设置页:字号已统一为全局档(次要 12 / 主 14 / 标题 16+),不再放大;
4297
- * 主容器由 .card 的 --nf-card-pad 统一提供(舒适 20px 22px)。 */
4298
- .settingsCard + .settingsCard {
4299
- /* 不再强制拉伸/压缩:设置卡片按内容自适应高度,避免内层分类跑出容器 */
4300
- flex: 0 0 auto;
4301
- min-height: auto;
4302
- }
4303
-
4304
- /* 设置页开关(滑块) */
4305
- .switch {
4306
- position: relative;
4307
- width: 42px;
4308
- height: 24px;
4309
- border-radius: var(--nf-radius-999, 999px);
4310
- border: 1px solid var(--nf-border-strong);
4311
- background: var(--nf-bg-inset);
4312
- cursor: pointer;
4313
- padding: 0;
4314
- flex: none;
4315
- transition: background 0.18s ease, border-color 0.18s ease;
4316
- }
4317
-
4318
- .switchKnob {
4319
- position: absolute;
4320
- top: 3px;
4321
- left: 3px;
4322
- width: 16px;
4323
- height: 16px;
4324
- border-radius: 50%;
4325
- background: #fff;
4326
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
4327
- transition: transform 0.18s ease;
4328
- }
4329
-
4330
- .switchOn {
4331
- background: var(--nf-accent);
4332
- border-color: var(--nf-accent);
4333
- }
4334
-
4335
- .switchOn .switchKnob {
4336
- transform: translateX(18px);
4337
- }
4338
-
4339
- /* ---- 玻璃透明度滑块:实色主题(新拟态/黏土)调低时变透,透出背景图 ---- */
4340
- /* 默认 --nf-glass-opacity=100%,color-mix 透明 0% → 与主题原值一致,不改动现有效果。 */
4341
- .panel[data-nf-theme='neumorph']:not([data-nf-mode='dark']),
4342
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='neumorph'][data-nf-mode='light'] {
4343
- --nf-glass-face: color-mix(in srgb, #e4e9f2, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4344
- --nf-bg-raise: color-mix(in srgb, #e4e9f2, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4345
- }
4346
- .panel[data-nf-mode='dark'][data-nf-theme='neumorph'],
4347
- body[data-ds-dark-theme] .panel[data-nf-theme='neumorph']:not([data-nf-mode]) {
4348
- --nf-glass-face: color-mix(in srgb, #2b2f36, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4349
- --nf-bg-raise: color-mix(in srgb, #2b2f36, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4350
- }
4351
- .panel[data-nf-theme='clay']:not([data-nf-mode='dark']),
4352
- body:not([data-ds-dark-theme]) .panel[data-nf-theme='clay'][data-nf-mode='light'] {
4353
- --nf-glass-face: color-mix(in srgb, #efe4d6, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4354
- --nf-bg-raise: color-mix(in srgb, #efe4d6, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4355
- }
4356
- .panel[data-nf-mode='dark'][data-nf-theme='clay'],
4357
- body[data-ds-dark-theme] .panel[data-nf-theme='clay']:not([data-nf-mode]) {
4358
- --nf-glass-face: color-mix(in srgb, #37302b, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4359
- --nf-bg-raise: color-mix(in srgb, #37302b, transparent calc(100% - var(--nf-glass-opacity, 100%)));
4360
- }