@bytechain.cn/colamd-themes 0.3.1 → 0.5.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 (100) hide show
  1. package/.claude/skills/colamd-themes-preview.skill.md +333 -0
  2. package/.claude/skills/colamd-themes.skill.md +10 -0
  3. package/.dsh/skills/colamd-themes/SKILL.md +14 -0
  4. package/.github/supported-topics.yml +17 -0
  5. package/.hermes/skills/tools/colamd-themes/SKILL.md +14 -0
  6. package/.openclaw/skills/colamd-themes/SKILL.md +1 -146
  7. package/.opencode/skills/colamd-themes/SKILL.md +17 -0
  8. package/.trae/rules/colamd-themes.md +0 -145
  9. package/CHANGELOG.md +318 -240
  10. package/DSH_SUPPORT_SUMMARY.md +87 -0
  11. package/README.md +414 -384
  12. package/README_CN.md +412 -384
  13. package/RELEASENOTE.md +541 -365
  14. package/bytechain.cn-colamd-themes-0.5.0.tgz +0 -0
  15. package/dist/cli.js +272 -32
  16. package/dist/cli.js.map +1 -1
  17. package/dist/color-utils.d.ts +1 -0
  18. package/dist/color-utils.js +25 -6
  19. package/dist/color-utils.js.map +1 -1
  20. package/dist/extractors/pdf-extractor.js +6 -1
  21. package/dist/extractors/pdf-extractor.js.map +1 -1
  22. package/dist/extractors/url-extractor.d.ts +0 -4
  23. package/dist/extractors/url-extractor.js +13 -126
  24. package/dist/extractors/url-extractor.js.map +1 -1
  25. package/dist/generator.d.ts +1 -1
  26. package/dist/generator.js +32 -11
  27. package/dist/generator.js.map +1 -1
  28. package/dist/models.d.ts +5 -4
  29. package/dist/models.js +2 -3
  30. package/dist/models.js.map +1 -1
  31. package/dist/renderer.d.ts +4 -2
  32. package/dist/renderer.js +68 -25
  33. package/dist/renderer.js.map +1 -1
  34. package/dist/templates/template.css +220 -498
  35. package/dist/templates/theme-paradigm.md +530 -658
  36. package/dist/templates/theme-template.hbs +256 -370
  37. package/dist/theme-store.js +19 -3
  38. package/dist/theme-store.js.map +1 -1
  39. package/dist/utils/document-paradigm.d.ts +12 -0
  40. package/dist/utils/document-paradigm.js +109 -0
  41. package/dist/utils/document-paradigm.js.map +1 -0
  42. package/dist/validators.d.ts +4 -1
  43. package/dist/validators.js +115 -1
  44. package/dist/validators.js.map +1 -1
  45. package/mcp-server/dist/index.d.ts +13 -0
  46. package/mcp-server/dist/index.d.ts.map +1 -0
  47. package/mcp-server/dist/index.js +0 -0
  48. package/mcp-server/dist/index.js.map +1 -0
  49. package/mcp-server/package-lock.json +1759 -0
  50. package/mcp-server/package.json +24 -0
  51. package/mcp-server/src/index.ts +0 -0
  52. package/mcp-server/tsconfig.json +19 -0
  53. package/package.json +54 -36
  54. package/skills/build-skills.sh +30 -5
  55. package/skills/colamd-themes/SKILL.md +180 -148
  56. package/src/cli.ts +474 -217
  57. package/src/color-systems.ts +289 -289
  58. package/src/color-utils.ts +137 -120
  59. package/src/contrast.ts +66 -66
  60. package/src/docx-style-paradigm.ts +811 -811
  61. package/src/export-cli.ts +356 -356
  62. package/src/extractors/base.ts +8 -8
  63. package/src/extractors/docx-extractor.ts +417 -417
  64. package/src/extractors/pdf-extractor.ts +533 -527
  65. package/src/extractors/url-extractor.ts +846 -981
  66. package/src/generator.ts +197 -169
  67. package/src/index.ts +29 -29
  68. package/src/models.ts +212 -212
  69. package/src/renderer.ts +332 -288
  70. package/src/templates/template.css +220 -498
  71. package/src/templates/theme-paradigm.md +530 -658
  72. package/src/templates/theme-template.hbs +256 -370
  73. package/src/theme-store.ts +185 -170
  74. package/src/types/pdf-parse.d.ts +12 -12
  75. package/src/utils/cli-utils.ts +84 -84
  76. package/src/utils/document-paradigm.ts +118 -0
  77. package/src/validators.ts +298 -176
  78. package/themes/academic-paper-pt.css +353 -1805
  79. package/themes/academic-paper.css +350 -1099
  80. package/themes/academic-style.css +342 -2430
  81. package/themes/colly.css +256 -370
  82. package/themes/elegant.css +288 -671
  83. package/themes/forest-ink.css +240 -664
  84. package/themes/guizang.css +250 -732
  85. package/themes/hermes-security.css +279 -0
  86. package/themes/meeting-minutes.css +256 -370
  87. package/themes/pixso-design.css +278 -1261
  88. package/themes/salvator-blog.css +256 -370
  89. package/themes/shimo-theme.css +256 -0
  90. package/themes/swiss-design.css +285 -746
  91. package/themes/template.css +220 -498
  92. package/themes/trae-blue.css +280 -737
  93. package/themes/word-contract.css +249 -0
  94. package/themes-preview/demo-content.md +187 -187
  95. package/tsconfig.json +18 -18
  96. package/src/mermaid-presets.ts +0 -142
  97. package/themes/swiss-design copy.css +0 -746
  98. package/themes-preview/colly-preview.html +0 -623
  99. package/themes-preview/meeting-minutes-preview.html +0 -625
  100. package/themes-preview/salvator-blog-preview.html +0 -623
