Canvas design decomposition
Mandatory triggers (load this skill first)
Load and follow this skill before proposing component structure for a
component library, writing implementation plans, or implementing
React—including when the user only asks for a plan or
breakdown—whenever you are modeling how UI should split into Canvas
components (a component library, section, or full page). The same
applies when you are about to build, add, or scaffold components (see
below). Treat any of the following as a trigger:
- Building or adding Canvas components: creating new folders under
src/components/, authoring component.yml and index.jsx (or .tsx),
scaffolding a component from a ticket or spec, coding a section from a
design, or implementing a named block (hero, footer, card, and so on).
Decompose before writing schema or React so names, slots, variants, and
reuse stay aligned—unless the task is a trivial one-line tweak inside an
existing, stable API.
- Designing or evolving a component library for Canvas—naming regions,
deciding reuse, props/slots, and granularity—whether the stimulus is a file, a
site, or a conversation.
- The message contains a Figma URL (
figma.com/design, figma.com/make, or
branch URLs) or explicit node-id / frame language tied to Figma.
- The source of truth is an existing website, screenshot, scraped
page, or reference URL meant to drive layout or components (pair with
nebula-scrape-url when a live URL needs
capture).
- The source is text-only or generative: a written brief, markdown spec, or
an AI- / prompt-generated design (layout description, wireframe in words,
component list from a chat). Phase A still applies—classify intake and list
unknowns even when pixels are absent.
- The user asks to implement, build, match, recreate, or plan
implementation of a design, frame, screen, or page from any
artifact or description.
Do not skip (common failure mode)
- Greenfield work is not exempt. Implementing a new page or Figma frame
from scratch still requires this skill—you map the design to a coherent tree,
props, and slots before locking implementation details.
- Draft files in the repo are not a shortcut. Existing
pages/*.json,
partial components under src/components/, or scraped assets may be helpful
starting points, but they do not replace reading this skill and
completing phases A–G for the current artifact. Reconcile draft code
with the breakdown; do not assume prior work already did decomposition.
- Plans count. If the user asks only for an implementation plan, you
still load this skill and summarize regions → components → placement before
pixel work or tooling shortcuts.
Automated tool output (for example Figma MCP reference JSX, HTML export, or
generated code) is input to this workflow—not a substitute for completing
phases A–G.
Turn a design artifact into a stable component model: regions, tree, prop vs
slot decisions, and granularity checks. A breakdown is incomplete without
sketching props and slots for each node—Canvas authors interact with the
tree through that API, so plan it with structure, not after implementation.
During planning, step past the single frame or ticket: ask where else each
piece could appear and what would differ (copy, children, variant). Prefer
reusable machineNames, slots for variable regions, and presets via
variant over one-off names or props that hard-code one campaign’s content.
Do not implement pixels or write component.yml inside this workflow—finish
the structure and prop/slot sketch first, then hand off.
Skill order
- This skill — workflow, tree, and handoff.
canvas-component-composability
— shared props/slots rules, repeatable content, and granularity checks.
canvas-component-metadata — exact
component.yml schema.
canvas-component-definition —
folder contract, mocks, naming authority.
implement-design — pixel-level fidelity
when the source is Figma and after the tree is locked (requires Figma MCP
when used). For non-Figma sources, implement from the locked tree and tokens
without this step unless the user points back to a Figma file.
For repeatable lists/grids in Canvas, see
canvas-component-composability/references/repeatable-content.md.
Inputs
Classify the source in Phase A. Typical categories:
| Kind |
Examples |
| Design tool |
Figma file, frame export, FigJam |
| Live reference |
Existing production or staging site, competitor URL |
| Captured media |
Screenshots, PDFs, brand decks |
| Structured scrape |
HTML/CSS snapshot via tooling |
| Prompt / prose |
User brief, AI-generated layout description, markdown wireframe |
Optional helpers:
Workflow (mandatory)
Complete phases A → G in order. Each phase has an exit criterion. If
Phase F fails, fix the tree and re-run Phase E for affected nodes only.
Phase A — Intake and framing
- Identify input type: design file (e.g. Figma), live site / scrape, screenshot,
or text-only / prompt-generated spec.
- List unknowns: breakpoints, empty states, max copy length, media aspect
ratios, hover/focus/active, accessibility expectations.
- Tag each unknown with risk: low / medium / high (edits likely to churn
structure).
Exit: Input type stated; unknowns listed with risk (workflow continues even
if some answers are missing).
Phase B — Region map
- Divide the design into regions (e.g. header, hero, content band, sidebar,
footer, modal chrome).
- For each region: label, purpose (one line), class —
chrome
(shell), navigation, or content.
Exit: Ordered region list with purpose and class for each.
Phase C — Candidate component inventory
- Map regions to candidate
machineName values (kebab-case folder names per
canvas-component-definition).
- Prefer reusable base names; variants via props/composition, not extra
component names, unless truly one-off.
- Mark reuse count when the same pattern appears two or more times.
- Generalize: For each candidate, note other plausible contexts (other
pages, shorter copy, different children). If it only makes sense for this one
screen, rename or decompose until it is reusably scoped.
Exit: Table: candidate machineName, responsibility, reuse count, parent
region.
Phase D — Component tree
- Build parent/child relationships: layout shells vs content leaves.
- Layout ownership: multi-column grids, page-level stacks, and section
wrappers belong in layout-oriented components; avoid baking unrelated grids
into content components unless the layout is invariant for every instance.
- Express the tree as a nested outline or Mermaid diagram (Mermaid node IDs: no
spaces; use camelCase or underscores).
Exit: Tree covers every inventory row; layout vs content roles are explicit.
Phase E — Props vs slots (per node)
Required: Every decomposition includes this phase. Props and slots are not a
late add-on—they define how editors use the tree. For each tree node,
sketch:
- Props: configuration and simple values editors should set directly
(variants, booleans, short strings, URLs, enums). Note intent and broad type
class (
string, boolean, enum, image/reference)—not final YAML. Follow
canvas-component-composability
for the actual props-vs-slots rubric, variants-vs-granular guidance, and prop
ordering. This phase records the decision; it does not redefine that rubric.
- Slots: areas where authors compose child components or arbitrary blocks.
Name the slot, describe allowed content, and note empty behavior
(collapse, placeholder, min height).
- Implementation style: record
variants (default) or granular props with
a one-line rationale in the handoff. For the Phase E write-up convention, see
references/props-vs-slots-rubric.md.
Exit: Every node has a prop/slot sketch, implementation style is stated, and
repeatable rich children are not modeled as object arrays in props.
Phase F — Granularity audit
Run the shared granularity checklist in
canvas-component-composability.
In this phase, audit the candidate tree against that shared rule set and record
the result; do not create a second split/merge rubric here. For the Phase F
audit note, see references/granularity.md.
- Mark each node pass/fail with a short rationale.
- If any node fails, merge, split, or extract, then repeat Phase E for changed
nodes only.
- Document intentional exceptions explicitly.
Exit: All nodes pass or failures are documented with explicit rationale.
Phase G — Handoff
Deliver one Markdown artifact using the template below. Point next steps to:
Exit: Filled template ready to paste into an issue or MR.
Out of scope here: page JSON
(canvas-page-definition), validation
runs (nebula-component-validation).
Output template
Copy and fill:
## Summary
- **Design source:** (e.g. Figma URL | live URL | screenshots | prompt/spec
text)
- **Scope:** (single component | section | full page)
- **Version / date:**
## Assumptions and open questions
- ...
## Region map
| Region | Purpose | Class |
| ------ | ------- | ----- |
| ... | ... | ... |
## Component inventory
| machineName (candidate) | Responsibility | Reuse | Parent region | Notes |
| ----------------------- | -------------- | ----- | ------------- | ----- |
| ... | ... | ... | ... | ... |
## Component tree
(Nested list or Mermaid)
## API sketch (per component)
### `machine-name`
**Implementation style:** variants (default) | granular props — one-line
rationale
**Props** (table rows in editor order: **variant first** when there is a single
primary variation enum; **content first** otherwise—then configuration)
| Name (camelCase intent) | Purpose | Required? | Kind (string / bool / enum / …) |
| ----------------------- | ------- | --------- | ------------------------------- |
| ... | ... | ... | ... |
**Slots**
| Slot key | Purpose | Empty behavior |
| -------- | ------- | -------------- |
| ... | ... | ... |
## Granularity audit
| Component / node | Pass/Fail | Notes / fix |
| ---------------- | --------- | ----------- |
| ... | ... | ... |
## Next steps
- [ ] `canvas-component-composability` — edge cases for props/slots,
repeatability, or granularity
- [ ] `canvas-component-metadata` — draft `component.yml`
- [ ] `canvas-component-definition` — folder, `index.jsx`, mocks
- [ ] `implement-design` — Figma fidelity pass (only when matching a Figma file)
Further reading
Anti-duplication
1---2name: canvas-design-decomposition3description: Plans structure for a component library with props/slots and right-sized component granularity. Run before building or adding Canvas components (new `src/components/` folders, component.yml, React), or for plan-only / breakdown-only work, whenever UI must map to a coherent tree. Mandatory for every new Figma frame or greenfield screen—repository drafts do not replace phases A–G.4---56# Canvas design decomposition78## Mandatory triggers (load this skill first)910Load and follow **this** skill **before** proposing component structure for a11component library, writing implementation plans, or implementing12React—**including** when the user only asks for a **plan** or13**breakdown**—whenever you are modeling **how** UI should split into Canvas14components (a **component library**, **section**, or **full page**). The same15applies when you are about to **build, add, or scaffold components** (see16below). Treat any of the following as a trigger:1718- **Building or adding Canvas components:** creating new folders under19 `src/components/`, authoring `component.yml` and `index.jsx` (or `.tsx`),20 **scaffolding** a component from a ticket or spec, **coding** a section from a21 design, or **implementing** a named block (hero, footer, card, and so on).22 Decompose **before** writing schema or React so names, slots, variants, and23 reuse stay aligned—unless the task is a trivial one-line tweak inside an24 existing, stable API.25- **Designing or evolving a component library** for Canvas—naming regions,26 deciding reuse, props/slots, and granularity—whether the stimulus is a file, a27 site, or a conversation.28- The message contains a **Figma URL** (`figma.com/design`, `figma.com/make`, or29 branch URLs) or explicit **node-id** / frame language tied to Figma.30- The source of truth is an **existing website**, **screenshot**, **scraped31 page**, or **reference URL** meant to drive layout or components (pair with32 [`nebula-scrape-url`](../nebula-scrape-url/SKILL.md) when a live URL needs33 capture).34- The source is **text-only or generative**: a written brief, markdown spec, or35 an **AI- / prompt-generated design** (layout description, wireframe in words,36 component list from a chat). Phase A still applies—classify intake and list37 unknowns even when pixels are absent.38- The user asks to **implement**, **build**, **match**, **recreate**, or **plan39 implementation** of a **design**, **frame**, **screen**, or **page** from any40 artifact or description.4142### Do not skip (common failure mode)4344- **Greenfield work is not exempt.** Implementing a **new** page or Figma frame45 from scratch still requires this skill—you map the design to a coherent tree,46 props, and slots before locking implementation details.47- **Draft files in the repo are not a shortcut.** Existing `pages/*.json`,48 partial components under `src/components/`, or scraped assets may be helpful49 **starting points**, but they do **not** replace reading this skill and50 completing phases **A–G** for the **current** artifact. Reconcile draft code51 with the breakdown; do not assume prior work already did decomposition.52- **Plans count.** If the user asks only for an implementation **plan**, you53 still load this skill and summarize regions → components → placement before54 pixel work or tooling shortcuts.5556Automated tool output (for example **Figma MCP reference JSX**, HTML export, or57generated code) is **input** to this workflow—not a substitute for completing58phases **A–G**.5960Turn a design artifact into a **stable component model**: regions, tree, prop vs61slot decisions, and granularity checks. A breakdown is **incomplete** without62sketching **props and slots** for each node—Canvas authors interact with the63tree through that API, so plan it **with** structure, not after implementation.6465During planning, **step past the single frame or ticket**: ask where else each66piece could appear and what would differ (copy, children, `variant`). Prefer67reusable `machineName`s, slots for variable regions, and presets via68**`variant`** over one-off names or props that hard-code one campaign’s content.6970**Do not** implement pixels or write `component.yml` inside this workflow—finish71the structure and prop/slot sketch first, then hand off.7273## Skill order74751. **This skill** — workflow, tree, and handoff.762. [`canvas-component-composability`](../canvas-component-composability/SKILL.md)77 — shared props/slots rules, repeatable content, and granularity checks.783. [`canvas-component-metadata`](../canvas-component-metadata/SKILL.md) — exact79 `component.yml` schema.804. [`canvas-component-definition`](../canvas-component-definition/SKILL.md) —81 folder contract, mocks, naming authority.825. [`implement-design`](../implement-design/SKILL.md) — pixel-level fidelity83 **when the source is Figma** and after the tree is locked (requires Figma MCP84 when used). For non-Figma sources, implement from the locked tree and tokens85 without this step unless the user points back to a Figma file.8687For repeatable lists/grids in Canvas, see88[`canvas-component-composability/references/repeatable-content.md`](../canvas-component-composability/references/repeatable-content.md).8990## Inputs9192Classify the source in Phase A. Typical categories:9394| Kind | Examples |95| --------------------- | --------------------------------------------------------------- |96| **Design tool** | Figma file, frame export, FigJam |97| **Live reference** | Existing production or staging site, competitor URL |98| **Captured media** | Screenshots, PDFs, brand decks |99| **Structured scrape** | HTML/CSS snapshot via tooling |100| **Prompt / prose** | User brief, AI-generated layout description, markdown wireframe |101102Optional helpers:103104- URL capture: [`nebula-scrape-url`](../nebula-scrape-url/SKILL.md) (not for105 Figma or docs).106- Figma fidelity pass (after decomposition):107 [`implement-design`](../implement-design/SKILL.md).108109## Workflow (mandatory)110111Complete phases **A → G** in order. Each phase has an **exit criterion**. If112Phase F fails, fix the tree and re-run Phase E for affected nodes only.113114### Phase A — Intake and framing115116- Identify input type: design file (e.g. Figma), live site / scrape, screenshot,117 or text-only / prompt-generated spec.118- List **unknowns**: breakpoints, empty states, max copy length, media aspect119 ratios, hover/focus/active, accessibility expectations.120- Tag each unknown with **risk**: low / medium / high (edits likely to churn121 structure).122123**Exit:** Input type stated; unknowns listed with risk (workflow continues even124if some answers are missing).125126### Phase B — Region map127128- Divide the design into **regions** (e.g. header, hero, content band, sidebar,129 footer, modal chrome).130- For each region: **label**, **purpose** (one line), **class** — `chrome`131 (shell), `navigation`, or `content`.132133**Exit:** Ordered region list with purpose and class for each.134135### Phase C — Candidate component inventory136137- Map regions to **candidate** `machineName` values (kebab-case folder names per138 [`canvas-component-definition`](../canvas-component-definition/SKILL.md)).139- Prefer reusable base names; variants via props/composition, not extra140 component names, unless truly one-off.141- Mark **reuse count** when the same pattern appears two or more times.142- **Generalize:** For each candidate, note **other plausible contexts** (other143 pages, shorter copy, different children). If it only makes sense for this one144 screen, rename or decompose until it is **reusably** scoped.145146**Exit:** Table: candidate `machineName`, responsibility, reuse count, parent147region.148149### Phase D — Component tree150151- Build parent/child relationships: **layout shells** vs **content leaves**.152- **Layout ownership:** multi-column grids, page-level stacks, and section153 wrappers belong in layout-oriented components; avoid baking unrelated grids154 into content components unless the layout is invariant for every instance.155- Express the tree as a nested outline or Mermaid diagram (Mermaid node IDs: no156 spaces; use camelCase or underscores).157158**Exit:** Tree covers every inventory row; layout vs content roles are explicit.159160### Phase E — Props vs slots (per node)161162**Required:** Every decomposition includes this phase. Props and slots are not a163late add-on—they define how editors use the tree. For **each** tree node,164sketch:165166- **Props:** configuration and simple values editors should set directly167 (variants, booleans, short strings, URLs, enums). Note intent and broad type168 class (`string`, `boolean`, `enum`, image/reference)—not final YAML. Follow169 [`canvas-component-composability`](../canvas-component-composability/SKILL.md)170 for the actual props-vs-slots rubric, variants-vs-granular guidance, and prop171 ordering. This phase records the decision; it does not redefine that rubric.172- **Slots:** areas where authors compose child components or arbitrary blocks.173 Name the slot, describe allowed content, and note **empty** behavior174 (collapse, placeholder, min height).175- **Implementation style:** record `variants` (default) or `granular props` with176 a one-line rationale in the handoff. For the Phase E write-up convention, see177 [references/props-vs-slots-rubric.md](references/props-vs-slots-rubric.md).178179**Exit:** Every node has a prop/slot sketch, implementation style is stated, and180repeatable rich children are not modeled as object arrays in props.181182### Phase F — Granularity audit183184Run the shared granularity checklist in185[`canvas-component-composability`](../canvas-component-composability/SKILL.md).186In this phase, audit the candidate tree against that shared rule set and record187the result; do not create a second split/merge rubric here. For the Phase F188audit note, see [references/granularity.md](references/granularity.md).189190- Mark each node pass/fail with a short rationale.191- If any node fails, merge, split, or extract, then repeat Phase E for changed192 nodes only.193- Document intentional exceptions explicitly.194195**Exit:** All nodes pass or failures are documented with explicit rationale.196197### Phase G — Handoff198199Deliver one Markdown artifact using the template below. Point **next steps** to:200201- Schema: [`canvas-component-metadata`](../canvas-component-metadata/SKILL.md)202- Composition edge cases:203 [`canvas-component-composability`](../canvas-component-composability/SKILL.md)204- Contract and mocks:205 [`canvas-component-definition`](../canvas-component-definition/SKILL.md)206- Visual fidelity from Figma: [`implement-design`](../implement-design/SKILL.md)207 (when applicable)208209**Exit:** Filled template ready to paste into an issue or MR.210211**Out of scope here:** page JSON212([`canvas-page-definition`](../canvas-page-definition/SKILL.md)), validation213runs ([`nebula-component-validation`](../nebula-component-validation/SKILL.md)).214215## Output template216217Copy and fill:218219```markdown220## Summary221222- **Design source:** (e.g. Figma URL | live URL | screenshots | prompt/spec223 text)224- **Scope:** (single component | section | full page)225- **Version / date:**226227## Assumptions and open questions228229- ...230231## Region map232233| Region | Purpose | Class |234| ------ | ------- | ----- |235| ... | ... | ... |236237## Component inventory238239| machineName (candidate) | Responsibility | Reuse | Parent region | Notes |240| ----------------------- | -------------- | ----- | ------------- | ----- |241| ... | ... | ... | ... | ... |242243## Component tree244245(Nested list or Mermaid)246247## API sketch (per component)248249### `machine-name`250251**Implementation style:** variants (default) | granular props — one-line252rationale253254**Props** (table rows in editor order: **variant first** when there is a single255primary variation enum; **content first** otherwise—then configuration)256257| Name (camelCase intent) | Purpose | Required? | Kind (string / bool / enum / …) |258| ----------------------- | ------- | --------- | ------------------------------- |259| ... | ... | ... | ... |260261**Slots**262263| Slot key | Purpose | Empty behavior |264| -------- | ------- | -------------- |265| ... | ... | ... |266267## Granularity audit268269| Component / node | Pass/Fail | Notes / fix |270| ---------------- | --------- | ----------- |271| ... | ... | ... |272273## Next steps274275- [ ] `canvas-component-composability` — edge cases for props/slots,276 repeatability, or granularity277- [ ] `canvas-component-metadata` — draft `component.yml`278- [ ] `canvas-component-definition` — folder, `index.jsx`, mocks279- [ ] `implement-design` — Figma fidelity pass (only when matching a Figma file)280```281282## Further reading283284- [`canvas-component-composability`](../canvas-component-composability/SKILL.md)285- [references/granularity.md](references/granularity.md)286- [references/props-vs-slots-rubric.md](references/props-vs-slots-rubric.md)287- [references/worked-example.md](references/worked-example.md)288289## Anti-duplication290291- Do not restate full `component.yml` grammar—use292 [`canvas-component-metadata`](../canvas-component-metadata/SKILL.md).293- Do not restate the reusable props/slots or granularity rulebooks here—link294 [`canvas-component-composability`](../canvas-component-composability/SKILL.md).