@topmindspace/tms-skills 0.1.0 → 0.1.2

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 (102) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +9 -3
  3. package/bin/tms-skills.js +200 -160
  4. package/package.json +12 -9
  5. package/top-ppt-html/README.md +162 -254
  6. package/top-ppt-html/SKILL.md +126 -111
  7. package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +3926 -3926
  8. package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.model.json +167 -167
  9. package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +4325 -4325
  10. package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.model.json +320 -320
  11. package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +5527 -5527
  12. package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.model.json +913 -913
  13. package/top-ppt-html/assets/pptx-export.js +1944 -1944
  14. package/top-ppt-html/assets/style-gallery.html +589 -589
  15. package/top-ppt-html/assets/templates/architecture.html +3728 -3728
  16. package/top-ppt-html/assets/templates/engine.css +840 -840
  17. package/top-ppt-html/assets/templates/presentation.html +3738 -3738
  18. package/top-ppt-html/assets/templates/research.html +4017 -4017
  19. package/top-ppt-html/assets/templates/ui.js +520 -520
  20. package/top-ppt-html/assets/theme-overview-architecture.png +0 -0
  21. package/top-ppt-html/assets/theme-overview-research.png +0 -0
  22. package/top-ppt-html/assets/theme-overview.png +0 -0
  23. package/top-ppt-html/evals/prompts.csv +15 -15
  24. package/top-ppt-html/evals/rubric.schema.json +25 -25
  25. package/top-ppt-html/evals/run_evals.py +220 -220
  26. package/top-ppt-html/evals/trace.example.json +16 -16
  27. package/top-ppt-html/package-lock.json +186 -0
  28. package/top-ppt-html/package.json +11 -11
  29. package/top-ppt-html/references/charts-basic.md +624 -624
  30. package/top-ppt-html/references/charts-discipline.md +110 -108
  31. package/top-ppt-html/references/charts-extended.md +482 -482
  32. package/top-ppt-html/references/charts.md +37 -28
  33. package/top-ppt-html/references/components-atoms.md +624 -624
  34. package/top-ppt-html/references/components.md +30 -30
  35. package/top-ppt-html/references/content-rules.md +510 -490
  36. package/top-ppt-html/references/default-surface.md +61 -0
  37. package/top-ppt-html/references/design-system.md +478 -478
  38. package/top-ppt-html/references/failure-modes.md +227 -214
  39. package/top-ppt-html/references/high-fidelity.md +127 -127
  40. package/top-ppt-html/references/icons.md +176 -397
  41. package/top-ppt-html/references/infographics-stats.md +308 -308
  42. package/top-ppt-html/references/infographics-structure.md +226 -226
  43. package/top-ppt-html/references/infographics.md +43 -43
  44. package/top-ppt-html/references/layout-grammar.md +325 -315
  45. package/top-ppt-html/references/layouts-architecture.md +108 -108
  46. package/top-ppt-html/references/layouts-combo.md +600 -600
  47. package/top-ppt-html/references/layouts-research.md +160 -160
  48. package/top-ppt-html/references/modes.md +259 -254
  49. package/top-ppt-html/references/outline-design.md +275 -275
  50. package/top-ppt-html/references/playbook.md +284 -266
  51. package/top-ppt-html/references/pptx-export.md +227 -209
  52. package/top-ppt-html/references/presentation-craft.md +69 -0
  53. package/top-ppt-html/references/styles.md +370 -370
  54. package/top-ppt-html/references/tech-design.md +138 -138
  55. package/top-ppt-html/scripts/audit_css.py +109 -109
  56. package/top-ppt-html/scripts/audit_docs.py +176 -176
  57. package/top-ppt-html/scripts/audit_skill.py +231 -220
  58. package/top-ppt-html/scripts/audit_styles.py +351 -351
  59. package/top-ppt-html/scripts/build_examples.py +55 -2276
  60. package/top-ppt-html/scripts/build_pptx.js +2386 -2380
  61. package/top-ppt-html/scripts/capture_theme_overview.js +79 -78
  62. package/top-ppt-html/scripts/checks_html.py +166 -127
  63. package/top-ppt-html/scripts/cross_verify.py +298 -294
  64. package/top-ppt-html/scripts/env_probe.py +158 -158
  65. package/top-ppt-html/scripts/extract_model.py +210 -210
  66. package/top-ppt-html/scripts/extract_snippet.py +374 -374
  67. package/top-ppt-html/scripts/gen_channel_a.js +214 -214
  68. package/top-ppt-html/scripts/layout-constants.json +111 -18
  69. package/top-ppt-html/scripts/lib_layout_regions.js +410 -412
  70. package/top-ppt-html/scripts/measure_height.py +178 -178
  71. package/top-ppt-html/scripts/negative_tests.py +433 -307
  72. package/top-ppt-html/scripts/package_skill.py +294 -291
  73. package/top-ppt-html/scripts/prepare_images.py +341 -341
  74. package/top-ppt-html/scripts/probe_image_export.py +187 -188
  75. package/top-ppt-html/scripts/quality_gate.py +309 -301
  76. package/top-ppt-html/scripts/recommend_layout.py +384 -0
  77. package/top-ppt-html/scripts/regression.py +308 -308
  78. package/top-ppt-html/scripts/render_compare.py +275 -275
  79. package/top-ppt-html/scripts/render_from_model.py +698 -698
  80. package/top-ppt-html/scripts/scaffold_report.py +1054 -1054
  81. package/top-ppt-html/scripts/section-file-map.json +104 -104
  82. package/top-ppt-html/scripts/smoke_pptx.sh +30 -0
  83. package/top-ppt-html/scripts/sync_runtime.py +659 -662
  84. package/top-ppt-html/scripts/validate_pptx.py +1579 -1510
  85. package/top-ppt-html/scripts/validate_report.py +1755 -1456
  86. package/top-ppt-html/assets/examples/2026-09-09-architecture-spectrum.html +0 -3926
  87. package/top-ppt-html/assets/examples/2026-09-09-architecture-spectrum.model.json +0 -168
  88. package/top-ppt-html/assets/examples/2026-09-09-presentation-apple-mono.html +0 -4325
  89. package/top-ppt-html/assets/examples/2026-09-09-presentation-apple-mono.model.json +0 -321
  90. package/top-ppt-html/assets/examples/2026-09-09-presentation-brand-red.html +0 -4325
  91. package/top-ppt-html/assets/examples/2026-09-09-presentation-brand-red.model.json +0 -321
  92. package/top-ppt-html/assets/examples/2026-09-09-research-deep-teal.html +0 -5527
  93. package/top-ppt-html/assets/examples/2026-09-09-research-deep-teal.model.json +0 -914
  94. package/top-ppt-html/assets/examples/2026-09-09-research-indigo-violet.html +0 -5527
  95. package/top-ppt-html/assets/examples/2026-09-09-research-indigo-violet.model.json +0 -914
  96. package/top-ppt-html/assets/examples/2026-09-09-research-warm-sand.html +0 -5527
  97. package/top-ppt-html/assets/examples/2026-09-09-research-warm-sand.model.json +0 -914
  98. package/top-ppt-html/assets/theme-overview-presentation.png +0 -0
  99. package/top-ppt-html/references/design-system-engine.md +0 -235
  100. package/top-ppt-html/references/industry-benchmark.md +0 -105
  101. package/top-ppt-html/references/reform-plan.md +0 -252
  102. package/top-ppt-html/scripts/layout_slots.json +0 -830
