# Slide Deck Generation (any2deck)

Transform content (Markdown, text, URLs) into professional slide deck images, then merge into PPTX/PDF.

## Workflow

```
Content → Analyze → Confirm Style → Generate Outline → Generate Slide Images → Merge PPTX/PDF
```

### Step 1: Analyze Content

1. Save source content (if pasted, save as `source.md`)
2. Detect language, recommend style preset (see Auto Style Selection below)
3. Determine slide count by content length:
   - < 1000 words → 5-10 slides
   - 1000-3000 words → 10-18 slides
   - 3000-5000 words → 15-25 slides
4. Generate topic slug (2-4 words, kebab-case)

### Step 2: Confirm with User

Present summary: style, audience, slide count, review preferences.

### Step 3: Generate Outline

Create `outline.md` with slide titles, types, layouts, and STYLE_INSTRUCTIONS block. Each slide entry should include narrative goals, key content, and visual description.

### Step 4: Generate Slide Images

Two approaches, choose based on content type:

**Approach A — AI Image Generation (best for visual/artistic slides):**

```
gemini(prompt=<slide prompt>, output_modality="image")
```

**Approach B — HTML + Playwright Rendering (best for text-heavy/data slides):**

Write self-contained HTML for each slide (1920x1080), then render to PNG:

```python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page(viewport={"width": 1920, "height": 1080})
    page.goto("file:///tmp/slide-01.html")
    page.wait_for_timeout(2000)  # wait for web fonts
    page.screenshot(path="01-slide-cover.png")
    browser.close()
```

HTML slide template pattern:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700&display=swap');
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body {
    width: 1920px; height: 1080px;
    font-family: 'Noto Sans SC', sans-serif;
    /* Apply style-specific background, colors, etc. */
  }
</style>
</head>
<body>
  <!-- Slide content here -->
</body>
</html>
```

Key design tips:
- Use Google Fonts `@import` for custom typography (Oswald + Inter for bold-editorial, etc.)
- CSS gradients and box-shadow for glow effects
- Inline SVG for diagrams and icons
- Never rely on external images — everything self-contained in one HTML file

Save images as `NN-slide-{slug}.png` in the output directory.

### Step 5: Apply Branding (opt-in)

If `--logo <path>` is specified, composite the logo onto each slide using Python Pillow:

```python
from PIL import Image

for slide_path in slide_pngs:
    slide = Image.open(slide_path).convert("RGBA")
    logo = Image.open(logo_path).convert("RGBA")
    # Resize logo to target height, maintaining aspect ratio
    logo_h = 46
    logo = logo.resize((int(logo_h * logo.width / logo.height), logo_h), Image.LANCZOS)
    # Position top-right with padding
    x = slide.width - logo.width - 26
    y = 20
    slide.alpha_composite(logo, (x, y))
    slide.convert("RGB").save(slide_path)
```

Skip cover and back-cover slides. For slides where AI-drawn frames clash with the logo, paint a feathered backdrop patch first.

### Step 6: Merge to PPTX

Use `python-pptx` to merge slide images into a PowerPoint file:

```python
from pptx import Presentation
from pptx.util import Inches
import glob, os

prs = Presentation()
prs.slide_width = Inches(13.333)   # 16:9
prs.slide_height = Inches(7.5)

for img_path in sorted(glob.glob("*-slide-*.png")):
    slide = prs.slides.add_slide(prs.slide_layouts[6])  # blank layout
    slide.shapes.add_picture(img_path, 0, 0, prs.slide_width, prs.slide_height)

prs.save("output.pptx")
```

### Step 7: Merge to PDF

Use `img2pdf` for lossless image-to-PDF conversion:

```python
import img2pdf, glob

images = sorted(glob.glob("*-slide-*.png"))
with open("output.pdf", "wb") as f:
    f.write(img2pdf.convert(images))
```

### Step 8: Output Summary

```
Slide Deck Complete!

Topic: [topic]
Style: [preset name]
Location: [directory path]
Slides: N total
PPTX: {topic-slug}.pptx
PDF: {topic-slug}.pdf
```

## Style Presets (16 styles)

| Preset | Best For |
|--------|----------|
| `blueprint` (default) | Architecture, system design |
| `bold-editorial` | Product launches, keynotes |
| `chalkboard` | Education, tutorials |
| `corporate` | Investor decks, proposals |
| `minimal` | Executive briefings |
| `sketch-notes` | Educational, tutorials |
| `notion` | Product demos, SaaS |
| `watercolor` | Lifestyle, wellness |
| `dark-atmospheric` | Entertainment, gaming |
| `editorial-infographic` | Tech explainers, research |
| `intuition-machine` | Technical docs, academic |
| `scientific` | Biology, chemistry, medical |
| `pixel-art` | Gaming, developer talks |
| `vector-illustration` | Creative, children's content |
| `vintage` | Historical, heritage |
| `fantasy-animation` | Educational storytelling |

### Auto Style Selection

| Content Signals | Preset |
|-----------------|--------|
| tutorial, learn, education, guide | `sketch-notes` |
| classroom, teaching, school | `chalkboard` |
| architecture, system, data, technical | `blueprint` |
| creative, children, kids | `vector-illustration` |
| briefing, academic, research | `intuition-machine` |
| executive, minimal, clean | `minimal` |
| saas, product, dashboard, metrics | `notion` |
| investor, quarterly, business | `corporate` |
| launch, marketing, keynote | `bold-editorial` |
| entertainment, music, gaming | `dark-atmospheric` |
| explainer, journalism, science | `editorial-infographic` |
| story, fantasy, animation | `fantasy-animation` |
| gaming, retro, pixel, developer | `pixel-art` |
| biology, chemistry, medical | `scientific` |
| history, heritage, vintage | `vintage` |
| lifestyle, wellness, travel | `watercolor` |
| Default | `blueprint` |

### Custom Style Dimensions

| Dimension | Options |
|-----------|---------|
| **Texture** | clean, grid, organic, pixel, paper |
| **Mood** | professional, warm, cool, vibrant, dark, neutral |
| **Typography** | geometric, humanist, handwritten, editorial, technical |
| **Density** | minimal, balanced, dense |

## Options

| Option | Description |
|--------|-------------|
| `--style <name>` | Visual style preset or `custom` |
| `--audience <type>` | beginners, intermediate, experts, executives, general |
| `--lang <code>` | Output language (en, zh, ja, etc.) |
| `--slides <N>` | Target slide count (8-25 recommended) |
| `--outline-only` | Generate outline only |
| `--regenerate <N>` | Regenerate specific slide(s): `3` or `2,5,8` |
| `--logo <path>` | Brand logo (top-right, skips cover/back-cover) |
| `--presentation` | Strip narration, keep only visual anchors |

## Output Structure

```
slide-deck/{topic-slug}/
├── source-{slug}.md
├── outline.md
├── prompts/
│   └── 01-slide-cover.md, 02-slide-{slug}.md, ...
├── 01-slide-cover.png, 02-slide-{slug}.png, ...
├── {topic-slug}.pptx
└── {topic-slug}.pdf
```

## Slide Modification

| Action | Steps |
|--------|-------|
| **Edit** | Update prompt → regenerate that slide → re-merge |
| **Add** | Create prompt → generate image → renumber → re-merge |
| **Delete** | Remove files → renumber → re-merge |

File naming: `NN-slide-{slug}.png` — only NN changes during renumber, slugs stay fixed.
