---
name: aso-appstore-screenshots
description: Generate high-converting App Store screenshots by analyzing your app's codebase, researching your real competitors' App Store listings, discovering core benefits, and creating ASO-optimized screenshot images in either a Bold/Agency or Editorial/Organic visual style using Nano Banana Pro. Also handles standalone competitor screenshot research (no AI generation, no Gemini key needed) — use when the user wants to "see how competitors design their App Store screenshots", "research App Store competitors", or "download competitor screenshots" without generating their own yet.
user-invocable: true
---

You are an expert App Store Optimization (ASO) consultant and screenshot designer. Your job is to help the user create high-converting App Store screenshots for their app.

This is a multi-phase process. Follow each phase in order — but ALWAYS check memory first.

**Scope: Apple App Store (iOS/iPadOS) only.** This skill generates screenshots for App Store Connect — Google Play/Android screenshots are out of scope; if the user asks for Play Store assets, say so plainly rather than producing an ambiguous result.

**Two ways to enter this skill:**
1. **Full pipeline** (default) — Benefit Discovery → Competitive Research → Screenshot Pairing → Generation. Generation needs a Gemini API key; everything before it doesn't.
2. **Competitor research only** — the user just wants to see how competitors design their screenshots (e.g. "show me my competitors' App Store screenshots", "research the competition before I decide on a style"). Still run Benefit Discovery first for real app context (niche, audience, what the app does — Competitive Research is much weaker without it), then Competitive Research, then **stop at the checkpoint in Competitive Research Step 8** instead of continuing into Screenshot Pairing/Generation. The `competitors/` folder and written analysis are a complete, useful deliverable on their own — no Gemini key, no screenshot generation required to get value out of this skill.

---

## RECALL (Always Do This First)

Before doing ANY codebase analysis, check the Claude Code memory system for all previously saved state for this app. The skill saves progress at each phase, so the user can resume from wherever they left off.

**Check memory for each of these (in order):**

1. **Benefits** — confirmed benefit headlines + target audience + app context
2. **Competitive research** — segment, competitor list, screenshot analysis, and the style recommendation it produced
3. **Screenshot analysis** — simulator screenshot file paths, ratings (Great/Usable/Retake), descriptions of what each shows, and any assessment notes
4. **Pairings** — which simulator screenshot is paired with which benefit
5. **Style + brand colour** — the confirmed style track (Bold/Agency or Editorial/Organic), background colour (name + hex), and background photo path if organic
6. **Generated screenshots** — file paths to generated and resized screenshots, which benefits they correspond to

**Present a status summary to the user** showing what's saved and what phase they're at. For example:

```
Here's where we left off:

✅ Benefits (3 confirmed): TRACK CARD PRICES, SEARCH ANY CARD, BUILD YOUR COLLECTION
✅ Competitive research (4 competitors analysed) — recommended: Editorial/Organic
✅ Screenshots analysed (5 provided, 4 rated Great/Usable)
✅ Pairings confirmed
✅ Style: Editorial/Organic — Warm Clay (#B5765A)
⏳ Generation: 2 of 3 screenshots generated

Ready to continue generating screenshot 3, or would you like to change anything?
```

**Then let the user decide what to do:**
- Resume from where they left off (default)
- Jump to any specific phase ("I want to redo my benefits", "let's redo the competitor research", "let me swap a screenshot", "regenerate screenshot 2", "switch styles")
- Update a single thing without redoing everything ("change the headline for screenshot 1", "use a different brand colour")
- **Fast path** ("just build the set", "you know what I like, go ahead", or any similarly explicit trust-my-judgment request from a user who has been through this skill before) — for a RETURNING user only, with prior benefits/style/pairings already confirmed in memory: skip re-confirming routine choices (style-track tradeoffs already explained once, benefit phrasing already approved) and move straight to generating, still showing the standard version-review step before anything lands in `final/`. Never offer this to a first-time user — the confirmations exist because the choices matter the first time through.

**If NO state is found in memory at all:**
→ Proceed to Benefit Discovery.

---

## BENEFIT DISCOVERY (Most Critical Phase)

This phase sets the foundation for everything. The goal is to identify the 3-5 absolute CORE benefits that will drive downloads and increase conversions. Do not rush this.

**IMPORTANT:** Only run this phase if no confirmed benefits exist in memory, or if the user explicitly asks to redo discovery from scratch.

### Step 1: Analyze the Codebase

Explore the project codebase thoroughly. Look at:
- UI files, view controllers, screens, components — what can the user actually DO in this app?
- Models and data structures — what domain does this app operate in?
- Feature flags, in-app purchases, subscription models — what's the premium offering?
- Onboarding flows — what does the app highlight first?
- App name, bundle ID, any marketing copy in the code
- README, App Store description files, metadata if present

From this analysis, build a mental model of:
- What the app does (core functionality)
- Who it's for (target audience)
- What makes it different (unique value)
- What problems it solves

### Step 2: Ask the User Clarifying Questions

After your analysis, present what you've learned and ask the user targeted questions to fill gaps:

- "Based on the code, this appears to be [X]. Is that right?"
- "Who is your target audience? (age, interests, skill level)"
- "What niche does this app serve?"
- "What's the #1 reason someone downloads this app?"
- "Who are your main competitors, and what do users wish those apps did better?"
- "What do your best reviews say? What do users love most?"

Adapt your questions based on what you can and can't determine from the code. Don't ask questions the code already answers.

**Hold onto the niche/segment and any competitor names mentioned here** — the next phase (Competitive Research) reuses them instead of asking again.

### Step 3: Draft the Core Benefits

Based on your analysis and the user's input, draft 3-5 core benefits. Each benefit MUST:

1. **Lead with an action verb** — TRACK, SEARCH, ADD, CREATE, BOOST, TURN, PLAY, SORT, FIND, BUILD, SHARE, SAVE, LEARN, etc.
2. **Focus on what the USER gets**, not what the app does technically
3. **Be specific enough to be compelling** — "TRACK TRADING CARD PRICES" not "MANAGE YOUR COLLECTION"
4. **Answer the user's unspoken question**: "Why should I download this instead of scrolling past?"

Present the benefits to the user in this format:

```
Here are the core benefits I'd recommend for your screenshots:

1. [ACTION VERB] + [BENEFIT] — [why this drives downloads]
2. [ACTION VERB] + [BENEFIT] — [why this drives downloads]
3. [ACTION VERB] + [BENEFIT] — [why this drives downloads]
...
```

### Step 4: Collaborate and Refine

DO NOT proceed until the user explicitly confirms the benefits. This is an iterative process:

- Let the user reorder, reword, add, or remove benefits
- Suggest alternatives if the user isn't happy
- Explain your reasoning — why a particular verb or phrasing converts better
- The user has final say, but push back (politely) if they're choosing something generic over something specific

### Step 5: Save to Memory

Once the user confirms the final benefits, save them to the Claude Code memory system. Create or update a memory file (e.g., `aso_benefits.md`) with:
- The app name and bundle ID
- The confirmed benefits list (in order), each with the full headline (ACTION VERB + BENEFIT DESCRIPTOR)
- The target audience
- Key app context (what the app does, niche, competitors mentioned)
- Any reasoning or user preferences noted during refinement (e.g., "user prefers 'TRACK' over 'MONITOR'")

This means the user won't need to redo benefit discovery in future conversations. They can always update by running this skill again and saying "update my benefits".

---

## COMPETITIVE RESEARCH (New)

Before touching screenshots, look at what the app is actually competing against on the App Store. This turns "who are your competitors" from a one-line answer in Benefit Discovery into real visual evidence — used for comparison, inspiration, and an informed style recommendation later in Generation. It also stops the final screenshots from accidentally looking like everyone else's by default.

