# Real Media Capture — Screenshots & Video

Use real captures ONLY when the topic *is* a real interface/tool/site. For abstract concepts, drawn media always wins (you control signal density). Never fabricate a mock and present it as a screenshot of a real product.

## Environment check (do this first)

Capture requires Playwright + Chromium in the execution environment, and network access to the target site. Test cheaply before promising:

```bash
npx playwright --version 2>/dev/null || npm i -D playwright && npx playwright install chromium --with-deps 2>&1 | tail -1
```

If install or target-site access fails (sandboxed/allowlisted networks often block arbitrary domains): tell the user plainly which rung of the media ladder you're falling back to, and build an *honest labeled diagram* ("simplified sketch of the consent screen") instead. A labeled sketch is honest; a pixel-perfect fake is not.

## Screenshots — `scripts/capture-screenshot.mjs`

```bash
node scripts/capture-screenshot.mjs <url> <output.png> [--selector css] [--width 1280] [--full]
```

Workflow:
1. Capture the real page (viewport 1280×800 default; `--selector` to clip one component; `--full` for full-page).
2. **Annotate or it's decoration.** Embed the PNG (base64 data-URI keeps the HTML self-contained; if >300KB, downscale or crop tighter) inside an SVG/positioned-div annotation layer:
   - Numbered callout badges with leader lines to the parts being discussed
   - Spotlight: dim the whole screenshot to ~35% with an undimmed cutout over the relevant region (CSS clip-path or an SVG mask) — switch the cutout as the chunks progress
   - Redact anything sensitive/irrelevant (blur rect) — coherence applies to screenshots too
3. Multi-step UI flows: filmstrip of 3–5 cropped captures with step numbers, connected by arrows — usually beats video.

Annotation rules (these are what make the overlay survive contact with a re-capture):
- **Overlay in the capture's own coordinate space.** Put the PNG in an `<svg>` with `viewBox="0 0 <capture-width> <capture-height>"` and place callouts in those units. Re-capturing at a different device scale then keeps every badge on its target. Percentage or pixel offsets against the rendered size do not survive.
- **Prefer `--selector` over cropping by eye.** Element capture removes the guesswork and keeps annotation coordinates stable across re-runs.
- **One spotlight at a time.** Two bright regions is two ideas, which means a second figure.
- **Every callout number resolves to a line of text** in an adjacent list or caption. An unnumbered arrow, or a number with no matching line, teaches nothing.
- **Re-capture is cheap; faking is banned.** If the UI changed, run the script again. Never patch a stale screenshot by editing pixels, and never assemble a product UI out of `<div>`s.

## Video — `scripts/record-video.mjs` (rare)

Justified only when the lesson is temporal behavior of a real interface that stills cannot carry: layout shift, animation jank, a live-updating feed, a race flashing by.

```bash
node scripts/record-video.mjs <url> <output.webm> [--duration 8] [--actions actions.json]
```

Rules:
- ≤15 seconds, muted, `loop` + `autoplay` only if reduced-motion is not set (gate with JS), `playsinline`, poster frame set to the most informative frame
- A caption ABOVE the video saying exactly what to watch for ("watch the sidebar jump when the ad loads") — unguided video is noise
- Provide the filmstrip fallback for reduced-motion users
- WebM (VP9) for size; if the file exceeds ~2MB, it's too long — cut it
- Ship alongside the HTML (relative path) — videos don't inline well as data URIs

`--actions actions.json` format: `[{"type":"click","selector":"..."},{"type":"wait","ms":500},{"type":"type","selector":"...","text":"..."},{"type":"scroll","y":400}]` — executed in order during recording, so you can capture an interaction, not just a page load.

## Sourcing images that aren't UI

Diagrams of real objects (anatomy, hardware, geography): prefer drawing simplified SVG over hotlinking web images — hotlinks rot, licenses bite, and photographic detail is usually extraneous load. If a real photo is genuinely irreplaceable (astronomy, microscopy), use a public-domain source (NASA, Wikimedia PD), attribute inline, and embed as data-URI.
