One static page that takes a reader who has never seen the app to a full working understanding:
numbered lessons in parts, each lesson with plain-English steps, a short demo rendered from real
screenshots that the step list follows in time, a gallery, and tips that state the app's limits
honestly. A search box reaches every step and fix. Everything is reproducible from a folder, so
the next build refreshes it in minutes instead of a rewrite. The templates in templates/ are
the working pieces of a shipped guide; copy them, do not reinvent them.
When to use
- "Make a how-to / user guide / help page / onboarding walkthrough for this app"
- A launch email needs something to link to, or a support desk keeps answering the same question
- An app changed and its guide must follow (run the folder's own CLAUDE.md procedure)
What you produce
how-to/
index.html the page (templates/page.html, filled in)
assets/shots/ real screens, one size, redacted, WebP
assets/demos/ MP4 + JPEG poster per demo, rendered from demos/demos.json
assets/brand/ logo.png and logo-dark.png (and any partner logo)
capture/ process.py, redactions.json, replacements.json, fonts/, capture-notes.md
demos/ Remotion project: src/ engine, demos.json storyboard, render.mjs
check.mjs currency, missing assets, emails, test strings, dashes, fill-ins
vercel/ deploy.sh password gate + publish script (optional)
CLAUDE.md rules, triggers and the update procedure (templates/CLAUDE.md)
Procedure
- Learn what matters before writing. Meeting notes, support tickets, the launch plan: what do people get stuck on, what is new, what is switched off. That sets the lesson order. Lead with the thing that generates the most support (usually signing in), then the feature people came for, then the rest. One lesson per feature people will look for: profile, notifications and a QR code are three lessons, not one. Past about eight lessons, group them into parts (Getting started, The product, People, Your things, Help) so the menu reads as categories and subcategories. Always end with a fixes lesson (FAQ) and a "need a hand" one.
- Capture real screens (
templates/capture/capture-notes.md): emulator, simulator or browser at one fixed size, a clean status bar, test accounts only, nothing sent to a real person. Save an accessibility dump beside each PNG; demo taps are read from it. - Process with
templates/capture/process.py:redactions.jsonblurs real people and covers admin-only UI;replacements.jsonrewrites test-account strings in the app's own font (drop its TTFs intocapture/fonts/), measured from the pixels so the size, weight, colour and centring match. Raw captures stay gitignored; only the WebP is committed. - Storyboard the demos in
demos/demos.json(seedemos.example.json): per step a shot, a caption, a hold in seconds, taps and typed text at capture-pixel coordinates,captionAtbottom when the top of the screen is the point. Every lesson gets a demo, 8 to 35 s; a lesson with only a still screenshot reads as frozen. Cut each demo so its steps line up with the lesson's steps, then putdata-mapon the demo (which lesson step each demo step belongs to); the page highlights that step while the video plays.npm run render -- --sheetproofs one still per step;npm run renderwrites the MP4s, posters andassets/demos/index.json(the timings the highlight reads). - Write the page from
templates/page.html. Keep the structure: header with the logo, the search centred and a hamburger menu on phones; hero with an "App guide" kicker and a quick-start row;<div class="part">headings; one<section class="lesson" data-group data-title>per lesson (sidebar, phone menu and counts build themselves); steps with a verb-first bold line; the demo in the media column; notes for tips and limits; a gallery strip; the FAQ with its own filter; a help lesson; the footer with the logos and the currency line (data-build,data-updated). - Check and look:
node check.mjsmust printok; open the page at phone and desktop width, watch the changed demos play, and try the search. No print button: a print stylesheet has to be laid out and proofed like a second design, and an unproofed one lands the reader with a broken sheet. The browser's own print command still works on the ordinary layout. - Publish:
templates/deploy.shwithtemplates/vercel/gives a Vercel site behind one shared password (GUIDE_PASSWORD), nothing butindex.htmlandassets/uploaded. Any static host works for a public guide. - Make it stay current: copy
templates/CLAUDE.mdinto the folder, add a repo skill or CLAUDE.md rule naming the triggers (new build, feature switch, flow change, fix, launch details), and wirecheck.mjsinto whatever fetches or ships builds.
Design
- Brand it from the product. The layout system is fixed (borders not shadows, Inter plus a
mono face for numbers, light and dark from one token set, phone frames at the capture
ratio, 16px gutters, no horizontal scroll on a phone), but the one accent colour and the
logos come from the product or the company the guide is for: set
--accent,--accent-inkand--accent-softin:rootto the brand colour and its dark and tinted shades, and put light and dark logo files inassets/brand/. If the repo has a brand skill or a design system, read it first and take colours, logo files and naming from there. - Demos autoplay muted when in view, pause when out, replay on tap, never autoplay under
prefers-reduced-motion, and drive the step highlight. Deep links land instantly; in-page clicks glide. - Always a search. It indexes every lesson, step, note, table row and FAQ entry; Enter jumps to the exact item and flashes it. On phones it opens from a search icon in the header.
- Navigation: a grouped sidebar on desktop, a hamburger menu with the same groups on phones and
tablets. Never a horizontal chip strip. Plus a Help button in the header, the one labelled
button there, jumping straight to the fixes lesson and landing instantly rather than gliding:
a guide runs tens of thousands of pixels and whoever reaches for Help is already stuck. Keep
that anchor short (
#help) and on one element, because it is what goes behind a QR code on a sign. Part headings therefore takepart-*ids: two elements sharing an id make the anchor ambiguous and the browser silently picks the first. - Logo visibility rules must name the element (
img.logo-dark) so a layout rule cannot show both the light and the dark artwork at once.
Rules
- Write for someone who has never used the app: sentence case, second person, no jargon,
no ticket ids. Say the number. No em dashes, no en dashes (the check fails on them).
One variety of English, the audience's: American for a US audience, and held everywhere,
including the capture scripts' own comments.
check.mjshas the word list and the switch. - Every sentence is true of the app as captured. Limits go in a tip, never hidden and never apologised for. Remove a warning the day the app fixes it.
- No real people in any image; no email address in the text; no credentials anywhere. Demo typing is an overlay of placeholder text. The check catches text; you check images.
- No test data on screen: rewrite it (Chris Test -> a plausible placeholder), do not blur it. Name the placeholders in CLAUDE.md so the next person keeps them consistent.
- Describe the audience's view. An admin test account shows extra UI; cover it or re-capture.
- One set of screenshots, one size, one build; the footer names the build. Mixed builds show.
- A demo per lesson, always; a screenshot beats a paragraph for anything else. Never a screen recording: recordings cannot be redacted or re-rendered.
- No empty states in the pictures. Put real content in the app (a note, an item in the bag) before capturing, or leave that screen out and list it for the next capture.
Templates
templates/page.html, templates/CLAUDE.md, templates/check.mjs, templates/deploy.sh,
templates/capture/{process.py, redactions.example.json, replacements.example.json, capture-notes.md}, templates/demos/{package.json, tsconfig.json, remotion.config.ts, render.mjs, demos.example.json, src/*}, templates/vercel/{middleware.js, vercel.json, package.json}. When this skill was pulled without its folder, fetch them from
https://github.com/Uplift-Duo-Co/uplift.page/tree/main/skills/app-how-to-page/templates.
Reference build: the E-Scrap 2026 app guide in Resource-Recycling/stova-app-testing, how-to/.