@@ -1,235 +0,0 @@
1
- # 设计系统 · 引擎 CSS 实现目录(维护者 / 深挖时读)
2
-
3
- > 顶栏 / 卡片 / 列表 / 表格 / 章节头 / 页脚 / Agenda / 动效等**类实现细节**。
4
- > 生成报告请用 `components-atoms.md` / `layouts-*.md` 的写法;本文件对应
5
- > `assets/templates/engine.css` 注入源,改 CSS 后必跑 `sync_runtime.py`。
6
- > **禁止**把本文件当生成时的默认阅读对象。
7
-
8
- ## 5. 顶栏 + 主题切换
9
-
10
- ```css
11
- .bar{position:sticky;top:0;z-index:50;height:var(--bar-h);
12
- background:color-mix(in srgb,var(--bg) 86%,transparent);
13
- backdrop-filter:saturate(160%) blur(14px);-webkit-backdrop-filter:saturate(160%) blur(14px);
14
- border-bottom:1px solid var(--border-soft)}
15
- .bar__in{height:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4)}
16
- .brand{display:flex;align-items:center;gap:var(--sp-3);min-width:0}
17
- .brand__mark{width:34px;height:34px;flex:none;border-radius:10px;background:var(--accent);
18
- color:var(--accent-on);display:grid;place-items:center;font-size:13px;font-weight:700}
19
- .brand__title{font-size:var(--fs-sm);font-weight:600;color:var(--text);
20
- white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
21
- .brand__sub{font-size:var(--fs-xs);color:var(--text-3);
22
- white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
23
- .nav{display:flex;align-items:center;gap:var(--sp-1)}
24
- .nav a{padding:8px 14px;border-radius:var(--r-full);color:var(--text-2);text-decoration:none;
25
- font-size:var(--fs-sm);font-weight:500;white-space:nowrap;transition:background-color .18s,color .18s}
26
- .nav a:hover{background:var(--surface-2);color:var(--text)}
27
- @media (max-width:1120px){.nav{display:none}}
28
- .iconbtn{width:40px;height:40px;flex:none;display:grid;place-items:center;
29
- border:1px solid var(--border);border-radius:var(--r-full);background:transparent;
30
- color:var(--text-2);cursor:pointer;transition:background-color .18s,color .18s}
31
- .iconbtn:hover{background:var(--surface-2);color:var(--text)}
32
- .iconbtn svg{width:19px;height:19px}
33
- .icon-sun,.icon-moon{display:none}
34
- html[data-theme="light"] .icon-moon{display:block}
35
- html[data-theme="dark"] .icon-sun{display:block}
36
- ```
37
-
38
- ## 6. 卡片 / 按钮 / 徽标 / 指标卡
39
-
40
- ```css
41
- .card{background:var(--surface);border:1px solid var(--border-soft);border-radius:var(--r-lg);
42
- padding:clamp(20px,2vw,30px);transition:border-color .2s,box-shadow .2s,background-color .28s}
43
- .card:hover{border-color:var(--border);box-shadow:var(--shadow-1)}
44
- .card--flat{background:var(--surface-1);border-color:transparent}
45
- .card--flat:hover{background:var(--surface-2)}
46
- .card--accent{background:var(--accent-soft);border-color:transparent}
47
- .card__hd{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3)}
48
- .card__ico{width:34px;height:34px;flex:none;border-radius:10px;background:var(--accent-soft);
49
- color:var(--accent-text);display:grid;place-items:center}
50
- .card__ico svg{width:18px;height:18px}
51
-
52
- .btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:48px;
53
- padding-inline:26px;border-radius:var(--r-full);font-size:var(--fs-sm);font-weight:500;
54
- text-decoration:none;cursor:pointer;white-space:nowrap;border:1px solid transparent;
55
- transition:background-color .2s,box-shadow .2s,transform .2s}
56
- .btn:hover{transform:translateY(-1px)}
57
- .btn--primary{background:var(--accent);color:var(--accent-on)}
58
- .btn--primary:hover{box-shadow:var(--shadow-2)}
59
- .btn--soft{background:var(--accent-soft);color:var(--accent-text)}
60
- .btn--ghost{background:transparent;color:var(--text);border-color:var(--border)}
61
- .btn--onDark{background:var(--surface);color:var(--text)}
62
-
63
- .chip{display:inline-flex;align-items:center;gap:6px;height:30px;padding-inline:13px;
64
- border-radius:var(--r-full);background:var(--surface-2);color:var(--text-2);
65
- font-size:var(--fs-xs);font-weight:500;white-space:nowrap}
66
- .chip--accent{background:var(--accent-soft);color:var(--accent-text)}
67
- .chip--line{background:transparent;border:1px solid var(--border);color:var(--text-2)}
68
-
69
- .metric{background:var(--surface);border:1px solid var(--border-soft);border-radius:var(--r-lg);
70
- padding:clamp(18px,1.7vw,26px);display:flex;flex-direction:column;gap:var(--sp-2)}
71
- .metric:hover{border-color:var(--border);box-shadow:var(--shadow-1)}
72
- .metric__v{display:flex;align-items:baseline;gap:4px;color:var(--text)}
73
- .metric__v small{font-size:.42em;font-weight:500;letter-spacing:0;color:var(--text-3)}
74
- .metric__k{font-size:var(--fs-sm);color:var(--text-2);font-weight:500}
75
- .metric__n{font-size:var(--fs-xs);color:var(--text-3);line-height:1.5}
76
- .metric--warn .metric__v{color:var(--accent)}
77
- ```
78
-
79
- ## 7. 列表(含流程箭头 / 对勾 / 序号)
80
-
81
- ```css
82
- .ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-4)}
83
- .ul li{position:relative;padding-left:30px;color:var(--text-2);font-size:var(--fs-body);line-height:1.65}
84
- .ul li::before{content:"";position:absolute;left:0;top:.52em;width:7px;height:7px;
85
- border-radius:50%;background:var(--accent)}
86
- .ul li strong{color:var(--text);font-weight:600}
87
- .ul--flow li::before{content:"→";width:auto;height:auto;background:none;color:var(--accent);
88
- font-weight:700;top:0;left:0}
89
- .ul--check li::before{width:18px;height:18px;top:.18em;background:var(--accent-soft);
90
- color:var(--accent-text);content:"✓";font-size:11px;font-weight:700;display:grid;place-items:center}
91
- .ul--num{counter-reset:n}.ul--num li{padding-left:34px;counter-increment:n}
92
- .ul--num li::before{content:counter(n);width:22px;height:22px;top:.06em;border-radius:50%;
93
- background:var(--accent-soft);color:var(--accent-text);font-size:11px;font-weight:700;
94
- display:grid;place-items:center}
95
- ```
96
-
97
- ## 8. 表格 / 引言 / 时间线 / 图示
98
-
99
- ```css
100
- .tbl-wrap{border:1px solid var(--border-soft);border-radius:var(--r-lg);overflow:hidden;
101
- background:var(--surface);overflow-x:auto}
102
- table{width:100%;border-collapse:collapse;min-width:min(720px,100%)}
103
- thead th{background:var(--surface-1);color:var(--text-2);font-size:var(--fs-xs);font-weight:600;
104
- letter-spacing:.04em;text-transform:uppercase;text-align:left;padding:15px 20px;
105
- border-bottom:1px solid var(--border);white-space:nowrap}
106
- tbody td{padding:17px 20px;border-bottom:1px solid var(--border-soft);font-size:var(--fs-sm);
107
- color:var(--text-2);vertical-align:top;line-height:1.6}
108
- tbody tr:last-child td{border-bottom:none}
109
- tbody tr:hover{background:var(--surface-1)}
110
- td strong{color:var(--text);font-weight:600}
111
- td.k{color:var(--text);font-weight:500;white-space:nowrap}
112
- td.num{font-variant-numeric:tabular-nums}
113
-
114
- .note{display:flex;gap:var(--sp-4);padding:clamp(20px,2vw,28px);border-radius:var(--r-lg);
115
- background:var(--accent-soft);border-left:3px solid var(--accent)}
116
- .note__ico{width:26px;height:26px;flex:none;border-radius:50%;background:var(--accent);
117
- color:var(--accent-on);display:grid;place-items:center;font-size:13px;font-weight:700;font-style:normal}
118
- .note__t{font-size:var(--fs-h3);font-weight:600;color:var(--text);margin-bottom:6px}
119
-
120
- .tl{position:relative;padding-left:30px}
121
- .tl::before{content:"";position:absolute;left:7px;top:10px;bottom:10px;width:2px;
122
- background:var(--border);border-radius:2px}
123
- .tl__i{position:relative;padding-bottom:var(--sp-6)}
124
- .tl__i:last-child{padding-bottom:0}
125
- .tl__d{position:absolute;left:-30px;top:5px;width:16px;height:16px;border-radius:50%;
126
- background:var(--surface);border:3px solid var(--border)}
127
- .tl__i--now .tl__d{border-color:var(--accent);background:var(--accent)}
128
- .tl__i--done .tl__d{border-color:var(--accent)}
129
- .tl__t{font-size:var(--fs-h3);font-weight:600;color:var(--text);margin-bottom:6px}
130
- .tl__l{font-size:var(--fs-xs);font-weight:700;letter-spacing:.08em;text-transform:uppercase;
131
- color:var(--accent-text);margin-bottom:2px}
132
-
133
- .fig{background:var(--surface);border:1px solid var(--border-soft);border-radius:var(--r-xl);
134
- padding:clamp(20px,2.2vw,36px);overflow:hidden}
135
- .fig__cap{text-align:center;margin-bottom:var(--sp-4);font-size:var(--fs-sm);
136
- color:var(--text-3);font-weight:500}
137
- .fig svg{display:block;width:100%;height:auto}
138
- ```
139
-
140
- ## 10. 章节头 / 页脚 / 动效 / 打印
141
-
142
- ```css
143
- .shead{margin-bottom:clamp(28px,3.4vh,48px);max-width:940px}
144
- .shead__title{margin-block:var(--sp-3) var(--sp-4)}
145
- .shead__desc{max-width:900px}
146
- .shead--center{margin-inline:auto;text-align:center}
147
- .shead--center .shead__desc{margin-inline:auto}
148
- .band--deep .t-lead,.band--deep .t-body{color:var(--deep-fg-2)}
149
- .band--deep .t-eyebrow{color:color-mix(in srgb,var(--accent) 40%,#fff)}
150
-
151
- .foot{padding-block:clamp(40px,5vh,64px);border-top:1px solid var(--border-soft);
152
- background:var(--surface-1)}
153
- .foot__in{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-5);flex-wrap:wrap}
154
-
155
- @media (prefers-reduced-motion:no-preference){.rv{opacity:0;transform:translateY(14px)}
156
- .rv.in{opacity:1;transform:none;transition:opacity var(--dur-long) var(--ease-emphasized),
157
- transform var(--dur-long) var(--ease-emphasized)}}
158
- @media (prefers-reduced-motion:reduce){.rv{opacity:1;transform:none}html{scroll-behavior:auto}}
159
- @media print{.rv{opacity:1!important;transform:none!important}
160
- .band{padding-block:24px;break-inside:avoid}body{background:#fff;color:#000}
161
- .pager{display:none!important}}
162
- ```
163
-
164
- ## 11. PPT 翻页导航(页码指示)
165
-
166
- 右侧固定页码圆点 + 计数,点击跳转;方向键翻页由公共 UI 脚本(`assets/templates/ui.js`,注入各模板)驱动。
167
-
168
- ```css
169
- /* 页码指示(固定右侧) */
170
- .pager{position:fixed;right:clamp(10px,1.6vw,26px);top:50%;transform:translateY(-50%);
171
- z-index:60;display:flex;flex-direction:column;align-items:center;gap:10px}
172
- .pager__count{font-size:var(--fs-xs);font-weight:600;color:var(--text-3);
173
- font-variant-numeric:tabular-nums;letter-spacing:.04em}
174
- .pager__dots{display:flex;flex-direction:column;gap:8px}
175
- .pager__dot{width:9px;height:9px;border-radius:50%;border:1px solid var(--border);
176
- background:transparent;cursor:pointer;padding:0;transition:background-color .2s,transform .2s,border-color .2s}
177
- .pager__dot:hover{transform:scale(1.3);border-color:var(--accent)}
178
- .pager__dot.on{background:var(--accent);border-color:var(--accent);transform:scale(1.25)}
179
- @media (max-width:760px){.pager{right:6px;gap:6px}.pager__dot{width:7px;height:7px}}
180
- @media (prefers-reduced-motion:reduce){.pager__dot{transition:none}}
181
- ```
182
-
183
- > 结构:`<aside class="pager"><div class="pager__count">3 / 10</div><div class="pager__dots">…每页一个 .pager__dot…</div></aside>`,由脚本生成。
184
-
185
- ## 12. Agenda 大纲页(第二页)
186
-
187
- 首页后必须是 Agenda。大编号 + 标题 + 一句话说明,整行可点击跳转。
188
-
189
- ```css
190
- .agenda{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
191
- .agenda__i{border-top:1px solid var(--border-soft)}
192
- .agenda__i:last-child{border-bottom:1px solid var(--border-soft)}
193
- .agenda__a{display:grid;grid-template-columns:auto 1fr auto;align-items:center;
194
- gap:clamp(16px,2.4vw,36px);padding:clamp(18px,2.2vh,26px) clamp(4px,.6vw,12px);
195
- text-decoration:none;color:inherit;transition:background-color .18s}
196
- .agenda__a:hover{background:var(--surface-1)}
197
- .agenda__n{font-size:clamp(1.4rem,2vw,1.9rem);font-weight:var(--fw-display);
198
- color:var(--accent);font-variant-numeric:tabular-nums;line-height:1;min-width:2.2em}
199
- .agenda__t{font-size:var(--fs-h3);font-weight:var(--fw-title);color:var(--text);margin-bottom:3px}
200
- .agenda__d{font-size:var(--fs-sm);color:var(--text-3)}
201
- .agenda__go{color:var(--text-3);transition:color .18s,transform .18s}
202
- .agenda__a:hover .agenda__go{color:var(--accent);transform:translateX(4px)}
203
- .agenda__go svg{width:20px;height:20px;display:block}
204
- ```
205
-
206
- > 结构:`<ol class="agenda"><li class="agenda__i"><a class="agenda__a" href="#why"><span class="agenda__n">01</span><span><span class="agenda__t">周期意义</span><span class="agenda__d">治理为何进入智能增长周期</span></span><span class="agenda__go">→</span></a></li>…</ol>`
207
-
208
- ## 13. 图表尺寸与优雅规范
209
-
210
- > 丰富但克制:一屏 1–2 个图,图表服务数据,不堆砌。
211
- > 完整图表代码(含漏斗/甘特/散点/瀑布/双向条形/多段环形)见 `components.md` 第二部分;尺寸下限的**硬约束与校验规则**见 `components.md` 第 35 节(校验脚本按 `data-chart` 类型核对)。
212
-
213
- | 图表 | 用途 | 建议高度 / 占比 |
214
- |------|------|----------------|
215
- | 环形/仪表盘 | 占比、达成度 | 直径 140–180px,配中心大数字 |
216
- | 柱状图 | 分阶段目标、对比 | 高 200–240px,柱圆角 5–6px |
217
- | 横向条形 / 棒棒糖 | 排名、覆盖率 | 行高 28–34px,条圆角 |
218
- | 折线/面积 | 时间趋势 | 高 200–240px,面积用 `fill-opacity:.12` 的 accent |
219
- | 斜率图 | 两期升降(谁升谁降) | 高 180–220px,两端都标数值 |
220
- | 雷达图 / 玫瑰图 | 多维能力 | 直径 220–260 / 180–220px,≤ 6 维 |
221
- | 堆叠条 / 马赛克图 | 构成(马赛克含规模维度) | 条高 24–32px;马赛克高 160–200px |
222
- | 瀑布图 | 增减归因 | 高 200–230px |
223
- | 漏斗图 / 桑基图 | 转化、流向归因 | 高 200–240px,≤ 5 层 / ≤ 8 带 |
224
- | 甘特图 | 计划排期 | 高 160–200px |
225
- | 散点/气泡 | 双维分布 | 高 220–260px |
226
- | 哑铃图 | 前后 / 两地对比 | 高 160–200px,行高 34–38px |
227
- | 子弹图 | 目标 vs 实际(含区间) | 高 140–180px,行高 32–36px |
228
- | 点图 | 分布 / 离散度 | 高 120–160px,行高 28px |
229
-
230
- **通用**:图表标签 `.f-txt3`(弱化),数值 `.f-txt` 加粗(突出);网格线 `.s-bds` 细线;数据系列用 `f-acc`(强调)+ `f-s3`(次要),多系列时同族明度递减、**不引入第二色相**。图与图之间留白 ≥ `--sp-6`。
231
- **信息量纪律**:系列 >5 合并"其他";类别 >8 取 Top 7 + 附录密表;时间点 >8 改折线/按季聚合;一屏一图一重心。完整规则见 `components.md` `charts.md` §64。
232
-
233
- ## 14. 主题切换 + 翻页脚本(与风格无关)
234
-
235
- 见任一模式模板(`assets/templates/*.html`)底部注入的公共 UI 脚本(源文件 `assets/templates/ui.js`,由 `sync_runtime.py` 注入),含主题切换、滚动显现、方向键翻页、页码指示生成。
@@ -1,105 +0,0 @@
1
- # 业界对标与设计决策
2
-
3
- 四大主流 PPT/报告技能的调研结论 → TopPPT HTML 的采纳/改造/不采用决策。生成报告前不必读本文档;**改动导出机制、版式体系或校验体系前必读**(防止无依据地破坏既有决策)。
4
-
5
- ## 对标结论速览
6
-
7
- | 技能 | 路线 | 核心机制 | TopPPT HTML 取舍 |
8
- |------|------|---------|----------|
9
- | CyberPPT(sdarpeng) | 原生 PPTX · 咨询级 | 三阶段流程(分析→蓝图→混合还原)、组件签名锁定、渲染回归、15 级排版比例尺、双硬门槛 | **大量采纳**(改造) |
10
- | guizang(op7418) | 单文件 HTML | 双视觉系统、22 锁定版式、颜色预设制、Node+Playwright 量化校验、演讲者模式 | 版式纪律采纳;颜色锁死不采纳 |
11
- | 花叔 huashu(alchaincyf) | HTML 设计系统 → PPTX | 内容结构化→设计选型(9 风格)→AI 插画→组装;20 设计哲学 + 5 维评审 | 内容结构化先行已内建 |
12
- | PPT Master(hugohe3) | 原生 PPTX | 方案先行确认、SVG 中间态、本地预览服务、断点恢复 | 断点恢复采纳;SVG 中间态不采纳 |
13
- | McKinsey/BCG 咨询材料实践 | 咨询机构 deck | 行动标题、金字塔论证(发现→证据→含义)、Exhibit 编号体系、密排高信息密度 | **研究模式全面对齐**(R1–R8 版式 + 密排比例尺) |
14
-
15
- ## 采纳明细(落到了哪里)
16
-
17
- | 借鉴点 | 来源 | TopPPT HTML 落地位置 |
18
- |--------|------|--------------|
19
- | 排版比例尺(C0 封面→T14 注释,15 级) | CyberPPT | `scripts/layout-constants.json` `typeScale`(基准 8 级)+ **`modeTypeScale` 三模式独立取值**(research 咨询密排:正文 10.5pt) |
20
- | 页型 = 锁定版式(不允许临场发明结构) | CyberPPT / guizang | `components.md` §36d–36f(research R1–R8)/ `components.md` §37–38b(arch A1–A3)+ pptx-export.md 页型表 |
21
- | 双硬门槛(可编辑 + 保真,pictures=0 是结果不是目标) | CyberPPT | `validate_pptx.py`(原生形状/字号下限/覆盖率)+ 铁律 16 |
22
- | 模型完整性校验前移 | CyberPPT | `validateModel`(预览端三态校验)+ `extract_model.py` 一致性抽查 + `validate_report.py` 模型一致性检查 |
23
- | 版式常量同源(防两通道漂移) | CyberPPT(组件签名)的轻量化 | `layout-constants.json` + `sync_runtime.py` 单源注入(三模板引擎/UI/运行时三类片段注入) |
24
- | 量化溢出检测(字号×行高×字数 vs 版心预算,无需浏览器) | guizang(Playwright 真实渲染) | `validate_report.py` 溢出估算(静态近似,零依赖,三模式独立预算) |
25
- | 页面方案先行确认(比 PPT Master 更轻) | PPT Master | 单次交互三项默认推荐(模式/风格/篇幅) |
26
- | 断点可恢复(REPORT_MODEL = 恢复锚点) | PPT Master | 重跑 extract → build 即恢复,无需重新生成 |
27
- | 内容结构化先行、设计选型 | 花叔 | 意图→模式/风格/篇幅默认推荐表(SKILL.md) |
28
- | WYSIWYG 预览(导出所见) | —(自研,回应"保真复刻"诉求) | header 预览模态:`slidesXml`(与导出同一序列化输出)→ DOMParser → 16:9 缩略 |
29
- | **行动标题 + 金字塔论证 + Exhibit 编号 + so-what** | McKinsey/BCG 咨询 deck 实践 | research 模式铁律 8/13 + R1/R2 版式 + `validate_report.py` 行动标题/Exhibit 连续性检查 |
30
- | **密排高信息密度(每页一个完整论证,不是每屏一个口号)** | 咨询材料"坐读"传统 | research 密度层(1240 版心/14–15px 正文/16 行密表)+ 密排比例尺(PPTX 正文 10.5pt)+ 单页预算 3200 字 |
31
- | **帮助即文档(in-product guidance)** | MD3 对话式设计 / 现代 SaaS onboarding | header「?」PPT 生成指引弹窗:双通道说明 + 可复制提示词 |
32
-
33
- ## 明确不采用(及原因)
34
-
35
- | 机制 | 来源 | 不采用原因 |
36
- |------|------|-----------|
37
- | AI 位图蓝图 / ImageGen 逐页蓝图 | CyberPPT | 环境依赖重;TopPPT HTML 以"锁定版式 + CSS token + 常量单源"达成同等的版式可复现性,且保住 `pictures=0` 可编辑性 |
38
- | 渲染回归(PowerPoint COM 导 PNG 对照)作为硬门禁 | CyberPPT | 需本机 PowerPoint;降级为**可选路径 C**(`pptx-export.md`),日常由通道 A 预览模态覆盖 WYSIWYG 对照 |
39
- | 颜色完全锁死(用户不可自定义) | guizang | 保留预设风格制(9 套)+ 工具栏实时切换(切换仅影响预览与导出风格,交付一致性由校验器把关) |
40
- | SVG 中间态逐页生成 | PPT Master | 双通道模型驱动更直接;SVG 中间态增加一次格式转换损耗 |
41
- | AI 插画配图 | 花叔 | 违反单文件零外链铁律;图形一律内联 SVG |
42
-
43
- ## 开源复用清单(不重复造轮子)
44
-
45
- | 能力 | 复用的业界开源成果 | 形态 |
46
- |------|------------------|------|
47
- | PPTX 生成引擎(通道 B) | **pptxgenjs**(业界标准,CyberPPT 唯一许可引擎同款) | npm 依赖(技能目录 `npm install pptxgenjs` 或指向已有 node_modules) |
48
- | PPTX 质检器 | **cyber-ppt 的 validate_pptx**(strict 硬门禁、越界/字号/密度/占位检查) | 已内置 `scripts/validate_pptx.py`(纯标准库改写) |
49
- | 排版比例尺 | **CyberPPT 15 级 Typography Scale** | 收敛为 8 级进 `layout-constants.json` |
50
- | 版式纪律 | **guizang 锁定版式**(不允许临时发明结构) | `components.md` R1–R8 / A1–A3 锁定版式表 |
51
- | 咨询论证结构(行动标题/Exhibit/so-what/密排) | **McKinsey/BCG 公开方法论**(金字塔原理、slide-by-slide 论证) | research 模式全套规则(`modes.md`「模式 B · 研究报告」) |
52
- | **第三方裁判交叉验证(防止自研栈自说自话)** | **python-pptx**(开源标准解析器) | `scripts/cross_verify.py`:A/B 双通道产物均经 python-pptx 严格解析 + 逐页文本一致性比对(实测抓出 rels 路径与 `a:graphic` 前缀两处 OOXML 规范缺陷——PowerPoint 宽容掩盖、严格解析器暴露) |
53
- | **check-overflow 溢出启发式** | **grapeot/pptx.skill**(AI-first pptx 检查库) | cross_verify 内置:文本估宽(CJK 1em/ASCII .55em)vs shape 宽×可容行数,18% 容差 |
54
- | **WCAG 对比度审计** | WCAG 2.1 AA + MD3 颜色角色 | `scripts/audit_styles.py`:9 风格 × light/dark × 8 组配对自动核查(实测修复 spectrum/warm-sand 按钮对比度) |
55
- | **原生图表(addChart 数据可编辑)** | PptxGenJS Charts | **已采纳**:交付通道 B 的带数据图表一律走 `addChart` → 真 chart part + 内嵌 Excel 工作簿(双击可"编辑数据"),并列为 `MODEL_CHART_COUNT` 硬门禁;A 通道(浏览器预览/回归双裁判)保留形状近似渲染,两者逐页文本由 `cross_verify.py` 保证一致 |
56
- | 设计系统 | **Material Design 3**(m3.material.io) | `design-system.md` §1b 对齐映射 |
57
- | 渲染回归(可选) | cyber-ppt `export_ppt_render.ps1`(PowerPoint COM)→ **开源替代:LibreOffice headless**(soffice --convert-to pdf,grapeot/pptx.skill 同路线,保真度约 85%) | 可选路径 C,不做硬门禁;本机未装 LibreOffice 时跳过 |
58
-
59
- **为何手写预览运行时而非内嵌 pptxgenjs**:pptxgenjs 浏览器版约 700KB(含 JSZip),内嵌进每份单文件报告体积不可接受;手写运行时约 120KB(OOXML 序列化,只做 WYSIWYG 预览与回归双裁判),且与交付通道 B 消费同一份 `layout-constants.json` 常量单源——**复用的是"引擎与规范",自研的只是"轻量序列化轮毂"**,两者产出经同一 `validate_pptx.py --strict` 验证一致(0/0)。
60
-
61
- ## TopPPT HTML 的差异化立场
62
-
63
- 1. **一套模型、两通道、一常量源**:`REPORT_MODEL` 是唯一事实源;预览端是真正的 OOXML 序列化器(不是截图、不是粗糙转换),与交付通道共用同一序列化语义与常量单源。
64
- 2. **页面仅预览、交付走精导**:页面提供 WYSIWYG 预览 + 可复制提示词(引导回 AI 对话生成);正式 PPTX 由智能体精导通道产出并过 strict 硬门禁(浏览器端跑不了门禁,不承担交付)。
65
- 3. **预览即交付所见**:预览模态渲染的就是交付同一序列化语义产出的 slide XML,不是另一套模拟。
66
- 4. **锁定版式纪律贯穿 HTML 与 PPTX**:research R1–R8 / arch A1–A3 与页型一一成对,新增版式必须"先扩表(含 PPTX 页型与 layout-constants.json 页型几何)、再使用"。
67
- 5. **三模式独立成体系**:模式不是切换关系而是三种输出形态——独立模板/密度/组件/预算/比例尺;咨询密排(R1–R8)与全幅图(A1–A3)各自对标业界最优实践(McKinsey deck / 架构图评审材料),而非同一骨架的参数缩放。
68
- 6. **双裁判验证(不止一个裁判)**:自研 `validate_pptx.py --strict` 之外,产物再经开源 python-pptx 严格解析与逐页文本比对(`scripts/cross_verify.py`)——自研校验器与手写序列化器同源,存在"自己验自己"盲区;正是靠第三方裁判抓出两处 OOXML 规范缺陷(`ppt/_rels/presentation.xml.rels` 路径、`a:graphic` 命名空间前缀)后才真正达成双通道保真。**改导出/预览运行时后必跑 cross_verify。**
69
-
70
- ---
71
-
72
- ## 深度对标(业界调研)
73
-
74
- **调研对象**:CyberPPT(sdarpeng,Codex Skill,SKILL.md 约 78KB)、ppt-master(Categorytyy)、ppt-agent-skill(Akxan,148★)、ppt-skill(Cyberceratops)。
75
-
76
- ### 采纳明细(落到了哪里)
77
-
78
- | 借鉴点 | 来源 | 落地位置 |
79
- |--------|------|--------------|
80
- | **图表通道分层 + 数据可追溯** | CyberPPT 的「可编辑信息层」门 | `charts.registry` 四元组(html / pptx 通道 / nativeType 或 path 约束 / dataTable);原生 16 类走 `addChart`,形状通道**强制附数据表**(`MODEL_CHART_DATATABLE`) |
81
- | **曲线/异形精确还原规则** | CyberPPT「曲线精确追踪门」 | 改造为**可复现常量约束**:采样点 ≥16(流带 ≥24)、双边界分别追踪、禁用 preset shape 替代 → `charts.registry[type].path` + `build_pptx.js ribbonRects` + `infographics.md` |
82
- | **容器边界溢出(按归属容器判定)** | CyberPPT「容器溢出门」 | `validate_pptx.py` `CONTAINER_OVERFLOW`(扣容器内边距,比页面级更严格)+ `containers.pad` 常量 |
83
- | **表格语义字号 / 表格密度** | CyberPPT「表格语义字号门」 | `TABLE_SEMANTIC_TYPE`(句子型内容禁 micro 档)+ `TABLE_DENSITY`(大面积空洞即失败)+ `design-system.md` §1f 语义字阶 C0–T14 |
84
- | **连续文本流(禁拆文本框)** | CyberPPT「连续文本流门」 | `CONTINUOUS_TEXT_FLOW`(深度模式)+ `content-rules.md` §四-f 写作纪律 |
85
- | **空间锚点注册** | CyberPPT「空间锚点门」(中心偏差 ≤2%、关键锚点 ≤6px) | `anchorTolerance` 常量 + `ANCHOR_TITLE_MISALIGNED`(页头标题对齐版心)+ manifest `anchors` 登记 + 人眼对照清单 P0/P1/P2 分级 |
86
- | **固定语义字阶** | CyberPPT `C0`/`T1–T14` 15 级 | `typography.levels`(15 级,role 指向 `modeTypeScale`,不重复存 pt) |
87
- | **设计原理注入** | ppt-master 的 14 本文献映射(CRAP / 7:2:1 / 字体决策矩阵) | `design-system.md` §1a(四条可自检准则) |
88
- | **12 列网格 + 安全边距** | ppt-master 的 `MARGIN` / `GRID` 常量 | `layout-constants.json` `grid`(13 条列轨 + 6 条行基线 + `safe`)+ `design-system.md` §1e |
89
- | **风格集 + 每风格 JSON 定义 + 画廊** | 业界常见 20+ 风格 | 风格 **9 套**(8 色族 + 1 彩色数据板),`styles`+`stylesDark`+`styleAccents`+`styleDataColors` 同源 + 画廊 + 参考图。**不追数量**:同色族换名的冗余已删;新增门槛见 `styles.md` §10 |
90
- | **SCR 论证 + 证据可追溯 + 多故事线脑暴** | CyberPPT 三阶段(证据表 → 脑暴 → SCR) | `outline-design.md` 七步法:② 证据表(MBB 字段 + 冲突不静默归一)③ 故事线脑暴(2–3 条 + issue tree / hypothesis tree)④ SCR 收敛 + 主张树 |
91
- | **跨页叙事节奏** | ppt-agent-skill(密度交替 / 章节递进 / 首尾呼应 / 渐进揭示) | `outline-design.md` §一-续(含 5 条节奏回查清单) |
92
- | **失败模式库 + 修复顺序** | ppt-agent-skill 的 8 failure modes | `failure-modes.md`(十四类模式 + 修复顺序铁律 + 错误解释纠正表) |
93
- | **数据表随行(可追溯)** | CyberPPT「数据表 / 证据 ID」 | `chart.dataTable` 三态(notes / inline / off)+ `inline` 在图表下方附原生表格(双通道同渲染) |
94
- | **PowerPoint 兼容门(打开 + 导 PNG)** | CyberPPT | 降级为**可选深度模式** `render_compare.py`(soffice 渲染 + 并排对照 + 偏差登记),缺失依赖自动跳过 |
95
-
96
- ### 明确不采纳(及原因)
97
-
98
- | 机制 | 来源 | 不采纳原因 |
99
- |------|------|-----------|
100
- | ImageGen 逐页蓝图(生成 16:9 位图再逐页还原) | CyberPPT 第二阶段 | 环境依赖重;与「单文件零外链 + `pictures=0` 默认」冲突。本技能以「锁定版式 + 常量单源 + 形状还原规则」达成同等可复现性 |
101
- | SHA-256 冻结签名 + 逐页人工验收确认 | CyberPPT | 交互轮次与耗时显著增加,与「一次问询 + 自动生成 + 校验闭环」定位冲突;改为 manifest 登记(可复现、无需冻结) |
102
- | 禁止 `python-pptx`(必须只用 pptxgenjs) | CyberPPT 生成工具门 | 本技能用 pptxgenjs **生成**、用 python-pptx 做**第三方裁判**——职责分离比"单一引擎"更能暴露问题(实测抓出两处 OOXML 缺陷) |
103
- | 联网检索素材脚本 | ppt-skill / ppt-agent-skill | 越出「报告生成」边界;外部数据由用户提供或对话中检索,来源须可追溯(`[n]` + 参考资料) |
104
- | HTML→SVG→PPTX 三段式管线 | ppt-skill / ppt-agent-skill | 增加一次格式转换损耗;本技能的双通道模型(同一 `REPORT_MODEL` → 原生形状 + 原生图表)保真度更高且保住数据可编辑 |
105
- | 允许 `pictures>0` 承载复杂视觉 | CyberPPT 混合还原 | 本技能默认 `pictures=0` 全原生可编辑;复杂信息图改用**形状/SVG 精确还原 + 数据表**达成同等视觉语义(且数据仍可核对) |
@@ -1,252 +0,0 @@
1
- # 整体整改方案(质量 · 性能 · 可靠)
2
-
3
- > **何时读**:改技能架构、门禁、图表选型、图文版式、导出链路前必读。
4
- > **定位**:质量整改方案——诊断根因、收敛复杂度、重建门禁、布局语法、演讲向图文模式、模型单写。
5
- > **状态**:P0/P1 已落地并随 **0.1.0** 发布;P2 见文末。
6
- > **原则**:先保决策信息,再谈美观;门禁抓真缺陷,不为过检堆规则;单源可验证,双写可收敛。
7
-
8
- ---
9
-
10
- ## 〇、问题现象 ↔ 根因对照
11
-
12
- | 现象(用户截图) | 直接原因 | 系统根因 |
13
- |-----------------|---------|---------|
14
- | 正文出现 `<a class="cite">…</a>` 字面量 | 填内容时把 HTML 源码当纯文本写入 | **双写无净化**:HTML 正文与 `REPORT_MODEL` 各自维护,模型字段未禁止标签;校验只匹配「正确 markup」,不拦「标签泄漏」 |
15
- | 除标题外大面积空白 | 页高模型强制 `min-height:100vh` + 内容不足 | **过空页仅 WARN**;`empty` 阈值 80–120 字过松;组合版式只强制 research |
16
- | 文字输出不全 / 截断 | `fitFont` 触底后仍裁切;模型-正文只对标题 | **保真阈值 50%**(`hits*2 < probes`)放行半页缺失;正文长度不校验 |
17
- | 环图标签叠字(0.5 / 0%) | 手写 SVG 标签框过窄换行;或 0.5% 与百分比串叠放 | **绕过锁定组件**:自由 SVG 无标签盒/避让规则;极小扇区仍用 donut |
18
- | 简单图占一整页「大图」 | presentation 契约写「1 张大图」;`minSize` 只有下限 | **设定错误**:无「信息复杂度 ↔ 面积」上限;`imageAdmission` 是死配置 |
19
- | 架构/流程图难看 | PPTX `diagram` 只有等高层带 + 小矩形连接件 | **结构图退化**:无真边/正交路由/菱形判断;A3 管线被压成单泳道 |
20
- | HTML 略好但仍有问题 | 同一套填内容习惯 + 同一套门禁假过 | 双通道同源缺陷,HTML 只是 CSS 稍好掩盖了结构问题 |
21
-
22
- **一句话诊断**:**基本设定过宽 + 双写失控 + 门禁假过 + 过度工程化导致填内容时绕过组件**。不是「再加几条校验」能了事,需要收敛复杂度并重建质量底线。
23
-
24
- ---
25
-
26
- ## 一、基本设定哪里不对
27
-
28
- ### 1.1 演示模式「1 张大图」是错误默认
29
-
30
- | 原设定 | 问题 | 新设定 |
31
- |--------|------|--------|
32
- | presentation 每页 1 张大图 | 简单 2 类占比也被做成整页 donut | **按信息复杂度定面积**:≤2 类且极偏 → KPI 大数;3–5 类中等 → 图 + 注解带;复杂结构才全幅 |
33
- | `charts.minSize` 只有下限 | 图可以无限大,与内容量脱钩 | 增加 **`charts.sizeByComplexity`**:数据点/类别数决定推荐区间,超出上/下限 WARN→FAIL |
34
- | 全幅图页 `fig--full` 随手可用 | 「简单图放大」合法化 | 全幅仅允许:架构总览 / ≥8 节点结构 / ≥8 系列趋势 / 用户指定素材大图 |
35
-
36
- ### 1.2 图文模式缺「演讲构图」契约
37
-
38
- 现有 `image` 页型只有六版式(full/half/bleed/grid/compare/wall),**没有演讲向的「主视觉 + 口头注解」节奏**。新增 **图文演讲版式(V1–V4)**,见 §四。
39
-
40
- ### 1.3 内容双写没有唯一事实源
41
-
42
- - HTML 正文手写 + `REPORT_MODEL` 手写 → 必然漂移(标签泄漏、空页、截断的温床)。
43
- - **v9 方向**:`REPORT_MODEL` 为内容唯一源;HTML 由「锁定组件 + 模型字段」填充,禁止把 HTML 标签写进模型字符串字段。
44
- - **过渡(本版立即执行)**:模型字段净化 + 标签泄漏硬门禁 + 一致性按段落覆盖率(≥80%)而非 50%。
45
-
46
- ---
47
-
48
- ## 二、是否过度工程化?——是,且在制造缺陷
49
-
50
- ### 2.1 复杂度清单(现状)
51
-
52
- | 层 | 规模 | 缺陷贡献 |
53
- |----|------|---------|
54
- | 页型 | 29 种 | scaffold/引擎/schema 三方易漂(已抓到 **cards 契约错**:scaffold 出 `[[k,v]]`,引擎要 `{title,points}`) |
55
- | 图表 | 36 登记 / 30 chart.type | 形状通道 20 类是缺陷农场;A/B 双引擎近 4k 行重复 |
56
- | 单源 JSON | 5 份 | `sync_runtime` 注入链一断就静默不一致 |
57
- | 门禁码 | 40+ | 关键码不在 `STRICT_FAILURE_CODES`,**假过** |
58
- | 文档 L2 | 20+ 文件 | 生成时读不完 → 绕过锁定组件自由发挥 |
59
-
60
- ### 2.2 收敛原则(v9)
61
-
62
- 1. **默认生成面收窄**:演示/研究默认 **12 页型 + 12 图表**;其余标「高级/按需」,不进默认选型表。
63
- 2. **双引擎职责砍半**:B 通道(`build_pptx.js`)是唯一交付;A 通道只做缩略预览,**不再要求逐页文本全等**(改为「标题 + 主文本 ≥80%」)。
64
- 3. **单源合并**:`layout_slots.json` 并入 `layout-constants.json`;`regionOf` 只保留 `lib_layout_regions.js` 一份。
65
- 4. **门禁只保留会改变交付决策的**:装饰性/节奏类降为报告;见 §三。
66
- 5. **文档**:L1 playbook 含「演讲图文构图 + 图表面积规则」;失败模式从 16 类压到 **10 类硬缺陷**。
67
-
68
- ### 2.3 明确不砍
69
-
70
- - 原生可编辑 PPTX(`pictures=0`)——产品差异点。
71
- - 亮暗双主题 + 9 风格——皮肤层,不制造内容缺陷。
72
- - 双单源常量(几何/字阶)——版式可复现的基础。
73
- - 负向测试(`negative_tests.py`)——防止门禁退化。
74
-
75
- ---
76
-
77
- ## 三、质量门禁重建(抓截图级真缺陷)
78
-
79
- ### 3.1 新硬门禁(strict 必拦)
80
-
81
- | 码 | 判据 | 对应现象 |
82
- |----|------|---------|
83
- | `HTML_TAG_IN_TEXT` | 可见文本剥离后仍含 `<a ` / `</a>` / `class="cite"` / `href=` / `<strong` 等 | 标签泄漏 |
84
- | `TITLE_ONLY_PAGE` | 去掉页头后正文 < 40 字且承载组件 = 0 | 空白内容页 |
85
- | `UNDERFILL_PAGE` | 承载 < 2 且非金句/章节幕/收尾 | 半空页 |
86
- | `TEXT_INCOMPLETE` | 模型字段与 PPTX/HTML 文本长度比 < 0.8,或句末无标点且长度截断 | 文字不全 |
87
- | `CHART_SKEW_INVALID` | donut/pie 最小扇区 < 5% 或类别 = 2 且 max/min > 20 | 环图叠字/不可读 |
88
- | `CHART_OVERSIZE` | 简单图(≤3 点或 ≤2 类)占内容区 > 55% | 简单大图 |
89
- | `IMAGE_SIMPLE_CONTENT` | `imageAdmission.forbidden` 语义被图片化(简单流程/柱状/表格截图) | 简单图当大图 |
90
- | `STRUCTURE_DEGRADED` | 含分支/判断语义却只有 `→` 文本箭头或空 `.arch` | 架构图难看 |
91
-
92
- ### 3.2 升级为 strict(原 WARN)
93
-
94
- - `LOW_TEXT_DENSITY` / `LOW_CONTENT_DENSITY` / `EMPTY_OR_UNMEASURABLE_SLIDE`
95
- - `UNBALANCED_EMPTY_SPACE`(**任一轴**留白 > 0.28,不再要求右+下同时)
96
- - `UNJUSTIFIED_LARGE_IMAGE`(面积 ≥ 40% 且不在 allowed)
97
- - `TEXT_OVERFLOW_ESTIMATE`
98
- - `MODEL_ROUNDTRIP_CONTENT_MISSING`(阈值 50% → **80%**)
99
-
100
- ### 3.3 降级为报告(不挡交付)
101
-
102
- - 图表多样性类型数下限、相邻同型、版式节奏连用、research 标题判断词正则
103
- - rubric 启发式 tone 维
104
- - CSS 死类、风格 WCAG 微调
105
-
106
- > **理由**:截图里没有一例是「图表不够多样」造成的;全是空白、泄漏、截断、失衡、错误选型。门禁预算应砸在后者。
107
-
108
- ### 3.4 负向测试新增(`negative_tests.py`)
109
-
110
- N15 标签泄漏 · N16 标题空页 · N17 极偏 donut · N18 简单图超大 · N19 正文截断 50% · N20 cards 元组契约
111
-
112
- ---
113
-
114
- ## 四、图文演讲模式(美观 · 合理 · 可讲)
115
-
116
- > 目标:**3 秒看清主张,30 秒讲完证据**。不是「配图好看的报告」,是「台上能指着讲的材料」。
117
-
118
- ### 4.1 构图契约(V1–V4)
119
-
120
- | 版式 | 结构 | 适用 | 面积比(视觉 : 注解) |
121
- |------|------|------|----------------------|
122
- | **V1 主视觉 + 右侧注解** | 图/照片 55–60% · 3–4 条要点 + 1 句 so-what | 产品、场景、对比图 | 6:4 |
123
- | **V2 上图下带** | 通栏图 50–55% · 下方指标带/三卡 | 总览 → 分解 | 55:45 |
124
- | **V3 大数 + 佐证图** | KPI 40% · 小图/迷你表 35% · 口径 25% | 极偏占比、单点结论 | 不用 donut |
125
- | **V4 双图对照** | A/B 各 40% · 中缝结论条 20% | 前后、方案、竞品 | 8:2 |
126
-
127
- ### 4.2 硬规则
128
-
129
- 1. **简单数据禁止全幅图**:≤2 类占比、单指标进度 → **V3**;全幅留给结构/全景/素材。
130
- 2. **图旁必须有口头注解**:3–4 条,每条 ≤2 行;禁止「一张图 + 标题」独页(金句/章节幕除外)。
131
- 3. **标签不进扇区内部**:环图/饼图数值放**图例行**或**引出线**,禁止叠在弧上(治叠字)。
132
- 4. **极偏数据换形态**:min/max ≥ 20 或 min 扇区 < 5% → KPI / 进度条 / 对比条,**禁 donut/pie**。
133
- 5. **图注与来源沉底**:`caption` 一行 + `footnote` 口径;不进主视觉。
134
- 6. **照片 vs 图表**:情绪/场景用照片(`media`);比较/趋势/构成用内联 SVG;**简单图表永不截图**。
135
- 7. **演讲节奏页**:每 4–6 页插 V3/金句/指标带,避免连续密排。
136
-
137
- ### 4.3 与三模式关系
138
-
139
- - **A presentation**:默认走 V1–V4;「1 张大图」废除。
140
- - **B research**:保留密排,但证据页主图仍受 `CHART_SKEW_INVALID` / `CHART_OVERSIZE` 约束。
141
- - **C architecture**:图为王不变,但必须真结构(边/分支/泳道),禁止文字箭头退化。
142
-
143
- ---
144
-
145
- ## 四-b、布局语法(核心:每页整齐优雅)
146
-
147
- > 详规见 **`references/layout-grammar.md`**。本节是方案层摘要。
148
-
149
- ### 4.b.1 为什么要预设网格/骨架
150
-
151
- 自由排版是「不整齐」的根因:左缘漂移、间距游离、双视觉重心、半空页。v9 规定:
152
-
153
- 1. **12 列网格强制**(PPTX `grid.x[]` ↔ HTML 栅格类同源)。
154
- 2. **预设骨架 P1–P12**:内容先选骨架再填,禁止临场发明栅格。
155
- 3. **三层槽位**:Chrome / Primary / Secondary / Annotation,面积比 22/55/20/18 量级。
156
- 4. **间距只准 token**(`--sp-*` / `--gap` / `containers.pad`)。
157
-
158
- ### 4.b.2 骨架一览(与 V1–V4 对齐)
159
-
160
- | 演讲图文 | 骨架 | 列比 | 权重 |
161
- |----------|------|------|------|
162
- | V1 主视觉+注解 | P1 | 7:5 | 60:40 |
163
- | V2 上图下带 | P2 | 12+4/4/4 | 55:45 |
164
- | V3 大数佐证 | P3 | 5:7 | 45:55 |
165
- | V4 双图对照 | P4 | 6:6 | 50:50 |
166
- | 三栏/四象限/拼贴/全幅 | P5/P6/P10/P9 | … | 见 grammar |
167
-
168
- ### 4.b.3 元素级优雅标准(摘要)
169
-
170
- | 元素 | 整齐关键 |
171
- |------|----------|
172
- | 图标 | 仅 16/20/24;光学对齐 x-height;图文距 8px |
173
- | 列表 | 项 ≤2 行;项距 12;加粗结论同一文本框 |
174
- | 卡片 | 等高 stretch;内边距一致;禁空卡 |
175
- | 指标 | 数字基线对齐;单位 45% 字号 |
176
- | 图表 | 标签不叠弧;标签盒防换行;环径 ≤ 内容高 45% |
177
- | 图文 | 比例锁;顶边对齐;图注在下 |
178
- | 结构图 | 正交边+箭头;同层等高;禁裸 `→` |
179
-
180
- ### 4.b.4 留白与填充率
181
-
182
- - presentation Body 填充 **62–78%**;research 70–85%;architecture 图 75–90%。
183
- - 合法空页仅:章节幕 / 金句 / 收尾。
184
- - 门禁:`LAYOUT_FILL_*` / `LAYOUT_MULTI_FOCUS` / `LAYOUT_ALIGN_DRIFT` / `LAYOUT_SPACING_OFF_TOKEN`。
185
-
186
- ### 4.b.5 排版总序
187
-
188
- **角色 → 骨架 P__ → 元素落位 → 间距 token → 对齐/留白 → LAYOUT_* 门禁**。禁止跳步直接堆组件。
189
-
190
- ---
191
-
192
- ## 五、可靠性与性能
193
-
194
- | 项 | 现状 | v9 |
195
- |----|------|-----|
196
- | 生成失败 | 缺字段只 console.warn | `extract_model` 缺关键字段 → 非 0;`build_pptx` 空页计入 strict |
197
- | 校验耗时 | 多脚本手跑 | **`quality_gate.py` 一键** = validate_report + validate_pptx + 新硬门禁 + deliver |
198
- | 预览 | A 通道全页 OOXML | 缩略级即可;交付只认 B |
199
- | 回归 | `regression.py` 全量 | 保留;示例矩阵覆盖新硬门禁负例 |
200
- | 文档体积 | L2 易爆 | 默认只读 SKILL + playbook;新规则进 playbook §六 |
201
-
202
- ---
203
-
204
- ## 六、分阶段落地
205
-
206
- ### P0(本迭代 · 必须)——已落地
207
-
208
- 1. 门禁:`HTML_TAG_IN_TEXT` / `TITLE_ONLY_PAGE` / 极偏 donut / 简单图超大 / 正文保真 ≥80%
209
- 2. 升级 empty / unbalanced / large-image / overflow 为 strict
210
- 3. 修复 **scaffold cards** 契约 → `{title, points}`
211
- 4. `extract_model` 模型字段 **strip HTML 标签**(cite 只允许模型侧 `[n]` 纯文本)
212
- 5. playbook + content-rules 写入 **V1–V4 图文演讲契约** 与 **图表面积/极偏规则**
213
- 6. `layout-constants` 增加 `qualityGates` / `charts.sizeByComplexity` / **`layoutSystem`(P1–P12)**
214
- 7. **`layout-grammar.md` + `LAYOUT_*` 门禁**(骨架/单重心/对齐/间距/填充率)
215
- 8. 负向测试 N15–N17
216
-
217
- ### P1(下一迭代)——大部分落地
218
-
219
- 1. **骨架 P1–P12 进 scaffold**(`data-skel` + `layoutPreset` + 打印骨架序列)
220
- 2. **默认图表收敛 8 核心**(`layoutSystem.defaultCharts`);高级图型标 advanced
221
- 3. **A/B 文本保真 80%**(`cross_verify` 覆盖率,不再要求逐字全等)
222
- 4. **泳道/层间正交箭头**(HTML `.lane__arr`/`.arch__conn` + PPTX line+triangle)
223
- 5. **布局 IR 单源**:`layoutSlots` 并入 `layout-constants`(`lib_layout_regions` 优先读 LC)
224
- 6. **模型驱动生成**:`render_from_model.py`(只填 REPORT_MODEL → 回填 HTML);图/exhibit scaffold 强制 P8 主从
225
-
226
- ### P2(后续增强)
227
-
228
- 1. 渲染对照纳入 quality_gate(有 LibreOffice 时)
229
- 2. 视觉基线(示例截图 diff)
230
- 3. ~~发布 0.1.0 + CHANGELOG~~ **已完成**
231
-
232
- ---
233
-
234
- ## 七、验收标准(Definition of Done)
235
-
236
- - [x] 截图四类问题(标签泄漏 / 空白 / 截断 / 简单大图)在负向测试中 **全部被 FAIL 抓住**
237
- - [x] 示例矩阵 9 份 `validate_report` 全绿(0 FAIL)
238
- - [x] 模型单写样张:`render_from_model` 产出 0 硬缺陷
239
- - [ ] PPTX 全链:`regression.py`(含 Node 环境时)`validate_pptx --strict` 0/0
240
- - [x] 文档:playbook/layout-grammar 含新契约;failure-modes 与错误码对齐
241
-
242
- ---
243
-
244
- ## 八、决策摘要(给评审)
245
-
246
- 1. **设定要改**:废除「演示 = 1 张大图」;图表面积跟信息复杂度走;极偏数据禁环图。
247
- 2. **复杂度要砍**:默认 12 页型 + 12 图表;双引擎砍半;门禁从 40+ 装饰项收敛到 **8 个真缺陷硬门禁**。
248
- 3. **双写要收**:模型字段禁 HTML;一致性 80%;中期模型驱动生成。
249
- 4. **图文要有演讲构图**:V1–V4,主视觉 + 口头注解,简单数据用大数不用整页图。
250
- 5. **质量靠门禁不靠自觉**:截图级缺陷必须 FAIL,负向测试锁死。
251
-
252
- > 整改顺序永远是:**补证据含义 → 改承载形态 → 调容器网格 → 有限缩字号 → 拆页**。禁止用装饰、放大图、砍口径过检。