git:20261005.032b435 to v3.0.0

124 added, 266 removed. Audit A to A.

---
name: pptx-generator
- description: "Build, design, inspect or restyle polished editable PowerPoint (.pptx) decks, slides, pitch decks and speaker notes from outlines, reports, research or templates. Includes measured layouts, native charts, diagrams, visual reference assets and saved-file validation. Generated decks have no slide transitions. Read this before hand-writing python-pptx code or rebuilding a supplied deck."
+ description: "Build, design, inspect or restyle editable PowerPoint (.pptx) decks, slides, pitch decks and speaker notes from outlines, reports, research or an existing template. Measured layouts, native charts, diagrams, visual reference assets and saved-file validation. Decks ship with no slide transitions. Read this before hand-writing python-pptx code or rebuilding a deck someone gave you."
license: MIT
- compatibility: Requires Python 3.8+ with python-pptx and lxml (both pulled in automatically). Charts are native PPTX charts, so matplotlib is not needed. LibreOffice is optional and only used to render a PDF preview.
+ compatibility: Python 3.8+ with python-pptx and lxml (they install together). Charts are native PPTX charts, so matplotlib is not needed. LibreOffice is optional and only used to render a PDF preview.
+ version: v3.0.0
---
# PPTX Generator
- Turn content into a real, editable `.pptx`. The output is a normal PowerPoint
- file - the recipient can retype a number, restyle a colour, or swap a chart
- type. Text, charts and diagrams stay editable; imported images remain images.
-
- ## Why the workflow is shaped like this
-
- The main failure modes are **text that overflows the slide** and
- **inconsistent geometry between slides**. The measured grid, text-fit estimates
- and saved-package checks reduce these failures; they do not replace rendering
- in PowerPoint or LibreOffice. Generated decks must contain no slide transitions. Font metrics
- are heuristic, and imported images are checked for bounds/collisions, not their
- internal label legibility.
+ Turn content into a real, editable `.pptx`. The recipient can retype a number,
+ restyle a colour or swap a chart type: text, charts and diagrams stay editable,
+ while imported pictures stay pictures.
- Respect the order below. In particular, never report a deck as finished without
- running the validator - it is the only thing that has actually looked at the
- bytes.
+ Two things break decks here: **text that overflows its shape** and **geometry that
+ drifts between slides**. The measured grid, the fit estimates and the
+ saved-package checks catch both, though they do not replace looking at a rendered
+ slide - font metrics are estimates, and a figure is checked for bounds, not for
+ whether its labels are readable. Do not call a deck finished without running the
+ validator: it is the one step that has read the saved bytes.
## Shared research and reference assets
- For external facts, images, tables or website style, read
- [`references/shared-scraping.md`](references/shared-scraping.md), which connects
- this skill to `ultimate-scrape-skill`. Skip scraping for local-only work.
+ For outside facts, images or a site's look, read
+ [`references/shared-scraping.md`](references/shared-scraping.md), which wires this
+ skill to `ultimate-scrape-skill`. Local-only work needs none of it.
Before choosing a visual direction, read [`assets/README.md`](assets/README.md)
and open [`assets/template-sheet.jpg`](assets/template-sheet.jpg) or
- [`assets/preview-sheet.jpg`](assets/preview-sheet.jpg). Use relevant references
- for hierarchy, grid, typography and image treatment; do not copy unrelated
- content or imply preview images are editable templates. Check
- [`assets/credits.json`](assets/credits.json) for source and reuse cautions.
+ [`assets/preview-sheet.jpg`](assets/preview-sheet.jpg), then take hierarchy, grid,
+ typography and image treatment from what fits. Do not copy unrelated content or
+ treat a preview as an editable template;
+ [`assets/credits.json`](assets/credits.json) records where each one came from.
## Workflow
- 1. **Check dependencies.** `python -c "import pptx, lxml"` - if that fails, run
- `python -m pip install python-pptx`. lxml arrives with python-pptx.
- `soffice --version` tells you whether a PDF preview is possible; its absence
- is not an error.
-
- 2. **If the input includes an existing deck/template, read
- `references/template-editing.md` before choosing a build path.** Preserve the
- source, inspect its slide structure and rendered appearance, and state what
- can be reused faithfully. `--base` appends slides; it does not replace or
- restyle existing slides. Do not imply otherwise.
+ 1. **Check the dependencies.** `python -c "import pptx, lxml"` should pass; if not,
+ `python -m pip install python-pptx`. `soffice --version` only tells you whether
+ a PDF preview is possible.
- 3. **Draft the content as an outline first**, in prose or bullets, before
- touching JSON. Set audience, purpose and a coherent visual system. Decide the
- single takeaway of each slide. For research, read authoritative sources and
- keep numbered source IDs with URLs and claim coverage. Share this register
- and original image assets with `word-generator` when delivering both formats.
- A deck is an argument, not a document with page breaks.
+ 2. **Working from an existing deck or template? Read
+ [`references/template-editing.md`](references/template-editing.md) before you
+ pick a build path.** Keep the source, inspect its slides and rendered look, and
+ say what can be reused faithfully. `--base` appends slides; it does not replace
+ or restyle the ones already there.
- 4. **Research quickly without starving quality.** Default to *Fast* unless the
- user requests exhaustive research or the topic is high-stakes: write 3–6
- focused questions, run independent searches in parallel, inspect up to five
- strong primary/authoritative pages, and extract only facts needed for the
- slide claims. Record title, URL, access date, key facts and slide/claim IDs
- in one source register. Deduplicate facts and URLs; stop once each key claim
- has support. Use *Deep* mode for disputed/high-stakes claims: widen source
- coverage and reconcile conflicting evidence. Never trade away claim checking
- for speed.
+ 3. **Write the argument before the JSON.** Settle the audience, purpose and one
+ visual system, then give each slide a single takeaway. A deck is an argument,
+ not a document with page breaks. Keep numbered source IDs, and share that
+ register plus the chosen images with `word-generator` when you deliver both.
- For visuals, reuse supplied/local figures first. If authorized web images
- are genuinely needed, use structured search with a small candidate cap
- (about 10 per targeted query), preview/thumbnail-filter first, deduplicate
- before full downloads, and download only the few chosen assets. Save the
- creator, source page, direct URL, rights and attribution beside each choice.
- The embedded-asset helper below is for user-provided PPTX/DOCX files; it is
- not web search or semantic ranking. Cache task research and selected local
- asset metadata so a paired Word/PPT deliverable does not repeat retrieval.
+ 4. **Research enough to be right.** Use the effort policy in
+ [`references/shared-scraping.md`](references/shared-scraping.md): a few focused
+ questions, primary sources, one register holding title, URL, access date and the
+ claims each source supports. Never trade claim checking for speed. Reach for
+ supplied and local figures first; for authorised web images, search small
+ (about 10 candidates per query) and preview, deduplicate and record creator,
+ source page, direct URL and licence before a full download. The step-6
+ extractor handles user-supplied PPTX/DOCX files and does not judge relevance,
+ so cache this work and a paired Word deliverable will not repeat it.
- 5. **Write a deck spec JSON** (schema below), choosing a layout per slide from
- the table further down. Write the `title` as a claim, not a label.
+ 5. **Write the spec JSON**, one layout per slide, each `title` a claim rather than
+ a label. The spec format, every layout and its fields, and the script map are in
+ [`references/deck-schema.md`](references/deck-schema.md).
- 6. **Use visuals and build it.** Reuse user-provided figures and original assets
- from a paired DOCX first. For images already embedded in a PPTX/DOCX, run the
- bounded local shortlist tool before rebuilding; it writes a contact sheet,
- dimensions, SHA-256 deduplication and use locations. Example:
+ 6. **Build it, using the visuals you chose.** Reuse the user's figures, then the
+ images from any paired DOCX. For pictures already inside a PPTX or DOCX, run
+ the bounded local shortlist tool first: it writes a contact sheet with
+ dimensions, SHA-256 deduplication and where each asset is used.
```bash
python scripts/extract_office_assets.py source.pptx --out work/assets --max-assets 12 --spec deck.json
python <skill-path>/scripts/build_deck.py deck.json -o deck.pptx
```
- This extractor only inventories local embedded raster images; it does not
- scrape the web, infer semantic relevance, or establish reuse rights. Open its
- contact sheet, pick only relevant assets, cite/license them where needed, and
- add chosen paths to the spec. Add `--base their-template.pptx` only when the
- supplied deck is intended as an append-only base.
+ Open its contact sheet, pick what is relevant, cite what needs citing, and put
+ the chosen paths in the spec. It inventories local embedded images only: it
+ does not scrape or decide what you may reuse. Add `--base their-template.pptx`
+ only for an append-only base.
- 7. **Keep slides transition-free.** Do not add fades, wipes, automatic advances
- or transition instructions in notes. The builder removes inherited slide
- transitions from the output copy when using `--base`; the source stays intact.
+ 7. **Keep it transition-free.** No fades, wipes, automatic advances or transition
+ notes. With `--base`, the builder strips inherited transitions from the output
+ copy and leaves the source alone.
- 8. **Validate, and read the warnings:**
+ 8. **Validate, and read the warnings.**
```bash
python <skill-path>/scripts/validate_deck.py deck.pptx --expect <n> --strict
```
- Errors are hard failures: a shape off the slide, overlapping text, a table that grows past the bottom of the slide, or an embedded slide transition.
- Warnings mean it will open but probably looks wrong - text likely overflowing
- its box, a table that will auto-grow, or type below 10pt. Overflow
- warnings mean the slide is carrying too much text. Fix it by splitting the
- slide or cutting words - **not** by lowering the font size. Tables are
- measured, not skipped, so a cramped table is reported like any other slide.
-
- 9. **Render and inspect** every slide with installed PowerPoint or LibreOffice,
- when available. Check actual wrapping, figure-label size, contrast, clipping,
- whitespace and narrative rhythm. Fix the spec and rebuild; no validator can
- certify visual perfection. Do not modify the user template in place.
-
- 10. **Report** the output path, slide count, theme, zero-transition check,
- structural result and whether rendering/visual review actually occurred.
- Do not paste the deck's contents back into chat or call unrendered output flawless.
-
- ## Deck spec schema
-
- Only `title` and `slides` are required. Every layout accepts `notes` (speaker
- notes) and `source` (citation line, right-aligned above the footer).
-
- ```json
- {
- "title": "How the Blue LED Was Invented",
- "subtitle": "Three decades, three researchers, one stubborn crystal",
- "author": "Your Name",
- "theme": {
- "primary": "1E3A5F", "accent": "2563EB", "highlight": "A16207",
- "text": "0F172A", "muted": "475569", "panel": "E9EEF5", "border": "CBD5E1",
- "font_head": "Segoe UI", "font_body": "Segoe UI", "font_mono": "Consolas",
- "bg_dark": "04121F", "deep": "0A2540", "ocean": "0E4C7A",
- "cyan": "22D3EE", "cyan_soft": "7DD3FC", "warm": "F59E0B", "alarm": "EF4444"
- },
- "slides": [
- {"layout": "title", "kicker": "Materials Science", "title": "How the Blue LED Was Invented",
- "subtitle": "Three decades, three researchers, one stubborn crystal",
- "author": "Your Name", "date": "2026"},
-
- {"layout": "section", "number": "01", "title": "The Long Wait",
- "text": "Why red and green came first"},
-
- {"layout": "bullets", "title": "Blue was the last colour to fall",
- "bullets": ["**Red** (1962) and **green** (1968) were solved within a decade.",
- "Blue needs a much wider band gap than any known material allowed."],
- "body_size": 16, "notes": "Detail that belongs in the talk, not on screen."},
-
- {"layout": "two_column", "title": "Two candidate materials",
- "left": {"heading": "ZnSe", "bullets": ["Direct band gap", "Short lifetime"]},
- "right": {"heading": "GaN", "bullets": ["Tougher crystal", "No p-type doping (yet)"]}},
-
- {"layout": "stats", "title": "The breakthrough in numbers",
- "items": [{"value": "1993", "label": "First practical blue LED"}]},
-
- {"layout": "timeline", "title": "Thirty years to a blue light",
- "items": [{"date": "1989", "label": "Amano", "text": "p-type GaN achieved"}]},
-
- {"layout": "table", "title": "Band gaps by colour", "headers": ["Colour", "Material", "Gap (eV)"],
- "rows": [["Blue", "InGaN", "3.4"]]},
-
- {"layout": "chart", "title": "Efficiency overtakes the filament lamp",
- "chart_type": "line", "unit": "lumens per watt",
- "categories": ["1970", "2010"], "series": [{"name": "White LED", "values": [1, 130]}]},
-
- {"layout": "stack", "title": "The InGaN junction", "items": [
- {"label": "p-type GaN", "note": "Hole supply", "marker": "+"},
- {"label": "InGaN active layer", "note": "Recombination emits light", "marker": "hv"}]},
-
- {"layout": "quote", "text": "The citation text.", "attribution": "Source, 2014"},
- {"layout": "image", "title": "A packaged LED", "image": "assets/led.png", "caption": "Caption."},
- {"layout": "closing", "title": "Thank you", "text": "Questions welcome.", "credit": "Sources: ..."}
- ]
- }
- ```
-
- ### Layout reference
-
- Light-background layouts use the standard header grid. Dark layouts
- (`hero`, `statement`, `hero_stat`, `network`, `forces`, `cutaway`, and
- `flow` with `"dark": true`) paint their own full-bleed background.
-
- | `layout` | Key fields | Notes |
- |----------|-----------|-------|
- | `title` | `title`, `kicker`, `subtitle`, `author`, `date` | Full-bleed navy opening. |
- | `section` | `number`, `title`, `text` | Divider. Its `title` becomes the running `kicker` on later slides. |
- | `bullets` | `title`, `bullets`, `body_size` | Auto-sizes 20pt down to 12pt. Use `body_size` for reference lists. |
- | `two_column` | `title`, `left`, `right` (`{heading, bullets}`) | For genuine comparisons only. |
- | `stats` | `title`, `items` (`{value, label}`) | 2-4 cards. Value shrinks with length. |
- | `timeline` | `title`, `items` (`{date, label, text}`) | **2-6 items.** More raises an error - split the slide. |
- | `quote` | `text`, `attribution` | Breaks a run of bullet slides. |
- | `table` | `title`, `headers`, `rows` | Keep to <= 5 columns. Rows are sized to their tallest cell and columns to their content, so the table cannot grow over the footer; a table that would need under 12pt raises instead. |
- | `chart` | `title`, `chart_type`, `categories`, `series`, `unit`, `bullets` | `bar`, `hbar`, `line`, `area`, `pie`, `doughnut`. Native and editable. |
- | `stack` | `title`, `items` (`{label, note, marker}`) | Layered structure bands. Max 8. Label, note and marker occupy measured columns with a reserved gutter, so a long note cannot run into its marker. |
- | `image` | `title`, `image`, `caption`, `alt` | Local PNG/JPEG path relative to spec JSON (API uses caller paths). Contained, never distorted. `alt` describes the message; caption is the fallback. |
- | `closing` | `title`, `text`, `credit` | `credit` is where template/attribution lines go. |
- | `hero` | `kicker`, `title`, `subtitle`, `meta` | Cinematic opening: ocean floor, grid, glowing cable. |
- | `statement` | `kicker`, `title`, `text` | Giant typography on a dark ambient background. |
- | `hero_stat` | `kicker`, `value`, `unit`, `text` | One enormous number. Sets the case up to 120pt. |
- | `split` | `title`, `left`, `right`, `text` | Two illustrative panels joined by a cyan route. |
- | `flow` | `title`, `steps`, `chips`, `vessel`, `dark` | Vertical chain plus an ocean cross-section strip. |
- | `journey` | `title`, `stations`, `zones` | Cross-section with labelled stations above and below. |
- | `cutaway` | `title`, `layers`, `note` | Vertical cutaway with leader lines to callouts. Dark. |
- | `network` | `title`, `nodes` (`{name, x, y}`), `links` (`[[i,j]]`), `note` | Conceptual node graph. Normalised 0-1 coords. |
- | `forces` | `title`, `items`, `note` | Warning callouts above a seabed. Dark. |
- | `compare` | `title`, `left`, `right` (`{heading, bullets, motif}`) | `motif` is `signal` or `light`; drawn, not emoji. |
- | `trinity` | `title`, `items`, `text` | Three stacked statement bands with arrows. |
- | `sequence` | `title`, `steps`, `highlight`, `network`, `note` | Horizontal chain; `highlight` marks the failure in red. |
-
- Inline `**bold**` works inside any bullet or text field.
-
- For a process with explicit source/context → action → outcome, use the native
- `sequence` or `flow` layout before reaching for unrelated photos. For a
- comparison that must fit a single page, use `compare`; for substantive evidence
- or a topic-specific hero, use a relevant image slide and a short caption. The
- image extractor is an inventory/shortlist step—not an auto-insertion feature.
- A selected asset must be explicitly referenced by an `image` slide or an image
- block in a companion Word spec; otherwise it remains unused by design.
-
- ## How the scripts fit together
-
- The workflow is a pipeline of small parts, not one program, because each part
- answers a different question and each can be run and tested alone:
-
- | File | Owns |
- |------|------|
- | `scripts/textmetrics.py` | Text and table measurement. The single owner of "how many lines does this need, how tall is that row, how wide is that column". No python-pptx import, so it is testable alone. |
- | `scripts/build_deck.py` | Spec JSON -> `.pptx`. Layout, theme tokens, freeform geometry. Imports its measurements from `textmetrics` and never re-derives them. |
- | `scripts/extract_office_assets.py` | Bounded PPTX/DOCX embedded-raster shortlist, SHA-256 deduplication, source-slide tracking, contact sheet and spec-use audit. No network or external dependencies. |
- | `scripts/validate_deck.py` | Re-reads the saved package and gates it. Re-measures with the *same* functions as the builder, so the two can never disagree. |
- | `tests/test_layout_rules.py` | Assert-based regression checks for the layout rules, including the two bugs that once shipped (a table sized for its shortest cell; a stack note box reaching into the marker column). |
-
- The one-way dependency is `textmetrics` <- `build_deck` / `validate_deck`. If you
- find yourself copying a line-count or width estimate into a new script, stop and
- import it instead: an estimate that exists twice is how a deck passes validation
- and still looks broken.
+ Errors are hard failures: a shape off the slide, overlapping text, a table
+ growing past the bottom, an embedded transition. Warnings mean it opens but
+ probably looks wrong: text spilling out of its box, an auto-growing table, type
+ below 10pt. Overflow means too much content - split the slide or cut words,
+ never shrink the font.
- Run the checks with:
+ 9. **Render it and look at every slide**, with installed PowerPoint or
+ LibreOffice. Check real wrapping, figure-label size, contrast, clipping,
+ whitespace and rhythm, then fix the spec and rebuild. No validator can certify
+ that a deck looks good, and you never edit the user's template in place.
- ```bash
- python <skill-path>/tests/test_layout_rules.py
- ```
+ 10. **Report** the output path, slide count, theme, the zero-transition check, the
+ structural result, and whether rendering and visual review actually happened.
+ Do not paste the deck back into chat or call unrendered output flawless.
## No slide transitions
- Slide transitions are intentionally unsupported in this collection. The builder
- removes inherited `<p:transition>` elements from an output copy, and validation
- fails if any remain. Zero transitions is a requirement, not a warning. Never
- modify the original reference/template just to remove its transitions.
+ Transitions are deliberately unsupported here. The builder removes inherited
+ `<p:transition>` elements from an output copy, and validation fails if any remain.
+ Zero transitions is a requirement, not a warning. Never strip them from the user's
+ original template just to satisfy it.
## Themes and design tokens
- Every colour is a token in the spec's `theme` block, so re-skinning a deck is a
- five-line edit and never a hunt through literals. `build_deck.py` ships a
- "Research Lab" light palette and the deep-ocean tokens (`bg_dark`, `deep`,
- `ocean`, `cyan`, `cyan_soft`, `warm`, `alarm`) used by the dark layouts.
+ Every colour is a token in the spec's `theme` block, so a re-skin is a five-line
+ edit rather than a hunt through literals; `build_deck.py` ships a light palette
+ and the deep-ocean tokens the dark layouts use.
- Two hard constraints:
+ - **The font has to exist on the machine that opens the deck.** python-pptx
+ cannot embed fonts, so a Google font silently substitutes and the deck renders
+ in something you never chose. Prefer `Segoe UI`, `Calibri`, `Arial` or
+ `Consolas`, and warn the user before naming a display face.
+ - **The 12pt floor is real.** The validator flags anything under 10pt except the
+ deliberately small footer and citation shapes, marked `chrome:` to stay quiet.
- - **Fonts must exist on the machine that opens the deck.** python-pptx cannot
- embed fonts, so a Google font named in the spec silently substitutes and the
- deck renders in something you never chose. Prefer `Segoe UI`, `Calibri`,
- `Arial` or `Consolas`, all of which are present on Windows. If the user wants
- a display face, say so rather than shipping a deck that looks different on
- their machine than it did on yours.
- - **The validator flags anything below 10pt**, except the deliberately small
- footer and citation shapes, which are marked `chrome:` precisely so they do
- not generate noise.
+ ## Rules that are not negotiable
- Set `"dark": true` on `flow` to place it on the dark background. The dark
- layouts paint their own canvas, so they do not use the standard header grid.
+ For an existing template or deck, [`references/template-editing.md`](references/template-editing.md)
+ applies too. Be specific about what you did: appended slides, rebuilt the deck in
+ the same visual style, or edited the supplied slides in place.
- ## Choosing content, not just layout
+ - **Never shrink type below 12pt to make something fit.** Split the slide.
+ - **Never state a licence or attribution you have not checked at the source.**
+ SlidesCarnival templates are CC BY 4.0, so a credit is required.
+ - **Never invent a citation, statistic, quotation or number.** Research it or
+ leave it out, and label a conceptual map as conceptual.
+ - **Never scrape or script-download** templates from sites that want an account,
+ and never work around a paywall. Ask the user for the file.
+ - **Never claim a chart or feature is present** without the validator confirming it.
+ - **Always run the validator** before you tell the user the deck is ready.
- Read `references/design-rules.md` before writing a spec of any size: the type
- scale, the six-bullets-six-words guideline, narrative arcs, chart conventions
- (always label the unit; never truncate a bar axis), and the anti-patterns. The
- script estimates fit and creates a normal package; that file guides editorial quality.
+ ## Editorial quality and no-library fallback
- For anything with real evidence in it, read `references/free-assets.md` - it has
- licence facts verified at source, and the attribution duties that follow.
+ Read [`references/design-rules.md`](references/design-rules.md) first for the type
+ scale, the six-bullets-six-words guideline, narrative arcs and chart conventions:
+ the script gets the geometry right, that file gets the content right. For anything
+ with real evidence in it, [`references/free-assets.md`](references/free-assets.md)
+ has licence facts checked at the source and the attribution they require.
- ## Rules that are not negotiable
+ If `python-pptx` cannot be installed, read
+ [`references/fallback.md`](references/fallback.md) before promising an output.
- For existing templates/decks, also follow `references/template-editing.md`. Be
- explicit about whether you appended slides, rebuilt a deck from the visual style,
- or edited the supplied slide content in place.
+ Changing this guide? Read
+ [`references/skill-evolution.md`](references/skill-evolution.md) first: edits are
+ scored against a contract and land only on strict improvement.
- - **Never lower a font below 12pt** to make text fit. Split the slide.
- - **Never state a licence or attribution claim you have not checked** at the
- source. SlidesCarnival templates are CC BY 4.0 - a credit is mandatory.
- - **Never fabricate a citation, statistic, quotation or number.** If the deck
- needs a figure you do not have, research it or leave it out. Label
- conceptual maps and diagrams as conceptual rather than implying they are
- authoritative.
- - **Never scrape or script-download** templates from sites that require an
- account, and never bypass a paywall. Ask the user for the file.
- - **Never claim a chart or feature is present** without the
- validator confirming it.
- - **Always run the validator** before telling the user the deck is ready.
+ <!-- SLOW_UPDATE_START -->
+ ## Rules that survived every revision
- ## Fallback when python-pptx cannot be installed
+ Distilled across many decks. Ordinary edits do not rewrite these; only a
+ gate-passing slow update does.
- If there is no package manager and no network, say so plainly rather than
- producing a broken deck. A `.pptx` is a ZIP of OOXML parts, so a minimal deck
- can be written with `zipfile` and string templates, but that path supports
- almost none of the layouts above. Prefer asking the user to install
- `python-pptx`.
+ - **The validator is the only thing that has read the file.** A deck that built is
+ not a deck that is right.
+ - **Never shrink text to fit.** Overflow means too much content: split it or cut
+ words. The 12pt floor holds in every layout.
+ - **Zero transitions, always.** The builder strips inherited ones from the output
+ copy and the validator rejects survivors.
+ - **Never invent a number, a quote or a source.** A plausible fabricated statistic
+ is the worst thing a deck can carry.
+ - **A preview is not a template and a download is not a licence.** Record what an
+ asset allows before it goes on a slide.
+ - **Say which checks ran.** A render you did not perform is not a visual review.
+ <!-- SLOW_UPDATE_END -->
- If LibreOffice is present, `soffice --headless --convert-to pdf deck.pptx`
- produces a PDF you can look at. Installed PowerPoint can also export PDF and PNG
- slides. Structural validation does not replace looking at rendered slides; say
- which checks you actually performed. `--strict` fails on warnings too. Missing
- alt text and picture/text collisions are checked, bar axes start at zero, theme
- backgrounds are explicit, and text that cannot fit at the floor raises rather
- than silently returning the smallest font. Shorten content instead of hiding it.
+ <!-- APPENDIX_START -->
+ Before you answer: the source is intact, the output is a new path, the validator
+ ran, the deck has no transitions, and every claim you report is one you verified.
+ <!-- APPENDIX_END -->