npx skills add ...
npx skills add affaan-m/ecc --skill ui-demo
Record polished UI demo videos using Playwright. Use when the user asks to create a demo, walkthrough, screen recording, or tutorial video of a web application. Produces WebM videos with visible cursor, natural pacing, and professional feel.
npx skills add affaan-m/ecc --skill ui-demo
Record polished demo videos of web applications using Playwright's video recording with an injected cursor overlay, natural pacing, and storytelling flow.
Every demo goes through three phases: Discover -> Rehearse -> Record. Never skip straight to recording.
Before writing any script, explore the target pages to understand what is actually there.
You cannot script what you have not seen. Fields may be <input> not <textarea>, dropdowns may be custom components not <select>, and comment boxes may support @mentions or #tags. Assumptions break recordings silently.
Navigate to each page in the flow and dump its interactive elements:
<select>, <input>, custom dropdowns, or comboboxes?value="0" or value="" which looks non-empty. Use Array.from(el.options).map(o => ({ value: o.value, text: o.text })). Skip options where text includes "Select" or value is "0".@mentions, #tags, markdown, or emoji? Check placeholder text.required, * in labels, and try submitting empty to see validation errors."Submit", "Submit Request", or "Send".input[type="number"] to its column header instead of assuming all numeric inputs mean the same thing.A field map for each page, used to write correct selectors in the script. Example:
Run through all steps without recording. Verify every selector resolves.
Silent selector failures are the main reason demo recordings break. Rehearsal catches them before you waste a recording.
Use ensureVisible, a wrapper that logs and fails loudly:
Only after discovery and rehearsal pass should you create the recording.
Plan the video as a story. Follow user-specified order, or use this default:
4s3s2s1.5-2s3s25-40ms per characterInject an SVG arrow cursor that follows mouse movements:
Call injectCursor(page) after every page navigation because the overlay is destroyed on navigate.
Never teleport the cursor. Move to the target before clicking:
Every call should include a descriptive label for debugging.
Type visibly, not instant-fill:
Use smooth scroll instead of jumps:
When showing a dashboard or overview page, move the cursor across key elements:
Inject a subtitle bar at the bottom of the viewport:
Call injectSubtitleBar(page) alongside injectCursor(page) after every navigation.
Usage pattern:
Guidelines:
Step N - Action format for consistency.Usage:
1280x720showSubtitle(page, 'Step N - ...') used at major transitionsmoveAndClick used for all clicks with descriptive labelstypeSlowly used for visible input"0" and "Select...".