--- name: template-author description: Add or edit ready-to-edit start-screen templates in `ComposerTemplateLibrary` (`CW-71` / `CW-77`). Use whenever the user asks to create, generate, design, or edit a template; recreate App Store marketing screenshots as a template (provide an `apps.apple.com` URL or numeric track id and this skill will inspect every Apple platform the app ships on); generate a background image for a template (landscapes, minimalist arches, mesh gradients, geometric, grain, or any other plate-fill imagery); add a new entry to the start-screen chooser; or update an existing builder, scene, palette, or copy. Pairs with the `screenshot-format` skill for the `.screenshot` JSON schema, and respects the workspace `screen-specs` and `test-driven-design` rules. --- # Template author ScreenShotComposer's start-screen templates ship in **two backing forms** that merge into one chooser catalog: 1. **Bundled file-based templates** — preferred for **all new work**. Each template is a `.screenshot`-shaped directory under `ScreenShotComposer/Templates//` (auto-bundled into `Resources/Templates//` by a `Copy bundled Templates` build phase) plus a `template.json` sidecar that holds chooser metadata. `BundledTemplateStore` discovers them at first access; the catalog merge in `ComposerTemplateLibrary.templates` makes them appear alongside legacy code-based templates with no extra wiring. 2. **Code-backed templates** — historical surface in `ComposerTemplateLibrary.swift` under `codeBackedTemplates` + `enum Builders`. Still supported for the original 11 templates but **do not add new ones here**. A bundled file with the same id shadows a code-backed entry, so the migration path is "bake → drop the Swift code". Three scenes ship per template by default: `.home`, `.feature`, `.socialProof` (the App Store standard 3-pager — `CW-77`). ### Empty bezels auto-fill with a device wallpaper A bezeled `image` layer that has no embedded raster is **not** an empty placeholder anymore. The renderer (`ImageLayerChromeView.bezeledLayer`) detects the bezel id and paints a generic iPhone / iPad / Mac mesh-gradient wallpaper inside the inner rect, both in the canvas preview and in any PNG that flows through `CompositionExporter` (chooser thumbnails, user PNG exports, etc). Mapping logic lives in `DeviceWallpaper.swift` (`iphone` → pink/purple/blue, `ipad` → coral/orange/purple, `mac` → cobalt/navy). Custom or unrecognized bezels fall through to the legacy "drop an image here" placeholder so the user still gets the affordance. **Implication for new templates:** **don't bake a placeholder screenshot into the bezel** when authoring — leave the layer's image empty and the wallpaper will fill it. Templates only need to embed an image inside the bezel when the design specifically calls for in-app UI (e.g. a Shortcuts mockup) rather than a generic device wallpaper. If you want the empty bezel to feel like a real device in the chooser preview, you don't have to do anything; just save with the bezel image unset. Read the **screenshot-format** skill (`.cursor/skills/screenshot-format/SKILL.md`) before authoring or editing a template; it documents the JSON your bundled directory ultimately stores. ## When to use this skill - "Create a template" / "add a template" / "design a template that looks like X". - "Recreate this App Store listing as a template" (with or without an `apps.apple.com` URL). - "Edit the *Hero Spotlight* template" / "change the social-proof page on every template" / "swap the bezel". - "Generate a background image for this template" — landscapes, minimalist arches, mesh gradients, geometric grids, grainy textures, paper-cut shapes, or any other plate-fill imagery that a flat color or gradient can't capture. - Adding a new template category, scene type, or palette helper. If the user only wants to draft a one-off `.screenshot` document (not a reusable template), use the **screenshot-format** skill directly instead. ## Workflow Pick the matching path. Both paths converge on the same registration + verification steps. ### Path A — Recreate an existing App Store listing User shares an `apps.apple.com` URL (or any numeric track id / bundle id). 1. **Inspect the listing across every Apple platform.** Run: ```bash .cursor/skills/template-author/scripts/fetch-app-store-listing.sh ``` The script emits a single JSON object on stdout with the iPhone, iPad, and Mac search results merged (whichever the app ships on). It pulls from `https://itunes.apple.com/lookup` once per `entity` (`software`, `iPadSoftware`, `macSoftware`) and notes which platforms returned no result. 2. **Download reference screenshots** into a scratch directory you can ignore in git: ```bash .cursor/skills/template-author/scripts/download-app-store-screenshots.sh \ tmp/-refs ``` Files land as `tmp/-refs//-.png`. Use the `0x0w` URL substitution the script applies to grab full-resolution captures, not the 643px thumbnails. 3. **Read the listing** to derive template intent: headline copy style, dominant background colors, **background style** (flat? gradient? landscape photo? minimalist arches? mesh gradient? geometric pattern?), device pose (centered? tilted pair? multi-device?), whether the listing leans editorial (left-aligned text) or hero (oversized headline). Look at the actual PNGs you just downloaded — the iTunes metadata only gives you titles and URLs. 4. **If the source background isn't a flat color or simple gradient, plan to generate a matching background image.** See [references/background-image-generation.md](references/background-image-generation.md) for the visual-language catalog (landscapes, arches, mesh, geometric, grain, paper-cut), prompt templates, plate sizing, and builder wiring. You'll execute the actual generation in **Common steps** below. 5. Continue at **Common steps** below (starts at step 3 — pick a template id). ### Path B — From scratch (no App Store URL) 1. Get a clear design intent from the user: **category** (`.devices`, `.hero`, `.minimal`, `.multiDevice`, `.editorial`), **mood** (palette, gradient direction), **device pose** for the home + feature scenes, and any custom **copy** they want over the boilerplate in `Builders.copy(for:scene:)`. 2. Continue at **Common steps** below. ### Common steps New templates ship as **bundled `.screenshot` directories** under `ScreenShotComposer/Templates//`. The recommended authoring loop is: 3. **Pick a template id** — short, lowercase, hyphenated, unique against `ComposerTemplateLibrary.templates`. Examples: `pastel-arches`, `hero-spotlight`. The id is used as the directory name, in the chooser, in Recents storage, and in preview filenames. 4. **Update the spec first** (per `screen-specs` skill). Add a `planned` row in `docs/product-specs/screens/composer-workspace.md` under the existing `CW-71` / `CW-77` block, calling out the new template id, category, and what it brings to the catalog. Note any embedded background art so reviewers know to look at the new `Templates//assets/` PNGs. 5. **Compose the template visually inside the running app.** ```bash bin/launch-mac ``` Use **File → New** to start from the closest existing template (or a blank document), then iterate on plate background, layers, copy, and bezels until each platform's three scenes look right. **Save** the document somewhere you can find — every embedded asset (background images, screenshots inside bezels, decorative artwork) ends up in the `.screenshot` package's `assets/` directory, so the saved document is already most of the bundled template. 6. **Promote the saved `.screenshot` document into a bundled template.** A `.screenshot` package and a bundled template directory share the same on-disk shape — `info.json` + `mac.json` / `iphone.json` / `ipad.json` + `assets/` + optional `QuickLook/`. Copy the saved package into the templates directory and rename it (drop the `.screenshot` extension) so it becomes `ScreenShotComposer/Templates//`. Then add a `template.json` sidecar: ```json { "id": "", "label": "Display Label", "summary": "One-line caption shown in the chooser row.", "category": "editorial" } ``` Valid `category` values mirror `ComposerTemplateCategory`: `devices`, `hero`, `minimal`, `multiDevice`, `editorial`. (Unknown values fall back to `editorial` at load time.) 7. **(Migrating a code-backed template?)** Use the bake helper instead of hand-copying. Add the template id to `ScreenShotComposerTests/BundledTemplateBaker.swift`'s `queue`, then run: ```bash bin/bake-bundled-templates ``` The helper runs the legacy Swift `Builders.*` for every (platform, scene), serializes the result through `ScreenshotPackageSerialization`, and copies the resulting directory into `ScreenShotComposer/Templates//`. After the directory is committed, delete the matching `Builders.*` function, the catalog row in `codeBackedTemplates`, the `builderFor(templateID:)` switch case, and the `homeWireframe` / `featureWireframe` / `copy(for:scene:)` entries for that id — the bundled file shadows the code path and the dead code becomes pure clutter. 8. **Add a unit test** (per `test-driven-design` skill). Add coverage to `ScreenShotComposerTests/BundledTemplateStoreTests.swift` (or model on it) — verify the new template is discovered by `BundledTemplateStore.shared`, lands in `ComposerTemplateLibrary.templates`, ships compositions for every supported platform, and (if it embeds background image bytes) carries `.imageFill` on the pinned background layer with non-empty `imageData`. 9. **Re-render the chooser previews:** ```bash bin/refresh-template-previews ``` This writes `--.png` (3 scenes × 3 platforms = **9 PNGs per template**) into `ScreenShotComposer/TemplatePreviews/`. Commit those PNGs alongside the new `Templates//` directory. 10. **Run tests + a launch smoke check:** ```bash bin/test-mac bin/launch-mac ``` 11. **Finalize the spec:** flip the `planned` row to `complete` and link the new test in the **Tests** column. Refresh `docs/product-specs/screens/README.md` if the overall status moved. ## Editing an existing template For **bundled templates** (the only kind you should add new work to): - Open `ScreenShotComposer/Templates//` as a `.screenshot` package in the running app (rename the directory to add a temporary `.screenshot` extension if needed, then rename back after saving). - Edit visually, save, and copy the saved package back over the bundled directory. The `template.json` sidecar persists across saves; copy it back if you overwrote it. - For mass tweaks (palette swap across every scene, copy edit), edit the JSON directly — the schema is documented in the **screenshot-format** skill. For **code-backed templates** (legacy), see [workflows/edit-template.md](workflows/edit-template.md) for the focused checklist (find the right builder, decide whether the change is per-scene or shared, when to retitle vs replace, when to bump preview PNGs). ## Anatomy & helpers (references) - [references/template-anatomy.md](references/template-anatomy.md) — `ComposerTemplate` metadata, `Builders.*` dispatch (legacy code path), `TemplateBuildContext` helpers (`frame`, `centeredFrame`, `primaryBezelID`, `primaryAspect`). - [references/palette-and-typography.md](references/palette-and-typography.md) — Shared color tokens (`Builders.inkText`, `lightText`, `mutedDarkText`, `mutedLightText`, `goldStar`), font scale conventions, `socialProofScene` palette. - [references/background-image-generation.md](references/background-image-generation.md) — When to generate a plate background image, visual-language catalog (landscapes, arches, mesh, geometric, grain, paper-cut, photography), prompt patterns, plate sizing, file naming. For bundled templates the generated PNG lives in the saved `.screenshot` package's `assets/` dir, not under `TemplateBackgrounds/`. - [references/previews-and-registration.md](references/previews-and-registration.md) — How `bin/refresh-template-previews` works, where chooser sidebar buckets are defined, Recents storage. ## Workflows - [workflows/from-app-store.md](workflows/from-app-store.md) — Detailed App Store inspection workflow (URL parsing, multi-platform lookup, screenshot download, palette extraction tips). - [workflows/from-scratch.md](workflows/from-scratch.md) — Clarifying questions and design-intent prompts when there's no reference listing. - [workflows/edit-template.md](workflows/edit-template.md) — Edit-in-place checklist. ## Helper scripts - `scripts/fetch-app-store-listing.sh ` — Lookup the app on iTunes Search across all three Apple software entities; print merged JSON (one block per platform) with screenshot URLs and basic metadata. - `scripts/download-app-store-screenshots.sh ` — Download every screenshot at full resolution into `//`. Both scripts depend only on `curl` and `jq` (standard on macOS).