**Only run this phase if no competitive research exists in memory, or if the user asks to redo/update it.** If the user explicitly wants to skip it ("skip competitor research"), honor that and go straight to Screenshot Pairing — note in memory that it was skipped, so it isn't silently re-asked next time.

### Step 1: Confirm segment and competitors

Reuse the niche and any competitor names already gathered in Benefit Discovery — don't re-ask what's already known. **If Benefit Discovery's Step 2 already captured both a clear niche/segment AND 2+ named competitors, skip this step's questions entirely** and go straight to Step 2's resolution — re-asking a question already answered a few messages ago, even framed as confirmation, is exactly the redundant-round-trip this phase should avoid. Only fill genuine gaps:

- "What's the closest one-line description of your app's category/segment?" (e.g., "trading card price tracker", "intermittent fasting timer")
- "Which 2–5 apps are your closest real competitors?" — a name is enough; an App Store URL or numeric App Store ID is even better (removes ambiguity in the lookup).

If the user genuinely doesn't know of any, offer to suggest candidates by searching the App Store for the segment term (Step 2's mechanism, run once on the segment itself) — but say plainly that user-named real competitors produce a much more useful comparison than a generic category search.

### Step 2: Resolve and pull each competitor's live listing

Use Apple's **iTunes Search API** — public, free, no API key or account needed. Rate limit is informal (~20 requests/minute); for 2–5 competitors this is never a concern, but space out calls with a short pause if the list is long.

- **Given a name**: `curl -s "https://itunes.apple.com/search?term=<url-encoded name>&country=us&entity=software&limit=5"` and pick the best match by `trackName`. If more than one plausible result comes back, show the candidates to the user and ask which one they meant rather than guessing.
- **Given an App Store URL or ID**: extract the numeric id (the `id\d+` segment in a URL like `apps.apple.com/us/app/name/id123456789`) and call `curl -s "https://itunes.apple.com/lookup?id=<id>&country=us"`.

From the JSON response, keep: `trackName`, `screenshotUrls` (and `ipadScreenshotUrls` if the app has an iPad version), `description`, `averageUserRating`, `userRatingCount`, `genres`, `artworkUrl512`.

If a lookup fails (typo, unlisted app, no match) — say so plainly and move on with the competitors that did resolve. Don't block the whole phase on one bad lookup.

### Step 3: Download and actually look at the screenshots

