# Export Deck

Export the friction analysis presentation as a high-quality PDF with screenshots of every slide.

## Input

The user may provide arguments like `/export-deck` or `/export-deck 300dpi` or `/export-deck light`.
- Default: 300 DPI, optimized PNGs, 1440x932 viewport
- `light`: lower quality optimization for smaller file size
- Custom DPI: e.g. `150dpi`, `300dpi`

## Steps

### 1. Ensure dev server is running

Check if `http://localhost:5174` is reachable. If not, start the Vite dev server:
```bash
cd /home/sagar/trace/dashboards/friction-presentation && npm run dev -- --port 5174
```
Wait for it to be ready before proceeding.

### 2. Write and run the Playwright screenshot script

Create a temporary Playwright script at `/home/sagar/trace/dashboards/friction-presentation/screenshot-slides.mjs`.

**CRITICAL requirements:**

- Uses viewport `{ width: 1440, height: 932 }` (user's actual MacBook Pro screen)
- Sets `deviceScaleFactor` to `Math.ceil(targetDPI / 96)` (default 300 DPI → scale 4)
- Iterates through all slides using `#slide-N` hash navigation
- **Auto-detect total slides**: on first page load, count `.slide` elements rather than hardcoding a number
- Waits 800ms after navigation, 500ms after tab click

**CRITICAL — Example tabs:**

Slides with `ExampleGroup` components have tabbed examples (Example 1 / Example 2). You MUST capture BOTH tabs as separate pages.

- **Naming**: Example slides use `Na.png` / `Nb.png` (e.g. `7a.png`, `7b.png`). Non-example slides use `N.png`.
- **Auto-detect which slides have tabs**: For each slide, check if the current slide's DOM contains `.example-tab` buttons. Do NOT hardcode slide numbers — the deck structure may change.
- **Scope tab clicks to the current slide's DOM**: All slides exist in the DOM simultaneously. You MUST scope your querySelector to the Nth `.slide` element. Otherwise you'll click a tab from a different slide and get identical a/b screenshots.

  ```js
  // CORRECT — scoped to current slide
  const clicked = await page.evaluate((idx) => {
    const slide = document.querySelectorAll('.slide')[idx];
    if (!slide) return false;
    const tabs = slide.querySelectorAll('.example-tab');
    if (tabs.length >= 2) { tabs[1].click(); return true; }
    return false;
  }, slideIndex); // slideIndex is 0-based

  // WRONG — matches tabs from ALL slides, clicks the wrong one
  // document.querySelectorAll('.example-tab')[1].click()
  ```

- **Use `page.evaluate()` for clicking**, NOT Playwright's `.click()` — tabs may be outside the visible viewport and Playwright will timeout waiting for them to be visible.
- **Verify a/b are different**: After capturing, run `md5sum` on all a/b pairs. If any pair has identical hashes, the tab click failed — investigate and fix before proceeding.

**Output location**: Save PNGs to `slides-png/` inside the project directory: `/home/sagar/trace/dashboards/friction-presentation/slides-png/`

**Run location**: The script MUST be run from the project directory (where `playwright` is installed as a dev dependency), NOT from `/tmp/`. Node won't find the `playwright` package otherwise.

Delete the script after running.

### 3. Optimize and set DPI

- Use `pngquant --quality=90-100 --speed 1` to optimize PNGs into `/tmp/slides-opt/` (saves ~50% size with no visible quality loss)
- Clean `/tmp/slides-opt/` FIRST — old files from previous runs will contaminate the PDF
- Use Pillow (from `.venv`) to set DPI metadata: `img.save(f, dpi=(300, 300))`

### 4. Create PDF with TOC bookmarks

**Do NOT just use bare `img2pdf`** — the PDF must have a clickable Table of Contents (outline/bookmarks).

Steps:
1. Create a base PDF with `img2pdf` from the optimized PNGs (ordered correctly: `1.png, 2.png, ..., 7a.png, 7b.png, 8a.png, ...`)
2. Use `pikepdf` to add TOC bookmarks. Structure the TOC to match the nav sections:
   - **The Big Picture** → Introduction, Goals, Key Numbers, Measurement Problem, Tool Comparison
   - **What Goes Wrong** → Each friction pattern with "Example 1" / "Example 2" sub-entries
   - **So What** → Compounding Effect, Users Don't Push Back, Productive Sessions, Where the Leverage Is
   - **Appendix** → Testing & Variance, Methodology, Summary
   - **Closing**
3. Map page indices correctly — account for a/b example pages shifting the count

Output to: `/home/sagar/trace/dashboards/friction-presentation/friction-analysis.pdf`

### 5. Report

Tell the user:
- Total pages in PDF
- File size
- DPI and viewport used
- Which slides had example tab 2 captured
- Confirm TOC bookmark structure

### Tools needed

These should already be installed:
- `playwright` (npm dev dependency in the project)
- `pngquant` (system package)
- `img2pdf` (installed via `uv tool install img2pdf`)
- `Pillow` (in `.venv`)
- `pikepdf` (in `.venv`)

If any are missing, install them before proceeding.

ARGUMENTS: $ARGUMENTS