@@ -1,289 +1,289 @@
1
- /**
2
- * Local color system library — predefined seed palettes for popular color schemes.
3
- * Each scheme provides a complete SeedPalette (5 seed colors + variants).
4
- */
5
-
6
- import type { SeedPalette } from "./validators.js";
7
- import { hslHue, hslSaturation, hslLightness } from "./contrast.js";
8
-
9
- export interface ColorSystem {
10
- id: string;
11
- name: string;
12
- nameCN: string;
13
- description: string;
14
- mode: "light" | "dark";
15
- palette: SeedPalette;
16
- }
17
-
18
- // ═══════════════════════════════════════════════════════════
19
- // 莫兰迪 (Morandi) — 低饱和度灰调
20
- // ═══════════════════════════════════════════════════════════
21
-
22
- const morandiPink: ColorSystem = {
23
- id: "morandi-pink",
24
- name: "Morandi Pink",
25
- nameCN: "莫兰迪 灰粉",
26
- description: "低饱和度灰粉基调,柔和慵懒",
27
- mode: "light",
28
- palette: {
29
- accent: "#b08a82", accentLight: "#e8ddd8", accentDark: "#8b6b63",
30
- surface: "#f5f2f0", panel: "#ece6e2", panelAlt: "#e2dad5",
31
- ink: "#3a3533", inkMuted: "#8a807c", inkDim: "#b0a8a4",
32
- border: "#d8d2ce", borderStrong: "#c0b8b4",
33
- },
34
- };
35
-
36
- const morandiGreen: ColorSystem = {
37
- id: "morandi-green",
38
- name: "Morandi Green",
39
- nameCN: "莫兰迪 灰绿",
40
- description: "低饱和度灰绿调,沉静淡雅",
41
- mode: "light",
42
- palette: {
43
- accent: "#8a9b7a", accentLight: "#e2e8dc", accentDark: "#6b7a5e",
44
- surface: "#f4f5f2", panel: "#e8ebe4", panelAlt: "#dce0d5",
45
- ink: "#3a3d35", inkMuted: "#8a8d82", inkDim: "#b0b4a8",
46
- border: "#d4d8ce", borderStrong: "#bcc0b4",
47
- },
48
- };
49
-
50
- const morandiBlue: ColorSystem = {
51
- id: "morandi-blue",
52
- name: "Morandi Blue",
53
- nameCN: "莫兰迪 灰蓝",
54
- description: "低饱和度灰蓝调,冷静克制",
55
- mode: "light",
56
- palette: {
57
- accent: "#7a8fa0", accentLight: "#dce4e8", accentDark: "#5e7080",
58
- surface: "#f2f4f6", panel: "#e6eaee", panelAlt: "#dae0e6",
59
- ink: "#353a3f", inkMuted: "#828a92", inkDim: "#a8b0b8",
60
- border: "#ced4dc", borderStrong: "#b4bcc4",
61
- },
62
- };
63
-
64
- // ═══════════════════════════════════════════════════════════
65
- // 马卡龙 (Macaron) — 粉彩糖果色
66
- // ═══════════════════════════════════════════════════════════
67
-
68
- const macaronStrawberry: ColorSystem = {
69
- id: "macaron-strawberry",
70
- name: "Macaron Strawberry",
71
- nameCN: "马卡龙 草莓",
72
- description: "柔粉奶油色,甜美活泼",
73
- mode: "light",
74
- palette: {
75
- accent: "#e893a6", accentLight: "#fde8ec", accentDark: "#c47082",
76
- surface: "#fefafb", panel: "#faf0f2", panelAlt: "#f4e4e8",
77
- ink: "#4a3035", inkMuted: "#9a8086", inkDim: "#c0a8ae",
78
- border: "#eed4d8", borderStrong: "#dab8be",
79
- },
80
- };
81
-
82
- const macaronMint: ColorSystem = {
83
- id: "macaron-mint",
84
- name: "Macaron Mint",
85
- nameCN: "马卡龙 薄荷",
86
- description: "清新薄荷绿,轻盈爽朗",
87
- mode: "light",
88
- palette: {
89
- accent: "#8cc9a8", accentLight: "#e6f6ee", accentDark: "#6aaa88",
90
- surface: "#f8fcfa", panel: "#eef6f2", panelAlt: "#e2f0e8",
91
- ink: "#304538", inkMuted: "#809588", inkDim: "#a8c0b0",
92
- border: "#cce8d6", borderStrong: "#b0d4bc",
93
- },
94
- };
95
-
96
- const macaronBlueberry: ColorSystem = {
97
- id: "macaron-blueberry",
98
- name: "Macaron Blueberry",
99
- nameCN: "马卡龙 蓝莓",
100
- description: "淡紫蓝调,温柔梦幻",
101
- mode: "light",
102
- palette: {
103
- accent: "#9aa8e0", accentLight: "#eaecf8", accentDark: "#7888c0",
104
- surface: "#f8f8fc", panel: "#f0f2f8", panelAlt: "#e6e8f4",
105
- ink: "#303548", inkMuted: "#808898", inkDim: "#a8b0c0",
106
- border: "#d0d4e8", borderStrong: "#b8bcd4",
107
- },
108
- };
109
-
110
- // ═══════════════════════════════════════════════════════════
111
- // 北欧 (Nordic) — 极简自然色
112
- // ═══════════════════════════════════════════════════════════
113
-
114
- const nordicWood: ColorSystem = {
115
- id: "nordic-wood",
116
- name: "Nordic Wood",
117
- nameCN: "北欧 原木",
118
- description: "浅木色与暖白搭配,自然温馨",
119
- mode: "light",
120
- palette: {
121
- accent: "#8b7355", accentLight: "#e8e0d4", accentDark: "#6b5a40",
122
- surface: "#faf8f4", panel: "#f2eeea", panelAlt: "#e8e2dc",
123
- ink: "#3a3530", inkMuted: "#8a8078", inkDim: "#b0a89e",
124
- border: "#d8d0c4", borderStrong: "#c0b8aa",
125
- },
126
- };
127
-
128
- const nordicMinimal: ColorSystem = {
129
- id: "nordic-minimal",
130
- name: "Nordic Minimal",
131
- nameCN: "北欧 极简白",
132
- description: "纯白基调,冷蓝点缀,极致简洁",
133
- mode: "light",
134
- palette: {
135
- accent: "#4a7c96", accentLight: "#dce6ec", accentDark: "#3a6078",
136
- surface: "#fefefe", panel: "#f6f8fa", panelAlt: "#eef2f6",
137
- ink: "#2a2a2a", inkMuted: "#7a7a7a", inkDim: "#aaaaaa",
138
- border: "#e0e0e0", borderStrong: "#c8c8c8",
139
- },
140
- };
141
-
142
- const nordicGray: ColorSystem = {
143
- id: "nordic-gray",
144
- name: "Nordic Gray",
145
- nameCN: "北欧 灰调",
146
- description: "中灰基调,森林绿点缀,沉稳自然",
147
- mode: "light",
148
- palette: {
149
- accent: "#6b8a7a", accentLight: "#dce6e0", accentDark: "#4e6b5c",
150
- surface: "#f6f5f4", panel: "#edebe8", panelAlt: "#e2e0dc",
151
- ink: "#3a3a3a", inkMuted: "#8a8a8a", inkDim: "#b0b0b0",
152
- border: "#d8d6d2", borderStrong: "#c0beb8",
153
- },
154
- };
155
-
156
- // ═══════════════════════════════════════════════════════════
157
- // 复古 (Vintage) — 暖棕岁月感
158
- // ═══════════════════════════════════════════════════════════
159
-
160
- const vintageWarmBrown: ColorSystem = {
161
- id: "vintage-brown",
162
- name: "Vintage Warm Brown",
163
- nameCN: "复古 暖棕",
164
- description: "暖棕纸色,旧时光氛围",
165
- mode: "light",
166
- palette: {
167
- accent: "#8b5e3c", accentLight: "#e8dcd0", accentDark: "#6b4428",
168
- surface: "#f8f2ea", panel: "#f0e8dc", panelAlt: "#e6dcc8",
169
- ink: "#3a3028", inkMuted: "#8a7a6a", inkDim: "#b0a090",
170
- border: "#d4c8b8", borderStrong: "#bca898",
171
- },
172
- };
173
-
174
- const vintageNewspaper: ColorSystem = {
175
- id: "vintage-newspaper",
176
- name: "Vintage Newspaper",
177
- nameCN: "复古 旧报纸",
178
- description: "泛黄纸色,怀旧阅读感",
179
- mode: "light",
180
- palette: {
181
- accent: "#7a5a3a", accentLight: "#e8dcc8", accentDark: "#5a4028",
182
- surface: "#f4f0e0", panel: "#ece4d0", panelAlt: "#e2d8c0",
183
- ink: "#3a3528", inkMuted: "#8a8070", inkDim: "#b0a898",
184
- border: "#c8c0a8", borderStrong: "#b0a890",
185
- },
186
- };
187
-
188
- const vintageWine: ColorSystem = {
189
- id: "vintage-wine",
190
- name: "Vintage Wine",
191
- nameCN: "复古 酒红",
192
- description: "暗酒红点缀,浓郁优雅",
193
- mode: "light",
194
- palette: {
195
- accent: "#8b3a3a", accentLight: "#e8d4d4", accentDark: "#6b2828",
196
- surface: "#f8f2f2", panel: "#f0e8e8", panelAlt: "#e6dcdc",
197
- ink: "#3a2a2a", inkMuted: "#8a7070", inkDim: "#b09898",
198
- border: "#d4c0c0", borderStrong: "#bca8a8",
199
- },
200
- };
201
-
202
- // ═══════════════════════════════════════════════════════════
203
- // 薄荷绿 (Mint) — 清新自然
204
- // ═══════════════════════════════════════════════════════════
205
-
206
- const mintFresh: ColorSystem = {
207
- id: "mint-fresh",
208
- name: "Mint Fresh",
209
- nameCN: "薄荷绿 清新",
210
- description: "鲜嫩薄荷叶色,清爽宜人",
211
- mode: "light",
212
- palette: {
213
- accent: "#5aaa80", accentLight: "#dceee4", accentDark: "#408860",
214
- surface: "#f8fcfa", panel: "#eef6f2", panelAlt: "#e2f0e8",
215
- ink: "#2a3a30", inkMuted: "#708a78", inkDim: "#98b0a0",
216
- border: "#c8e4d4", borderStrong: "#a8ccb8",
217
- },
218
- };
219
-
220
- const mintDeep: ColorSystem = {
221
- id: "mint-deep",
222
- name: "Mint Deep",
223
- nameCN: "薄荷绿 深薄荷",
224
- description: "深邃薄荷绿,沉稳清新",
225
- mode: "light",
226
- palette: {
227
- accent: "#3a8a60", accentLight: "#d4e8dc", accentDark: "#286a48",
228
- surface: "#f4f8f6", panel: "#e8f0ec", panelAlt: "#dce8e2",
229
- ink: "#283830", inkMuted: "#708878", inkDim: "#98b0a0",
230
- border: "#b8dcc8", borderStrong: "#98c4ac",
231
- },
232
- };
233
-
234
- const mintDew: ColorSystem = {
235
- id: "mint-dew",
236
- name: "Mint Dew",
237
- nameCN: "薄荷绿 晨露",
238
- description: "晨露般清透浅绿,轻柔温和",
239
- mode: "light",
240
- palette: {
241
- accent: "#7ab898", accentLight: "#e0f0e8", accentDark: "#5a9878",
242
- surface: "#fafdfc", panel: "#f2f8f4", panelAlt: "#e8f2ec",
243
- ink: "#2c3832", inkMuted: "#788880", inkDim: "#a0b0a8",
244
- border: "#d0e8dc", borderStrong: "#b8d4c4",
245
- },
246
- };
247
-
248
- // ── Registry ──
249
-
250
- export const COLOR_SYSTEMS: ColorSystem[] = [
251
- morandiPink, morandiGreen, morandiBlue,
252
- macaronStrawberry, macaronMint, macaronBlueberry,
253
- nordicWood, nordicMinimal, nordicGray,
254
- vintageWarmBrown, vintageNewspaper, vintageWine,
255
- mintFresh, mintDeep, mintDew,
256
- ];
257
-
258
- export function getColorSystem(id: string): ColorSystem | undefined {
259
- return COLOR_SYSTEMS.find((cs) => cs.id === id);
260
- }
261
-
262
- /** Match extracted accent/surface to the nearest color system by hue + saturation distance. */
263
- export function matchColorSystem(accent: string, surface: string): ColorSystem {
264
- const hAccent = hslHue(accent);
265
- const sAccent = hslSaturation(accent);
266
- const lSurface = hslLightness(surface);
267
-
268
- let best = COLOR_SYSTEMS[0];
269
- let bestDist = Infinity;
270
-
271
- for (const cs of COLOR_SYSTEMS) {
272
- const hCs = hslHue(cs.palette.accent);
273
- const sCs = hslSaturation(cs.palette.accent);
274
- const lCs = hslLightness(cs.palette.surface);
275
-
276
- // Weighted distance: hue 40%, saturation 30%, lightness 30%
277
- const dH = Math.abs(hAccent - hCs);
278
- const hueDist = Math.min(dH, 360 - dH) / 360; // wrap around
279
- const satDist = Math.abs(sAccent - sCs);
280
- const lumDist = Math.abs(lSurface - lCs);
281
- const dist = hueDist * 0.4 + satDist * 0.3 + lumDist * 0.3;
282
-
283
- if (dist < bestDist) {
284
- bestDist = dist;
285
- best = cs;
286
- }
287
- }
288
- return best;
289
- }
1
+ /**
2
+ * Local color system library — predefined seed palettes for popular color schemes.
3
+ * Each scheme provides a complete SeedPalette (5 seed colors + variants).
4
+ */
5
+
6
+ import type { SeedPalette } from "./validators.js";
7
+ import { hslHue, hslSaturation, hslLightness } from "./contrast.js";
8
+
9
+ export interface ColorSystem {
10
+ id: string;
11
+ name: string;
12
+ nameCN: string;
13
+ description: string;
14
+ mode: "light" | "dark";
15
+ palette: SeedPalette;
16
+ }
17
+
18
+ // ═══════════════════════════════════════════════════════════
19
+ // 莫兰迪 (Morandi) — 低饱和度灰调
20
+ // ═══════════════════════════════════════════════════════════
21
+
22
+ const morandiPink: ColorSystem = {
23
+ id: "morandi-pink",
24
+ name: "Morandi Pink",
25
+ nameCN: "莫兰迪 灰粉",
26
+ description: "低饱和度灰粉基调,柔和慵懒",
27
+ mode: "light",
28
+ palette: {
29
+ accent: "#b08a82", accentLight: "#e8ddd8", accentDark: "#8b6b63",
30
+ surface: "#f5f2f0", panel: "#ece6e2", panelAlt: "#e2dad5",
31
+ ink: "#3a3533", inkMuted: "#8a807c", inkDim: "#b0a8a4",
32
+ border: "#d8d2ce", borderStrong: "#c0b8b4",
33
+ },
34
+ };
35
+
36
+ const morandiGreen: ColorSystem = {
37
+ id: "morandi-green",
38
+ name: "Morandi Green",
39
+ nameCN: "莫兰迪 灰绿",
40
+ description: "低饱和度灰绿调,沉静淡雅",
41
+ mode: "light",
42
+ palette: {
43
+ accent: "#8a9b7a", accentLight: "#e2e8dc", accentDark: "#6b7a5e",
44
+ surface: "#f4f5f2", panel: "#e8ebe4", panelAlt: "#dce0d5",
45
+ ink: "#3a3d35", inkMuted: "#8a8d82", inkDim: "#b0b4a8",
46
+ border: "#d4d8ce", borderStrong: "#bcc0b4",
47
+ },
48
+ };
49
+
50
+ const morandiBlue: ColorSystem = {
51
+ id: "morandi-blue",
52
+ name: "Morandi Blue",
53
+ nameCN: "莫兰迪 灰蓝",
54
+ description: "低饱和度灰蓝调,冷静克制",
55
+ mode: "light",
56
+ palette: {
57
+ accent: "#7a8fa0", accentLight: "#dce4e8", accentDark: "#5e7080",
58
+ surface: "#f2f4f6", panel: "#e6eaee", panelAlt: "#dae0e6",
59
+ ink: "#353a3f", inkMuted: "#828a92", inkDim: "#a8b0b8",
60
+ border: "#ced4dc", borderStrong: "#b4bcc4",
61
+ },
62
+ };
63
+
64
+ // ═══════════════════════════════════════════════════════════
65
+ // 马卡龙 (Macaron) — 粉彩糖果色
66
+ // ═══════════════════════════════════════════════════════════
67
+
68
+ const macaronStrawberry: ColorSystem = {
69
+ id: "macaron-strawberry",
70
+ name: "Macaron Strawberry",
71
+ nameCN: "马卡龙 草莓",
72
+ description: "柔粉奶油色,甜美活泼",
73
+ mode: "light",
74
+ palette: {
75
+ accent: "#e893a6", accentLight: "#fde8ec", accentDark: "#c47082",
76
+ surface: "#fefafb", panel: "#faf0f2", panelAlt: "#f4e4e8",
77
+ ink: "#4a3035", inkMuted: "#9a8086", inkDim: "#c0a8ae",
78
+ border: "#eed4d8", borderStrong: "#dab8be",
79
+ },
80
+ };
81
+
82
+ const macaronMint: ColorSystem = {
83
+ id: "macaron-mint",
84
+ name: "Macaron Mint",
85
+ nameCN: "马卡龙 薄荷",
86
+ description: "清新薄荷绿,轻盈爽朗",
87
+ mode: "light",
88
+ palette: {
89
+ accent: "#8cc9a8", accentLight: "#e6f6ee", accentDark: "#6aaa88",
90
+ surface: "#f8fcfa", panel: "#eef6f2", panelAlt: "#e2f0e8",
91
+ ink: "#304538", inkMuted: "#809588", inkDim: "#a8c0b0",
92
+ border: "#cce8d6", borderStrong: "#b0d4bc",
93
+ },
94
+ };
95
+
96
+ const macaronBlueberry: ColorSystem = {
97
+ id: "macaron-blueberry",
98
+ name: "Macaron Blueberry",
99
+ nameCN: "马卡龙 蓝莓",
100
+ description: "淡紫蓝调,温柔梦幻",
101
+ mode: "light",
102
+ palette: {
103
+ accent: "#9aa8e0", accentLight: "#eaecf8", accentDark: "#7888c0",
104
+ surface: "#f8f8fc", panel: "#f0f2f8", panelAlt: "#e6e8f4",
105
+ ink: "#303548", inkMuted: "#808898", inkDim: "#a8b0c0",
106
+ border: "#d0d4e8", borderStrong: "#b8bcd4",
107
+ },
108
+ };
109
+
110
+ // ═══════════════════════════════════════════════════════════
111
+ // 北欧 (Nordic) — 极简自然色
112
+ // ═══════════════════════════════════════════════════════════
113
+
114
+ const nordicWood: ColorSystem = {
115
+ id: "nordic-wood",
116
+ name: "Nordic Wood",
117
+ nameCN: "北欧 原木",
118
+ description: "浅木色与暖白搭配,自然温馨",
119
+ mode: "light",
120
+ palette: {
121
+ accent: "#8b7355", accentLight: "#e8e0d4", accentDark: "#6b5a40",
122
+ surface: "#faf8f4", panel: "#f2eeea", panelAlt: "#e8e2dc",
123
+ ink: "#3a3530", inkMuted: "#8a8078", inkDim: "#b0a89e",
124
+ border: "#d8d0c4", borderStrong: "#c0b8aa",
125
+ },
126
+ };
127
+
128
+ const nordicMinimal: ColorSystem = {
129
+ id: "nordic-minimal",
130
+ name: "Nordic Minimal",
131
+ nameCN: "北欧 极简白",
132
+ description: "纯白基调,冷蓝点缀,极致简洁",
133
+ mode: "light",
134
+ palette: {
135
+ accent: "#4a7c96", accentLight: "#dce6ec", accentDark: "#3a6078",
136
+ surface: "#fefefe", panel: "#f6f8fa", panelAlt: "#eef2f6",
137
+ ink: "#2a2a2a", inkMuted: "#7a7a7a", inkDim: "#aaaaaa",
138
+ border: "#e0e0e0", borderStrong: "#c8c8c8",
139
+ },
140
+ };
141
+
142
+ const nordicGray: ColorSystem = {
143
+ id: "nordic-gray",
144
+ name: "Nordic Gray",
145
+ nameCN: "北欧 灰调",
146
+ description: "中灰基调,森林绿点缀,沉稳自然",
147
+ mode: "light",
148
+ palette: {
149
+ accent: "#6b8a7a", accentLight: "#dce6e0", accentDark: "#4e6b5c",
150
+ surface: "#f6f5f4", panel: "#edebe8", panelAlt: "#e2e0dc",
151
+ ink: "#3a3a3a", inkMuted: "#8a8a8a", inkDim: "#b0b0b0",
152
+ border: "#d8d6d2", borderStrong: "#c0beb8",
153
+ },
154
+ };
155
+
156
+ // ═══════════════════════════════════════════════════════════
157
+ // 复古 (Vintage) — 暖棕岁月感
158
+ // ═══════════════════════════════════════════════════════════
159
+
160
+ const vintageWarmBrown: ColorSystem = {
161
+ id: "vintage-brown",
162
+ name: "Vintage Warm Brown",
163
+ nameCN: "复古 暖棕",
164
+ description: "暖棕纸色,旧时光氛围",
165
+ mode: "light",
166
+ palette: {
167
+ accent: "#8b5e3c", accentLight: "#e8dcd0", accentDark: "#6b4428",
168
+ surface: "#f8f2ea", panel: "#f0e8dc", panelAlt: "#e6dcc8",
169
+ ink: "#3a3028", inkMuted: "#8a7a6a", inkDim: "#b0a090",
170
+ border: "#d4c8b8", borderStrong: "#bca898",
171
+ },
172
+ };
173
+
174
+ const vintageNewspaper: ColorSystem = {
175
+ id: "vintage-newspaper",
176
+ name: "Vintage Newspaper",
177
+ nameCN: "复古 旧报纸",
178
+ description: "泛黄纸色,怀旧阅读感",
179
+ mode: "light",
180
+ palette: {
181
+ accent: "#7a5a3a", accentLight: "#e8dcc8", accentDark: "#5a4028",
182
+ surface: "#f4f0e0", panel: "#ece4d0", panelAlt: "#e2d8c0",
183
+ ink: "#3a3528", inkMuted: "#8a8070", inkDim: "#b0a898",
184
+ border: "#c8c0a8", borderStrong: "#b0a890",
185
+ },
186
+ };
187
+
188
+ const vintageWine: ColorSystem = {
189
+ id: "vintage-wine",
190
+ name: "Vintage Wine",
191
+ nameCN: "复古 酒红",
192
+ description: "暗酒红点缀,浓郁优雅",
193
+ mode: "light",
194
+ palette: {
195
+ accent: "#8b3a3a", accentLight: "#e8d4d4", accentDark: "#6b2828",
196
+ surface: "#f8f2f2", panel: "#f0e8e8", panelAlt: "#e6dcdc",
197
+ ink: "#3a2a2a", inkMuted: "#8a7070", inkDim: "#b09898",
198
+ border: "#d4c0c0", borderStrong: "#bca8a8",
199
+ },
200
+ };
201
+
202
+ // ═══════════════════════════════════════════════════════════
203
+ // 薄荷绿 (Mint) — 清新自然
204
+ // ═══════════════════════════════════════════════════════════
205
+
206
+ const mintFresh: ColorSystem = {
207
+ id: "mint-fresh",
208
+ name: "Mint Fresh",
209
+ nameCN: "薄荷绿 清新",
210
+ description: "鲜嫩薄荷叶色,清爽宜人",
211
+ mode: "light",
212
+ palette: {
213
+ accent: "#5aaa80", accentLight: "#dceee4", accentDark: "#408860",
214
+ surface: "#f8fcfa", panel: "#eef6f2", panelAlt: "#e2f0e8",
215
+ ink: "#2a3a30", inkMuted: "#708a78", inkDim: "#98b0a0",
216
+ border: "#c8e4d4", borderStrong: "#a8ccb8",
217
+ },
218
+ };
219
+
220
+ const mintDeep: ColorSystem = {
221
+ id: "mint-deep",
222
+ name: "Mint Deep",
223
+ nameCN: "薄荷绿 深薄荷",
224
+ description: "深邃薄荷绿,沉稳清新",
225
+ mode: "light",
226
+ palette: {
227
+ accent: "#3a8a60", accentLight: "#d4e8dc", accentDark: "#286a48",
228
+ surface: "#f4f8f6", panel: "#e8f0ec", panelAlt: "#dce8e2",
229
+ ink: "#283830", inkMuted: "#708878", inkDim: "#98b0a0",
230
+ border: "#b8dcc8", borderStrong: "#98c4ac",
231
+ },
232
+ };
233
+
234
+ const mintDew: ColorSystem = {
235
+ id: "mint-dew",
236
+ name: "Mint Dew",
237
+ nameCN: "薄荷绿 晨露",
238
+ description: "晨露般清透浅绿,轻柔温和",
239
+ mode: "light",
240
+ palette: {
241
+ accent: "#7ab898", accentLight: "#e0f0e8", accentDark: "#5a9878",
242
+ surface: "#fafdfc", panel: "#f2f8f4", panelAlt: "#e8f2ec",
243
+ ink: "#2c3832", inkMuted: "#788880", inkDim: "#a0b0a8",
244
+ border: "#d0e8dc", borderStrong: "#b8d4c4",
245
+ },
246
+ };
247
+
248
+ // ── Registry ──
249
+
250
+ export const COLOR_SYSTEMS: ColorSystem[] = [
251
+ morandiPink, morandiGreen, morandiBlue,
252
+ macaronStrawberry, macaronMint, macaronBlueberry,
253
+ nordicWood, nordicMinimal, nordicGray,
254
+ vintageWarmBrown, vintageNewspaper, vintageWine,
255
+ mintFresh, mintDeep, mintDew,
256
+ ];
257
+
258
+ export function getColorSystem(id: string): ColorSystem | undefined {
259
+ return COLOR_SYSTEMS.find((cs) => cs.id === id);
260
+ }
261
+
262
+ /** Match extracted accent/surface to the nearest color system by hue + saturation distance. */
263
+ export function matchColorSystem(accent: string, surface: string): ColorSystem {
264
+ const hAccent = hslHue(accent);
265
+ const sAccent = hslSaturation(accent);
266
+ const lSurface = hslLightness(surface);
267
+
268
+ let best = COLOR_SYSTEMS[0];
269
+ let bestDist = Infinity;
270
+
271
+ for (const cs of COLOR_SYSTEMS) {
272
+ const hCs = hslHue(cs.palette.accent);
273
+ const sCs = hslSaturation(cs.palette.accent);
274
+ const lCs = hslLightness(cs.palette.surface);
275
+
276
+ // Weighted distance: hue 40%, saturation 30%, lightness 30%
277
+ const dH = Math.abs(hAccent - hCs);
278
+ const hueDist = Math.min(dH, 360 - dH) / 360; // wrap around
279
+ const satDist = Math.abs(sAccent - sCs);
280
+ const lumDist = Math.abs(lSurface - lCs);
281
+ const dist = hueDist * 0.4 + satDist * 0.3 + lumDist * 0.3;
282
+
283
+ if (dist < bestDist) {
284
+ bestDist = dist;
285
+ best = cs;
286
+ }
287
+ }
288
+ return best;
289
+ }