Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/claude-design-align.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@open-codesign/core': patch
---

Align system prompt content with Claude Design conventions extracted from real artifact analysis (research docs §11.4, §1.2, §2, §6, §11.3):

- EDITMODE protocol: empty `{}` block is now valid — signals tweak-aware artifacts to the host.
- Design methodology: token-density target 9 ± 3 oklch tokens per artifact.
- Craft directives: typography ladder defaults to two font families (mono only when needed); add four-animation CSS keyframe budget (`fadeUp` / `breathe` / `pulse-ring` / `spin`).
- Progressive disclosure: marketing/landing/case-study prompts now surface a Fraunces typography hint as a Layer 2 routing addition.
14 changes: 14 additions & 0 deletions packages/core/src/generate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,20 @@ describe('composeSystemPrompt() — progressive disclosure', () => {
expect(p).toContain('Customer quotes deserve distinguished treatment');
});

it('marketing prompt includes Fraunces hint', () => {
const p = composeSystemPrompt({
mode: 'create',
userPrompt: 'indie marketing landing page',
});
expect(p).toContain('Fraunces');
expect(p).toContain('Marketing typography hint');
});

it('dashboard prompt does NOT include Fraunces hint', () => {
const p = composeSystemPrompt({ mode: 'create', userPrompt: '做个数据看板' });
expect(p).not.toContain('Marketing typography hint');
});

