Generate a DESIGN.md file at the project root that captures the current visual design system, so AI agents generating new screens stay on-brand.
DESIGN.md follows the official DESIGN.md format spec: optional YAML frontmatter carrying machine-readable design tokens, followed by up to eight markdown sections in a fixed order. Tokens are normative; prose provides context for how to apply them. Sections may be omitted when not relevant, but those present stay in the specified order. Use the canonical headings below so the file remains portable across DESIGN.md-aware tools.
The YAML frontmatter is the machine-readable layer. It's what Stitch's linter validates and what the live panel renders tiles from. Keep it tight; every entry should correspond to a token the project actually uses.
---
name: <project title>
description: <one-line tagline>
colors:
primary: "#b8422e"
neutral-bg: "#faf7f2"
# ...one entry per extracted color; key = descriptive slug
typography:
display:
fontFamily: "Cormorant Garamond, Georgia, serif"
fontSize: "clamp(2.5rem, 7vw, 4.5rem)"
fontWeight: 300
lineHeight: 1
letterSpacing: "normal"
body:
# ...
rounded:
sm: "4px"
md: "8px"
spacing:
sm: "8px"
md: "16px"
components:
button-primary:
backgroundColor: "{colors.primary}"
textColor: "{colors.neutral-bg}"
rounded: "{rounded.sm}"
padding: "16px 48px"
button-primary-hover:
backgroundColor: "{colors.primary-deep}"
---
Rules that matter:
{path.to.token} (e.g. {colors.primary}, {rounded.md}). Components may reference primitives; primitives may not reference each other.rgb(), hsl(), oklch(), wide-gamut, or mixed-color value when it is the project's normative source. Never split the source of truth without explicit reason.backgroundColor, textColor, typography, rounded, padding, size, height, width. Shadows, motion, focus rings, backdrop-filter: none of those fit. Carry them in the sidecar (Step 4b).oxblood-deep, surface-container-low). Don't rename to Material defaults.button-primary / button-primary-hover / button-primary-active as sibling keys.## Overview## Colors## Typography## Layout## Elevation & Depth## Shapes## Components## Do's and Don'tsOmit irrelevant sections rather than filling them with invented rules. Put responsive layout in Layout, depth in Elevation & Depth, radius and form language in Shapes, and per-component behavior in Components. Unknown sections are preserved by the format, but new visual guidance should use the canonical structure whenever it fits.
DESIGN.md.DESIGN.md is stale (the design has drifted).If a DESIGN.md already exists, do not silently overwrite it. Show the user the existing file and STOP and use Codex's structured user-input/question tool when available; if unavailable, ask directly in chat to clarify what you cannot infer. whether to refresh, overwrite, or merge.
Decide by scanning first (Scan mode Step 1). If the scan finds no tokens, no component files, and no rendered site, offer seed mode; don't silently switch. $impeccable document --seed requests new-work's world workshop, but it does not authorize replacing coherent code: when an incumbent system exists, offer scan mode or route an explicit identity-replacement request through new-work.
Search the codebase in priority order:
--color-, --font-, --spacing-, --radius-, --shadow-, --ease-, --duration- declarations in CSS files (usually src/styles/, public/css/, app/globals.css, etc.). Record name, value, and the file it's defined in.tailwind.config.{js,ts,mjs} exists, read the theme.extend block for colors, fontFamily, spacing, borderRadius, boxShadow.theme.ts, tokens.ts, or equivalent.tokens.json, design-tokens.json, Style Dictionary output, W3C token community group format.Build a structured draft from the discovered tokens. For each token class:
From the auto-extracted tokens, draft the YAML frontmatter now (you'll write it at the top of DESIGN.md in Step 4). This is the machine-readable layer: what the live panel and Stitch's linter consume.
oxblood-deep, editorial-magenta, not blue-800). Value = whichever format the project treats as canonical (OKLCH or hex; see the frontmatter rules above). Don't split the source of truth: one format in the frontmatter, don't redefine the same token in prose with a different value.display, headline, title, body, label). Typography is an object; include only the props that are real for the project (fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, fontFeature, fontVariation).sm / md / lg, or surface-sm, or numeric steps).button-primary, button-primary-hover, button-ghost). Reference primitives via {colors.X}, {rounded.Y}. If a variant needs a property Stitch's 8-prop set doesn't cover (shadow, focus ring, backdrop-filter), carry the full snippet in the sidecar instead.Skip anything the project doesn't have. Empty scale keys or fabricated tokens pollute the spec.
The following require creative input that cannot be auto-extracted. Ask them in two structured rounds of no more than three questions each (or the harness's lower limit), waiting between rounds:
Carry a line from PRODUCT.md only when it is a durable brand commitment that actually constrains the visual system. Page strategy and surface concepts do not belong here.
The file opens with the YAML frontmatter staged in Step 2b (schema documented at the top of this reference), then the markdown body using the canonical structure below.
name: [Project Title]
description: [one-line tagline]
colors:
Creative North Star: "[Named metaphor in quotes]"
[2-3 paragraph holistic description: personality, density, and aesthetic philosophy. Start from the North Star and work outward. State only confirmed visual rejections. End with a short Key Characteristics: bullet list.]
[Describe the palette character in one sentence.]
The [Rule Name] Rule. [Short, forceful prohibition or doctrine, e.g. "The One Voice Rule. The primary accent is used on ≤10% of any given screen. Its rarity is the point."]
Display Font: [Family] (with [fallback])
Body Font: [Family] (with [fallback])
Label/Mono Font: [Family, if distinct]
Character: [1-2 sentence personality description of the pairing.]
The [Rule Name] Rule. [Short doctrine about type use.]
[Describe the grid or spatial model, container behavior, density, responsive changes, and the spacing rhythm. Include exact values only when observed.]
[One paragraph: does this system use shadows, tonal layering, or a hybrid? If "no shadows", say so explicitly and describe how depth is conveyed instead.]
box-shadow: [exact value]): [When to use it.]The [Rule Name] Rule. [e.g. "The Flat-By-Default Rule. Surfaces are flat at rest. Shadows appear only as a response to state (hover, elevation, focus)."]
[Describe the form language: corner/radius strategy, borders, clipping, and any recurring silhouette or geometry.]
For each component, lead with a short character line, then specify shape, color assignment, states, and any distinctive behavior.
[Description.]
Concrete visual guardrails grounded in the incumbent implementation or the user's chosen world. Lead each with "Do" or "Don't" and include exact values only when established. Do not turn a task-specific concept or surface strategy into a system-wide prohibition.
The frontmatter owns token primitives (colors, typography, rounded, spacing, components). The sidecar at .impeccable/design.json carries what Stitch's schema can't hold: tonal ramps per color, shadow/elevation tokens, motion tokens, breakpoints, full component HTML/CSS snippets (the panel renders these into a shadow DOM), and narrative (north star, rules, do's/don'ts). It extends the frontmatter, it doesn't duplicate it.
Regenerate the sidecar whenever you regenerate root DESIGN.md. If the user only asks to refresh the sidecar (e.g., from the live panel's stale-hint), preserve DESIGN.md and write only .impeccable/design.json.
{
"schemaVersion": 2,
"generatedAt": "ISO-8601 string",
"title": "Design System: [Project Title]",
"extensions": {
"colorMeta": {
"primary": { "role": "primary", "displayName": "Editorial Magenta", "canonical": "oklch(60% 0.25 350)", "tonalRamp": ["...", "...", "..."] },
"cool-paper": { "role": "neutral", "displayName": "Cool Paper", "canonical": "oklch(96% 0.005 230)", "tonalRamp": ["...", "...", "..."] }
},
"typographyMeta": {
"display": { "displayName": "Display", "purpose": "Hero headlines only." }
},
"shadows": [
{ "name": "ambient-low", "value": "0 4px 24px rgba(0,0,0,0.12)", "purpose": "Diffuse hover glow under accent elements." }
],
"motion": [
{ "name": "ease-standard", "value": "cubic-bezier(0.4, 0, 0.2, 1)", "purpose": "Default easing for state transitions." }
],
"breakpoints": [
{ "name": "sm", "value": "640px" }
]
},
"components": [
{
"name": "Primary Button",
"kind": "button | input | nav | chip | card | custom",
"refersTo": "button-primary",
"description": "One-line what and when.",
"html": "<button class=\"ds-btn-primary\">SAVE CHANGES</button>",
"css": ".ds-btn-primary { background: #191c1d; color: #fff; padding: 16px 48px; letter-spacing: 0.05em; text-transform: uppercase; font-weight: 500; border: none; border-radius: 0; transition: background 0.2s, transform 0.2s; } .ds-btn-primary:hover { background: oklch(60% 0.25 350); transform: translateY(-2px); }"
}
],
"narrative": {
"northStar": "The Editorial Sanctuary",
"overview": "2-3 paragraphs of the philosophy, pulled from DESIGN.md Overview section.",
"keyCharacteristics": ["...", "..."],
"rules": [{ "name": "The One Voice Rule", "body": "...", "section": "colors|typography|elevation" }],
"dos": ["Do use ..."],
"donts": ["Don't use ..."]
}
}
What changed from schemaVersion 1. The old sidecar carried token primitive arrays (tokens.colors[], tokens.typography[], etc.). Those values now live in the frontmatter. The sidecar only carries metadata that can't live in the frontmatter (tonal ramps, canonical OKLCH when the hex is an approximation, display names, role hints), keyed by the frontmatter token name (colorMeta.<token-name>, typographyMeta.<token-name>). Components still carry full HTML/CSS because Stitch's 8-prop set can't hold them.
The html and css fields must be self-contained, drop-in snippets that render correctly when injected into a shadow DOM. The panel applies them directly: no post-processing, no framework runtime.
css string. Do not reference Tailwind classes; do not assume a Tailwind CSS bundle is loaded. Each component is self-contained.:root (e.g. --color-primary, --radius-md), reference them via var(--color-primary); they inherit through the shadow DOM and stay live-bound. If tokens live only in JS theme objects (styled-components, CSS-in-JS), resolve to literal values at generation time.<img src="...">. A typical icon is 16-24px; copy the SVG path data directly.:hover, :focus-visible, and (if meaningful) :active rules inline. A static default-only snapshot makes the panel feel dead. Hover + focus rules in the CSS make it feel alive.box-sizing: border-box, line-height: inherit, -webkit-font-smoothing). The panel already has a neutral canvas; don't re-ship resets.ds- (e.g. ds-btn-primary, ds-input-search) so component CSS doesn't collide with other components' CSS in the same shadow DOM.Aim for a tight set of 5-10 components that best represent the visual system:
If the project has no component library yet (bare landing page, new project), synthesize canonical primitives from the tokens using best-practice defaults consistent with the DESIGN.md's rules. Every .impeccable/design.json has something to render, even on day zero.
For each color token, generate an 8-step tonalRamp array: dark to light, same hue and chroma, stepped lightness from ~15% to ~95%. The panel renders this as a strip under the swatch. If the project already defines a tonal scale (Material surface-container-low family, Tailwind-style blue-50..blue-900), use those values. Otherwise synthesize in OKLCH.
Pull directly from the DESIGN.md you just wrote:
narrative.northStar → the **Creative North Star: "..."** line from Overviewnarrative.overview → the philosophy paragraphs from Overviewnarrative.keyCharacteristics → the bulleted **Key Characteristics:** listnarrative.rules → every **The [Name] Rule.** [body] across all sections, tagged with sectionnarrative.dos / narrative.donts → the bullet lists from Do's and Don'ts verbatimDo not reword. The panel shows these as secondary collapsible context; the same voice that's in the Markdown carries through.
.impeccable/design.json was also written alongside; the live panel will now render this project's actual button/input/nav primitives instead of generic approximations.Your own write is the freshest source; subsequent commands in this session don't need a reload.
For projects with no visual system to extract yet. Produces a user-chosen visual-world scaffold, not a fabricated token spec.
PRODUCT.md is the prerequisite. If it is missing, load init.md and complete its product interview first. Do not create a visual identity without durable product context.
If PRODUCT.md exists, load new-work.md and resolve visual authority. Seed mode requires a concrete first surface: use the target the user named, or ask what they want to make first. Run new-work's Create or replace the visual world flow, then Commit the world, so the visual world and its first expression are chosen together. Stop after the directional DESIGN.md seed and surface brief; do not implement. A structured simulated user counts as the user and must get the same choice.
If new-work already completed the workshop in this session, use its chosen direction directly. Do not ask again.
Use the canonical section order from Scan mode. Populate the selected workshop direction and leave unresolved implementation facts as honest placeholders. The seed commits a world and its invariants; it does not pretend implementation tokens already exist.
Lead the file with:
<!-- SEED: established with the user before implementation; re-run $impeccable document once there's code to capture the actual tokens and components. -->
Per-section guidance in seed mode:
[to be resolved during implementation].[to be resolved during implementation].Seed mode writes a minimal frontmatter with name and description only; no colors, typography, rounded, spacing, or components yet. Real tokens land on the next Scan-mode run. Skip the .impeccable/design.json sidecar in seed mode for the same reason: nothing to render.
$impeccable document once you have some code. That pass will extract real tokens and generate the sidecar."Your own write is the freshest source; no reload needed.
**The [Name] Rule.** [short doctrine]. These are memorable, citable, and much stickier for AI consumers than bullet lists. Stitch's own outputs use them heavily ("The No-Line Rule", "The Ghost Border Fallback"). Aim for 1-3 per section.Layout; put motion with the affected world or component.colors.primary as hex, the prose can name it and describe its role but should not reassert a different hex. The frontmatter is normative.motion:, breakpoints:, shadows: at the top level). Stitch's Zod schema only accepts colors, typography, rounded, spacing, components. Anything else belongs in the sidecar's extensions.