返回 ppt-master
beautify-pptx.md
根目录 / skills / ppt-master / workflows / profiles / beautify-pptx.md
1 ---
2 description: Generate profile for 1:1, content-faithful re-layout of an existing deck through Default or explicit Quick execution.
3 ---
4
5 # Beautify PPTX (Re-layout) Profile
6
7 > Generate profile, not a top-level route. [`template-fill-pptx.md`](../template-fill-pptx.md) reuses a deck's design and swaps in new content; this profile keeps a deck's content and redoes its layout.
8
9 Re-lays-out an existing `.pptx`: text is preserved **verbatim** and source
10 palette / fonts are the preselected recommendation. Only explicit user
11 requirements or final confirmation may override them; never deviate silently.
12 It rebuilds layout, hierarchy, whitespace, and effective visual treatment into
13 a new native deck through the SVG pipeline — not a patch over the original.
14
15 **Trigger**: the user supplies a `.pptx` and asks to beautify / re-layout / 重新排版 / 美化 while keeping the content. Explicit intent + a provided file only; never auto-infer.
16
17 **Hard rule — select one runtime before continuing**: when the same request
18 also meets [`quick-generate.md`](./quick-generate.md)'s explicit trigger, load
19 that runtime and do not load `generate-pptx.md`. Otherwise load
20 [`generate-pptx.md`](../generate-pptx.md) and do not load Quick. The 1:1
21 Beautify constraints in this file apply in either runtime.
22
23 ---
24
25 ## 1. When to Run
26
27 | Pattern | Example |
28 |---|---|
29 | Existing `.pptx` + beautify intent | "把这份 PPT 美化一下" / "make this deck look better" |
30 | Existing `.pptx` + re-layout intent | "重新排版这份 PPT,内容别动" / "re-layout this, keep the wording" |
31 | Existing `.pptx` + paste-back intent | "重排后我要把元素贴回原来的模板" |
32
33 **Hard rule — content is frozen**: every text string from the source is preserved exactly (no add / remove / reword / reorder). Beautification freedom lives only in layout, hierarchy, spacing, and visual rhythm.
34
35 **Hard rule — not a patch, not a fill**: this regenerates a native deck through the selected Default or Quick SVG → PPTX runtime. It does **not** edit the source file in place, and it is **not** [`template-fill-pptx`](../template-fill-pptx.md) (which clones source slides and replaces text). It also does not parse an arbitrary third-party template for text-only substitution (the rejected #53 direction) — it builds every page from scratch.
36
37 **Distinct from mirror templates**: `replication_mode: mirror` ([`executor-structured.md`](../../references/executor-structured.md) §1.1) keeps layout + visuals verbatim and edits text. Beautify is the inverse — content verbatim, layout redone, source identity recommended unless the user overrides it.
38
39 **Distinct from page-image reconstruction**: when the authoritative input is
40 an ordered raster page roster and the user wants its visible layout preserved,
41 activate the Codex-supported, Quick-only
42 [`image-to-pptx.md`](./image-to-pptx.md) instead.
43 Beautify requires a semantic source PPTX and deliberately redesigns layout; the
44 two fidelity profiles never compose.
45
46 **When this profile is wrong — re-architecture belongs to ordinary Generate**: this profile preserves the source's page count and page order 1:1. It is for "keep this deck, just lay it out better". When the user instead wants the original page breakdown reconsidered — merge / split / reorder pages, re-outline the structure, build a *better deck* from the same content rather than a prettier version of the same pages — do not activate this profile. This includes re-pagination for fit: "keep every word but split a crowded page so it reads better" changes page count. Convert the deck with [`ppt_to_md`](../../scripts/source_to_md/ppt_to_md.py) and use ordinary Quick when Quick was explicit, otherwise the Default main pipeline. The deciding question: is the source's page split information to preserve, or just the previous author's structure to improve? Preserve → activate this profile; improve → ordinary Generate in the selected runtime.
47
48 ---
49
50 ## 2. Inputs
51
52 🚧 **GATE**: the user has provided:
53
54 | Input | Required | Notes |
55 |---|---:|---|
56 | Source PPTX | Yes | The deck to re-lay-out |
57 | Beautify scope | Optional | Density / emphasis preference — never content rewrites, and never page drops (v1 is strict 1:1) |
58
59 ---
60
61 ## 3. Create the Project Workspace
62
63 Match the canvas to the source so 1:1 pages and paste-back align. Determine the source aspect first — before the project exists, run `beautify_identity.py <source.pptx>` to **stdout** and read `canvas.aspect` (the formal standard intake bundle is written in Step 4, after `init`) — then `init` with the matching format:
64
65 | Source aspect | Format |
66 |---|---|
67 | ≈1.778 (16:9) | `ppt169` |
68 | ≈1.333 (4:3) | `ppt43` |
69 | other | nearest format in [`canvas-formats.md`](../../references/canvas-formats.md); record the source pixel size in the spec |
70
71 ```bash
72 # Default runtime:
73 python3 ${SKILL_DIR}/scripts/project_manager.py init <project_name> --format <format>
74
75 # Quick runtime instead:
76 python3 ${SKILL_DIR}/scripts/project_manager.py init <project_name> --format <format> --quick-generate
77
78 # Both runtimes then import once:
79 python3 ${SKILL_DIR}/scripts/project_manager.py import-sources <project_path> <source.pptx>
80 ```
81
82 Run exactly one `init` command: the Quick form only when Quick was selected.
83
84 ---
85
86 ## 4. Extract Identity and Data; Assemble Inventory
87
88 Use the standard PPTX intake bundle from Step 3. `project_manager.py import-sources` already writes it under `analysis/` for PPTX-family inputs. If the bundle is missing because the project predates this workflow, generate it once:
89
90 ```bash
91 python3 ${SKILL_DIR}/scripts/pptx_intake.py <project_path>/sources/<source.pptx> -o <project_path>/analysis
92 ```
93
94 **Content + images — already produced by Step 3.** `import-sources` ran `ppt_to_md` on the deck, so the **frozen content contract** is `sources/<stem>.md` (one source slide per block, in order). If the source deck contains pictures, they are already propagated to `images/` with per-slide binding in `images/image_manifest.json` (`occurrences[].slide_index`). Do **not** re-run `ppt_to_md` — it would duplicate the conversion and write images to `analysis/<stem>_files/` instead of `images/`.
95
96 **Visual identity (theme + observed sample + canvas)**: read `<project_path>/analysis/<stem>.identity.json` (intake prefixes per-deck artifacts by source-file stem).
97
98 | Field | Use |
99 |---|---|
100 | `theme.palette.background` / `text` / `primary` / `accent1..6` | the deck's *declared* colors |
101 | `theme.fonts.title` / `body` (`latin` / `ea` / `cs`; `scripts` maps `Hans` / `Hant` / `Jpan` / `Hang` supplemental faces) | the deck's *declared* fonts; use the matching script when `ea` is empty |
102 | `theme.sizes.title` / `body` (pt) | the deck's *declared* placeholder sizes (master `txStyles`) — the size a run inherits when it sets no explicit `sz`; `body` is the **level-1** default (coarsest, commonly over-reads) |
103 | `theme.sizes.body_levels` (pt list) | the full master `bodyStyle` ramp (lvl1..lvl9, e.g. `[32, 28, 24, 20, …]`) — **reference context** so you can read a deeper level than the over-reading level-1, not an auto-seed |
104 | `observed.colors` / `observed.fonts` (`latin` / `ea`, frequency-ranked) | a usage **sample / frequency hint** — run-level fonts + explicit `srgbClr` fills across slides |
105 | `observed.sizes_pt` (pt, frequency-ranked) | a usage **sample** of run-level explicit point sizes — the **size the deck actually renders at** when it overrides the placeholder default; the source for the Step 5 `body_size` recommendation |
106 | `layout_sizes_pt` (pt, frequency-ranked) | **reference fact only**, NOT an auto-seed — the level-1 sizes that the in-use slide layouts' body placeholders declare. Usually empty (decks rely on runs / master) and ambiguous when present; use it as a hint when judging the body size, never as the authoritative seed |
107 | `canvas.aspect` | drives the Step 3 format choice |
108
109 > Note: `theme` is what the deck declares; `observed` is a frequency sample of run-level overrides (not a complete style resolution — it misses `schemeClr` and master/layout inheritance, and counts chart/gradient fills). A hand-edited deck can diverge from `theme` — Step 5 resolves which to use.
110
111 **Hard rule — regenerate visuals, do not carry them over**: charts / tables / images are rebuilt from their data in the effective style, never spliced in byte-for-byte. This keeps the deck style-consistent and natively editable. **Data values are frozen** (categories / series / cell text / numbers unchanged); only their rendering is the deck's own. Pictures (`ppt_to_md`-extracted files) are reused but re-laid-out — position / crop / size follow the new layout, not the source slot. A user who wants an original element verbatim copies it across themselves.
112
113 **Optional source-SVG visual reference**: when the source deck has complex vector decoration, distinctive page chrome, or a visual language that cannot be captured by `<stem>.identity.json` colors/fonts alone, create a read-only SVG reference package under `analysis/`. This is for understanding style only; it is not a carry-over asset path.
114
115 ```bash
116 python3 ${SKILL_DIR}/scripts/pptx_to_svg.py <project_path>/sources/<source.pptx> -o <project_path>/analysis/source_svg_import
117 python3 ${SKILL_DIR}/scripts/extract_svg_assets.py <project_path>/analysis/source_svg_import/svg-flat \
118 --icons-dir <project_path>/analysis/source_svg_import/icons \
119 --icon-namespace imported \
120 --inplace --id-prefix source_flat --min-decoration-bytes 3000 --clean-stale
121 ```
122
123 Use the cleaned `analysis/source_svg_import/svg-flat/slide_*.svg` files plus `analysis/source_svg_import/svg-flat_vector_asset_inventory.json` in Step 5/Strategist. Extraction is required for inspection when complex vectors exist: it creates a candidate pool the AI can index, compare, and judge for possible reuse without reading every heavy vector body. Read an individual `analysis/source_svg_import/icons/imported/*.svg` only when the cleaned page and inventory indicate that candidate may be promoted or materially affects the style decision. These candidates are analysis artifacts first, not automatic output assets.
124
125 Default: do **not** copy these candidates into the project `icons/`, do **not** list them as reusable output assets, and do **not** preserve original vector decorations byte-for-byte in the beautified deck. The Executor still regenerates fresh native shapes from the confirmed plan.
126
127 **Optional reuse gate**: retain source slide, filename, use, and dependencies
128 for a non-text brand/logo/motif/decorative candidate. Default lists it in Step 5
129 and waits; only confirmed candidates are promoted. Quick's current main agent
130 decides directly and stops only when frozen facts lack a lossless preservation
131 path. Promote to `<project_path>/icons/imported/` and reference with
132 `<use data-icon="imported/<name>"/>`; Quick never runs `finalize_svg.py`. Never
133 promote text-bearing groups, charts/tables, page layouts, or dense composites.
134
135 **Assemble the inventory** — the deterministic join into one per-slide ledger, `analysis/beautify_inventory.json`, the contract Step 5 resolves and Step 7 verifies against:
136
137 ```bash
138 python3 ${SKILL_DIR}/scripts/beautify_inventory.py <project_path>/analysis/<stem>.slide_library.json \
139 --images <project_path>/images/image_manifest.json -o <project_path>/analysis/beautify_inventory.json
140 ```
141
142 If `images/image_manifest.json` does not exist because the source deck has no extracted pictures, omit `--images`. The script joins per slide: `text_blocks` (slot text + geometry), `tables` (cell grid), `charts` (categories + series values), `diagrams` (SmartArt nodes + hierarchy/connections + source layout), and `images` (bound via `image_manifest` `occurrences[].slide_index`, with geometry / `usage_count`). The **frozen source values are inlined**, so the inventory is a self-contained contract, not a pointer back to `slide_library.json`. It emits `ignored` and `needs_confirmation` as **empty arrays** — fill them with judgment before Step 5:
143
144 | Field | Fill with |
145 |---|---|
146 | `ignored` | hidden slides / shapes, master-only text, image crop / opacity / rotation / mask (not captured upstream) |
147 | `needs_confirmation` | unreadable SmartArt data; combo / dual-axis / waterfall charts; merged-cell or multi-header tables; density-outlier pages — **either** overcrowded **or** near-empty / title-only |
148
149 **Mandatory — bounded inventory reads**: the complete inventory is the Step 7
150 validation ledger, not the default authoring prompt. Read its compact roster,
151 then the current page; add geometry only for structural ambiguity:
152
153 ```bash
154 python3 ${SKILL_DIR}/scripts/beautify_inventory.py \
155 <project_path>/analysis/beautify_inventory.json --summary
156 python3 ${SKILL_DIR}/scripts/beautify_inventory.py \
157 <project_path>/analysis/beautify_inventory.json --page <N>
158 python3 ${SKILL_DIR}/scripts/beautify_inventory.py \
159 <project_path>/analysis/beautify_inventory.json --page <N> --with-geometry
160 ```
161
162 During authoring, do not bulk-read either complete file.
163
164 **SmartArt output boundary**: Preserve its extracted wording and semantic relationships, then redraw it through SVG as ordinary editable PowerPoint shapes. Do not attempt to regenerate a native SmartArt object or reuse persisted-drawing text as a second content source.
165
166 ```markdown
167 ## ✅ Extraction Complete
168
169 - [x] `sources/<stem>.md` (from Step 3) holds every source slide's text, in order; extracted pictures, if any, are in `images/` + `images/image_manifest.json`
170 - [x] `analysis/<stem>.identity.json` has theme + observed identity + canvas aspect
171 - [x] `analysis/<stem>.slide_library.json` holds chart + table data and SmartArt semantic structure for regeneration
172 - [x] `analysis/source_profile.json` (multi-deck index) summarizes the source facts in its `decks[]` entry
173 - [x] `analysis/beautify_inventory.json` ledgers per-slide text / images / data + ignored + needs-confirmation
174 - [ ] **Next**: Step 5 — resolve Beautify decisions in the selected runtime
175 ```
176
177 ---
178
179 ## 5. Beautify Decisions
180
181 ### Quick branch
182
183 When Quick was selected, do not run the Default confirmation flow below. Apply
184 the same inventory interpretation, source-identity judgment, and body-size
185 method documented in this section, but make the decisions directly in the
186 active context. Explicit user requirements remain authoritative; otherwise use
187 the source identity as the default. Resolve `ignored` and `needs_confirmation`
188 without creating a confirmation payload, Design Spec, lock, or substitute
189 plan. If a flagged complex object cannot be regenerated without losing frozen
190 facts, stop as a hard prerequisite instead of simplifying it.
191
192 **Mandatory — close the transient Quick state before authoring**: before
193 entering §6 and [`quick-generate.md`](./quick-generate.md) §3, resolve every
194 row below in the active context:
195
196 | Transient state | Required closure |
197 |---|---|
198 | Roster and message | Exact source-order roster and one core message per page |
199 | Identity and type | Source identity, palette, fonts, body size, and type-role anchors |
200 | Page geometry | Per-page density, body frame, primary zone, and composition direction |
201 | Meaning and rhythm | Frozen relationships, reading path, neighbor/section rhythm, and ending |
202 | Resources and capabilities | Required local resources are usable; triggered notes, motion, audio, image, icon, formula, Chart/Table, and verification outcomes are decided |
203
204 Keep it transient: create no page/resource plan, Design Spec, lock,
205 confirmation payload, or substitute artifact. Then continue to §6 Quick.
206
207 ### Default branch — Recommend & Confirm
208
209 ⛔ **BLOCKING**: the scope is not hard-coded — same spirit as the Strategist confirmation stage. Recommend each item below from what the deck actually contains (the Step 4 inventory), present the plan, and **wait for the user to confirm or adjust** before writing any spec. Use Generate Step 4's selected surface for the full visual confirmation; keep the structural-scope decisions in chat. Values confirmed through either channel are honored identically.
210
211 This step has two halves:
212 - **Visual re-confirm via the selected confirmation surface** — the **full** Step 4 field set (below), seeded from the source so every targeted-confirmation field (canvas, mode, visual style, palette, icons, typography incl. body baseline, image strategy, generation mode) is **pre-filled with the inherited / source-derived default and left editable**. Beautify *recommends* keeping the source's identity, but never removes the user's place to override any field — you may choose not to change a value, but you must not deny the place to change it. This is also where the deck's text size is confirmed: `<stem>.identity.json` now carries size hints — `observed.sizes_pt` (the point sizes the deck actually renders at) and `theme.sizes` (the declared placeholder defaults) — so the `body_size` recommendation **follows the source's own font size** rather than a blind canvas default; the user still confirms or overrides it here.
213 - **Structural scope** — the inventory-driven list decisions below (ignored, reuse, needs-confirmation, verification level) stay in **chat**; they have no confirm-UI widget.
214
215 | Plan item | Recommend from | Default lean |
216 |---|---|---|
217 | Identity source | `<stem>.identity.json` `theme` vs `observed` | present **both as color / typography candidates in the selected confirmation surface** so the user picks the one that looks right (theme first when the deck is theme-driven; observed first when slides override heavily) — recommend a default ordering and say why |
218 | Preserve scope | inventory `text_blocks` / `images` / `charts` / `tables` / `diagrams` | all text verbatim; data values and SmartArt relationships frozen; pictures reused |
219 | Ignored | inventory `ignored` | name them so the user sees what drops (hidden / master-only text / image crop / rotation) |
220 | Needs confirmation | inventory `needs_confirmation` | flag complex charts + overcrowded pages explicitly; ask how to handle |
221 | Verification level | deck size / risk | recommend the Step 7 per-page checks; user sets strictness |
222
223 **Hard rule — content is frozen, not the scope decisions**: text strings and chart/table/table-cell data values are non-negotiable (verbatim). *Which* identity to inherit, what to ignore, and how to treat flagged items are recommend-then-confirm, never silently decided.
224
225 **Recommend honestly — name the v1 ceiling**:
226
227 | Item | What v1 delivers |
228 |---|---|
229 | Overcrowded source page | layout / hierarchy / whitespace improve **within the page as-is** — v1 does **not** relieve information overload (that needs re-pagination / rewrite, deferred). Flag such pages; the user may accept or note them for manual split |
230 | Paste-back into the original | regenerated elements retain confirmed palette + font declarations; v1 does **not** guarantee coordinate alignment or font availability in the original deck |
231 | Complex charts / merged-cell tables | best-effort from the captured data; combo / dual-axis / waterfall lose the un-captured plots — flagged for the user |
232
233 **Visual re-confirm — full confirmation seeded from the source**:
234
235 Apply [`generate-pptx`](../generate-pptx.md) Step 4's surface decision first. In
236 the default UI branch, use
237 `<project_path>/confirm_ui/recommendations.stage1.json` and
238 `recommendations.stage2.json` at the same two handoffs and launch the same
239 confirm server. In the chat branch, present the same two stages and fields without launching the server or requiring
240 `result.json`. The active, unconfirmed UI stage may be overwritten for a
241 requested regeneration; normal progression leaves confirmed earlier stages
242 intact. Do **not** hide fields: seed **every** targeted-confirmation field with
243 the inherited / source-derived default so the user sees the recommendation and
244 keeps the place to change it. Schema →
245 [`scripts/docs/confirm_ui.md`](../../scripts/docs/confirm_ui.md).
246
247 Rows are abbreviated; follow Confirm UI's four-locale contract and omit `english` for English sources.
248
249 ```json
250 {
251 "primary_language": "<source main language>",
252 "recommend": {
253 "canvas": "<step3-canvas-id>",
254 "mode": "briefing",
255 "visual_style": "<closest visual-style id to the source look>",
256 "icons": "<sensible default icon library>",
257 "image_usage": ["provided"]
258 },
259 "page_count": { "value": "<source-slide-count>" },
260 "audience": { "value": "<carry over from the deck's apparent audience, or state a concrete provisional audience>" },
261 "communication_intent": { "value": "<open prose inferred from the deck; preserve multiple purposes and their relationship>" },
262 "audience_outcome": { "value": "<what the audience should know, understand, decide, or do>" },
263 "core_message": { "value": "<the deck-wide claim / ask / action already present in the source>" },
264 "delivery_context": { "value": "<primary presenter-led / reader-led / hybrid / recorded; hybrid names its lead and secondary use; occasion if inferable>" },
265 "artifact_afterlife": { "value": "<review / approval / archive / hand-off / reuse / none planned>" },
266 "content_divergence": { "value": "keep source wording and page structure verbatim", "locked": true },
267 "color": { "selected": 0, "candidates": [
268 { "name_zh": "复刻源 PPT(推荐)", "name_en": "Source replica (recommended)", "name_ja": "元PPTを再現(推奨)", "palette": { "background": "#...", "secondary_bg": "#...", "primary": "#...", "accent": "#...", "secondary_accent": "#...", "body_text": "#..." } },
269 { "name_zh": "实际用色(observed)", "name_en": "Observed palette", "name_ja": "実際の使用色(observed)", "palette": { "background": "#...", "secondary_bg": "#...", "primary": "#...", "accent": "#...", "secondary_accent": "#...", "body_text": "#..." } },
270 { "name_zh": "备选配色 A", "name_en": "Alternative palette A", "name_ja": "代替配色A", "palette": { "background": "#...", "secondary_bg": "#...", "primary": "#...", "accent": "#...", "secondary_accent": "#...", "body_text": "#..." } }
271 ] },
272 "typography": { "selected": 0, "candidates": [
273 { "name_zh": "复刻源 PPT(推荐)", "name_en": "Source replica (recommended)", "name_ja": "元PPTを再現(推奨)", "heading": { "primary": "...", "english": "...", "css": "<PPT-safe stack>" }, "body": { "primary": "...", "english": "...", "css": "<PPT-safe stack>" }, "body_size": <dominant observed.sizes_pt × 4/3, as px> },
274 { "name_zh": "备选字体 A", "name_en": "Alternative pairing A", "name_ja": "代替ペアリングA", "heading": { "primary": "...", "english": "...", "css": "<PPT-safe stack>" }, "body": { "primary": "...", "english": "...", "css": "<PPT-safe stack>" }, "body_size": <canvas-appropriate baseline> },
275 { "name_zh": "备选字体 B", "name_en": "Alternative pairing B", "name_ja": "代替ペアリングB", "heading": { "primary": "...", "english": "...", "css": "<PPT-safe stack>" }, "body": { "primary": "...", "english": "...", "css": "<PPT-safe stack>" }, "body_size": <canvas-appropriate baseline> }
276 ] }
277 }
278 ```
279
280 - **Recommend keep, allow override**: pre-fill the open communication contract from the source's apparent audience and purpose, preserving composite purposes in prose; also pre-fill canvas / mode / visual style / icons / image strategy with the source-faithful default (canvas = Step 3 format, mode = `briefing`, image_usage = `provided`). The purpose examples are hints, never a `primary_job` selector. Beautify's only true non-choices are frozen text and strict 1:1 page count (changing either means routing to the main pipeline). Seed `content_divergence` to verbatim preservation with `locked: true`; the Confirm UI renders it read-only and the server restores the locked value on every staged submit. A request to reshape wording or page structure routes to the main pipeline instead of weakening this profile.
281 - **Our recommendation is the pre-selected default = the source replica**: for color and typography, author **several candidates** like the from-scratch flow. The pre-selected default (`selected: 0`, the first card) is what beautify recommends — the candidate that **best replicates the source deck's style** (the truest reading of `theme` / `observed`). Replicate-by-default.
282 - **Judge the other alternatives exactly as the from-scratch flow does — fonts as much as colors**: don't invent a beautify-specific rule. Author each non-replica candidate with the **same content-driven judgment the Strategist uses when generating from scratch** (color §e, typography §g), applied to the material this project provides — the source document's content and subject, the company's own theme colors, and any brand signal. Pick the palette **and** the font pairing by what fits *this* deck's content; fonts are chosen by content fit, not just defaulted to a safe face. Reach **≥3 meaningful candidates total**; reasonable font repetition is non-blocking, so never manufacture a different pairing just to satisfy a quota. `primary` always follows the source deck's main language; include `english` only when that language is not English.
283 - **`body_size` is the load-bearing field, and the replica follows the source's own size**: seed the replica candidate's `body_size` from the source's actual body size — take the dominant `observed.sizes_pt` value (the most frequent run-level size, the **body proxy**) and **convert it to px (`× 4/3`)** before seeding, since the system is px-only and the source measures in pt: a source 20pt body becomes `26.67`px, so the replica renders at the source's true size (seeding the bare `20` as px would shrink it ~25% — the pt-as-px trap). Whichever source value you land on below (observed mode, or `theme.sizes.body`) gets the same `× 4/3` conversion. The confirm page writes that px to `result.json` (`body_size`); the chat branch retains the same px in its visible final summary. Neither path performs another conversion or adds `body_size_pt` provenance (pt never enters the contract). The "most frequent = body" read is a proxy, not a guarantee — `observed.sizes_pt` counts every explicit run size (titles, captions, footnotes, chart/label text included, no placeholder-type resolution), so a deck dense with small labels can let a caption size outrank true body; cross-check the proxy against the page's actual body blocks and the sanity range below before trusting it, and prefer the size the body paragraphs visibly render at over the raw mode when the two disagree. Fall back to `theme.sizes.body` (the declared placeholder size) when `observed.sizes_pt` is empty, and to a PPT consumption-mode baseline (`text` 20 / `balanced` 24 / `presentation` 32 px — one fixed value per mode) only when neither is present. Note `theme.sizes.body` is the master `bodyStyle` **level-1 declared default** — a coarse value that commonly **over-reads** the real body density (decks often render body at a deeper outline level or override it smaller), so when you land on this fallback treat it as an upper-ish guess and run it through the sanity check below, never as a precise body size. `theme.sizes.body_levels` and `layout_sizes_pt` are **reference context, not extra fallback tiers**: consult them to judge a saner body value when the deck is theme-driven (`observed` empty) — e.g. a deeper `body_levels` entry or a `layout_sizes_pt` hint may read truer than level-1 — but do not auto-seed from them; the seed chain stays `observed → theme.sizes.body → consumption-mode baseline`, and a theme-driven deck whose body size genuinely can't be pinned cleanly is exactly the case the sanity check is for. The canvas hint stays a **sanity range**, not the seed: if the source's own size lands far outside it (a dense source doc reads tiny on a projection canvas), surface that to the user rather than silently snapping — the replica recommendation is the source's size, the user confirms or overrides. Non-replica alternatives may use the consumption-mode baseline. This is what prevents the deck from exporting at an unintentionally small size while still honoring the source.
284
285 Run Generate Step 4's confirmation orchestration unchanged, including its
286 pre-launch surface decision and the UI branch's pre-wait Stage-1 chat handoff.
287
288 In the UI branch, after the final wait returns, read
289 `<project_path>/confirm_ui/result.json` exactly once. In the chat or delegated
290 branch, retain the visible final summary instead and require no UI result. After
291 any launched UI path, run `--shutdown` before Step 6; do not assume `5050`.
292
293 On confirmation, enter [`generate-pptx`](../generate-pptx.md) Step 4 as Strategist with the plan pre-resolved. The two beautify invariants always hold: the content-faithful clause ([`strategist.md`](../../references/strategist.md) §d Layer 1) and page count = source slide count (strict 1:1). Write the retained final confirmation state completely into `design_spec.md` — `mode` (recommended `briefing`), canvas, `visual_style`, color (e) + typography (g) incl. `body_size` (the reviewed values; skip both recommendation flows) — honoring whatever the user kept or overrode. Do not reopen UI evidence afterward. §VII contains only `Page | Family | Template | Usage` rows for selected `chart` or `table` catalog references; project their family-qualified keys into `spec_lock.md` `page_visualizations`. Qualitative relationships and unmatched Chart/Table plans stay in §IX; Default/Quick makes the mandatory per-page Structure decision before geometry. §VIII contains source pictures for re-layout.
294
295 **Hard rule — §IX is verbatim and 1:1**: each source slide becomes exactly one page, in source order, its text transcribed word-for-word from `sources/<stem>.md`. Do not merge, split, drop, or rewrite. Complete and audit `design_spec.md` first, then author `spec_lock.md` from that Design Spec plus the source/page/template context per `strategist.md` §6 before handing off to the Executor.
296
297 ---
298
299 ## 6. Author + Export
300
301 **Quick**: follow [`quick-generate.md`](./quick-generate.md) §3–4. The
302 Beautify inventory is the exact page roster and frozen-content contract; keep
303 its source order, hand-author every page, run the lockless Quick final checker,
304 and export with `--quick-generate`. Do not run Confirm UI, write a Design Spec
305 or lock, run the Default first-page gate, or call `finalize_svg.py`.
306
307 **Quick — lightweight long-deck review cadence (may adapt for a short deck or
308 semantic boundary)**: after about five pages or at a section
309 boundary, reread only the inventory summary/current-page views and cross-page
310 anchors. Do not run a checker; this is neither a gate nor an approval stop. Send
311 one `authored/total` status after each batch.
312
313 **Default**: run the standard pipeline as follows.
314
315 Run the standard pipeline ([`generate-pptx`](../generate-pptx.md) Steps 6–7). The Executor re-lays-out each page — hierarchy, spacing, alignment, page rhythm — using the semantic anchors in `spec_lock.md` plus current page/source/template context; valid page-local colors, gradients, effects, and export-safe display faces need not be added to the lock. It regenerates charts / tables as native SVG from the extracted data and re-lays-out the source pictures.
316
317 Follow [`generate-pptx`](../generate-pptx.md) Step 7 for the canonical serial
318 post-processing commands, gates, success criteria, and export artifacts.
319
320 ---
321
322 ## 7. Validate Output
323
324 ```bash
325 python3 ${SKILL_DIR}/scripts/source_to_md/ppt_to_md.py <project_path>/exports/<output.pptx>
326 ```
327
328 | Check | Expected |
329 |---|---|
330 | Text fidelity | every source text string appears in the output, unaltered |
331 | Data fidelity | chart categories / series / table cells match the source exactly |
332 | Page count | output slide count equals the source slide count |
333 | Regenerated visuals | charts / tables are native SVG re-themed to the effective palette |
334 | Identity | text / shapes use effective colors + fonts, seeded from `<stem>.identity.json` |
335 | Paste-back | copied elements retain effective palette + font declarations; alignment and font availability are not guaranteed |
336
337 ```markdown
338 ## ✅ Beautify Complete
339
340 - [x] Content + data values verbatim (read-back Markdown matches the source)
341 - [x] 1:1 page count preserved
342 - [x] Effective colors + fonts applied consistently
343 - [x] Charts / tables regenerated as native SVG in the effective style
344 - [x] Native PPTX exported to `exports/`
345 ```
346
347 ---
348
349 ## Current Boundary
350
351 | Capability | Status |
352 |---|---|
353 | Re-layout with verbatim text | Supported |
354 | Source palette / fonts as preselected recommendation, with user-approved overrides | Supported |
355 | Strict 1:1 page mapping | Supported |
356 | Regenerate charts / tables as native SVG from extracted data | Supported |
357 | Re-lay-out source pictures | Supported |
358 | Re-pagination (split dense / merge sparse) | Not in v1 |
359 | Carry source charts / tables / images over byte-for-byte | Out of scope — user copies originals manually if wanted |
360 | Silent visual-style / identity deviation | Out of scope |
361 | Batch / multi-deck beautification | Not in v1 |
362
362 lines MARKDOWN