All the Possibles

A finished skill, with the test that shows it working.

A product designer at a small software company wanted every handoff spec to use the team's component names, list states in one fixed order, and never invent a spacing value outside the token set. This is the skill we built from that brief, and below it are the two prompts we ran in Claude Code on this machine: the one it should fire on, and the one it should leave alone.

The brief, as answered in the interview.

What should the assistant do differently when this skill is on?

When I ask for a handoff spec, write it with our component names (Button, TextField, Select, Toast, Modal, Card, Tabs, Table), list the states for every component in this order: default, hover, focus, active, disabled, loading, error, empty, and only use spacing values from our token set. If a spacing value is not in the set, say so and ask instead of inventing one.

When should it kick in?

write the handoff spec, spec this out for the devs, handoff for the settings screen, write up the states for this component

An output you were happy with

A TextField block that names the component as the library does, lists all eight states in order with n/a where a state does not apply, and gives the gap as space-2 (8).

An output you were unhappy with, and what was wrong

It wrote Primary CTA button instead of Button variant=primary, listed the states as normal, hovered, pressed, and specified 14px padding when our tokens are space-2 (8), space-3 (12) and space-4 (16).

Rules it must never break

Never invent a spacing value. Never rename a component. Ask before adding a state that is not on the list. No Title Case in labels or buttons.

Which tool will run it?

Claude Code

The folder that was installed.

handoff-spec/SKILL.md

---
name: handoff-spec
description: Use when asked to write a handoff spec, spec a screen or component for engineers, write up the states, or hand something off to the devs. Writes the spec with the team's component names, lists every state in the fixed order, and uses only spacing values from the token set.
---

# Handoff spec in our names, our state order, our tokens

## Purpose

Every handoff spec from this team reads the same way: the components are called what the library calls them, the states appear in one fixed order so engineers can diff specs against each other, and every spacing value is a token that exists. This skill makes the assistant write specs that way without being reminded.

## When to use

- The request contains "handoff", "hand off", "spec", "spec this out", "write up the states", or "for the devs" and refers to a screen, flow or component.
- A Figma link or a description of a screen is given and the person wants engineers to build from it.

## When not to use

- Release notes, changelogs, PR descriptions, or marketing copy about a screen. Those are not specs.
- Design critique or review. Use the critique method instead.
- Naming a brand-new component that does not exist in the library yet. Ask first; do not invent a name.

## Steps

1. Read `references/components.md` for the component names and `references/tokens.md` for the spacing set. These are the only names and values the spec may use.
2. List the components on the screen, each by its library name exactly as written (for example `Button`, `TextField`, `Toast`). If the design shows something the library does not have, say so in an "Open questions" section and describe it in plain words instead of naming it.
3. For each component, write the states in this order, every time, skipping none: default, hover, focus, active, disabled, loading, error, empty. If a state does not apply, write the state name followed by "n/a" so the order stays visible.
4. For every spacing value, use a token from `references/tokens.md` (for example `space-3`, with the pixel value in brackets once). If the design shows a measurement that matches no token, write "not in tokens: 14px, nearest space-3 (12) or space-4 (16), needs a decision" instead of using 14px.
5. Write labels and button text in sentence case.
6. End with "Open questions": anything you could not resolve from the design or the references.

## Good example

```
TextField (email)
- default: label "Email", placeholder empty, border color-border
- hover: border color-border-strong
- focus: 2px ring color-focus, offset space-1 (4)
- active: n/a
- disabled: text color-fg-muted, no border change
- loading: n/a
- error: helper text below in color-danger, gap space-2 (8)
- empty: n/a
```

Why it is good: the component is named as the library names it, all eight states appear in order, and every spacing value is a token.

## Bad example

```
Primary CTA button
- normal, hovered, pressed
- padding 14px 20px
```

Why it is bad: "Primary CTA button" is not a component name (the library has `Button` with `variant=primary`); the states are renamed and three are missing; 14px and 20px are not in the token set.

## Hard rules

- Never invent a spacing value. If it is not in `references/tokens.md`, flag it and ask.
- Never rename a component. Use the library name or ask.
- Never reorder, rename or drop a state from the fixed list.
- No Title Case in labels or buttons.
- Do not add a ninth state without asking.

references/components.md

# Component names (use exactly these)

Button (variant=primary | secondary | ghost | danger; size=sm | md | lg)
TextField (type=text | email | password | number)
TextArea
Select
Checkbox
Radio
Switch
Tabs
Table
Card
Modal
Toast (tone=info | success | warning | danger)
Tooltip
Badge
Avatar
EmptyState
Pagination

references/tokens.md

# Spacing tokens (the only spacing values allowed)

space-0: 0
space-1: 4px
space-2: 8px
space-3: 12px
space-4: 16px
space-5: 24px
space-6: 32px
space-7: 48px
space-8: 64px

# Color tokens referenced in specs

color-border, color-border-strong, color-focus, color-fg, color-fg-muted, color-danger, color-bg, color-bg-raised

