# Deck To HTML

> Convert a PDF or PowerPoint deck into a single self-contained interactive HTML presentation — native animated SVG charts, sequenced entrance animations, live-embedded demos, keyboard navigation, and a PDF export path. Use whenever someone wants a deck turned into HTML, an "interactive"/"animated"/"web" version of slides, a pptx/pdf converted to a web deck, or asks to rebuild charts from a deck natively. Triggers on "PPT를 HTML로", "덱을 HTML로", "interactive slides", "html deck", "pptx to html", "pdf to html slides", "animated slide deck".

- Skill: `hunkim/deck-to-html` (Agent Skill, multi-file: 21 files)
- Install (CLI): `npx skillmds@latest add hunkim/deck-to-html`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hunkim/deck-to-html/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: hunkim (https://skillmd.com/u/hunkim)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hunkim/deck-to-html

---


# Deck → interactive HTML

Turn a `.pptx` / `.pdf` into **one self-contained `.html` file** that presents better than
the original: charts redrawn natively so they animate, screenshots kept where the
screenshot *is* the evidence, live demos embedded in-slide, and a clean console.

Everything here was learned building a real investor deck. Follow the order.

## Non-negotiables

1. **Never fabricate data.** Recover real numbers (`references/04-chart-data-recovery.md`)
   or keep the source image. A plausible-looking invented curve in an investor deck is a
   serious failure, not a shortcut.
2. **Content is verbatim** unless the user says otherwise. Fix typos and awkward
   phrasing; flag anything factually inconsistent rather than silently "improving" it.
3. **One HTML file.** All CSS, JS, fonts and images inlined. It must work with the
   network off — you cannot debug a missing CDN from a stage.
4. **QA is not optional.** Every slide screenshotted, 0 console errors, 0 overflow.
   `references/06-qa-and-export.md`.
5. **Load the `slide-design` skill too** if it is available — it governs *what* goes on a
   slide. This skill governs *how* it is built.

## Workflow

### 1 — Read the source before building anything

```bash
markitdown deck.pptx > dump.md                    # text, per slide
soffice --headless --convert-to pdf deck.pptx   # LibreOffice; in Claude's sandbox:
                                                #   python scripts/office/soffice.py ...
pdftoppm -jpeg -r 100 deck.pdf slide              # visual reference for every page
python3 -c "import zipfile;zipfile.ZipFile('deck.pptx').extractall('unpacked')"
```

Look at every rendered page. Then classify each slide:

| Source slide is… | Rebuild as |
|---|---|
| Text, tables, bullet lists | Native HTML |
| A chart drawn with PPT shapes | Native SVG — recover the data from the shapes |
| A chart pasted as an image | Native SVG — recover the data from pixels |
| A screenshot that *is* the evidence (leaderboard, news card, product UI) | Keep the image + animated SVG overlay |
| A URL / demo | Native slide + live `<iframe>` demo overlay |

Full extraction recipes, hidden-slide detection and image↔slide mapping:
`references/01-extract-source.md`.

### 2 — Build the generator, not the HTML

Never hand-write a 5000-line HTML file. Write a Python generator:

```
src/build.py      slide definitions -> emits the single .html
src/style.css     design system + components
src/app.js        runtime (nav, demos, tooltips, count-up)
src/charts.py     native SVG chart builders
src/assets.py     image -> base64 WebP data URI
```

`build.py` inlines `style.css` and `app.js` and replaces `/*__DEMOS__*/` and
`/*__TITLES__*/` placeholders. Copy `assets/` from this skill as the starting point —
they are the proven versions, not sketches. `references/02-architecture.md`.

### 3 — Commit to one design system

Fixed **1280×720** stage, `transform: scale()` to fit any viewport. One background tone
for the whole deck. Every content slide is:

```
kicker  ·  optional numbered badge + h1  ·  one-line sub  ·  .body
```

Same paddings, same type scale, one accent colour. If the deck has a numbered agenda
slide ("Five Advantages"), the badges on the detail slides **must** match that list — and
must stay in deck order. Reordering slides means renumbering both.

### 4 — Animate as sequencing, not decoration

`[data-anim]` + inline `transition-delay`, gated on `.is-active`. The entrance order is
the order you speak in. Slide-to-slide transitions stay quiet — a fast fade and a 1%
nudge, never 3D. `references/03-animation.md`.

### 5 — QA, every time

```bash
node qa.js        # per-slide overflow + pageerrors  (ACTIVE slide only — see gotchas)
node console.js   # full console + requestfailed sweep
node shot.js      # screenshot every slide, then LOOK at them
```

### 6 — Export

`node topdf.js && python3 make_pdf.py` → 16:9 PDF with animations settled.
`references/06-qa-and-export.md`.

## The gotchas that will cost you hours

Read `references/07-gotchas.md` before writing CSS. The five that bite hardest:

- **Two `style` attributes on one element** — the second is silently dropped, so your
  `transition-delay` vanishes and sequencing breaks. Merge them.
- **`preserveAspectRatio="none"` stretches text.** Measure the rendered container and
  match the viewBox aspect, or use `meet`.
- **`flex:1` inside a non-flex parent collapses to zero height** — the chart renders blank.
- **Overflow checks give false positives on inactive slides** — entrance transforms inflate
  `scrollHeight`. Only measure `.slide.is-active`.
- **Percentage `max-height` does not resolve** against an auto-height parent. Constrain by
  width and let height follow.

## Reference index

| File | Covers |
|---|---|
| `references/01-extract-source.md` | pptx/pdf extraction, hidden slides, media mapping, PPT-shape chart recovery |
| `references/02-architecture.md` | generator layout, stage/scaling, slide skeleton, asset pipeline |
| `references/03-animation.md` | `[data-anim]`, SVG draw/grow, `offset-path`, count-up, sequencing rules |
| `references/04-chart-data-recovery.md` | pixel-extracting real data from a chart image, with calibration + validation |
| `references/05-image-overlays.md` | registering an animated SVG onto a screenshot |
| `references/06-qa-and-export.md` | Playwright QA scripts, console hygiene, PDF export |
| `references/07-gotchas.md` | every trap hit in production, with the fix |

`assets/` ships working `style.css`, `app.js`, `assets.py`, and all QA/export scripts.

