@topmindspace/tms-skills 0.3.9 → 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 (168) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/README.en.md +12 -9
  3. package/README.md +12 -9
  4. package/bin/tms-skills.js +144 -12
  5. package/package.json +1 -1
  6. package/top-ppt-html/README.en.md +2 -2
  7. package/top-ppt-html/README.md +1 -1
  8. package/top-ppt-html/SKILL.md +8 -7
  9. package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +16 -171
  10. package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.model.json +13 -3
  11. package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +16 -324
  12. package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.model.json +15 -1
  13. package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +16 -917
  14. package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.model.json +15 -1
  15. package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.html +99 -18
  16. package/top-ppt-html/assets/icons/index.json +557 -0
  17. package/top-ppt-html/assets/icons//344/270/212/344/274/240.png +0 -0
  18. package/top-ppt-html/assets/icons//344/270/212/344/274/240.svg +1 -0
  19. package/top-ppt-html/assets/icons//344/270/213/350/275/275.png +0 -0
  20. package/top-ppt-html/assets/icons//344/270/213/350/275/275.svg +1 -0
  21. package/top-ppt-html/assets/icons//344/270/213/351/231/215.png +0 -0
  22. package/top-ppt-html/assets/icons//344/270/213/351/231/215.svg +1 -0
  23. package/top-ppt-html/assets/icons//344/271/246/347/255/276.png +0 -0
  24. package/top-ppt-html/assets/icons//344/271/246/347/255/276.svg +1 -0
  25. package/top-ppt-html/assets/icons//344/272/221.png +0 -0
  26. package/top-ppt-html/assets/icons//344/272/221.svg +1 -0
  27. package/top-ppt-html/assets/icons//344/275/215/347/275/256.png +0 -0
  28. package/top-ppt-html/assets/icons//344/275/215/347/275/256.svg +1 -0
  29. package/top-ppt-html/assets/icons//344/277/241/346/201/257.png +0 -0
  30. package/top-ppt-html/assets/icons//344/277/241/346/201/257.svg +1 -0
  31. package/top-ppt-html/assets/icons//345/210/206/344/272/253.png +0 -0
  32. package/top-ppt-html/assets/icons//345/210/206/344/272/253.svg +1 -0
  33. package/top-ppt-html/assets/icons//345/213/276/351/200/211.png +0 -0
  34. package/top-ppt-html/assets/icons//345/213/276/351/200/211.svg +1 -0
  35. package/top-ppt-html/assets/icons//345/215/240/346/257/224.png +0 -0
  36. package/top-ppt-html/assets/icons//345/215/240/346/257/224.svg +1 -0
  37. package/top-ppt-html/assets/icons//345/233/242/351/230/237.png +0 -0
  38. package/top-ppt-html/assets/icons//345/233/242/351/230/237.svg +1 -0
  39. package/top-ppt-html/assets/icons//345/233/276/350/241/250.png +0 -0
  40. package/top-ppt-html/assets/icons//345/233/276/350/241/250.svg +1 -0
  41. package/top-ppt-html/assets/icons//345/242/236/351/225/277.png +0 -0
  42. package/top-ppt-html/assets/icons//345/242/236/351/225/277.svg +1 -0
  43. package/top-ppt-html/assets/icons//345/256/211/345/205/250.png +0 -0
  44. package/top-ppt-html/assets/icons//345/256/211/345/205/250.svg +1 -0
  45. package/top-ppt-html/assets/icons//345/257/271/350/257/235.png +0 -0
  46. package/top-ppt-html/assets/icons//345/257/271/350/257/235.svg +1 -0
  47. package/top-ppt-html/assets/icons//345/267/245/345/205/267.png +0 -0
  48. package/top-ppt-html/assets/icons//345/267/245/345/205/267.svg +1 -0
  49. package/top-ppt-html/assets/icons//345/276/252/347/216/257.png +0 -0
  50. package/top-ppt-html/assets/icons//345/276/252/347/216/257.svg +1 -0
  51. package/top-ppt-html/assets/icons//346/210/220/346/236/234.png +0 -0
  52. package/top-ppt-html/assets/icons//346/210/220/346/236/234.svg +1 -0
  53. package/top-ppt-html/assets/icons//346/211/213/346/234/272.png +0 -0
  54. package/top-ppt-html/assets/icons//346/211/213/346/234/272.svg +1 -0
  55. package/top-ppt-html/assets/icons//346/225/210/347/216/207.png +0 -0
  56. package/top-ppt-html/assets/icons//346/225/210/347/216/207.svg +1 -0
  57. package/top-ppt-html/assets/icons//346/225/260/346/215/256.png +0 -0
  58. package/top-ppt-html/assets/icons//346/225/260/346/215/256.svg +1 -0
  59. package/top-ppt-html/assets/icons//346/226/207/344/273/266/345/244/271.png +0 -0
  60. package/top-ppt-html/assets/icons//346/226/207/344/273/266/345/244/271.svg +1 -0
  61. package/top-ppt-html/assets/icons//346/226/207/346/241/243.png +0 -0
  62. package/top-ppt-html/assets/icons//346/226/207/346/241/243.svg +1 -0
  63. package/top-ppt-html/assets/icons//346/227/227/345/270/234.png +0 -0
  64. package/top-ppt-html/assets/icons//346/227/227/345/270/234.svg +1 -0
  65. package/top-ppt-html/assets/icons//346/227/266/351/227/264.png +0 -0
  66. package/top-ppt-html/assets/icons//346/227/266/351/227/264.svg +1 -0
  67. package/top-ppt-html/assets/icons//346/230/237/346/240/207.png +0 -0
  68. package/top-ppt-html/assets/icons//346/230/237/346/240/207.svg +1 -0
  69. package/top-ppt-html/assets/icons//346/231/272/350/203/275.png +0 -0
  70. package/top-ppt-html/assets/icons//346/231/272/350/203/275.svg +1 -0
  71. package/top-ppt-html/assets/icons//346/235/203/351/231/220.png +0 -0
  72. package/top-ppt-html/assets/icons//346/235/203/351/231/220.svg +1 -0
  73. package/top-ppt-html/assets/icons//346/243/200/346/237/245.png +0 -0
  74. package/top-ppt-html/assets/icons//346/243/200/346/237/245.svg +1 -0
  75. package/top-ppt-html/assets/icons//346/264/236/345/257/237.png +0 -0
  76. package/top-ppt-html/assets/icons//346/264/236/345/257/237.svg +1 -0
  77. package/top-ppt-html/assets/icons//346/265/201/347/250/213.png +0 -0
  78. package/top-ppt-html/assets/icons//346/265/201/347/250/213.svg +1 -0
  79. package/top-ppt-html/assets/icons//346/270/205/345/215/225.png +0 -0
  80. package/top-ppt-html/assets/icons//346/270/205/345/215/225.svg +1 -0
  81. package/top-ppt-html/assets/icons//347/201/253/347/256/255.png +0 -0
  82. package/top-ppt-html/assets/icons//347/201/253/347/256/255.svg +1 -0
  83. package/top-ppt-html/assets/icons//347/201/257/346/263/241.png +0 -0
  84. package/top-ppt-html/assets/icons//347/201/257/346/263/241.svg +1 -0
  85. package/top-ppt-html/assets/icons//347/224/250/346/210/267.png +0 -0
  86. package/top-ppt-html/assets/icons//347/224/250/346/210/267.svg +1 -0
  87. package/top-ppt-html/assets/icons//347/233/256/346/240/207.png +0 -0
  88. package/top-ppt-html/assets/icons//347/233/256/346/240/207.svg +1 -0
  89. package/top-ppt-html/assets/icons//347/256/255/345/244/264.png +0 -0
  90. package/top-ppt-html/assets/icons//347/256/255/345/244/264.svg +1 -0
  91. package/top-ppt-html/assets/icons//347/273/204/347/273/207.png +0 -0
  92. package/top-ppt-html/assets/icons//347/273/204/347/273/207.svg +1 -0
  93. package/top-ppt-html/assets/icons//347/275/227/347/233/230.png +0 -0
  94. package/top-ppt-html/assets/icons//347/275/227/347/233/230.svg +1 -0
  95. package/top-ppt-html/assets/icons//350/241/250/346/240/274.png +0 -0
  96. package/top-ppt-html/assets/icons//350/241/250/346/240/274.svg +1 -0
  97. package/top-ppt-html/assets/icons//350/256/241/345/210/222.png +0 -0
  98. package/top-ppt-html/assets/icons//350/256/241/345/210/222.svg +1 -0
  99. package/top-ppt-html/assets/icons//350/256/276/347/275/256.png +0 -0
  100. package/top-ppt-html/assets/icons//350/256/276/347/275/256.svg +1 -0
  101. package/top-ppt-html/assets/icons//350/266/213/345/212/277.png +0 -0
  102. package/top-ppt-html/assets/icons//350/266/213/345/212/277.svg +1 -0
  103. package/top-ppt-html/assets/icons//351/202/256/344/273/266.png +0 -0
  104. package/top-ppt-html/assets/icons//351/202/256/344/273/266.svg +1 -0
  105. package/top-ppt-html/assets/icons//351/207/221/351/222/261.png +0 -0
  106. package/top-ppt-html/assets/icons//351/207/221/351/222/261.svg +1 -0
  107. package/top-ppt-html/assets/icons//351/223/276/346/216/245.png +0 -0
  108. package/top-ppt-html/assets/icons//351/223/276/346/216/245.svg +1 -0
  109. package/top-ppt-html/assets/icons//351/227/252/347/224/265.png +0 -0
  110. package/top-ppt-html/assets/icons//351/227/252/347/224/265.svg +1 -0
  111. package/top-ppt-html/assets/icons//351/243/216/351/231/251.png +0 -0
  112. package/top-ppt-html/assets/icons//351/243/216/351/231/251.svg +1 -0
  113. package/top-ppt-html/assets/pptx-export.js +2 -2
  114. package/top-ppt-html/assets/style-gallery.html +1 -1
  115. package/top-ppt-html/assets/templates/architecture.html +15 -3
  116. package/top-ppt-html/assets/templates/engine.css +12 -0
  117. package/top-ppt-html/assets/templates/presentation.html +15 -3
  118. package/top-ppt-html/assets/templates/research.html +15 -3
  119. package/top-ppt-html/package-lock.json +2 -2
  120. package/top-ppt-html/package.json +2 -2
  121. package/top-ppt-html/references/icons.md +22 -19
  122. package/top-ppt-html/references/layout-variants.md +69 -0
  123. package/top-ppt-html/references/style-pack.md +40 -0
  124. package/top-ppt-html/scripts/build_pptx.js +93 -26
  125. package/top-ppt-html/scripts/check_icons.py +119 -0
  126. package/top-ppt-html/scripts/hydrate_charts.py +60 -5
  127. package/top-ppt-html/scripts/icon_lib.js +66 -37
  128. package/top-ppt-html/scripts/layout-constants.json +91 -4
  129. package/top-ppt-html/scripts/make_icon_pack.py +172 -0
  130. package/top-ppt-html/scripts/model-schema.json +4 -1
  131. package/top-ppt-html/scripts/render_from_model.py +116 -55
  132. package/top-ppt-html/scripts/validate_pptx.py +1 -0
  133. package/top-ppt-html/scripts/validate_report.py +153 -0
  134. package/topmind-cover/README.en.md +4 -4
  135. package/topmind-cover/README.md +4 -4
  136. package/topmind-cover/SKILL.md +36 -18
  137. package/topmind-cover/assets/examples/README.md +13 -7
  138. package/topmind-cover/assets/examples/bg-blur-alt.png +0 -0
  139. package/topmind-cover/assets/examples/bg-blur-wechat.png +0 -0
  140. package/topmind-cover/assets/examples/bg-blur.png +0 -0
  141. package/topmind-cover/assets/examples/overview.png +0 -0
  142. package/topmind-cover/assets/examples/paper-collage-alt.png +0 -0
  143. package/topmind-cover/assets/examples/paper-collage-wechat.png +0 -0
  144. package/topmind-cover/assets/examples/paper-collage.png +0 -0
  145. package/topmind-cover/assets/examples/white-clean-alt-wechat.png +0 -0
  146. package/topmind-cover/assets/examples/white-clean-alt.png +0 -0
  147. package/topmind-cover/assets/examples/white-clean-wechat.png +0 -0
  148. package/topmind-cover/assets/examples/white-clean.png +0 -0
  149. package/topmind-cover/package.json +2 -2
  150. package/topmind-cover/references/cover-prompts.md +436 -0
  151. package/topmind-cover/references/cover-styles.md +149 -14
  152. package/topmind-cover/references/impact-language.md +9 -6
  153. package/topmind-cover/references/ref-white-clean-1.png +0 -0
  154. package/topmind-cover/references/ref-white-clean-2.png +0 -0
  155. package/topmind-wechat-post/README.en.md +1 -1
  156. package/topmind-wechat-post/README.md +1 -1
  157. package/topmind-wechat-post/references/wechat-constraints.md +5 -0
  158. package/topmind-wechat-post/scripts/md2wechat.py +130 -27
  159. package/topmind-wechat-post/scripts/negative_tests.py +74 -0
  160. package/topmind-x-article/README.en.md +25 -5
  161. package/topmind-x-article/README.md +21 -8
  162. package/topmind-x-article/SKILL.md +37 -13
  163. package/topmind-x-article/package.json +1 -1
  164. package/topmind-x-article/references/publish-checklist.md +9 -2
  165. package/topmind-x-article/references/x-html-format.md +73 -0
  166. package/topmind-x-article/scripts/md2x-html.py +394 -0
  167. package/topmind-x-article/scripts/md2x.py +18 -3
  168. package/topmind-x-article/scripts/negative_tests.py +17 -0
