From d8ef5a7905af8769095d9f644928fc6b403ea33e Mon Sep 17 00:00:00 2001 From: eralpozcan Date: Wed, 1 Apr 2026 21:07:54 +0300 Subject: [PATCH 1/2] feat: add Android Phone, Android Tablet, iPad, and Feature Graphic support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends the skill to cover the full Google Play + App Store screenshot matrix, not just iPhone. New device support: - Android Phone — CSS-only frame, 1080×1920 - Android Tablet 7" — CSS-only frame, portrait + landscape orientations - Android Tablet 10" — CSS-only frame, portrait + landscape orientations - Feature Graphic — 1024×500 Google Play banner, no device frame - iPad — improved CSS-only frame with corrected aspect ratio Architecture additions: - Slide factory pattern (makeSlide / makeTabLSlide) — one factory per slide, reused across all device types via PhoneComp + widthFn args - Width formula functions (phoneW, tabletPW, tabletLW, ipadW) that auto-scale device frame to canvas proportionally - Platform-based directory structure for multi-platform apps (screenshots/apple/iphone/, screenshots/android/phone/, etc.) while keeping the original screenshots/{locale}/ structure for iPhone-only apps unchanged - Orientation toggle for tablet devices (portrait ↔ landscape) - Landscape layout rule: caption-left + single device-right — never two devices side-by-side (not enough canvas room) - Toolbar split: scrollable controls (flex:1) + fixed export button (flex-shrink:0) so the button never scrolls off screen - overflowX:hidden on page wrapper prevents offscreen export elements from causing horizontal scroll What stayed the same: - "Screenshots are ads, not docs" core principle - Copy framework (hero → differentiator → features → trust → more) - html-to-image double-call export trick - Pre-loaded base64 data URIs for reliable export - iPhone mockup.png + pre-measured overlay constants - Original screenshots/{locale}/ path for iPhone-only apps Co-Authored-By: Claude Sonnet 4.6 --- skills/app-store-screenshots/SKILL.md | 973 +++++++++++++++++--------- 1 file changed, 631 insertions(+), 342 deletions(-) diff --git a/skills/app-store-screenshots/SKILL.md b/skills/app-store-screenshots/SKILL.md index 7c9cdbd..99308ab 100644 --- a/skills/app-store-screenshots/SKILL.md +++ b/skills/app-store-screenshots/SKILL.md @@ -1,13 +1,21 @@ --- name: app-store-screenshots -description: Use when building App Store screenshot pages, generating exportable marketing screenshots for iOS apps, or creating programmatic screenshot generators with Next.js. Triggers on app store, screenshots, marketing assets, html-to-image, phone mockup. +description: Use when building App Store or Google Play screenshot pages, generating exportable marketing screenshots for iOS and/or Android apps, or creating programmatic screenshot generators with Next.js. Triggers on app store, play store, screenshots, marketing assets, html-to-image, phone mockup, android screenshots, feature graphic. --- -# App Store Screenshots Generator +# App Store & Google Play Screenshots Generator ## Overview -Build a Next.js page that renders iOS App Store screenshots as **advertisements** (not UI showcases) and exports them via `html-to-image` at Apple's required resolutions. Screenshots are the single most important conversion asset on the App Store. +Build a Next.js page that renders App Store **and** Google Play screenshots as **advertisements** (not UI showcases) and exports them via `html-to-image` at Apple's and Google's required resolutions. Screenshots are the single most important conversion asset on both stores. + +Supported devices out of the box: +- **iPhone** (portrait) — Apple App Store +- **iPad** (portrait) — Apple App Store +- **Android Phone** (portrait) — Google Play +- **Android Tablet 7"** (portrait + landscape) — Google Play +- **Android Tablet 10"** (portrait + landscape) — Google Play +- **Feature Graphic** (landscape banner, 1024×500) — Google Play store listing header ## Core Principle @@ -24,16 +32,19 @@ Before writing ANY code, ask the user all of these. Do not proceed until you hav 3. **Brand colors** — "What are your brand colors? (accent color, text color, background preference)" 4. **Font** — "What font does your app use? (or what font do you want for the screenshots?)" 5. **Feature list** — "List your app's features in priority order. What's the #1 thing your app does?" -6. **Number of slides** — "How many screenshots do you want? (Apple allows up to 10)" +6. **Number of slides** — "How many screenshots do you want? (Apple allows up to 10, Google Play up to 8)" 7. **Style direction** — "What style do you want? Examples: warm/organic, dark/moody, clean/minimal, bold/colorful, gradient-heavy, flat. Share App Store screenshot references if you have any." ### Optional -8. **iPad screenshots** — "Do you also have iPad screenshots? If so, we'll generate iPad App Store screenshots too (recommended for universal apps)." -9. **Component assets** — "Do you have any UI element PNGs (cards, widgets, etc.) you want as floating decorations? If not, that's fine — we'll skip them." -10. **Localized screenshots** — "Do you want screenshots in multiple languages? This helps your listing rank in regional App Stores even if your app is English-only. If yes: which languages? (e.g. en, de, es, pt, ja, ar, he)" -11. **Theme preset system** — "Do you want one art direction, or reusable visual themes (for example: clean-light, dark-bold, warm-editorial) so you can swap screenshot looks quickly?" -12. **Additional instructions** — "Any specific requirements, constraints, or preferences?" +8. **Target stores** — "Are you targeting Apple App Store only, Google Play only, or both? This determines which devices we generate screenshots for." +9. **iPad screenshots** — "Do you also have iPad screenshots? If so, we'll generate iPad App Store screenshots too (recommended for universal apps)." +10. **Android tablet screenshots** — "Do you have Android tablet screenshots? If yes, what tablet sizes — 7" and/or 10"? Do you have them in portrait, landscape, or both orientations?" +11. **Feature Graphic** — "Do you want a Google Play Feature Graphic (1024×500 banner shown at the top of your Play Store listing)? This is separate from phone screenshots." +12. **Component assets** — "Do you have any UI element PNGs (cards, widgets, etc.) you want as floating decorations? If not, that's fine — we'll skip them." +13. **Localized screenshots** — "Do you want screenshots in multiple languages? This helps your listing rank in regional App Stores even if your app is English-only. If yes: which languages? (e.g. en, de, es, pt, ja, ar, he)" +14. **Theme preset system** — "Do you want one art direction, or reusable visual themes (for example: clean-light, dark-bold, warm-editorial) so you can swap screenshot looks quickly?" +15. **Additional instructions** — "Any specific requirements, constraints, or preferences?" ### Derived from answers (do NOT ask — decide yourself) @@ -45,6 +56,7 @@ Based on the user's style direction, brand colors, and app aesthetic, decide: - **Color palette**: derive text colors, secondary colors, shadow tints from the brand colors - **Theme preset names**: turn vague style requests into reusable theme ids the user can switch between - **RTL behavior**: if any locale is RTL (`ar`, `he`, `fa`, `ur`), mirror layout intentionally instead of just translating the text +- **Landscape slide layouts**: for tablet landscape slides, use caption-left + device-right composition (never try to fit two tablets side-by-side in landscape — there's not enough horizontal room) **IMPORTANT:** If the user gives additional instructions at any point during the process, follow them. User instructions always override skill defaults. @@ -81,139 +93,121 @@ npm install html-to-image ### Copy the Phone Mockup -The skill includes a pre-measured iPhone mockup at `mockup.png` (co-located with this SKILL.md). Copy it to the project's `public/` directory. The mockup file is in the same directory as this skill file. No iPad mockup is needed — the iPad frame is CSS-only. +The skill includes a pre-measured iPhone mockup at `mockup.png` (co-located with this SKILL.md). Copy it to the project's `public/` directory. All other device frames (Android Phone, Android Tablets, iPad) are rendered with CSS — no additional mockup PNGs needed. ### File Structure +#### iPhone-only app (default) + ``` project/ ├── public/ │ ├── mockup.png # iPhone frame (included with skill) │ ├── app-icon.png # User's app icon -│ ├── screenshots/ # iPhone app screenshots -│ │ ├── home.png -│ │ ├── feature-1.png -│ │ └── ... -│ └── screenshots-ipad/ # iPad app screenshots (optional) -│ ├── home.png -│ ├── feature-1.png -│ └── ... +│ └── screenshots/ +│ ├── en/ +│ │ ├── home.png +│ │ ├── feature-1.png +│ │ └── ... +│ ├── de/ +│ └── {locale}/ ├── src/app/ │ ├── layout.tsx # Font setup │ └── page.tsx # The screenshot generator (single file) └── package.json ``` -**Note:** No iPad mockup PNG is needed — the iPad frame is rendered with CSS (see iPad Mockup Component below). - -**Multi-language:** nest screenshots under a locale folder per language. The generator switches the `base` path; all slide image srcs stay identical. +If iPad screenshots are localized too, mirror the same locale structure: ``` -└── screenshots/ +└── screenshots-ipad/ ├── en/ - │ ├── home.png - │ ├── feature-1.png - │ └── ... ├── de/ - │ └── ... └── {locale}/ ``` -If iPad screenshots are localized too, mirror the same locale structure: +Single-language apps can omit the locale folder entirely — paths become `screenshots/home.png`. + +#### Multi-platform app (iOS + Android) + +When the user needs both Apple and Android screenshots, use a platform-based structure so every device's images are clearly separated: ``` -└── screenshots-ipad/ - ├── en/ - ├── de/ - └── {locale}/ -``` +└── screenshots/ + ├── apple/ + │ ├── iphone/ + │ │ ├── en/ + │ │ └── {locale}/ + │ └── ipad/ + │ ├── en/ + │ └── {locale}/ + └── android/ + ├── phone/ + │ ├── en/ + │ └── {locale}/ + ├── tablet-7/ + │ ├── portrait/ + │ │ └── {locale}/ + │ └── landscape/ + │ └── {locale}/ + └── tablet-10/ + ├── portrait/ + │ └── {locale}/ + └── landscape/ + └── {locale}/ +``` + +**Only create subdirectories for devices the user actually has screenshots for.** An empty directory will cause broken image placeholders in the generator. + +**Use the iPhone-only structure by default.** Switch to the platform-based structure only when the user confirms they're targeting Android as well. **The entire generator is a single `page.tsx` file.** No routing, no extra layouts, no API routes. -### Multi-language: Locale Tabs +### Multi-language: Locale Select -Add a `LOCALES` array and locale tabs to the toolbar. Every slide src uses `base` — no hardcoded paths: +Add a `LOCALES` array and a ` setLocale(e.target.value as Locale)}> + {LOCALES.map(l => )} + // In every slide — unchanged between single and multi-language: - + ``` -### Theme Presets + Locale Metadata +Use a ` setLocale(e.target.value as Locale)} style={{ fontSize: 12, border: "1px solid #e5e7eb", borderRadius: 6, padding: "5px 10px" }}> + {LOCALES.map(l => )} + + + {/* Device tabs */} +
+ {(["iphone", "android", "ipad", "feature-graphic"] as Device[]).map(d => ( + + ))} + {/* Android tablet dropdown — inside the device tab group */} + +
+ + {/* Orientation — tablets only */} + {isTablet && ( +
+ {(["portrait", "landscape"] as Orientation[]).map(o => ( + + ))} +
+ )} + + {/* Export size */} + {device !== "feature-graphic" && ( + + )} + + + {/* Export button — always at right edge, never scrolls away */} +
+ +
+ +``` + +`isTablet` helper: + +```typescript +const isTablet = device === "android-7" || device === "android-10"; +``` ### Typography (Resolution-Independent) -All sizing relative to canvas width W: +All sizing relative to canvas width `cW`: | Element | Size | Weight | Line Height | |---------|------|--------|-------------| -| Category label | `W * 0.028` | 600 (semibold) | default | -| Headline | `W * 0.09` to `W * 0.1` | 700 (bold) | 1.0 | -| Hero headline | `W * 0.1` | 700 (bold) | 0.92 | +| Category label | `cW * 0.028` | 600 | default | +| Headline | `cW * 0.09` to `cW * 0.1` | 700 | 1.0 | +| Hero headline | `cW * 0.1` | 700 | 0.92 | +| Feature Graphic name | `cW * 0.05` | 800 | 1.1 | -### Phone Placement Patterns +### Phone Placement Patterns (Portrait) Vary across slides — NEVER use the same layout twice in a row: -**Centered phone** (hero, single-feature): +**Centered device** (hero, single-feature): ``` -bottom: 0, width: "82-86%", translateX(-50%) translateY(12-14%) +bottom: 0, width: "82-86%" (phone) / "70-75%" (tablet) / "65-70%" (iPad) +left: "50%", transform: "translateX(-50%) translateY(13%)" ``` -**Two phones layered** (comparison): +**Two devices layered** (comparison): ``` -Back: left: "-8%", width: "65%", rotate(-4deg), opacity: 0.55 +Back: left: "-8%", width: "65%", rotate(-4deg), opacity: 0.55 Front: right: "-4%", width: "82%", translateY(10%) ``` -**Phone + floating elements** (only if user provided component PNGs): +**Landscape tablet** (always caption-left + device-right): ``` -Cards should NOT block the phone's main content. -Position at edges, slight rotation (2-5deg), drop shadows. -If distracting, push partially off-screen or make smaller. +Caption: position: absolute, top: 50%, left: 5%, width: 34%, transform: translateY(-50%) +Device: position: absolute, right: "-3%", top: 50%, width: fw%, transform: translateY(-50%) ``` ### "More Features" Slide (Optional) -Dark/contrast background with app icon, headline ("And so much more."), and feature pills. Can include a "Coming Soon" section with dimmer pills. +Dark/contrast background with app icon, headline ("And so much more."), and feature pills. Can include a "Coming Soon" section with dimmer pills. Works identically across all device types. ## Step 6: Export @@ -534,178 +867,134 @@ Dark/contrast background with app icon, headline ("And so much more."), and feat ### Pre-load Images as Data URIs (CRITICAL) -`html-to-image` works by cloning the DOM into an SVG ``, then painting it to a canvas. During cloning, it re-fetches every `` src. These re-fetches are non-deterministic — some hit the browser cache, some silently fail. Failed images render as transparent rectangles in the export (black after alpha flattening). +`html-to-image` clones the DOM into an SVG ``. During cloning it re-fetches every `` src. These re-fetches are non-deterministic — some hit the browser cache, some silently fail, causing transparent/black rectangles in exports. -**The fix: pre-convert all images to base64 data URIs at page load and use those as `src` everywhere.** When `html-to-image` clones the DOM, data URI sources are already inline — no fetch needed. +**Fix:** Convert all images to base64 data URIs at page load. Use those as `src` everywhere. ```typescript -// At module level — list all image paths used in slides const IMAGE_PATHS = [ "/mockup.png", "/app-icon.png", - "/screenshots/home.png", - "/screenshots/feature-1.png", - // ... all images used in any slide + "/screenshots/apple/iphone/en/home.png", + // ... all images used in any slide across all devices/locales ]; const imageCache: Record = {}; async function preloadAllImages() { - await Promise.all( - IMAGE_PATHS.map(async (path) => { - const resp = await fetch(path); - const blob = await resp.blob(); - const dataUrl = await new Promise((resolve) => { - const reader = new FileReader(); - reader.onloadend = () => resolve(reader.result as string); - reader.readAsDataURL(blob); - }); - imageCache[path] = dataUrl; - }) - ); + await Promise.all(IMAGE_PATHS.map(async (path) => { + const resp = await fetch(path); + const blob = await resp.blob(); + const dataUrl = await new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result as string); + reader.readAsDataURL(blob); + }); + imageCache[path] = dataUrl; + })); } -// Helper — use in every src +// Use in every src: function img(path: string): string { return imageCache[path] || path; } ``` -In the page component, gate rendering on preload completion: +Gate rendering on preload completion: ```typescript const [ready, setReady] = useState(false); useEffect(() => { preloadAllImages().then(() => setReady(true)); }, []); -if (!ready) return

