Design a logo or mark through reference study, generated concept rounds, and a browsable contact sheet the user picks from. Use "/logo new <brief>" to start, "/logo round <dir>" to rebuild a sheet, "/logo ship <dir>" to emit final assets.
Scanned 8/31/2026
Install to Claude Code
npx -y skills add oharu121/skills --skill logo --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Logo?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/oharu121-logo)More formats (shields.io, HTML) on the badges page.
---
name: logo
description: Design a logo or mark through reference study, generated concept rounds, and a browsable contact sheet the user picks from. Use "/logo new <brief>" to start, "/logo round <dir>" to rebuild a sheet, "/logo ship <dir>" to emit final assets.
user-invocable: true
argument-hint: "new <brief> | round <dir> | refine <concept-id> | ship <dir>"
allowed-tools: Bash(node *, uv run *, python3 *, curl *, mkdir *, cp *), Read, Write, Edit, Glob, Grep, WebSearch, WebFetch, AskUserQuestion
---
# Logo Skill
You are designing a mark. The user picks; you generate, render, and narrow.
## Path Variables
- `SKILLS_DIR` = this skill's directory (where `SKILL.md` lives)
- `SCRATCH` = the session scratchpad directory, or `$(mktemp -d)` if none is
given. **Concepts and contact sheets never go in the user's repo** — only the
final chosen assets do
## Dispatch
- `new <brief>` → follow [explore.md](explore.md) from the top
- `round <dir>` → rebuild and serve the contact sheet for `<dir>` (step 4 of
explore.md). Use when concepts changed and you want a fresh look
- `refine <concept-id>` → re-enter explore.md at the refinement round with that
concept as the seed
- `ship <dir>` → follow [ship.md](ship.md) to emit final assets
- anything else → list the subcommands above and stop
## Requirements
- **Node** for the contact sheet. No dependencies
- **`uv`** only if you bake typeface outlines (`outline.py` pulls `fonttools`
and `uharfbuzz` on demand). Purely geometric marks do not need it
- A way to view a rendered page. The sheet is served over HTTP precisely so a
headless browser can reach it
---
## Non-negotiables
These are not style preferences. Each is here because skipping it produced a
visibly worse result, and they are ordered by how much damage they do.
### 1. Study real work before generating anything
Generating first and looking at references later does not work. Asked for *N*
concepts cold, you will produce *N* samples from one distribution — the same
monoline geometric stroke drawing, wearing *N* hats. It reads as generic because
it *is* the generic default, and it is the house style of every automated logo
tool.
Breadth has to come from outside. [references.md](references.md) is the step
that supplies it. Do not skip it because the brief seems obvious.
### 2. Render it and look before showing it to anyone
You cannot judge a mark from its path data. Build the contact sheet, open it,
and look at the pixels before presenting.
This is not a formality. Real bugs that survived review-by-reading: a letter
whose stem was missing its top half, a subtitle whose ascenders punched through
the word above it, a mark sized so small beside its wordmark that it read as a
bullet point. All three were obvious in a browser and invisible in the markup.
### 3. Judge at 16px
The sheet renders every concept at 16px for a reason. That is the size a favicon
is actually used at, it is the size that eliminates candidates, and it is the one
nobody looks at until the thing ships.
What it reliably decides:
- **Solid fills survive; strokes close up.** A stroked ring at 16px fills in
- **Detail is a liability.** A 10-stroke CJK glyph at 16px is texture, not a
character. Two of them is a smudge
- **Silhouette beats interior.** A circle among square favicons is identifiable
even when nothing inside it resolves
### 4. Never bake in an assumption about the person
If a mark depends on a fact about the user — what their name means, which
characters it is written with, what a symbol signifies in their culture — **ask
before building it**, with AskUserQuestion.
You will otherwise produce a confident, polished, well-executed artefact built on
a guess, and the guess will not be visible in the output. A name that sounds like
a common word usually is not one.
### 5. Use real typeface outlines, not hand-rolled letterforms
Hand-drawn geometric letters look like a template and carry bugs. Bake outlines
from a real face with `SKILLS_DIR/scripts/outline.py` and freeze them as path
data: correct contrast and kerning, no webfont request, no flash of fallback
type.
The trade: baked outlines fix the string. If the wordmark text might ever be
localised or edited, say so at the time — it has to stay live text.
### 6. Decide colour by comparison, not theory
Put candidate palettes side by side in the sheet and look. Two colours that are
defensible individually can fight when adjacent — near-complementary pairs
especially. The fix is usually not a different hue but removing one from the
pairing.
### 7. The user picks, at every gate
Never advance a round on your own taste. Present, recommend with reasons, and
wait. Say plainly which candidates you would cut and why — an opinion is useful,
a decision is not yours.
---
## Anti-patterns
| Smell | What it actually means |
| ----- | ---------------------- |
| Every concept shares one skeleton | You produced one concept, *N* times. Go do the reference study |
| All strokes, uniform weight | The generated default. Try solid fills, real type, or no mark at all |
| A mark for its own sake | Plenty of strong identities are type plus one colour. "No mark" is a candidate |
| Judging from the SVG source | You have not seen it. Build the sheet |
| A concept that needs its name explained | If it needs explaining it is not reading. The 16px column is the test |
## Tooling
| Need | Command |
| ---- | ------- |
| Contact sheet + local server | `node SKILLS_DIR/scripts/gallery.mjs <dir> [--port N] [--title T] [--no-serve]` |
| Bake typeface outlines to paths | `uv run --with fonttools --with uharfbuzz python SKILLS_DIR/scripts/outline.py` |
`outline.py` reads a JSON job list on stdin and writes JSON on stdout. Source
faces come from `LOGO_FONT_DIR` (default `.fonts`), or a job may name an absolute
path. See [ship.md](ship.md) for the job shape and the traps.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!