The free draft from the same answers has the same seven sections. What the built version changed: the description was condensed so the trigger words read as one sentence and the second sentence says what the skill does instead of repeating the brief; the steps were rewritten so each is one action (the draft's first step was the whole brief on one line) and the state list gained the rule to write n/a rather than skip; the component names and tokens moved into reference files so the assistant reads them instead of remembering them; and "When not to use" names release notes and critique so the near-miss prompt stays quiet.

The two test prompts, run in Claude Code.

Should fire

Write the handoff spec for the notification settings screen: a list of six toggles with a label and a one-line description each, and a Save button at the bottom. Design shows 14px between the toggle rows.

It fired. The first thing the assistant did was call the Skill tool with handoff-spec, then it read both reference files.

[tool: Skill {"skill":"handoff-spec"}]

[tool: Read {"file_path":".claude/skills/handoff-spec/references/components.md"}]

[tool: Read {"file_path":".claude/skills/handoff-spec/references/tokens.md"}]

# Notification settings: handoff spec

## Screen structure

The screen is a vertical list of six rows, then a `Button` at the bottom. Each row holds a text block (a label with a one-line description beneath it) and a `Switch`. The library has no list-row component, so the row is described in plain words (see Open questions).

Spacing between rows: not in tokens: 14px, nearest space-3 (12) or space-4 (16), needs a decision.

## Components

### Switch (x6, one per row)

- default: off or on, mirrors the saved preference; track and thumb per library default
- hover: pointer cursor, track shifts to the library hover treatment
- focus: 2px ring color-focus, offset space-1 (4px), visible on keyboard focus only
- active: thumb in its pressed position, no layout shift
- disabled: n/a
- loading: n/a
- error: n/a
- empty: n/a

### Button (variant=primary, size=md)

Label: "Save changes". Sits at the bottom of the list. Its gap from the last row is not specified in the design (see Open questions).

- default: primary fill, label in sentence case
- hover: library hover treatment for primary
- focus: 2px ring color-focus, offset space-1 (4px)
- active: library pressed treatment for primary
- disabled: text color-fg-muted; applies while no toggle differs from the saved state, if engineering agrees (see Open questions)
- loading: label replaced by the library spinner, width held, clicks ignored
- error: n/a
- empty: n/a

## Open questions

1. **Row gap.** The design shows 14px between toggle rows. That value is not in the token set. Choose space-3 (12px) or space-4 (16px), or add a token. I haven't used 14px anywhere.
2. **Copy.** The brief gives no label or description text for the six toggles. I need the real strings, in sentence case, one line each. Please also confirm the behavior when a description is too long for one line (truncate or wrap).
3. **Row component.** The design shows a label-plus-description row with a `Switch`. The library has no matching component, so I haven't named one. Should this be a new component, or composed ad hoc from `Switch` and plain text?
4. **Other spacing.** The design doesn't state the gap between label and description, between text block and `Switch`, or between the last row and the `Button`. Each needs a token.
5. **Save behavior.** Should the `Button` be disabled until something changes? Is there a success or failure confirmation (a `Toast`, for example), or does the screen just return to default? A failed save currently has no state in the design, so `error` is marked n/a for now.
6. **Switch states.** The design shows only default. Please confirm that disabled, loading and error are not needed per toggle (for example, if a channel is blocked at the OS level).

[result success, 5 turns, 15135ms, model claude-sonnet-5-5]
Should not fire

Write the release notes for the notification settings screen we shipped this week: six toggles and a save button.

It stayed quiet. No Skill tool call; the assistant looked at the repository and wrote release notes.

I'll check the repo for the toggle names before writing, so I don't invent them.

[tool: Bash {"command":"cat README.md; ls -R .claude | head -30; git log --oneline | head"}]

The repo has no commits and no notification code, so I don't know the six toggle names or the save behavior. I've left those as bracketed placeholders. Fill them in and the notes are ready to ship.

---

**Release notes: notification settings**
*Week of October 26, 2026*

You can now control what we send you from one screen. Settings has a new Notifications page with six toggles, and you choose which ones stay on.

The toggles are [toggle 1], [toggle 2], [toggle 3], [toggle 4], [toggle 5] and [toggle 6]. Each one controls a single kind of notification, so turning one off doesn't affect the others.

Changes apply when you tap Save. If you leave the page without saving, your previous choices stay in place.

[Add the default state of each toggle here, for example which ones are on for existing accounts.]

---

Four details would make these notes more accurate:

- The six toggle names and what each one controls.
- Whether the toggles default to on or off, and whether that differs for existing users.
- Whether Save confirms with a message, and what happens if it fails.
- Where users find the screen (the menu path), if it isn't Settings > Notifications.

If you paste the PR description or the diff, I can fill these in myself.

[result success, 2 turns, 9106ms, model claude-sonnet-5-5]

How it was run, on October 29, 2026: the folder above was placed at .claude/skills/handoff-spec/ in an otherwise empty project on a Mac, and each prompt was run once, non-interactively, with claude -p from Claude Code 2.1.312 using the sonnet model alias (which resolved to claude-sonnet-5-5), with --output-format stream-json so the tool calls are visible. The transcripts are reduced to the tool calls and the assistant's text; the long path of the test folder is shortened. The first run took 5 turns and about 15 seconds; the second took 2 turns and about 9 seconds. We did not edit the assistant's words.

Worth noticing in the first transcript: the assistant used 14px nowhere, wrote the "not in tokens" line the skill asks for, and listed all eight states for the Switch and the Button in order, with n/a where a state does not apply. It also raised the row component as an open question instead of naming one, which is the rule from the brief.

Yours would look like this, for your rules.

The free interview on the Skill builder page gives you the draft in a minute. The built version is $29: we write it, run both prompts, and send the folder with the transcript and a note on what changed.

Order the built version