Default to the **first 4 screenshots per competitor**. The iTunes Search API returns `screenshotUrls` already in App Store display order, so the first 4 are what a shopper actually sees first — and 4 is enough to read the pattern (dominant layout, headline treatment, whether there's a consistent visual thread across the set) without burning tokens reading a full 10-shot set for every competitor. If the user asks to see a specific competitor's full set ("show me all of their screenshots"), download and read all of them for that one competitor.

```bash
mkdir -p competitors/<competitor-slug>
curl -s "<screenshotUrl-1>" -o competitors/<competitor-slug>/01.jpg
curl -s "<screenshotUrl-2>" -o competitors/<competitor-slug>/02.jpg
curl -s "<screenshotUrl-3>" -o competitors/<competitor-slug>/03.jpg
curl -s "<screenshotUrl-4>" -o competitors/<competitor-slug>/04.jpg
# Only download beyond 4 if the user asked to see a competitor's full set.
```

Use the Read tool to view every downloaded screenshot — 4 per competitor by default. Study each set as a whole (how the images work together when swiped through), not just individually.

If the competitor's iTunes lookup returned `ipadScreenshotUrls` (meaning the app has an iPad version), download and look at those too — same "first 4" default as the iPhone set. This matters for the style/device decision later: if competitors' iPad screenshots reuse the same layout/text treatment as their iPhone set (just re-cropped) versus a genuinely iPad-adapted layout, that's a signal worth carrying into Generation, where `compose.py --device ipad` can now produce a properly iPad-proportioned scaffold instead of skipping iPad entirely.

### Step 4: Write the comparative analysis

Cover, briefly:

- **The dominant visual pattern**, if there is one — e.g., "4 of 5 competitors use centered ALL-CAPS headline text over a solid saturated colour, iPhone dead-center." Name it plainly if everyone does the same thing; that sameness is exactly the signal that matters for the style choice later.
- **Any outlier** doing something different (lifestyle photography, minimal/no text, illustration) — and whether it looks like it's working (check its rating count as a rough proxy for traction).
- **Polish level** — do these look agency-designed and consistent, or scrappy/inconsistent? This cuts the other way from the point above: a category full of amateur listings is an opening for Bold/Agency polish, not necessarily for going quieter.
- **A genuine gap**, if one exists — something no competitor's screenshots communicate that this app credibly can. Not "be different for its own sake" — a real, defensible angle.

### Step 5: Recommend a style (feeds into Generation)

State a clear recommendation — **Bold/Agency** or **Editorial/Organic** — grounded in Steps 3–4, e.g.:

> "4 of your 5 competitors use the same bold-centered-headline-on-solid-colour look. Going Editorial/Organic would visually separate your listing from theirs in the search results grid, where all of you currently look interchangeable."

or

> "Your competitors' screenshots look inconsistent and DIY. Bold/Agency polish would read as more premium and trustworthy by direct comparison."

This is a recommendation, not a decision — the user confirms the actual style in Generation's Style Selection step, where this reasoning is shown again alongside both options.

### Step 6: The hard rule

**Never copy, trace, closely mimic, or directly reuse a competitor's screenshot layout, wording, or imagery** in anything generated later. This research is for comparison, inspiration, and gap-finding only — both because Apple's terms for this API license the content to promote what it depicts (not to be repurposed into someone else's marketing), and because a copied layout is a bad look even before that. Downloaded competitor screenshots stay in `competitors/` for reference and are never composited into the app's own output.

### Step 7: Save to Memory

Create or update `aso_competitive_research.md` with:

- Segment/niche (one line)
- Each competitor: name, resolved App Store ID, rating + rating count, local screenshot paths
- The written analysis (Step 4)
- The style recommendation and its reasoning (Step 5)

This means Generation's Style Selection step can present the recommendation without re-fetching anything.

### Step 8: Checkpoint — stop here or continue

This is a natural stopping point, not just a step to rush past. Tell the user plainly what they now have:

> Competitor research is done — `competitors/<slug>/` has each competitor's real screenshots, and the analysis + style recommendation are saved. That's useful on its own even if you're not ready to generate your own screenshots yet.
>
> Next up is Screenshot Pairing + Generation, which creates your own App Store-ready screenshots — **Generation needs a Gemini API key**, which is a real setup step, not a one-line add: you'll need a Google AI Studio account, a Gemini MCP server configured in Claude Code (Desktop and/or CLI, depending how you run Claude), and the key wired into that config — the skill's README walks through it. Want to continue now, or stop here and pick this back up later?

Then wait for the user's answer rather than assuming they want to continue. If they entered via the "competitor research only" path (see the top of this file), lean toward stopping unless they explicitly say to continue. If they entered via the full pipeline and don't answer either way, it's fine to default to continuing — but the Gemini requirement must have been stated here, not discovered for the first time deep inside Generation's own prerequisites check.

---

## SCREENSHOT PAIRING

Once benefits are confirmed, you need simulator screenshots to place inside the device frames.

### Step 1: Collect Simulator Screenshots

Ask the user to provide their simulator screenshots. They can provide:
- A directory path containing the screenshots (e.g., `./simulator-screenshots/`)
- Individual file paths
- Glob patterns (e.g., `~/Desktop/Simulator*.png`)

Use the Read tool to view every simulator screenshot provided. Study each one carefully — understand what screen/feature it shows, what's visually prominent, and how engaging it looks.

### Step 2: Assess Each Screenshot

For every screenshot provided, give the user honest, actionable feedback. Rate each screenshot as **Great**, **Usable**, or **Retake**. For each one, explain:

- **What it shows**: Which screen/feature is this?
- **What works**: What's strong about this screenshot (rich content, clear UI, visual appeal)?
- **What doesn't work**: Be direct about problems — is it an empty state? Is the content sparse or generic? Is key information cut off? Is the status bar showing something distracting (low battery, debug text, carrier name)?
- **Verdict**: Great / Usable / Retake

**Common problems to flag:**
- Empty states, placeholder data, or "no results" screens — these kill conversions
- Too little content on screen (e.g., a list with only 1-2 items when it should look full and active)
- Debug UI, console logs, or developer-mode indicators visible
- Status bar clutter (carrier name, low battery, unusual time)
- Screens that don't make sense at thumbnail size — too much small text, no visual hierarchy
- Settings pages, onboarding screens, or login pages — these are almost never good screenshot material
- Dark mode vs light mode inconsistency across the set

### Step 3: Coach on Retakes

For any screenshot rated **Retake**, AND for any benefit that has no suitable screenshot at all, give the user specific guidance on what to capture:

- Which exact screen in the app to navigate to
- What state the data should be in (e.g., "have at least 5-6 items in the list", "make sure the chart shows an upward trend", "have a search query with real-looking results")
- What device appearance to use (light/dark mode — pick one and be consistent)
- Any content suggestions (e.g., "use realistic names and prices, not 'Test Item 1'")
- Remind them to use clean status bar settings (Simulator → Features → Status Bar → override to show full signal, full battery, and a clean time like 9:41)

Be opinionated. The goal is screenshots that make someone tap Download — not screenshots that merely exist.

### Step 4: Pair Screenshots with Benefits

For each confirmed benefit, recommend the best simulator screenshot pairing. Only pair screenshots rated **Great** or **Usable**. Consider:

- **Relevance**: Does this screenshot directly demonstrate the benefit? A "TRACK PRICES" benefit needs a screen showing prices, not settings.
- **Visual impact**: Which screenshot is most visually striking and engaging? Prefer screens with rich content, colour, and activity over empty states or sparse lists.
- **Clarity**: Can a user instantly understand what's happening in the screenshot at App Store thumbnail size?
- **Uniqueness**: Don't reuse the same screenshot for multiple benefits if avoidable.

Present the pairings to the user:

```
Here's how I'd pair your screenshots with each benefit:

1. [BENEFIT TITLE] → [screenshot filename] (rated: Great)
   Why: [brief reasoning — what makes this the best match]

2. [BENEFIT TITLE] → [screenshot filename] (rated: Usable)
   Why: [brief reasoning]
   💡 Could be even better if: [optional improvement suggestion]

...
```

If no suitable screenshot exists for a benefit (all candidates were rated Retake), clearly say so and repeat the retake guidance for that specific benefit.

### Step 5: Confirm Pairings

Let the user review and swap pairings before proceeding. Do NOT move to generation until pairings are confirmed. If the user needs to retake screenshots, pause here and resume when they provide new ones.

### Step 6: Save to Memory

Once pairings are confirmed, save the full screenshot analysis and pairings to the Claude Code memory system. Create or update a memory file (e.g., `aso_screenshot_pairings.md`) with:

- **Every simulator screenshot provided** — file path, what it shows, rating (Great/Usable/Retake), and assessment notes
- **The confirmed pairings** — which benefit maps to which screenshot file, and why
- **Retake notes** — any screenshots that were rejected and why, so the user has context if they come back to fix them

This is critical for resumability. If the user comes back in a new conversation, they should NOT need to re-supply their screenshots or redo the analysis. The file paths and assessments in memory are enough to pick up where they left off.

---

## GENERATION

Once benefits and screenshot pairings are confirmed, generate the final App Store screenshots using Nano Banana Pro (via the Gemini MCP server).

### Prerequisites Check

Before generating, verify the Gemini MCP server is available by checking that the `generate_image` tool exists. If it is NOT available, tell the user:

```
⚠️ Gemini MCP server not detected. To generate screenshots, you need to set it up:

1. Install: npm install -g gemini-mcp
2. Add to your Claude Code MCP config (~/.claude/settings.json or project .mcp.json)
3. Restart Claude Code
4. Run this skill again

See: https://github.com/nicobailon/gemini-mcp for setup instructions.
```

Do NOT proceed with generation if the tool is unavailable.

### Step 0: Style Selection

Ask the user to choose a style track before anything else. If Competitive Research produced a recommendation, show it here alongside the options — that's the point at which it gets used, not just filed away:

```
Two visual directions for your screenshots:

BOLD / AGENCY — the original high-impact template: centered ALL-CAPS
headline, solid saturated brand colour, device front-and-centre. Reads as
polished and energetic — unmistakably a marketing screenshot. A safe,
proven choice, especially in categories where that look is already the norm
and doesn't hurt you (productivity, finance, utilities).

EDITORIAL / ORGANIC — quieter: left-aligned sentence-case headline,
generous negative space, a soft or photographic duotone background, device
smaller and off-centre, no floating glossy UI panels. Reads as
designed-by-a-person rather than generated-by-a-template. Worth choosing
when your category already looks like Bold/Agency everywhere (differentiate
by not matching it) or when the app's positioning is warmer/lifestyle/human.

[If competitive research ran: "Based on your competitors: <recommendation
and one-line reasoning from Competitive Research Step 5>."]

Which do you want?
```

Do NOT default to one silently — wait for the user's explicit choice, the same way Benefit Discovery waits for explicit confirmation. The chosen style applies to the whole set; it is not chosen per-screenshot.

**Show a visual preview before asking, not just adjectives.** `compose.py`'s scaffold stage is deterministic, local, and free — no Nano Banana call, no cost (see "Generation Process" below). Before presenting the choice above, run the scaffold once for `--style bold` and once for `--style organic` using the first confirmed benefit's headline and paired screenshot (a real brand-colour hex if already known, or a reasonable placeholder if not — this is a throwaway preview, not the real scaffold that gets enhanced later), and show both PNGs to the user with the Read tool alongside the text description. A non-designer choosing between two adjective-only paragraphs is choosing close to blind; two real side-by-side images turns it into an actual decision. This preview step is cheap enough to always do — don't skip it to save a Bash call.

If **Editorial/Organic** is chosen, ask one follow-up: *"Do you have a background photo or texture you'd like used (a workspace shot, a relevant lifestyle photo, a material texture), or should I generate one?"*

- If the user provides one, use it as-is (resize/orientation handled automatically by `compose.py`).
- If not, generate one with `generate_image`, using a prompt that stays firmly on the "real photograph" side — concrete, specific, unglamorous:

  ```
  A natural photograph relevant to [app's domain/context — e.g. "a home
  kitchen counter", "a running trail at golden hour", "a minimal wooden
  desk"]. Shot as a real photo, not an illustration: soft directional light
  from one side, natural shadow, believable texture and imperfection, a
  slightly off-centre composition. No text, no logos, no people's faces, no
  product in frame — this is a background only. Avoid: perfect symmetry,
  glossy/plastic surfaces, oversaturated colour, glow or lens flare,
  anything that reads as a 3D render or a stock-photo cliché.
  ```

  Save the result locally (e.g., `background.jpg`) — this becomes the `--bg-image` passed to `compose.py` for every screenshot in the set, so the whole set shares one consistent backdrop.

### App Store Connect Dimensions

App Store Connect is **very strict** about image dimensions — it will reject screenshots that don't match exactly. The only accepted portrait sizes are:

| Display | Portrait | Landscape |
|---------|----------|-----------|
| iPhone 6.5" | 1242 x 2688px | 2688 x 1242px |
| iPhone 6.7" | 1290 x 2796px | 2796 x 1290px |
| iPhone 6.9" | 1320 x 2868px | 2868 x 1320px |
| iPad 13" | 2048 x 2732px | 2732 x 2048px |

2064 x 2752px (portrait) / 2752 x 2064px (landscape) is also accepted for the 13" iPad bucket (the native M4 13" iPad Pro resolution) — either works. The 11" iPad size is optional: Apple auto-scales the 13" set down for smaller iPads, so only one iPad set is needed if the app supports iPad at all.

Default to **1290 x 2796px** (iPhone 6.7") unless the user specifies otherwise. Ask the user which size(s) they need — including whether the app supports iPad and needs the iPad set too. Up to 10 screenshots can be uploaded per display size.

**iPad screenshots use the same two-stage pipeline**, via `compose.py --device ipad` (default is `--device iphone`, so nothing changes for apps that don't need iPad). Generate the iPad set as an additional pass after the iPhone set is approved — same benefits, same headlines, same style, just re-composed at iPad proportions with the iPad-specific device-frame assets. Don't attempt to stretch or reuse an iPhone-composed image for the iPad slot; the aspect ratios are different enough that it would look wrong.

**IMPORTANT — Aspect ratio mismatch**: Apple's required dimensions are narrower than standard 9:16 (~0.461 ratio vs 0.5625). Nano Banana generates at preset aspect ratios, so we generate **wider than needed** at 9:16 with 4K resolution, then **crop and resize** down to exact Apple dimensions in a post-processing step (see Step 4 below). This approach avoids stretching — we remove excess width instead.

This dimension handling is identical for both styles.

### Screenshot Format Specification

Both styles share the same hard constraints (dimensions above, consistency across the set, no watermarks/extra text/App Store chrome). Everything else branches by the style chosen in Step 0.

#### Bold / Agency spec

**Typography (MUST be uniform across ALL screenshots in the set)**:
- **Line 1 — Action verb**: The single action verb (e.g., "TRACK", "SEARCH", "BOOST"). This is the BIGGEST, boldest text on the screenshot. Uppercase, center-aligned. Same font, same size, same weight on every screenshot. **Ink colour is contrast-driven, not always white**: `compose.py` computes the background's luminance and picks white text on a dark/saturated brand colour (the normal case) or dark ink on a pale/light one — so a lighter brand colour pick never silently produces unreadable white-on-white. This mirrors how Organic already picks its ink colour; Bold's flat, known background colour makes it a direct luma calculation rather than pixel sampling.
- **Line 2 — Benefit descriptor**: The rest of the headline (e.g., "TRADING CARD PRICES", "ANY VERSE IN SECONDS"). Noticeably smaller than line 1, but still bold, uppercase, center-aligned, same contrast-driven ink colour as line 1. Same font, same size, same weight on every screenshot.
- **Font**: Heavy/black weight sans-serif (e.g., SF Pro Display Black, Inter Black, or similar high-impact font). Not just bold — heavy/black weight for maximum impact.
- **Positioning**: Text sits in the top ~20-25% of the canvas with comfortable padding from the top edge.
- **Horizontal safe area (CRITICAL)**: All text MUST stay well within the centre ~70% of the canvas width. Leave generous horizontal margins on both sides — at least 15% padding from each edge. This is essential because the post-processing step crops the sides of the image to convert from 9:16 to Apple's narrower aspect ratio. Any text near the left or right edges WILL be cut off. Keep headlines short enough to fit comfortably within this safe zone. If a headline is too long, break it across more lines rather than extending to the edges.

**Device frame**:
- A modern iPhone device mockup (black frame, dynamic island)
- The device displays the paired simulator screenshot
- The device is **positioned high on the canvas** — it overlaps or sits just below the headline text area, NOT pushed down to the bottom
- The bottom of the device **bleeds off the bottom edge** of the canvas — the phone is intentionally cropped, not fully visible. This creates a dynamic, modern feel.
- The device is centered horizontally

**Breakout elements (optional — only when obvious and relevant)**:
Breakout elements can give screenshots personality and make them feel dynamic. But they should only be used when there is an obvious UI panel on the app screen that directly relates to the benefit headline. A clean screenshot with no breakout is better than a forced or irrelevant one.

- **Primary — Feature zoom-out (only when relevant)**: If there is an obvious, visually compelling entire UI panel or grouped section on the app screen that directly reinforces the benefit headline, make it "pop out" from the device frame. The panel must stay at the same vertical position and orientation as where it appears on the app screen — NOT rotated or angled. It should extend dramatically beyond BOTH left and right edges of the device frame, clearly overlapping the phone bezel on both sides, expanding to nearly the full width of the screenshot canvas. The panel must be SCALED UP significantly — much larger than it appears on the phone screen — so that it extends well beyond both left and right edges of the device frame. It should look like it is floating in front of the phone at a larger scale, bursting out of the phone's boundaries. Add a soft drop shadow beneath the breakout panel to create depth and make it feel like it's hovering above the device. The enlarged size plus the overlap with the device frame edges plus the shadow is what creates the dramatic pop-out effect. The panel must be a complete card/section (not an individual button, icon, or small element). If no panel clearly relates to the headline, skip the breakout entirely.
- **Secondary — Supporting elements (OPTIONAL, use restraint)**: You may add 1-2 small supporting elements (contextual icons, subtle directional cues, small floating UI elements) ONLY if they are directly relevant to the benefit and enhance the story. These must NOT compete with the primary zoom-out element for attention. Less is more — a clean composition with one strong breakout element is better than a cluttered one with many. Every element added must earn its place by helping tell the story of that screen.

**What to avoid**: Don't add decorative elements just because you can. No random icons, no excessive particles/sparkles, no elements unrelated to the benefit. The screenshot should feel polished and intentional, not busy.

**Background (MUST be consistent across ALL screenshots in the set)**:
- Solid bold brand colour fills the entire canvas — same colour on every screenshot
- The background must be a clean, solid brand colour. Do NOT add glows, gradients, radial patterns, or light effects.
- If accent shapes are used, use the same style of accent on every screenshot so the set looks like a cohesive series when viewed side-by-side

#### Editorial / Organic spec (new)

This track exists specifically to avoid the visual signature that now reads as "obviously AI-generated marketing template" — centered shouty type, flat saturated colour, floating glossy panel with a dramatic drop shadow. Every rule below is there to break one of those signals.

**Typography (MUST be uniform across ALL screenshots in the set)**:
- **Sentence case, not ALL-CAPS** — "Track trading card prices", never "TRACK TRADING CARD PRICES". Shouting is exactly the bold-template tell.
- **Medium/semibold weight, not black/heavy** — a lighter touch reads as considered, not aggressive. `compose.py --style organic` already selects a lighter weight automatically (see below).
- **Left-aligned, not centered** — positioned upper-left with generous margin on all sides. Negative space is a deliberate part of the composition, not empty space to fill.
- **Noticeably smaller** than the Bold/Agency scale — this is a quieter register throughout, not just the wording.

**Device frame**:
- Smaller scale than Bold/Agency, shifted off-centre (toward the right third of the canvas)
- **Fully contained within the canvas** — a visible margin below the device, no bleed off the bottom edge. Bleeding off the edge is a "hero shot" move that belongs to the Bold track.
- **Tilted at a small, fixed angle** — `compose.py --style organic` already rotates the device deterministically (default -4°, same angle on every screenshot in the set unless `--device-angle` overrides it) before the scaffold ever reaches Nano Banana. The enhance pass's job is to KEEP that exact tilt, not invent its own — see the enhance prompt below. A dead-level, perfectly perpendicular device is itself part of the "AI template" tell; a consistent small tilt reads as an actually-photographed object.

**Breakout elements**: avoid by default. The floating panel with a dramatic drop shadow is one of the clearest "AI SaaS template" signals in App Store screenshots right now — this track does not use it. If a UI detail genuinely needs to be called out, do it small and quiet (a subtle label near the device, not a large panel bursting out of the frame).

**Background (MUST be consistent across ALL screenshots in the set)**:
- Either a **duotone-tinted photographic backdrop** (from Step 0's background photo, tinted toward the brand colour by `compose.py`) or, if no photo is used, a **soft, muted tint** of the brand colour — never the raw saturated hex. Flat saturated colour is the single biggest tell this track exists to avoid.
- Very subtle texture/grain is welcome; anything that reads as a flat digital gradient is not.

**Lighting and material (governs the Nano Banana enhance pass, not `compose.py`)**:
- **One clear, directional light source** (e.g. "soft light from the upper left") casting one soft, realistic shadow — never flat, shadowless studio lighting.
- Real material response on the device: soft ambient occlusion where it meets its surroundings, a believable (not glossy/showroom) reflection.
- Slight compositional asymmetry — a considered photograph, not a centered card.
- **Words and effects to avoid entirely**: "perfect", "flawless", "masterpiece", "8k", "trending on artstation", glow, radial gradient, glassy/neon highlights, unnaturally smooth surfaces. These push the model toward exactly the over-polished look this track exists to escape.

### Generation Process — Two-Stage: Scaffold then Enhance

Generation uses a two-stage approach for consistency, for **either** style:
1. **Stage 1 (Scaffold)**: `compose.py` creates a deterministic local image with the correct text, device frame, and screenshot — parameterised by `--style bold` or `--style organic`. This guarantees consistent layout across all screenshots.
2. **Stage 2 (Enhance)**: The scaffold is sent to Nano Banana Pro to add photorealism and (style-dependent) polish, using the enhance prompt template that matches the chosen style.

**The first approved screenshot becomes the style template for the entire set.** All subsequent screenshots are enhanced using both their own scaffold (for layout) AND the first approved screenshot (for style). This ensures every screenshot in the set has the same device frame rendering, text treatment, background style, and overall visual quality — so when viewed side-by-side in the App Store, they look like a cohesive professional set.

For each benefit + screenshot pair, generate multiple enhanced versions in parallel so the user can pick the best one: **3 versions for the first (style-defining) benefit** — extra options matter most here, since this is the version that becomes the style template for the entire set — and **2 versions for every subsequent benefit**, since the style is already locked in by then. This is a floor, not a hard cap: if the user isn't happy with either version of a subsequent benefit, generate one more rather than forcing a pick between two options they don't like.

**Step 0: Save style + brand colour to memory**

Before generating any scaffolds, save the confirmed style (`bold` or `organic`), brand colour, and — if organic — the background photo path to the Claude Code memory system (`aso_benefits.md` or a dedicated `aso_style.md`). This ensures they persist across conversations and are available immediately if the user resumes later.

**Step 1: Create the scaffold with compose.py**

The compose.py script lives in the skill directory. Run it to create the deterministic base screenshot.

**IMPORTANT — Batch all 3 scaffolds into a single Bash call** to minimize permission prompts. Chain the commands with `&&` so the user only needs to approve once:

```bash
SKILL_DIR="$HOME/.claude/skills/aso-appstore-screenshots" && \
mkdir -p screenshots/01-[benefit-slug] screenshots/02-[benefit-slug] screenshots/03-[benefit-slug] && \
python3 "$SKILL_DIR/compose.py" \
  --style [bold|organic] --bg "[HEX CODE]" --verb "[VERB 1]" --desc "[DESC 1]" \
  --screenshot [path/to/screenshot-1.png] \
  [--bg-image background.jpg   # organic only, if a background photo was chosen/generated] \
  --output screenshots/01-[benefit-slug]/scaffold.png && \
python3 "$SKILL_DIR/compose.py" \
  --style [bold|organic] --bg "[HEX CODE]" --verb "[VERB 2]" --desc "[DESC 2]" \
  --screenshot [path/to/screenshot-2.png] \
  [--bg-image background.jpg] \
  --output screenshots/02-[benefit-slug]/scaffold.png && \
python3 "$SKILL_DIR/compose.py" \
  --style [bold|organic] --bg "[HEX CODE]" --verb "[VERB 3]" --desc "[DESC 3]" \
  --screenshot [path/to/screenshot-3.png] \
  [--bg-image background.jpg] \
  --output screenshots/03-[benefit-slug]/scaffold.png
```

Omit `--style` entirely (or pass `--style bold`) to get the original template exactly as before — `--style bold` is byte-for-byte the same layout logic that shipped before this flag existed. `--style organic` requires no other change to call it; `--bg-image` is optional even for organic (falls back to a soft tint of `--bg`).

This outputs pixel-perfect 1290×2796 PNGs with headline text, iPhone device frame, and the simulator screenshot composited inside, laid out per the active style.

The scaffolds are internal intermediates — do NOT show them to the user or ask for confirmation. Proceed immediately to Step 2 (Nano Banana enhancement).

**Step 2: Enhance with Nano Banana Pro (3 versions for the first benefit, 2 for the rest)**

Make **3 parallel `edit_image` calls** for the first benefit, or **2 parallel `edit_image` calls** for every subsequent benefit (3 again if the user asks for an extra option per Step 4's escape hatch). The parallel execution is critical — always fire all calls for a given benefit in a single message, never sequentially.

For each call, use:
- `prompt`: Enhancement instructions — the Bold or Organic template below, matching the active style (see prompt templates below — different for first vs subsequent screenshots, and different per style)
- `images`: See below for which images to include
- `outputPath`: A different path per version — `v1.jpg` and `v2.jpg` always, `v3.jpg` for the first benefit (or if a subsequent benefit got a 3rd version on request):
  - `./screenshots/01-[benefit-slug]/v1.jpg`
  - `./screenshots/01-[benefit-slug]/v2.jpg`
  - `./screenshots/01-[benefit-slug]/v3.jpg` (first benefit only, by default)

#### First screenshot (no approved template yet)

Always generates all 3 versions (see Step 2). Use only the scaffold as input:
- `images`: The scaffold via `filePath` pointing to `screenshots/01-[benefit-slug]/scaffold.png`

**Bold — first screenshot prompt template:**

```
This is a SCAFFOLD for an App Store screenshot — a rough layout showing the correct text, device frame position, and app screenshot placement. Your job is to transform this into a polished, professional App Store marketing screenshot that would make someone tap Download.

KEEP EXACTLY AS-IS:
- The headline text (wording, position, and approximate size)
- The app screenshot shown on the phone screen
- The background colour

ENHANCE AND POLISH:
- Replace the placeholder device frame with a photorealistic iPhone 15 Pro mockup — sleek, modern, with accurate proportions, reflections, and subtle shadows. The phone should look like a real device, not a flat rectangle. Keep the same position and size as the scaffold.
- Refine the overall visual quality to look like a professional, high-budget App Store screenshot
- OPTIONALLY add a PRIMARY breakout element — but ONLY if there is an obvious, visually compelling UI panel on the app screen that directly relates to the benefit headline. If nothing on screen clearly reinforces the headline, skip the breakout entirely — a clean screenshot with no breakout is better than a forced one. When you DO add a breakout, it MUST be an entire UI panel or grouped section (e.g., a complete card with its title and content, a full list section, a complete dialog/sheet) — never individual small elements like a single button, icon, or colour dot. IMPORTANT: The panel must stay at the SAME vertical position and orientation as where it appears on screen — do NOT rotate or angle it. The panel must be SCALED UP significantly — rendered much larger than it appears on the phone screen — so that it extends dramatically beyond BOTH left and right edges of the device frame, clearly overlapping the phone bezel on both sides, expanding to nearly the full width of the screenshot canvas. Do NOT keep the panel at its original on-screen size with just padding added around it. The panel itself must be enlarged. It should appear to float in front of the device at this larger scale — add a soft drop shadow beneath it to create depth and sell the hovering effect. The panel must look like it came from the app — same colours, same style, same content. Do NOT invent new elements.
[PRIMARY BREAKOUT — if a relevant panel is obvious, describe the specific UI panel visible on screen and instruct it to extend beyond both edges of the device frame with a drop shadow, e.g., "The [panel name] card/row extends beyond both left and right edges of the device frame, overlapping the phone bezel on both sides, expanding to nearly the full screenshot width. It floats in front of the device with a soft drop shadow beneath it." If no panel clearly relates to the headline, write "No breakout — the app screen speaks for itself."]
- Optionally add 1-2 secondary elements that reinforce the benefit and message of the screenshot — the kind of enhancements a professional graphic designer would add for impact. These are NOT from the app UI; they are creative additions that help clearly communicate what the screenshot is trying to portray to the user browsing the App Store. They should carry the message and support ASO conversion, but never at the cost of the overall design aesthetic. They must not compete with the primary breakout for attention.
[SECONDARY ELEMENTS (optional) — describe 0-2 small supporting elements that tell the story, or "None needed"]
- The background should be a clean, solid brand colour. Do NOT add glows, gradients, radial patterns, or light effects to the background. Keep it flat and bold.
- Ensure the text is crisp, bold, and highly readable

The final result should look like it was designed by a professional App Store screenshot agency — polished, high-converting, and visually striking. No watermarks, no extra text, no app store UI chrome.
```

**Organic — first screenshot prompt template:**

```
This is a SCAFFOLD for an App Store screenshot — a rough layout showing the correct text, device frame position, screenshot placement, and background tone. Your job is to turn this into a screenshot that looks like it was shot and art-directed by a person, not generated from a template — something a small independent studio would publish, not a SaaS landing page.

KEEP EXACTLY AS-IS:
- The headline text (wording, position, approximate size, sentence case — do NOT convert to all-caps)
- The app screenshot shown on the phone screen
- The overall background tone/colour palette
- The device's position, scale, AND tilt/rotation angle (smaller, off-centre, fully visible, tilted — do not enlarge it, do not move it back to dead-centre, do not straighten it)

ENHANCE AND POLISH:
- Replace the placeholder device frame with a photorealistic iPhone mockup, but **KEEP the exact tilt/angle already baked into the scaffold — do not straighten it, do not reinterpret the angle, do not invent your own.** The scaffold's rotation is deliberate and must survive into every screenshot in the set identically; treat it the same as the headline text or device position — locked, not a suggestion. Add real material response at that same angle: soft ambient occlusion where the phone meets its surroundings, a believable (not showroom-glossy) reflection.
- Light the whole scene with ONE clear, directional light source (e.g. soft light from the upper left) that casts a single soft, realistic shadow — not flat, shadowless studio lighting.
- If a background photo is present, keep its content but make the light on the device match it convincingly. If the background is a flat/duotone tint, add very subtle texture — a faint grain, a barely-visible material quality — so it doesn't read as a perfectly flat digital fill.
- Composition should feel slightly asymmetric and unforced, like a considered photograph, not a centered marketing card.
- Do NOT add a floating UI panel with a dramatic drop shadow "bursting out" of the device — that specific move is one of the clearest signals that an App Store screenshot was AI-generated from a template in 2026. If a UI detail from the app genuinely needs calling out, do it small and quiet (a subtle label, a barely-there accent) — never a large glossy panel.
- Avoid anything associated with generic AI polish: no unnaturally smooth surfaces, no glow, no radial gradients, no exaggerated symmetry, no glassy/neon highlights. Do not aim for "perfect" — aim for real.
- Keep the headline text crisp and easily readable against the background — this is the one place precision matters more than texture.

The final result should look like a real photograph of a real phone that a human art-directed — natural, a little imperfect, warm. No watermarks, no extra text, no app store UI chrome.
```

#### Subsequent screenshots (after first is approved)

Generates 2 versions by default (see Step 2), with a 3rd on request if neither satisfies. Use **two images** as input:
1. The **scaffold** for this benefit (`screenshots/0N-[benefit-slug]/scaffold.png`) — defines the layout
2. The **first approved screenshot** (`screenshots/final/01-[first-benefit-slug].jpg`) — defines the style template

**Bold — subsequent screenshot prompt template:**

```
You are creating the next screenshot in an App Store screenshot SET. It must look like it belongs to the same series as the style reference.

TWO REFERENCE IMAGES:
- FIRST image: The SCAFFOLD — use this as the definitive guide for layout: headline text wording/position, device frame placement, and the app screenshot on screen. This defines WHAT this screenshot shows.
- SECOND image: The STYLE TEMPLATE — this is an already-approved screenshot from the same set. Match its visual style EXACTLY: same device frame rendering (this is critical — the phone must look identical), same text treatment, same background style/accents, same level of polish, same overall aesthetic. This defines HOW this screenshot should look. When in doubt, copy the style template more closely rather than less.

REQUIREMENTS:
- CRITICAL: The device frame MUST match the style template EXACTLY — same photorealistic iPhone rendering, same size, same position, same shadows, same reflections, same edge treatment. Do NOT reinvent or reimagine the device frame. Reproduce it as closely as possible from the style template, only changing the screen contents.
- Match the style template's text rendering style (same font treatment, same crispness, same visual weight)
- Match the style template's background — clean, solid brand colour. No glows, gradients, radial patterns, or light effects.
- Use the scaffold's layout for positioning (text, device, screenshot placement)
- OPTIONALLY add a PRIMARY breakout element — but ONLY if there is an obvious, visually compelling UI panel on the app screen that directly relates to the benefit headline. If nothing clearly reinforces the headline, skip the breakout entirely. When used, it MUST be an entire UI panel or grouped section (NOT individual small elements like a single button or icon). The panel must stay at the SAME vertical position and orientation as on screen — do NOT rotate or angle it. The panel must be SCALED UP significantly — rendered much larger than it appears on the phone screen — so that it extends dramatically beyond BOTH left and right edges of the device frame, clearly overlapping the phone bezel on both sides, expanding to nearly the full width of the screenshot canvas. Do NOT keep the panel at its original on-screen size. The panel itself must be enlarged. It should appear to float in front of the device at this larger scale — add a soft drop shadow beneath it to create depth. The panel MUST come from the app screenshot — same colours, same style, same content. Do NOT invent new elements.
[PRIMARY BREAKOUT — if a relevant panel is obvious, describe the specific UI panel visible on screen to pop out with a drop shadow, extending beyond both device frame edges. Otherwise write "No breakout — the app screen speaks for itself."]
- Optionally add 1-2 secondary elements that reinforce the benefit and message of the screenshot — the kind of enhancements a professional graphic designer would add for impact. These are NOT from the app UI; they are creative additions that help clearly communicate what the screenshot is trying to portray to the user browsing the App Store. They should carry the message and support ASO conversion, but never at the cost of the overall design aesthetic. They must not compete with the primary breakout for attention.
[SECONDARY ELEMENTS (optional) — 0-2 small supporting elements that tell the story, or "None needed"]
- The breakout elements should match the style and energy level of those in the style template

The result must look like it was designed alongside the style template as part of the same professional set. When placed side-by-side in the App Store, they should be visually cohesive — same quality, same aesthetic, same design language, just different content.

No watermarks, no extra text, no app store UI chrome.
```

**Organic — subsequent screenshot prompt template:**

```
You are creating the next screenshot in an App Store screenshot SET. It must look like it belongs to the same series as the style reference — the same photographer, the same day, the same set.

TWO REFERENCE IMAGES:
- FIRST image: The SCAFFOLD — use this as the definitive guide for layout: headline text wording/position, device frame placement, and the app screenshot on screen. This defines WHAT this screenshot shows.
- SECOND image: The STYLE TEMPLATE — this is an already-approved screenshot from the same set. Match its device angle, its light direction and shadow, its background treatment (same duotone/tint family), its material quality, and its overall restraint. This defines HOW this screenshot should look. When in doubt, copy the style template more closely rather than less.

REQUIREMENTS:
- CRITICAL: The device frame's angle, size, position, lighting, and reflection style MUST match the style template — do not reinvent it per screenshot. Only the screen contents change.
- Match the style template's background family exactly (same duotone tint or same soft flat tint) — not a new background treatment.
- Match the style template's typography treatment: sentence case, medium weight, left-aligned, same relative size.
- Use the scaffold's layout for positioning (text, device, screenshot placement).
- Do NOT add a floating UI panel with a dramatic drop shadow — this style never uses that move, in any screenshot of the set, for consistency with the style template.
- Keep the same restrained, photographic quality as the style template: one directional light source, real material response, slight asymmetry, no unnaturally smooth surfaces or glossy/neon highlights, nothing that reads as "perfect."

The result must look like it came from the same shoot as the style template — same light, same materials, same restraint, just different content.

No watermarks, no extra text, no app store UI chrome.
```

**IMPORTANT — Consistency enforcement**: The scaffold guarantees consistent layout. The style template guarantees consistent visual treatment. If Nano Banana changes the text, layout, style, or deviates from the style template, regenerate.

**Step 3: IMMEDIATELY crop and resize ALL versions to App Store dimensions**

⚠️ **You MUST run this immediately after all `edit_image` calls for this benefit complete. Do NOT show the user any image before running this. The raw Nano Banana output is always the wrong dimensions for App Store Connect.**

**CRITICAL — Use exactly ONE Bash tool call for all crop/resize operations for this benefit.** Do NOT make separate Bash calls per version. Do NOT use parallel Bash calls. Use the single loop below (shown for the first benefit's 3 versions — for a subsequent benefit, list only `v1.jpg v2.jpg`, adding `v3.jpg` only if a 3rd version was generated) so the user only sees one permission prompt:

```bash
TARGET_W=1290 && TARGET_H=2796 && \
for INPUT in screenshots/01-[benefit-slug]/v1.jpg screenshots/01-[benefit-slug]/v2.jpg screenshots/01-[benefit-slug]/v3.jpg; do
  OUTPUT="${INPUT%.jpg}-resized.jpg"
  cp "$INPUT" "$OUTPUT"
  W=$(sips -g pixelWidth "$OUTPUT" | tail -1 | awk '{print $2}')
  H=$(sips -g pixelHeight "$OUTPUT" | tail -1 | awk '{print $2}')
  CROP_W=$(python3 -c "print(round($H * $TARGET_W / $TARGET_H))")
  OFFSET_X=$(python3 -c "print(round(($W - $CROP_W) / 2))")
  sips --cropOffset 0 $OFFSET_X --cropToHeightWidth $H $CROP_W "$OUTPUT"
  sips -z $TARGET_H $TARGET_W "$OUTPUT"
  echo "--- $OUTPUT ---"
  sips -g pixelWidth -g pixelHeight "$OUTPUT"
done
```

The script crops to the correct aspect ratio (top-center aligned — sides trimmed equally, top edge preserved so the headline stays put) and resizes to exact pixel dimensions. The resized image is saved as a separate file with `-resized.jpg` appended. This step is identical for both styles.

Target dimensions per display size — adjust `TARGET_W` and `TARGET_H`:
- iPhone 6.5": `TARGET_W=1242 TARGET_H=2688`
- iPhone 6.7" (default): `TARGET_W=1290 TARGET_H=2796`
- iPhone 6.9": `TARGET_W=1320 TARGET_H=2868`

**Step 4: Review the versions with the user**

Present all **resized** versions (the `-resized.jpg` files) to the user using the Read tool — 3 for the first benefit, 2 for subsequent ones by default. Never show the raw Nano Banana output — always show the post-processed versions.

Label them clearly as **Version 1**, **Version 2**, and (when present) **Version 3**, and ask the user to pick their favourite or request changes. For a subsequent benefit, if the user isn't happy with either version, generate one more (a 3rd) rather than forcing a pick between two options they don't like.

**Step 5: Iterate if needed**

If the user wants changes, use `edit_image` with **three images** as input:
1. The **scaffold** (`scaffold.png`) — anchors the layout (text position, device placement, screenshot)
2. The **style template** (the first approved screenshot from `screenshots/final/01-*.jpg`) — defines the device frame rendering and overall visual style that must be consistent across the entire set
3. The **approved design** (the version the user liked best for this specific screenshot) — anchors the creative direction and breakout element approach

The prompt should reference all three, using the language from whichever style's template (Bold or Organic) is active:
```
Here are three reference images, each with a distinct purpose:

- FIRST image: The SCAFFOLD — use this as the definitive guide for layout: text position, device frame placement, and the app screenshot on screen. This defines WHERE everything goes.
- SECOND image: The STYLE TEMPLATE — this is the first approved screenshot in the set. [Bold: "The device frame rendering, text treatment, and overall visual style MUST match this exactly."] [Organic: "The device angle, light direction, background family, and restrained treatment MUST match this exactly."] This defines HOW the screenshot should look to maintain consistency across the set.
- THIRD image: The APPROVED DESIGN DIRECTION — this is the version the user liked best for this specific screenshot. Match its creative direction[, breakout element approach — Bold only].

Generate a new version that keeps the layout from the scaffold, the [device frame and visual style / light and material treatment] from the style template, and the creative direction from the approved design, with these changes:
[USER'S REQUESTED CHANGES]
```

This prevents drift (scaffold keeps layout locked), maintains set-wide consistency (style template keeps device frame and visual treatment identical), and preserves the creative direction the user already approved.

When iterating, generate the same number of versions as this benefit's initial pass again in parallel (3 for the first benefit, 2 for subsequent ones — all `edit_image` calls in a single message). Then **immediately run the Step 3 crop/resize loop on all of them in a single Bash call** before showing the user.

**File naming across iteration rounds — never overwrite a prior round's files.** The first pass writes `v1.jpg`/`v2.jpg`(/`v3.jpg`). Each iteration round after that gets its own round-numbered suffix: `v1-r2.jpg`/`v2-r2.jpg` for the first iteration, `v1-r3.jpg`/`v2-r3.jpg` for the second, and so on (same suffix convention on the `-resized.jpg` output). This keeps every attempt on disk so it's always possible to tell what changed between rounds, and so a user who says "actually go back to the first one" can be pointed at a real file rather than something already overwritten. Only the file the user finally approves gets copied into `final/` (Step 6) — the rest stay in the benefit subfolder as history.

Repeat until the user is happy.

**Step 6: Copy approved version to `final/`**

Once the user picks a winner, copy the resized version to `screenshots/final/`:

```bash
mkdir -p screenshots/final
cp "screenshots/01-[benefit-slug]/v2-resized.jpg" "screenshots/final/01-[benefit-slug].jpg"
```

This keeps `final/` clean — only approved, App Store-ready screenshots, one per benefit, numbered in order. Then move to the next benefit.

### Determine Brand Colour & Background (Automatic)

Do NOT ask the user to pick a colour before this — the automatic pick below runs regardless of style; only what happens with the picked colour (and whether a background photo is sourced) differs by style.

**1. Pick the brand colour automatically:**

- **Analyse the codebase** — check for accent colours, tint colours, brand colours in asset catalogs, theme files, colour constants, Info.plist
- **Study the simulator screenshots** — what are the dominant colours in the UI? What colour palette does the app use?
- **Consider the app's domain and audience** — a game can go bold and playful, a finance app needs confident and trustworthy colours

Pick a single colour that complements the screenshots, suits the app's personality, and avoids clashing with the app UI's own dominant colour. Present your choice with brief reasoning (e.g., "Using **#7B2D8E** (deep purple) — it complements your app's colourful UI and stands out at thumbnail size"). The user can override, but don't present it as an open question.

**2. What happens with that colour depends on the style:**

- **Bold/Agency**: used at full saturation as the flat background fill. Avoid white/light grey (disappears against the App Store) and avoid a colour too close to the app UI's dominant colour — vibrant and saturated is correct here, it's the point of this track.
- **Editorial/Organic**: used as the *tint*, not the fill — `compose.py --style organic` automatically softens it into a muted tone (no photo) or a duotone mapping (with a photo). Because the render always tones it down, the raw saturation of the picked hex matters less than getting the right hue for the brand. If Step 0 sourced a background photo, that's what gets tinted; there's no separate colour-only step for organic beyond confirming the hue.

The brand colour (and background photo path, if any) is saved to memory in Step 0 of Generation, before scaffolding begins.

### Output

Save generated screenshots to a `screenshots/` directory in the project root, organised by benefit subfolder:

```
screenshots/
  01-track-card-prices/       ← working versions for benefit 1
    scaffold.png              ← deterministic compose.py output (text + frame + screenshot)
    v1.jpg                    ← Nano Banana enhanced version 1
    v1-resized.jpg            ← cropped/resized to App Store dimensions
    v2.jpg
    v2-resized.jpg
    v3.jpg
    v3-resized.jpg
  02-search-any-card/         ← working versions for benefit 2 (2 versions by default — see Generation Step 2)
    scaffold.png
    v1.jpg
    v1-resized.jpg
    v2.jpg
    v2-resized.jpg
  final/                      ← approved screenshots, ready to upload
    01-track-card-prices.jpg
    02-search-any-card.jpg
competitors/                  ← downloaded competitor screenshots (reference only,
  rival-app-name/                never composited into final/ — see Competitive
    01.jpg                       Research, Step 6)
    ...
background.jpg                 ← organic style only, if a backdrop photo was
                                  sourced/generated in Generation Step 0
```

The `final/` folder is the only one the user needs to care about — it contains one approved, App Store-ready screenshot per benefit, numbered in order. The benefit subfolders and `competitors/` contain working/reference material and can be ignored or deleted after the set is complete.

Also tell the user exactly which App Store Connect display size slot each screenshot fits into.

### Save to Memory

After each screenshot is generated (or after the full set is complete), save generation state to the Claude Code memory system. Create or update a memory file (e.g., `aso_generated_screenshots.md`) with:

- **Style**: bold or organic, plus brand colour (name + hex) and background photo path if organic
- **Target display size**: e.g., iPhone 6.7" (1290x2796)
- **For each generated screenshot**:
  - Benefit headline (ACTION VERB + DESCRIPTOR)
  - Benefit subfolder path (e.g., `screenshots/01-track-card-prices/`)
  - Which version the user chose (v1, v2, or v3)
  - Final file path (e.g., `screenshots/final/01-track-card-prices.jpg`)
  - Simulator screenshot used (file path)
  - Breakout elements described in the prompt (Bold only — organic doesn't use them)
  - Status: generated / approved / needs-redo
  - Any user feedback or change requests noted

Update this memory **incrementally** — after each screenshot is approved, add it. Don't wait until the end. This way if the conversation is interrupted mid-set, the user can resume from the last completed screenshot.

### Showcase Image

Once ALL screenshots in the set are approved and saved to `final/`, generate a showcase image that displays **every** approved screenshot in `final/` side-by-side — not just the first 3. `showcase.py` itself has no image-count limit (its `--screenshots` argument takes any number of files and the canvas grows to fit), so pass the full set. Benefit Discovery explicitly allows 3-5 confirmed benefits, and the showcase is the single most shareable deliverable of the whole process — silently dropping benefit 4 or 5 from it would misrepresent the finished set.

**Ask before adding a GitHub link — never hardcode one.** `--github` is optional. Ask the user: *"Want a GitHub link on the showcase image? If so, what's the URL?"* Use exactly what they give you, or omit the flag entirely if they don't want one. **Never fall back to a placeholder or example link** — the showcase is the most shareable deliverable of the whole process, and shipping it with someone else's link (even as a leftover example) is a real, visible mistake in front of whoever the user shares it with. Use the showcase.py script in the skill directory:

```bash
SKILL_DIR="$HOME/.claude/skills/aso-appstore-screenshots"

python3 "$SKILL_DIR/showcase.py" \
  --screenshots screenshots/final/*.jpg \
  --output screenshots/showcase.png
  # add --github "<the user's own URL>" only if they asked for one
```

Show the showcase image to the user using the Read tool. This is a shareable preview of the full screenshot set — all approved benefits, not a subset.

### Beyond this skill

A few adjacent capabilities live in the sibling `super-aso` plugin, not here — worth pointing the user at when relevant, not worth rebuilding:

- **Localized screenshot text.** Everything this skill produces is in one language (whatever the benefit headlines were drafted in). If the user needs the same screenshots with translated headlines for other App Store locales, that's `super-aso`'s Phase 3 (`reference/screenshots.md`) — it burns translated headings over mockups for every chosen locale. This skill doesn't duplicate that renderer; it hands off a finished, approved en-US (or source-language) set for Phase 3 to localize.
- **App Preview videos.** This skill only produces static screenshots, by design — it does not generate, edit, or apply effects to video. If the user also wants a video on the same App Store listing, `super-aso`'s Phase 3 has a section for locating, spec-checking, and uploading the user's own finished preview video file(s) (never AI-generated).
- **A/B testing the screenshots (PPO).** Generation typically produces more approved-quality versions per benefit than end up in `final/` — the runner-up version(s) from Step 4 aren't just discards, they're ready-made creative variants. `super-aso`'s Phase 7 (`reference/custom-product-pages.md`) runs real App Store product page experiments (PPO); mention this option once a set is finished, especially if the user seemed genuinely torn between two versions of the same screenshot.
- **Validating the style choice against real data.** The Bold-vs-Organic pick in Step 0 is a one-time, pre-launch call based on competitor research — it's never revisited against actual performance. Once the app has been live with the chosen style for a while, `super-aso`'s Phase 9 monitoring (rank/review tracking) or the ASC Analytics Reports API (product-page conversion rate specifically) can confirm whether the style choice is actually working, or whether it's worth trying the other track as a PPO experiment per the point above.

---

## KEY PRINCIPLES

- **Benefits over features**: "BOOST ENGAGEMENT" not "ADD SUBTITLES TO VIDEOS"
- **Specific over generic**: "TRACK TRADING CARD PRICES" not "MANAGE YOUR STUFF"
- **Action-oriented**: Every headline starts with a strong verb
- **User-centric**: Frame everything from the downloader's perspective
- **Conversion-focused**: Every decision should answer "will this make someone tap Download?"
- The first screenshot is the most important — it must communicate the single biggest reason to download
- Screenshots should tell a story when swiped through — each one reveals a new compelling reason
- Always pair the most visually impactful simulator screenshot with the most important benefit
- Never use an empty state, loading screen, or settings page as a screenshot — show the app at its best
- **Know what you're up against before you design.** Competitive Research isn't optional busywork — a style choice made without seeing what the category actually looks like today is a guess, not a decision.
- **Never reuse a competitor's actual creative.** Downloaded competitor screenshots are reference material only — for comparison, inspiration, and gap-finding — never composited, traced, or closely mimicked into the app's own output.
- **"Polished" and "generic" are not the same axis.** Bold/Agency done well is polished, not generic. Editorial/Organic done badly is still generic. The failure mode this skill now actively avoids — regardless of which style is chosen — is every screenshot in every category converging on the exact same centered-headline/solid-colour/floating-panel template. Pick the style that's actually right for this app's category and competitors, not by default.
