figma-codegen
Turn a Figma selection into code that looks like the rest of the project: reuse the components and
tokens that already exist, only build what's genuinely missing. The grounded tools do the heavy
lifting so you are not guessing from a screenshot. This file is the router; deep detail lives in
references/ — load a reference when its step is in play.
When to use
- The user pastes a Figma URL/selection and asks for code ("code this", "build this component").
- The user wants to extend an existing component to match a Figma frame.
More than one Figma file open
Every tool result says so when it applies, so you do not have to check up front: with two or more
files connected and none claimed, results carry a MORE THAN ONE FIGMA FILE IS OPEN block naming
them. It matters because calls otherwise follow whichever file the user last touched, which changes
when they switch tabs — so a task can read one file and write to another and report success.
When you see it, claim the file before doing anything else: list_files names every connected file,
use_file({ fileName }) claims one for this session (use_file({ sessionId }) when two open files
share a name — Figma allows that, and x (Copy) is how it happens). Every later call then reaches
that file whatever is in front, including while its tab sits in the background. If the user has not
said which file, ask — do not guess from the names.
Workflow
Run the grounded tools against the selection, then generate — trust them over the rendered image.
get_design_context (detail full, dedupeComponents: true) → the structural tree with
tokens resolved to names (Primary/500, spacing/4), styles deduped into globalVars, and each
instance's mainComponent / componentProperties. This is the layout + binding source of truth.
Keep dedupeComponents: true and don't depth-limit a subtree you'll build from.
→ How to read the tree, the per-node fidelity catalog (effects, per-side borders, stroke align,
per-corner radius, blend, masks, gradients, image-fit, auto-layout/grid, aspect-ratio,
scroll/sticky, stack & stroke-space), Dev Mode annotations as ground truth, and grounding a page
too big for one call: references/grounding.md.
component_map → every Figma component grouped to a local code component with a status
(high / medium / low / unmapped), candidate.filePath, and matchedProps.
high / medium: reuse that component (import from candidate.filePath), don't regenerate.
Never invent a component name component_map didn't report.
candidate.ambiguousWith (a capped list of { name, filePath }): the Figma name matched two or
more code components nearly equally and the join couldn't confidently pick — a verify-me pick,
not a confident reuse (the analogue of token_map's ambiguousWith). Check which of the winning
candidate + these runner-ups is the right component for this context before importing (a wrong
reuse is a silent visual bug), then record the confirmed one in the map file so the next run is
certain. Absent when the pick was unambiguous.
- Wire each entry's
instances[].props (resolved variant / boolean / text values) onto the reused
component — one element per instance, with its own props.
candidate.unmatchedProps: Figma axes the component has no prop for (a leading icon, a required
flag, an active state) → surface as component-extension TODOs, never fake them with ad-hoc markup.
unmapped: build it new in the project's style. For a repeated unmapped component
(instanceCount > 1), build from its first instance's subtree; if that came back
deduped/truncated, drill get_design_context on instances[0].nodeId once — don't rebuild a
repeated component by eye.
- When you're emitting a component's own definition (its prop types, not just rendering it),
get_component_api on the component/instance returns the full property API — every VARIANT option
and each BOOLEAN/TEXT/INSTANCE_SWAP prop with its default — so the prop space is grounded, not
inferred from the instances you happened to see.
token_map → every Figma variable joined to a project token with status + ref + matchedBy.
A document's shared paint styles (single solid color styles — the token mechanism of
pre-variables files) join the same way, marked source: 'style'.
- mapped: reference
candidate.ref (bg-primary-500, var(--color-primary-500)) — never the raw
hex/px get_design_context resolved. matchedBy: ['name'] on a colour (value drifted): use it
but flag the mismatch.
candidate.ambiguousWith (several project tokens share that exact value and the name couldn't
split them): a capped, verify-me pick — choose the semantically right sibling for the context
(or keep the value and flag the gap), never treat it as a confirmed reuse.
- On a document with few or no variables (most real-world files),
get_design_context's own
projectTokens map is the fallback: any raw color in the payload that exactly equals a project
token's value is annotated there ({ "#6266F0": { ref, name, matchedBy: ["value"] } }). Before
hardcoding a hex, look it up and emit the ref when it fits the context semantically.
matchedBy: ["value"] marks the entry as name-blind value-equality evidence — a hypothesis to
verify, not a resolved binding: an entry with candidates lists same-value tokens to choose
between by meaning, a semantically wrong token is worse than the raw value (keep the raw
value and note the gap instead), and a bound Figma variable always outranks a raw-value match.
framework-builtin (a built-in scale step of the project's utility framework — Tailwind or
UnoCSS — e.g. spacing/4, line-height/7, weight/Bold): carries builtin: { scale, step }
— compose the utility (p-4/gap-4, leading-7, font-bold), not an arbitrary
p-[16px]. This is not a gap.
from (a SCSS variable): the ref does not resolve on its own. The file you write must
import the declaring file, and from is repo-relative while Sass resolves @use against
the importing file — so re-resolve it from where you are writing: from
src/components/card.scss, from: src/styles/_tokens.scss becomes
@use '../styles/tokens' as *, never the repo-relative path verbatim. as * keeps the ref as
given; the project's own @use style may namespace it instead (@use '../styles/tokens' makes
$color-primary-500 into tokens.$color-primary-500). Emitting the ref without the import is
a compile error, not a style nit.
unmapped: use the value but call out the gap (offer to add it to the token source); don't
hardcode silently.
figmaModes ({ Light: …, Dark: … }, with the file's theme axes on themedCollections): the
token is theme-dependent — figmaValue is only the default mode, never the whole story.
Mapped: emit candidate.ref and confirm the project token itself switches per theme (.dark /
[data-theme] / prefers-color-scheme / a dark: story); if the project defines only one
value, wire the other mode's value into that mechanism or surface a theme gap. Unmapped: the
default mode is the base, other modes ride the project's dark-mode mechanism (dark: variants /
prefers-color-scheme). Themes encoded without native modes — paired collections or name
groups (Color/Light/* + Color/Dark/*, a plan-limited workaround) — get the same treatment.
Export the assets grounding can't carry — logos, photos, icons have no pixels and otherwise
render as grey blocks. save_image_fills for IMAGE-fill nodes (the original asset, not a
clipped re-render), icon_map first for icons (reuse curated .svgs), get_screenshot only for
the composited look.
→ Full asset/icon/svg/colour-contract workflow:
references/assets-and-icons.md.
Then emit code in the detected stack (the profile comes back on component_map / token_map; you do
not call analyze_project yourself): compose the reused components, wrap unmapped pieces, and apply
token references for colour/spacing/radius/typography.
Keep code in sync as the design changes
Codegen is rarely one-shot — the design keeps moving. To make the second pass an incremental edit
instead of a regeneration:
- After you generate,
design_diff on the section/component nodeId saves a baseline (its
get_design_context) under .figwright/snapshots/. Committing that file lets teammates share the
baseline; the tool never touches git.
- When asked to re-sync ("the design changed, update the component"),
design_diff the same
nodeId again: it returns the per-node, per-property delta — added / removed / changed nodes
with resolved values (a fill, a padding, a text string, a token rebind), each with a readable path
(Card / Header / Title). Edit only the code those nodes map to; don't regenerate the screen.
Ground each changed value the usual way (it's a get_design_context slice), then design_diff with
update: true to accept the new design as the baseline.
- Scope it by the same
nodeId unit you coded from. no-changes means the design is untouched since
the baseline — nothing to do.
Record verified mappings (so the next run reuses, not re-guesses)
The joins re-derive from scratch every run. A mapping you confirmed — reused a component and it
rendered right, resolved an ambiguous colour to the semantically correct token — is worth recording
so the next run treats it as ground truth instead of re-guessing. Two append-only map files, each read
back by its join as highest authority:
docs/figma-component-map.md — rows | FigmaName | code/path | (or FigmaName -> path).
component_map then returns that component as source: 'map-file', confidence 1.
docs/figma-token-map.md — rows | FigmaName | ref |. token_map returns it as
matchedBy: ['map-file'], confidence 1. The ref is what you'd emit — a utility (bg-primary-500),
a var(--color-primary-500), or the bare token name.
A recorded row OVERRIDES the fuzzy join on every future run — so record proof, not a pick. The
gate is your own verify step (§ Responsive & verify): only after you rendered the result and it
matched the Figma node do you record the mapping you proved. A wrong row doesn't fail loudly — it
silently mis-maps that component/token in every future generation until a human notices, which is
worse than no record at all. If you're not certain, don't record it; a re-guess next run is
recoverable, a confidently-wrong recorded row is not.
Record only the mappings the join was unsure of — a low/medium component match you
confirmed, an unmapped component you built (record its new file), or a token that came back
ambiguousWith / matchedBy: ['value'] / unmapped and you resolved by meaning. Skip the
already-high deterministic matches; they re-derive correctly and a row for them is just noise.
These files are committed project docs — treat a row like a line of code you're asserting is
correct, not a scratch note. One figma name → one target per row; keep them reviewable.
Keep the files healthy. When component_map / token_map report staleOverrides (a recorded
target that no longer resolves — the file/token was renamed or deleted), the join has already
degraded to the fuzzy result; fix that row to the new target or delete it.
Responsive & verify
- Responsive by default — root is
w-full, never the artboard's fixed width; ground breakpoints
from the file's other-width frames. → references/responsive.md.
- Verify visually before you call it done — render with the project's toolchain, screenshot at the
design's viewport, diff against the Figma node, fix at the source.
→
references/verify.md.
Motion (animation)
When get_design_context (full detail) tags a node with a motion summary — applied
animation-style presets, animated property fields, a timeline duration — carry it into the project's
animation mechanism (CSS @keyframes / transition, Framer Motion, GSAP, Vue <transition>) instead
of emitting a static component. get_node_motion returns the full keyframe detail when the summary
isn't enough. Dropping a frame's animation is a fidelity miss, the same class as dropping a shadow.
→ references/motion.md.
Rules
- Ground every section — never eyeball a value off the screenshot. Every px size, colour,
font-size, radius, and spacing comes from
get_design_context, for every section. The screenshot
is visual intent only; guessing "the easy sections" is the cardinal miss. On a page too big to ground
at once, scope by section nodeId — never depth-cap the whole page, never retry an oversized call.
- Reuse beats regenerate. A
high/medium component_map candidate must be imported and used.
- Reference tokens, not literals. Emit a mapped variable's
ref; reserve raw values for unmapped
gaps, and surface those gaps rather than burying them.
- Carry every visual property, don't drop fidelity. Effects, per-side borders +
strokeAlign,
per-corner radius, blend mode, masks, gradients, image scaleMode, and auto-layout/grid spacing are
all in the context — translate each (the catalog is in references/grounding.md). Dropping any is a
grounding miss, not a simplification.
- Export visual assets, don't fake them. A grey box or a hand-typed wordmark is a miss.
- Match the project, not a house style. Mirror the existing import style, file layout, and naming.
- Spell class names in full; don't assemble them from
&. In a language whose & concatenates
(SCSS / Sass / Less / Stylus / postcss-nested) .card { &__title {} } compiles to
.card__title — a name that exists only after
compilation, so the class the markup carries appears nowhere in the source and adjusting one rule
means searching a fragment like __title and reading every hit. Declare it flat at the top level
instead. profile.styling.classNaming (on component_map / token_map) reports the project's own
habit and the project wins: ampersand → write &__title; flat or absent → write flat.
→ references/stylesheets.md for the descendant-selector trap that
looks like the fix and isn't, and what & is still the right tool for.
- Render and verify before you call it done. (See
references/verify.md.)
- Never write a config file or wizard prompt; everything is inferred from the project + the tools.
1---2name: figma-codegen3description: Generate framework-aware code from a Figma design. Reads the project's stack profile and emits code matching the existing framework (React/Vue/Svelte/Next/etc.) and styling (Tailwind/CSS/CSS-in-JS), reusing existing components and design tokens instead of regenerating from scratch. Triggers whenever the user wants a Figma design turned into code — e.g. 'code this design', 'implement this frame', 'build this screen/component', 'turn this Figma into React/Vue', 'convert this design to code' — or whenever a Figma URL or the current Figma selection appears alongside a coding request. Works for full screens, single sections, or one component.4---5
6# figma-codegen
7
8Turn a Figma selection into code that looks like the rest of the project: reuse the components and
9tokens that already exist, only build what's genuinely missing. The grounded tools do the heavy
10lifting so you are not guessing from a screenshot. This file is the router; deep detail lives in
11[`references/`](./references) — load a reference when its step is in play.
12
13## When to use
14
15- The user pastes a Figma URL/selection and asks for code ("code this", "build this component").
16- The user wants to extend an existing component to match a Figma frame.
17
18## More than one Figma file open
19
20Every tool result says so when it applies, so you do not have to check up front: with two or more
21files connected and none claimed, results carry a `MORE THAN ONE FIGMA FILE IS OPEN` block naming
22them. It matters because calls otherwise follow whichever file the user last touched, which changes
23when they switch tabs — so a task can read one file and write to another and report success.
24
25When you see it, claim the file before doing anything else: `list_files` names every connected file,
26`use_file({ fileName })` claims one for this session (`use_file({ sessionId })` when two open files
27share a name — Figma allows that, and `x (Copy)` is how it happens). Every later call then reaches
28that file whatever is in front, including while its tab sits in the background. If the user has not
29said which file, ask — do not guess from the names.
30
31## Workflow
32
33Run the grounded tools against the selection, then generate — **trust them over the rendered image.**
34
351. **`get_design_context`** (detail `full`, `dedupeComponents: true`) → the structural tree with
36 tokens resolved to names (`Primary/500`, `spacing/4`), styles deduped into `globalVars`, and each
37 instance's `mainComponent` / `componentProperties`. This is the layout + binding source of truth.
38 Keep `dedupeComponents: true` and don't depth-limit a subtree you'll build from.
39 → **How to read the tree, the per-node fidelity catalog (effects, per-side borders, stroke align,
40 per-corner radius, blend, masks, gradients, image-fit, auto-layout/grid, aspect-ratio,
41 scroll/sticky, stack & stroke-space), Dev Mode annotations as ground truth, and grounding a page
42 too big for one call: [`references/grounding.md`](./references/grounding.md).**
43
442. **`component_map`** → every Figma component grouped to a local code component with a `status`
45 (high / medium / low / unmapped), `candidate.filePath`, and `matchedProps`.
46 - `high` / `medium`: **reuse that component** (import from `candidate.filePath`), don't regenerate.
47 Never invent a component name `component_map` didn't report.
48 - `candidate.ambiguousWith` (a capped list of `{ name, filePath }`): the Figma name matched two or
49 more code components nearly equally and the join couldn't confidently pick — a **verify-me** pick,
50 not a confident reuse (the analogue of `token_map`'s `ambiguousWith`). Check which of the winning
51 `candidate` + these runner-ups is the right component for _this_ context before importing (a wrong
52 reuse is a silent visual bug), then record the confirmed one in the map file so the next run is
53 certain. Absent when the pick was unambiguous.
54 - Wire each entry's `instances[].props` (resolved variant / boolean / text values) onto the reused
55 component — one element per instance, with its own props.
56 - `candidate.unmatchedProps`: Figma axes the component has no prop for (a leading icon, a `required`
57 flag, an active state) → surface as component-extension TODOs, never fake them with ad-hoc markup.
58 - `unmapped`: build it new in the project's style. For a **repeated** unmapped component
59 (`instanceCount > 1`), build from its **first instance's** subtree; if that came back
60 `deduped`/`truncated`, drill `get_design_context` on `instances[0].nodeId` once — don't rebuild a
61 repeated component by eye.
62 - When you're emitting a component's **own definition** (its prop types, not just rendering it),
63 `get_component_api` on the component/instance returns the full property API — every VARIANT option
64 and each BOOLEAN/TEXT/INSTANCE_SWAP prop with its default — so the prop space is grounded, not
65 inferred from the instances you happened to see.
66
673. **`token_map`** → every Figma variable joined to a project token with `status` + `ref` + `matchedBy`.
68 A document's shared paint styles (single solid color styles — the token mechanism of
69 pre-variables files) join the same way, marked `source: 'style'`.
70 - mapped: reference `candidate.ref` (`bg-primary-500`, `var(--color-primary-500)`) — never the raw
71 hex/px `get_design_context` resolved. `matchedBy: ['name']` on a colour (value drifted): use it
72 but flag the mismatch.
73 - `candidate.ambiguousWith` (several project tokens share that exact value and the name couldn't
74 split them): a capped, verify-me pick — choose the semantically right sibling for the context
75 (or keep the value and flag the gap), never treat it as a confirmed reuse.
76 - On a document with few or no variables (most real-world files), `get_design_context`'s own
77 `projectTokens` map is the fallback: any raw color in the payload that exactly equals a project
78 token's value is annotated there (`{ "#6266F0": { ref, name, matchedBy: ["value"] } }`). Before
79 hardcoding a hex, look it up and emit the `ref` when it fits the context semantically.
80 `matchedBy: ["value"]` marks the entry as name-blind value-equality evidence — a hypothesis to
81 verify, not a resolved binding: an entry with `candidates` lists same-value tokens to choose
82 between by meaning, a semantically wrong token is **worse** than the raw value (keep the raw
83 value and note the gap instead), and a bound Figma variable always outranks a raw-value match.
84 - `framework-builtin` (a built-in scale step of the project's utility framework — Tailwind or
85 UnoCSS — e.g. `spacing/4`, `line-height/7`, `weight/Bold`): carries `builtin: { scale, step }`
86 — compose the utility (`p-4`/`gap-4`, `leading-7`, `font-bold`), **not** an arbitrary
87 `p-[16px]`. This is **not** a gap.
88 - `from` (a SCSS variable): the ref does **not** resolve on its own. The file you write must
89 import the declaring file, and `from` is **repo-relative** while Sass resolves `@use` against
90 the _importing_ file — so re-resolve it from where you are writing: from
91 `src/components/card.scss`, `from: src/styles/_tokens.scss` becomes
92 `@use '../styles/tokens' as *`, never the repo-relative path verbatim. `as *` keeps the ref as
93 given; the project's own `@use` style may namespace it instead (`@use '../styles/tokens'` makes
94 `$color-primary-500` into `tokens.$color-primary-500`). Emitting the ref without the import is
95 a **compile error**, not a style nit.
96 - `unmapped`: use the value but call out the gap (offer to add it to the token source); don't
97 hardcode silently.
98 - `figmaModes` (`{ Light: …, Dark: … }`, with the file's theme axes on `themedCollections`): the
99 token is **theme-dependent** — `figmaValue` is only the default mode, never the whole story.
100 Mapped: emit `candidate.ref` and confirm the project token itself switches per theme (`.dark` /
101 `[data-theme]` / `prefers-color-scheme` / a `dark:` story); if the project defines only one
102 value, wire the other mode's value into that mechanism or surface a theme gap. Unmapped: the
103 default mode is the base, other modes ride the project's dark-mode mechanism (`dark:` variants /
104 `prefers-color-scheme`). Themes encoded without native modes — paired collections or name
105 groups (`Color/Light/*` + `Color/Dark/*`, a plan-limited workaround) — get the same treatment.
106
1074. **Export the assets grounding can't carry** — logos, photos, icons have no pixels and otherwise
108 render as grey blocks. `save_image_fills` for `IMAGE`-fill nodes (the original asset, not a
109 clipped re-render), `icon_map` first for icons (reuse curated `.svg`s), `get_screenshot` only for
110 the composited look.
111 → **Full asset/icon/svg/colour-contract workflow:
112 [`references/assets-and-icons.md`](./references/assets-and-icons.md).**
113
114Then emit code in the detected stack (the profile comes back on `component_map` / `token_map`; you do
115not call `analyze_project` yourself): compose the reused components, wrap unmapped pieces, and apply
116token references for colour/spacing/radius/typography.
117
118## Keep code in sync as the design changes
119
120Codegen is rarely one-shot — the design keeps moving. To make the second pass an incremental edit
121instead of a regeneration:
122
123- **After you generate**, `design_diff` on the section/component `nodeId` saves a baseline (its
124 `get_design_context`) under `.figwright/snapshots/`. Committing that file lets teammates share the
125 baseline; the tool never touches git.
126- **When asked to re-sync** ("the design changed, update the component"), `design_diff` the same
127 `nodeId` again: it returns the per-node, per-property delta — `added` / `removed` / `changed` nodes
128 with resolved values (a fill, a padding, a text string, a token rebind), each with a readable `path`
129 (`Card / Header / Title`). Edit only the code those nodes map to; don't regenerate the screen.
130 Ground each changed value the usual way (it's a `get_design_context` slice), then `design_diff` with
131 `update: true` to accept the new design as the baseline.
132- Scope it by the same `nodeId` unit you coded from. `no-changes` means the design is untouched since
133 the baseline — nothing to do.
134
135## Record verified mappings (so the next run reuses, not re-guesses)
136
137The joins re-derive from scratch every run. A mapping you **confirmed** — reused a component and it
138rendered right, resolved an ambiguous colour to the semantically correct token — is worth recording
139so the next run treats it as ground truth instead of re-guessing. Two append-only map files, each read
140back by its join as highest authority:
141
142- **`docs/figma-component-map.md`** — rows `| FigmaName | code/path |` (or `FigmaName -> path`).
143 `component_map` then returns that component as `source: 'map-file'`, confidence 1.
144- **`docs/figma-token-map.md`** — rows `| FigmaName | ref |`. `token_map` returns it as
145 `matchedBy: ['map-file']`, confidence 1. The `ref` is what you'd emit — a utility (`bg-primary-500`),
146 a `var(--color-primary-500)`, or the bare token name.
147
148- **A recorded row OVERRIDES the fuzzy join on every future run — so record proof, not a pick.** The
149 gate is your own verify step (§ Responsive & verify): only after you rendered the result and it
150 matched the Figma node do you record the mapping you _proved_. A wrong row doesn't fail loudly — it
151 silently mis-maps that component/token in every future generation until a human notices, which is
152 worse than no record at all. If you're not certain, don't record it; a re-guess next run is
153 recoverable, a confidently-wrong recorded row is not.
154- **Record only the mappings the join was unsure of** — a `low`/`medium` component match you
155 confirmed, an `unmapped` component you built (record its new file), or a token that came back
156 `ambiguousWith` / `matchedBy: ['value']` / `unmapped` and you resolved by meaning. Skip the
157 already-`high` deterministic matches; they re-derive correctly and a row for them is just noise.
158- **These files are committed project docs — treat a row like a line of code you're asserting is
159 correct**, not a scratch note. One figma name → one target per row; keep them reviewable.
160- **Keep the files healthy.** When `component_map` / `token_map` report `staleOverrides` (a recorded
161 target that no longer resolves — the file/token was renamed or deleted), the join has already
162 degraded to the fuzzy result; fix that row to the new target or delete it.
163
164## Responsive & verify
165
166- **Responsive by default** — root is `w-full`, never the artboard's fixed width; ground breakpoints
167 from the file's other-width frames. → [`references/responsive.md`](./references/responsive.md).
168- **Verify visually before you call it done** — render with the project's toolchain, screenshot at the
169 design's viewport, diff against the Figma node, fix at the source.
170 → [`references/verify.md`](./references/verify.md).
171
172## Motion (animation)
173
174When `get_design_context` (full detail) tags a node with a `motion` summary — applied
175animation-style presets, animated property fields, a timeline duration — carry it into the project's
176animation mechanism (CSS `@keyframes` / `transition`, Framer Motion, GSAP, Vue `<transition>`) instead
177of emitting a static component. `get_node_motion` returns the full keyframe detail when the summary
178isn't enough. Dropping a frame's animation is a fidelity miss, the same class as dropping a shadow.
179→ [`references/motion.md`](./references/motion.md).
180
181## Rules
182
183- **Ground every section — never eyeball a value off the screenshot.** Every px size, colour,
184 font-size, radius, and spacing comes from `get_design_context`, for _every_ section. The screenshot
185 is visual intent only; guessing "the easy sections" is the cardinal miss. On a page too big to ground
186 at once, scope by section `nodeId` — never depth-cap the whole page, never retry an oversized call.
187- **Reuse beats regenerate.** A `high`/`medium` `component_map` candidate must be imported and used.
188- **Reference tokens, not literals.** Emit a mapped variable's `ref`; reserve raw values for `unmapped`
189 gaps, and surface those gaps rather than burying them.
190- **Carry every visual property, don't drop fidelity.** Effects, per-side borders + `strokeAlign`,
191 per-corner radius, blend mode, masks, gradients, image `scaleMode`, and auto-layout/grid spacing are
192 all in the context — translate each (the catalog is in `references/grounding.md`). Dropping any is a
193 grounding miss, not a simplification.
194- **Export visual assets, don't fake them.** A grey box or a hand-typed wordmark is a miss.
195- **Match the project, not a house style.** Mirror the existing import style, file layout, and naming.
196- **Spell class names in full; don't assemble them from `&`.** In a language whose `&` concatenates
197 (SCSS / Sass / Less / Stylus / postcss-nested) `.card { &__title {} }` compiles to
198 `.card__title` — a name that exists only after
199 compilation, so the class the markup carries appears nowhere in the source and adjusting one rule
200 means searching a fragment like `__title` and reading every hit. Declare it flat at the top level
201 instead. `profile.styling.classNaming` (on `component_map` / `token_map`) reports the project's own
202 habit and **the project wins**: `ampersand` → write `&__title`; `flat` or absent → write flat.
203 → [`references/stylesheets.md`](./references/stylesheets.md) for the descendant-selector trap that
204 looks like the fix and isn't, and what `&` is still the right tool for.
205- **Render and verify before you call it done.** (See `references/verify.md`.)
206- Never write a config file or wizard prompt; everything is inferred from the project + the tools.