Generate a branded social media image for announcing a feature or update. The image is built as an HTML page styled to match the project's brand, then screenshotted with Playwright.
Phase 1: Ensure Playwright is Available
npx playwright --version 2>/dev/null || (echo "Installing Playwright..." && npx playwright install chromium)
If installation fails, inform the user and suggest npm install -D playwright && npx playwright install chromium.
Phase 2: Understand What Changed (Git-Aware)
Analyze the recent git history to understand what feature/update to announce:
Check recent commits:
git log --oneline -20
Check current diff (staged + unstaged):
git diff HEAD --stat
git diff HEAD -- '*.tsx' '*.jsx' '*.vue' '*.svelte' '*.html' '*.css' '*.scss' '*.rb' '*.erb'
Check recent branch name (often describes the feature):
git branch --show-current
Synthesize what the feature/update is from this context.
Present findings to user with AskUserQuestion:
- Header: "Feature"
- Question: "Based on recent changes, it looks like you're working on [X]. What should this announcement be about?"
- Options:
- "[Auto-detected feature description]" - Use what was detected
- "Something else" - Let user describe it
- If
$1 was provided as an argument, use that instead of asking.
Phase 3: Auto-Generate Announcement Text
Generate text elements for the image:
- Headline: A punchy, short headline (3-8 words) about the feature
- Tagline: A one-sentence supporting description
- Badge/Label: Optional category label (e.g., "New Feature", "Update", "Improvement")
Present these to the user with AskUserQuestion:
- Header: "Copy"
- Question: "Here's the text I'd put on the image. Want to adjust anything?"
- Options:
- "Looks good" - Use as-is
- "Edit headline" - User provides custom headline
- "Edit everything" - User provides all text
- "No text overlay" - Generate image without text
Phase 4: Choose Platform & Size
Use AskUserQuestion:
- Header: "Platform"
- Question: "What platform is this image for?"
- Options:
- "Twitter/X (1200x675)" - Standard Twitter card size
- "LinkedIn (1200x627)" - LinkedIn share image
- "Instagram (1080x1080)" - Square format
- "Open Graph (1200x630)" - Universal social preview
Store the chosen width and height for the Playwright viewport.
Phase 5: Choose Visual Style
Use AskUserQuestion:
- Header: "Style"
- Question: "What visual style should the image use?"
- Options:
- "Stylized mockup (Recommended)" - Simplified, polished recreation of UI elements using the app's actual components and CSS. Recognizable but not pixel-perfect.
- "Screenshot + overlay" - Takes a real screenshot of the running app and adds branded text overlays, gradients, and annotations.
- "Abstract/illustrative" - Uses brand colors and typography to create a geometric or gradient design that suggests the feature without replicating specific UI.
Style: Stylized Mockup
This is the most involved style. The goal is to create a representation of the UI that feels like the app without being a literal screenshot.
Find relevant UI components related to the feature:
- Search for component files that match the feature (e.g., if the feature is "dark mode", find theme toggle components)
- Read the component markup to understand the UI structure
- Note key visual elements: buttons, cards, inputs, tables, navigation items
Extract visual patterns from components:
- Border radius values
- Shadow styles
- Specific layout patterns (sidebar + main, card grids, etc.)
- Icon usage
- Interactive element styles (buttons, toggles, inputs)
Build a simplified HTML mockup that:
- Shows the key UI elements of the feature in a stylized, editorial layout
- Uses the actual brand colors, fonts, and border-radius from the codebase
- Adds subtle visual polish (soft shadows, slight gradients, generous whitespace)
- Frames the UI in a "browser window" or "device frame" if appropriate
- Is NOT a full working page -- it's a curated, art-directed composition
Style: Screenshot + Overlay
- Ask the user for the URL of the running app (suggest common localhost URLs)
- Navigate to the relevant page with Playwright
- Take a base screenshot
- Create an HTML overlay page that:
- Embeds the screenshot as a background image
- Adds a gradient overlay (using brand colors) for text readability
- Places headline and tagline text on top
- Adds a badge/label if applicable
- Screenshot the overlay page
Style: Abstract/Illustrative
Build an HTML page with:
- A gradient or geometric background using brand colors
- The project logo (if found in
/public, /assets, or /src/assets)
- Large, bold headline text using the project's font
- Supporting tagline
- Abstract shapes, lines, or patterns that evoke the feature category
- Clean, modern aesthetic with generous whitespace
Phase 6: Deep Brand Analysis
This is the most important phase. Spend real time here. The generated image must feel like it was made by the same team that built the product -- not a generic template with brand colors swapped in. The goal is to internalize the brand's visual identity so deeply that the image is indistinguishable from something the design team would produce.
6.1: Study Existing Marketing Materials First
Before looking at config files, study how the brand actually presents itself. These are your primary references:
Landing pages and marketing pages -- search for:
pages/index, app/page, pages/home, components/landing/, components/marketing/, components/hero
- Any files with
landing, marketing, home, hero, cta in the name
- Read these files thoroughly. Note the exact tone, layout patterns, how they compose text + visuals, gradient directions, decorative elements, background treatments
Existing social/OG images -- search for:
og-image, social, share, twitter, preview in /public or /assets
- Any existing announcement or marketing images in the repo
- These are your strongest reference for what the brand considers "on-brand" for social
Blog or changelog pages -- search for:
blog, changelog, updates, announcements in page/route files
- These show how the brand communicates updates -- mirror this tone and style
Email templates -- search for:
email, mailer, newsletter templates
- These reveal another facet of the brand's visual language
README and docs -- check for badges, banner images, or styled headers that reveal brand personality
6.2: Color Palette
Extract the full color system, not just primary/secondary:
Tailwind config (tailwind.config.js, tailwind.config.ts):
- Read the entire
theme.extend.colors block
- Note the full palette: primary, secondary, accent, neutral, success, warning, error
- Pay attention to color relationships -- how does the brand pair colors?
CSS custom properties (search for :root in global CSS files):
- Look for
--primary, --brand, --accent, --background, --foreground, --muted, --card or similar
- Extract HSL/RGB/hex values
- Note if there are separate light/dark mode palettes
Design token files (search for tokens, theme, design-system in filenames):
- Extract color definitions and semantic mappings
Actual usage in marketing components:
- Read hero sections, CTA buttons, feature cards, pricing tables
- Note which colors are used for backgrounds vs. text vs. accents vs. borders
- Look for gradient definitions -- exact stops, directions, and where they're used
- Find the brand's "signature" color combinations (e.g., dark bg + bright accent, soft pastels, bold primaries)
6.3: Typography
- Font imports (search for
@import with font URLs, @font-face, or Google Fonts links)
- Tailwind fontFamily config
- CSS font-family declarations on body/headings
- Package.json for font packages (e.g.,
@fontsource/*, next/font)
- Actual heading styles -- read marketing page headings to see:
- Font weight (bold? black? medium?)
- Letter spacing (tight? normal? wide?)
- Text transform (uppercase? normal?)
- Line height
- How headlines are sized relative to body text
For the image, use the detected font. If it's a Google Font, include the <link> tag in the HTML. If it's a local/custom font, fall back to a similar system font or Google Font alternative.
6.4: Logo & Assets
Search for logo files:
public/logo*, public/images/logo*, src/assets/logo*, assets/logo*
public/*.svg (check for logo-like SVGs)
public/brand*, src/assets/brand*
If a logo is found, embed it in the image (inline SVG or base64-encoded).
Also look for:
- Icon libraries or custom icon sets used in the app
- Illustration styles (line art? filled? duotone?)
- Background patterns or textures
- Decorative elements (dots, grids, blobs, rings)
6.5: Visual Language & Patterns
Go beyond basic config -- study the visual personality of the brand:
- Border radius: Is the app rounded (
rounded-xl, rounded-2xl) or sharp (rounded-none, rounded-sm)? Use the exact same radii.
- Shadows: Soft/elevated or flat? What shadow values are used? (e.g.,
shadow-lg vs shadow-sm vs no shadow)
- Dark mode: Is dark mode the default or primary theme? What's the background color?
- Gradients: Are gradients used prominently? What direction, what colors, where?
- Glass/blur effects: Any
backdrop-blur usage? Translucent cards?
- Borders: Are borders used for separation or are things borderless? What color/opacity?
- Spacing rhythm: Is the design dense and compact or airy with lots of whitespace?
- Decorative elements: Does the brand use background grids, dot patterns, glow effects, noise textures, gradient orbs?
- Animation style: While animation won't appear in the image, the feel of a brand that uses smooth spring animations vs. no animations tells you about its personality
6.6: Synthesize a Brand Brief
Before building the image, write a short internal summary of the brand's visual identity:
- "This brand uses [dark/light] backgrounds with [color] accents. Typography is [font] at [weight], [tight/normal] letter spacing. The aesthetic is [minimal/bold/playful/corporate]. Key visual motifs include [gradients/glass/sharp corners/etc]. Marketing pages use [layout pattern] with [decorative elements]."
Use this brief as your guide for every design decision in the image. Every element should pass the test: "Would this look at home on their landing page?"
Phase 7: Build the HTML Image Page
Unique temp files: To avoid race conditions when multiple agents run in parallel, generate a slug-based ID for this run. Format: {project-slug}-{feature-slug}-{short-id} where project slug comes from the directory name or package.json name, feature slug is a 2-3 word kebab-case summary of the feature, and short ID is 4-6 random alphanumeric chars. Example: baremetrics-dark-mode-a3f2. Use this slug in all temp file paths below (shown as [UNIQUE_ID]). Both the HTML file and the capture script must use the same slug.
Create a self-contained HTML file at /tmp/feature-image-[UNIQUE_ID]-page.html that:
- Is exactly the chosen dimensions (viewport-sized, no scroll)
- Embeds all styles inline (no external CSS dependencies)
- Includes fonts via Google Fonts link (or similar CDN)
- Uses the detected brand colors, fonts, and visual patterns
- Contains the chosen text overlay (headline, tagline, badge)
- Matches the chosen visual style (mockup, screenshot+overlay, or abstract)
HTML Structure Template
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css2?family=[DETECTED_FONT]&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: [WIDTH]px;
height: [HEIGHT]px;
overflow: hidden;
font-family: '[DETECTED_FONT]', system-ui, sans-serif;
}
body {
background: [BRAND_GRADIENT_OR_COLOR];
color: [TEXT_COLOR];
display: flex;
/* Layout depends on style choice */
}
/* ... style-specific CSS ... */
</style>
</head>
<body>
<!-- Content depends on style choice -->
</body>
</html>
Design Quality Guidelines
The image should look like it was designed by a professional. Follow these principles:
- Hierarchy: Headline is the largest element. Tagline supports it. Badge is small.
- Contrast: Text must be easily readable against the background.
- Alignment: Use a clear grid. Left-align or center consistently.
- Polish: Subtle shadows, smooth gradients, refined typography (letter-spacing, line-height).
- Restraint: Don't use more than 2-3 colors. Don't use more than 2 font weights.
Space Usage (CRITICAL)
These images will be viewed at small sizes in social feeds, timeline cards, and link previews. Every pixel matters. Dead space is wasted space.
Mandatory rules:
- Fill the canvas. Content should use 85-95% of the available area. Padding should be tight -- 40-60px max on a 1200px-wide image, not 100+.
- Make text BIG. Headlines should be 48-72px minimum (at 1x). If the headline is short (3-4 words), go even bigger -- 80-100px. The text needs to be readable at thumbnail size (~400px wide). If you squint at the image and can't read the headline, it's too small.
- No empty centers. If the layout has a headline on top and a UI mockup on the bottom, don't leave a big gap in the middle. Stack elements tightly or fill the space with supporting content.
- UI mockups should be large. If showing a stylized UI element, it should take up at least 50-60% of the image area. Don't render a tiny card floating in a sea of background gradient.
- Edge-to-edge when appropriate. UI mockups can bleed off the edges of the canvas -- this looks more dynamic and uses space better than centering everything with margins.
- Badge/label text should be 14-18px, not smaller. It needs to be visible.
- Test at thumbnail size. Before finalizing, mentally shrink the image to 400px wide. Can you still read the headline? Can you tell what the UI shows? If not, make things bigger.
Common mistakes to avoid:
- A small headline centered in the middle of a large background -- scale it up, push it to a corner or edge
- A UI mockup that's 30% of the canvas surrounded by gradient -- make it dominant
- Excessive padding that makes content feel like it's floating in space
- Tagline text at 14-16px -- bump it to 20-24px minimum
- Using the same spacing between all elements instead of grouping related items tightly
Phase 8: Screenshot with Playwright
Create and run a Node.js script:
import { chromium } from 'playwright';
import { readFileSync } from 'fs';
async function capture() {
const browser = await chromium.launch();
const context = await browser.newContext({
viewport: { width: [WIDTH], height: [HEIGHT] },
deviceScaleFactor: 2, // Retina quality
});
const page = await context.newPage();
// Load the HTML file
const html = readFileSync('/tmp/feature-image-[UNIQUE_ID]-page.html', 'utf-8');
await page.setContent(html, { waitUntil: 'networkidle' });
// Wait for fonts to load
await page.waitForTimeout(1000);
await page.screenshot({
path: './feature-image.png',
type: 'png',
});
await browser.close();
console.log('Saved: ./feature-image.png');
}
capture().catch(console.error);
Save the script to /tmp/feature-image-[UNIQUE_ID]-capture.mjs, run it, then clean up:
node /tmp/feature-image-[UNIQUE_ID]-capture.mjs && rm /tmp/feature-image-[UNIQUE_ID]-capture.mjs /tmp/feature-image-[UNIQUE_ID]-page.html
Phase 9: Verify & Present
Check the file exists and has reasonable size:
ls -la ./feature-image.png
sips -g pixelWidth -g pixelHeight ./feature-image.png 2>/dev/null || file ./feature-image.png
Read the image using the Read tool to show it to the user.
Ask if adjustments are needed with AskUserQuestion:
- Header: "Result"
- Question: "Here's your feature image. What do you think?"
- Options:
- "Looks great" - Done
- "Adjust colors" - Tweak the color palette
- "Adjust text" - Change headline/tagline
- "Try different style" - Switch to another visual style
- If adjustments are needed, go back to the relevant phase and regenerate.
Output summary:
Generated: ./feature-image.png
Size: [W]x[H] @ 2x ([actual_W]x[actual_H] pixels)
Platform: [chosen platform]
Style: [chosen style]
Error Handling
- Playwright not found after install attempt: Suggest manual installation with
npm install -D playwright && npx playwright install chromium
- No git history: Skip git analysis, ask user directly what the feature is
- No brand colors found: Fall back to a clean, neutral palette (dark background, white text, blue accent)
- No fonts detected: Fall back to Inter (Google Font) as a safe, modern default
- Screenshot fails: Check if the HTML file was created correctly, try with a simpler layout
- Font not loading in screenshot: Increase the wait timeout, or fall back to system fonts
Tips for Best Results
- Run this skill from within the project directory so brand detection works
- If the app has a running dev server, the "Screenshot + overlay" style will produce the most authentic results
- For abstract style, the skill works well even without UI components to reference
- The generated image is 2x resolution (retina) -- it will look sharp on all screens
1---2name: feature-image-23description: Generate a branded social media image announcing a new feature or update. Analyzes git history, auto-detects brand from codebase (Tailwind, CSS vars, design tokens), replicates UI elements, and captures via Playwright. Use when the user wants to create an announcement image, says 'feature image,' 'announcement graphic,' 'social image for feature,' or wants to visually announce a code change.4---56Generate a branded social media image for announcing a feature or update. The image is built as an HTML page styled to match the project's brand, then screenshotted with Playwright.78## Phase 1: Ensure Playwright is Available910```bash11npx playwright --version 2>/dev/null || (echo "Installing Playwright..." && npx playwright install chromium)12```1314If installation fails, inform the user and suggest `npm install -D playwright && npx playwright install chromium`.1516## Phase 2: Understand What Changed (Git-Aware)1718Analyze the recent git history to understand what feature/update to announce:19201. **Check recent commits:**21 ```bash22 git log --oneline -2023 ```24252. **Check current diff (staged + unstaged):**26 ```bash27 git diff HEAD --stat28 git diff HEAD -- '*.tsx' '*.jsx' '*.vue' '*.svelte' '*.html' '*.css' '*.scss' '*.rb' '*.erb'29 ```30313. **Check recent branch name** (often describes the feature):32 ```bash33 git branch --show-current34 ```35364. **Synthesize** what the feature/update is from this context.37385. **Present findings to user** with `AskUserQuestion`:39 - Header: "Feature"40 - Question: "Based on recent changes, it looks like you're working on [X]. What should this announcement be about?"41 - Options:42 - "[Auto-detected feature description]" - Use what was detected43 - "Something else" - Let user describe it44 - If `$1` was provided as an argument, use that instead of asking.4546## Phase 3: Auto-Generate Announcement Text4748Generate text elements for the image:4950- **Headline**: A punchy, short headline (3-8 words) about the feature51- **Tagline**: A one-sentence supporting description52- **Badge/Label**: Optional category label (e.g., "New Feature", "Update", "Improvement")5354Present these to the user with `AskUserQuestion`:55- Header: "Copy"56- Question: "Here's the text I'd put on the image. Want to adjust anything?"57- Options:58 - "Looks good" - Use as-is59 - "Edit headline" - User provides custom headline60 - "Edit everything" - User provides all text61 - "No text overlay" - Generate image without text6263## Phase 4: Choose Platform & Size6465Use `AskUserQuestion`:66- Header: "Platform"67- Question: "What platform is this image for?"68- Options:69 - "Twitter/X (1200x675)" - Standard Twitter card size70 - "LinkedIn (1200x627)" - LinkedIn share image71 - "Instagram (1080x1080)" - Square format72 - "Open Graph (1200x630)" - Universal social preview7374Store the chosen width and height for the Playwright viewport.7576## Phase 5: Choose Visual Style7778Use `AskUserQuestion`:79- Header: "Style"80- Question: "What visual style should the image use?"81- Options:82 - "Stylized mockup (Recommended)" - Simplified, polished recreation of UI elements using the app's actual components and CSS. Recognizable but not pixel-perfect.83 - "Screenshot + overlay" - Takes a real screenshot of the running app and adds branded text overlays, gradients, and annotations.84 - "Abstract/illustrative" - Uses brand colors and typography to create a geometric or gradient design that suggests the feature without replicating specific UI.8586### Style: Stylized Mockup8788This is the most involved style. The goal is to create a representation of the UI that *feels* like the app without being a literal screenshot.89901. **Find relevant UI components** related to the feature:91 - Search for component files that match the feature (e.g., if the feature is "dark mode", find theme toggle components)92 - Read the component markup to understand the UI structure93 - Note key visual elements: buttons, cards, inputs, tables, navigation items94952. **Extract visual patterns from components:**96 - Border radius values97 - Shadow styles98 - Specific layout patterns (sidebar + main, card grids, etc.)99 - Icon usage100 - Interactive element styles (buttons, toggles, inputs)1011023. **Build a simplified HTML mockup** that:103 - Shows the key UI elements of the feature in a stylized, editorial layout104 - Uses the actual brand colors, fonts, and border-radius from the codebase105 - Adds subtle visual polish (soft shadows, slight gradients, generous whitespace)106 - Frames the UI in a "browser window" or "device frame" if appropriate107 - Is NOT a full working page -- it's a curated, art-directed composition108109### Style: Screenshot + Overlay1101111. Ask the user for the URL of the running app (suggest common localhost URLs)1122. Navigate to the relevant page with Playwright1133. Take a base screenshot1144. Create an HTML overlay page that:115 - Embeds the screenshot as a background image116 - Adds a gradient overlay (using brand colors) for text readability117 - Places headline and tagline text on top118 - Adds a badge/label if applicable1195. Screenshot the overlay page120121### Style: Abstract/Illustrative122123Build an HTML page with:124- A gradient or geometric background using brand colors125- The project logo (if found in `/public`, `/assets`, or `/src/assets`)126- Large, bold headline text using the project's font127- Supporting tagline128- Abstract shapes, lines, or patterns that evoke the feature category129- Clean, modern aesthetic with generous whitespace130131## Phase 6: Deep Brand Analysis132133This is the most important phase. Spend real time here. The generated image must feel like it was made by the same team that built the product -- not a generic template with brand colors swapped in. The goal is to internalize the brand's visual identity so deeply that the image is indistinguishable from something the design team would produce.134135### 6.1: Study Existing Marketing Materials First136137Before looking at config files, study how the brand actually presents itself. These are your primary references:1381391. **Landing pages and marketing pages** -- search for:140 - `pages/index`, `app/page`, `pages/home`, `components/landing/`, `components/marketing/`, `components/hero`141 - Any files with `landing`, `marketing`, `home`, `hero`, `cta` in the name142 - Read these files thoroughly. Note the exact tone, layout patterns, how they compose text + visuals, gradient directions, decorative elements, background treatments1431442. **Existing social/OG images** -- search for:145 - `og-image`, `social`, `share`, `twitter`, `preview` in `/public` or `/assets`146 - Any existing announcement or marketing images in the repo147 - These are your strongest reference for what the brand considers "on-brand" for social1481493. **Blog or changelog pages** -- search for:150 - `blog`, `changelog`, `updates`, `announcements` in page/route files151 - These show how the brand communicates updates -- mirror this tone and style1521534. **Email templates** -- search for:154 - `email`, `mailer`, `newsletter` templates155 - These reveal another facet of the brand's visual language1561575. **README and docs** -- check for badges, banner images, or styled headers that reveal brand personality158159### 6.2: Color Palette160161Extract the full color system, not just primary/secondary:1621631. **Tailwind config** (`tailwind.config.js`, `tailwind.config.ts`):164 - Read the entire `theme.extend.colors` block165 - Note the full palette: primary, secondary, accent, neutral, success, warning, error166 - Pay attention to color *relationships* -- how does the brand pair colors?1671682. **CSS custom properties** (search for `:root` in global CSS files):169 - Look for `--primary`, `--brand`, `--accent`, `--background`, `--foreground`, `--muted`, `--card` or similar170 - Extract HSL/RGB/hex values171 - Note if there are separate light/dark mode palettes1721733. **Design token files** (search for `tokens`, `theme`, `design-system` in filenames):174 - Extract color definitions and semantic mappings1751764. **Actual usage in marketing components**:177 - Read hero sections, CTA buttons, feature cards, pricing tables178 - Note which colors are used for backgrounds vs. text vs. accents vs. borders179 - Look for gradient definitions -- exact stops, directions, and where they're used180 - Find the brand's "signature" color combinations (e.g., dark bg + bright accent, soft pastels, bold primaries)181182### 6.3: Typography1831841. **Font imports** (search for `@import` with font URLs, `@font-face`, or Google Fonts links)1852. **Tailwind fontFamily config**1863. **CSS font-family declarations** on body/headings1874. **Package.json** for font packages (e.g., `@fontsource/*`, `next/font`)1885. **Actual heading styles** -- read marketing page headings to see:189 - Font weight (bold? black? medium?)190 - Letter spacing (tight? normal? wide?)191 - Text transform (uppercase? normal?)192 - Line height193 - How headlines are sized relative to body text194195For the image, use the detected font. If it's a Google Font, include the `<link>` tag in the HTML. If it's a local/custom font, fall back to a similar system font or Google Font alternative.196197### 6.4: Logo & Assets198199Search for logo files:200```201public/logo*, public/images/logo*, src/assets/logo*, assets/logo*202public/*.svg (check for logo-like SVGs)203public/brand*, src/assets/brand*204```205206If a logo is found, embed it in the image (inline SVG or base64-encoded).207208Also look for:209- Icon libraries or custom icon sets used in the app210- Illustration styles (line art? filled? duotone?)211- Background patterns or textures212- Decorative elements (dots, grids, blobs, rings)213214### 6.5: Visual Language & Patterns215216Go beyond basic config -- study the visual *personality* of the brand:217218- **Border radius**: Is the app rounded (`rounded-xl`, `rounded-2xl`) or sharp (`rounded-none`, `rounded-sm`)? Use the exact same radii.219- **Shadows**: Soft/elevated or flat? What shadow values are used? (e.g., `shadow-lg` vs `shadow-sm` vs no shadow)220- **Dark mode**: Is dark mode the default or primary theme? What's the background color?221- **Gradients**: Are gradients used prominently? What direction, what colors, where?222- **Glass/blur effects**: Any `backdrop-blur` usage? Translucent cards?223- **Borders**: Are borders used for separation or are things borderless? What color/opacity?224- **Spacing rhythm**: Is the design dense and compact or airy with lots of whitespace?225- **Decorative elements**: Does the brand use background grids, dot patterns, glow effects, noise textures, gradient orbs?226- **Animation style**: While animation won't appear in the image, the *feel* of a brand that uses smooth spring animations vs. no animations tells you about its personality227228### 6.6: Synthesize a Brand Brief229230Before building the image, write a short internal summary of the brand's visual identity:231232- "This brand uses [dark/light] backgrounds with [color] accents. Typography is [font] at [weight], [tight/normal] letter spacing. The aesthetic is [minimal/bold/playful/corporate]. Key visual motifs include [gradients/glass/sharp corners/etc]. Marketing pages use [layout pattern] with [decorative elements]."233234Use this brief as your guide for every design decision in the image. Every element should pass the test: "Would this look at home on their landing page?"235236## Phase 7: Build the HTML Image Page237238**Unique temp files:** To avoid race conditions when multiple agents run in parallel, generate a slug-based ID for this run. Format: `{project-slug}-{feature-slug}-{short-id}` where project slug comes from the directory name or package.json name, feature slug is a 2-3 word kebab-case summary of the feature, and short ID is 4-6 random alphanumeric chars. Example: `baremetrics-dark-mode-a3f2`. Use this slug in all temp file paths below (shown as `[UNIQUE_ID]`). Both the HTML file and the capture script must use the same slug.239240Create a self-contained HTML file at `/tmp/feature-image-[UNIQUE_ID]-page.html` that:2412421. **Is exactly the chosen dimensions** (viewport-sized, no scroll)2432. **Embeds all styles inline** (no external CSS dependencies)2443. **Includes fonts via Google Fonts link** (or similar CDN)2454. **Uses the detected brand colors, fonts, and visual patterns**2465. **Contains the chosen text overlay** (headline, tagline, badge)2476. **Matches the chosen visual style** (mockup, screenshot+overlay, or abstract)248249### HTML Structure Template250251```html252<!DOCTYPE html>253<html>254<head>255 <meta charset="utf-8">256 <link href="https://fonts.googleapis.com/css2?family=[DETECTED_FONT]&display=swap" rel="stylesheet">257 <style>258 * { margin: 0; padding: 0; box-sizing: border-box; }259 html, body {260 width: [WIDTH]px;261 height: [HEIGHT]px;262 overflow: hidden;263 font-family: '[DETECTED_FONT]', system-ui, sans-serif;264 }265 body {266 background: [BRAND_GRADIENT_OR_COLOR];267 color: [TEXT_COLOR];268 display: flex;269 /* Layout depends on style choice */270 }271 /* ... style-specific CSS ... */272 </style>273</head>274<body>275 <!-- Content depends on style choice -->276</body>277</html>278```279280### Design Quality Guidelines281282The image should look like it was designed by a professional. Follow these principles:283284- **Hierarchy**: Headline is the largest element. Tagline supports it. Badge is small.285- **Contrast**: Text must be easily readable against the background.286- **Alignment**: Use a clear grid. Left-align or center consistently.287- **Polish**: Subtle shadows, smooth gradients, refined typography (letter-spacing, line-height).288- **Restraint**: Don't use more than 2-3 colors. Don't use more than 2 font weights.289290### Space Usage (CRITICAL)291292These images will be viewed at small sizes in social feeds, timeline cards, and link previews. Every pixel matters. Dead space is wasted space.293294**Mandatory rules:**2952961. **Fill the canvas.** Content should use 85-95% of the available area. Padding should be tight -- 40-60px max on a 1200px-wide image, not 100+.2972. **Make text BIG.** Headlines should be 48-72px minimum (at 1x). If the headline is short (3-4 words), go even bigger -- 80-100px. The text needs to be readable at thumbnail size (~400px wide). If you squint at the image and can't read the headline, it's too small.2983. **No empty centers.** If the layout has a headline on top and a UI mockup on the bottom, don't leave a big gap in the middle. Stack elements tightly or fill the space with supporting content.2994. **UI mockups should be large.** If showing a stylized UI element, it should take up at least 50-60% of the image area. Don't render a tiny card floating in a sea of background gradient.3005. **Edge-to-edge when appropriate.** UI mockups can bleed off the edges of the canvas -- this looks more dynamic and uses space better than centering everything with margins.3016. **Badge/label text should be 14-18px**, not smaller. It needs to be visible.3027. **Test at thumbnail size.** Before finalizing, mentally shrink the image to 400px wide. Can you still read the headline? Can you tell what the UI shows? If not, make things bigger.303304**Common mistakes to avoid:**305- A small headline centered in the middle of a large background -- scale it up, push it to a corner or edge306- A UI mockup that's 30% of the canvas surrounded by gradient -- make it dominant307- Excessive padding that makes content feel like it's floating in space308- Tagline text at 14-16px -- bump it to 20-24px minimum309- Using the same spacing between all elements instead of grouping related items tightly310311## Phase 8: Screenshot with Playwright312313Create and run a Node.js script:314315```javascript316import { chromium } from 'playwright';317import { readFileSync } from 'fs';318319async function capture() {320 const browser = await chromium.launch();321 const context = await browser.newContext({322 viewport: { width: [WIDTH], height: [HEIGHT] },323 deviceScaleFactor: 2, // Retina quality324 });325 const page = await context.newPage();326327 // Load the HTML file328 const html = readFileSync('/tmp/feature-image-[UNIQUE_ID]-page.html', 'utf-8');329 await page.setContent(html, { waitUntil: 'networkidle' });330331 // Wait for fonts to load332 await page.waitForTimeout(1000);333334 await page.screenshot({335 path: './feature-image.png',336 type: 'png',337 });338339 await browser.close();340 console.log('Saved: ./feature-image.png');341}342343capture().catch(console.error);344```345346Save the script to `/tmp/feature-image-[UNIQUE_ID]-capture.mjs`, run it, then clean up:347348```bash349node /tmp/feature-image-[UNIQUE_ID]-capture.mjs && rm /tmp/feature-image-[UNIQUE_ID]-capture.mjs /tmp/feature-image-[UNIQUE_ID]-page.html350```351352## Phase 9: Verify & Present3533541. **Check the file exists and has reasonable size:**355 ```bash356 ls -la ./feature-image.png357 sips -g pixelWidth -g pixelHeight ./feature-image.png 2>/dev/null || file ./feature-image.png358 ```3593602. **Read the image** using the Read tool to show it to the user.3613623. **Ask if adjustments are needed** with `AskUserQuestion`:363 - Header: "Result"364 - Question: "Here's your feature image. What do you think?"365 - Options:366 - "Looks great" - Done367 - "Adjust colors" - Tweak the color palette368 - "Adjust text" - Change headline/tagline369 - "Try different style" - Switch to another visual style370 - If adjustments are needed, go back to the relevant phase and regenerate.3713724. **Output summary:**373 ```374 Generated: ./feature-image.png375 Size: [W]x[H] @ 2x ([actual_W]x[actual_H] pixels)376 Platform: [chosen platform]377 Style: [chosen style]378 ```379380## Error Handling381382- **Playwright not found after install attempt**: Suggest manual installation with `npm install -D playwright && npx playwright install chromium`383- **No git history**: Skip git analysis, ask user directly what the feature is384- **No brand colors found**: Fall back to a clean, neutral palette (dark background, white text, blue accent)385- **No fonts detected**: Fall back to Inter (Google Font) as a safe, modern default386- **Screenshot fails**: Check if the HTML file was created correctly, try with a simpler layout387- **Font not loading in screenshot**: Increase the wait timeout, or fall back to system fonts388389## Tips for Best Results3903911. Run this skill from within the project directory so brand detection works3922. If the app has a running dev server, the "Screenshot + overlay" style will produce the most authentic results3933. For abstract style, the skill works well even without UI components to reference3944. The generated image is 2x resolution (retina) -- it will look sharp on all screens