@topmindspace/tms-skills 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +72 -19
- package/top-ppt-html/assets/examples/2026-09-09-architecture-spectrum.html +72 -19
- package/top-ppt-html/assets/examples/2026-09-09-presentation-apple-mono.html +72 -19
- package/top-ppt-html/assets/examples/2026-09-09-presentation-brand-red.html +72 -19
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +72 -19
- package/top-ppt-html/assets/examples/2026-09-09-research-deep-teal.html +72 -19
- package/top-ppt-html/assets/examples/2026-09-09-research-indigo-violet.html +72 -19
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +72 -19
- package/top-ppt-html/assets/examples/2026-09-09-research-warm-sand.html +72 -19
- package/top-ppt-html/assets/pptx-export.js +2 -2
- package/top-ppt-html/assets/style-gallery.html +56 -26
- package/top-ppt-html/assets/templates/architecture.html +72 -19
- package/top-ppt-html/assets/templates/engine.css +70 -17
- package/top-ppt-html/assets/templates/presentation.html +72 -19
- package/top-ppt-html/assets/templates/research.html +72 -19
- package/top-ppt-html/assets/theme-overview-architecture.png +0 -0
- package/top-ppt-html/assets/theme-overview-presentation.png +0 -0
- package/top-ppt-html/assets/theme-overview-research.png +0 -0
- package/top-ppt-html/assets/theme-overview.png +0 -0
- package/top-ppt-html/package-lock.json +34 -2
- package/top-ppt-html/package.json +7 -2
- package/top-ppt-html/references/design-system.md +13 -6
- package/top-ppt-html/references/styles.md +60 -26
- package/top-ppt-html/references/tech-design.md +1 -1
- package/top-ppt-html/scripts/audit_styles.py +59 -1
- package/top-ppt-html/scripts/layout-constants.json +71 -3
- package/top-ppt-html/scripts/layout_slots.json +1 -1
- package/top-ppt-html/scripts/model-schema.json +1 -1
- package/top-ppt-html/scripts/regression.py +17 -16
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
# 风格系统(9 套预设 · 覆盖 8 个色族 + 1 个彩色数据板)
|
|
2
2
|
|
|
3
|
-
> **何时读**:改配色、换/新增风格、调亮暗 token
|
|
3
|
+
> **何时读**:改配色、换/新增风格、调亮暗 token、配编码色板、对齐风格语汇(字体/圆角/字阶/密度)时。**何时不读**:只想挑风格(Gate 0 参考图 + `--task style-theme` 速览即可)。
|
|
4
4
|
> **取节**:`python scripts/extract_snippet.py --task style-theme`(快速选型 + 新增步骤);单套风格细节 `--file styles.md --section <1-11>`(数字节号)。
|
|
5
5
|
|
|
6
6
|
## 工作原理
|
|
7
7
|
|
|
8
|
-
报告结构与样式分离。`design-system.md` 提供**风格无关的 CSS 引擎**(版式、栅格、组件、排版类、SVG
|
|
8
|
+
报告结构与样式分离。`design-system.md` 提供**风格无关的 CSS 引擎**(版式、栅格、组件、排版类、SVG 语义类全部复用);每套风格**覆盖两层 token**:
|
|
9
|
+
|
|
10
|
+
1. **结构色层**(必须):强调色、表面色族、文字色、边框——决定「是什么颜色」;
|
|
11
|
+
2. **风格语汇层**(必须与定位一致):`--font-body` / `--font-display` / `--radius` / `--fs-*` 微调 / `--letter-*` / `--lh-*` / `--gap` / `--shadow-*` / `--link`——决定「是什么气质」(字体、圆角、字阶、留白、阴影)。
|
|
12
|
+
|
|
13
|
+
**语汇清单单源** = `scripts/layout-constants.json` `styleIdentity`;`engine.css` 覆盖块逐项落地;`audit_styles.py` 校验缺一即 FAIL。**只改色不改语汇 = 只有皮肤没有性格**。
|
|
9
14
|
|
|
10
15
|
切换方式:`<html data-mode="X" data-style="business-blue" data-theme="light">`。
|
|
11
16
|
|
|
12
|
-
- **模式(三选一,生成时锁定)与风格正交**:结构 / 类名 / 组件由模式模板决定(`assets/templates
|
|
17
|
+
- **模式(三选一,生成时锁定)与风格正交**:结构 / 类名 / 组件由模式模板决定(`assets/templates/`),风格覆盖上述两层 token。
|
|
13
18
|
- 生成后 header 风格下拉可实时切换 9 套(纯视觉皮肤不动内容);交付前切回选定值(`data-style` 与 `REPORT_MODEL.style` 一致,校验器检查)。
|
|
14
19
|
- 除 `spectrum` 外,每套风格**只有一个强调色**,层次仍靠表面明度差 + 1px 边框;`spectrum` 的彩色仅限数据系列(见第 9 节边界)。
|
|
15
|
-
- 每套都同时给出 light 与 dark
|
|
20
|
+
- 每套都同时给出 light 与 dark 两套**色**值;语汇层(字体/圆角/字阶)两主题共用。
|
|
16
21
|
- 风格 × 模式矩阵预览见 `assets/style-gallery.html`(三模式 Tab 为一级维度、9 风格卡片为二级,每张卡按当前模式渲染迷你版式特征)。
|
|
17
|
-
- **PPTX
|
|
22
|
+
- **PPTX 导出侧的色 token 与本文件同源**:单一事实源在 `scripts/layout-constants.json` `styles`(light 变量),两导出通道自动消费(`sync_runtime.py` 注入/校验);改风格值改 JSON,不要只改本文档。**PPTX 字体族一律 Microsoft YaHei**(投影可读性),不跟 HTML 换衬线/系统栈。
|
|
18
23
|
|
|
19
24
|
## 快速选型(含三模式推荐风格)
|
|
20
25
|
|
|
@@ -39,12 +44,15 @@
|
|
|
39
44
|
**定位**:专业、克制、信息密度高。中性灰阶 + Google Blue。
|
|
40
45
|
**适用**:绝大多数商务/技术/数据汇报。
|
|
41
46
|
|
|
47
|
+
**语汇**:Google Material · 圆角 16 · 同字族 · 密度 normal · `--link` = accent-text。
|
|
48
|
+
|
|
42
49
|
```css
|
|
43
50
|
html[data-style="business-blue"] {
|
|
44
51
|
--font-body: "Google Sans","Roboto",-apple-system,BlinkMacSystemFont,"Segoe UI",
|
|
45
52
|
"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans SC",sans-serif;
|
|
46
53
|
--font-display: var(--font-body);
|
|
47
|
-
--radius: 16px;
|
|
54
|
+
--radius: 16px; --fw-display:700; --fw-title:600;
|
|
55
|
+
--letter-display:-.03em; --letter-eyebrow:.11em; --lh-body:1.68; --lh-lead:1.62; --link:#1b66c9;
|
|
48
56
|
--bg:#ffffff; --surface:#ffffff; --surface-1:#f8f9fa; --surface-2:#f1f3f4; --surface-3:#e8eaed;
|
|
49
57
|
--surface-inv:#202124; --text:#202124; --text-2:#5f6368; --text-3:#80868b; --text-inv:#ffffff;
|
|
50
58
|
--border:#dadce0; --border-soft:#e8eaed;
|
|
@@ -55,6 +63,7 @@ html[data-style="business-blue"][data-theme="dark"] {
|
|
|
55
63
|
--surface-inv:#e8eaed; --text:#e8eaed; --text-2:#adb4bd; --text-3:#868d96; --text-inv:#14171c;
|
|
56
64
|
--border:#2f353d; --border-soft:#23282f;
|
|
57
65
|
--accent:#8ab4f8; --accent-soft:#16243a; --accent-soft-2:#1d3557; --accent-text:#8ab4f8; --accent-on:#0d1b2e;
|
|
66
|
+
--link:#8ab4f8;
|
|
58
67
|
}
|
|
59
68
|
```
|
|
60
69
|
|
|
@@ -64,21 +73,23 @@ html[data-style="business-blue"][data-theme="dark"] {
|
|
|
64
73
|
|
|
65
74
|
**定位**:苹果式极简。大留白、超大字号、几乎无彩色,靠留白与排版取胜。
|
|
66
75
|
**适用**:产品发布、品牌、面向高管/外部的演示。
|
|
67
|
-
**特点**:强调色为近黑/近白(按钮实底黑),CTA 可极少量用系统蓝 `#0071e3
|
|
76
|
+
**特点**:强调色为近黑/近白(按钮实底黑),CTA 可极少量用系统蓝 `#0071e3`(`--link`);分块少、字大、行宽松。
|
|
77
|
+
**语汇**:Apple 极简 · 圆角 20 · **typeBoost**(display/h1 放大)· `--fw-title:500` 更轻 · 行高 1.75 · 栅格 gap 放大 · 阴影几乎归零。
|
|
68
78
|
|
|
69
79
|
```css
|
|
70
80
|
html[data-style="apple-mono"] {
|
|
71
|
-
--font-body: -apple-system,BlinkMacSystemFont,"SF Pro Text","
|
|
72
|
-
"
|
|
81
|
+
--font-body: -apple-system,BlinkMacSystemFont,"SF Pro Text","Helvetica Neue",
|
|
82
|
+
"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
|
|
73
83
|
--font-display: -apple-system,BlinkMacSystemFont,"SF Pro Display","Helvetica Neue","PingFang SC",sans-serif;
|
|
74
|
-
--radius: 20px;
|
|
75
|
-
--fs-display: clamp(3rem,5.4vw,4.75rem); /*
|
|
84
|
+
--radius: 20px; --fw-display:600; --fw-title:500;
|
|
85
|
+
--fs-display: clamp(3rem,5.4vw,4.75rem); /* typeBoost */
|
|
76
86
|
--fs-h1: clamp(2.125rem,3.6vw,3.25rem);
|
|
87
|
+
--letter-display:-.04em; --letter-eyebrow:.12em; --lh-body:1.75; --lh-lead:1.7;
|
|
88
|
+
--gap:clamp(22px,2.2vw,36px); --link:#0071e3;
|
|
77
89
|
--bg:#ffffff; --surface:#ffffff; --surface-1:#f5f5f7; --surface-2:#f5f5f7; --surface-3:#e8e8ed;
|
|
78
90
|
--surface-inv:#1d1d1f; --text:#1d1d1f; --text-2:#6e6e73; --text-3:#86868b; --text-inv:#f5f5f7;
|
|
79
91
|
--border:#d2d2d7; --border-soft:#e8e8ed;
|
|
80
92
|
--accent:#1d1d1f; --accent-soft:#f5f5f7; --accent-soft-2:#e8e8ed; --accent-text:#1d1d1f; --accent-on:#ffffff;
|
|
81
|
-
--link:#0071e3; /* 仅链接/个别 CTA */
|
|
82
93
|
--shadow-1:none; --shadow-2:0 4px 24px rgba(0,0,0,.06);
|
|
83
94
|
}
|
|
84
95
|
html[data-style="apple-mono"][data-theme="dark"] {
|
|
@@ -97,12 +108,15 @@ html[data-style="apple-mono"][data-theme="dark"] {
|
|
|
97
108
|
**定位**:结构化、正式、咨询范。衬线标题 + 无衬线正文 + 细线框架 + 小圆角 + 高密表格。
|
|
98
109
|
**适用**:战略、咨询、立项、可研、对标。
|
|
99
110
|
**特点**:强调色为藏青;标题用衬线(Georgia/宋体),eyebrow 小字大写拉开字距;靠 1px hairline 与网格分块,几乎不用阴影。
|
|
111
|
+
**语汇**:咨询范 · **serifDisplay** · 圆角 6(近直角)· 密度 dense · `--letter-eyebrow:.14em` · 行高收紧 1.55 · gap 收紧。
|
|
100
112
|
|
|
101
113
|
```css
|
|
102
114
|
html[data-style="mckinsey"] {
|
|
103
115
|
--font-body: "Inter","IBM Plex Sans",-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;
|
|
104
116
|
--font-display: "Georgia","Times New Roman","Songti SC","STSong","SimSun",serif;
|
|
105
|
-
--radius: 6px;
|
|
117
|
+
--radius: 6px; --fw-display:600; --fw-title:600;
|
|
118
|
+
--letter-display:-.015em; --letter-eyebrow:.14em; --lh-body:1.55; --lh-lead:1.5;
|
|
119
|
+
--gap:clamp(14px,1.3vw,22px);
|
|
106
120
|
--bg:#ffffff; --surface:#ffffff; --surface-1:#f2f4f7; --surface-2:#f2f4f7; --surface-3:#e4e7ec;
|
|
107
121
|
--surface-inv:#101828; --text:#101828; --text-2:#475467; --text-3:#667085; --text-inv:#ffffff;
|
|
108
122
|
--border:#d0d5dd; --border-soft:#e4e7ec;
|
|
@@ -117,7 +131,7 @@ html[data-style="mckinsey"][data-theme="dark"] {
|
|
|
117
131
|
}
|
|
118
132
|
```
|
|
119
133
|
|
|
120
|
-
> 标题用 `.t-h1/.t-h2` 时衬线字体生效(`--font-display`);eyebrow
|
|
134
|
+
> 标题用 `.t-h1/.t-h2` 时衬线字体生效(`--font-display`);eyebrow 走 `--letter-eyebrow:.14em` + `text-transform:uppercase` 强化咨询感。
|
|
121
135
|
|
|
122
136
|
---
|
|
123
137
|
|
|
@@ -125,12 +139,14 @@ html[data-style="mckinsey"][data-theme="dark"] {
|
|
|
125
139
|
|
|
126
140
|
**定位**:以品牌主色红为强调,正式且有辨识度。可将下方红色替换为任意企业品牌色。
|
|
127
141
|
**适用**:企业品牌材料、正式汇报、对外宣讲。
|
|
142
|
+
**语汇**:正式品牌 · HarmonyOS Sans 栈 · 圆角 14 · 同字族粗字重 · 密度 normal。
|
|
128
143
|
|
|
129
144
|
```css
|
|
130
145
|
html[data-style="brand-red"] {
|
|
131
146
|
--font-body: "HarmonyOS Sans","PingFang SC","Microsoft YaHei","Noto Sans SC",-apple-system,"Segoe UI",sans-serif;
|
|
132
147
|
--font-display: var(--font-body);
|
|
133
|
-
--radius: 14px;
|
|
148
|
+
--radius: 14px; --fw-display:700; --fw-title:600;
|
|
149
|
+
--letter-display:-.025em; --letter-eyebrow:.12em; --lh-body:1.66; --lh-lead:1.6;
|
|
134
150
|
--bg:#ffffff; --surface:#ffffff; --surface-1:#faf7f7; --surface-2:#f5f0f0; --surface-3:#ece5e5;
|
|
135
151
|
--surface-inv:#1f1a1b; --text:#1f1a1b; --text-2:#5d5456; --text-3:#8a8083; --text-inv:#ffffff;
|
|
136
152
|
--border:#e2d9da; --border-soft:#ece5e5;
|
|
@@ -150,16 +166,20 @@ html[data-style="brand-red"][data-theme="dark"] {
|
|
|
150
166
|
|
|
151
167
|
**定位**:温暖高级、编辑感/年报感。米白暖底 + 古铜金强调,衬线标题。
|
|
152
168
|
**适用**:年度报告、品牌叙事、文化建设、价值观。
|
|
169
|
+
**语汇**:编辑/年报 · **serifDisplay** · 圆角 12 · 宽松行高 1.72 · gap 略放 · 阴影极轻。
|
|
153
170
|
|
|
154
171
|
```css
|
|
155
172
|
html[data-style="warm-sand"] {
|
|
156
173
|
--font-body: "Inter","Source Han Sans","PingFang SC","Microsoft YaHei",-apple-system,sans-serif;
|
|
157
174
|
--font-display: "Georgia","Playfair Display","Songti SC","STSong","SimSun",serif;
|
|
158
|
-
--radius: 12px;
|
|
175
|
+
--radius: 12px; --fw-display:600; --fw-title:600;
|
|
176
|
+
--letter-display:-.01em; --letter-eyebrow:.13em; --lh-body:1.72; --lh-lead:1.65;
|
|
177
|
+
--gap:clamp(18px,1.8vw,30px);
|
|
159
178
|
--bg:#fbf9f6; --surface:#ffffff; --surface-1:#f6f2ec; --surface-2:#efe9df; --surface-3:#e6ded2;
|
|
160
179
|
--surface-inv:#2a2521; --text:#2a2521; --text-2:#6b5f52; --text-3:#93836f; --text-inv:#f6f2ec;
|
|
161
180
|
--border:#e0d7c9; --border-soft:#eae3d6;
|
|
162
181
|
--accent:#96681f; --accent-soft:#f3ecdd; --accent-soft-2:#eaddc4; --accent-text:#8f6117; --accent-on:#ffffff;
|
|
182
|
+
--shadow-1:none; --shadow-2:0 1px 3px rgba(42,37,33,.08);
|
|
163
183
|
}
|
|
164
184
|
html[data-style="warm-sand"][data-theme="dark"] {
|
|
165
185
|
--bg:#15120e; --surface:#15120e; --surface-1:#1d1913; --surface-2:#26201a; --surface-3:#312920;
|
|
@@ -175,12 +195,14 @@ html[data-style="warm-sand"][data-theme="dark"] {
|
|
|
175
195
|
|
|
176
196
|
**定位**:沉稳、可信赖。冷灰底 + 深青强调。
|
|
177
197
|
**适用**:金融、风控、ESG、可持续、审计。
|
|
198
|
+
**语汇**:金融可信 · Inter/Source Han 栈 · 圆角 12 · 同字族 · 密度 normal。
|
|
178
199
|
|
|
179
200
|
```css
|
|
180
201
|
html[data-style="deep-teal"] {
|
|
181
202
|
--font-body: "Inter","Source Han Sans","PingFang SC","Microsoft YaHei",-apple-system,sans-serif;
|
|
182
203
|
--font-display: var(--font-body);
|
|
183
|
-
--radius: 12px;
|
|
204
|
+
--radius: 12px; --fw-display:700; --fw-title:600;
|
|
205
|
+
--letter-display:-.028em; --letter-eyebrow:.11em; --lh-body:1.66; --lh-lead:1.6;
|
|
184
206
|
--bg:#ffffff; --surface:#ffffff; --surface-1:#f2f6f5; --surface-2:#e8f0ef; --surface-3:#dce7e5;
|
|
185
207
|
--surface-inv:#14201e; --text:#14201e; --text-2:#4a5a57; --text-3:#73837f; --text-inv:#ffffff;
|
|
186
208
|
--border:#cfdedc; --border-soft:#e0eae9;
|
|
@@ -202,11 +224,15 @@ html[data-style="deep-teal"][data-theme="dark"] {
|
|
|
202
224
|
**适用**:产品发布会、指挥中心大屏、深色优先场景。
|
|
203
225
|
**深色优先的落地**:架构模式模板(默认风格即 graphite-dark)出厂 `data-theme="dark"`;其他模式选用本风格时,交付前建议切到 dark(或向用户明示浅色为辅助变体)。浅色变体的灰阶为**中性石墨灰**(不带蓝味),与商务蓝的白底纯蓝拉开辨识度;强调色为深蓝青(与 dark 侧亮蓝青 #4da3ff 同系)。
|
|
204
226
|
|
|
227
|
+
**语汇**:沉浸石墨 · Inter/SF 栈 · 圆角 14 · 密度 dense · 深色阴影更沉 · gap 紧。
|
|
228
|
+
|
|
205
229
|
```css
|
|
206
230
|
html[data-style="graphite-dark"] {
|
|
207
231
|
--font-body: "Inter","SF Pro Text","PingFang SC","Microsoft YaHei",-apple-system,sans-serif;
|
|
208
232
|
--font-display: "Inter","SF Pro Display","PingFang SC",sans-serif;
|
|
209
|
-
--radius: 14px;
|
|
233
|
+
--radius: 14px; --fw-display:700; --fw-title:600;
|
|
234
|
+
--letter-display:-.03em; --letter-eyebrow:.1em; --lh-body:1.62; --lh-lead:1.55;
|
|
235
|
+
--gap:clamp(14px,1.4vw,24px);
|
|
210
236
|
--bg:#f4f5f7; --surface:#ffffff; --surface-1:#eceef1; --surface-2:#e3e6ea; --surface-3:#d8dbdf;
|
|
211
237
|
--surface-inv:#14171b; --text:#1a1d21; --text-2:#4b5158; --text-3:#767c84; --text-inv:#eef2f6;
|
|
212
238
|
--border:#ced1d6; --border-soft:#e3e6ea;
|
|
@@ -229,12 +255,14 @@ html[data-style="graphite-dark"][data-theme="dark"] {
|
|
|
229
255
|
|
|
230
256
|
**定位**:创新、前沿。冷白底 + 靛紫强调。
|
|
231
257
|
**适用**:AI、科技、研发、创新、前沿技术。
|
|
258
|
+
**语汇**:科技前沿 · Inter/SF 栈 · 圆角 16 · 轻快字距 · 密度 normal。
|
|
232
259
|
|
|
233
260
|
```css
|
|
234
261
|
html[data-style="indigo-violet"] {
|
|
235
262
|
--font-body: "Inter","SF Pro Text","PingFang SC","Microsoft YaHei",-apple-system,sans-serif;
|
|
236
263
|
--font-display: var(--font-body);
|
|
237
|
-
--radius: 16px;
|
|
264
|
+
--radius: 16px; --fw-display:700; --fw-title:600;
|
|
265
|
+
--letter-display:-.032em; --letter-eyebrow:.12em; --lh-body:1.68; --lh-lead:1.62;
|
|
238
266
|
--bg:#ffffff; --surface:#ffffff; --surface-1:#f4f4fb; --surface-2:#ececf7; --surface-3:#e0e0f0;
|
|
239
267
|
--surface-inv:#1b1a2e; --text:#1b1a2e; --text-2:#52506b; --text-3:#7a779a; --text-inv:#ffffff;
|
|
240
268
|
--border:#d7d7e8; --border-soft:#e6e6f2;
|
|
@@ -261,11 +289,15 @@ html[data-style="indigo-violet"][data-theme="dark"] {
|
|
|
261
289
|
- 同屏彩色数据系列 ≤ 5;超过就合并为"其他"。
|
|
262
290
|
- **9 套风格各有自己的 `c1–c5`**(单源 `styleDataColors`,见第 11 节与 `design-system.md` §9b)——本风格只是把彩色作为**定位**(`c1` = 强调色),并不是"唯一能出彩的风格"。
|
|
263
291
|
|
|
292
|
+
**语汇**:数据看板 · Inter/SF 栈 · 圆角 14 · 密度 dense · 紧凑 gap · 行高略紧。
|
|
293
|
+
|
|
264
294
|
```css
|
|
265
295
|
html[data-style="spectrum"] {
|
|
266
296
|
--font-body: "Inter","SF Pro Text","PingFang SC","Microsoft YaHei",-apple-system,sans-serif;
|
|
267
297
|
--font-display: var(--font-body);
|
|
268
|
-
--radius: 14px;
|
|
298
|
+
--radius: 14px; --fw-display:700; --fw-title:600;
|
|
299
|
+
--letter-display:-.03em; --letter-eyebrow:.1em; --lh-body:1.6; --lh-lead:1.55;
|
|
300
|
+
--gap:clamp(12px,1.2vw,20px);
|
|
269
301
|
--bg:#fbfcfe; --surface:#ffffff; --surface-1:#f4f6fa; --surface-2:#eceff5; --surface-3:#dfe4ec;
|
|
270
302
|
--surface-inv:#171a21; --text:#171a21; --text-2:#4d5566; --text-3:#7b8494; --text-inv:#ffffff;
|
|
271
303
|
--border:#d6dce6; --border-soft:#e6eaf1;
|
|
@@ -326,11 +358,13 @@ html[data-style="spectrum"][data-theme="dark"] {
|
|
|
326
358
|
|
|
327
359
|
1. 在「快速选型」表加一行(中/英文名 + data-style + 定位 + 适用 + 族)。
|
|
328
360
|
2. 选一个**中性色族**(冷灰/暖灰/纯黑白)+ 一个**强调色**,写 light + dark 两个覆盖块。
|
|
329
|
-
3.
|
|
330
|
-
4.
|
|
331
|
-
- `scripts/layout-constants.json` → `styles`(light 10 字段)+ `stylesDark`(dark 10 字段)+ `styleAccents`(强调色族)+ **`styleDataColors` / `styleDataColorsDark`(编码色板 c1–c5,见第 11 节)**
|
|
332
|
-
- `assets/templates/engine.css` → `html[data-style="X"]{…}` + `html[data-style="X"][data-theme="dark"]{…}` + **编码色板两个覆盖块(`--c1..--c5
|
|
361
|
+
3. 定**风格语汇**(缺一即「只有皮肤没有性格」):字体栈 `--font-body` / `--font-display`、圆角 `--radius`、字阶微调(`--fs-*`)、字距/行高(`--letter-*` / `--lh-*`)、密度(`--gap`)、阴影、必要时 `--link`。
|
|
362
|
+
4. **六处同步**(缺一即漂移):
|
|
363
|
+
- `scripts/layout-constants.json` → `styles`(light 10 字段)+ `stylesDark`(dark 10 字段)+ `styleAccents`(强调色族)+ **`styleIdentity`(语汇清单)** + **`styleDataColors` / `styleDataColorsDark`(编码色板 c1–c5,见第 11 节)**
|
|
364
|
+
- `assets/templates/engine.css` → `html[data-style="X"]{…}` + `html[data-style="X"][data-theme="dark"]{…}` + **编码色板两个覆盖块(`--c1..--c5`)**——语汇 token 必须落在 light 块
|
|
333
365
|
- `assets/templates/ui.js` → `var STYLES` 数组加一项(`['id','中文名','#亮色accent']`)
|
|
334
|
-
-
|
|
335
|
-
|
|
366
|
+
- 本文件速查表 + 各节 CSS(语汇与 engine 逐字一致)+ 第 11 节编码色板表
|
|
367
|
+
- `assets/style-gallery.html` 画廊 `STYLE_META` 描述行(`pfontBody`/`pfontDisplay`/`prad`/`pscale`/`peye`/`plh`/`pgap`/`pw`/`pletter`;配色由注入的 `PRESETS` 自动派生)
|
|
368
|
+
- `references/design-system.md` 字体决策矩阵(若引入新字体语汇)
|
|
369
|
+
5. 跑 `python scripts/sync_runtime.py`(注入到三模板与画廊)→ `python scripts/audit_styles.py`(**9 套** × light/dark × 8 组 WCAG + 双源色 token + 编码色板 + ui.js 色板 + **风格语汇 styleIdentity**,全过才通过)→ `python scripts/build_examples.py` → `python scripts/regression.py`。
|
|
336
370
|
6. 可选:`node scripts/capture_theme_overview.js`(需 playwright)重生成 `assets/theme-overview*.png` 参考图。
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
|
|
109
109
|
## 七、发布态与兼容
|
|
110
110
|
|
|
111
|
-
- **发布版**:**v9.
|
|
111
|
+
- **发布版**:**v9.1**(布局语法 + 模型单写 + 硬门禁 + 风格语汇层)。**版本唯一事实源 = `layout-constants.json` `version`**;`model-schema.json` / `layoutSlots` 同步该值、技能 `package.json` 为 `9.1.x`;`sync_runtime.py` 校验一致。变更流水见仓库根 `CHANGELOG.md`。
|
|
112
112
|
- **兼容回落**:排版比例尺只有 `modeTypeScale` 一套;未知模式回落 `presentation` 档。环境变量 `TOP_PPT_NODE_EXE` / `TOP_PPT_NODE_PATH`(旧名已移除)。
|
|
113
113
|
- **文档分工**:本文件管架构与机制;日常规范见 `references/*`,业界对标依据见 `industry-benchmark.md`。
|
|
114
114
|
|
|
@@ -180,6 +180,55 @@ def audit_data_palette(styles):
|
|
|
180
180
|
return diffs
|
|
181
181
|
|
|
182
182
|
|
|
183
|
+
def audit_style_identity(styles):
|
|
184
|
+
"""风格语汇审计:每套风格的 HTML 身份 token 必须落地(字体栈 / 圆角 / 字阶微调 / 链接色)。
|
|
185
|
+
与 layout-constants.json 的 styleIdentity 清单逐项对照,拦「styles.md 写了、engine.css 没落」的漂移。"""
|
|
186
|
+
diffs = []
|
|
187
|
+
ident = {k: v for k, v in (LC.get('styleIdentity') or {}).items() if not k.startswith('$')}
|
|
188
|
+
if not ident:
|
|
189
|
+
return ['layout-constants.json 缺 styleIdentity(风格语汇清单)']
|
|
190
|
+
for sid, rule in ident.items():
|
|
191
|
+
css = styles.get(sid, {}).get('light', {})
|
|
192
|
+
if not css:
|
|
193
|
+
diffs.append(f'styleIdentity.{sid}: engine.css 缺 light 覆盖块')
|
|
194
|
+
continue
|
|
195
|
+
raw = re.search(
|
|
196
|
+
r'html\[data-style="%s"\]\{([\s\S]*?)\}' % re.escape(sid), CSS)
|
|
197
|
+
body = raw.group(1) if raw else ''
|
|
198
|
+
if '--font-body' not in body:
|
|
199
|
+
diffs.append(f'{sid}: 缺 --font-body(风格字体栈未落地)')
|
|
200
|
+
if '--font-display' not in body:
|
|
201
|
+
diffs.append(f'{sid}: 缺 --font-display(标题字体栈未落地)')
|
|
202
|
+
radius = str(rule.get('radius') or '')
|
|
203
|
+
if radius and f'--radius:{radius}' not in body.replace(' ', ''):
|
|
204
|
+
# 允许 --radius: 16px 带空格
|
|
205
|
+
if not re.search(r'--radius:\s*%s' % re.escape(radius), body):
|
|
206
|
+
diffs.append(f'{sid}: --radius 未设为 {radius}')
|
|
207
|
+
if rule.get('serifDisplay'):
|
|
208
|
+
fd = re.search(r'--font-display:\s*([^;]+);', body)
|
|
209
|
+
if not fd or 'serif' not in fd.group(1).lower():
|
|
210
|
+
diffs.append(f'{sid}: serifDisplay=true 但 --font-display 非 serif 栈')
|
|
211
|
+
if rule.get('typeBoost') and '--fs-display' not in body:
|
|
212
|
+
diffs.append(f'{sid}: typeBoost=true 但未覆盖 --fs-display')
|
|
213
|
+
if rule.get('link'):
|
|
214
|
+
if '--link' not in body:
|
|
215
|
+
diffs.append(f'{sid}: 声明 link 但缺 --link token')
|
|
216
|
+
else:
|
|
217
|
+
lv = re.search(r'--link:\s*([^;]+);', body)
|
|
218
|
+
if lv and lv.group(1).strip().lower() != str(rule['link']).lower():
|
|
219
|
+
diffs.append(f'{sid}: --link={lv.group(1).strip()} != styleIdentity {rule["link"]}')
|
|
220
|
+
le = rule.get('letterEyebrow')
|
|
221
|
+
if le and f'--letter-eyebrow:{le}' not in body.replace(' ', ''):
|
|
222
|
+
if not re.search(r'--letter-eyebrow:\s*%s' % re.escape(le), body):
|
|
223
|
+
diffs.append(f'{sid}: --letter-eyebrow 未设为 {le}')
|
|
224
|
+
for sid in (LC.get('styles') or {}):
|
|
225
|
+
if sid.startswith('$'):
|
|
226
|
+
continue
|
|
227
|
+
if sid not in ident:
|
|
228
|
+
diffs.append(f'styleIdentity 缺风格 {sid}')
|
|
229
|
+
return diffs
|
|
230
|
+
|
|
231
|
+
|
|
183
232
|
def audit_ui_palette():
|
|
184
233
|
"""ui.js 的 header 风格下拉色板必须与 layout-constants.json 的 accent 一致
|
|
185
234
|
(ui.js 在运行时块之前执行,无法直接读 PRESETS,故用审计兜住这最后一处手写色值)。"""
|
|
@@ -290,4 +339,13 @@ if u_fails:
|
|
|
290
339
|
else:
|
|
291
340
|
print(f' 全部一致({n_styles} 套色板 = {n_styles} 套 accent)')
|
|
292
341
|
|
|
293
|
-
|
|
342
|
+
id_fails = audit_style_identity(css_styles)
|
|
343
|
+
print('\n── 风格语汇(font / radius / typeBoost / serifDisplay / link · engine.css ↔ styleIdentity)──')
|
|
344
|
+
if id_fails:
|
|
345
|
+
for f in id_fails:
|
|
346
|
+
print(' [DIFF]', f)
|
|
347
|
+
else:
|
|
348
|
+
n_id = len([k for k in (LC.get('styleIdentity') or {}) if not k.startswith('$')])
|
|
349
|
+
print(f' 全部落地({n_id} 套风格语汇与 engine.css 覆盖块一致)')
|
|
350
|
+
|
|
351
|
+
sys.exit(1 if (c_fails or d_fails or dd_fails or s_fails or dp_fails or u_fails or id_fails) else 0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "TopPPT HTML 版式常量单源 —— 页面几何 / 12 列网格 / 语义字阶 C0–T14 / 三模式独立排版比例尺 / 页型几何 / 9 风格 token + 编码色板 / 图表登记四元组 / 容器内边距 / 锚点容差 / 图片准入门与图片规格 imageSpec / 校验预算 / 强调色表 / 去AI味词表 / 深度模式。改这里,然后跑 python scripts/sync_runtime.py 注入 build_pptx.js(require)/ pptx-export.js(常量块)/ 三模板(引擎·UI·运行时内联副本)。禁止手改各处副本。页型字段约束见 scripts/model-schema.json(DSL schema 单源,两端页型须同步增减)。",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.2",
|
|
4
4
|
"page": {
|
|
5
5
|
"pw": 13.333,
|
|
6
6
|
"ph": 7.5,
|
|
@@ -2105,7 +2105,75 @@
|
|
|
2105
2105
|
"在.{0,6}的背景下"
|
|
2106
2106
|
]
|
|
2107
2107
|
},
|
|
2108
|
-
"stylesFontPolicy": "PPTX font/fontDisplay 一律 Microsoft YaHei(Windows/Mac Office 可用;禁 PingFang SC / SimSun 单点)。HTML 侧 engine.css 用完整 fallback
|
|
2108
|
+
"stylesFontPolicy": "PPTX font/fontDisplay 一律 Microsoft YaHei(Windows/Mac Office 可用;禁 PingFang SC / SimSun 单点)。HTML 侧 engine.css 用完整 fallback 栈承载风格字体语汇(衬线/系统栈/字阶/字距/圆角/密度),色 token 与本表双源一致。PPTX 不跟 HTML 换字体族——投影可读性优先于字体个性。",
|
|
2109
|
+
"styleIdentity": {
|
|
2110
|
+
"$comment": "HTML 侧风格语汇清单(与 engine.css 的 html[data-style=X] 覆盖块一一对应)。audit_styles.py 校验:每套至少含 font-body / font-display / radius;声明 serifDisplay 的必须是 serif 栈;声明 typeBoost 的必须覆盖 fs-display;声明 link 的必须有 --link。改语汇改 engine.css + 本表 + styles.md 三处,再跑 sync_runtime + audit_styles。",
|
|
2111
|
+
"business-blue": {
|
|
2112
|
+
"radius": "16px",
|
|
2113
|
+
"serifDisplay": false,
|
|
2114
|
+
"typeBoost": false,
|
|
2115
|
+
"density": "normal",
|
|
2116
|
+
"mood": "google-material"
|
|
2117
|
+
},
|
|
2118
|
+
"apple-mono": {
|
|
2119
|
+
"radius": "20px",
|
|
2120
|
+
"serifDisplay": false,
|
|
2121
|
+
"typeBoost": true,
|
|
2122
|
+
"density": "airy",
|
|
2123
|
+
"link": "#0071e3",
|
|
2124
|
+
"mood": "apple-minimal"
|
|
2125
|
+
},
|
|
2126
|
+
"mckinsey": {
|
|
2127
|
+
"radius": "6px",
|
|
2128
|
+
"serifDisplay": true,
|
|
2129
|
+
"typeBoost": false,
|
|
2130
|
+
"density": "dense",
|
|
2131
|
+
"letterEyebrow": ".14em",
|
|
2132
|
+
"mood": "consulting"
|
|
2133
|
+
},
|
|
2134
|
+
"brand-red": {
|
|
2135
|
+
"radius": "14px",
|
|
2136
|
+
"serifDisplay": false,
|
|
2137
|
+
"typeBoost": false,
|
|
2138
|
+
"density": "normal",
|
|
2139
|
+
"mood": "formal-brand"
|
|
2140
|
+
},
|
|
2141
|
+
"warm-sand": {
|
|
2142
|
+
"radius": "12px",
|
|
2143
|
+
"serifDisplay": true,
|
|
2144
|
+
"typeBoost": false,
|
|
2145
|
+
"density": "airy",
|
|
2146
|
+
"mood": "editorial"
|
|
2147
|
+
},
|
|
2148
|
+
"deep-teal": {
|
|
2149
|
+
"radius": "12px",
|
|
2150
|
+
"serifDisplay": false,
|
|
2151
|
+
"typeBoost": false,
|
|
2152
|
+
"density": "normal",
|
|
2153
|
+
"mood": "trust-finance"
|
|
2154
|
+
},
|
|
2155
|
+
"graphite-dark": {
|
|
2156
|
+
"radius": "14px",
|
|
2157
|
+
"serifDisplay": false,
|
|
2158
|
+
"typeBoost": false,
|
|
2159
|
+
"density": "dense",
|
|
2160
|
+
"mood": "immersive-graphite"
|
|
2161
|
+
},
|
|
2162
|
+
"indigo-violet": {
|
|
2163
|
+
"radius": "16px",
|
|
2164
|
+
"serifDisplay": false,
|
|
2165
|
+
"typeBoost": false,
|
|
2166
|
+
"density": "normal",
|
|
2167
|
+
"mood": "tech-frontier"
|
|
2168
|
+
},
|
|
2169
|
+
"spectrum": {
|
|
2170
|
+
"radius": "14px",
|
|
2171
|
+
"serifDisplay": false,
|
|
2172
|
+
"typeBoost": false,
|
|
2173
|
+
"density": "dense",
|
|
2174
|
+
"mood": "data-board"
|
|
2175
|
+
}
|
|
2176
|
+
},
|
|
2109
2177
|
"styles": {
|
|
2110
2178
|
"business-blue": {
|
|
2111
2179
|
"accent": "1A73E8",
|
|
@@ -2478,7 +2546,7 @@
|
|
|
2478
2546
|
},
|
|
2479
2547
|
"layoutSlots": {
|
|
2480
2548
|
"$comment": "页型布局 IR(Layout Intermediate Representation):全部可交付页型的语义槽位。双通道按同一槽位语义落位;坐标以 layout-constants.json pageTypes 为唯一几何源,scripts/lib_layout_regions.js 将槽位映射为英寸矩形。role: primary/secondary/annotation/chrome。required: true 表示缺了即不合格。",
|
|
2481
|
-
"version": "9.
|
|
2549
|
+
"version": "9.2",
|
|
2482
2550
|
"pageTypes": {
|
|
2483
2551
|
"points": {
|
|
2484
2552
|
"mode": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "页型布局 IR(Layout Intermediate Representation):全部可交付页型的语义槽位。双通道按同一槽位语义落位;坐标以 layout-constants.json pageTypes 为唯一几何源,scripts/lib_layout_regions.js 将槽位映射为英寸矩形。role: primary/secondary/annotation/chrome。required: true 表示缺了即不合格。",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.1",
|
|
4
4
|
"pageTypes": {
|
|
5
5
|
"points": {
|
|
6
6
|
"mode": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "TopPPT HTML · REPORT_MODEL DSL schema 单源。双端同源:scripts/sync_runtime.py 把本文件注入 assets/pptx-export.js 的 __TOPPPT_SCHEMA__ 标记块(浏览器端 validateModel);scripts/extract_model.py 直接读本文件做本地校验。禁止在两端手写副本。字段路径约定:'a.b:c' 中 ':array' 要求非空数组,':str' 要求非空字符串,无后缀仅做真值检查;'anyof:a|b:c' 表示「任一满足即通过」(用于素材图片页:src / items / placeholder 三选一)。pageTypes[].modes = 该页型允许的模式(越界仅告警,不阻断)。commonSectionFields 为任意页型可选的通用字段(flags = 待核实标注清单,image = 素材图片/配图占位)。chartTypes = 图表类型白名单(起含原生与形状两条通道,通道归属见 scripts/layout-constants.json 的 charts.registry)。图片规格与占位约定见同文件 imageSpec。",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.1",
|
|
4
4
|
"modes": [
|
|
5
5
|
"presentation",
|
|
6
6
|
"research",
|
|
@@ -270,25 +270,26 @@ def main() -> int:
|
|
|
270
270
|
print(' [task_routes] FAIL(extract_snippet 不可导入)')
|
|
271
271
|
fails.append('task-routes')
|
|
272
272
|
|
|
273
|
-
# ⑧
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
273
|
+
# ⑧ 浏览器真值测量(可选):静态估算看不到「表格被半幅容器横向裁掉一列」这类真实布局缺陷。
|
|
274
|
+
# 当前解释器可能未装 playwright(托管运行时常见);measure_height.py 会自动回落到
|
|
275
|
+
# 本机已装 playwright 的解释器,因此这里只要能跑 measure_height 就不再跳过。
|
|
276
|
+
mh_fail = []
|
|
277
|
+
for html in examples:
|
|
278
|
+
r13 = run([PY, str(ROOT / 'scripts' / 'measure_height.py'), str(html)])
|
|
279
|
+
out = (r13.stdout or '') + (r13.stderr or '')
|
|
280
|
+
if r13.returncode != 0:
|
|
281
|
+
mh_fail.append(html.stem)
|
|
282
|
+
print(out[-500:])
|
|
283
|
+
elif '跳过:' in out and 'playwright' in out.lower():
|
|
284
|
+
# 解释器与回落链都找不到 playwright → 整批跳过(可选依赖)
|
|
285
|
+
print(' [measure_height] SKIP(playwright 未安装,可选真值裁判)')
|
|
286
|
+
skipped.append('measure-height')
|
|
287
|
+
mh_fail = []
|
|
288
|
+
break
|
|
289
|
+
if 'measure-height' not in skipped:
|
|
286
290
|
print(' [measure_height 页高/容器裁切真值]', 'OK' if not mh_fail else f'FAIL {mh_fail}')
|
|
287
291
|
if mh_fail:
|
|
288
292
|
fails.append('measure-height')
|
|
289
|
-
else:
|
|
290
|
-
print(' [measure_height] SKIP(playwright 未安装,可选真值裁判)')
|
|
291
|
-
skipped.append('measure-height')
|
|
292
293
|
|
|
293
294
|
print('=' * 56)
|
|
294
295
|
if skipped:
|