clean-ui-shot
Skill4 starsChanged 2 days agoMITView on GitHub
Shoot polished, framed screenshots of a web app's real UI as cropped images, the app as a rounded, shadowed window on a stage, with padding where the window edge shows and bleed where the crop cuts through. Two styles, asked up front, clean (a soft gray stage) or glass (a gradient coloured from the UI itself, with a frosted white bezel). A house style for docs pages, changelogs, landing pages, and READMEs. Use whenever the user asks for UI screenshots, docs or changelog images, "nice", "framed", "clean", or "cropped" screenshots of their app, or wants existing product screenshots refreshed because the UI changed, even if they don't name this skill or describe the style.
- Installs packages
2 other projects use a version of this, 2 of them edited.
Adopted by
Most recently taken up by
- 1weiho/cinematic-shotedited, first seen Nov 1, 2026
- 1weiho/skillsedited, first seen Nov 1, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 2
- 1weiho/cinematic-shot★ 237100% same
- 1weiho/skills★ 237100% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository50 other files it gives its agents.
- agent-writingSkill
- arenaSkill
- blast-radiusSkill
- bun-playwright-runner-selectionSkill
- cinematic-shotSkill
- codebase-designSkill
- debug-loopSkill
- dep-upgradeSkill
- diagnosing-bugsSkill
- discoverSkill
- domain-modelingSkill
- earshotSkill
- eval-judgeSkill
- flaky-testSkill
- grillingSkill
- grillSkill
- idea-scoutSkill
- improve-codebase-architectureSkill
- interrogateSkill
- make-mediaSkill
- migrate-to-rustSkill
- migration-planSkill
- multi-agent-windows-hazardsSkill
- perf-loopSkill
- postmortemSkill
- prototypeSkill
- prSkill
- real-soundSkill
- recallSkill
- release-notesSkill
- repo-mapSkill
- researchSkill
- retroSkill
- secure-diffSkill
- sellSkill
- subagent-report-recoverySkill
- tasteSkill
- taste-skillSkill
- tddSkill
- teachSkill
- to-questionnaireSkill
- to-specSkill
- to-ticketsSkill
- wayfinderSkill
- weeklySkill
- windows-bash-backslash-halvingSkill
- wizardSkill
- writing-for-agentsSkill
- ycSkill
- ystack-upgradeSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 8 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 57
Use a scratchpad directory for shot lists and outputs until images are final.
- Distinctive: line 100
Look at every image: before using it. To review a batch at once:
- Very specific: line 104
Check for: a crop that slices through a label or pill, empty space dominating the frame, text too small to read, a stray hover or focus …
- Distinctive: line 112
If the site has an image-zoom component, use it so the 2000px detail is reachable on click.
- Distinctive: line 117
When replacing an image, update alt text that no longer matches, and delete files nothing references any more (git grep the name first).
- Distinctive: line 124
Clean up: Stop the server by port and remove any scratch copies:
- Distinctive: line 148
Consistency: keep the stage, padding, and radius as the script sets them, so new shots match the existing ones.
- Very specific: line 164
Search and fuzzy menus: use a query that returns clean, on-topic results, or none at all.
- Distinctive: line 172
Content: use demo data and generated assets only.
- Distinctive: line 175
Glass palette: check the gradient against the product.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Clean UI shot
From 1weiho/cinematic-shot by Yiwei Ho, MIT licence (see
LICENSE). Unmodified apart from this line.
The output is an image like a product-page detail shot: a crop of the real UI, rendered as a window with rounded corners and a shadow on a stage. Window edges that fall inside the crop get padding; edges where the crop cuts through the UI bleed off the stage. That contrast is what makes a crop read as "a detail of a real app" instead of a pasted rectangle, so choose crops with it in mind.
There are two styles. Both use the same crops and render the UI at the same scale; only the stage and frame differ.
- clean (default): a soft warm-gray gradient stage, a layered neutral shadow, 56px of padding. Quiet and consistent; suits docs, changelogs, and READMEs, where many shots sit together.
- glass: a gradient stage coloured from the shot itself, a frosted, semi-transparent white bezel around the window, and 96px of padding. The script samples the capture, picks its main hues (saturated brand accents count more than large pale areas), and lays soft tints of them into the corners, so every product gets its own palette. A dark UI gets deep tones; a UI with no colour falls back to the clean stage. Suits landing pages, launch posts, and social images.
Everything is captured from the real app running locally, ideally a throwaway instance with demo data, so the shots show the current UI, not a mock.
The scripts live in the scripts/ folder next to this file (written
<skill>/scripts/ below). They need Node, playwright with Chromium, and
sharp, resolved from the directory you run them in. If the project doesn't
have them, npm i playwright sharp in a scratch directory, run
npx playwright install chromium there once, and run the scripts from that
directory.
Before you start
- Ask which style the user wants before shooting, unless they already said. Describe both in a sentence each (as above), say which you'd pick for where the images will go, and wait for the answer. Use one style per batch, so images that sit together match. If the project already has shots in one of these styles, say so and suggest matching them.
- Ask before starting a dev server. Many people prefer to start their own. Explain why the shots need one and propose a throwaway instance on a free port. Approval doesn't carry over from an earlier session.
- Never drive a server or workspace the user is using. Clicking around a real workspace creates, edits, and comments on real data. Prefer a scratch copy seeded with the project's demo or fixture data. If the app has none, ask what is safe to show.
- Use a scratchpad directory for shot lists and outputs until images are final.
Workflow
- Pick the shots. One image per idea. Show the state that explains the feature: a selected element with its panel open, a dialog with real results, a list with real-looking rows. For docs, the page's hero image usually goes right under the title, with section images under the heading they illustrate. For a changelog, only releases worth a picture get one.
- Start the app in the background (
run_in_background) and read its output for the ready line and URL. If it fails, fix the cause (missing install, stale build) before shooting. - Write a shots file in the scratchpad. Start from
<skill>/scripts/shots.example.mjs, which has the field reference at the top and recipes for full windows, panel crops, menus, command palettes, mocked backends, and popups. Read the app's source for real routes, accessible names, and visible text, and use them instead of guessing selectors. Shoot.
node <skill>/scripts/shoot.mjs <shots.mjs> --url http://127.0.0.1:<port> --out <dir> --style clean|glass [--format png|webp] [--only a,b] [--raw <dir>]Each shot is captured at 3× device scale and composed at 2×, giving a 2000px-wide image for clean (2160px for glass, whose wider padding widens the stage).
--styleapplies to every shot; a shot's ownstyleoverrides it. Glass prints the gradient it built for each shot. Pass--rawto keep the uncomposed captures for debugging.The default format is lossless PNG: a master that keeps coloured text crisp and that a site's image pipeline (Next
<Image>, Astro, a CDN) can re-encode without compounding loss. Pass--format webpfor a q86 webp at a fraction of the size when the project already keeps its images as webp, or when the files are committed and served as-is with no pipeline and size matters. Lossy webp subsamples chroma, so small coloured text softens slightly. Expect clean PNGs of roughly 100–400 KB and glass PNGs of around 0.5–1.2 MB (the stage's film grain doesn't compress losslessly); webp is usually under 100 KB in either style.- Look at every image before using it. To review a batch at once:
Check for: a crop that slices through a label or pill, empty space dominating the frame, text too small to read, a stray hover or focus ring, a loading or skeleton state, a toast, odd search matches, the wrong page. Fix and reshoot withnode <skill>/scripts/contact-sheet.mjs <sheet.png> a.png b.png c.png d.png--only. - Place the images where the project already keeps them (look for an
existing
public/,assets/, ordocs/images/folder and match its naming and image format).- If the site has an image-zoom component, use it so the 2000px detail is reachable on click.
- Alt text describes what the image shows ("The Properties tab showing position, size, and alignment controls for a selected headline"), not that it is a screenshot.
- When replacing an image, update alt text that no longer matches, and
delete files nothing references any more (
git grepthe name first).
- Check them in context. Open the page that uses them, at desktop width and in dark mode if the site has one, and confirm the crop still reads at the size it's shown.
- Clean up. Stop the server by port and remove any scratch copies:
An exit code of 143 from the background server task just means it was killed.kill $(lsof -tiTCP:<port> -sTCP:LISTEN)
Choosing crops
- Viewport: 1280×800 by default, for home pages and full-window views. 1280×720 for editor-like layouts, so the work area fills its space instead of floating in whitespace.
- Width: a docs column shows images at roughly 700 css px. A crop much narrower than ~900 UI px gets blown up, and one wider than 1280 shrinks the text to unreadable. Panels and dialogs read well at 950–1100 wide.
- Which edges show: an edge is padded when the crop touches that side of
the viewport, and bleeds otherwise. A crop like
{ x: 300, y: 0, w: 980, h: 600 }shows the window's top and right edges and bleeds left and bottom, which suits right-side panels. Make every crop touch at least one viewport edge, or nothing in the frame shows a window edge. - Height: bleed the bottom (h ≈ 560–620 at 720 tall) rather than showing a tall strip of empty panel. Aim for roughly 1.5–1.8 : 1 output.
- Full window: omit
cropfor an overview shot. All four edges get padding. - Consistency: keep the stage, padding, and radius as the script sets them, so new shots match the existing ones. The dark stage is only for UIs that are dark themselves.
- Phones: for a phone-sized viewport (about 390×844), set
stageWso the UI isn't blown up (≈ 560 for clean, ≈ 640 for glass) and raiseradiusto about 40 so the window reads as a phone screen.
Gotchas
- Backend-only states: a scratch instance often lacks a logged-in
session, live data, or a running job. Mock the responses with
routesand seed client state withinit. If the app reacts to data arriving before the page settles (auto-scrolling, jumping to the latest item), delay the mocked responses a few seconds. - Popups and new windows: catch them with
context.waitForEvent('page')before the click that opens them, and return the popup fromsetup. - Search and fuzzy menus: use a query that returns clean, on-topic
results, or none at all. Wait for
networkidlewhen results come from the network. - Actions that write data: posting, saving, or commenting changes the scratch data, so later shots in the same run show the side effects (a badge, a new row). Reset the scratch data for a clean slate.
- Animation: the browser runs with reduced motion, but some transitions
ignore it. Raise
settlefor a shot that catches something mid-animation. - Content: use demo data and generated assets only. Never use real people's photos, avatars, names, or emails as sample content. Don't copy the user's own work-in-progress data into the scratch project.
- Glass palette: check the gradient against the product. A tiny accent
can outweigh the brand colour, or a large pale area can lose to a small
icon. If the colours are off, pass a CSS background as the shot's
gradient(start from the one the script printed), and use the same one for every shot in the batch. - Dark mode: shoot light by default. Light shots read fine as light cards on a dark site. Don't produce dark variants unless asked.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

