@topmindspace/tms-skills 0.1.14 → 0.1.16

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 (40) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.en.md +3 -3
  3. package/README.md +3 -3
  4. package/package.json +1 -1
  5. package/top-ppt-html/README.en.md +2 -2
  6. package/top-ppt-html/README.md +1 -1
  7. package/top-ppt-html/SKILL.md +3 -3
  8. package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +13 -12
  9. package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +13 -12
  10. package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +13 -12
  11. package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.html +75 -40
  12. package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.model.json +82 -37
  13. package/top-ppt-html/assets/pptx-export.js +5 -5
  14. package/top-ppt-html/assets/showcase/showcase-charts.png +0 -0
  15. package/top-ppt-html/assets/showcase/showcase-cover.png +0 -0
  16. package/top-ppt-html/assets/showcase/showcase-gates.png +0 -0
  17. package/top-ppt-html/assets/showcase/showcase-modes.png +0 -0
  18. package/top-ppt-html/assets/showcase/showcase-positioning.png +0 -0
  19. package/top-ppt-html/assets/showcase/showcase-split.png +0 -0
  20. package/top-ppt-html/assets/showcase/showcase-toolbar.png +0 -0
  21. package/top-ppt-html/assets/showcase/style-business-blue-cover.png +0 -0
  22. package/top-ppt-html/assets/showcase/style-graphite-cover.png +0 -0
  23. package/top-ppt-html/assets/showcase/style-mckinsey-cover.png +0 -0
  24. package/top-ppt-html/assets/style-gallery.html +1 -1
  25. package/top-ppt-html/assets/templates/architecture.html +14 -13
  26. package/top-ppt-html/assets/templates/engine.css +7 -6
  27. package/top-ppt-html/assets/templates/presentation.html +14 -13
  28. package/top-ppt-html/assets/templates/research.html +14 -13
  29. package/top-ppt-html/assets/theme-overview-architecture.png +0 -0
  30. package/top-ppt-html/assets/theme-overview-research.png +0 -0
  31. package/top-ppt-html/assets/theme-overview.png +0 -0
  32. package/top-ppt-html/package-lock.json +2 -2
  33. package/top-ppt-html/package.json +1 -1
  34. package/top-ppt-html/references/components-atoms.md +3 -3
  35. package/top-ppt-html/references/content-rules.md +1 -1
  36. package/top-ppt-html/references/design-system.md +2 -1
  37. package/top-ppt-html/references/pptx-export.md +1 -1
  38. package/top-ppt-html/scripts/build_pptx.js +5 -5
  39. package/top-ppt-html/scripts/capture_showcase_pages.js +145 -0
  40. package/top-ppt-html/scripts/layout-constants.json +6 -2
@@ -4,73 +4,116 @@
4
4
  "theme": "light",
5
5
  "title": "TopMind × tms-skills",
6
6
  "subtitle": "HTML + PPT 双交付 · 为正式商务演示而生",
7
- "meta": "产品介绍 · 2026-09-26 · v0.1.14",
7
+ "meta": "产品介绍 · 2026-09-26 · v0.1.16",
8
8
  "agenda": [
9
9
  [
10
10
  "01",
11
- "差异化定位",
12
- "正式商务 · 双交付"
11
+ "市面 PPT 技能很多,为何还要 top-ppt-html",
12
+ "01 · 为什么是我们"
13
13
  ],
14
14
  [
15
15
  "02",
16
- "tms-skills 概览",
17
- "可安装技能 monorepo"
16
+ "tms-skills:整仓可安装的智能体技能",
17
+ "02 · tms-skills"
18
18
  ],
19
19
  [
20
20
  "03",
21
- "top-ppt-html",
22
- "HTML + 保真 PPTX"
21
+ "双交付:HTML 即演示,PPTX 可继续编",
22
+ "03 · top-ppt-html"
23
23
  ],
24
24
  [
25
25
  "04",
26
- "三模式契约",
27
- "演示 · 研究 · 架构"
26
+ "模式先定后写:A 演示 · B 研究 · C 架构",
27
+ "04 · 三模式"
28
28
  ],
29
29
  [
30
30
  "05",
31
- "图表工艺",
32
- "多样 · 可编辑 · 门禁"
31
+ "交付面三件套:演示 HTML · 可编辑 PPTX · 门禁说明",
32
+ "05 · 图表工艺"
33
33
  ],
34
34
  [
35
35
  "06",
36
- "风格与主题",
37
- "九风格 × 亮暗"
36
+ "0.1.x 能力累进:定位与样张随版本加厚",
37
+ "05 · 图表工艺"
38
38
  ],
39
39
  [
40
40
  "07",
41
- "质量门禁",
42
- "strict 0/0 交付"
41
+ "九风格开场即可见,亮暗主题一键贯穿",
42
+ "06 · 风格主题"
43
43
  ],
44
44
  [
45
45
  "08",
46
- "Header 工具栏",
47
- "演示即文档"
46
+ "散装出稿止步,strict 0/0 才算交付",
47
+ "07 · 质量门禁"
48
48
  ],
49
49
  [
50
50
  "09",
51
- "Fast Mode",
52
- "少问一句 · 工艺不降"
51
+ "从想法到上台:工艺链路如何把主张垫实",
52
+ "07 · 质量门禁"
53
+ ],
54
+ [
55
+ "10",
56
+ "核图优先:排名对比用横向条,一眼分出轻重",
57
+ "05 · 图表工艺"
58
+ ],
59
+ [
60
+ "11",
61
+ "打开 HTML 即演示:顶栏快捷操作一览",
62
+ "08 · Header 工具栏"
63
+ ],
64
+ [
65
+ "12",
66
+ "Fast Mode:跳过问询,不跳过工艺",
67
+ "09 · Fast Mode"
53
68
  ]
54
69
  ],
