Generate a self-contained single-file HTML demo or presentation using Alpine.js + Tailwind via CDN. Emailable, double-clickable, no build step or server. Use when the user asks for a demo, prototype, slide deck, walkthrough, pitch, or interactive mockup. Triggers on phrases like "make a demo", "build a one-pager", "prototype this", "presentation/slides", "single-file HTML", or "no build step".
Produce one HTML file. No package.json, no bundler, no server, no separate JS/CSS files. The output must run by double-clicking it (or open file.html) with only an internet connection for the CDN scripts.
Reference examples
Four canonical patterns live alongside this file in references/. Read whichever matches the request before you start writing. Use them for interaction structure and Alpine patterns, not as mandatory visual themes.
references/catalogue.html — the baseline demo pattern: search + filter + sort + detail pane + empty state. Start here for any list-with-details ask.
references/dashboard-with-tour.html — KPI dashboard with a coaching-mark tour (spotlight overlay, getBoundingClientRect measurement, persisted "tour seen" via the $persist plugin).
references/slide-deck.html — keyboard-driven slide deck with five layouts (cover, bullets, metric, quote, code), speaker notes, fullscreen mode.
references/streaming-ai.html — simulated AI: thinking-step trace, word-by-word streaming reply, regenerate / edit / accept controls, runId to abort stale streams.
Who you are talking to
Assume the person invoking this skill is a non-developer stakeholder — comfortable with computers and willing to open a file in a text editor or run open foo.html, but not interested in framework internals. They are using this to put a working interactive thing in front of a client, a stakeholder, a team, or an audience without booking a sprint with engineering.
What that means for you:
No jargon without translation. If you mention x-data, getter, $persist, or a CDN, give a one-line "this means…" the first time. The teaching comments inside the HTML do this; your chat replies should too.
Default to "I'll just do it" for technical implementation details. Do not ask whether to add getters, state fields, or event handlers. Do ask for creative direction when the user's request does not specify the desired style, tone, audience, or theme.
You make the edits, not them. Never tell the user to open the file and change a line, replace an array, or paste a snippet. If something needs changing, change it yourself with the editing tools. The user's only interaction with the file should be opening it in a browser to look at the result.
Talk about outcomes, not implementations. "I added a search box that filters as you type" beats "I bound x-model to a reactive search property and added a filteredItems getter." Reserve the second form for inline code comments.
Don't suggest dev workflow changes. No "add a test", "run the linter", "set up CI", "convert to TypeScript". They are not running any of that.
Be generous with realistic sample data. They'll often hand you a topic ("a demo of our pricing tiers") rather than data. Invent plausible content; they will replace it (by asking you, not by editing). Aim for content that looks like a real customer's, not lorem ipsum.
When you need their content, ask in plain English. "Got the pricing tiers and what each includes? Paste them in and I'll wire them in." Not "provide the items array in JSON."
This is not a reason to dumb anything down. The output is still a properly built, idiomatic Alpine app — it just needs to land without a developer in the loop.
When to use this skill
Use it for:
Demos / prototypes — interactive UI to show an idea (catalogue, dashboard, form flow, data explorer).
One root x-data block holds the entire app's reactive state. Nested x-data only when scoping is genuinely needed (e.g. a repeated component with local state).
Use getters as computed properties — get filteredItems() rather than recomputing in templates. Alpine re-runs them automatically.
x-cloak on the root plus [x-cloak]{display:none!important} in a <style> to prevent the un-hydrated flash.
Tabular numerics (tabular-nums) on price/count columns. Small detail, big polish.
Comment the Alpine concepts inline the way references/catalogue.html does (x-model is two-way binding, x-for renders one element per array item, etc.). The output is a teaching artifact as much as a working demo.
No emojis in the output unless the user asked for them.
No scattered assets. Images, icons, textures, fonts, and data must either be embedded in the HTML (data: URLs, inline SVG, inline CSS, or inline arrays) or loaded from stable remote URLs/CDNs. Do not leave sibling .png, .jpg, .svg, .json, .js, .css, or screenshot files next to the onepager.
Clean up after yourself. If you generate images, screenshots, extracted data, browser snapshots, or temporary files while building or verifying the onepager, delete those temporary artifacts before delivery unless the user explicitly asked to keep them.
Style and theme discovery
Before creating a onepager, identify whether the user has already specified the visual direction. Treat phrases like "investor memo", "retro arcade", "luxury retail", "internal dashboard", "zine", "playful", "minimal", "cyberpunk", "for kids", "for executives", or a linked/reference design as style direction.
If style direction is missing or too vague, interview the user briefly before writing the HTML. Ask one concise question with 3-5 concrete style options plus an invitation to name their own. Keep the options tailored to the topic rather than generic. For example:
What style should this onepager use: analyst briefing, collector magazine, playful trading-card binder, auction-house premium, or something else?
When the user provides a style, honor it through layout, typography scale, color, imagery, density, copy tone, and interaction details. Do not impose a business/editorial theme unless the user chose it or the topic clearly calls for it.
If the user explicitly asks you to proceed without asking questions, choose a style that fits the audience and topic, then state the assumption in one sentence before building.
Interaction and implementation conventions
Theme follows the interview. Pick color, spacing, and typography from the user's chosen style. There is no universal palette or business default.
Fallback style only when needed. If the user gives no style direction and cannot be reached, use a clear, readable neutral treatment with restrained colors and enough contrast. Keep it visually appropriate to the topic, not automatically corporate.
Spacing: use a responsive page container appropriate to the chosen style. Dense dashboards, magazine explainers, pitch pages, and playful demos should not all share the same spacing system.
Typography: make headings, labels, and body copy match the theme and audience. Preserve readability; do not use tiny text, negative tracking, or viewport-scaled font sizes.
Transitions: prefer x-transition with explicit enter/leave classes for anything that appears/disappears. Motion should fit the style; keep it subtle for serious contexts and more expressive for playful ones.
Empty states: every list and detail pane should have one. Write the empty-state copy in the selected tone.
Keyboard: for presentations, wire @keydown.arrow-right.window / arrow-left / space on the root. For demos, at minimum support Escape to close modals/panes.
Mobile-first dense content: tables, catalogues, card grids, and comparison lists must be designed for narrow screens first. On mobile, stack dense rows into readable cards, allow long labels and chips to wrap, avoid truncate except at wider breakpoints, and use min-w-0 on flex/grid children that contain dynamic text. Reintroduce compact rows or table-like layouts only from sm/md upward.
Images and visual assets
Prefer CSS, inline SVG, or remote image URLs for decorative visuals. If an image must travel with the onepager, embed it as a data: URL inside the HTML so the delivered artifact remains one file.
When using generated bitmap images, either embed the final chosen image in the HTML or use a stable hosted URL if the environment provides one. Remove any intermediate image files, screenshots, masks, or rejected variants. The final working directory should contain the onepager HTML only, plus any unrelated files that existed before the task.
Hero visuals and decorative mock objects should carry real information. Avoid blank placeholder cards, generic grey boxes, or empty device frames. Fill them with lightweight, topic-specific content such as labels, charts, stats, mini examples, or meaningful silhouettes so the first viewport feels intentional even before the user interacts.
Browser verification workflow
Even though the delivered file should be double-clickable, browser tooling often cannot inspect file:// pages. During development, serve the directory with a tiny local server such as python3 -m http.server 4173, open http://127.0.0.1:4173/<file>.html, verify desktop and mobile layouts, then stop the server before finishing.
If the agent cannot directly see or inspect the page, tell the user that a browser bridge is worth installing for future work. Recommend an in-app browser, Playwright MCP server, browser-use plugin, or equivalent browser extension/MCP service that lets the AI navigate local URLs, inspect the DOM, capture screenshots, and check responsive layouts. This is especially important for onepagers because visual issues often survive static HTML review.
Do not leave verification artifacts behind. Browser screenshots, Playwright snapshot folders, console logs, and temporary server output are development byproducts, not part of the delivered onepager.
Presentation-mode specifics
When the request is a slide deck:
State shape: { slide: 0, slides: [...] } where each slide is { title, body, notes? } or a discriminated { type: 'cover' | 'bullets' | 'image' | 'code', ... }.
Render exactly one slide at a time via x-show + x-transition keyed on slide index.
Show slide + 1 / slides.length in a corner.
Bind keys: →/Space advances, ← retreats, Home/End jump, f toggles a fullscreen boolean that hides chrome.
Speaker notes hidden by default, toggleable with n.
Progress bar at the top: width: ((slide+1) / slides.length * 100) + '%'.
Demo-mode specifics
When the request is an interactive demo:
Sample data goes in an items (or domain-appropriate) array at the top of x-data. Provide 12–20 realistic-looking entries — enough to make filter/sort feel meaningful, not so many the file bloats.
Always include: a search/filter control, a sort control, a list, a detail pane (or modal), and an empty state. This is the load-bearing pattern from references/catalogue.html and it scales to most demo asks.
Selection state lives at the root (selected: null), not inside the loop.
If the demo has a data table or card table, build an explicit mobile layout rather than relying on the desktop table to shrink. A good default is: controls stack, each result becomes a self-contained card, badges/chips wrap onto separate lines, and secondary details move below the title. Confirm that no row requires horizontal scrolling unless horizontal scrolling is the product behavior.
Offer an onboarding flow
After delivering a non-trivial demo, offer to add a coaching-mark / onboarding tour as a follow-up. Don't add it unprompted — surface it as a one-line question: "Want me to wire up a coaching-mark tour for this?". Most demos benefit, but unsolicited additions inflate scope.
This is a two-step flow: first deliver the demo and ask whether the user wants the tour; only after they say yes should you add the full coaching-mark system.
When the user accepts, the pattern from references/dashboard-with-tour.html is the reference:
State: tour: { active: false, step: 0 } plus a tourSteps array of { target, title, body, placement, autoSelect? } entries. target matches a data-tour="..." attribute on a real DOM element. placement is 'top' | 'bottom' | 'left' | 'right'. autoSelect is optional — opens a drawer / picks an item before measuring, so the spotlight can land on dynamically-revealed UI.
Spotlight: a single fixed-position div with box-shadow: 0 0 0 9999px rgba(15, 23, 42, 0.72) and no background. The shadow dims everything outside the box; transitions on top/left/width/height animate between targets cheaply. Crisper than an SVG mask.
Coaching card: another fixed div positioned next to the spotlight using the step's placement. Title, body, step counter (n / total), Back / Next / Skip controls.
Measurement: measureTarget() calls getBoundingClientRect() on the active step's data-tour element, with scrollIntoView({ block: 'center', behavior: 'smooth' }) first. Re-measure on resize and scroll so the spotlight tracks. Use $nextTick after step changes so DOM updates from autoSelect settle before measuring.
Keyboard: Escape ends the tour, ArrowRight / Enter advances, ArrowLeft retreats.
Annotation in HTML: sprinkle data-tour="some-id" attributes on the elements steps point at. Identifiers should be lowercase-kebab and unique. Bind dynamically with :data-tour="'item-' + i.id" when targeting list rows.
Don't block clicks on the spotlit element — pointer-events: none on the spotlight, with a transparent click-trap overlay behind it that catches outside clicks and ends the tour.
For lighter onboarding (one-shot welcome panels, dismissible tooltips), a single <div x-show="!seenWelcome"> with a localStorage check via $persist is enough — don't reach for the full tour machinery.
Output checklist (run mentally before handing back)
Doctype, lang, viewport, charset, title set.
Tailwind + Alpine CDN tags in <head>, Alpine has defer.
x-cloak style block present and applied to root.
All reactive state in one x-data (or justified nested ones).
Getters used for derived data, not inline computations.
At least one x-transition somewhere — UIs without motion feel dead.
Empty state for every list / detail region.
Mobile layout checked for dense lists/tables: no clipped chips, no squeezed columns, no accidental horizontal scrolling, and long dynamic names still fit.
Hero or major illustrative visuals contain topic-specific content, not empty placeholders.
Served locally and checked in a real browser when browser tooling is available; if not available, recommend a browser extension/plugin/MCP bridge for future visual QA.
For non-trivial demos, final response offers the coaching-mark / onboarding tour as a follow-up rather than adding it silently.
Tasteful comments explaining the Alpine directives, matching references/catalogue.html's tone.
No build artifacts, no sibling assets, no screenshot files, no browser snapshot folders, no <link rel="stylesheet"> to local files, no <script src="./...">, and no local <img src="./...">.
Opens cleanly with open foo.html — verify mentally that nothing assumes a server origin (no fetch to relative URLs, no module scripts).
Graduation signals (mention these to the user when relevant)
If the demo grows past ~1500 lines, needs persistence, needs multiple pages, or starts wanting components, surface the upgrade path:
$persist plugin for localStorage-backed state (one extra script tag — already in references/dashboard-with-tour.html).
petite-vue or full Vue 3 from CDN for component decomposition without a build step.
An actual backend + framework when the single-file format stops paying for itself.
1---2name: onepager3description: Generate a self-contained single-file HTML demo or presentation using Alpine.js + Tailwind via CDN. Emailable, double-clickable, no build step or server. Use when the user asks for a demo, prototype, slide deck, walkthrough, pitch, or interactive mockup. Triggers on phrases like "make a demo", "build a one-pager", "prototype this", "presentation/slides", "single-file HTML", or "no build step".4---56# Onepager — single-file demo & presentation generator78Produce one HTML file. No `package.json`, no bundler, no server, no separate JS/CSS files. The output must run by double-clicking it (or `open file.html`) with only an internet connection for the CDN scripts.910## Reference examples1112Four canonical patterns live alongside this file in `references/`. Read whichever matches the request before you start writing. Use them for interaction structure and Alpine patterns, not as mandatory visual themes.1314- `references/catalogue.html` — the baseline demo pattern: search + filter + sort + detail pane + empty state. Start here for any list-with-details ask.15- `references/dashboard-with-tour.html` — KPI dashboard with a coaching-mark tour (spotlight overlay, `getBoundingClientRect` measurement, persisted "tour seen" via the `$persist` plugin).16- `references/slide-deck.html` — keyboard-driven slide deck with five layouts (cover, bullets, metric, quote, code), speaker notes, fullscreen mode.17- `references/streaming-ai.html` — simulated AI: thinking-step trace, word-by-word streaming reply, regenerate / edit / accept controls, `runId` to abort stale streams.1819## Who you are talking to2021Assume the person invoking this skill is a **non-developer stakeholder** — comfortable with computers and willing to open a file in a text editor or run `open foo.html`, but not interested in framework internals. They are using this to put a working interactive thing in front of a client, a stakeholder, a team, or an audience without booking a sprint with engineering.2223What that means for you:2425- **No jargon without translation.** If you mention `x-data`, `getter`, `$persist`, or a CDN, give a one-line "this means…" the first time. The teaching comments inside the HTML do this; your chat replies should too.26- **Default to "I'll just do it"** for technical implementation details. Do not ask whether to add getters, state fields, or event handlers. Do ask for creative direction when the user's request does not specify the desired style, tone, audience, or theme.27- **You make the edits, not them.** Never tell the user to open the file and change a line, replace an array, or paste a snippet. If something needs changing, change it yourself with the editing tools. The user's only interaction with the file should be opening it in a browser to look at the result.28- **Talk about outcomes, not implementations.** "I added a search box that filters as you type" beats "I bound `x-model` to a reactive `search` property and added a `filteredItems` getter." Reserve the second form for inline code comments.29- **Don't suggest dev workflow changes.** No "add a test", "run the linter", "set up CI", "convert to TypeScript". They are not running any of that.30- **Be generous with realistic sample data.** They'll often hand you a topic ("a demo of our pricing tiers") rather than data. Invent plausible content; they will replace it (by asking you, not by editing). Aim for content that looks like a real customer's, not lorem ipsum.31- **When you need their content, ask in plain English.** "Got the pricing tiers and what each includes? Paste them in and I'll wire them in." Not "provide the `items` array in JSON."3233This is not a reason to dumb anything down. The output is still a properly built, idiomatic Alpine app — it just needs to *land* without a developer in the loop.3435## When to use this skill3637Use it for:38- **Demos / prototypes** — interactive UI to show an idea (catalogue, dashboard, form flow, data explorer).39- **Presentations / slide decks** — keyboard-navigable slides with transitions, speaker notes, progress.40- **Walkthroughs / tutorials** — step-by-step guided UI, often with a "next" button advancing state.41- **Pitches / explainers** — landing-page-style narrative scrolls with reactive bits.4243Do **not** use it for:44- Anything needing real persistence, auth, server-side logic, or a real backend.45- Multi-page apps, routing-heavy UIs, or anything where one file becomes unwieldy (>~1500 lines is the soft ceiling — flag this to the user).46- Production apps. This is a starter, not a destination.4748## Hard rules49501. **One file.** All markup, state, styles, and data live in the single `.html` you output. Never split.512. **CDN only, no install.** Use these exact tags in `<head>`:52 ```html53 <script src="https://cdn.tailwindcss.com"></script>54 <script defer src="https://unpkg.com/alpinejs@3.14.1/dist/cdn.min.js"></script>55 ```56 `defer` on Alpine is required.573. **One root `x-data` block** holds the entire app's reactive state. Nested `x-data` only when scoping is genuinely needed (e.g. a repeated component with local state).584. **Use getters as computed properties** — `get filteredItems()` rather than recomputing in templates. Alpine re-runs them automatically.595. **`x-cloak` on the root** plus `[x-cloak]{display:none!important}` in a `<style>` to prevent the un-hydrated flash.606. **Tabular numerics** (`tabular-nums`) on price/count columns. Small detail, big polish.617. **Comment the Alpine concepts inline** the way `references/catalogue.html` does (`x-model is two-way binding`, `x-for renders one element per array item`, etc.). The output is a teaching artifact as much as a working demo.628. **No emojis** in the output unless the user asked for them.639. **No scattered assets.** Images, icons, textures, fonts, and data must either be embedded in the HTML (`data:` URLs, inline SVG, inline CSS, or inline arrays) or loaded from stable remote URLs/CDNs. Do not leave sibling `.png`, `.jpg`, `.svg`, `.json`, `.js`, `.css`, or screenshot files next to the onepager.6410. **Clean up after yourself.** If you generate images, screenshots, extracted data, browser snapshots, or temporary files while building or verifying the onepager, delete those temporary artifacts before delivery unless the user explicitly asked to keep them.6566## Style and theme discovery6768Before creating a onepager, identify whether the user has already specified the visual direction. Treat phrases like "investor memo", "retro arcade", "luxury retail", "internal dashboard", "zine", "playful", "minimal", "cyberpunk", "for kids", "for executives", or a linked/reference design as style direction.6970If style direction is missing or too vague, interview the user briefly before writing the HTML. Ask one concise question with 3-5 concrete style options plus an invitation to name their own. Keep the options tailored to the topic rather than generic. For example:7172> What style should this onepager use: analyst briefing, collector magazine, playful trading-card binder, auction-house premium, or something else?7374When the user provides a style, honor it through layout, typography scale, color, imagery, density, copy tone, and interaction details. Do not impose a business/editorial theme unless the user chose it or the topic clearly calls for it.7576If the user explicitly asks you to proceed without asking questions, choose a style that fits the audience and topic, then state the assumption in one sentence before building.7778## Interaction and implementation conventions7980- **Theme follows the interview.** Pick color, spacing, and typography from the user's chosen style. There is no universal palette or business default.81- **Fallback style only when needed.** If the user gives no style direction and cannot be reached, use a clear, readable neutral treatment with restrained colors and enough contrast. Keep it visually appropriate to the topic, not automatically corporate.82- **Spacing**: use a responsive page container appropriate to the chosen style. Dense dashboards, magazine explainers, pitch pages, and playful demos should not all share the same spacing system.83- **Typography**: make headings, labels, and body copy match the theme and audience. Preserve readability; do not use tiny text, negative tracking, or viewport-scaled font sizes.84- **Transitions**: prefer `x-transition` with explicit `enter`/`leave` classes for anything that appears/disappears. Motion should fit the style; keep it subtle for serious contexts and more expressive for playful ones.85- **Empty states**: every list and detail pane should have one. Write the empty-state copy in the selected tone.86- **Keyboard**: for presentations, wire `@keydown.arrow-right.window` / `arrow-left` / `space` on the root. For demos, at minimum support `Escape` to close modals/panes.87- **Mobile-first dense content**: tables, catalogues, card grids, and comparison lists must be designed for narrow screens first. On mobile, stack dense rows into readable cards, allow long labels and chips to wrap, avoid `truncate` except at wider breakpoints, and use `min-w-0` on flex/grid children that contain dynamic text. Reintroduce compact rows or table-like layouts only from `sm`/`md` upward.8889## Images and visual assets9091Prefer CSS, inline SVG, or remote image URLs for decorative visuals. If an image must travel with the onepager, embed it as a `data:` URL inside the HTML so the delivered artifact remains one file.9293When using generated bitmap images, either embed the final chosen image in the HTML or use a stable hosted URL if the environment provides one. Remove any intermediate image files, screenshots, masks, or rejected variants. The final working directory should contain the onepager HTML only, plus any unrelated files that existed before the task.9495Hero visuals and decorative mock objects should carry real information. Avoid blank placeholder cards, generic grey boxes, or empty device frames. Fill them with lightweight, topic-specific content such as labels, charts, stats, mini examples, or meaningful silhouettes so the first viewport feels intentional even before the user interacts.9697## Browser verification workflow9899Even though the delivered file should be double-clickable, browser tooling often cannot inspect `file://` pages. During development, serve the directory with a tiny local server such as `python3 -m http.server 4173`, open `http://127.0.0.1:4173/<file>.html`, verify desktop and mobile layouts, then stop the server before finishing.100101If the agent cannot directly see or inspect the page, tell the user that a browser bridge is worth installing for future work. Recommend an in-app browser, Playwright MCP server, browser-use plugin, or equivalent browser extension/MCP service that lets the AI navigate local URLs, inspect the DOM, capture screenshots, and check responsive layouts. This is especially important for onepagers because visual issues often survive static HTML review.102103Do not leave verification artifacts behind. Browser screenshots, Playwright snapshot folders, console logs, and temporary server output are development byproducts, not part of the delivered onepager.104105## Presentation-mode specifics106107When the request is a slide deck:108- State shape: `{ slide: 0, slides: [...] }` where each slide is `{ title, body, notes? }` or a discriminated `{ type: 'cover' | 'bullets' | 'image' | 'code', ... }`.109- Render exactly one slide at a time via `x-show` + `x-transition` keyed on `slide` index.110- Show `slide + 1 / slides.length` in a corner.111- Bind keys: `→`/`Space` advances, `←` retreats, `Home`/`End` jump, `f` toggles a `fullscreen` boolean that hides chrome.112- Speaker notes hidden by default, toggleable with `n`.113- Progress bar at the top: `width: ((slide+1) / slides.length * 100) + '%'`.114115## Demo-mode specifics116117When the request is an interactive demo:118- Sample data goes in an `items` (or domain-appropriate) array at the top of `x-data`. Provide 12–20 realistic-looking entries — enough to make filter/sort feel meaningful, not so many the file bloats.119- Always include: a search/filter control, a sort control, a list, a detail pane (or modal), and an empty state. This is the load-bearing pattern from `references/catalogue.html` and it scales to most demo asks.120- Selection state lives at the root (`selected: null`), not inside the loop.121- If the demo has a data table or card table, build an explicit mobile layout rather than relying on the desktop table to shrink. A good default is: controls stack, each result becomes a self-contained card, badges/chips wrap onto separate lines, and secondary details move below the title. Confirm that no row requires horizontal scrolling unless horizontal scrolling is the product behavior.122123## Offer an onboarding flow124125After delivering a non-trivial demo, **offer to add a coaching-mark / onboarding tour** as a follow-up. Don't add it unprompted — surface it as a one-line question: *"Want me to wire up a coaching-mark tour for this?"*. Most demos benefit, but unsolicited additions inflate scope.126127This is a two-step flow: first deliver the demo and ask whether the user wants the tour; only after they say yes should you add the full coaching-mark system.128129When the user accepts, the pattern from `references/dashboard-with-tour.html` is the reference:130131- **State**: `tour: { active: false, step: 0 }` plus a `tourSteps` array of `{ target, title, body, placement, autoSelect? }` entries. `target` matches a `data-tour="..."` attribute on a real DOM element. `placement` is `'top' | 'bottom' | 'left' | 'right'`. `autoSelect` is optional — opens a drawer / picks an item before measuring, so the spotlight can land on dynamically-revealed UI.132- **Spotlight**: a single fixed-position div with `box-shadow: 0 0 0 9999px rgba(15, 23, 42, 0.72)` and no background. The shadow dims everything outside the box; transitions on `top/left/width/height` animate between targets cheaply. Crisper than an SVG mask.133- **Coaching card**: another fixed div positioned next to the spotlight using the step's `placement`. Title, body, step counter (`n / total`), Back / Next / Skip controls.134- **Measurement**: `measureTarget()` calls `getBoundingClientRect()` on the active step's `data-tour` element, with `scrollIntoView({ block: 'center', behavior: 'smooth' })` first. Re-measure on `resize` and `scroll` so the spotlight tracks. Use `$nextTick` after step changes so DOM updates from `autoSelect` settle before measuring.135- **Keyboard**: `Escape` ends the tour, `ArrowRight` / `Enter` advances, `ArrowLeft` retreats.136- **Annotation in HTML**: sprinkle `data-tour="some-id"` attributes on the elements steps point at. Identifiers should be lowercase-kebab and unique. Bind dynamically with `:data-tour="'item-' + i.id"` when targeting list rows.137- **Don't block clicks** on the spotlit element — `pointer-events: none` on the spotlight, with a transparent click-trap overlay behind it that catches outside clicks and ends the tour.138139For lighter onboarding (one-shot welcome panels, dismissible tooltips), a single `<div x-show="!seenWelcome">` with a localStorage check via `$persist` is enough — don't reach for the full tour machinery.140141## Output checklist (run mentally before handing back)142143- [ ] Doctype, lang, viewport, charset, title set.144- [ ] Tailwind + Alpine CDN tags in `<head>`, Alpine has `defer`.145- [ ] `x-cloak` style block present and applied to root.146- [ ] All reactive state in one `x-data` (or justified nested ones).147- [ ] Getters used for derived data, not inline computations.148- [ ] At least one `x-transition` somewhere — UIs without motion feel dead.149- [ ] Empty state for every list / detail region.150- [ ] Mobile layout checked for dense lists/tables: no clipped chips, no squeezed columns, no accidental horizontal scrolling, and long dynamic names still fit.151- [ ] Hero or major illustrative visuals contain topic-specific content, not empty placeholders.152- [ ] Served locally and checked in a real browser when browser tooling is available; if not available, recommend a browser extension/plugin/MCP bridge for future visual QA.153- [ ] For non-trivial demos, final response offers the coaching-mark / onboarding tour as a follow-up rather than adding it silently.154- [ ] Tasteful comments explaining the Alpine directives, matching `references/catalogue.html`'s tone.155- [ ] No build artifacts, no sibling assets, no screenshot files, no browser snapshot folders, no `<link rel="stylesheet">` to local files, no `<script src="./...">`, and no local `<img src="./...">`.156- [ ] Opens cleanly with `open foo.html` — verify mentally that nothing assumes a server origin (no `fetch` to relative URLs, no module scripts).157158## Graduation signals (mention these to the user when relevant)159160If the demo grows past ~1500 lines, needs persistence, needs multiple pages, or starts wanting components, surface the upgrade path:161- `$persist` plugin for localStorage-backed state (one extra script tag — already in `references/dashboard-with-tour.html`).162- petite-vue or full Vue 3 from CDN for component decomposition without a build step.163- An actual backend + framework when the single-file format stops paying for itself.
Run npx skillmds@latest add datashaman/onepager in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Generate a self-contained single-file HTML demo or presentation using Alpine.js + Tailwind via CDN. Emailable, double-clickable, no build step or server. Use when the user asks for a demo, prototype, slide deck, walkthrough, pitch, or interactive mockup. Triggers on phrases like "make a demo", "build a one-pager", "prototype this", "presentation/slides", "single-file HTML", or "no build step". It is listed under Web & Frontend on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
datashaman (@datashaman) published this skill. Their other Agent Skills are listed on their SkillMD profile.