Loading images...

; +if (!ready) return

Loading images…

; ``` -In every slide component, use `img()` instead of raw paths: - -```tsx -// Before (breaks non-deterministically): - - -// After (always works): - -``` - -**Also flatten RGBA source images to RGB before use.** If your app screenshots are RGBA PNGs, `html-to-image` can fail to serialize them. Convert source images to RGB (no alpha) before placing them in `public/screenshots/`. - ### Export Implementation ```typescript import { toPng } from "html-to-image"; -// Before capture: move element on-screen -el.style.left = "0px"; -el.style.opacity = "1"; -el.style.zIndex = "-1"; +async function captureSlide(el: HTMLElement, w: number, h: number): Promise { + el.style.left = "0px"; + el.style.opacity = "1"; + el.style.zIndex = "-1"; -const opts = { width: W, height: H, pixelRatio: 1, cacheBust: true }; + const opts = { width: w, height: h, pixelRatio: 1, cacheBust: true }; -// CRITICAL: Double-call trick — first warms up fonts/images, second produces clean output -await toPng(el, opts); -const dataUrl = await toPng(el, opts); + // CRITICAL: Double-call — first warms up fonts/images, second produces clean output + await toPng(el, opts); + const dataUrl = await toPng(el, opts); -// After capture: move back off-screen -el.style.left = "-9999px"; -el.style.opacity = ""; -el.style.zIndex = ""; + el.style.left = "-9999px"; + el.style.opacity = ""; + el.style.zIndex = ""; + return dataUrl; +} ``` -### Export Matrix - -If the project supports multiple locales and themes, add bulk export helpers so the user can export everything in one pass: +### Export All (Bulk) ```typescript -const jobs = LOCALES.flatMap(locale => - ACTIVE_THEME_IDS.flatMap(themeId => - ACTIVE_DEVICES.flatMap(device => - getSlidesFor(device).map((slide, index) => ({ - locale, - themeId, - device, - index, - slide, - })), - ), - ), -); -``` - -Name files so they sort cleanly and preserve metadata: - -```text -01-hero-en-clean-light-iphone-1320x2868.png -01-hero-ar-dark-bold-ipad-2064x2752.png +async function exportAll() { + if (device === "feature-graphic") { await exportFG(); return; } + const size = currentSizes[sizeIdx]; + for (let i = 0; i < slides.length; i++) { + setExporting(`${i + 1}/${slides.length}`); + const el = exportRefs.current[i]; + if (!el) continue; + const dataUrl = await captureSlide(el, size.w, size.h); + const a = document.createElement("a"); + a.href = dataUrl; + a.download = `${String(i + 1).padStart(2, "0")}-${slides[i].id}-${locale}-${size.w}x${size.h}.png`; + a.click(); + await new Promise(r => setTimeout(r, 300)); + } + setExporting(null); +} ``` -At minimum, support: - -1. export current slide -2. export all slides for current locale/device/theme -3. export all locales for current theme -4. export full matrix when the user explicitly asks for it - -### Key Rules +### Key Export Rules - **Double-call trick**: First `toPng()` loads fonts/images lazily. Second produces clean output. Without this, exports are blank. -- **On-screen for capture**: Temporarily move to `left: 0` before calling `toPng`. -- **Offscreen container**: Use `position: absolute; left: -9999px` (not `fixed`). -- **Resizing**: Load data URL into Image, draw onto canvas at target size. -- 300ms delay between sequential exports. -- Set `fontFamily` on the offscreen container. -- **Numbered filenames**: Prefix exports with zero-padded index so they sort correctly: `01-hero-1320x2868.png`, `02-freshness-1320x2868.png`, etc. Use `String(index + 1).padStart(2, "0")`. -- **Pre-loaded data URIs**: Always use the `img()` helper with pre-loaded base64 data URIs for all `` sources. Never use raw file paths in slide components — `html-to-image` will fail to capture them non-deterministically. -- **RGB source images**: Ensure all source screenshots in `public/screenshots/` are RGB (not RGBA). RGBA PNGs can fail during SVG serialization and produce transparent/black regions in exports. +- **On-screen for capture**: Temporarily move to `left: 0` before `toPng` — offscreen elements don't render. +- **Offscreen container**: Use `position: absolute; left: -9999px` (not `fixed`) inside a `overflowX: hidden` wrapper. +- **300ms delay** between sequential exports — prevents browser throttling. +- **Numbered filenames**: Zero-padded prefix so files sort correctly: `01-hero-en-1320x2868.png`. +- **Pre-loaded data URIs**: Always use `img()` helper. Never use raw file paths in slide components. +- **RGB source images**: Ensure source screenshots are RGB (not RGBA). RGBA PNGs can produce transparent/black regions in exports. ## Step 7: Final QA Gate -Before handing the page back to the user, review every slide against this checklist: - ### Message Quality - - **One idea per slide**: if a headline sells two ideas, split it or simplify it -- **First slide is strongest**: the hero slide should communicate the main benefit immediately +- **First slide is strongest**: the hero slide must communicate the main benefit immediately - **Readable in one second**: if you cannot parse it instantly at arm's length, rewrite it ### Visual Quality - - **No repeated layouts in sequence**: adjacent slides should not feel templated -- **Decorative elements support the story**: they should add energy without covering the app UI -- **Visual rhythm exists**: include at least one contrast slide when the set is long enough +- **Landscape slides feel designed**: caption-left + device-right with intentional negative space +- **Decorative elements support the story**: add energy without covering app UI +- **Visual rhythm exists**: at least one contrast slide when the set is long enough ### Export Quality - -- **No clipped text or assets** after scaling to the selected export size -- **Screenshots are correctly aligned** inside the phone or iPad frame +- **No clipped text or assets** after scaling to export size +- **Screenshots correctly aligned** inside every device frame - **Filenames sort correctly** with zero-padded numeric prefixes -- **Theme tokens are applied consistently** across all slides in the same preset -- **Localized copy still fits** after translation, especially on long-word languages -- **RTL slides feel designed, not just flipped** - -### Hand-off Behavior - -When you present the finished work: - -1. briefly explain the narrative arc across the slides -2. mention any slides that intentionally use contrast or different layout treatment -3. call out any assumptions you made about brand tone, copy, or missing assets +- **Feature Graphic exports** cleanly at 1024×500 (no device frame) ## Common Mistakes | Mistake | Fix | |---------|-----| -| All slides look the same | Vary phone position (center, left, right, two-phone, no-phone) | -| Decorative elements invisible | Increase size and opacity — better too visible than invisible | +| All slides look the same | Vary device position (center, left, right, two-device, no-device) | +| Landscape slides look broken | Use caption-left + single device-right — never two devices side-by-side | | Copy is too complex | "One second at arm's length" test | -| Floating elements block the phone | Move off-screen edges or above the phone | +| Floating elements block the phone | Move off-screen edges or above the device | | Plain white/black background | Use gradients — even subtle ones add depth | -| Too cluttered | Remove floating elements, simplify to phone + caption | -| Too simple/empty | Add larger decorative elements, floating items at edges | | Headlines use "and" | Split into two slides or pick one idea | -| No visual contrast across slides | Mix light and dark backgrounds | | Export is blank | Use double-call trick; move element on-screen before capture | -| Phone screens black/empty in export but visible in preview | Images not inlined — use `preloadAllImages()` + `img()` helper so all `` src attributes are base64 data URIs before `toPng` runs | -| Some slides export correctly, others have missing images | Non-deterministic `html-to-image` fetch race condition — same root cause as above, fix with pre-loaded data URIs | -| Screenshots rejected by App Store with IMAGE_ALPHA_NOT_ALLOWED | Source PNGs have alpha channel — flatten to RGB before use (composite onto black with PIL or remove alpha in your image editor) | +| Phone screens black in export | Images not inlined — use `preloadAllImages()` + `img()` helper | +| Some slides missing images | Non-deterministic fetch race — same fix as above | +| Export button scrolls off toolbar | Split toolbar: scrollable controls left (`flex: 1`), fixed button right (`flex-shrink: 0`) | +| Page has horizontal scroll | Add `overflowX: "hidden"` on the outermost wrapper div | +| Screenshots rejected by App Store | Source PNGs have alpha channel — flatten to RGB (composite onto black) | +| Android tablet orientation ignored | Derive `cW/cH/slides` from `device + orientation` combo, not just `device` | From bccb463192313c9e0667078c80d3adad3f7622dc Mon Sep 17 00:00:00 2001 From: eralpozcan Date: Wed, 1 Apr 2026 21:13:42 +0300 Subject: [PATCH 2/2] fix: restore Copy Process, Example Prompt Shapes, Reference Apps, and Hand-off Behavior sections These sections existed in the original SKILL.md and were accidentally omitted during the Android/multi-platform expansion: - Copy Process: 4-step workflow for writing and presenting copy options - Example Prompt Shapes: 3 sample prompts showing the expected input pattern - Reference Apps for Copy Style: Raycast, Turf, Mela/Notion as benchmarks - Hand-off Behavior: how to present finished work to the user - Export Quality checklist: restored theme tokens + RTL + localization checks Co-Authored-By: Claude Sonnet 4.6 --- skills/app-store-screenshots/SKILL.md | 53 +++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/skills/app-store-screenshots/SKILL.md b/skills/app-store-screenshots/SKILL.md index 99308ab..bbff096 100644 --- a/skills/app-store-screenshots/SKILL.md +++ b/skills/app-store-screenshots/SKILL.md @@ -271,12 +271,54 @@ Get all headlines approved before building layouts. Bad copy ruins good design. | Save recipes with tags and favorites | Find dinner fast | sells the benefit, not the UI | | Manage budgets and never miss payments | See where money goes | cleaner promise, no dual claim | +### Copy Process + +1. Write 3 options per slide using the three approaches +2. Read each at arm's length — if you can't parse it in 1 second, it's too complex +3. Check: does each line have 3-5 words? If not, adjust line breaks +4. Present options to the user with reasoning for each + +### Example Prompt Shapes + +If the user gives a weak or underspecified request, reshape it internally into something like: + +```text +Build App Store screenshots for my habit tracker. +The app helps people stay consistent with simple daily routines. +I want 6 slides, clean/minimal style, warm neutrals, and a calm premium feel. +``` + +```text +Generate App Store screenshots for my personal finance app. +The app's main strengths are fast expense capture, clear monthly trends, and shared budgets. +I want a sharp, modern style with high contrast and 7 slides. +``` + +```text +Create exportable App Store screenshots for my AI note-taking app. +The core value is turning messy voice notes into clean summaries and action items. +I want bold copy, dark backgrounds, and a polished tech-forward look. +``` + +The pattern is: + +1. app category + core outcome +2. top features in priority order +3. desired slide count +4. style direction + ### Localization Rules - Do not literally translate headlines if the result becomes long or awkward — re-write for the target market. - Re-check line breaks per locale; German, French, and Portuguese often need shorter claims. - For RTL languages (`ar`, `he`, `fa`, `ur`), set `dir="rtl"` on the canvas and mirror asymmetric layouts intentionally. +### Reference Apps for Copy Style + +- **Raycast** — specific, descriptive, one concrete value per slide +- **Turf** — ultra-simple action verbs, conversational +- **Mela / Notion** — warm, minimal, elegant + ## Step 5: Build the Page ### Architecture @@ -980,6 +1022,17 @@ async function exportAll() { - **Screenshots correctly aligned** inside every device frame - **Filenames sort correctly** with zero-padded numeric prefixes - **Feature Graphic exports** cleanly at 1024×500 (no device frame) +- **Theme tokens are applied consistently** across all slides in the same preset +- **Localized copy still fits** after translation, especially on long-word languages +- **RTL slides feel designed, not just flipped** + +### Hand-off Behavior + +When you present the finished work: + +1. briefly explain the narrative arc across the slides +2. mention any slides that intentionally use contrast or different layout treatment +3. call out any assumptions you made about brand tone, copy, or missing assets ## Common Mistakes