@taloswork/ose-shared 0.1.2 → 0.1.4

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 (237) hide show
  1. package/package.json +3 -3
  2. package/skills/document/SKILL.md +56 -53
  3. package/skills/document/assets/fonts/Archivo-Regular.woff2 +0 -0
  4. package/skills/document/assets/fonts/Archivo-SemiBold.woff2 +0 -0
  5. package/skills/document/assets/fonts/BigShouldersDisplay-Bold.woff2 +0 -0
  6. package/skills/document/assets/fonts/BodoniModa-SemiBold.woff2 +0 -0
  7. package/skills/document/assets/fonts/ChakraPetch-600.woff2 +0 -0
  8. package/skills/document/assets/fonts/CormorantGaramond-SemiBold.woff2 +0 -0
  9. package/skills/document/assets/fonts/DMSerifDisplay-400.woff2 +0 -0
  10. package/skills/document/assets/fonts/Fraunces-SemiBold.woff2 +0 -0
  11. package/skills/document/assets/fonts/GochiHand-Regular.woff2 +0 -0
  12. package/skills/document/assets/fonts/IBMPlexSans-Regular.woff2 +0 -0
  13. package/skills/document/assets/fonts/IBMPlexSans-SemiBold.woff2 +0 -0
  14. package/skills/document/assets/fonts/Inter-Regular.woff2 +0 -0
  15. package/skills/document/assets/fonts/Jost-Regular.woff2 +0 -0
  16. package/skills/document/assets/fonts/Jost-SemiBold.woff2 +0 -0
  17. package/skills/document/assets/fonts/Karla-Regular.woff2 +0 -0
  18. package/skills/document/assets/fonts/Lexend-500.woff2 +0 -0
  19. package/skills/document/assets/fonts/Lora-Regular.woff2 +0 -0
  20. package/skills/document/assets/fonts/Manrope-Bold.woff2 +0 -0
  21. package/skills/document/assets/fonts/Manrope-Regular.woff2 +0 -0
  22. package/skills/document/assets/fonts/Marcellus-Regular.woff2 +0 -0
  23. package/skills/document/assets/fonts/Nunito-700.woff2 +0 -0
  24. package/skills/document/assets/fonts/PlayfairDisplay-600.woff2 +0 -0
  25. package/skills/document/assets/fonts/PublicSans-Regular.woff2 +0 -0
  26. package/skills/document/assets/fonts/Quicksand-600.woff2 +0 -0
  27. package/skills/document/assets/fonts/Sora-Regular.woff2 +0 -0
  28. package/skills/document/assets/fonts/Sora-SemiBold.woff2 +0 -0
  29. package/skills/document/assets/fonts/SpaceGrotesk-500.woff2 +0 -0
  30. package/skills/document/assets/fonts/Syne-700.woff2 +0 -0
  31. package/skills/document/assets/fonts/ZillaSlab-600.woff2 +0 -0
  32. package/skills/document/assets/fonts/fonts.json +316 -0
  33. package/skills/document/bin/deck-build.cjs +273 -5
  34. package/skills/document/bin/doc-gen.cjs +108 -23
  35. package/skills/document/bin/html2pptx.cjs +284 -51
  36. package/skills/document/catalog.json +43 -0
  37. package/skills/document/deck-design.md +191 -0
  38. package/skills/document/layouts/README.md +33 -0
  39. package/skills/document/layouts/banner-columns.tpl +9 -9
  40. package/skills/document/layouts/bento.tpl +3 -3
  41. package/skills/document/layouts/big-stat.tpl +3 -3
  42. package/skills/document/layouts/blocks-2x2.tpl +12 -12
  43. package/skills/document/layouts/brand-values.tpl +5 -5
  44. package/skills/document/layouts/cards-3.tpl +3 -3
  45. package/skills/document/layouts/cards-grid.tpl +3 -3
  46. package/skills/document/layouts/chart-full.tpl +3 -3
  47. package/skills/document/layouts/chart-kpi.tpl +3 -3
  48. package/skills/document/layouts/color-palette.tpl +5 -5
  49. package/skills/document/layouts/comparison.tpl +3 -3
  50. package/skills/document/layouts/concept-hub.tpl +3 -3
  51. package/skills/document/layouts/cover-centered.tpl +1 -1
  52. package/skills/document/layouts/cover-image.tpl +1 -1
  53. package/skills/document/layouts/cover-minimal.tpl +3 -3
  54. package/skills/document/layouts/cover-statement.tpl +3 -3
  55. package/skills/document/layouts/cover.tpl +1 -1
  56. package/skills/document/layouts/data-table.tpl +3 -3
  57. package/skills/document/layouts/dos-donts.tpl +14 -14
  58. package/skills/document/layouts/editorial-panel.tpl +11 -11
  59. package/skills/document/layouts/ending-contact.tpl +1 -1
  60. package/skills/document/layouts/ending.tpl +1 -1
  61. package/skills/document/layouts/funnel.tpl +3 -3
  62. package/skills/document/layouts/gantt.tpl +3 -3
  63. package/skills/document/layouts/hero.tpl +3 -3
  64. package/skills/document/layouts/icon-row.tpl +3 -3
  65. package/skills/document/layouts/image-full.tpl +5 -5
  66. package/skills/document/layouts/image-grid.tpl +3 -3
  67. package/skills/document/layouts/image-left.tpl +3 -3
  68. package/skills/document/layouts/list.tpl +3 -3
  69. package/skills/document/layouts/logo-guidelines.tpl +8 -8
  70. package/skills/document/layouts/map-distribution.tpl +3 -3
  71. package/skills/document/layouts/map-quad.tpl +6 -6
  72. package/skills/document/layouts/matrix-2x2.tpl +3 -3
  73. package/skills/document/layouts/numbered-brief.tpl +12 -12
  74. package/skills/document/layouts/org-tree.tpl +3 -3
  75. package/skills/document/layouts/problem-solution-banner.tpl +7 -7
  76. package/skills/document/layouts/problem-solution.tpl +3 -3
  77. package/skills/document/layouts/pyramid.tpl +3 -3
  78. package/skills/document/layouts/quote-aside.tpl +11 -0
  79. package/skills/document/layouts/quote.tpl +1 -1
  80. package/skills/document/layouts/radar.tpl +3 -3
  81. package/skills/document/layouts/ring-progress.tpl +3 -3
  82. package/skills/document/layouts/section-fullbleed.tpl +3 -3
  83. package/skills/document/layouts/section-image.tpl +1 -1
  84. package/skills/document/layouts/section-stat.tpl +1 -1
  85. package/skills/document/layouts/section.tpl +1 -1
  86. package/skills/document/layouts/slots.json +1 -1
  87. package/skills/document/layouts/split-two-col.tpl +3 -3
  88. package/skills/document/layouts/stats-chart.tpl +3 -3
  89. package/skills/document/layouts/steps-serpentine.tpl +11 -11
  90. package/skills/document/layouts/steps-vertical.tpl +3 -3
  91. package/skills/document/layouts/steps.tpl +3 -3
  92. package/skills/document/layouts/team-row.tpl +4 -4
  93. package/skills/document/layouts/three-kpi.tpl +3 -3
  94. package/skills/document/layouts/timeline.tpl +3 -3
  95. package/skills/document/layouts/title-meta.tpl +5 -5
  96. package/skills/document/layouts/title.tpl +2 -2
  97. package/skills/document/layouts/toc-agenda.tpl +3 -3
  98. package/skills/document/layouts/toc-editorial.tpl +15 -0
  99. package/skills/document/layouts/toc-panel.tpl +4 -4
  100. package/skills/document/layouts/toc.tpl +3 -3
  101. package/skills/document/layouts/transition.tpl +1 -1
  102. package/skills/document/layouts/two-kpi.tpl +3 -3
  103. package/skills/document/layouts/type-specimen.tpl +10 -10
  104. package/skills/document/layouts/versus.tpl +3 -3
  105. package/skills/document/motion/README.md +29 -0
  106. package/skills/document/motion/anthropic.json +29 -0
  107. package/skills/document/motion/apple.json +41 -0
  108. package/skills/document/motion/bistro-warm.json +16 -0
  109. package/skills/document/motion/black-gold.json +29 -0
  110. package/skills/document/motion/board-brief.json +14 -0
  111. package/skills/document/motion/bold-clash.json +16 -0
  112. package/skills/document/motion/branding.json +22 -0
  113. package/skills/document/motion/campus-teal.json +22 -0
  114. package/skills/document/motion/cinereel.json +23 -0
  115. package/skills/document/motion/clinic-care.json +22 -0
  116. package/skills/document/motion/cool.json +41 -0
  117. package/skills/document/motion/dark-glass.json +22 -0
  118. package/skills/document/motion/gov-brief.json +14 -0
  119. package/skills/document/motion/grid-tech.json +16 -0
  120. package/skills/document/motion/hand-drawn.json +23 -0
  121. package/skills/document/motion/ivory-gold.json +22 -0
  122. package/skills/document/motion/legal-slate.json +15 -0
  123. package/skills/document/motion/magazine-ink.json +29 -0
  124. package/skills/document/motion/mckinsey.json +28 -0
  125. package/skills/document/motion/memphis.json +16 -0
  126. package/skills/document/motion/mono.json +21 -0
  127. package/skills/document/motion/neon-cyber.json +42 -0
  128. package/skills/document/motion/olive-gold.json +22 -0
  129. package/skills/document/motion/organic-earth.json +15 -0
  130. package/skills/document/motion/pastel-saas.json +15 -0
  131. package/skills/document/motion/portfolio-noir.json +21 -0
  132. package/skills/document/motion/press-room.json +14 -0
  133. package/skills/document/motion/retro-press.json +15 -0
  134. package/skills/document/motion/sport-arena.json +16 -0
  135. package/skills/document/motion/swiss-grid.json +34 -0
  136. package/skills/document/motion/wedding-blush.json +15 -0
  137. package/skills/document/packs/README.md +28 -0
  138. package/skills/document/packs/board-brief/backdrop.html +4 -0
  139. package/skills/document/packs/board-brief/layouts/cover.tpl +12 -0
  140. package/skills/document/packs/board-brief/layouts/toc-agenda.tpl +20 -0
  141. package/skills/document/packs/board-brief/pack.css +27 -0
  142. package/skills/document/packs/press-room/backdrop.html +4 -0
  143. package/skills/document/packs/press-room/layouts/cover.tpl +12 -0
  144. package/skills/document/packs/press-room/layouts/section.tpl +13 -0
  145. package/skills/document/packs/press-room/pack.css +27 -0
  146. package/skills/document/styles/README.md +65 -16
  147. package/skills/document/styles/_contract-defaults.css +55 -0
  148. package/skills/document/styles/_samples/_groups/biz-premium.webp +0 -0
  149. package/skills/document/styles/_samples/_groups/creative.webp +0 -0
  150. package/skills/document/styles/_samples/_groups/editorial.webp +0 -0
  151. package/skills/document/styles/_samples/_groups/minimal.webp +0 -0
  152. package/skills/document/styles/_samples/_groups/natural.webp +0 -0
  153. package/skills/document/styles/_samples/_groups/tech-future.webp +0 -0
  154. package/skills/document/styles/_samples/anthropic.webp +0 -0
  155. package/skills/document/styles/_samples/apple.webp +0 -0
  156. package/skills/document/styles/_samples/bistro-warm.webp +0 -0
  157. package/skills/document/styles/_samples/black-gold.webp +0 -0
  158. package/skills/document/styles/_samples/board-brief.webp +0 -0
  159. package/skills/document/styles/_samples/bold-clash.webp +0 -0
  160. package/skills/document/styles/_samples/branding.webp +0 -0
  161. package/skills/document/styles/_samples/campus-teal.webp +0 -0
  162. package/skills/document/styles/_samples/cinereel.webp +0 -0
  163. package/skills/document/styles/_samples/clinic-care.webp +0 -0
  164. package/skills/document/styles/_samples/cool.webp +0 -0
  165. package/skills/document/styles/_samples/dark-glass.webp +0 -0
  166. package/skills/document/styles/_samples/gov-brief.webp +0 -0
  167. package/skills/document/styles/_samples/grid-tech.webp +0 -0
  168. package/skills/document/styles/_samples/hand-drawn.webp +0 -0
  169. package/skills/document/styles/_samples/ivory-gold.webp +0 -0
  170. package/skills/document/styles/_samples/legal-slate.webp +0 -0
  171. package/skills/document/styles/_samples/magazine-ink.webp +0 -0
  172. package/skills/document/styles/_samples/mckinsey.webp +0 -0
  173. package/skills/document/styles/_samples/memphis.webp +0 -0
  174. package/skills/document/styles/_samples/mono.webp +0 -0
  175. package/skills/document/styles/_samples/neon-cyber.webp +0 -0
  176. package/skills/document/styles/_samples/olive-gold.webp +0 -0
  177. package/skills/document/styles/_samples/organic-earth.webp +0 -0
  178. package/skills/document/styles/_samples/pastel-saas.webp +0 -0
  179. package/skills/document/styles/_samples/portfolio-noir.webp +0 -0
  180. package/skills/document/styles/_samples/press-room.webp +0 -0
  181. package/skills/document/styles/_samples/retro-press.webp +0 -0
  182. package/skills/document/styles/_samples/sport-arena.webp +0 -0
  183. package/skills/document/styles/_samples/swiss-grid.webp +0 -0
  184. package/skills/document/styles/_samples/wedding-blush.webp +0 -0
  185. package/skills/document/styles/anthropic/backdrop.html +4 -0
  186. package/skills/document/styles/anthropic/skin.css +15 -8
  187. package/skills/document/styles/apple/backdrop.html +4 -1
  188. package/skills/document/styles/apple/skin.css +5 -2
  189. package/skills/document/styles/bistro-warm/backdrop.html +4 -0
  190. package/skills/document/styles/bistro-warm/skin.css +27 -0
  191. package/skills/document/styles/black-gold/backdrop.html +3 -0
  192. package/skills/document/styles/black-gold/skin.css +15 -8
  193. package/skills/document/styles/bold-clash/backdrop.html +4 -0
  194. package/skills/document/styles/bold-clash/skin.css +27 -0
  195. package/skills/document/styles/branding/backdrop.html +4 -0
  196. package/skills/document/styles/branding/skin.css +14 -7
  197. package/skills/document/styles/campus-teal/backdrop.html +3 -0
  198. package/skills/document/styles/campus-teal/skin.css +27 -0
  199. package/skills/document/styles/cinereel/skin.css +28 -10
  200. package/skills/document/styles/clinic-care/backdrop.html +4 -0
  201. package/skills/document/styles/clinic-care/skin.css +27 -0
  202. package/skills/document/styles/cool/backdrop.html +3 -0
  203. package/skills/document/styles/cool/skin.css +5 -2
  204. package/skills/document/styles/dark-glass/backdrop.html +4 -0
  205. package/skills/document/styles/dark-glass/skin.css +27 -0
  206. package/skills/document/styles/gov-brief/backdrop.html +4 -0
  207. package/skills/document/styles/gov-brief/skin.css +27 -0
  208. package/skills/document/styles/grid-tech/backdrop.html +37 -0
  209. package/skills/document/styles/grid-tech/skin.css +27 -0
  210. package/skills/document/styles/hand-drawn/skin.css +16 -8
  211. package/skills/document/styles/ivory-gold/skin.css +21 -8
  212. package/skills/document/styles/legal-slate/backdrop.html +6 -0
  213. package/skills/document/styles/legal-slate/skin.css +27 -0
  214. package/skills/document/styles/magazine-ink/skin.css +7 -2
  215. package/skills/document/styles/mckinsey/backdrop.html +5 -0
  216. package/skills/document/styles/mckinsey/skin.css +5 -2
  217. package/skills/document/styles/memphis/backdrop.html +5 -0
  218. package/skills/document/styles/memphis/skin.css +27 -0
  219. package/skills/document/styles/mono/backdrop.html +6 -0
  220. package/skills/document/styles/mono/skin.css +6 -3
  221. package/skills/document/styles/neon-cyber/backdrop.html +4 -0
  222. package/skills/document/styles/neon-cyber/skin.css +27 -0
  223. package/skills/document/styles/olive-gold/backdrop.html +5 -0
  224. package/skills/document/styles/olive-gold/skin.css +15 -8
  225. package/skills/document/styles/organic-earth/backdrop.html +4 -0
  226. package/skills/document/styles/organic-earth/skin.css +27 -0
  227. package/skills/document/styles/pastel-saas/backdrop.html +4 -0
  228. package/skills/document/styles/pastel-saas/skin.css +27 -0
  229. package/skills/document/styles/portfolio-noir/backdrop.html +4 -0
  230. package/skills/document/styles/portfolio-noir/skin.css +27 -0
  231. package/skills/document/styles/retro-press/backdrop.html +6 -0
  232. package/skills/document/styles/retro-press/skin.css +27 -0
  233. package/skills/document/styles/sport-arena/backdrop.html +4 -0
  234. package/skills/document/styles/sport-arena/skin.css +27 -0
  235. package/skills/document/styles/swiss-grid/skin.css +6 -1
  236. package/skills/document/styles/wedding-blush/backdrop.html +6 -0
  237. package/skills/document/styles/wedding-blush/skin.css +27 -0