@@ -1,4 +1,7 @@
1
- # 封面风格库(8 种)
1
+ # 封面风格库(11 种)
2
+
3
+ > 想自己写提示词直接丢给 AI 生图(不走技能流程)?看 [`cover-prompts.md`](./cover-prompts.md)——
4
+ > 11 风格完整可拷贝提示词 + 2 张参考图复刻学习 + 全平台爆款封面流派调研。
2
5
 
3
6
  > **原创铁律**:本库示例图均为原创,只演示抽象设计原则(标题是视觉重心、信息分层、留白呼吸感、数字与关键词强调),不临摹任何第三方封面;复用时版式与配色不得与第三方封面构成实质相似——只学原则,不学版式。
4
7
 
@@ -21,7 +24,7 @@ prompt 配方为中英双语模板:`{TITLE}` 为标题文字占位符(短标
21
24
  **版式与配色也不得与第三方封面构成实质相似:只学原则,不学版式。**
22
25
  禁止照抄任何第三方封面的文案、形象、版式结构与配色组合——包括但不限于
23
26
  标题文字、数字、品牌词、IP 形象、署名,以及"左文右图""底部标签条""两行撞色标题"
24
- 这类可辨识的构图公式。`assets/examples/` 中的 16 张示例图均为原创设计,
27
+ 这类可辨识的构图公式。`assets/examples/` 中的 26 张风格示例图均为原创设计,
25
28
  其标题/数字/品牌/署名(如"深蓝 OS 2.0""提示词避坑指南""AI绘画挑战营""@阿狐画画")
26
29
  均为虚构演示内容,仅用于演示设计原则。
27
30
  用本库组 prompt 时,标题、形象、版式细节必须自己原创;
@@ -29,7 +32,7 @@ prompt 配方为中英双语模板:`{TITLE}` 为标题文字占位符(短标
29
32
 
30
33
  ---
31
34
 
32
- ## 1. gan-huo · 爆款干货
35
+ ## 9. gan-huo · 爆款干货
33
36
 
34
37
  - **适用场景**:干货清单、评测、盘点、实测筛选类文章;"我替你试完了/筛完了"这类
35
38
  第一人称实测文的默认选择。示例图:`assets/examples/gan-huo.png`(原创:"提示词避坑指南")。
@@ -69,7 +72,7 @@ prompt 配方为中英双语模板:`{TITLE}` 为标题文字占位符(短标
69
72
 
70
73
  ---
71
74
 
72
- ## 2. big-type · 巨字宣言
75
+ ## 5. big-type · 巨字宣言
73
76
 
74
77
  - **适用场景**:观点评论、深度长文、产品/版本发布宣言;"一句话立场"类文章的默认选择。
75
78
  示例图:`assets/examples/big-type.png`(原创:"慢即是快")。
@@ -107,7 +110,7 @@ prompt 配方为中英双语模板:`{TITLE}` 为标题文字占位符(短标
107
110
 
108
111
  ---
109
112
 
110
- ## 3. brand-launch · 品牌发布
113
+ ## 10. brand-launch · 品牌发布
111
114
 
112
115
  - **适用场景**:产品发布、版本更新、官方最佳实践/白皮书;有明确品牌主体的内容首选。
113
116
  示例图:`assets/examples/brand-launch.png`(原创虚构品牌"深蓝 OS 2.0")。
@@ -146,7 +149,7 @@ prompt 配方为中英双语模板:`{TITLE}` 为标题文字占位符(短标
146
149
 
147
150
  ---
148
151
 
149
- ## 4. tutorial-steps · 教程步骤
152
+ ## 6. tutorial-steps · 教程步骤
150
153
 
151
154
  - **适用场景**:教程、上手指南、分步实操、保姆级攻略。
152
155
  示例图:`assets/examples/tutorial-steps.png`(原创:"从想法到产品")。
@@ -184,7 +187,7 @@ prompt 配方为中英双语模板:`{TITLE}` 为标题文字占位符(短标
184
187
 
185
188
  ---
186
189
 
187
- ## 5. ip-fun · IP 趣味
190
+ ## 11. ip-fun · IP 趣味
188
191
 
189
192
  - **适用场景**:实战案例、数据战报、复盘、系列连载(上/下篇)。
190
193
  示例图:`assets/examples/ip-fun.png`(原创:狐狸画家 IP + "AI绘画挑战营")。
@@ -228,7 +231,136 @@ prompt 配方为中英双语模板:`{TITLE}` 为标题文字占位符(短标
228
231
 
229
232
  ---
230
233
 
231
- ## 6. news-flash · 资讯快报
234
+ ## 1. white-clean · 白色清新
235
+
236
+ - **适用场景**:干货清单、实测盘点、效率/副业/职场类选题;"替你筛好了、看完即用"类
237
+ 亲和干货的默认选择。示例图:`assets/examples/white-clean.png`(原创:"一人公司起步指南")。
238
+ 设计语言来源:用户 2026-09-29 提供的两张"白色清新"风格代表图
239
+ (`references/ref-white-clean-1.png`、`ref-white-clean-2.png`);只学抽象设计语言,不抄版式。
240
+ - **设计语言(抽象原则)**:
241
+ - 纯白底 + 大面积留白:干净清新,信息流里"透气"。
242
+ - 标题极大:空间允许时字高冲击画面 1/3;1~2 行横跨顶部,关键词撞色。
243
+ - 关键词装饰每次只用 2~3 种:撞色变色 / 马克笔横条衬底 / 色块衬底。
244
+ - 场景化插图:3D 毛绒 / Q 版人物 + 与主题绑定的工作场景(悬浮卡片、工具、桌面),
245
+ 插图讲"正在用"的故事,不做无意义装饰。
246
+ - 圆角胶囊标签行:浅色胶囊 + 小图标 + 短词,收束卖点。
247
+ - 小装饰点到为止:星星、感叹号、波浪线,至多 2 处。
248
+ - **配色故事**:纯白 `#FFFFFF` 全幅主色(走极端浅明度);标题墨黑 `#1A1A1A` 打底;
249
+ 撞色只给标题关键词(优选组合三选一,见配方);胶囊用撞色对应的浅色系。
250
+ - **标题写法规范**:
251
+ - 短标题 6~10 字,1~2 行,顶部横跨,空间允许时字高冲击 1/3(底线 ≥1/4),
252
+ 如"一人公司起步指南"。
253
+ - 每行至多 1 个撞色关键词。
254
+ - 胶囊标签行 3 个短词,`·` 分隔(如"实测筛选 · 长文精选 · 全流程实操"),
255
+ 字号约为标题的 1/4。
256
+ - **标题文案提炼公式**:人群/场景 + 结果承诺。
257
+ 示例(虚构演示):"打工人副业增收课"。
258
+ - **prompt 配方**:
259
+ ```
260
+ 中文:白色清新风中文封面。字体量级:标题是绝对视觉重心——顶部横跨墨黑色(#1A1A1A)超大粗黑中文标题"{TITLE}"(逐字准确),1~2 行,空间允许时字高冲击画面 1/3(底线≥1/4);中部一条浅色圆角胶囊标签行"{TAGLINE}"(如"实测筛选 · 长文精选 · 全流程实操",必须真实)收束卖点,字号约为标题的 1/4。字体优选组合 {FONT_COMBO} 三选一:A 超粗黑体(力量感,笔画粗、字面满)/ B 圆润黑体(亲和感,笔画圆润、字角圆)/ C 黑体正文 + 英文关键词斜体(国际感)。配色系统:纯白 #FFFFFF 全幅主色(极端浅明度,大面积留白);标题墨黑 #1A1A1A 打底;撞色优选组合 {COLOR_COMBO} 三选一:A 品牌蓝 #2B7FFF + 活力橙红 #FF5A2E / B 电光紫 #7C5CFF + 薄荷青 #00C2A8 / C 墨黑 #1A1A1A + 品牌蓝 #2B7FFF,撞色只给标题关键词(每行至多 1 个撞色词);胶囊用撞色对应的浅色(如 #EAF2FF 系)。构图能量:一条"主题→背书→场景"动线——顶部大标题横跨全宽(钩子与主题合一)→ 中部胶囊标签行(背书)→ 底部场景化插图舞台({SCENE},如毛绒质感 3D 小角色在悬浮卡片与主题工具之间忙碌、带柔和投影,约占画面 35%,必须与主题绑定、讲"正在用"的故事)做记忆点落点;标题与插图上下叠放,禁止左右对半镜像分区。花式优选组合 {FX_COMBO} 每次只用 2~3 种:①关键词变色高亮(撞色,见配色组合);②黄色 #FFD93B 马克笔横条衬底(横条略宽于字、不压笔画);③关键词原位垫实色块(色块高度为字高的 1.2 倍,字色与色块明暗对立,标题总字数不变、严禁复制关键词做独立元素)。方向/透视优选组合 {DIR_COMBO} 三选一:A 标题全水平、胶囊轻微错位叠放;B 撞色关键词整体上扬 ≤8°(字不转、整体转);C 插图轻微俯视透视、标题保持水平。大标题永远水平,绝不透视变形。质感细节:纯白底必须带一层极淡的纸纹 + 插图区一团柔和的浅色光晕,拒绝死白平板底。除标题、胶囊行外无其他文字;所有文字与关键元素在中央垂直 60% 安全区内,横构图 16:9,尺寸 1200×675。
261
+
262
+ EN: Clean-white Chinese cover. Type scale: the title is the absolute visual anchor — an oversized ink-black (#1A1A1A) extra-bold Chinese title "{TITLE}" (exact) spanning the top in 1–2 lines, glyph height pushing toward 1/3 of the frame when space allows (floor 1/4); one light rounded-capsule tag row "{TAGLINE}" (e.g. "实测筛选 · 长文精选 · 全流程实操", must be factual) mid-page cinches the selling points at ~1/4 of the title size. Font combo {FONT_COMBO}, pick one of three: A ultra-bold heiti (powerful, heavy strokes, full letterforms) / B rounded heiti (friendly, soft strokes, rounded corners) / C heiti body with italic English keywords (international feel). Color system: full-bleed pure white #FFFFFF ground (extreme-light value, generous negative space); ink-black #1A1A1A title base; accent combo {COLOR_COMBO}, pick one of three: A brand blue #2B7FFF + vivid orange-red #FF5A2E / B electric purple #7C5CFF + mint teal #00C2A8 / C ink black #1A1A1A + brand blue #2B7FFF — accents touch title keywords only (at most one accented word per line); capsules use the matching light tints (e.g. the #EAF2FF family). Composition energy: one "theme → proof → scene" path — the giant title spans the top (hook and theme in one) → the capsule tag row (proof) → a scenario illustration stage at the bottom ({SCENE}, e.g. a fluffy 3D mascot busy among floating cards and topic tools with soft shadows, ~35% of frame, must tie to the topic and tell a "being used" story) as the memorable landing; title and illustration stack vertically — a mirrored left-right split is forbidden. Flourish combo {FX_COMBO}, use only 2–3 per image: ① keyword recolor highlight (accent color per the palette combo); ② yellow #FFD93B marker highlighter bar behind a keyword (bar slightly wider than the glyphs, never touching strokes); ③ solid color block under a keyword in place (block height 1.2× glyph height, opposing light-dark contrast, total character count unchanged — never duplicate the keyword as a separate element). Direction/perspective combo {DIR_COMBO}, pick one of three: A fully horizontal title with slightly offset-stacked capsules; B the accented keyword tilted upward ≤8° as a whole (glyphs not rotated, the block rotated); C illustration in slight top-down perspective while the title stays horizontal. The main title is always horizontal — never warped in perspective. Texture: the white ground must carry one whisper-faint paper grain plus one soft light-tint halo in the illustration zone — a dead flat white ground is forbidden. No text besides the title and capsule row. All text and key elements within the central vertical 60% safe zone. Landscape 16:9, 1200×675.
263
+ ```
264
+ 占位符:`{TAGLINE}` 胶囊标签行(3 短词,`·` 分隔,≤14 字,必须真实)、
265
+ `{SCENE}` 场景化插图描述(必须与主题绑定:角色 + 场景 + 主题道具,讲"正在用"的故事)、
266
+ `{FONT_COMBO}` 字体三选一(A 超粗黑 / B 圆润黑 / C 黑体+英文斜体)、
267
+ `{COLOR_COMBO}` 撞色三选一(A 蓝+橙红 / B 紫+青 / C 黑+品牌蓝)、
268
+ `{FX_COMBO}` 花式每次 2~3 种(变色 / 马克笔横条 / 色块衬底)、
269
+ `{DIR_COMBO}` 方向三选一(A 全水平 / B 关键词上扬≤8° / C 插图俯视)。
270
+ - **绝不清单**:
271
+ - 绝不深底/灰底:本风格必须是纯白底,底色一深直接变味。
272
+ - 绝不标题字高不足 1/4:空间允许必须冲击 1/3。
273
+ - 绝不左右对半镜像分区:标题与插图必须上下叠放。
274
+ - 绝不每行超 1 个撞色词:撞色一多就"吵"。
275
+ - 绝不一句话超 3 种颜色:标题内只许墨黑 + 撞色组合的两种。
276
+ - 绝不透视变形大标题:大标题永远水平。
277
+ - 绝不色块吞字:色块高度≤1.3 倍字高,明暗对立。
278
+ - 绝不装饰压笔画:横条/圈注不压字。
279
+ - 绝不装饰超量:花式 2~3 种封顶,小装饰(星星/感叹号)至多 2 处。
280
+ - 绝不无意义插图:插图必须与主题绑定、讲"正在用"的故事,纯装饰角色一律不用。
281
+
282
+ ---
283
+
284
+ ## 2. bg-blur · 背景虚化
285
+
286
+ - **适用场景**:生活方式、职场日常、运动健康、城市观察;"氛围感 + 主题"类文章的
287
+ 默认选择。示例图:`assets/examples/bg-blur.png`(原创:"深夜加班自救手册")。
288
+ - **设计语言(抽象原则)**:
289
+ - 虚化摄影背景 + 清晰前景主体:大光圈景深对比本身就是记忆点。
290
+ - 背景走浅色调虚化(明亮、通透),拒绝暗黑压抑。
291
+ - 前景主体锐利清晰,与主题强绑定(人物半身 / 产品特写 / 主题物件三选一)。
292
+ - 大标题压在清晰区:空间允许时字高冲击 1/3,字色与背景明度对立。
293
+ - 光斑/柔光只做氛围,不进文字区。
294
+ - **配色故事**:浅色虚化摄影背景(米白 / 浅灰 / 柔光,极端浅明度);标题深色
295
+ (墨黑 / 深棕);强调色只给一处(关键词或一处光斑色)。
296
+ - **标题写法规范**:
297
+ - 短标题 6~10 字,单行或双行,压在画面清晰区,空间允许时字高冲击 1/3(底线 ≥1/4)。
298
+ - 标题字加浅色光晕衬底或细描边,保证在虚化背景上可读。
299
+ - **标题文案提炼公式**:场景 + 痛点/获得。
300
+ 示例(虚构演示):"通勤包里的效率术"。
301
+ - **prompt 配方**:
302
+ ```
303
+ 中文:背景虚化风中文封面。字体量级:大标题压在清晰区——深色超大粗黑中文标题"{TITLE}"(逐字准确),单行或双行,空间允许时字高冲击画面 1/3(底线≥1/4),是全图唯一的视觉重心;标题字加一层浅色光晕衬底(或 2px 浅色描边,描边宽≤笔画宽 1/5),保证在虚化背景上清晰可读。字体优选组合 {FONT_COMBO} 三选一:A 超粗黑体(醒目)/ B 人文黑体(亲和)/ C 粗黑 + 数字/英文斜体混排。配色系统:浅色调虚化摄影背景 {BG_SCENE}(极端浅明度:明亮、通透,拒绝暗黑);标题深色(墨黑 #1A1A1A / 深棕二选一);强调色优选组合 {COLOR_COMBO} 三选一:A 暖橙 #FF8A3D(配光斑)/ B 品牌蓝 #2B7FFF / C 朱红 #E6392B,强调色只给标题关键词一处。构图能量:一条"氛围→主体→主题"动线——浅色虚化背景(氛围,大光圈虚化 + 柔和光斑,不进文字区)→ 清晰前景主体({SUBJECT},锐利清晰、约占画面 30~40%,必须与主题强绑定)→ 大标题压在主体旁的清晰区(主题);背景与主体明暗/虚实对立,景深对比就是记忆点。花式优选组合 {FX_COMBO} 每次只用 2 种:①关键词变色高亮(强调色);②关键词字号放大到其余字的 1.4 倍(不换行)。方向/透视优选组合 {DIR_COMBO} 三选一:A 标题全水平、主体三分法站位;B 标题沿主体轮廓轻微上扬 ≤8°;C 前景主体轻微仰视透视、标题保持水平。大标题不做透视变形。质感细节:背景虚化必须有真实的光斑层次 + 前景主体边缘锐利,拒绝"全图均匀模糊"的假虚化。除标题外无其他文字;所有文字与关键主体在中央垂直 60% 安全区内,横构图 16:9,尺寸 1200×675。
304
+
305
+ EN: Background-blur Chinese cover. Type scale: the big title presses the sharp zone — an oversized dark extra-bold Chinese title "{TITLE}" (exact), one or two lines, glyph height pushing toward 1/3 of the frame when space allows (floor 1/4), the single visual anchor of the page; the title carries one light halo backing (or a 2px light outline, outline width ≤ 1/5 of stroke width) so it stays legible over the blur. Font combo {FONT_COMBO}, pick one of three: A ultra-bold heiti (punchy) / B humanist heiti (friendly) / C bold heiti mixed with italic numerals/English. Color system: light-toned blurred photographic background {BG_SCENE} (extreme-light value: bright, airy — dark and moody is forbidden); dark title (ink black #1A1A1A / deep brown, pick one); accent combo {COLOR_COMBO}, pick one of three: A warm orange #FF8A3D (pairs with bokeh) / B brand blue #2B7FFF / C vermilion #E6392B — the accent touches exactly one title keyword. Composition energy: one "atmosphere → subject → theme" path — the light blurred background (atmosphere: wide-aperture blur plus soft bokeh, kept out of the text zone) → the sharp foreground subject ({SUBJECT}, tack-sharp, 30–40% of frame, must tie strongly to the topic) → the big title pressed into the clear zone beside the subject (theme); background and subject oppose in light and in sharpness — the depth-of-field contrast IS the memorable element. Flourish combo {FX_COMBO}, use only 2 per image: ① keyword recolor highlight (accent color); ② keyword enlarged to 1.4× the other glyphs (no line break). Direction/perspective combo {DIR_COMBO}, pick one of three: A fully horizontal title with the subject on a rule-of-thirds position; B the title rising gently ≤8° along the subject's contour; C the foreground subject in slight low-angle perspective while the title stays horizontal. The main title is never warped in perspective. Texture: the background blur must show real bokeh layering, and the foreground subject must have crisp edges — uniformly blurred "fake bokeh" is forbidden. No text besides the title. All text and key subjects within the central vertical 60% safe zone. Landscape 16:9, 1200×675.
306
+ ```
307
+ 占位符:`{BG_SCENE}` 背景虚化场景三选一(明亮办公室虚化 / 城市街景光斑虚化 / 自然柔光虚化,
308
+ 必须浅色调)、`{SUBJECT}` 清晰前景主体三选一(人物半身 / 产品特写 / 主题物件,
309
+ 必须与主题强绑定)、`{FONT_COMBO}` 字体三选一、`{COLOR_COMBO}` 强调色三选一
310
+ (橙/蓝/朱红,只给一处)、`{FX_COMBO}` 花式 2 种(变色 + 字号对比)、
311
+ `{DIR_COMBO}` 方向三选一。
312
+ - **绝不清单**:
313
+ - 绝不暗黑虚化背景:本风格背景必须是浅色调,暗底直接变味。
314
+ - 绝不全图均匀模糊:背景虚化必须有光斑层次,前景主体必须锐利。
315
+ - 绝不标题落在虚化重灾区:标题必须压在清晰区,否则可读性全失。
316
+ - 绝不标题字高不足 1/4:空间允许必须冲击 1/3。
317
+ - 绝不一句话超 3 种颜色:深色标题 + 一处强调色。
318
+ - 绝不透视变形大标题。
319
+ - 绝不光斑进文字区:光斑只做背景氛围。
320
+ - 绝不主体与主题无关:前景主体必须与主题强绑定,无意义摆拍一律不用。
321
+ - 绝不装饰超量:变色 + 字号对比 2 种封顶。
322
+
323
+ ---
324
+
325
+ ## 3. paper-collage · 纸感拼贴
326
+
327
+ - **适用场景**:手账、整理术、生活灵感、旧物改造、轻教程;"手作感 / 人味"类选题的
328
+ 默认选择。示例图:`assets/examples/paper-collage.png`(原创:"手账整理术")。
329
+ - **设计语言(抽象原则)**:
330
+ - 浅色底 + 纸片拼贴:撕边 / 圆角 / 便签纸片错位叠放,拼贴本身就是构图。
331
+ - 固定手法三选一:和纸胶带 / 回形针 / 图钉,"贴上去"的真实感。
332
+ - 标题落在最大纸片上(或牛皮纸标签),空间允许时字高冲击 1/3。
333
+ - 小贴纸 / 小标签点缀,元素总数 ≤5。
334
+ - 手工感:撕纸毛边、胶带半透明,拒绝 CG 塑料感。
335
+ - **配色故事**:米白 / 浅灰底(极端浅明度);纸片用马卡龙浅色系优选组合
336
+ (浅蓝 / 浅粉 / 浅黄 / 浅绿三选一);标题深色;一处跳色(朱红 / 赭石)只给最小的标签。
337
+ - **标题写法规范**:
338
+ - 短标题 4~8 字,印在最大纸片中央,空间允许时字高冲击 1/3(底线 ≥1/4),如"手账整理术"。
339
+ - 纸片上不加第二行小字,干净。
340
+ - **标题文案提炼公式**:旧物 / 日常 + 动词改造。
341
+ 示例(虚构演示):"工位改造计划"。
342
+ - **prompt 配方**:
343
+ ```
344
+ 中文:纸感拼贴风中文封面。字体量级:标题是视觉重心——深色超大粗黑中文标题"{TITLE}"(逐字准确),印在最大纸片中央,空间允许时字高冲击画面 1/3(底线≥1/4);纸片上不加第二行小字。字体优选组合 {FONT_COMBO} 三选一:A 超粗黑体(海报感)/ B 手写体(人味,笔画清晰可辨)/ C 黑体 + 英文小字混排。配色系统:米白 / 浅灰底(极端浅明度);纸片马卡龙浅色系优选组合 {COLOR_COMBO} 三选一:A 浅蓝 #D6E9FF + 浅黄 #FFF3C4 / B 浅粉 #FFDCE5 + 浅绿 #D9F2E2 / C 牛皮纸 #E8DCC8 + 纯白 #FFFFFF;标题深色(墨黑 / 深棕二选一);跳色只给最小的标签一处(朱红 #E6392B / 赭石 #B5651D 二选一)。构图能量:一条"底→纸片→标题"动线——浅色底(呼吸)→ 3~5 张纸片 {PAPER_COMBO} 错位叠放拼贴(撕边 / 圆角 / 便签三选一,纸片带撕纸毛边与柔和投影)→ 最大纸片上的大标题(主题);纸片用 {FIX_COMBO} 固定(和纸胶带 / 回形针 / 图钉三选一,半透明/金属质感真实);1~2 张小贴纸或小标签做点缀(元素总数 ≤5)。花式优选组合 {FX_COMBO} 每次只用 2 种:①标题关键词变色(跳色);②小标签上手写感圈注(只圈一处)。方向/透视优选组合 {DIR_COMBO} 三选一:A 纸片全水平、错位叠放;B 最大纸片整体倾斜 ≤8°(字不转、纸转);C 轻微俯视拼贴桌面、标题保持水平。大标题不做透视变形。质感细节:纸片必须有撕纸毛边 + 纸纹 + 柔和投影,胶带半透明,拒绝 CG 塑料感。除标题、小标签短词外无其他文字;所有文字与关键纸片在中央垂直 60% 安全区内,横构图 16:9,尺寸 1200×675。
345
+
346
+ EN: Paper-collage Chinese cover. Type scale: the title is the visual anchor — an oversized dark extra-bold Chinese title "{TITLE}" (exact) printed at the center of the largest paper scrap, glyph height pushing toward 1/3 of the frame when space allows (floor 1/4); no second line of small text on the scrap. Font combo {FONT_COMBO}, pick one of three: A ultra-bold heiti (poster feel) / B handwriting style (human touch, strokes clean and legible) / C heiti mixed with small English. Color system: off-white / light-gray ground (extreme-light value); pastel paper palette combo {COLOR_COMBO}, pick one of three: A light blue #D6E9FF + light yellow #FFF3C4 / B light pink #FFDCE5 + light green #D9F2E2 / C kraft #E8DCC8 + pure white #FFFFFF; dark title (ink black / deep brown, pick one); one pop of color reserved for the smallest tag only (vermilion #E6392B / ochre #B5651D, pick one). Composition energy: one "ground → scraps → title" path — the light ground (breathing room) → 3–5 paper scraps {PAPER_COMBO} in offset collage (torn edge / rounded corner / sticky-note, pick one; scraps carry torn fibrous edges and soft shadows) → the big title on the largest scrap (theme); scraps fastened with {FIX_COMBO} (washi tape / paper clip / push pin, pick one, realistic translucent/metal texture); 1–2 small stickers or tags as garnish (at most 5 elements total). Flourish combo {FX_COMBO}, use only 2 per image: ① title keyword recolor (pop color); ② hand-drawn circle on a small tag (only one circle). Direction/perspective combo {DIR_COMBO}, pick one of three: A all scraps horizontal in offset stack; B the largest scrap tilted ≤8° as a whole (glyphs not rotated, the scrap rotated); C slight top-down view of the collage desk while the title stays horizontal. The main title is never warped in perspective. Texture: scraps must show torn fibrous edges plus paper grain plus soft shadows, tape translucent — plasticky CG rendering is forbidden. No text besides the title and small tag words. All text and key scraps within the central vertical 60% safe zone. Landscape 16:9, 1200×675.
347
+ ```
348
+ 占位符:`{PAPER_COMBO}` 纸片三选一(撕边 / 圆角 / 便签)、`{FIX_COMBO}` 固定手法三选一
349
+ (和纸胶带 / 回形针 / 图钉)、`{FONT_COMBO}` 字体三选一、`{COLOR_COMBO}` 纸片配色三选一、
350
+ `{FX_COMBO}` 花式 2 种(变色 + 圈注)、`{DIR_COMBO}` 方向三选一。
351
+ - **绝不清单**:
352
+ - 绝不深底:本风格必须是浅色底。
353
+ - 绝不纸片超 5 张:元素总数 ≤5,多一张就碎。
354
+ - 绝不标题字高不足 1/4:空间允许必须冲击 1/3。
355
+ - 绝不 CG 塑料感:无毛边无纸纹无投影的纸片一律重画。
356
+ - 绝不透视变形大标题。
357
+ - 绝不一句话超 3 种颜色。
358
+ - 绝不纸片上加第二行小字。
359
+ - 绝不装饰超量:变色 + 圈注 2 种封顶。
360
+
361
+ ---
362
+
363
+ ## 4. news-flash · 资讯快报
232
364
 
233
365
  - **适用场景**:资讯、快讯、热点解读、人物专访预告、"祛魅/揭秘"类选题。
234
366
  示例图:`assets/examples/news-flash.png`(原创:"今日AI速览" + 纸纹底 + 俯视桌面静物)。
@@ -346,15 +478,18 @@ prompt 配方为中英双语模板:`{TITLE}` 为标题文字占位符(短标
346
478
 
347
479
  ---
348
480
 
349
- ## 风格速查
481
+ ## 风格速查(浅色优先:1~8 浅色,9~11 深色/高饱和)
350
482
 
351
483
  | 风格 | 一句话 | 标题字号占比 | 首选题材 |
352
484
  |---|---|---|---|
353
- | gan-huo | 深炭灰底 + 米白 1/3 巨标题 + 朱红印章点睛,一眼即干货 | ~1/3 | 干货清单/评测/盘点 |
485
+ | white-clean | 纯白底 + 冲击 1/3 的撞色巨标题 + 场景化插图 + 胶囊标签,清新透气 | 冲击 1/3 | 干货清单/实测盘点/效率职场 |
486
+ | bg-blur | 浅色虚化摄影背景 + 锐利前景主体,大标题压清晰区 | 冲击 1/3 | 生活方式/职场日常/运动健康 |
487
+ | paper-collage | 马卡龙纸片拼贴 + 和纸胶带/回形针,标题印最大纸片上 | 冲击 1/3 | 手账/整理术/旧物改造 |
488
+ | news-flash | 纸纹米底 + 纯黑大标题 + 朱红爆点词点睛,快讯的干脆 | ~1/3 | 资讯/快讯/热点解读 |
354
489
  | big-type | 标题即画面:1/3 幅墨黑书法烫金,奶油亮底一声断言 | 1/3~2/5 | 观点/深度/发布宣言 |
355
- | brand-launch | 深海军蓝 + 荧光绿唯一强调,品牌大标题压阵 | 1/4~1/3 | 产品发布/版本更新 |
356
490
  | tutorial-steps | 宣纸书法 1/3 镇场 + 底部赭石时间线,三步即上手 | ~1/3 | 教程/上手指南 |
357
- | ip-fun | 暖橙舞台 + 深棕叠放巨标题 + 趣味 IP 记忆点 | 1/4~1/3 | 实战案例/数据战报 |
358
- | news-flash | 纸纹米底 + 纯黑大标题 + 朱红爆点词点睛,快讯的干脆 | ~1/3 | 资讯/快讯/热点解读 |
359
491
  | minimal | 85% 留白 + 一处朱红点睛 + 宽字距深灰标题,张力拉满 | ~1/6(字重补) | 随笔/书评/轻观点 |
360
- | magazine | 暖灰影棚颗粒 + 人像氛围 + 砖红细线,标题压阵 | 1/4~1/3 | 访谈/人物特写/商业分析 |
492
+ | magazine | 暖灰影棚颗粒 + 人像氛围 + 砖红细线,标题压阵 | 1/4~1/3 | 访谈/人物特写/商业分析 |
493
+ | gan-huo | 深炭灰底 + 米白 1/3 巨标题 + 朱红印章点睛,一眼即干货 | ~1/3 | 干货清单/评测/盘点 |
494
+ | brand-launch | 深海军蓝 + 荧光绿唯一强调,品牌大标题压阵 | 1/4~1/3 | 产品发布/版本更新 |
495
+ | ip-fun | 暖橙舞台 + 深棕叠放巨标题 + 趣味 IP 记忆点 | 1/4~1/3 | 实战案例/数据战报 |
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## 一、字体:字是第一眼
8
8
 
9
- 1. **标题字高占画面高度 ≥1/4(上限约 2/5)。**——为什么有效:封面在信息流里先以缩略图出现,字小等于没写标题。
9
+ 1. **标题字高目标冲击 1/3(空间允许时),底线 ≥1/4。**——为什么有效:封面在信息流里先以缩略图出现,字小等于没写标题;1/3 是"一眼即主题"的经验阈值,空间不够时才退到 1/4。
10
10
  2. **全图只给一处强调**(一个关键词或一个数字),用字号/色彩/描边等手法与其它文字拉开断层式差距。——为什么有效:处处强调等于没有强调,单点强调才能形成视觉锚。
11
11
  3. **字色与底色明度差拉到最大**(深底配浅字、浅底配深字)。——为什么有效:对比是可读性的前提,也是缩略图下抓住注意力的最廉价手段。
12
12
  4. **数字优先于文字做视觉钩子。**——为什么有效:数字比文字更快被大脑处理,且自带"具体、可验证"的信任感,3 秒内信息密度最高。
@@ -43,7 +43,7 @@
43
43
 
44
44
  | # | 保守错误 | 纠正方向 |
45
45
  |---|---|---|
46
- | 1 | 标题太小(字高 <1/5 画面) | 先定标题字高 ≥1/4,再摆其他元素;标题是视觉重心,不是配角 |
46
+ | 1 | 标题太小(字高 <1/5 画面) | 先定标题字高目标 1/3(底线 ≥1/4),再摆其他元素;标题是视觉重心,不是配角 |
47
47
  | 2 | 对比太弱(灰底灰字、强调色饱和度不足) | 字色底色明度差拉满;强调色敢用高饱和,但只用一处 |
48
48
  | 3 | 画面太平(元素平均用力、无重心、无动线) | 先定一条主阅读动线和一个最大元素,其他全部让路 |
49
49
  | 4 | 元素太多太碎(>5 个、装饰无节制) | 每加一个元素就问"删掉它会损失什么",答不上来就删 |
@@ -60,11 +60,11 @@
60
60
 
61
61
  | # | 装饰 | 效果 | 风险 | 适用风格 | 提示词写法(具体可执行) |
62
62
  |---|---|---|---|---|---|
63
- | 1 | 关键词变色高亮 | 1~2 个关键词换强调色,成为全图视觉锚点;3 秒内眼睛先被"有色"字抓住 | 一句话超 3 色会吵;低对比配色(浅灰底白字)直接隐身 | gan-huo、news-flash、tutorial-steps、magazine | 把"翻车"两字换成朱红 #E6392B,其余字米白 #FAF6EC;整句只用这两种颜色 |
64
- | 2 | 字号对比 | 关键词放大 1.3~1.6 倍,信息层级瞬间拉开,钩子词拥有最大视觉权重 | 放大超 1.6 倍易挤占构图、导致换行断裂;数字放大优先于文字放大 | big-type、gan-huo、news-flash、magazine | 标题中"暴跌"二字字号放大到其余字的 1.5 倍,其余字保持原字号,不换行 |
65
- | 3 | 文字底部色块/描边 | 色块衬底:关键词下垫一块实色矩形,街头海报感,远距离可读;描边:深底浅字时勾勒字形,字更"跳" | 色块过厚会吞掉字下半部;浅色字+浅色色块对比不足;描边过粗导致笔画粘连 | brand-launch(色块)、big-type(描边)、ip-fun(色块) | "暴跌"两字下方垫一块朱红 #E6392B 实色矩形,矩形高度为字高的 1.2 倍,字为米白压在色块上;描边写法:米白字加 2px 深灰描边,描边宽度不超过笔画宽度的 1/5 |
63
+ | 1 | 关键词变色高亮 | 1~2 个关键词换强调色,成为全图视觉锚点;3 秒内眼睛先被"有色"字抓住 | 一句话超 3 色会吵;低对比配色(浅灰底白字)直接隐身 | gan-huo、news-flash、tutorial-steps、magazine、white-clean、bg-blur、paper-collage | 把"翻车"两字换成朱红 #E6392B,其余字米白 #FAF6EC;整句只用这两种颜色 |
64
+ | 2 | 字号对比 | 关键词放大 1.3~1.6 倍,信息层级瞬间拉开,钩子词拥有最大视觉权重 | 放大超 1.6 倍易挤占构图、导致换行断裂;数字放大优先于文字放大 | big-type、gan-huo、news-flash、magazine、bg-blur | 标题中"暴跌"二字字号放大到其余字的 1.5 倍,其余字保持原字号,不换行 |
65
+ | 3 | 文字底部色块/描边 | 色块衬底:关键词下垫一块实色矩形,街头海报感,远距离可读;描边:深底浅字时勾勒字形,字更"跳" | 色块过厚会吞掉字下半部;浅色字+浅色色块对比不足;描边过粗导致笔画粘连 | brand-launch(色块)、big-type(描边)、ip-fun(色块)、white-clean(色块/马克笔横条) | "暴跌"两字下方垫一块朱红 #E6392B 实色矩形,矩形高度为字高的 1.2 倍,字为米白压在色块上;描边写法:米白字加 2px 深灰描边,描边宽度不超过笔画宽度的 1/5 |
66
66
  | 4 | 轻微阴影/立体 | 字从底色上"浮"起来,增加纵深;轻微立体(1~2 层错位)有质感 | 三重叠加(描边+阴影+立体)必糊;阴影过重显脏;深色底+深色阴影等于没加 | big-type、brand-launch、ip-fun | 标题字加一层向右下 45° 的柔和投影,投影颜色 #000000 不透明度 30%,偏移距离为字高的 1/10;立体写法:字后方加一层同字形、朱红 #E6392B、向右下错位 4px 的色块字,只错位一层 |
67
- | 5 | 手绘下划线/圈注/箭头 | 手绘感=人味(参见第 20 条),划线给关键词"划重点",圈注给数据"画圈强调",箭头给动线"指路" | 线条过粗会压住字;圈注套住整句等于没强调;箭头超过 2 个画面变流程图 | gan-huo(圈注)、news-flash(箭头)、tutorial-steps(下划线/箭头) | 在"翻车"两字下方画一条手绘感波浪下划线,朱红 #E6392B,线宽为笔画宽度的 1/2,略带抖动不压字;圈注写法:用朱红马克笔笔触把"23.2%"圈起来,圈略大于字、不压笔画;箭头写法:从标题指向配图的红色手绘箭头,一条,线条粗细均匀 |
67
+ | 5 | 手绘下划线/圈注/箭头 | 手绘感=人味(参见第 20 条),划线给关键词"划重点",圈注给数据"画圈强调",箭头给动线"指路" | 线条过粗会压住字;圈注套住整句等于没强调;箭头超过 2 个画面变流程图 | gan-huo(圈注)、news-flash(箭头)、tutorial-steps(下划线/箭头)、white-clean(马克笔横条)、paper-collage(圈注) | 在"翻车"两字下方画一条手绘感波浪下划线,朱红 #E6392B,线宽为笔画宽度的 1/2,略带抖动不压字;圈注写法:用朱红马克笔笔触把"23.2%"圈起来,圈略大于字、不压笔画;箭头写法:从标题指向配图的红色手绘箭头,一条,线条粗细均匀 |
68
68
  | 6 | 适度旋转 | 印章/标签/角标类小元素倾斜 ≤8°,打破呆板,制造"贴上去"的真实感 | 大标题旋转必乱码;竖排+旋转组合必翻车;旋转超 8° 显廉价 | 仅用于印章/标签/角标小元素(如"实测""必看"角标),不用于大标题 | 右上角"实测"角标整体顺时针旋转 6°,字不转、整体转;大标题保持水平,一个字都不许倾斜 |
69
69
 
70
70
  ### 7.2 八风格装饰指定(每风格 2~3 种必用)
@@ -79,6 +79,9 @@
79
79
  | news-flash(新闻快讯) | ①关键词变色高亮 ②字号对比 ⑤手绘箭头 | 快讯风=突发感:变色+放大双管齐下让爆点词在信息流里"炸"出来,一条箭头指向配图、制造"正在发生"的现场感 |
80
80
  | minimal(极简) | 只用一点睛色块(③的克制版) | 极简的冲击力来自克制本身:只允许一处色块衬底点睛,多一种装饰就破功;变色、旋转、手绘一律不用 |
81
81
  | magazine(杂志风) | ①关键词变色高亮 ②字号对比 | 杂志封面语言就是"大标题+关键词强调":变色给情绪、字号对比给层级,两种都作用于标题排印本身,不加外部装饰以保编辑感 |
82
+ | white-clean(白色清新) | ①关键词变色高亮 ③色块衬底/马克笔横条 ⑤手绘下划线 | 清新风靠"撞色+横条"制造亲和的干货感:变色定锚点、马克笔横条给"划重点"的人味;每次只用其中 2~3 种,小装饰(星星/感叹号)至多 2 处 |
83
+ | bg-blur(背景虚化) | ①关键词变色高亮 ②字号对比 | 虚化风的冲击力全在"虚实对比"上:标题只用变色+放大两种装饰,背景光斑不抢戏;标题必须压清晰区 |
84
+ | paper-collage(纸感拼贴) | ①关键词变色高亮 ⑤手绘圈注 | 拼贴风要"手作感":变色给标题关键词,圈注只圈最小标签一处;纸片本身已是装饰,标题装饰 2 种封顶 |
82
85
 
83
86
  ### 7.3 装饰禁令清单(Worker B:写入各风格"绝不"清单)
84
87
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  Full lifecycle for WeChat articles: delivery package, review & rewrite, three quality gates, status sync, WeChat inline typography, and publish checklist.
6
6
 
7
- - Version: **v0.1.0** (same tag as `@topmindspace/tms-skills@0.3.9`)
7
+ - Version: **v0.1.0** (same tag as `@topmindspace/tms-skills@0.5.0`)
8
8
 
9
9
  ## Install
10
10
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  公众号文章全生命周期:交付包、审校改写、质量三关、状态同步、微信内联排版与发布清单。
6
6
 
7
- - 版本:**v0.1.0**(与 `@topmindspace/tms-skills@0.3.9` 同 tag)
7
+ - 版本:**v0.1.0**(与 `@topmindspace/tms-skills@0.5.0` 同 tag)
8
8
 
9
9
  ## 安装
10
10
 
@@ -38,6 +38,11 @@
38
38
 
39
39
  - 无代码块语法,**不要用 `<pre>`**:pre 不自动换行,窄屏横向溢出,且会被格式检测标为风险项
40
40
  - 用 `<section style="white-space:pre-wrap;word-break:break-all;">` + 等宽字体 + 深色底模拟
41
+ - **已发布文章里不可能有一键复制按钮**(2026-09-29 核实):公众号正文剥离 JS,
42
+ 第三方工具的"复制代码"按钮只活在它们自己的预览页,进不了正文;编辑器原生代码块
43
+ 也没有读者侧复制入口。``` 围栏渲染为高亮代码区(语言标签 + pre-wrap 自动折行),
44
+ 读者靠长按/全选手动复制。需要分发"复制即用"的提示词时,走评论区置顶、附件、
45
+ 或小程序文档等站外链路,**不要在正文里承诺一键复制**
41
46
  - 不支持 mermaid、LaTeX、SVG 内联(部分 SVG 会被剥离)
42
47
  - `<iframe>`、`<video>` 会被剥离,视频只能用公众号自带的腾讯视频/视频号组件
43
48
  - **结论**:mermaid / 公式必须预渲染成 PNG 再插图
@@ -143,7 +143,7 @@ LANG_RULES = {
143
143
  ],
144
144
  "yaml": [
145
145
  ("comment", r"#[^\n]*"),
146
- ("key", r"(?m)^\s*[\w.\-/]+(?=\s*:)"),
146
+ ("key", r"^\s*[\w.\-/]+(?=\s*:)"),
147
147
  ("string", r'"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\\])*\''),
148
148
  ("keyword", r"\b(?:true|false|null|yes|no|on|off)\b"),
149
149
  ("number", r"\b\d+\.?\d*\b"),
@@ -157,9 +157,9 @@ LANG_RULES = {
157
157
  ("op", r"[=<>!*/+\-]+"),
158
158
  ],
159
159
  "diff": [
160
- ("meta", r"(?m)^@@[^\n]*|^---[^\n]*|^\+\+\+[^\n]*"),
161
- ("add", r"(?m)^\+[^\n]*"),
162
- ("del", r"(?m)^-[^\n]*"),
160
+ ("meta", r"^@@[^\n]*|^---[^\n]*|^\+\+\+[^\n]*"),
161
+ ("add", r"^\+[^\n]*"),
162
+ ("del", r"^-[^\n]*"),
163
163
  ],
164
164
  "html": [
165
165
  ("comment", r"<!--[\s\S]*?-->"),
@@ -219,7 +219,10 @@ def highlight(code, lang, scheme=None):
219
219
  palette = scheme or CTX.get("hl_scheme") or HIGHLIGHT
220
220
  pattern = _HL_PATTERN_CACHE.get(key)
221
221
  if pattern is None:
222
- pattern = re.compile("|".join("(?P<%s>%s)" % (name, pat) for name, pat in rules), re.S)
222
+ # (?m) 不能写进单个分支:拼成 alternation 后它就不在表达式开头了,
223
+ # Python 会报 "global flags not at the start"(历史 crash:```yaml / ```diff
224
+ # 代码块直接 Traceback)。MULTILINE 在编译期统一加,分支里只留 ^。
225
+ pattern = re.compile("|".join("(?P<%s>%s)" % (name, pat) for name, pat in rules), re.S | re.M)
223
226
  _HL_PATTERN_CACHE[key] = pattern
224
227
  out = []
225
228
  pos = 0
@@ -294,8 +297,12 @@ def load_theme(spec):
294
297
  path = resolve_theme(spec)
295
298
  if not path:
296
299
  return base
297
- with open(path, encoding="utf-8") as fh:
298
- data = json.load(fh)
300
+ try:
301
+ with open(path, encoding="utf-8") as fh:
302
+ data = json.load(fh)
303
+ except (OSError, ValueError) as e:
304
+ # ValueError 覆盖 json.JSONDecodeError:坏掉的主题文件给干净报错,不抛 Traceback
305
+ sys.exit("错误:主题文件无法解析 %s(%s)" % (path, e))
299
306
  accent = data.get("accent", base["accent"])
300
307
  # 主色派生字段必须按「本主题」的主色重算,不能继承默认主题的值:
301
308
  # 默认主题的 accent_light / mark_bg 是砖红系,继承过来会让蓝色或灰色主题里
@@ -341,8 +348,67 @@ PANGU_B = re.compile(r"([A-Za-z0-9])([%s])" % HAN)
341
348
  # render_inline() 的行内模式:预编译在模块级,避免每行重复走 re 缓存查找
342
349
  # (666k 行级调用 × 10 个模式时,re.sub 的字符串模式查找是可观开销)。
343
350
  INLINE_CODE_RE = re.compile(r"`([^`]+)`")
344
- INLINE_IMG_RE = re.compile(r"!\[([^\]]*)\]\(([^)\s]+)(?:\s+\"[^\"]*\")?\)")
345
- INLINE_LINK_RE = re.compile(r"\[([^\]]+)\]\(([^)\s]+)\)")
351
+
352
+
353
+ def _parse_paren(s, j):
354
+ """s[j] == '(' 时找与之匹配的 ')'(括号可嵌套:URL 里允许出现平衡括号,如维基链接)。
355
+
356
+ 返回 (括号内文本, 右括号之后的位置);括号不平衡返回 None。
357
+ """
358
+ depth = 0
359
+ k, n = j, len(s)
360
+ while k < n:
361
+ c = s[k]
362
+ if c == "(":
363
+ depth += 1
364
+ elif c == ")":
365
+ depth -= 1
366
+ if depth == 0:
367
+ return s[j + 1:k], k + 1
368
+ k += 1
369
+ return None
370
+
371
+
372
+ # `(url)` / `(url "title")` / `(url 'title')` / `(url (title))` → url(title 丢弃)。
373
+ _URL_TITLE_RE = re.compile(r'^(\S+?)(?:\s+(?:"[^"]*"|\'[^\']*\'|\([^()]*\)))?\s*$')
374
+
375
+
376
+ def _split_url_title(inner):
377
+ """把链接/图片括号内的 `url "title"` 拆出 url(title 丢弃)。
378
+
379
+ 裸 url 不得含空白:含裸空白时返回 ""(调用方保留原文,
380
+ 与旧正则 `[^)\\s]+` 的行为一致,不静默吞掉)。
381
+ """
382
+ m = _URL_TITLE_RE.match(inner.strip())
383
+ return m.group(1) if m else ""
384
+
385
+
386
+ def _scan_md_links(text, img, repl):
387
+ """扫描替换行内图片/链接,url 括号支持嵌套、可带 "title"。
388
+
389
+ img=True 扫 ![alt](src),False 扫 [label](url);repl(文本, url) -> 替换串。
390
+ 括号不平衡、url 为空、url 含裸空白时保留原文(旧正则同样认不出这些写法,
391
+ 保留原文比截断 URL 更安全——历史 bug:`![a](img(1).png)` 被截成 `img(1`,
392
+ 文件明明存在却被记成缺失;`[维基](…/猫_(动物))` 的 URL 被截断、正文多个 `)`)。
393
+ """
394
+ open_tok = "![" if img else "["
395
+ skip = len(open_tok)
396
+ res = []
397
+ i, n = 0, len(text)
398
+ while i < n:
399
+ if text.startswith(open_tok, i):
400
+ k = text.find("]", i + skip)
401
+ if k != -1 and k + 1 < n and text[k + 1] == "(":
402
+ parsed = _parse_paren(text, k + 1)
403
+ if parsed:
404
+ url = _split_url_title(parsed[0])
405
+ if url:
406
+ res.append(repl(text[i + skip:k], url))
407
+ i = parsed[1]
408
+ continue
409
+ res.append(text[i])
410
+ i += 1
411
+ return "".join(res)
346
412
  INLINE_BADGE_RE = re.compile(r"\[!([^\]]+)\]")
347
413
  INLINE_HL_RE = re.compile(r"==([^=]+)==")
348
414
  INLINE_UNDER_RE = re.compile(r"\+\+([^+]+)\+\+")
@@ -390,9 +456,8 @@ def render_inline(raw):
390
456
  strong = 'font-weight:600;color:%s;' % theme["text_strong"]
391
457
  em = 'font-style:normal;color:%s;' % theme["text_muted"]
392
458
 
393
- # images(行内图与独立成行图共用同一正则语义)
394
- def img_repl(m):
395
- alt, src = m.group(1), m.group(2)
459
+ # images(行内图与独立成行图共用同一括号语义)
460
+ def img_repl(alt, src):
396
461
  # 行内图片同样走图片管线:本地文件解析 → 复制到 images/ → 登记清单,
397
462
  # 否则 --embed-images 找不到文件、清单漏项、计数为 0(历史 bug:
398
463
  # 段落里的 ![alt](x.png) 被原样保留相对路径,粘贴到公众号后整图消失)。
@@ -403,11 +468,13 @@ def render_inline(raw):
403
468
  return ('<img src="%s"%s style="max-width:100%%;height:auto;'
404
469
  'border-radius:3px;vertical-align:middle;">') % (src, caption)
405
470
 
406
- text = INLINE_IMG_RE.sub(img_repl, text)
471
+ text = _scan_md_links(text, True, img_repl)
407
472
 
408
473
  # links
409
- def link_repl(m):
410
- label, url = m.group(1), m.group(2)
474
+ def link_repl(label, url):
475
+ # 入口处已 esc():先还原,插入点与脚注登记处再按需转义。
476
+ # 否则脚注列表里 URL 的 & 会被 esc 两次、显示成 &amp;(历史 bug)。
477
+ label, url = html.unescape(label), html.unescape(url)
411
478
  if link_mode == "footnote" and footnotes is not None:
412
479
  # url→序号字典:原写法每次链接都扫全表两次(O(n²)),长文链接多时明显变慢
413
480
  fidx = CTX.get("footnote_idx")
@@ -423,14 +490,14 @@ def render_inline(raw):
423
490
  idx = [f["url"] for f in footnotes].index(url) + 1
424
491
  return ('%s<sup style="font-size:11px;color:%s;'
425
492
  'padding-left:1px;">[%d]</sup>'
426
- % (label, theme["accent"], idx))
493
+ % (esc(label), theme["accent"], idx))
427
494
  if link_mode == "inline":
428
495
  return ('%s<span style="font-size:13px;color:%s;">(%s)</span>'
429
- % (label, theme["text_light"], url))
496
+ % (esc(label), theme["text_light"], esc(url)))
430
497
  return ('<span style="font-size:13px;color:%s;word-break:break-all;">'
431
- '%s(%s)</span>' % (theme["text_light"], label, url))
498
+ '%s(%s)</span>' % (theme["text_light"], esc(label), esc(url)))
432
499
 
433
- text = INLINE_LINK_RE.sub(link_repl, text)
500
+ text = _scan_md_links(text, False, link_repl)
434
501
 
435
502
  # badges: [!文本]
436
503
  # 不用 display:inline-block:公众号对非常规 display 值支持不稳定,
@@ -483,9 +550,33 @@ def render_inline(raw):
483
550
  # ---------------------------------------------------------------- blocks
484
551
 
485
552
  HEADING_RE = re.compile(r"^(#{1,6})\s+(.*)$")
486
- FENCE_RE = re.compile(r"^```(\w*)\s*$")
553
+ # 围栏反引号数 >= 3:```` 开栏只能由 >= 4 反引号闭合(CommonMark),
554
+ # 否则 markdown 示例代码里的内层 ``` 会把外层栏提前"闭合",造成静默错排。
555
+ FENCE_RE = re.compile(r"^(`{3,})(\w*)\s*$")
487
556
  HR_RE = re.compile(r"^(-{3,}|\*{3,}|_{3,})\s*$")
488
- IMG_ONLY_RE = re.compile(r"^!\[([^\]]*)\]\(([^)\s]+)(?:\s+\"[^\"]*\")?\)\s*$")
557
+
558
+
559
+ def match_img_only(line):
560
+ """独立成行图片:![alt](src) 独占一行(src 括号可嵌套、可带 title)。
561
+
562
+ 返回 (alt, src),不是独立成行图片返回 None。
563
+ 与行内图片共用同一括号语义(_parse_paren + _split_url_title)。
564
+ """
565
+ if not line.startswith("!["):
566
+ return None
567
+ k = line.find("]", 2)
568
+ if k == -1:
569
+ return None
570
+ j = k + 1
571
+ if j >= len(line) or line[j] != "(":
572
+ return None
573
+ parsed = _parse_paren(line, j)
574
+ if not parsed:
575
+ return None
576
+ src = _split_url_title(parsed[0])
577
+ if not src or line[parsed[1]:].strip():
578
+ return None
579
+ return line[2:k], src
489
580
  CAPTION_RE = re.compile(r"^\*(.+)\*\s*$")
490
581
  TABLE_SEP_RE = re.compile(r"^\|?[\s:|-]+\|[\s:|-]*$")
491
582
  CONTAINER_RE = re.compile(r"^:::+\s*(\w+)?\s*(.*)$")
@@ -1008,10 +1099,20 @@ def convert_blocks(lines, md_path, out_dir, theme, ctx):
1008
1099
 
1009
1100
  m = FENCE_RE.match(stripped)
1010
1101
  if m:
1011
- lang = m.group(1)
1102
+ open_len = len(m.group(1))
1103
+ lang = m.group(2)
1012
1104
  i += 1
1013
1105
  buf = []
1014
- while i < n and not lines[i].strip().startswith("```"):
1106
+ while i < n:
1107
+ s2 = lines[i].strip()
1108
+ k = 0
1109
+ while k < len(s2) and s2[k] == "`":
1110
+ k += 1
1111
+ # 闭合栏:反引号数 >= 开栏数且后面无其它字符(闭合栏可比开栏长)。
1112
+ # 带信息串的 ```python 不是闭合栏,是栏内代码——旧写法按
1113
+ # startswith("```") 判闭合,会把栏提前关掉。
1114
+ if k >= open_len and not s2[k:].strip():
1115
+ break
1015
1116
  buf.append(lines[i])
1016
1117
  i += 1
1017
1118
  i += 1
@@ -1086,7 +1187,7 @@ def convert_blocks(lines, md_path, out_dir, theme, ctx):
1086
1187
  out.append(block_html)
1087
1188
  continue
1088
1189
 
1089
- m = IMG_ONLY_RE.match(stripped)
1190
+ m = match_img_only(stripped)
1090
1191
  if m:
1091
1192
  caption = None
1092
1193
  if i + 1 < n:
@@ -1094,9 +1195,9 @@ def convert_blocks(lines, md_path, out_dir, theme, ctx):
1094
1195
  if cm:
1095
1196
  caption = cm.group(1)
1096
1197
  i += 1
1097
- src = resolve_image(m.group(2), md_path, out_dir,
1198
+ src = resolve_image(m[1], md_path, out_dir,
1098
1199
  ctx["assets"], ctx["asset_root"])
1099
- out.append(render_figure(src, caption, theme, alt=m.group(1)))
1200
+ out.append(render_figure(src, caption, theme, alt=m[0]))
1100
1201
  i += 1
1101
1202
  continue
1102
1203
 
@@ -1107,7 +1208,7 @@ def convert_blocks(lines, md_path, out_dir, theme, ctx):
1107
1208
  if (not cur or HEADING_RE.match(cur) or HR_RE.match(cur)
1108
1209
  or CONTAINER_RE.match(cur) or cur.startswith(">")
1109
1210
  or cur.startswith("|") or is_list_item(lines[i])
1110
- or IMG_ONLY_RE.match(cur) or FENCE_RE.match(cur)):
1211
+ or match_img_only(cur) or FENCE_RE.match(cur)):
1111
1212
  break
1112
1213
  buf.append(cur)
1113
1214
  i += 1
@@ -1603,6 +1704,8 @@ def main():
1603
1704
  if missing:
1604
1705
  sys.exit("缺少必填参数:%s" % "、".join(missing))
1605
1706
 
1707
+ if os.path.isdir(args.input):
1708
+ sys.exit("错误:输入是目录不是文件 %s" % args.input)
1606
1709
  if not os.path.isfile(args.input):
1607
1710
  sys.exit("错误:找不到输入文件 %s" % args.input)
1608
1711