55
70
  "sections": [
56
71
  {
57
- "type": "points",
58
- "layoutPreset": "P4",
72
+ "type": "cards",
73
+ "layoutPreset": "P5",
59
74
  "eyebrow": "01 · 为什么是我们",
60
75
  "title": "市面 PPT 技能很多,为何还要 top-ppt-html",
61
- "points": [
62
- [
63
- "正式商务演示,不是花哨 gadget",
64
- "为演示报告与上台汇报而生——直观、大气、可编辑,而非装饰堆砌"
65
- ],
66
- [
67
- "HTML + PPT 双交付",
68
- "日常用 HTML 等同幻灯片演示;需要时再导出高保真可编辑 PPTX"
69
- ],
70
- [
71
- "信息密度与克制(参考 MD3)",
72
- "整体空间布局合适、文字/图形/形状/颜色克制——读得清、站得住"
73
- ]
76
+ "columns": 3,
77
+ "cards": [
78
+ {
79
+ "title": "正式商务演示",
80
+ "points": [
81
+ [
82
+ "不是花哨 gadget",
83
+ "为演示报告与上台汇报而生——直观、大气、可编辑"
84
+ ],
85
+ [
86
+ "一屏一主张",
87
+ "标题即行动句,少装饰堆砌"
88
+ ]
89
+ ]
90
+ },
91
+ {
92
+ "title": "HTML + PPT 双交付",
93
+ "points": [
94
+ [
95
+ "HTML 日常上台",
96
+ "单文件可翻页,等同幻灯片"
97
+ ],
98
+ [
99
+ "PPTX 按需导出",
100
+ "版式保真、可继续编辑"
101
+ ]
102
+ ]
103
+ },
104
+ {
105
+ "title": "MD3 式克制",
106
+ "points": [
107
+ [
108
+ "密度合适",
109
+ "文字/图形/形状/颜色克制"
110
+ ],
111
+ [
112
+ "无 AI chrome",
113
+ "结论条 tonal 满铺,禁左侧装饰轨"
114
+ ]
115
+ ]
116
+ }
74
117
  ],
75
118
  "soWhat": "产出即上台:同源模型保证 HTML 与 PPTX 一致,图表带数据可核对。"
76
119
  },
@@ -121,7 +164,8 @@
121
164
  ]
122
165
  }
123
166
  ],
124
- "footnote": "包名 @topmindspace/tms-skills · 当前线 0.1.x(latest)"
167
+ "footnote": "包名 @topmindspace/tms-skills · 当前线 0.1.16(latest)",
168
+ "soWhat": "安装器与技能同仓同 tag——装一次,版本线对齐。"
125
169
  },
126
170
  {
127
171
  "type": "split",
@@ -190,7 +234,7 @@
190
234
  "points": [
191
235
  [
192
236
  "咨询密排",
193
- "Exhibit · 来源 · so-what"
237
+ "Exhibit · 来源 · 结论条"
194
238
  ],
195
239
  [
196
240
  "结论可核对",
@@ -212,7 +256,8 @@
212
256
  ]
213
257
  }
214
258
  ],
215
- "footnote": "意图线索:路演/汇报/演讲 → A;调研/对标 → B;拓扑/方案图 → C"
259
+ "footnote": "意图线索:路演/汇报/演讲 → A;调研/对标 → B;拓扑/方案图 → C",
260
+ "soWhat": "先定模式再写页——A/B/C 契约决定密度、图表与结论条用法。"
216
261
  },
