CI's monitor shot fails with "three renders, no two alike" but discarded the renders; the artifact now has
unstable-<shot>-<k>.png to show what changes between them.
- Library: an "All games" label and a 2 px rule (blue→orange in Portal themes) between the shelf and the grid,
hidden with the shelf.
- The pretend Frame's screenshots are the games' own in-game store screenshots (never cover art), installed games
first; the running demo game is BONELAB (it has screenshots, so Take screenshot adds a real one).
- render_docs: a shot whose steps fail is retried in a fresh window and never written (a window that didn't connect
had produced an empty Library); every shot is rendered twice in fresh windows and kept only when both agree (a
misdrawn glyph, "7.θ W", slipped through once); changes from 0.04 % of the pixels count (the sidebar card
showing another game is 0.12 %, run-to-run noise under 0.007 %). --fast renders once.
- record_tour: SHOWCASE_DEBUG=1 prints each step's start time. Docs images and the tour re-rendered.
.github/workflows/showcase.yml renders the docs screenshots on UI pushes to main (and the tour when its storyboard or
scripts change, or on Run workflow), keeps every render as an artifact and opens/updates the PR showcase/update
when a picture visibly changed. Releases attach the tour as FramePort-tour.mp4. docs/SHOWCASE.md explains running
it, the step language and the CI flow; README opens with the teaser (link to the full MP4). Renders refuse
placeholder art (--allow-missing-art). tests/test_showcase.py: demo library, privacy scan, image threshold,
manifests (every docs image has a shot), step validation, element picking, pointer paths, ffmpeg graphs.
scripts/demo_record.py is replaced by the tour.
scripts/showcase/: the fakes split out of ui_smoke (the pretend Frame now reads the demo library's state, fixed
dates, a Take screenshot fake, a frozen monitor stream for stills), web.py (the GUI in web mode driven by name
through Flutter's semantics tree, drawn cursor, eased pointer paths, settle detection, one browser per window),
steps.py (the step language shared by screenshots and the tour), demo_home.py (21 catalog games from
docs/showcase/demo-library.yaml + demo-analyses.json, art and store details fetched once and cached) and
render_docs.py (docs/showcase/shots.yaml -> docs/images, rewritten only on a visible change; --check for CI).