it('no-keyword prompt: falls back to FULL craft directives', () => {
const p = composeSystemPrompt({ mode: 'create', userPrompt: '随便做点东西' });
// Full craft directives includes ALL ten subsections — verify several signal ones
Expand Down
22 changes: 17 additions & 5 deletions packages/core/src/prompts/craft-directives.v1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ Do not bury headline metrics in body paragraphs.

## Typography ladder

A polished single-page artifact combines three type families:
- Display / editorial — headlines, hero numbers, section openers
- Workhorse sans — body, navigation, captions
- Mono — data, code, tabular numbers, timestamps, kbd-style accents
Default: **two font families** — display/editorial for hero, headlines, numbers; workhorse sans for body, nav, captions. A third (mono) is used ONLY when the design needs timestamps, code, or tabular numerics — not by default.

Use the mono family sparingly (10–15 % of text surface) so it reads as intentional. Pair selection follows the anti-slop preferred-fonts list.
- Display / editorial: hero numbers, section openers
- Workhorse sans: body, navigation, captions
- Mono (when needed): data, timestamps, code accents — sparingly

Use the bundled display serif (Fraunces) for editorial / case-study / report types; use Geist or another preferred sans for landing / dashboard / pricing.

## Dark themes need warmth

Expand Down Expand Up @@ -98,3 +99,14 @@ For dashboard / data / analytics artifacts, include these "live system" cues to
- KPI cards get a 4px vertical accent bar on the left side. Color varies by metric category (revenue=teal, growth=amber, retention=violet, regions=green) — pick from the artifact palette, not arbitrary.

Slide decks substitute: cover → 3-7 content slides with strong hierarchy each → closing slide.

## Animation budget

Cap your CSS keyframe library at **four named animations** per artifact. The Claude Design canon:

- `fadeUp` — entrance (translateY + opacity)
- `breathe` — ambient pulsing (scale 1↔1.08, opacity 0.7↔1)
- `pulse-ring` — emphasis (scale + opacity → 0)
- `spin` — rotation

Apply with staggered `animation-delay` (0.1s, 0.2s, 0.3s) for section-by-section reveal. Never script a JS animation loop — CSS only.
11 changes: 11 additions & 0 deletions packages/core/src/prompts/design-methodology.v1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,14 @@ Each revision should make the design more itself, not more generic. If a revisio
- Body text: 16–18 px base (1rem–1.125rem), line-height 1.5–1.7.
- Whitespace: err on the side of generous. A design with too much space looks confident; one with too little looks anxious.
- Section rhythm: vary height and density. Not every section should be a tight 3-column card grid.

## Token density

Aim for 9 ± 3 design tokens per artifact, declared as a flat object at the top of the script:

- 1 background, 1 surface, 1 high-contrast text, 1 muted text, 1 border/line
- 1 accent + 1 light pair (e.g. `green` + `greenL`)
- Optional: 1 secondary accent + light pair
- All in `oklch()`, with `/ alpha` for transparency (`oklch(1 0 0 / 0.82)`)

Brutal minimalism. A 9-token palette is the entire design system for one artifact.
10 changes: 10 additions & 0 deletions packages/core/src/prompts/editmode-protocol.v1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ The host environment will:
- Reference the parameters from your code via the named constant (`TWEAK_DEFAULTS.accentColor`).
- Pick 3-6 parameters that meaningfully change the artifact's look. Don't expose every CSS variable.

## Empty block is valid

Even if your artifact has no tunable parameters yet, you may emit an empty block — it signals to the host that this artifact is tweak-aware:

```js
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{}/*EDITMODE-END*/;
```

The host scans for the markers regardless of contents.

## Type detection

| Value pattern | Renders as |
Expand Down
54 changes: 47 additions & 7 deletions packages/core/src/prompts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,18 @@ Each revision should make the design more itself, not more generic. If a revisio
- Headings: large enough to anchor the page, not so large they crowd content.
- Body text: 16–18 px base (1rem–1.125rem), line-height 1.5–1.7.
- Whitespace: err on the side of generous. A design with too much space looks confident; one with too little looks anxious.
- Section rhythm: vary height and density. Not every section should be a tight 3-column card grid.`;
- Section rhythm: vary height and density. Not every section should be a tight 3-column card grid.

## Token density

Aim for 9 ± 3 design tokens per artifact, declared as a flat object at the top of the script:

- 1 background, 1 surface, 1 high-contrast text, 1 muted text, 1 border/line
- 1 accent + 1 light pair (e.g. \`green\` + \`greenL\`)
- Optional: 1 secondary accent + light pair
- All in \`oklch()\`, with \`/ alpha\` for transparency (\`oklch(1 0 0 / 0.82)\`)

Brutal minimalism. A 9-token palette is the entire design system for one artifact.`;

const EDITMODE_PROTOCOL = `# EDITMODE protocol — declaring tweakable parameters

Expand Down Expand Up @@ -198,6 +209,16 @@ The host environment will:
- Reference the parameters from your code via the named constant (\`TWEAK_DEFAULTS.accentColor\`).
- Pick 3-6 parameters that meaningfully change the artifact's look. Don't expose every CSS variable.

## Empty block is valid

Even if your artifact has no tunable parameters yet, you may emit an empty block — it signals to the host that this artifact is tweak-aware:

\`\`\`js
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{}/*EDITMODE-END*/;
\`\`\`

The host scans for the markers regardless of contents.

## Type detection

| Value pattern | Renders as |
Expand Down Expand Up @@ -434,12 +455,13 @@ Do not bury headline metrics in body paragraphs.

## Typography ladder

A polished single-page artifact combines three type families:
- Display / editorial — headlines, hero numbers, section openers
- Workhorse sans — body, navigation, captions
- Mono — data, code, tabular numbers, timestamps, kbd-style accents
Default: **two font families** — display/editorial for hero, headlines, numbers; workhorse sans for body, nav, captions. A third (mono) is used ONLY when the design needs timestamps, code, or tabular numerics — not by default.

- Display / editorial: hero numbers, section openers
- Workhorse sans: body, navigation, captions
- Mono (when needed): data, timestamps, code accents — sparingly

Use the mono family sparingly (10–15 % of text surface) so it reads as intentional. Pair selection follows the anti-slop preferred-fonts list.
Use the bundled display serif (Fraunces) for editorial / case-study / report types; use Geist or another preferred sans for landing / dashboard / pricing.

## Dark themes need warmth

Expand Down Expand Up @@ -485,7 +507,18 @@ For dashboard / data / analytics artifacts, include these "live system" cues to
- A live clock in the top-right of the page header: HH:MM:SS in tabular-nums font, updated each second via a single \`setInterval(updateClock, 1000)\`. This is the ONE permitted JS interval — do not chain other animations onto it. Clear it on unmount if your code supports lifecycle.
- KPI cards get a 4px vertical accent bar on the left side. Color varies by metric category (revenue=teal, growth=amber, retention=violet, regions=green) — pick from the artifact palette, not arbitrary.

Slide decks substitute: cover → 3-7 content slides with strong hierarchy each → closing slide.`;
Slide decks substitute: cover → 3-7 content slides with strong hierarchy each → closing slide.

## Animation budget

Cap your CSS keyframe library at **four named animations** per artifact. The Claude Design canon:

- \`fadeUp\` — entrance (translateY + opacity)
- \`breathe\` — ambient pulsing (scale 1↔1.08, opacity 0.7↔1)
- \`pulse-ring\` — emphasis (scale + opacity → 0)
- \`spin\` — rotation

Apply with staggered \`animation-delay\` (0.1s, 0.2s, 0.3s) for section-by-section reveal. Never script a JS animation loop — CSS only.`;

const CHART_RENDERING = `# Chart rendering contract

Expand Down Expand Up @@ -753,6 +786,10 @@ Do not produce these. Each one is the tell of an unconsidered, generated-feeling

These patterns are forbidden when combined without a distinctive visual angle that makes them feel intentional rather than assembled from a component kit.`;

const MARKETING_FONT_HINT = `# Marketing typography hint

Marketing / landing / case-study artifacts: prefer **Fraunces** (variable font, optical-size 9..144) for the display family — its 72pt+ optical size unlocks subtle character better than fixed-size DM Serif Display. Pair with **DM Sans** or **Geist** for body, and **JetBrains Mono** for any code / timestamp accents.`;

// Split CRAFT_DIRECTIVES into a Map<subsectionName, "## name\n\nbody"> so the
// progressive-disclosure composer can include only the subsections relevant to
// the user's prompt. The intro paragraph (everything before the first `## `)
Expand Down Expand Up @@ -798,6 +835,7 @@ export const PROMPT_SECTIONS: Record<string, string> = {
iosStarterTemplate: IOS_STARTER_TEMPLATE,
antiSlop: ANTI_SLOP,
antiSlopDigest: ANTI_SLOP_DIGEST,
marketingFontHint: MARKETING_FONT_HINT,
safety: SAFETY,
};

Expand All @@ -815,6 +853,7 @@ export const PROMPT_SECTION_FILES: Record<keyof typeof PROMPT_SECTIONS, string>
iosStarterTemplate: 'ios-starter-template.v1.txt',
antiSlop: 'anti-slop.v1.txt',
antiSlopDigest: 'anti-slop-digest.v1.txt',
marketingFontHint: 'marketing-font-hint.v1.txt',
safety: 'safety.v1.txt',
};

Expand Down Expand Up @@ -960,6 +999,7 @@ function planKeywordMatches(userPrompt: string): KeywordMatchPlan {
topLevel.push(IOS_STARTER_TEMPLATE);
}
if (KEYWORDS_MARKETING.test(userPrompt)) {
topLevel.push(MARKETING_FONT_HINT);
craftSubsectionNames.push(
'Single-page structure ladder',
'Big numbers get dedicated visual blocks',
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/prompts/marketing-font-hint.v1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Marketing typography hint

Marketing / landing / case-study artifacts: prefer **Fraunces** (variable font, optical-size 9..144) for the display family — its 72pt+ optical size unlocks subtle character better than fixed-size DM Serif Display. Pair with **DM Sans** or **Geist** for body, and **JetBrains Mono** for any code / timestamp accents.
Loading