diff --git a/.gitignore b/.gitignore
index 74abca3d..fe2cf8f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,9 @@ screenshots/
# Local screenshot scratch folder (capture-steam-interval.ts output)
screenshot-review/
+# Raw screencast frames + intermediate encodes (capture-videos.ts scratch).
+videos/
+
# background-agent git worktrees — never track
.worktrees/
diff --git a/README.md b/README.md
index fc0051c1..87c21861 100644
--- a/README.md
+++ b/README.md
@@ -13,12 +13,22 @@ N64 classic — without leaving your game. It runs as an **in-game overlay** in
Steam's Gaming Mode and as a **standalone app** on the desktop, detecting which
mode you're in and adapting automatically.
-[**Install →**](#install) · [Featured plugins](#featured-plugins) · [All plugins](#all-plugins) · [Supported devices](#supported-devices--testing) · [Docs](#documentation)
+[**Install →**](#install) · [See it in action](#see-it-in-action) · [Featured plugins](#featured-plugins) · [All plugins](#all-plugins) · [Supported devices](#supported-devices--testing) · [Docs](#documentation)
> 🚧 **Pre-launch.** Daily-driven on OneXPlayer devices and tested on Valve's
> Steam Deck. I'm [looking for testers](#supported-devices--testing) on other
> handhelds.
+## See it in action
+
+Set your power limit without leaving your game — TDP presets and a live slider,
+right in the overlay:
+
+
+
+Clips are captured straight from the running overlay — see
+[docs/media-capture.md](docs/media-capture.md).
+
## Install
One command. It downloads the prebuilt binary and overlay, verifies SHA-256,
@@ -271,6 +281,7 @@ before trusting a change). Full dev/build/test loop:
| [Gamepad Navigation](docs/gamepad-navigation-guide.md) | Spatial navigation, focus management |
| [OS Compatibility](docs/os-compatibility.md) | SteamOS, Bazzite, CachyOS specifics |
| [Releasing](docs/releasing.md) | Versioning policy + how releases are cut |
+| [Media Capture](docs/media-capture.md) | Capturing overlay screenshots + video clips |
See [CHANGELOG.md](CHANGELOG.md) for the release history.
diff --git a/docs/media-capture.md b/docs/media-capture.md
new file mode 100644
index 00000000..b6f12224
--- /dev/null
+++ b/docs/media-capture.md
@@ -0,0 +1,177 @@
+# Media capture — screenshots & video clips
+
+Loadout's README and per-plugin pages are illustrated with media captured
+straight from the **running overlay** over its CEF DevTools endpoint
+(`http://localhost:9222` in dev). Two scripts drive the same overlay the same
+way — they share the CDP + navigation + recipe machinery in
+[`scripts/lib/overlay-cdp.ts`](../scripts/lib/overlay-cdp.ts):
+
+| Script | Output | Written to |
+| -------------------------------- | --------------------------------- | ----------------------------------------------------- |
+| `scripts/capture-screenshots.ts` | PNG stills (tracked) | `plugins//assets/screenshot*.png`, `docs/assets/` |
+| `scripts/capture-videos.ts` | animated **WebP** clips (tracked) | `plugins//assets/demo.webp`, `docs/assets/*.webp` |
+
+## Prerequisites
+
+- The overlay running in dev with DevTools exposed: `bun run dev:overlay`
+ (DevTools is baked in via `electrobun.config.ts` → `build.linux.chromiumFlags`).
+- `ffmpeg` on `PATH` — used to encode the captured frames. It's the only extra
+ dependency; the WebP/GIF/H.264 encoders it ships with are all we need.
+
+## Capturing video clips
+
+There are two capture modes, both encoding to WebP with ffmpeg:
+
+- **Per-plugin tours** (`--tours`, the default) — captioned tours defined by
+ each plugin's `tour.json`. See [Per-plugin tours](#per-plugin-tours---tours).
+- **Steam Big Picture** (`--target=steam`) — theme-loader / Store Bridge as
+ they appear in Steam's own UI. See
+ [Steam Big Picture clips](#steam-big-picture-clips---targetsteam).
+
+```sh
+bun run capture:videos --list # list every tour + steam clip
+bun run capture:videos --format=all # also emit GIF + MP4 alongside the WebP
+bun run capture:videos --width=1024 # lighter than the 1280 default
+bun run capture:videos --keep-frames # leave the raw JPEG frames in videos/
+```
+
+### How it records
+
+`Page.startScreencast` streams JPEG frames as the page changes; each frame is
+timestamped on arrival. Frames only arrive on a **visual change**, so a
+deliberate `wait` hold emits no frames — its duration is preserved as the gap
+to the next frame. ffmpeg then re-encodes the frames (with their real
+per-frame durations) to a constant-rate animated WebP. Raw frames land in the
+gitignored `videos//` scratch dir and are deleted unless `--keep-frames`.
+
+## Steam Big Picture clips (`--target=steam`)
+
+Some of the best features — theme-loader's CSS theming and Store Bridge's Epic
+collection — render in **Steam's own Big Picture UI**, not the overlay. That's a
+different CEF surface (port `8080`, discovered via
+[`@loadout/steam-cdp`](../packages/steam-cdp)), but the same screencast → ffmpeg
+pipeline applies.
+
+**Run it from Gaming Mode with Big Picture in the foreground.** CEF only rasters
+its offscreen surface while Steam is actively painting it, so a backgrounded Big
+Picture screencasts blank — the script skips a clip that captures too few
+frames and tells you why.
+
+Two clips ship (`--target=steam --list` to see them):
+
+- **`steam-theme`** — flips theme-loader's injected `