@@ -0,0 +1,14 @@
1
+ {
2
+ "transition": {
3
+ "effect": "cut"
4
+ },
5
+ "entrance": {
6
+ "cards": [
7
+ {
8
+ "sel": ".card",
9
+ "anim": "fade",
10
+ "stagger": 100
11
+ }
12
+ ]
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "transition": {
3
+ "effect": "dissolve",
4
+ "durMs": 420
5
+ },
6
+ "entrance": {
7
+ "cover": [
8
+ {
9
+ "sel": ".cover-sub",
10
+ "anim": "fade",
11
+ "delay": 200
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "transition": {
3
+ "effect": "push",
4
+ "dir": "l",
5
+ "durMs": 280
6
+ },
7
+ "entrance": {
8
+ "cards": [
9
+ {
10
+ "sel": ".card",
11
+ "anim": "fly-left",
12
+ "stagger": 90
13
+ }
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "transition": {
3
+ "effect": "wipe",
4
+ "dir": "l",
5
+ "durMs": 260
6
+ },
7
+ "entrance": {
8
+ "cover": [
9
+ {
10
+ "sel": ".cover-title",
11
+ "anim": "appear"
12
+ },
13
+ {
14
+ "sel": ".cover-sub",
15
+ "anim": "fade",
16
+ "delay": 120
17
+ }
18
+ ],
19
+ "cards": [
20
+ {
21
+ "sel": ".card",
22
+ "anim": "appear",
23
+ "stagger": 70
24
+ }
25
+ ],
26
+ "stat": [
27
+ {
28
+ "sel": ".stat-num",
29
+ "anim": "appear",
30
+ "delay": 140
31
+ }
32
+ ]
33
+ }
34
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "transition": {
3
+ "effect": "dissolve",
4
+ "durMs": 520
5
+ },
6
+ "entrance": {
7
+ "cover": [
8
+ {
9
+ "sel": ".cover-sub",
10
+ "anim": "fade",
11
+ "delay": 280
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,28 @@
1
+ # packs —— 模板包(pack)
2
+
3
+ pack = 实现完整 class 契约的 `pack.css` **加上**一组包专属签名版式。
4
+
5
+ 因为 `pack.css` 实现了契约,共享 `layouts/` 的全部结构版式在包内天然可用;
6
+ 包自带的 `layouts/<id>.tpl` 与共享同名时**包内优先**(同名遮蔽)。
7
+
8
+ 目录结构见 `docs/superpowers/specs/2026-09-01-ppt-tpl-prod-design.md` §5.3。
9
+
10
+ ## 两条硬约束(都有闸门)
11
+
12
+ 1. **遮蔽版式不得引入新槽位**。`deck-build` 用共享 `layouts/slots.json` 校验 spec,
13
+ 包内版式并不单独登记:自己发明一个槽位,模型读不到、用户填了还会被整份拒绝。
14
+ 更根本的是可移植性——同一份 spec 换个 `--style` 就该照样出得来。
15
+ 2. **包内版式可以带颜色,但只能引用 `pack.css` 声明的变量**,禁止裸十六进制。
16
+
17
+ ## 现有的包
18
+
19
+ | pack | 大类 | 遮蔽的版式 | 签名 |
20
+ |---|---|---|---|
21
+ | **board-brief** 董事会简报 | biz-premium | `cover`(顶部密级条 + 标题压到中轴以下,共享版靠留白撑气势)· `toc-agenda`(编号/议题/时长的表格式议程,共享版是卡片列表) | 四角角标 |
22
+ | **press-room** 报刊头版 | editorial | `cover`(报头通栏 + 三分之二版大标题)· `section`(左栏轴 + 并列刊号,共享版是幽灵数字压在标题后)· `quote`(左侧巨型引号 + 右侧不对称引文,共享版是居中) | 顶部报头条 |
23
+
24
+ ## 新增一个包
25
+
26
+ 见 `.claude/skills/ppt-tpl-prod/SKILL.md` 的"新增一个 pack"。`pack.css` 由
27
+ `gen-skin.mjs <id> --pack` 从 `ppt-tpl/families/<id>/family.json` 生成,与 skin
28
+ 的 CSS 完全同构;专属版式是手写的结构创新,不由生成器产。
@@ -0,0 +1,4 @@
1
+ <!-- generated by scripts/ppt-tpl/gen-skin.mjs — signature: corner-marks -->
2
+ <div style="position:absolute;inset:0;background:#F4FAFF"></div>
3
+ <div style="position:absolute;left:56px;top:56px;border-left:2px solid var(--accent);border-top:2px solid var(--accent);width:34px;height:34px;pointer-events:none"></div>
4
+ <div style="position:absolute;right:56px;bottom:56px;border-right:2px solid var(--accent);border-bottom:2px solid var(--accent);width:34px;height:34px;pointer-events:none"></div>
@@ -0,0 +1,12 @@
1
+ <!-- packs/board-brief/layouts/cover — 包内签名版式,遮蔽共享 cover。
2
+ 治理文件封面:顶部密级/文件条(实心块 + 通栏细线),标题左对齐但压低到版面中轴
3
+ 以下,底部两栏署名。共享 cover 把标题放在 332px 并靠留白撑气势,这里相反:
4
+ 气势让位于"这是一份可归档的文件"。槽位与共享 cover 完全一致。 -->
5
+ <section class="slide" data-layout="cover" style="position:relative;width:1280px;height:720px;overflow:hidden"><div class="slide-backdrop"></div>
6
+ <div class="accent-bar" style="position:absolute;left:0;top:0;width:296px;height:34px"></div>
7
+ <div class="eyebrow" style="position:absolute;left:calc(96px * var(--space-scale,1));top:9px;font-size:calc(12px * var(--type-scale,1));letter-spacing:.4em;color:var(--slide-bg)">{{eyebrow|内部资料 · 请勿外传}}</div>
8
+ <div class="rule" style="position:absolute;left:0;right:0;top:34px;height:1px"></div>
9
+ <h1 class="cover-title" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(200px * var(--space-scale,1));top:404px;font-size:calc(62px * var(--type-scale,1));line-height:1.16;letter-spacing:-.5px">{{title|2026 年第三季度<br>经营情况汇报}}</h1>
10
+ <div class="rule" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:556px;height:1px"></div>
11
+ <p class="cover-sub" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:576px;font-size:calc(17px * var(--type-scale,1));line-height:1.6">{{subtitle|提交董事会审议}}</p>
12
+ <div class="deck-footer" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));bottom:38px;display:flex;justify-content:space-between;font-size:calc(12px * var(--type-scale,1));letter-spacing:.08em"><span>{{presenter|汇报人 · 部门}}</span><span>{{date|2026-09}}</span></div></section>
@@ -0,0 +1,20 @@
1
+ <!-- packs/board-brief/layouts/toc-agenda — 包内签名版式,遮蔽共享 toc-agenda。
2
+ 议程表:每一项是一整行(编号 / 议题 / 时长),行间用细线分隔,像会议纪要的表格,
3
+ 而不是共享版的卡片列表。槽位与共享 toc-agenda 一致。 -->
4
+ <section class="slide" data-layout="toc-agenda" style="position:relative;width:1280px;height:720px;overflow:hidden"><div class="slide-backdrop"></div>
5
+ <div class="eyebrow-row" style="position:absolute;left:calc(96px * var(--space-scale,1));top:96px;display:flex;align-items:center;gap:14px"><span class="accent-bar" style="width:24px;height:2px;display:inline-block"></span><span class="eyebrow" style="font-size:calc(12px * var(--type-scale,1));letter-spacing:.34em">{{eyebrow|AGENDA}}</span></div>
6
+ <h2 class="deck-title" style="position:absolute;left:calc(96px * var(--space-scale,1));top:124px;font-size:calc(42px * var(--type-scale,1));letter-spacing:-.3px">{{title|会议议程}}</h2>
7
+ <div class="rule" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:206px;height:1px"></div>
8
+ <div style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:222px;display:flex;justify-content:space-between;align-items:baseline"><span class="toc-num" style="font-size:calc(15px * var(--type-scale,1));width:56px;display:inline-block">01</span><span class="toc-title" style="flex:1;font-size:calc(21px * var(--type-scale,1))">{{item1_title|上季度经营回顾}}</span><span class="toc-desc" style="font-size:calc(14px * var(--type-scale,1))">{{item1_dur|15 分钟}}</span></div>
9
+ <div class="rule" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:274px;height:1px"></div>
10
+ <div style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:290px;display:flex;justify-content:space-between;align-items:baseline"><span class="toc-num" style="font-size:calc(15px * var(--type-scale,1));width:56px;display:inline-block">02</span><span class="toc-title" style="flex:1;font-size:calc(21px * var(--type-scale,1))">{{item2_title|核心指标与偏差分析}}</span><span class="toc-desc" style="font-size:calc(14px * var(--type-scale,1))">{{item2_dur|20 分钟}}</span></div>
11
+ <div class="rule" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:342px;height:1px"></div>
12
+ <div style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:358px;display:flex;justify-content:space-between;align-items:baseline"><span class="toc-num" style="font-size:calc(15px * var(--type-scale,1));width:56px;display:inline-block">03</span><span class="toc-title" style="flex:1;font-size:calc(21px * var(--type-scale,1))">{{item3_title|下一阶段计划}}</span><span class="toc-desc" style="font-size:calc(14px * var(--type-scale,1))">{{item3_dur|15 分钟}}</span></div>
13
+ <div class="rule" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:410px;height:1px"></div>
14
+ <div style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:426px;display:flex;justify-content:space-between;align-items:baseline"><span class="toc-num" style="font-size:calc(15px * var(--type-scale,1));width:56px;display:inline-block">04</span><span class="toc-title" style="flex:1;font-size:calc(21px * var(--type-scale,1))">{{item4_title|资源与预算申请}}</span><span class="toc-desc" style="font-size:calc(14px * var(--type-scale,1))">{{item4_dur|10 分钟}}</span></div>
15
+ <div class="rule" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:478px;height:1px"></div>
16
+ <div style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:494px;display:flex;justify-content:space-between;align-items:baseline"><span class="toc-num" style="font-size:calc(15px * var(--type-scale,1));width:56px;display:inline-block">05</span><span class="toc-title" style="flex:1;font-size:calc(21px * var(--type-scale,1))">{{item5_title|议案表决}}</span><span class="toc-desc" style="font-size:calc(14px * var(--type-scale,1))">{{item5_dur|10 分钟}}</span></div>
17
+ <div class="rule" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));top:546px;height:1px"></div>
18
+ <div class="rule rule-foot" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));bottom:40px;height:1px"></div>
19
+ <div class="deck-footer" style="position:absolute;left:calc(96px * var(--space-scale,1));bottom:17px;font-size:calc(12px * var(--type-scale,1));letter-spacing:.1em">{{footer|季度经营汇报 / 议程}}</div>
20
+ <div class="deck-pageno" style="position:absolute;right:calc(96px * var(--space-scale,1));bottom:17px;font-size:calc(12px * var(--type-scale,1))">{{pageno|02}}</div></section>
@@ -0,0 +1,27 @@
1
+ /* packs/board-brief — generated by scripts/ppt-tpl/gen-skin.mjs from ppt-tpl/families/board-brief/family.json.
2
+ 手改会在下次生成时丢失:要改就改 family.json。 */
3
+ :root{
4
+ --space-scale:0.96; --type-scale:0.94;
5
+ --accent:#075F8B; --c1:#075F8B; --c2:#634E8E; --c3:#913C61; --c4:#8E4430; --chart-1:#075F8B;
6
+ --title:#202930; --body:#4B5156; --muted:#767D82; --foot:#767D82;
7
+ --hair:#C8D3DC; --card-radius:4px;
8
+ --font-head:'Archivo','Noto Sans SC',sans-serif;
9
+ --font-body:'IBM Plex Sans','Noto Sans SC',sans-serif;
10
+ --title-color:#202930; --body-color:#4B5156; --slide-bg:#F4FAFF; --font-heading:var(--font-head);
11
+ }
12
+ .slide{background:#F4FAFF;color:var(--body);font-family:var(--font-body)}
13
+ .slide-backdrop{position:absolute;inset:0;background:#F4FAFF}
14
+ .deck-header,.deck-footer,.deck-pageno{color:var(--muted)}
15
+ .rule,.rule-foot{background:var(--hair)}
16
+ .eyebrow{color:var(--accent);letter-spacing:.22em;font-weight:700}
17
+ .accent-bar{background:var(--accent)}
18
+ .deck-title,.cover-title,.section-title,.ending-title{color:var(--title);font-family:var(--font-head);font-weight:700}
19
+ .cover-sub,.ending-sub,.section-desc{color:var(--muted)}
20
+ .card{border-radius:var(--card-radius);background:transparent;border:1px solid var(--hair)}
21
+ .card-idx{color:var(--muted)} .card-body{color:var(--body)} .card-title{color:var(--title)}
22
+ .card-grid .card:nth-child(4n+1) .card-rail,.card-grid .card:nth-child(4n+1) .card-dot{background:var(--c1)}
23
+ .card-grid .card:nth-child(4n+2) .card-rail,.card-grid .card:nth-child(4n+2) .card-dot{background:var(--c2)}
24
+ .card-grid .card:nth-child(4n+3) .card-rail,.card-grid .card:nth-child(4n+3) .card-dot{background:var(--c3)}
25
+ .card-grid .card:nth-child(4n+4) .card-rail,.card-grid .card:nth-child(4n+4) .card-dot{background:var(--c4)}
26
+ .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head)}
27
+ .kpi-label,.stat-unit{color:var(--muted)} .stat-lead{color:var(--title)} .stat-note{color:var(--body)}
@@ -0,0 +1,4 @@
1
+ <!-- generated by scripts/ppt-tpl/gen-skin.mjs — signature: header-band -->
2
+ <div style="position:absolute;inset:0;background:#FDF5F0"></div>
3
+ <div style="position:absolute;left:0;right:0;top:0;height:5px;background:var(--accent);opacity:.92;pointer-events:none"></div>
4
+ <div style="position:absolute;left:0;top:0;width:60px;height:16px;background:var(--accent);pointer-events:none"></div>
@@ -0,0 +1,12 @@
1
+ <!-- packs/press-room/layouts/cover — 包内签名版式,遮蔽共享 cover。
2
+ 报纸头版:顶部通栏报头(双细线夹住的刊名条)+ 中部占三分之二版面的通栏大标题 +
3
+ 底部三栏 meta。与共享 cover 的"左对齐区块"是两种结构,不是同一版式换色。 -->
4
+ <section class="slide" data-layout="cover" style="position:relative;width:1280px;height:720px;overflow:hidden"><div class="slide-backdrop"></div>
5
+ <div class="rule" style="position:absolute;left:72px;right:72px;top:74px;height:2px"></div>
6
+ <div class="eyebrow-row" style="position:absolute;left:72px;right:72px;top:88px;display:flex;justify-content:space-between;align-items:center"><span class="eyebrow" style="font-size:calc(13px * var(--type-scale,1));letter-spacing:.42em">{{eyebrow|THE PRESS ROOM}}</span><span class="eyebrow" style="font-size:calc(13px * var(--type-scale,1));letter-spacing:.42em">{{date|2026 年 9 月}}</span></div>
7
+ <div class="rule" style="position:absolute;left:72px;right:72px;top:118px;height:1px"></div>
8
+ <h1 class="cover-title" style="position:absolute;left:72px;right:72px;top:206px;font-size:calc(104px * var(--type-scale,1));line-height:1.02;letter-spacing:-1.5px">{{title|头版主标题<br>第二行}}</h1>
9
+ <div class="accent-bar" style="position:absolute;left:72px;top:474px;width:180px;height:6px"></div>
10
+ <p class="cover-sub" style="position:absolute;left:72px;right:340px;top:508px;font-size:calc(22px * var(--type-scale,1));line-height:1.5">{{subtitle|一句导语,交代这次要讲的是什么。}}</p>
11
+ <div class="rule rule-foot" style="position:absolute;left:72px;right:72px;bottom:66px;height:1px"></div>
12
+ <div class="deck-footer" style="position:absolute;left:72px;bottom:36px;font-size:calc(13px * var(--type-scale,1));letter-spacing:.06em">{{presenter|署名 · 部门}}</div></section>
@@ -0,0 +1,13 @@
1
+ <!-- packs/press-room/layouts/section — 包内签名版式,遮蔽共享 section。
2
+ 栏目页:左侧一根到底的强调色栏轴 + 竖排刊号,右侧标题与导语。共享 section 是
3
+ "巨型幽灵数字压在标题后面",两者的结构关系相反(这里数字与文字并列不重叠)。 -->
4
+ <section class="slide" data-layout="section" style="position:relative;width:1280px;height:720px;overflow:hidden"><div class="slide-backdrop"></div>
5
+ <div class="accent-bar" style="position:absolute;left:96px;top:132px;bottom:132px;width:6px"></div>
6
+ <div class="section-ghost" style="position:absolute;left:136px;top:150px;font-weight:700;line-height:.9;font-size:calc(148px * var(--type-scale,1));letter-spacing:-4px">{{index|01}}</div>
7
+ <div class="eyebrow" style="position:absolute;left:142px;top:318px;font-size:calc(13px * var(--type-scale,1));letter-spacing:.42em">{{eyebrow|CHAPTER}}</div>
8
+ <h2 class="section-title" style="position:absolute;left:470px;right:96px;top:150px;font-size:calc(72px * var(--type-scale,1));line-height:1.1;letter-spacing:-.5px">{{title|栏目标题}}</h2>
9
+ <div class="rule" style="position:absolute;left:470px;right:96px;top:330px;height:1px"></div>
10
+ <p class="section-desc" style="position:absolute;left:470px;right:96px;top:362px;font-size:calc(19px * var(--type-scale,1));line-height:1.7">{{desc|一句本栏概述,点出这一章要回答的问题。}}</p>
11
+ <div class="rule rule-foot" style="position:absolute;left:96px;right:96px;bottom:40px;height:1px"></div>
12
+ <div class="deck-footer" style="position:absolute;left:96px;bottom:17px;font-size:calc(12px * var(--type-scale,1));letter-spacing:.1em">{{footer|报告标题 / 栏目}}</div>
13
+ <div class="deck-pageno" style="position:absolute;right:96px;bottom:17px;font-size:calc(12px * var(--type-scale,1))">{{pageno|02}}</div></section>
@@ -0,0 +1,27 @@
1
+ /* packs/press-room — generated by scripts/ppt-tpl/gen-skin.mjs from ppt-tpl/families/press-room/family.json.
2
+ 手改会在下次生成时丢失:要改就改 family.json。 */
3
+ :root{
4
+ --space-scale:1; --type-scale:1;
5
+ --accent:#C12E4C; --c1:#C12E4C; --c2:#896103; --c3:#0B7927; --c4:#117379; --chart-1:#C12E4C;
6
+ --title:#26201D; --body:#564F4B; --muted:#827B76; --foot:#827B76;
7
+ --hair:#CBBFB7; --card-radius:4px;
8
+ --font-head:'Bodoni Moda','Songti SC',sans-serif;
9
+ --font-body:'Public Sans','Noto Sans SC',sans-serif;
10
+ --title-color:#26201D; --body-color:#564F4B; --slide-bg:#FDF5F0; --font-heading:var(--font-head);
11
+ }
12
+ .slide{background:#FDF5F0;color:var(--body);font-family:var(--font-body)}
13
+ .slide-backdrop{position:absolute;inset:0;background:#FDF5F0}
14
+ .deck-header,.deck-footer,.deck-pageno{color:var(--muted)}
15
+ .rule,.rule-foot{background:var(--hair)}
16
+ .eyebrow{color:var(--accent);letter-spacing:.22em;font-weight:700}
17
+ .accent-bar{background:var(--accent)}
18
+ .deck-title,.cover-title,.section-title,.ending-title{color:var(--title);font-family:var(--font-head);font-weight:700;--talos-bake:1}
19
+ .cover-sub,.ending-sub,.section-desc{color:var(--muted)}
20
+ .card{border-radius:var(--card-radius);background:transparent;border:1px solid var(--hair)}
21
+ .card-idx{color:var(--muted)} .card-body{color:var(--body)} .card-title{color:var(--title)}
22
+ .card-grid .card:nth-child(4n+1) .card-rail,.card-grid .card:nth-child(4n+1) .card-dot{background:var(--c1)}
23
+ .card-grid .card:nth-child(4n+2) .card-rail,.card-grid .card:nth-child(4n+2) .card-dot{background:var(--c2)}
24
+ .card-grid .card:nth-child(4n+3) .card-rail,.card-grid .card:nth-child(4n+3) .card-dot{background:var(--c3)}
25
+ .card-grid .card:nth-child(4n+4) .card-rail,.card-grid .card:nth-child(4n+4) .card-dot{background:var(--c4)}
26
+ .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head);--talos-bake:1}
27
+ .kpi-label,.stat-unit{color:var(--muted)} .stat-lead{color:var(--title)} .stat-note{color:var(--body)}
@@ -1,9 +1,14 @@
1
1
  # Skin catalog (styles) — pick ONE per deck
2
2
 
3
+ **族名单的真源是 `catalog.json`**(groups + entries),本文件是人读的说明;新增族
4
+ 两边都要更新。`verify-catalog.mjs` **不读本文件** —— 它比对的是 `catalog.json`
5
+ 与磁盘(样图/CSS/motion 是否存在、`styles/<id>` 目录有没有漏登记、oneliner 有没有
6
+ 超长),所以"目录建了但没登记"抓得住,"登记了但本 README 忘了写"抓不住,只能靠人。
7
+
3
8
  A **skin** = the paint (colors + fonts + design tokens) applied to structure-only
4
9
  `layouts/*.tpl` at render time via `--style <name>`. Pick ONE skin for the whole
5
10
  deck by vibe/scenario; never mix. Each skin fully defines the class contract, so any
6
- of the 54 layouts renders in any skin.
11
+ layout renders in any skin — see `layouts/README.md` for the current count and index.
7
12
 
8
13
  `html2pptx deck.html out.pptx --style <name> [--backdrop <variant>]`
9
14
 
@@ -11,18 +16,34 @@ of the 54 layouts renders in any skin.
11
16
 
12
17
  | skin | light/dark | 适用场景 | signature |
13
18
  |---|---|---|---|
14
- | **cool** ⭐默认 | dark | 科技 · 发布 · pitch · 主题演讲 | 深蓝 + 蓝青辉光 + 玻璃卡 + 4色 ramp |
15
- | **black-gold** | dark | 金融 · 年报 · 路演 · 奢侈品 · 高端商务 | 纯黑 + 金辉光 + 衬线;金曲线仅封面 |
16
- | **apple** | dark | 产品发布 · 主题演讲 · 极简演示 | 纯黑舞台 + 超大留白 + 单色白层级 |
17
- | **olive-gold** | dark | 高端 · 证书 · 招商 · 品牌 | 深橄榄金 + 亮金 + 奶白粗体 |
18
- | **mckinsey** | light | 咨询 · 战略汇报 · 评审 · 董事会 | 白底藏青 + 克制蓝 + **蓝方块序号卡** |
19
- | **anthropic** | light | AI/产品 · 研究分享 · 人文品牌 | 奶油 + 赤陶珊瑚 + Georgia 衬线 |
20
- | **branding** | light | 品牌手册 · 可持续 · 美妆 · 零售 · 极简 | 暖米底 + 鼠尾草/薄荷绿 + 优雅衬线标题 |
21
- | **hand-drawn** | light | 创意 · 头脑风暴 · 教学 · 工作坊 | 纸感 + 马克笔色 + **手绘歪框卡** |
22
- | **mono** | light | 极简 · 高端 · 设计 · 单色报告 | 纯白 + 黑灰明度层级 + 细线 + 大留白 |
23
- | **ivory-gold** | light | 奢华极简 · 品牌手册 · 路演 · 高端零售 | 奶油底 + 青铜金 Anton 粗体大写标题(标题=accent)+ **黑色反色区块**(`.slide-inverse`) |
24
- | **cinereel** | dark | 影视 · 创意作品集 · 音乐/传媒行业 · 幕后花絮 | 黑底/照片底 + 白色 Anton 粗体大写(无色相)+ **常驻胶片取景框**(顶/底黑遮幅条,每页恒定)+ 浅灰面板反色(`.slide-inverse`) |
19
+ | **cool** ⭐默认 | dark | 科技 · 发布 · pitch · 主题演讲 | 深蓝 + 蓝青辉光 + 玻璃卡 + **Sora** 几何无衬线 + **右上仪表刻度尺** |
20
+ | **black-gold** | dark | 金融 · 年报 · 路演 · 奢侈品 · 高端商务 | 纯黑 + 金辉光 + **Bodoni Moda** 高反差 didone + **双线证书内框** |
21
+ | **apple** | dark | 产品发布 · 主题演讲 · 极简演示 | 纯黑舞台 + 最大留白(`--space-scale:1.22`)+ **Manrope** + **底部地平线与反射** |
22
+ | **olive-gold** | dark | 高端 · 证书 · 招商 · 品牌 | 深橄榄金 + 亮金 + **Marcellus** 古典罗马体 + **四角雕版角标** |
23
+ | **mckinsey** | light | 咨询 · 战略汇报 · 评审 · 董事会 | 白底藏青 + **IBM Plex Sans** + 最高信息密度(`--space-scale:0.86`)+ **顶部实心页眉条与档案标签** |
24
+ | **anthropic** | light | AI/产品 · 研究分享 · 人文品牌 | 奶油 + 赤陶珊瑚 + **Fraunces** 有机衬线 + **右侧边注竖线** |
25
+ | **branding** | light | 品牌手册 · 可持续 · 美妆 · 零售 · 极简 | 暖米底 + 鼠尾草绿 + **Cormorant Garamond** + **左侧装订书脊带** |
26
+ | **hand-drawn** | light | 创意 · 头脑风暴 · 教学 · 工作坊 | 纸感 + 马克笔色 + **Gochi Hand** 手写体(已 bake)+ **手绘歪框卡** |
27
+ | **mono** | light | 极简 · 高端 · 设计 · 单色报告 | 纯白 + 黑灰明度层级 + **Archivo** + **印刷裁切框与四角对位十字** |
28
+ | **ivory-gold** | light | 奢华极简 · 品牌手册 · 路演 · 高端零售 | 奶油底 + 青铜金 **Anton** 粗体大写标题(标题=accent)+ **黑色反色区块**(`.slide-inverse`) |
29
+ | **cinereel** | dark | 影视 · 创意作品集 · 音乐/传媒行业 · 幕后花絮 | 黑底/照片底 + 白色超浓缩粗体大写(Big Shoulders Display,无色相)+ 几何无衬线正文(Jost)+ **常驻胶片取景框**(顶/底黑遮幅条,每页恒定)+ 浅灰面板反色(`.slide-inverse`) |
25
30
  | **magazine-ink** | light | 人文分享 · 行业观察 · 商业发布 · 杂志感演讲 | 瓷白底 + 靛蓝 Noto Serif SC 衬线大标题 + 无衬线正文 + 等宽元数据 + 无阴影无卡片盒(纯发丝线分隔)+ 巨幅淡墨水印章节号 |
31
+ | **neon-cyber** | dark | 科技 · 游戏 · Web3 · 夜场发布 | 深紫夜场 + 品红辉光 + **Jost** 几何无衬线 + **等距网格与右上辉光**(生成族,DNA 见 `ppt-tpl/families/neon-cyber/`) |
32
+ | **dark-glass** | dark | 产品评审 · 技术方案 · 路线图 · 内部汇报 | 石墨灰 + 冰蓝 + **Space Grotesk** + **四角角标** + 最松节奏(`--space-scale:1.06`)(生成族) |
33
+ | **grid-tech** | dark | 工程 · 基础设施 · 数据平台 · 技术大会 | 近黑 + 荧光绿 + **Chakra Petch** 方硬科技体 + **底缘刻度尺** + 最紧节奏(0.92)(生成族) |
34
+ | **pastel-saas** | light | SaaS · 产品提案 · 增长复盘 · 客户成功 | 薰衣草白 + 圆角 **Quicksand** + **地平线色场** + 大留白(1.1)(生成族) |
35
+ | **memphis** | light | 创意提案 · 品牌活动 · 校园分享 · 工作坊 | 米白 + 撞色橙 + **Syne** 反常规展示体 + **右缘阶梯色块**(生成族) |
36
+ | **retro-press** | light | 文化 · 书业 · 展览 · 品牌故事 | 旧纸米黄 + 砖红 + **DM Serif Display** + 宋体系 CJK + **四角裁切框**(生成族) |
37
+ | **bold-clash** | light | 发布造势 · 营销 campaign · 潮牌 · 音乐节 | 亮黄底 + 品红/墨黑 + **Anton** + **左缘书脊带** + 最大字号(1.12)(生成族) |
38
+ | **organic-earth** | light | 可持续 · 农业食品 · 户外 · ESG 报告 | 米绿 + 苔绿陶土 + **Fraunces** + 宋体系 CJK + **地平线**(生成族) |
39
+ | **campus-teal** | light | 教学 · 课件 · 培训 · 校园 | 浅青 + **Lexend** 高可读无衬线 + **点阵底纹** + 大留白(1.06)(生成族) |
40
+ | **clinic-care** | light | 医疗 · 健康科普 · 器械 · 公共卫生 | 洁净浅蓝 + 圆角 **Nunito** + **双层版心细框**(生成族) |
41
+ | **wedding-blush** | light | 婚礼 · 请柬 · 纪念册 · 私人典礼 | 胭脂米白 + **Playfair Display** 高反差衬线 + 宋体系 CJK + **升起的弧**(生成族) |
42
+ | **portfolio-noir** | dark | 作品集 · 个人品牌 · 摄影 · 设计评审 | 炭黑 + 铜金 + **Archivo/Space Grotesk** + **底座色带** + 最松节奏(1.12)(生成族) |
43
+ | **bistro-warm** | light | 餐饮 · 门店 · 食品品牌 · 菜单发布 | 奶油 + 辣椒红 + **Zilla Slab** 板衬线 + **斜切带**(生成族) |
44
+ | **gov-brief** | light | 政务 · 公共事务 · 工作汇报 · 会议材料 | 素白 + 藏蓝 + **Public Sans** + **顶部报头条** + 最紧字号(0.96)(生成族) |
45
+ | **sport-arena** | dark | 赛事 · 体育 · 战报 · 俱乐部 | 夜蓝 + 亮橙 + **Big Shoulders Display** 窄体 + **斜切带** + 紧排(0.92)(生成族) |
46
+ | **legal-slate** | light | 法务 · 合规 · 尽调 · 风险评估 | 石板白 + 墨绿 + **Lora** 衬线 + 宋体系 CJK + **四角裁切框**(生成族) |
26
47
  | **swiss-grid** | light | 科技产品 · 数据汇报 · 设计/工程分享 · 年度总结 | 全无衬线 + 克莱因蓝单色高亮 + 极致字号反差(标题细/KPI 粗)+ 零阴影零圆角零渐变 + 点阵网格底纹 |
27
48
 
28
49
  **Default** — when the user didn't specify: `cool` (酷炫深色). For clean/formal/light
@@ -37,7 +58,35 @@ padding of your own:
37
58
  `branding` → **暖米绿意 · 品牌手册** · `hand-drawn` → **纸感手绘 · 创意教学** ·
38
59
  `mono` → **纯白黑灰 · 极简设计** · `ivory-gold` → **奶油青铜 · 奢华极简** ·
39
60
  `cinereel` → **黑白胶片 · 影视创意** · `magazine-ink` → **瓷白靛蓝 · 杂志人文** ·
40
- `swiss-grid` → **克莱因蓝白 · 瑞士国际**
61
+ `swiss-grid` → **克莱因蓝白 · 瑞士国际** · `neon-cyber` → **霓虹品红 · 赛博夜场** ·
62
+ `dark-glass` → **石墨冰蓝 · 产品评审** · `grid-tech` → **近黑荧绿 · 工程评审** ·
63
+ `pastel-saas` → **薰衣草白 · SaaS 提案** · `memphis` → **米白撞色 · 创意提案** ·
64
+ `retro-press` → **旧纸砖红 · 文化叙事** · `bold-clash` → **亮黄墨黑 · 发布造势** ·
65
+ `organic-earth` → **苔绿陶土 · 可持续** · `campus-teal` → **浅青板书 · 教学课件** ·
66
+ `clinic-care` → **洁净浅蓝 · 医疗健康** · `wedding-blush` → **胭脂米白 · 婚礼请柬** ·
67
+ `portfolio-noir` → **炭黑铜金 · 作品集** · `bistro-warm` → **奶油辣椒红 · 餐饮门店** ·
68
+ `gov-brief` → **素白藏蓝 · 政务汇报** · `sport-arena` → **夜场亮橙 · 赛事发布** ·
69
+ `legal-slate` → **石板墨绿 · 法务合规**
70
+
71
+ ## 皮肤靠什么区分(不只是配色)
72
+
73
+ 三条正交的轴。只改配色的皮肤会和别的皮肤长得一样 —— 加皮肤时三条都要想过:
74
+
75
+ 1. **字体** — 每个皮肤的 `--font-head`/`--font-body` 组合都是唯一的,并且 CJK 首选分了
76
+ 宋体系/黑体系(纯拉丁字体对中文 deck 不起作用,只有 CJK 栈能拉开中文观感;楷体系目前
77
+ 没有打包字体,`assets/fonts/` 只有 Noto Sans SC 与 Noto Serif SC 两套 CJK 子集)。
78
+ **字体栈里只允许出现打包字体与通用兜底**(`sans-serif`/`serif`/`cursive`)——写
79
+ `Heiti SC`/`Comic Sans MS`/`Kaiti SC` 这类"某些机器上碰巧有"的名字,渲染结果就取决于
80
+ 跑它的那台机器,像素基线与样图会一起变得不可信。CJK 位置写 `PingFang SC`/`Songti SC`
81
+ 是安全的:它们在 `fonts.json` 里被别名到打包子集。**衬线/展示字体还必须 bake**,否则
82
+ 只在预览里生效、进不了交付的 pptx(见 deck-design.md § Fonts)。
83
+ 2. **结构签名** — `backdrop.html` 里一个有边界的标记:页眉条、裁切框、书脊带、四角角标、
84
+ 刻度尺、地平线。这是 layout 之外唯一能引入**结构**差异的地方,也是同质化最容易发生的
85
+ 环节 —— 弥散的渐变光晕换到别的皮肤上没人看得出,不算签名。
86
+ 3. **排版节奏** — `--space-scale` / `--type-scale`。`layouts/*.tpl` 的字号与页边距都写成
87
+ `calc(N * var(--…-scale,1))`,所以皮肤可以在不碰任何 layout 的前提下定义自己的疏密。
88
+ 当前跨度:`mckinsey` 0.86(董事会材料的信息密度)→ `apple` 1.22(发布会舞台的留白)。
89
+ **改动后必须跑 deck-qa** —— 缩放会重排文字,过大就 off-canvas。
41
90
 
42
91
  ## Backdrop variants
43
92
 
@@ -81,9 +130,9 @@ generations of the same skin don't all look identical. Pass `--backdrop
81
130
 
82
131
  Add a skin = **one `styles/<name>/skin.css`** defining the full class contract
83
132
  (+ optional `backdrop.html`). The `deck-layouts` guard checks every skin paints the
84
- contract. All 54 layouts get the new skin for free. Build a skin from a reference
85
- image: sample its palette → fill the token/class contract (mirror an existing skin
86
- of the same light/dark polarity).
133
+ contract. Every layout in `layouts/README.md` gets the new skin for free. Build a
134
+ skin from a reference image: sample its palette → fill the token/class contract
135
+ (mirror an existing skin of the same light/dark polarity).
87
136
 
88
137
  Chart color: `stats-chart` fills its bars from **`--chart-1`** (substituted into the
89
138
  `__CHART1__` placeholder), NOT the raw `--accent` — accent is tuned as a text/hairline
@@ -0,0 +1,55 @@
1
+ /* styles/_contract-defaults.css — 扩展契约的中性兜底实现。
2
+ 注入顺序:SKELETON_CSS → 本文件 → styles/<id>/skin.css | packs/<id>/pack.css
3
+ 皮肤/包可以覆写其中任意一条;不覆写就拿到这里的中性版本。
4
+ 目的:扩展契约从"改 N 个皮肤"降为"改这一个文件",让 promote-layout 反向通道跑得起来。
5
+ 规则:只能引用已有 token(--accent/--title/--body/--muted/--hair/--c1..--c4/--card-radius),
6
+ 一个裸十六进制都不许有 —— deck-layouts.test.ts 会断言。
7
+
8
+ **加一条声明之前必读(属性粒度,不是选择器粒度)**:
9
+ "所有皮肤都定义了这个选择器,所以兜底是惰性的" —— 这个推理只在选择器粒度成立。
10
+ CSS 是逐**属性**层叠的:皮肤在 `.panel` 上只写了 `background`,兜底里的 `border`
11
+ 照样会落到它头上。而且皮肤常常把颜色写在更具体的作用域里(比如
12
+ `.steps .step:nth-child(n) .step-circle`),那条规则在没有 `.steps` 祖先的版式里
13
+ (icon-row)根本不匹配,兜底的 `color` 就会赢。
14
+ 所以本文件只保留"没有任何现役皮肤会被它改变观感"的属性。逐属性实测(每条声明单独
15
+ 注入,与不注入逐字节比对 PNG)后删掉的四条,括号内是实测受影响的组合数:
16
+ .dt-head 的 font-family(7/13 —— anthropic/black-gold/branding/cinereel/hand-drawn/
17
+ ivory-gold/olive-gold 的 data-table 表头字体会从正文体翻成展示体:cinereel
18
+ Jost→Big Shoulders Display、anthropic 无衬线→Fraunces 衬线、hand-drawn
19
+ Comic Sans→Gochi Hand,肉眼可辨。只有 magazine-ink 自己写了 font-family,
20
+ 其余五个族的正文体与展示体恰好同族才没变);
21
+ .step-circle 的 color(39/78 —— 皮肤只在 `.steps .step:nth-child(n) .step-circle`
22
+ 作用域里定色,icon-row/steps-vertical/versus 没有 .steps 祖先,13 个族全中);
23
+ .panel 的 border(21/26 —— 多数皮肤只写 background/box-shadow);
24
+ 同一条规则里的 border-radius 实测 0/26,但一个既无边框又无底色的盒子谈不上圆角,
25
+ 所以一并去掉,不留没有意义的声明;
26
+ .cmp-col--rec 的 box-shadow(4/39 —— cinereel 与 magazine-ink 没写)。
27
+ 保留下来的 `.cmp-col--rec{border}` 实测 0/39:没写 border 的 swiss-grid 在自己的
28
+ `.cmp-col` 规则里定了边(同特异性、位置在后),仍然赢过兜底。
29
+ 改完必须重跑 `node scripts/deck-fidelity.mjs`(它现在会注入本文件,此前不注入,
30
+ 所以这个文件曾经完全在像素闸门的视野之外),并按
31
+ `.claude/skills/ppt-tpl-prod/SKILL.md`"改 _contract-defaults.css"一节做
32
+ 注入/不注入的对照渲染 —— deck-fidelity 的 32x18 签名对这类细微改动不够敏感。 */
33
+
34
+ /* compare */
35
+ .cmp-col--rec{border:1px solid var(--accent)}
36
+ /* process */
37
+ .step-circle{background:transparent;border:1px solid var(--hair);font-family:var(--font-head)}
38
+ /* toc */
39
+ .toc-num{color:var(--muted);font-family:var(--font-head)}
40
+ /* surfaces */
41
+ .surface{background:transparent;border:1px solid var(--hair);border-radius:var(--card-radius,4px)}
42
+ .panel{background:transparent}
43
+ /* timeline */
44
+ .tl-date{color:var(--title);font-family:var(--font-head)}
45
+ /* concept hub */
46
+ .hub-center{background:transparent;border:1px solid var(--accent);color:var(--title)}
47
+ /* image overlays — 压在图/scrim 上,与皮肤明暗无关 */
48
+ .scrim{background:linear-gradient(180deg,rgba(0,0,0,0) 0%,rgba(0,0,0,.55) 100%)}
49
+ .overlay-title{color:rgba(255,255,255,1)}
50
+ /* data table */
51
+ .dt-head{color:var(--title);border-bottom:1px solid var(--hair)}
52
+ /* figures */
53
+ .gantt-bar{background:var(--c1)}
54
+ .map-pin{background:var(--accent)}
55
+ .ring-fill{stroke:var(--accent)}
@@ -1 +1,5 @@
1
1
  <div style="position:absolute;inset:0;background:radial-gradient(46% 60% at 88% 8%,__ACCENT__24,transparent 60%),radial-gradient(40% 52% at 8% 96%,__ACCENT__14,transparent 64%)"></div><div class="bd-arc" style="position:absolute;left:0;right:0;height:120px;top:var(--bd-arc-y,540px);pointer-events:none"><svg width="100%" height="100%" viewBox="0 0 1280 120" preserveAspectRatio="none"><defs><linearGradient id="arc" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".12"/><stop offset=".5" stop-color="__ACCENT__" stop-opacity=".34"/><stop offset="1" stop-color="__ACCENT__" stop-opacity=".12"/></linearGradient><filter id="arcb"><feGaussianBlur stdDeviation="1.4"/></filter></defs><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width="1.6" filter="url(#arcb)"/><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width=".7"/></svg></div>
2
+ <!-- signature: the margin rule — a scholar's side-note line with an accent tick. -->
3
+ <div style="position:absolute;right:58px;top:104px;bottom:104px;width:1px;background:var(--hair);pointer-events:none"></div>
4
+ <div style="position:absolute;right:46px;top:104px;width:26px;height:2px;background:var(--accent);pointer-events:none"></div>
5
+ <div style="position:absolute;right:46px;bottom:104px;width:26px;height:2px;background:var(--hair);pointer-events:none"></div>