gooseworks-ai/goose-graphics-create-style
> End-to-end skill that turns a single reference image into a published Gooseworks style — analyzes the image, drafts the slim style spec, renders a hero example plus 2-3 additional formats via Playwright, writes the `gooseworks-style.json` manifest, and publishes via `npx gooseworks styles publish` so other agents can discover it. Mirrors goose-graphics-create-format but for styles.
npx skills add https://github.com/gooseworks-ai/goose-skills --skill goose-graphics-create-style
Authors a new graphics style and publishes it to the central Gooseworks
library via npx gooseworks styles publish. The output is a working
directory with a gooseworks-style.json manifest plus a hero rendered
example and 2-3 additional examples that demonstrate the aesthetic flexing
across formats.
Use when the user has a reference image and wants the aesthetic available
as a reusable, discoverable style — so any future
/goose-graphics --style <slug> --format <any> call can render against it.
Always check first: run npx gooseworks styles list (or
npx gooseworks styles search "warm editorial") to see whether a
community-published style already covers the look. If one fits, just use
it via the regular goose-graphics flow.
goose-graphics skill must be installed in the same workspace —this skill uses its screenshot/screenshot.js to render examples.
Install via:
npx gooseworks install --claude --with goose-graphics
(Swap --claude for --cursor or --codex as needed.) See the install
page on the hub for the canonical command:
https://skills.gooseworks.ai/skills/goose-graphics
(goose-graphics/screenshot/node_modules/ must exist). If not:
cd <path-to>/goose-graphics/screenshot && npm install && npx playwright install chromium
npx gooseworks login) forpublish to authenticate.
/goose-graphics-create-style --ref <image-path> [--name <slug>] [--mood <mood-group>]
--ref <image-path> (required) — path to the reference image(PNG/JPG/WebP).
--name <slug> (optional) — desired style slug in lowercase-kebab-case(e.g., pillow-block, neon-dashboard). If omitted, propose 2-3
candidate names after analyzing the image and ask the user to pick.
--mood <mood-group> (optional) — which moodGroup the style belongsto. One of: Dark & Moody, Light & Editorial, Organic & Warm,
Bold & Energetic, Retro & Cinematic, Structural & Technical,
Friendly Corporate. If omitted, infer from the image and confirm.
If the user says "I want a new style for goose-graphics" without args, ask
for the reference image path first, then proceed.
<working-dir>/
gooseworks-style.json # manifest (see "Manifest format" below)
poster.png # hero example (REQUIRED — exactly one with isHero: true)
carousel.png # additional examples (recommend 2-3 across formats)
infographic.png
...
The backend rejects publish with an empty examples array or with no
hero — exactly one example must be marked isHero: true.
All examples are generated using the same brief used by the rest of the
catalog, so users can compare styles apples-to-apples:
> Brief: 5 Tips for Building a Startup in 2026
>
> Tips (use these verbatim, adapt phrasing per style voice):
> 1. Ship fast, learn faster
> 2. Build AI into the core
> 3. Hire for leverage, not headcount
> 4. Obsess over 10 users before 10,000
> 5. Revenue beats runway
Always use this brief. Do not invent your own — it makes the catalog
inconsistent.
Read tool (it supports PNG/JPG/WebP natively).out in plain text before moving on** — do not skip ahead.
Palette — identify 3-6 dominant colors. For each, propose a hex
value in the right family (you cannot extract exact hex; pick
well-balanced values). Classify each by role: background/canvas,
primary surface, accent, secondary accent, text, muted text,
borders/dividers, any neon/highlight color.
Typography — heading face (serif / sans / slab / mono), body face
(same or different family), weight range, tracking (negative / normal /
positive), line-height (tight / generous), overall feel
(geometric / humanist / elegant / technical / rounded / condensed).
Map to a Google Fonts equivalent (Inter, Fraunces, Playfair Display,
Space Grotesk, IBM Plex Mono, etc.).
Layout & shape language — corner radius (sharp / 12px / 28px
squircle / pill / circle), borders (yes / no), shadows
(yes / no / subtle), tile density, alignment, whether elements overlap.
Signature visual moves — what makes this style THIS style?
Examples: "pillowy 28px squircle tiles with hero numerals
bottom-right", "blush canvas + oversized black serif money stats",
"dark jewel surfaces + neon pink pill labels". Lead with these — they
differentiate the style across formats.
Mood / category — dark/light, calm/loud, premium/playful. Use this
to pick the moodGroup if not provided.
(palette + typography + signature visual moves) that flexes across all
formats. It is NOT a fixed composition. If your analysis describes
"5 cards in a bento grid" or "3 vertical insight cards," you are
mixing format into style. Re-frame in terms of palette, typography,
and signature visual moves that any format can adopt.
If --name was provided, use it. Otherwise propose 2-3 candidates derived
from the signature moves (e.g. pillow-block, pastel-ledger,
neon-dashboard) and ask the user to pick. Slug must be
lowercase-kebab-case ([a-z0-9-]+).
Collision check: run npx gooseworks styles get <slug> — if the
catalog returns a hit, the slug is taken. Suggest an alternative.
(The user may omit slug from the manifest; the backend auto-generates
one. On 409 the CLI prompts you to accept the server's suggested slug;
pass --yes at publish time to auto-accept.)
If --mood was provided, use it. Otherwise pick the best fit from the
seven moodGroup values (see §Invocation) and confirm.
This becomes the designMd field of the manifest in step 5. Hold it in
memory; do not write it to disk until step 5 packages it into the
manifest. Mirror the structure of canonical slim specs (e.g.
dot-grid-stat, pillow-block, blush-annual, neon-dashboard) — fetch
one as a reference if unsure of the shape:
npx gooseworks styles get dot-grid-stat
Required sections, in this order:
signature move. End with the vibe / brand analogy.
## Palette — markdown table with Hex | Role columns. Includesemi-transparent variants (rgba(...)) where the style uses them.
## Typography — Google Fonts <link> block, font CSS variablelines, then a type table with columns `Role | Font | Size | Weight |
Line-height | Tracking`. Include rows for hero, display, body, label,
caption, brand. End with a Principles sub-list (3-5 bullets).
## Layout — bullet list. Must include a "Format padding" linelisting per-format padding
(carousel/infographic/slides/poster/story/chart/tweet). Then 4-6
aesthetic-principle bullets.
## Do / Don't — two sub-lists, 5 bullets each.## CSS snippets — :root variables block, then 1-2ready-to-paste HTML snippets demonstrating the signature move
(e.g. a hero tile, a card, a CTA pill).
Keep it under ~200 lines / 8KB. Aesthetic-only — no fixed compositions.
Minimum length is 50 chars (the manifest validator's floor); the sweet
spot for the catalog is 2000-6000 chars.
Pick a hero format (the one example that best showcases the aesthetic),
plus 2-3 additional formats so the catalog tile shows variety. **Hero
priority order:**
poster > carousel > infographic > slides > chart > story > tweet
i.e. start at poster and walk down until you hit a format that fits the
aesthetic well.
For each example, generate HTML at the format's exact dimensions using the
slim spec's palette, fonts, and signature visual moves, and the standard
brief above. Format dimensions:
| Format | Dimensions | Notes |
|---|---|---|
| poster | 1080×1350 portrait | Hero composition with all 5 tips |
| infographic | 1080×variable | Tall vertical, 5 tip sections stacked |
| carousel | 1080×1080 | Single representative cover slide |
| slides | 1920×1080 | Single representative widescreen slide |
| story | 1080×1920 vertical | Single representative story slide |
| chart | 1080×1080 | Bar / line / block chart of stats from the 5 tips |
| tweet | 1080×1080 | Testimonial card on decorative background, NOT a poster |
Critical: the tweet format is a simulated tweet/testimonial card
centered on a decorative background styled with the new aesthetic — not a
poster. Background uses the new style's palette/shapes; the centered card
looks like a real social-media post (avatar, display name, handle, body,
timestamp, engagement metrics).
HTML rules (apply to every example):
<style> block + Google Fonts<link>.
vw/vh/%/rem/em/clamp().html, body { width: Xpx; height: Ypx; overflow: hidden; }. Infographic
is the exception: width fixed, height grows.
do not invent new colors.
can't fit the move comfortably, scale it down — do not abandon it.
Render each via the screenshot tool, writing PNGs **directly into the
working directory** (one PNG per format, named after the format slug):
node <path-to>/goose-graphics/screenshot/screenshot.js \
--format <format> \
--input <path-to-html> \
--output <working-dir>/<format>.png \
--font-delay 1500
Single-file vs directory input: carousel, slides, and story are
"multi-file" formats by default — if --input is a directory, the tool
renders every .html file inside it to numbered slide-NN.png files in
the --output directory. For the single representative slide we want
here, pass a single .html file as --input and a single PNG path as
--output — the tool detects the file input and writes one PNG. The
other formats (poster, infographic, chart, tweet) are always single-file.
Common failure modes:
layout.
--font-delay to 2000.Prerequisites.
gooseworks-style.jsonMatch the shape documented in goose-graphics/SKILL.md §17.1. Required:
{
"name": "Desert Sunset",
"slug": "desert-sunset",
"description": "Warm dusk gradients with rust and amber on cream paper. Editorial serif headlines paired with a single sans-serif accent. Built for DTC beauty product launches, lifestyle long-form, and event posters where you want a confident, sun-soaked, high-end magazine feel.",
"designMd": "# Desert Sunset\n\n…full slim spec markdown from step 3 — palette table, typography table, layout rules, do/don'ts, CSS snippets…",
"moodGroup": "Organic & Warm",
"tags": ["warm", "desert", "editorial", "serif", "dtc"],
"palette": [
{ "hex": "#E06A2C", "role": "primary" },
{ "hex": "#3A1F1A", "role": "ink" },
{ "hex": "#F5EFE7", "role": "paper" }
],
"examples": [
{ "format": "poster", "isHero": true, "file": "./poster.png", "caption": "Hero render" },
{ "format": "carousel", "file": "./carousel.png" },
{ "format": "story", "file": "./story.png" }
]
}
Constraints to respect:
name: 1-120 charsslug: optional kebab-case [a-z0-9-]+; backend auto-generates ifabsent. A 409 collision returns a server-suggested slug — the CLI
handles the retry.
description: 20-1000 chars (required). See guidelines below.designMd: minimum 50 chars (required) — the spec from step 3.moodGroup: optional; one of the seven values listed in §Invocation.tags: array of 3-10 lowercase strings. See guidelines below.palette: array of { hex: "#RRGGBB", role?: string }.examples: array, minimum 1 entry, exactly one withisHero: true.
examples[].format: slug of an existing graphics format(any from npx gooseworks formats list).
examples[].file: relative path to the PNG in the working directory.Read 2-3 of the rendered PNGs (the hero plus the most distinct two) and
visually verify:
poster.
If anything looks off, fix the HTML and re-render. Don't ship broken
examples.
cd <working-dir>
npx gooseworks styles publish
The CLI reads gooseworks-style.json, validates it client-side, uploads
the manifest plus the example PNGs, and registers the style in the
catalog.
Slug-collision UX: if the slug is taken, the CLI prompts
Slug 'X' is taken. Use 'Y' instead? with the server's suggestion. Pass
--yes to auto-accept (useful for scripted runs):
npx gooseworks styles publish --yes
Success output:
Published style: <slug>
https://skills.gooseworks.ai/styles/<slug>
Exit codes: 0 success, 1 transient/auth (network, 401, 5xx), 2
user error (400 validation, 403 not owner, 413 file too large, declined
409).
Amending a published style later:
npx gooseworks styles update <slug>
Same manifest format; no slug-collision retry (the slug is locked).
Tell the user:
/goose-graphics --style <slug> --format <format> --brief "...".
The description is what makes the style discoverable by AI agents
searching the catalog. Treat it as a search index, not flavor text.
launches and event posters."
paired with a delicate body serif."
publishing, event flyers."
nothing without concrete signals — pair them with palette, typography,
or industry context.
3-10 lowercase tags. Cover:
warm, dark, energetic, calmsparse, densecorporate, editorial, playfulmid-century, y2k, retrosaas, dtc, beauty, financeSkip tags that just restate the slug.
npx gooseworks styles get dot-grid-stat,
npx gooseworks styles get pillow-block,
npx gooseworks styles get blush-annual,
npx gooseworks styles get neon-dashboard.
goose-graphics/screenshot/screenshot.js is the rendering pipeline; itsets format-specific viewport and capture mode.
npx gooseworks formats get <format> returns each format's spec andcontent limits — fetch the relevant one if you're unsure how a format
should behave.
or "3 vertical insight cards" is composition, not style. Style =
palette + typography + signature visual moves.
with no isHero: true entry.
on a decorative background.
for Building a Startup in 2026" with the five canonical tips.
missing fonts is worse than no example.
npx gooseworks styles list first —if the look already exists in the catalog, point the user at it instead
of publishing a duplicate.
Take gooseworks-ai/goose-graphics-create-style from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm, npx.
Without those the skill loads but fails at the first command.