| name | synthesizing-taste |
| description | Extract brand taste tokens from reference materials into taste.md |
| user-invocable | true |
| allowed-tools | Read, Write, Glob, Grep, Edit |
Synthesizing Taste
Extract brand taste tokens from reference materials and generate a taste.md file. Analyzes existing code, design files, and brand guidelines to codify the project's visual identity.
Trigger
/synthesize [source]
Overview
This skill reverse-engineers taste from existing materials:
- Existing codebase patterns
- Design files or Figma exports
- Brand guidelines documents
- Reference websites or screenshots
Use when:
- Starting a new project and need to capture existing brand
- Onboarding to a project with undefined taste
- Updating taste.md after design system changes
- Consolidating scattered style decisions
Workflow
Phase 0: Load Visual Inspiration (if exists)
Before analyzing code, check for visual context in grimoires/artisan/inspiration/:
grimoires/artisan/inspiration/
├── direction.md # Design direction (want vs avoid)
├── references.md # Reference vocabulary
├── moodboard/ # Visual reference images
└── evolution/ # Taste evolution history
If inspiration folder exists:
-
Read direction.md:
- Parse "We Want" attributes (premium, confident, minimal, etc.)
- Parse "We Avoid" constraints (playful, dense, decorative, etc.)
- Note tension resolution priorities
-
Read references.md:
- Build vocabulary map ("premium" → Stripe patterns)
- Load anti-references to avoid (Bootstrap, etc.)
- Create quick reference lookup
-
View moodboard images:
- Read each .png file in moodboard/
- Note visual patterns: colors, spacing, shadows, corners, density
- Cross-reference with references.md entries
-
Ask clarifying questions based on visuals:
Looking at your moodboard:
- stripe-dashboard.png: Generous p-8 padding, shadow-sm
- linear-sidebar.png: Tight density, monospace accents
Questions:
1. For main content: Spacious (Stripe) or dense (Linear)?
2. For navigation: Same or different density?
3. Shadows: Subtle (Stripe) or none (Linear)?
-
Use inspiration to guide extraction:
- Extracted patterns that match direction.md → keep
- Extracted patterns that conflict with "We Avoid" → flag
- Missing patterns from references → suggest adding
If no inspiration folder:
- Proceed directly to Phase 1
- Optionally prompt: "Create grimoires/artisan/inspiration/ for better grounding?"
Phase 1: Collect References
Identify sources to analyze:
Reference Sources:
├── Code: src/components/*, tailwind.config.js
├── Design: figma-export.json, design-tokens.json
├── Brand: brand-guidelines.pdf, style-guide.md
└── Examples: reference-sites.md, screenshots/
Phase 2: Extract Patterns
From Code
Scan for repeated patterns:
grep -rh "bg-\|text-\|border-" src/ | sort | uniq -c | sort -rn
grep -rh "gap-\|p-\|m-\|space-" src/ | sort | uniq -c | sort -rn
grep -rh "font-\|text-\|tracking-\|leading-" src/ | sort | uniq -c | sort -rn
From Tailwind Config
Extract custom values:
module.exports = {
theme: {
extend: {
colors: {
primary: '#2563eb',
accent: '#f59e0b',
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
},
},
};
From Design Tokens
Parse design system exports:
{
"color": {
"primary": { "value": "#2563eb" },
"secondary": { "value": "#1f2937" }
},
"spacing": {
"xs": { "value": "4px" },
"sm": { "value": "8px" }
}
}
Phase 3: Identify Brand Personality
Analyze patterns to determine personality traits:
| Pattern Observed | Personality Trait |
|---|
| Tight spacing, small text | Precise, dense |
| Large padding, whitespace | Spacious, calm |
| Bold colors, high contrast | Confident, bold |
| Muted colors, subtle shadows | Refined, subtle |
| Sharp corners | Modern, technical |
| Rounded corners | Friendly, approachable |
| Sans-serif fonts | Clean, contemporary |
| Serif fonts | Traditional, editorial |
If inspiration/direction.md exists, validate:
Extracted personality: Dense, Modern
direction.md says: "We avoid: Dense"
⚠️ Conflict: Code patterns suggest density, but direction.md
indicates you want to avoid this.
Options:
1. Flag as violation → add to Never Rules
2. Accept code reality → update direction.md
3. This is intentional (specific context)
Phase 4: Generate taste.md
Output structured taste file:
# Taste: [Project Name]
## Brand Personality
- **Precise**: Tight spacing, minimal decoration
- **Confident**: Bold primary color, clear hierarchy
- **Minimal**: Limited color palette, no gradients
## Colors
| Token | Value | Tailwind | Usage |
|-------|-------|----------|-------|
| primary | #2563eb | blue-600 | Buttons, links, accents |
| secondary | #1f2937 | gray-800 | Text, headings |
| accent | #f59e0b | amber-500 | Highlights, badges |
| background | #ffffff | white | Page background |
| surface | #f9fafb | gray-50 | Cards, panels |
| muted | #6b7280 | gray-500 | Secondary text |
## Typography
| Token | Classes | Usage |
|-------|---------|-------|
| heading | font-semibold tracking-tight | H1-H6 |
| body | font-normal text-gray-700 | Paragraphs |
| caption | text-sm text-gray-500 | Labels, helpers |
| mono | font-mono text-sm | Code |
## Spacing Scale
| Token | Value | Usage |
|-------|-------|-------|
| xs | gap-1, p-1 | Tight groupings |
| sm | gap-2, p-2 | Related items |
| md | gap-4, p-4 | Default spacing |
| lg | gap-6, p-6 | Section padding |
| xl | gap-8, p-8 | Page sections |
## Motion
| Token | Value | Usage |
|-------|-------|-------|
| duration-fast | 100ms | Micro-interactions |
| duration-default | 200ms | Standard transitions |
| duration-slow | 300ms | Page transitions |
| easing-default | ease-out | Entrances |
| easing-movement | ease-in-out | Position changes |
## Shadows
| Token | Value | Usage |
|-------|-------|-------|
| shadow-sm | 0 1px 2px | Subtle elevation |
| shadow-md | 0 4px 6px | Cards, dropdowns |
| shadow-lg | 0 10px 15px | Modals, popovers |
## Borders
| Token | Value | Usage |
|-------|-------|-------|
| border-default | border-gray-200 | Dividers, inputs |
| border-focus | ring-2 ring-blue-500 | Focus states |
| radius-default | rounded-lg | Buttons, cards |
| radius-full | rounded-full | Avatars, pills |
## Never Rules
Things that violate this brand's taste:
- Never use gradients (except loading skeletons)
- Never use shadows heavier than shadow-lg
- Never use colors outside the palette
- Never use animation duration > 300ms
- Never use purple or multicolor accents
Phase 5: Generate Tailwind Config
Optionally generate matching Tailwind config:
module.exports = {
theme: {
extend: {
colors: {
primary: '#2563eb',
secondary: '#1f2937',
accent: '#f59e0b',
surface: '#f9fafb',
muted: '#6b7280',
},
transitionDuration: {
fast: '100ms',
DEFAULT: '200ms',
slow: '300ms',
},
},
},
};
Counterfactuals — Design System Synthesis
The Target (What We Do)
Extract a coherent taste.md from existing UI by identifying the actual token set in use — colors, typography scale, spacing rhythm, motion curves — and encoding them as a single-source-of-truth document. The Tailwind config is generated FROM taste.md, never the reverse.
taste.md → Tailwind config → Components
↘ CSS variables ↗
The Near Miss — Tailwind-First Synthesis (Seductively Close, But Wrong)
What it looks like: Extracting the Tailwind config directly from code, then writing taste.md to describe what Tailwind already has.
Tailwind config → taste.md (describing Tailwind)
Components → Tailwind config
Why it's tempting: Tailwind config is machine-readable and already structured. It seems efficient to "just document what's there." The result even looks correct — taste.md matches the Tailwind config perfectly.
Physics of Error: Coupling Inversion — The taste document becomes a downstream artifact of implementation rather than an upstream source of truth. When a new component needs a color decision, there's no principled basis for choice — only "what does Tailwind already have?" The design system loses its ability to say "no" because it's descriptive, not prescriptive. Drift is guaranteed because additions go to Tailwind first and taste.md lags behind.
Detection signal: taste.md that mirrors Tailwind config structure 1:1; no design rationale or usage guidance in taste.md; taste.md updated AFTER Tailwind config changes.
The Category Error — Component-Level Extraction (Fundamentally Wrong)
What it looks like: Surveying individual component styles and averaging them into a "design system."
Component A uses blue-500, Component B uses blue-600
→ taste.md: "primary blue is between blue-500 and blue-600"
Why someone might try it: "Let's see what the codebase actually uses." This feels empirical and grounded.
Physics of Error: Semantic Collapse — Individual component styling decisions reflect local context (hover states, emphasis, hierarchy), not system-level tokens. Averaging local decisions destroys the semantic relationships between tokens (primary vs. muted, interactive vs. static). The result CANNOT function as a design system because it conflates implementation artifacts with design intentions — like deriving a grammar by averaging sentence lengths.
Bridgebuilder action: Immediate rejection. Regenerate from Target by extracting design intentions, not implementation details.
Output Format
═══════════════════════════════════════════════════
TASTE SYNTHESIS: [Project Name]
═══════════════════════════════════════════════════
SOURCES ANALYZED:
├── Code: 47 component files
├── Config: tailwind.config.js
└── Design: design-tokens.json
PATTERNS EXTRACTED:
├── Colors: 6 tokens
├── Typography: 4 tokens
├── Spacing: 5 tokens
├── Motion: 5 tokens
└── Shadows: 3 tokens
PERSONALITY DETECTED:
├── Precise (tight spacing: 78% of components)
├── Confident (bold primary usage)
└── Minimal (3-color palette)
FILES GENERATED:
├── grimoires/taste.md
└── tailwind.config.taste.js (optional)
═══════════════════════════════════════════════════
Quick Reference Card
COLLECT:
├── Component files
├── Tailwind config
├── Design tokens
└── Brand guidelines
EXTRACT:
├── Color patterns
├── Typography patterns
├── Spacing patterns
├── Motion patterns
└── Shadow patterns
IDENTIFY:
├── Personality traits
├── Consistency level
├── Outliers/violations
└── Never rules
GENERATE:
├── taste.md
├── Token tables
├── Never rules
└── Tailwind config (optional)
Checklist
Before Synthesis:
├── [ ] Reference sources identified
├── [ ] Code access available
├── [ ] Config files located
└── [ ] Design assets available
During Synthesis:
├── [ ] Colors extracted
├── [ ] Typography extracted
├── [ ] Spacing extracted
├── [ ] Motion extracted
├── [ ] Personality identified
└── [ ] Never rules documented
After Synthesis:
├── [ ] taste.md generated
├── [ ] Tokens are consistent
├── [ ] Tailwind config matches
└── [ ] Team reviewed and approved