| name | propose-palette |
| description | Generate a coherent 5–6 color palette from a mood / theme word (e.g. "midnight desert", "sea glass", "rainy bookstore", "sun-faded Polaroid") and map each color to the Campfire app's semantic tokens (ember, flame, amber, pine, moss, bark, mist, paper, night, dusk). Returns a tokens-and-rationale block the Stylist agent can drop into its standard "Tokens" + "Diff" sections. Use this when an agent or user asks for a new palette from a vibe word, or wants to reskin the Campfire dashboard around a different theme. Does NOT pick fonts, spacing, or motion — palettes only.
|
| user-invocable | true |
Propose a palette
You are in propose-palette mode. Your job is to turn one mood phrase
into a small, coherent palette that drops straight into
app/src/theme.css.
Step 1 — Read the current tokens
view app/src/theme.css and identify the existing palette
variables under :root. The semantic surface variables
(--bg-page, --bg-card, --fg-strong, --fg-muted, --accent,
--accent-strong, --rule) all reference raw palette tokens. Your
job is to replace the raw palette tokens so the semantic
mappings stay intact and the whole UI re-themes from one edit.
If app/src/theme.css is missing, stop and report it — don't invent
a palette in a vacuum.
Step 2 — Interpret the mood
Pull out the key descriptors. Examples:
| Mood phrase | Descriptors |
|---|
| "midnight desert" | dark, warm, dusty, low chroma |
| "sea glass" | cool, pale, slightly chalky, airy |
| "sun-faded Polaroid" | washed, low contrast, cream-leaning |
| "rainy bookstore" | muted greens, paper, gentle warmth |
If the mood is ambiguous, pick the most concrete reading and say so
in one line — don't ask the caller to clarify.
Step 3 — Pick 5 hues, then derive 5 surfaces
Pick 5 hues that feel like the mood. Aim for:
- One accent (the loudest color in the system — used for primary
emphasis, the eyebrow text, etc.).
- One accent-strong (1–2 steps deeper for headings).
- One secondary hue (for variety in cards, charts, illustrations).
- One muted natural (the "background" of the system — pine, moss,
bark, sand, etc.).
- One deep (the darkest text color).
Then derive 5 surfaces:
- A page background (lightest neutral)
- A card background (one shade lighter than the page background, OR
one shade darker if you're going for a dark theme)
- A strong foreground (deep, near-black, used for body text)
- A muted foreground (mid-tone, used for meta and labels)
- A rule color (the divider — usually
rgba(<fg-strong>, 0.08))
Step 4 — Accessibility check
For every pairing the UI uses (--fg-strong on --bg-page,
--fg-strong on --bg-card, --fg-muted on --bg-card,
--accent on --bg-card), compute the contrast ratio and confirm
WCAG AA at 16px body (≥ 4.5:1 for normal text, ≥ 3:1 for
large/bold text).
If any pairing fails, adjust the value and recompute — don't ship a
failing palette. Show the final ratios in the output.
Step 5 — Output
Return only this block, nothing else:
## Palette — <mood phrase>
**Read of the mood:** <one sentence>
### Raw tokens (paste into :root in app/src/theme.css)
| Variable | Value | Role |
| ------------------ | --------- | -------------------------- |
| --color-ember | #xxxxxx | accent |
| --color-flame | #xxxxxx | accent-strong |
| --color-amber | #xxxxxx | secondary |
| --color-pine | #xxxxxx | natural / muted accent |
| --color-moss | #xxxxxx | natural support |
| --color-bark | #xxxxxx | warm support |
| --color-mist | #xxxxxx | page background |
| --color-paper | #xxxxxx | card background |
| --color-night | #xxxxxx | fg-strong (body text) |
| --color-dusk | #xxxxxx | fg-muted (meta) |
### Diff (drop-in replacement for the palette section)
\`\`\`css app/src/theme.css
:root {
/* palette — <mood phrase> */
--color-ember: #xxxxxx;
--color-flame: #xxxxxx;
--color-amber: #xxxxxx;
--color-pine: #xxxxxx;
--color-moss: #xxxxxx;
--color-bark: #xxxxxx;
--color-mist: #xxxxxx;
--color-paper: #xxxxxx;
--color-night: #xxxxxx;
--color-dusk: #xxxxxx;
}
\`\`\`
### Contrast check (WCAG AA, 16px body)
| Pairing | Ratio | Pass? |
| ----------------------------- | ----- | ----- |
| --fg-strong on --bg-page | 12.4 | ✓ |
| --fg-strong on --bg-card | 13.1 | ✓ |
| --fg-muted on --bg-card | 5.2 | ✓ |
| --accent on --bg-card | 4.8 | ✓ |
Boundaries
- Replace existing tokens, don't add new ones. The semantic
layer in
theme.css (--bg-page, --accent, etc.) already maps
to the raw tokens; if you keep the raw token names the whole UI
re-themes for free.
- Hex only. No
oklch(), color-mix(), or named colors — keep
it boring and portable.
- Don't edit files. Return the markdown above and only the
markdown above. The calling agent (Stylist) will fold this into
its standard three-section reply.
- Don't pick fonts, spacing, or motion. Those are separate
conversations. Palette only.