.claude/skills/figma-diff-section/SKILL.md

Figma Diff Section Pipeline

Run the full Figma → diff → plan pipeline for one section. Fetches fresh data, extracts structure, diffs against code, and synthesizes an implementation plan.

Figma Diff Section Pipeline

Run the full pipeline for one section. The argument is a Figma URL (https://www.figma.com/design/...?node-id=XXXX-YYYY) or a raw node ID (XXXX:YYYY).

Prerequisites

  • FIGMA_TOKEN env var set

Steps

1. Fetch

Fetch the section node via the Figma REST API and save to figma-cache/:

curl -sH "X-Figma-Token: $FIGMA_TOKEN" \
  "https://api.figma.com/v1/files/{fileKey}/nodes?ids={nodeId}&geometry=paths" \
  -o figma-cache/<section-slug>.json

Extract the fileKey and nodeId from the Figma URL. Node IDs use : in the API (e.g. 10018:95883) but - in URLs (e.g. node-id=10018-95883).

2. Extract

python3 .claude/skills/figma-diff-section/extract-structure.py figma-cache/<section-slug>.json

This writes figma-cache/<section-slug>-structure.json with:

  • Noise stripped (geometry, invisible nodes, vectors)
  • Variable tokens resolved (e.g. new-base/primary)
  • Typography style tokens resolved (e.g. Body/Emphasized)

3. Diff

For each screen (or logical screen group) in the structure JSON, compare it against the source code and write a diff report.

How to read the structure JSON

Each node has:

  • fills[].token — design token name (e.g. new-base/primary). If tokenized: true, it's bound to a variable; if false, it's hardcoded.
  • fontSize, fontWeight, lineHeightPx — each is {value, tokenized, token}
  • textStyle — typography style name (e.g. Body/Emphasized, Callout/Regular) when a text style is applied. This means the font is tokenized via a style, even if fontSize.tokenized is false.
  • cornerRadius, paddingTop/Right/Bottom/Left, itemSpacing, layoutMode — layout props, each {value, tokenized, token}
  • strokes[].token — border color token

Component instances and overrides

When a node has type: "INSTANCE", it is a placed instance of a Figma component. Overrides are the most important signal on instance nodes.

  • componentId — the base component being used
  • overrides — array of {id, overriddenFields} listing which child nodes have been customized away from the component default

How to use this:

  • If overrides is absent or empty → the instance uses the component's default values exactly. Do not infer custom styling from child node values alone.
  • If overrides is present → only the listed fields on the listed child IDs are intentionally customized. Everything else is the component default.
  • Multiple instances of the same componentId with different overrides = different states of the same component.

What to compare

For each screen: read the Figma JSON, then read the source files, then diff:

  • Typography: fontSize, fontWeight, lineHeight, textStyle, textAlignHorizontal (omitted in JSON when LEFT — treat absence as LEFT)
  • Colors: fills and strokes — use token name if tokenized, hex if not
  • Spacing: padding, gap (itemSpacing), margin
  • Border: cornerRadius, strokeWidth, strokeStyle
  • Layout: layoutMode, alignment, sizing

Diff output rules

  • Only report actual differences — skip things that match.
  • Format each finding as: - **[ComponentName:lineNumber]** Description — \current value` → `figma value` (token: `token-name` if tokenized)`
  • Items needing designer/product confirmation: add ⚠️ confirm
  • Write diff reports to docs/figma-diffs/

4. Synthesize

Read all diff reports for this section and produce a single deduplicated implementation plan.

Deduplication rules

  • If the same finding appears across multiple screens (e.g. fontSize change in every screen), list it ONCE under a "Shared" section
  • Designer annotations override or supplement diff findings — mark them as must-do
  • Items flagged ⚠️ confirm in diffs go into "Flagged for review"

Plan output format

# [Section] — Implementation Plan

## Designer annotations (must-do)
- [ ] **[File:line]**: Description — *"exact annotation text"*

## Diff findings (confirmed)

### Shared layout & structure
### Shared typography
### [other logical groupings]

## Flagged for review
- [ ] **Item**: what needs a decision before implementing

## Out of scope / ignore

Synthesis rules

  • Every finding must reference ComponentName:lineNumber with currentfigma value
  • Use token names where diffs show tokenized values
  • Do NOT invent findings not present in the diff reports or annotations
  • Do NOT include findings about keyboard rendering, dark mode, or anything the diffs mark as out of scope

Write the plan to docs/figma-diffs/<section-slug>-plan.md.

Notes

  • Re-running is safe — all outputs are overwritten