217
262
  {
218
263
  "type": "donut",
@@ -494,12 +494,12 @@ function table(x, y, w, colW, rows, S, opts) {
494
494
  function soWhatBar(sh, text, S) {
495
495
  var R = (typeof regionOf === 'function') ? regionOf('exhibit', 'annotation')
496
496
  : { x: MX, y: PT.exhibit.soWhatY, w: CW, h: 0.62 };
497
- /* MD3 结论条:衬底 + 左 accent 轨 + 正文(不绘制「SO WHAT」标签字样) */
498
- var bodyW = Math.max(2.5, R.w - 0.44);
499
- var fzB = fitFont([String(text || '')], bodyW, R.h - 0.14, { max: 14, gapFactor: 0.2, maxShrinkSteps: 3 });
497
+ /* MD3 结论条:tonal soft 满铺 + 舒适字阶;禁止左 accent 装饰轨(anti-AI-flavor) */
498
+ var padX = 0.28, padY = 0.10;
499
+ var bodyW = Math.max(2.5, R.w - padX * 2);
500
+ var fzB = fitFont([String(text || '')], bodyW, R.h - padY * 2, { max: 15, gapFactor: 0.2, maxShrinkSteps: 3 });
500
501
  sh.push(shape('rect', R.x, R.y, R.w, R.h, S.soft));
501
- sh.push(shape('rect', R.x, R.y, 0.06, R.h, S.accent));
502
- sh.push(txSp(R.x + 0.22, R.y + 0.06, R.w - 0.44, R.h - 0.12,
502
+ sh.push(txSp(R.x + padX, R.y + padY, R.w - padX * 2, R.h - padY * 2,
503
503
  [[{ t: String(text || ''), sz: fzB, b: 1, col: S.ink, font: S.font }]], { anchor: 'ctr' }));
504
504
  }
505
505
  function footnoteLine(sh, text, S) {
@@ -86,7 +86,7 @@
86
86
  .pv__hfill{height:100%;border-radius:999px;background:var(--pa)}
87
87
  .pv__hval{font-size:10px;font-weight:700;color:var(--ptxt);width:28px;text-align:right;flex:none}
88
88
  .pv__src{font-size:9px;color:var(--ptxt2);border-top:1px solid var(--pbd);padding-top:5px;margin-top:2px}
89
- .pv__sowhat{display:flex;align-items:flex-start;gap:8px;margin-top:16px;padding:12px 16px;border-left:4px solid var(--pa);border-radius:8px;
89
+ .pv__sowhat{display:flex;align-items:center;gap:8px;margin-top:16px;padding:16px 24px;border:1px solid color-mix(in srgb,var(--pa) 28%,transparent);border-radius:8px;
90
90
  background:var(--pas);border-radius:0 6px 6px 0;padding:6px 10px;margin-bottom:10px}
91
91
  .pv__swK{font-size:8.5px;font-weight:700;letter-spacing:.1em;color:var(--pa);flex:none}
92
92
  .pv__swV{font-size:10px;font-weight:500;color:var(--ptxt);line-height:1.5}
@@ -505,23 +505,24 @@ tbody tr:hover{background:var(--surface-1)}
505
505
  td strong{color:var(--text);font-weight:600}
506
506
  td.k{color:var(--text);font-weight:500;white-space:nowrap}
507
507
  td.num{font-variant-numeric:tabular-nums}
508
- /* ── 结论条(MD3 tonal strip · 本页重点收口;默认不显示「So what」标签) ──
508
+ /* ── 结论条(MD3 tonal surface · 本页重点收口;默认不显示「So what」标签) ──
509
+ 去 AI 味硬规则:禁止左侧 accent 装饰轨 / 竖条 / chip 堆;强调靠 soft 满铺 + 字重/行高/呼吸间距。
509
510
  与上方主内容呼吸间距 ≥ --sp-6;flex:none 防止被主内容挤压;一屏页不得压进注释带。 */
510
511
  .band>.wrap:has(>.sowhat),.band>.wrap:has(>.note){display:flex;flex-direction:column}
511
- .sowhat{display:flex;align-items:flex-start;gap:var(--sp-3);flex:none;
512
+ .sowhat{display:flex;align-items:center;gap:var(--sp-3);flex:none;
512
513
  margin-top:clamp(28px,3.6vh,48px); /* ≥ --sp-6 量级,修「贴底」 */
513
- padding:var(--sp-4) var(--sp-5);background:var(--accent-soft);border:1px solid var(--accent-soft-2);
514
- border-left:4px solid var(--accent);border-radius:var(--r-md);max-width:100%}
514
+ padding:var(--sp-5) var(--sp-6);background:var(--accent-soft);border:1px solid var(--accent-soft-2);
515
+ border-radius:var(--r-md);max-width:100%}
515
516
  .sowhat__k{display:none}
516
517
  .sowhat--labeled .sowhat__k{display:inline;font-size:var(--fs-xs);font-weight:700;letter-spacing:.1em;
517
518
  text-transform:uppercase;color:var(--accent-text);white-space:nowrap;flex:none;padding-top:.15em}
518
519
  .sowhat__v,.sowhat>:not(.sowhat__k){font-size:var(--fs-h3);color:var(--text);font-weight:var(--fw-title);
519
- line-height:1.55;flex:1;min-width:0}
520
+ line-height:1.65;flex:1;min-width:0}
520
521
  .sowhat__v p,.sowhat__stack{margin:0}
521
522
  .sowhat__stack{display:flex;flex-direction:column;gap:var(--sp-2)}
522
523
 
523
524
  .note{display:flex;gap:var(--sp-4);padding:clamp(20px,2vw,28px);border-radius:var(--r-lg);
524
- background:var(--accent-soft);border-left:3px solid var(--accent)}
525
+ background:var(--accent-soft);border:1px solid var(--accent-soft-2)}
525
526
  .note__ico{width:26px;height:26px;flex:none;border-radius:50%;background:var(--accent);
526
527
  color:var(--accent-on);display:grid;place-items:center;font-size:13px;font-weight:700;font-style:normal}
527
528
  .note__t{font-size:var(--fs-h3);font-weight:600;color:var(--text);margin-bottom:6px}
@@ -1218,7 +1219,7 @@ font-weight:600}
1218
1219
  <div class="pmodal__body">
1219
1220
  <div class="hdoc">
1220
1221
  <h4>HTML 与 PPTX 的分工</h4>
1221
- <p>HTML 是阅读与演示界面,PPTX 是协作与修改格式——两者来自同一内容模型(window.REPORT_MODEL),PPTX 内全部是原生形状、文本框、表格(<code>pictures=0</code>),可在 PowerPoint / WPS 中继续编辑;<b>带数据的图表为原生数据图表</b>(chart 对象 + 内嵌 Excel,双击即可"编辑数据");口径、来源与 so-what 自动写入<b>演讲者备注</b>,不占版面。</p>
1222
+ <p>HTML 是阅读与演示界面,PPTX 是协作与修改格式——两者来自同一内容模型(window.REPORT_MODEL),PPTX 内全部是原生形状、文本框、表格(<code>pictures=0</code>),可在 PowerPoint / WPS 中继续编辑;<b>带数据的图表为原生数据图表</b>(chart 对象 + 内嵌 Excel,双击即可"编辑数据");口径、来源与结论条自动写入<b>演讲者备注</b>,不占版面。</p>
1222
1223
  <h4>怎么获得 PPTX</h4>
1223
1224
  <div class="hch">
1224
1225
  <div>
@@ -1794,7 +1795,7 @@ window.REPORT_MODEL = {
1794
1795
 
1795
1796
  /* __TOPPPT_RUNTIME_START__ */
1796
1797
  /* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
1797
- /* __TOPPPT_RUNTIME_SHA__:f4dc2ab366ea79c4 */
1798
+ /* __TOPPPT_RUNTIME_SHA__:57dbfb4f2b594c45 */
1798
1799
  /* ═══════════════════════════════════════════════════════════════════════════
1799
1800
  * TopPPT HTML· 浏览器端 PPTX 预览运行时
1800
1801
  * 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
@@ -2291,12 +2292,12 @@ function table(x, y, w, colW, rows, S, opts) {
2291
2292
  function soWhatBar(sh, text, S) {
2292
2293
  var R = (typeof regionOf === 'function') ? regionOf('exhibit', 'annotation')
2293
2294
  : { x: MX, y: PT.exhibit.soWhatY, w: CW, h: 0.62 };
2294
- /* MD3 结论条:衬底 + 左 accent 轨 + 正文(不绘制「SO WHAT」标签字样) */
2295
- var bodyW = Math.max(2.5, R.w - 0.44);
2296
- var fzB = fitFont([String(text || '')], bodyW, R.h - 0.14, { max: 14, gapFactor: 0.2, maxShrinkSteps: 3 });
2295
+ /* MD3 结论条:tonal soft 满铺 + 舒适字阶;禁止左 accent 装饰轨(anti-AI-flavor) */
2296
+ var padX = 0.28, padY = 0.10;
2297
+ var bodyW = Math.max(2.5, R.w - padX * 2);
2298
+ var fzB = fitFont([String(text || '')], bodyW, R.h - padY * 2, { max: 15, gapFactor: 0.2, maxShrinkSteps: 3 });
2297
2299
  sh.push(shape('rect', R.x, R.y, R.w, R.h, S.soft));
2298
- sh.push(shape('rect', R.x, R.y, 0.06, R.h, S.accent));
2299
- sh.push(txSp(R.x + 0.22, R.y + 0.06, R.w - 0.44, R.h - 0.12,
2300
+ sh.push(txSp(R.x + padX, R.y + padY, R.w - padX * 2, R.h - padY * 2,
2300
2301
  [[{ t: String(text || ''), sz: fzB, b: 1, col: S.ink, font: S.font }]], { anchor: 'ctr' }));
2301
2302
  }
2302
2303
  function footnoteLine(sh, text, S) {
@@ -479,23 +479,24 @@ tbody tr:hover{background:var(--surface-1)}
479
479
  td strong{color:var(--text);font-weight:600}
480
480
  td.k{color:var(--text);font-weight:500;white-space:nowrap}
481
481
  td.num{font-variant-numeric:tabular-nums}
482
- /* ── 结论条(MD3 tonal strip · 本页重点收口;默认不显示「So what」标签) ──
482
+ /* ── 结论条(MD3 tonal surface · 本页重点收口;默认不显示「So what」标签) ──
483
+ 去 AI 味硬规则:禁止左侧 accent 装饰轨 / 竖条 / chip 堆;强调靠 soft 满铺 + 字重/行高/呼吸间距。
483
484
  与上方主内容呼吸间距 ≥ --sp-6;flex:none 防止被主内容挤压;一屏页不得压进注释带。 */
484
485
  .band>.wrap:has(>.sowhat),.band>.wrap:has(>.note){display:flex;flex-direction:column}
485
- .sowhat{display:flex;align-items:flex-start;gap:var(--sp-3);flex:none;
486
+ .sowhat{display:flex;align-items:center;gap:var(--sp-3);flex:none;
486
487
  margin-top:clamp(28px,3.6vh,48px); /* ≥ --sp-6 量级,修「贴底」 */
487
- padding:var(--sp-4) var(--sp-5);background:var(--accent-soft);border:1px solid var(--accent-soft-2);
488
- border-left:4px solid var(--accent);border-radius:var(--r-md);max-width:100%}
488
+ padding:var(--sp-5) var(--sp-6);background:var(--accent-soft);border:1px solid var(--accent-soft-2);
489
+ border-radius:var(--r-md);max-width:100%}
489
490
  .sowhat__k{display:none}
490
491
  .sowhat--labeled .sowhat__k{display:inline;font-size:var(--fs-xs);font-weight:700;letter-spacing:.1em;
491
492
  text-transform:uppercase;color:var(--accent-text);white-space:nowrap;flex:none;padding-top:.15em}
492
493
  .sowhat__v,.sowhat>:not(.sowhat__k){font-size:var(--fs-h3);color:var(--text);font-weight:var(--fw-title);
493
- line-height:1.55;flex:1;min-width:0}
494
+ line-height:1.65;flex:1;min-width:0}
494
495
  .sowhat__v p,.sowhat__stack{margin:0}
495
496
  .sowhat__stack{display:flex;flex-direction:column;gap:var(--sp-2)}
496
497
 
497
498
  .note{display:flex;gap:var(--sp-4);padding:clamp(20px,2vw,28px);border-radius:var(--r-lg);
498
- background:var(--accent-soft);border-left:3px solid var(--accent)}
499
+ background:var(--accent-soft);border:1px solid var(--accent-soft-2)}
499
500
  .note__ico{width:26px;height:26px;flex:none;border-radius:50%;background:var(--accent);
500
501
  color:var(--accent-on);display:grid;place-items:center;font-size:13px;font-weight:700;font-style:normal}
501
502
  .note__t{font-size:var(--fs-h3);font-weight:600;color:var(--text);margin-bottom:6px}
@@ -503,23 +503,24 @@ tbody tr:hover{background:var(--surface-1)}
503
503
  td strong{color:var(--text);font-weight:600}
504
504
  td.k{color:var(--text);font-weight:500;white-space:nowrap}
505
505
  td.num{font-variant-numeric:tabular-nums}
506
- /* ── 结论条(MD3 tonal strip · 本页重点收口;默认不显示「So what」标签) ──
506
+ /* ── 结论条(MD3 tonal surface · 本页重点收口;默认不显示「So what」标签) ──
507
+ 去 AI 味硬规则:禁止左侧 accent 装饰轨 / 竖条 / chip 堆;强调靠 soft 满铺 + 字重/行高/呼吸间距。
507
508
  与上方主内容呼吸间距 ≥ --sp-6;flex:none 防止被主内容挤压;一屏页不得压进注释带。 */
508
509
  .band>.wrap:has(>.sowhat),.band>.wrap:has(>.note){display:flex;flex-direction:column}
509
- .sowhat{display:flex;align-items:flex-start;gap:var(--sp-3);flex:none;
510
+ .sowhat{display:flex;align-items:center;gap:var(--sp-3);flex:none;
510
511
  margin-top:clamp(28px,3.6vh,48px); /* ≥ --sp-6 量级,修「贴底」 */
511
- padding:var(--sp-4) var(--sp-5);background:var(--accent-soft);border:1px solid var(--accent-soft-2);
512
- border-left:4px solid var(--accent);border-radius:var(--r-md);max-width:100%}
512
+ padding:var(--sp-5) var(--sp-6);background:var(--accent-soft);border:1px solid var(--accent-soft-2);
513
+ border-radius:var(--r-md);max-width:100%}
513
514
  .sowhat__k{display:none}
514
515
  .sowhat--labeled .sowhat__k{display:inline;font-size:var(--fs-xs);font-weight:700;letter-spacing:.1em;
515
516
  text-transform:uppercase;color:var(--accent-text);white-space:nowrap;flex:none;padding-top:.15em}
516
517
  .sowhat__v,.sowhat>:not(.sowhat__k){font-size:var(--fs-h3);color:var(--text);font-weight:var(--fw-title);
517
- line-height:1.55;flex:1;min-width:0}
518
+ line-height:1.65;flex:1;min-width:0}
518
519
  .sowhat__v p,.sowhat__stack{margin:0}
519
520
  .sowhat__stack{display:flex;flex-direction:column;gap:var(--sp-2)}
520
521
 
521
522
  .note{display:flex;gap:var(--sp-4);padding:clamp(20px,2vw,28px);border-radius:var(--r-lg);
522
- background:var(--accent-soft);border-left:3px solid var(--accent)}
523
+ background:var(--accent-soft);border:1px solid var(--accent-soft-2)}
523
524
  .note__ico{width:26px;height:26px;flex:none;border-radius:50%;background:var(--accent);
524
525
  color:var(--accent-on);display:grid;place-items:center;font-size:13px;font-weight:700;font-style:normal}
525
526
  .note__t{font-size:var(--fs-h3);font-weight:600;color:var(--text);margin-bottom:6px}
@@ -1224,7 +1225,7 @@ background:var(--surface-2);border-radius:6px;padding:2px 7px;color:var(--text)}
1224
1225
  <div class="pmodal__body">
1225
1226
  <div class="hdoc">
1226
1227
  <h4>HTML 与 PPTX 的分工</h4>
1227
- <p>HTML 是阅读与演示界面,PPTX 是协作与修改格式——两者来自同一内容模型(window.REPORT_MODEL),PPTX 内全部是原生形状、文本框、表格(<code>pictures=0</code>),可在 PowerPoint / WPS 中继续编辑;<b>带数据的图表为原生数据图表</b>(chart 对象 + 内嵌 Excel,双击即可"编辑数据");口径、来源与 so-what 自动写入<b>演讲者备注</b>,不占版面。</p>
1228
+ <p>HTML 是阅读与演示界面,PPTX 是协作与修改格式——两者来自同一内容模型(window.REPORT_MODEL),PPTX 内全部是原生形状、文本框、表格(<code>pictures=0</code>),可在 PowerPoint / WPS 中继续编辑;<b>带数据的图表为原生数据图表</b>(chart 对象 + 内嵌 Excel,双击即可"编辑数据");口径、来源与结论条自动写入<b>演讲者备注</b>,不占版面。</p>
1228
1229
  <h4>怎么获得 PPTX</h4>
1229
1230
  <div class="hch">
1230
1231
  <div>
@@ -1804,7 +1805,7 @@ window.REPORT_MODEL = {
1804
1805
 
1805
1806
  /* __TOPPPT_RUNTIME_START__ */
1806
1807
  /* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
1807
- /* __TOPPPT_RUNTIME_SHA__:f4dc2ab366ea79c4 */
1808
+ /* __TOPPPT_RUNTIME_SHA__:57dbfb4f2b594c45 */
1808
1809
  /* ═══════════════════════════════════════════════════════════════════════════
1809
1810
  * TopPPT HTML· 浏览器端 PPTX 预览运行时
1810
1811
  * 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
@@ -2301,12 +2302,12 @@ function table(x, y, w, colW, rows, S, opts) {
2301
2302
  function soWhatBar(sh, text, S) {
2302
2303
  var R = (typeof regionOf === 'function') ? regionOf('exhibit', 'annotation')
2303
2304
  : { x: MX, y: PT.exhibit.soWhatY, w: CW, h: 0.62 };
2304
- /* MD3 结论条:衬底 + 左 accent 轨 + 正文(不绘制「SO WHAT」标签字样) */
2305
- var bodyW = Math.max(2.5, R.w - 0.44);
2306
- var fzB = fitFont([String(text || '')], bodyW, R.h - 0.14, { max: 14, gapFactor: 0.2, maxShrinkSteps: 3 });
2305
+ /* MD3 结论条:tonal soft 满铺 + 舒适字阶;禁止左 accent 装饰轨(anti-AI-flavor) */
2306
+ var padX = 0.28, padY = 0.10;
2307
+ var bodyW = Math.max(2.5, R.w - padX * 2);
2308
+ var fzB = fitFont([String(text || '')], bodyW, R.h - padY * 2, { max: 15, gapFactor: 0.2, maxShrinkSteps: 3 });
2307
2309
  sh.push(shape('rect', R.x, R.y, R.w, R.h, S.soft));
2308
- sh.push(shape('rect', R.x, R.y, 0.06, R.h, S.accent));
2309
- sh.push(txSp(R.x + 0.22, R.y + 0.06, R.w - 0.44, R.h - 0.12,
2310
+ sh.push(txSp(R.x + padX, R.y + padY, R.w - padX * 2, R.h - padY * 2,
2310
2311
  [[{ t: String(text || ''), sz: fzB, b: 1, col: S.ink, font: S.font }]], { anchor: 'ctr' }));
2311
2312
  }
2312
2313
  function footnoteLine(sh, text, S) {
@@ -506,23 +506,24 @@ tbody tr:hover{background:var(--surface-1)}
506
506
  td strong{color:var(--text);font-weight:600}
507
507
  td.k{color:var(--text);font-weight:500;white-space:nowrap}
508
508
  td.num{font-variant-numeric:tabular-nums}
509
- /* ── 结论条(MD3 tonal strip · 本页重点收口;默认不显示「So what」标签) ──
509
+ /* ── 结论条(MD3 tonal surface · 本页重点收口;默认不显示「So what」标签) ──
510
+ 去 AI 味硬规则:禁止左侧 accent 装饰轨 / 竖条 / chip 堆;强调靠 soft 满铺 + 字重/行高/呼吸间距。
510
511
  与上方主内容呼吸间距 ≥ --sp-6;flex:none 防止被主内容挤压;一屏页不得压进注释带。 */
511
512
  .band>.wrap:has(>.sowhat),.band>.wrap:has(>.note){display:flex;flex-direction:column}
512
- .sowhat{display:flex;align-items:flex-start;gap:var(--sp-3);flex:none;
513
+ .sowhat{display:flex;align-items:center;gap:var(--sp-3);flex:none;
513
514
  margin-top:clamp(28px,3.6vh,48px); /* ≥ --sp-6 量级,修「贴底」 */
514
- padding:var(--sp-4) var(--sp-5);background:var(--accent-soft);border:1px solid var(--accent-soft-2);
515
- border-left:4px solid var(--accent);border-radius:var(--r-md);max-width:100%}
515
+ padding:var(--sp-5) var(--sp-6);background:var(--accent-soft);border:1px solid var(--accent-soft-2);
516
+ border-radius:var(--r-md);max-width:100%}
516
517
  .sowhat__k{display:none}
517
518
  .sowhat--labeled .sowhat__k{display:inline;font-size:var(--fs-xs);font-weight:700;letter-spacing:.1em;
518
519
  text-transform:uppercase;color:var(--accent-text);white-space:nowrap;flex:none;padding-top:.15em}
519
520
  .sowhat__v,.sowhat>:not(.sowhat__k){font-size:var(--fs-h3);color:var(--text);font-weight:var(--fw-title);
520
- line-height:1.55;flex:1;min-width:0}
521
+ line-height:1.65;flex:1;min-width:0}
521
522
  .sowhat__v p,.sowhat__stack{margin:0}
522
523
  .sowhat__stack{display:flex;flex-direction:column;gap:var(--sp-2)}
523
524
 
524
525
  .note{display:flex;gap:var(--sp-4);padding:clamp(20px,2vw,28px);border-radius:var(--r-lg);
525
- background:var(--accent-soft);border-left:3px solid var(--accent)}
526
+ background:var(--accent-soft);border:1px solid var(--accent-soft-2)}
526
527
  .note__ico{width:26px;height:26px;flex:none;border-radius:50%;background:var(--accent);
527
528
  color:var(--accent-on);display:grid;place-items:center;font-size:13px;font-weight:700;font-style:normal}
528
529
  .note__t{font-size:var(--fs-h3);font-weight:600;color:var(--text);margin-bottom:6px}
@@ -1470,7 +1471,7 @@ transition:color .18s,background-color .18s}
1470
1471
  <div class="pmodal__body">
1471
1472
  <div class="hdoc">
1472
1473
  <h4>HTML 与 PPTX 的分工</h4>
1473
- <p>HTML 是阅读与演示界面,PPTX 是协作与修改格式——两者来自同一内容模型(window.REPORT_MODEL),PPTX 内全部是原生形状、文本框、表格(<code>pictures=0</code>),可在 PowerPoint / WPS 中继续编辑;<b>带数据的图表为原生数据图表</b>(chart 对象 + 内嵌 Excel,双击即可"编辑数据");口径、来源与 so-what 自动写入<b>演讲者备注</b>,不占版面。</p>
1474
+ <p>HTML 是阅读与演示界面,PPTX 是协作与修改格式——两者来自同一内容模型(window.REPORT_MODEL),PPTX 内全部是原生形状、文本框、表格(<code>pictures=0</code>),可在 PowerPoint / WPS 中继续编辑;<b>带数据的图表为原生数据图表</b>(chart 对象 + 内嵌 Excel,双击即可"编辑数据");口径、来源与结论条自动写入<b>演讲者备注</b>,不占版面。</p>
1474
1475
  <h4>怎么获得 PPTX</h4>
1475
1476
  <div class="hch">
1476
1477
  <div>
@@ -2077,7 +2078,7 @@ window.REPORT_MODEL = {
2077
2078
 
2078
2079
  /* __TOPPPT_RUNTIME_START__ */
2079
2080
  /* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
2080
- /* __TOPPPT_RUNTIME_SHA__:f4dc2ab366ea79c4 */
2081
+ /* __TOPPPT_RUNTIME_SHA__:57dbfb4f2b594c45 */
2081
2082
  /* ═══════════════════════════════════════════════════════════════════════════
2082
2083
  * TopPPT HTML· 浏览器端 PPTX 预览运行时
2083
2084
  * 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
@@ -2574,12 +2575,12 @@ function table(x, y, w, colW, rows, S, opts) {
2574
2575
  function soWhatBar(sh, text, S) {
2575
2576
  var R = (typeof regionOf === 'function') ? regionOf('exhibit', 'annotation')
2576
2577
  : { x: MX, y: PT.exhibit.soWhatY, w: CW, h: 0.62 };
2577
- /* MD3 结论条:衬底 + 左 accent 轨 + 正文(不绘制「SO WHAT」标签字样) */
2578
- var bodyW = Math.max(2.5, R.w - 0.44);
2579
- var fzB = fitFont([String(text || '')], bodyW, R.h - 0.14, { max: 14, gapFactor: 0.2, maxShrinkSteps: 3 });
2578
+ /* MD3 结论条:tonal soft 满铺 + 舒适字阶;禁止左 accent 装饰轨(anti-AI-flavor) */
2579
+ var padX = 0.28, padY = 0.10;
2580
+ var bodyW = Math.max(2.5, R.w - padX * 2);
2581
+ var fzB = fitFont([String(text || '')], bodyW, R.h - padY * 2, { max: 15, gapFactor: 0.2, maxShrinkSteps: 3 });
2580
2582
  sh.push(shape('rect', R.x, R.y, R.w, R.h, S.soft));
2581
- sh.push(shape('rect', R.x, R.y, 0.06, R.h, S.accent));
2582
- sh.push(txSp(R.x + 0.22, R.y + 0.06, R.w - 0.44, R.h - 0.12,
2583
+ sh.push(txSp(R.x + padX, R.y + padY, R.w - padX * 2, R.h - padY * 2,
2583
2584
  [[{ t: String(text || ''), sz: fzB, b: 1, col: S.ink, font: S.font }]], { anchor: 'ctr' }));
2584
2585
  }
2585
2586
  function footnoteLine(sh, text, S) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "top-ppt-html",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "top-ppt-html",
9
- "version": "0.1.14",
9
+ "version": "0.1.16",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "pptxgenjs": "^4.0.0"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "top-ppt-html",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "private": true,
5
5
  "description": "TopPPT HTML:正式商务演示双交付。单文件 HTML + 版式保真可编辑 PPTX;MD3 密度克制;布局骨架 P1–P12;模型单写;strict 0/0 交付。",
6
6
  "license": "MIT",
@@ -626,10 +626,10 @@ python scripts/prepare_images.py ./photos --layout grid --mode path # 大图
626
626
  ## 结论条 `.sowhat`(本页重点收口)
627
627
 
628
628
  > **语义**:本页关键 takeaway,不是脚注。
629
- > **版式**:MD3 tonal 衬条——`accent-soft` 底 + 左 4px accent 轨 + 略大于正文的 `--fw-title` 字重。
629
+ > **版式**:MD3 tonal surface——`accent-soft` 满铺 + 细描边 + 略大于正文的 `--fw-title` / `line-height:1.65` + 舒适内边距(`--sp-5`/`--sp-6`)。**禁止左侧 accent 装饰轨**(anti-AI-flavor)。
630
630
  > **标签**:**默认不显示**「So what / SO WHAT / 结论」字样;只写句子(或 `.sowhat__stack` 短多行)。罕见需标签时加 `.sowhat--labeled` + `.sowhat__k`。
631
- > **间距**:与上方主内容 `margin-top: var(--sp-5)`(≥24px),禁止贴底。
632
- > **PPTX**:`soWhatBar()` 同源衬底+左轨+正文,**不绘制 SO WHAT 字符串**。
631
+ > **间距**:与上方主内容 `margin-top: clamp(28px,3.6vh,48px)`(≥`--sp-6` 量级),禁止贴底;善用页内呼吸,不挤、不空。
632
+ > **PPTX**:`soWhatBar()` 同源 soft 满铺衬底 + 正文(无左轨),**不绘制 SO WHAT 字符串**。
633
633
 
634
634
  ```html
635
635
  <div class="sowhat rv"><span class="sowhat__v">一行含义或建议(≤60 字)。</span></div>
@@ -474,7 +474,7 @@ DGIG: 数据 = 能自我增强的生产资料
474
474
 
475
475
  1. **发现(Finding)**:直接陈述数据与事实,≤200 字/段;数字前置("入湖表 68% 从未被查询")。
476
476
  2. **证据(Evidence)**:Exhibit 图表框 / 密表 / 指标带;外部数据必带 `[n]`;每个 Exhibit 必有来源行。
477
- 3. **结论条**:`.sowhat` 一行收口(≤60 字)——"这意味着…/因此建议…";**不显示「So what」标签**,靠 MD3 衬条(左 accent 轨 + soft 底)强调;写不出结论说明这页论证不完整。
477
+ 3. **结论条**:`.sowhat` 一行收口(≤60 字)——"这意味着…/因此建议…";**不显示「So what」标签**;靠 MD3 tonal surface(`accent-soft` 满铺 + 细描边 + 舒适字阶/行高)强调——**禁止左侧 accent 装饰轨**(anti-AI-flavor);写不出结论说明这页论证不完整。
478
478
 
479
479
  ### 8-2、行动标题写法
480
480
 
@@ -63,7 +63,8 @@
63
63
  - 不加多余角标、chips 堆叠、日期页码横条(铁律 14)
64
64
  - 不用渐变、彩色阴影、玻璃拟态、无意义图标墙
65
65
  - 图标每屏 3–8 个(`icons.md`),架构模式图为王可无图标
66
- - 文案层的高危词表见 `layout-constants.json` `aiFlavor.words`(`validate_report.py` 硬拦)
66
+ - **结论条禁左侧 accent 装饰轨(left rail)**:`.sowhat` / 同类收口条只用 MD3 tonal surface(`accent-soft` 满铺 + 细描边)+ 舒适字阶/行高/内边距表达强调;**禁止**竖色条、霓虹边、装饰 chip 当「AI chrome」。功能向状态条(如 `.flagbar` 待核实)可保留细强调,但不得照搬到结论条。
67
+ - 文案层的高危词表见 `layout-constants.json` `aiFlavor.words`(`validate_report.py` 硬拦);视觉层本条写入 `aiFlavor.visual` 注释与 `content-rules` / `components-atoms` / SKILL
67
68
 
68
69
  ## 1b. MD3 对齐映射(m3.material.io)
69
70
 
@@ -108,7 +108,7 @@ HTML 侧仍用 MD3 clamp;双端都以「最后一排可读」为准(`present
108
108
 
109
109
  > 几何常量见 `layout-constants.json` `pageTypes.{sankey,treemap,boxplot,network,marimekko,streamgraph}`(含节点/流带上限、采样点下限、双边界追踪约束);版式与生成规则详见 `references/infographics.md`。
110
110
 
111
- **通用可选字段(全部页型)**:`soWhat`(结论条,MD3 accent 左轨 + soft 底;**不绘制「SO WHAT」标签**)、`footnote`(页脚来源行)、`flags`(**待核实标注清单** `["…"]` → accent 强调色清单条,提示用户二次确认,并写入演讲者备注)、`image`(素材图片 / 配图占位,见 `image` 页型)、`exhibitNo`(非 exhibit 页型也可带 Exhibit 徽标)。research 模式 `soWhat/footnote` **只在关键论证页填写**(克制条款;结论条无 So what 字样);comparison 页型的 `verdict` 为 accent 实底结论条。
111
+ **通用可选字段(全部页型)**:`soWhat`(结论条,MD3 tonal soft 满铺、**无左轨**;**不绘制「SO WHAT」标签**)、`footnote`(页脚来源行)、`flags`(**待核实标注清单** `["…"]` → accent 强调色清单条,提示用户二次确认,并写入演讲者备注)、`image`(素材图片 / 配图占位,见 `image` 页型)、`exhibitNo`(非 exhibit 页型也可带 Exhibit 徽标)。research 模式 `soWhat/footnote` **只在关键论证页填写**(克制条款;结论条无 So what 字样);comparison 页型的 `verdict` 为 accent 实底结论条。
112
112
 
113
113
  > **素材图片(单源 `layout-constants.json` 的 `imageSpec`)**:`image` 三选一必填——`src`(用户图,data: 内联或相对路径)|`items:[{src,alt?,caption?,placeholder?}]`(多图版式)|`placeholder:true`(**配图占位**,无素材时锁版式用)。
114
114
  > - **六版式**(`layout`):`full` 版心全宽 3:1|`half` 左图右注 4:3|`bleed` 通栏出血 21:9|`grid` 多图网格 4:3(2/3/4/6 张)|`compare` 双图 A/B 4:3|`wall` Logo 墙 1:1。比例写在 `imageSpec.ratioDefault`,**HTML 用同比例锁定类、PPTX 用同一比例算高度并垂直居中**——两通道版式一致。
@@ -364,13 +364,13 @@ function isRec(v) { return !!v && typeof v === 'object' && !Array.isArray(v); }
364
364
  function soWhatBar(s, text) {
365
365
  const R = REGIONS.regionOf('exhibit', 'annotation') ||
366
366
  { x: MX, y: PT.exhibit.soWhatY, w: CW, h: 0.62 };
367
- /* MD3 结论条:衬底 + 左 accent 轨 + 正文(不绘制「SO WHAT」标签字样) */
368
- const bodyW = Math.max(2.5, R.w - 0.44);
369
- const fzB = fitFont([String(text || '')], bodyW, R.h - 0.14, { max: 14, gapFactor: 0.2, maxShrinkSteps: 3 });
367
+ /* MD3 结论条:tonal soft 满铺 + 舒适字阶;禁止左 accent 装饰轨(anti-AI-flavor) */
368
+ const padX = 0.28, padY = 0.10;
369
+ const bodyW = Math.max(2.5, R.w - padX * 2);
370
+ const fzB = fitFont([String(text || '')], bodyW, R.h - padY * 2, { max: 15, gapFactor: 0.2, maxShrinkSteps: 3 });
370
371
  s.addShape('rect', { x: R.x, y: R.y, w: R.w, h: R.h, fill: { color: STYLE.soft }, line: { type: 'none' }, objectName: trName('soWhat') });
371
- s.addShape('rect', { x: R.x, y: R.y, w: 0.06, h: R.h, fill: { color: STYLE.accent }, line: { type: 'none' } });
372
372
  s.addText(String(text || ''), {
373
- x: R.x + 0.22, y: R.y + 0.06, w: R.w - 0.44, h: R.h - 0.12,
373
+ x: R.x + padX, y: R.y + padY, w: R.w - padX * 2, h: R.h - padY * 2,
374
374
  fontFace: STYLE.font, fontSize: sz(fzB), bold: true, color: STYLE.ink, valign: 'middle',
375
375
  objectName: trName('soWhat'),
376
376
  });