diff --git a/README.md b/README.md
index f919abe..076bc2f 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,8 @@ desktop, or multi-user access platform.
+ alt="mir listing your machines, attaching to a tmux session on one of them,
+ then minting a read-only invite that expires in an hour">
## Beta
diff --git a/assets/demo.sh b/assets/demo.sh
index 330e998..12756d6 100644
--- a/assets/demo.sh
+++ b/assets/demo.sh
@@ -1,42 +1,116 @@
#!/usr/bin/env bash
-# Illustrative Miranda demo for the README GIF — scripted (not a live capture) so the
-# story is tight and reproducible. Rendered via assets/demo.tape with charmbracelet/vhs.
+# Illustrative Miranda demo for the README GIF — authored output, not a live
+# capture, so the story stays tight and reproducible. Rendered by
+# assets/demo.tape with charmbracelet/vhs:
+#
+# vhs assets/demo.tape # run from the repo root
+#
+# Honesty rule for this file: every line it prints is a line the current `mir`
+# prints. The overview screen is go/internal/cli/overview_model.go's Render()
+# output; the attach banner is overview.go's; the `mir share` block — header,
+# QR, both invite lines, the wait line — was captured verbatim from a real run
+# against relay.sourceful-labs.net. That invite has long since expired. The
+# tmux screen and the shell prompt are the user's own programs, not mir's.
set -u
-C=$'\033[0m'; DIM=$'\033[2m'; B=$'\033[1m'
-G=$'\033[32m'; CY=$'\033[36m'; YL=$'\033[33m'; MG=$'\033[35m'; GY=$'\033[90m'
-PR="${DIM}~${C} ${MG}\$${C} " # local prompt
-RP="${CY}macmini${C}:${DIM}~${C} ${MG}\$${C} " # "remote" prompt
+C=$'\033[0m'; DIM=$'\033[2m'; B=$'\033[1m'; MG=$'\033[35m'
+STATUS=$'\033[30;42m' # tmux's default status bar: black on green
+ALT_ON=$'\033[?1049h\033[?25l' # overview.go: altScreenOn
+ALT_OFF=$'\033[?25h\033[?1049l' # overview.go: altScreenOff
+CLS=$'\033[H\033[2J' # overview.go: clearScreen
+PR="${DIM}~${C} ${MG}\$${C} " # the demo user's shell prompt
-printf '\033[H\033[2J' # wipe the `bash assets/demo.sh` invocation line — start clean
+cmd() { printf "%b%b%b\n" "$PR" "$B" "$1$C"; sleep 0.9; }
-# cmd — render a prompt and a typed command, with a beat before output.
-cmd() { printf "%b%b%b\n" "$1" "$B" "$2$C"; sleep 0.55; }
-out() { printf "%b\n" "$1"; sleep 0.18; }
+# ── the overview, exactly as overviewModel.Render() draws it ──────────────────
+overview() {
+ printf '%s%s' "$ALT_ON" "$CLS"
+ printf '\r\n'
+ printf ' %smir%s%s — your machines%s\r\n' "$B" "$C" "$DIM" "$C"
+ printf '\r\n'
+ printf ' ▸ ● workstation\r\n'
+ [ "${1:-}" = "windows" ] && printf ' %s3 windows — agent, build, logs%s\r\n' "$DIM" "$C"
+ printf ' ● builder\r\n'
+ printf ' ○ pi\r\n'
+ printf '\r\n'
+ printf ' %senter attach · s share · r rename · x retire · q quit · ? help%s\r\n' "$DIM" "$C"
+}
-sleep 0.4
-cmd "$PR" "mir up"
-out " ${G}✓${C} serving ${B}macmini${C} ${DIM}·${C} wallet ${YL}G4XC6h…k4kN${C} ${DIM}·${C} relay.sourceful-labs.net"
-out " ${G}✓${C} LAN-direct on ${DIM}(mDNS + QUIC)${C} ${DIM}·${C} persistent tmux ${DIM}·${C} ${DIM}the relay never sees your shell${C}"
-sleep 0.7
-printf "\n%b\n\n" "${GY}── from your laptop, anywhere ───────────────────────────────${C}"
-sleep 0.3
+# ── what the far end paints once the data channel is up: plain tmux. tmux
+# takes the alt screen itself, which is why detaching puts the banner back.
+tmux_screen() {
+ local rows cols left right
+ rows=$(tput lines); cols=$(tput cols)
+ left='[main] 0:agent* 1:build- 2:logs'
+ right='"workstation" 15:42 30-Aug-26 '
+ printf '%s%s' "$ALT_ON" "$CLS"
+ printf 'workstation:~/src/ingest $ ./agent run --plan refactor.md\r\n'
+ printf '[13:58:04] step 4/9 rewrote loader.go, splitter.go\r\n'
+ printf '[14:19:40] step 5/9 go test ./... — 312 passed\r\n'
+ printf '[15:41:57] step 6/9 migrating fixtures … 41%%\r\n'
+ printf '%s▉%s' "$B" "$C"
+ printf '\033[?7l\033[%d;1H%s%s%*s%s%s\033[?7h' "$rows" "$STATUS" "$left" \
+ "$(( cols - ${#left} - ${#right} ))" '' "$right" "$C"
+}
+
+printf '%s' "$CLS" # wipe the `bash assets/demo.sh` invocation line
+sleep 0.8
-cmd "$PR" "mir list"
-out " ${MG}📣${C} new device ${B}\"macmini\"${C} joined your wallet"
-out " ${B}macmini${C} ${DIM}a1b2c3d4…${C} ${G}online${C} ${DIM}· LAN-direct${C}"
-out " ${B}linux${C} ${DIM}d4e5f6a7…${C} ${G}online${C} ${DIM}· relay${C}"
+# 1. bare `mir` opens your machines.
+cmd "mir"
+overview
+sleep 2.2
+
+# 2. Enter attaches. overview.go leaves the alt screen, prints the banner on
+# stderr, then the machine's own tmux paints over it.
+printf '%s' "$ALT_OFF"
+printf '[mir] attached to workstation — Ctrl-O then d comes back to your machines\r\n'
sleep 0.7
+tmux_screen
+sleep 3.2
+
+# 3. Ctrl-O d comes back: tmux gives the screen up, then the overview redraws.
+# The row now remembers what is running over there.
+printf '%s' "$ALT_OFF"
+overview windows
+sleep 2.2
-cmd "$PR" "mir attach macmini"
-out " ${DIM}[mir]${C} ${B}macmini${C} — peer-to-peer, ${CY}Noise-encrypted end-to-end${C} ${DIM}(no SSH, no port-forward)${C}"
-sleep 0.5
-cmd "$RP" "uptime"
-out " 14:32:07 up 3 days, 2:11, load average: 0.11, 0.09, 0.05"
+# 4. q quits to the shell; one invite, read-only, gone in an hour.
+printf '%s' "$ALT_OFF"
+cmd "mir share --ttl 1h workstation"
+printf 'Share "workstation" — read-only access until 16:42.\n'
+printf '\n 📱 Have your guest scan this:\n\n'
sleep 0.3
-cmd "$RP" "whoami && hostname"
-out "fredrik"
-out "macmini"
-sleep 0.4
-printf "%b%b" "$RP" "${B}▉${C}"
-sleep 1.6
+/bin/cat <<'QR'
+█████████████████████████████████████████████████████
+█████████████████████████████████████████████████████
+████ ▄▄▄▄▄ ██▀█▀▄▄▄█▄▀▀▄▄▀▀ █ ▄ █▀ █▀▄█ ▄▄▄▄▄ ████
+████ █ █ █▄ █▄▄███▄▄▄█▀ ▀█▀ █▄▀█▄██ ▀█ █ █ ████
+████ █▄▄▄█ ██▀ █▄▄▀▄ ▄▄▄ ▄ ▄ ▄▄▄█ █▄▄▄█ ████
+████▄▄▄▄▄▄▄█ ▀▄█▄▀ ▀▄▀ █ █▄█ ▀ █ █▄▀ █▄▀ █▄▄▄▄▄▄▄████
+████ █▄▄▄▄ ██ ██ ▄▄▀ ▄▄▄██▄▄▄▄ ▄▄██▄▄▀▀█▄█▀████
+████ █▀█▄▄▄▄▄ ▀████▀▀▀▄▄█▄▄ ▄▀▄▄▄█ ▀█▀ █▀██▄██ ▄████
+████ ▀ ▄▄▀▀▄█▀█▄▄ █▄▄ ▀▀█▄██ █▄ ▄███▄▄ ▄▀█ ▄████
+█████▄ █▄▄█▀▀ ▀█▄▀███ ███ ▄▀▀▀ ██▀▀██ █▀█▀█▄▄ ████
+████ ▄█ █▄▄ ▀ ▀██▄▀▄█ ▀▄█▀██▄▄▀▄█ ████ ▄▄▄ ▀▄ ████
+█████ █▄▀ ▄▀ ▀█▀▄██ ▄▄ ██▄██▄█ ▄▀▀█▀▄ ▀▀█▀▀▄▄▄▄ ▄████
+████ ▄▄ ▄▄▄ ▄▀ ▄█ ██▄ █ ▄▄▄ ▄▄█▄ █▄ ▄▄▀ ▄▄▄ ▀█ ▄████
+████▀▄▀▀ █▄█ ▄▄█▀ ▀▀▀█ ▄ █▄█ ▀ ▀▄▀▄ ▄▄ █▄█ █ ████
+████▀██ ▄▄▄▄▀▀ ▄ █▄▄▄▄▄ ▄▄▄▄▄▀ █ ▄▄▀▄▄▄▄▄ ██ ████
+████ ▄█▀▄█▄█▀▀▀ ▄▀ ██▀█▀ ▄██▄█▀ ███▀▄▀▀█▀ ▄▀▀▄█ ▄████
+████ ▀█ █▀▄▀▄▀▀▄█▄▄▄█ █ ▄▄▄ ▄▄ ▄▄▀▀ ▀██ ▀▀▀████
+████▀▄█▀ ▀▄▀█▄▄▄██▄▄▄▀▀█▀▀██▄ ▀▀▀▀▄ ▀▄▀██▄ █▄▀█ ▄████
+████▄▀ ▀▀▀▄█▀███ █▄██ ▄▀ ▄█▄██▄▄▄█▄▄▀▄█▄ █▄▄▀▀ ████
+█████▀▀▀ █▄▀▄█▄█▀ ▀██ █ ██▀▀▀▀█▀▀▄▀▀▄▀ ▄▄▄ ▄ ▄████
+████▄██▄▄█▄▄ █▄▄ █ ▀ ▄▄▄ ▄▄ ██ ▄███ ▄▄▄ ▄▀█ ████
+████ ▄▄▄▄▄ █ ▀█▄ ▀ █ ▄█ █▄█ █ ▀▄ ▄ █▄█ █▄ ████
+████ █ █ █▄▀ ▄ ███▄▄▀ ▄▄▄▄▄█▄ ██ ▄▄▄ ▄ ▄▄ ██▄▄████
+████ █▄▄▄█ █ ▄ ▄▄█▄▄▄▄▄▀█ ▀██▀ ███ ▀▀█▄ ▄█▄ ▄▄▀█████
+████▄▄▄▄▄▄▄█▄█▄██▄▄▄▄▄▄█▄▄▄▄▄▄█▄▄▄█▄▄███▄██▄█▄█▄▄████
+█████████████████████████████████████████████████████
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+QR
+printf '\n …or open: https://term.sourceful-labs.net/#join-eyJzIjoiaHR0cHM6Ly9yZWxheS5zb3VyY2VmdWwtbGFicy5uZXQiLCJ0IjoiYzRlNGJiODc5NWFjM2Y2NmMyODE3ZjM3NGNiYjY3ZDUifQ\n'
+printf ' …or on the CLI: mir join eyJzIjoiaHR0cHM6Ly9yZWxheS5zb3VyY2VmdWwtbGFicy5uZXQiLCJ0IjoiYzRlNGJiODc5NWFjM2Y2NmMyODE3ZjM3NGNiYjY3ZDUifQ\n'
+printf '\nwaiting for your guest (5 min)…\n'
+sleep 4
diff --git a/assets/demo.tape b/assets/demo.tape
index 4ba2c33..07f0d82 100644
--- a/assets/demo.tape
+++ b/assets/demo.tape
@@ -1,12 +1,23 @@
-# vhs tape for the Miranda demo GIF. Render with: vhs assets/demo.tape
+# vhs tape for the Miranda demo GIF. Render from the repo root with:
+#
+# vhs assets/demo.tape
+#
# Produces assets/miranda-demo.gif from the illustrative assets/demo.sh.
+# The canvas is sized so `mir share`'s invite QR fits on one screen without
+# scrolling: 42 rows x 80 columns at this font size and padding. The last beat
+# needs 41 of those rows, and 80 columns is the narrowest that still wraps each
+# invite URL to two lines rather than three — narrow keeps the cells (and the
+# 📱 in the mint header) as large as the README's 900px column allows.
+#
+# Keep Width and Height EVEN. An odd width defeats the palette pass and the
+# same recording lands at 14 MB instead of ~210 KB.
Output assets/miranda-demo.gif
Set Shell "bash"
-Set FontSize 20
-Set Width 1200
-Set Height 680
+Set FontSize 16
+Set Width 884
+Set Height 878
Set Padding 26
Set Theme "Dracula"
@@ -17,4 +28,4 @@ Type "bash assets/demo.sh"
Enter
Sleep 600ms
Show
-Sleep 12s
+Sleep 13800ms
diff --git a/assets/miranda-demo.gif b/assets/miranda-demo.gif
index 253d747..e05c5c5 100644
Binary files a/assets/miranda-demo.gif and b/assets/miranda-demo.gif differ