diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1d92e11..b86b0af 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -89,7 +89,14 @@ Some files are produced by scripts; edit the generator, not the output:
- `docs/commands.md` and the website command reference — `npm run docs:commands`
(run after `npm run build`, which writes the oclif manifest).
-- `docs/demo.svg` (the animated README terminal) — `npm run docs:demo`.
+- `docs/demo.webp` (the animated README terminal) — `npm run docs:demo`, which
+ runs [VHS](https://github.com/charmbracelet/vhs) on `docs/demo.tape`. Requires
+ `vhs` and an ffmpeg built with **libwebp** (Homebrew's core ffmpeg lacks it):
+ `brew tap homebrew-ffmpeg/ffmpeg && brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-webp`.
+ Also needs an authenticated pdcli profile (use a sandbox). For a polished,
+ reproducible recording, first run `./scripts/seed-demo.sh` — it builds a clean
+ "pdcli demo" pipeline (sane deal values, a duplicate person, a stale deal so
+ `audit` has findings) and points the tape at it.
`oclif.manifest.json` is generated and git-ignored; never commit it.
diff --git a/README.md b/README.md
index 444c808..63718b0 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[](https://wavyx.github.io/pdcli/)
-
+
Command-line interface for [Pipedrive](https://www.pipedrive.com/) — fast, scriptable, built for terminals, CI pipelines, and AI agents.
diff --git a/docs/demo.svg b/docs/demo.svg
deleted file mode 100644
index 10d94e1..0000000
--- a/docs/demo.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-
diff --git a/docs/demo.tape b/docs/demo.tape
new file mode 100644
index 0000000..1242cff
--- /dev/null
+++ b/docs/demo.tape
@@ -0,0 +1,57 @@
+# docs/demo.tape — regenerate the animated README terminal with VHS.
+#
+# brew install vhs # or: go install github.com/charmbracelet/vhs@latest
+# npm run docs:demo # runs: vhs docs/demo.tape → docs/demo.webp
+#
+# This records REAL pdcli output, so run it against an AUTHENTICATED profile —
+# point it at a sandbox/demo account, not production. The commands below are
+# read-only and show aggregates only (no contact PII). Swap them freely, but
+# avoid mutating commands so the recording is repeatable.
+
+# WebP: crisp + ~10x smaller than GIF, renders in a GitHub . Needs an ffmpeg
+# built with libwebp — Homebrew's core ffmpeg lacks it, so install the tap build:
+# brew tap homebrew-ffmpeg/ffmpeg && brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-webp
+Output docs/demo.webp
+
+Require pdcli
+
+# --- look & feel -------------------------------------------------------------
+Set Shell bash
+Set FontSize 16
+Set Width 1200 # wide enough that no output line clips (the old SVG was 720)
+Set Height 760
+Set Padding 28
+Set BorderRadius 12
+Set TypingSpeed 45ms
+Set CursorBlink true
+# Brand palette (matches the docs site / old demo): dark green ground, mint accent.
+Set Theme { "name": "pdcli", "background": "#0c1611", "foreground": "#c9d4cd", "cursor": "#4ade80", "selection": "#1f2b24", "black": "#0a120e", "brightBlack": "#6b7d72", "red": "#e06c75", "brightRed": "#e06c75", "green": "#4ade80", "brightGreen": "#4ade80", "yellow": "#e5c07b", "brightYellow": "#e5c07b", "blue": "#61afef", "brightBlue": "#61afef", "magenta": "#c678dd", "brightMagenta": "#c678dd", "cyan": "#56b6c2", "brightCyan": "#56b6c2", "white": "#c9d4cd", "brightWhite": "#ffffff" }
+
+# --- start clean -------------------------------------------------------------
+Hide
+Type "clear" Enter
+Show
+
+# --- scenes (read-only) ------------------------------------------------------
+# This account has 2 pipelines, so pipeline-scoped reports need --pipeline.
+# Each scene clears first (Hide/clear/Show) so output starts at the top — keeps
+# tall tables readable and one scene from bleeding into the next. Keep each
+# scene's output SHORT enough to fit the Height above (a full `field list` would
+# overflow and the frame catches it mid-scroll).
+Type "pdcli pipeline health --pipeline 1" Sleep 400ms Enter
+Sleep 3s
+
+Hide
+Type "clear" Enter
+Show
+Type "pdcli funnel --pipeline 1" Sleep 400ms Enter
+Sleep 3s
+
+Hide
+Type "clear" Enter
+Show
+Type "pdcli audit" Sleep 400ms Enter
+Sleep 3.5s
+
+# hold the final frame so the loop doesn't appear cut off
+Sleep 1.8s
diff --git a/docs/demo.webp b/docs/demo.webp
new file mode 100644
index 0000000..9bdd8bc
Binary files /dev/null and b/docs/demo.webp differ
diff --git a/package.json b/package.json
index db2bc5e..5590e08 100644
--- a/package.json
+++ b/package.json
@@ -197,7 +197,7 @@
"scripts": {
"build": "oclif manifest",
"docs:commands": "npm run build && node scripts/gen-commands.mjs",
- "docs:demo": "node scripts/gen-demo.mjs",
+ "docs:demo": "vhs docs/demo.tape",
"lint": "eslint . && prettier --check .",
"lint:fix": "eslint --fix . && prettier --write .",
"test": "vitest run",
diff --git a/scripts/gen-demo.mjs b/scripts/gen-demo.mjs
deleted file mode 100644
index 37a9251..0000000
--- a/scripts/gen-demo.mjs
+++ /dev/null
@@ -1,162 +0,0 @@
-// Generates docs/demo.svg — a self-contained, animated SVG terminal that types
-// two real pdcli commands and reveals their output, on a ~12s loop.
-//
-// Constraints (so it renders inside a GitHub README ):
-// - SMIL only — no