design system token v0.3

This commit is contained in:
Juan
2026-04-13 17:03:28 -05:00
parent 1d80882647
commit f7acb63782
4 changed files with 127 additions and 732 deletions

View File

@@ -51,6 +51,7 @@ function componentCount(): number {
function buildDesignPhilosophy(): string {
return `## Design Philosophy
- **TypeScript only**: All code MUST be written in TypeScript (\`.tsx\` / \`.ts\`). Never generate plain JavaScript (\`.jsx\` / \`.js\`).
- **Minimal and restrained**: Off-white + off-black + warm greys. One single accent color (orange). No gradients, no decorative color, no multiple accent hues.
- **Typography-driven**: Source Serif 4/Pro (serif) for headings and body content. Aspekta (sans, self-hosted) for UI labels, buttons, navigation, and form elements.
- **Calm, professional aesthetic**: Tight border-radii, subtle shadows, generous whitespace.
@@ -170,7 +171,7 @@ function buildCompositionRules(): string {
- **Form layout**: Vertical stack with \`gap-4\`, labels above inputs
- **Navbar**: Fixed top, \`z-50\`, \`h-16\`, logo left, nav center, actions right
- **Typography pairing**: Serif (\`font-serif\`) for content headings, sans (\`font-sans\`) for UI labels/buttons
- **Color restraint**: Orange ONLY for primary actions and key emphasis -- never decorative
- **Color restraint**: Trust the default component variants for orange accent -- they apply it at the right scale. Don't apply \`bg-primary\` to large surfaces, containers, or section backgrounds
- **Focus pattern**: \`focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\`
- **Disabled pattern**: \`disabled:pointer-events-none disabled:opacity-50\`
- **Aria-invalid pattern**: \`aria-invalid:ring-destructive/20 aria-invalid:border-destructive\`
@@ -242,7 +243,7 @@ function generateSkill(): string {
> **Stack**: React 19, Radix UI, Tailwind CSS v4, CVA, tailwind-merge, clsx, Lucide icons
> **Framework-agnostic**: No Next.js imports. Works with Vite, Remix, Astro, CRA, or any React setup.
This skill gives you full context to generate pixel-perfect, on-brand UI using the Greyhaven Design System. Every component lives in \`components/ui/\`. Use semantic tokens, never raw colors. Follow the patterns exactly.
This skill gives you full context to generate pixel-perfect, on-brand UI using the Greyhaven Design System. Every component lives in \`components/ui/\`. Use semantic tokens, never raw colors. Follow the patterns exactly. **ALWAYS use TypeScript (.tsx/.ts) — never plain JavaScript.**
`,
'---\n',
buildDesignPhilosophy(),
@@ -260,41 +261,73 @@ This skill gives you full context to generate pixel-perfect, on-brand UI using t
}
// ---------------------------------------------------------------------------
// AGENT.md (non-Claude AI agents: Cursor, Copilot, Windsurf, etc.)
// AGENT.md (project-level instructions for non-Claude AI agents)
// ---------------------------------------------------------------------------
function generateAgent(): string {
return [
`# Greyhaven Design System
// Count components by category for the summary
const categories = new Map<string, number>()
for (const c of COMPONENT_CATALOG) {
categories.set(c.category, (categories.get(c.category) || 0) + 1)
}
const categorySummary = Array.from(categories.entries())
.map(([cat, count]) => `${cat} (${count})`)
.join(', ')
> **Auto-generated** by \`scripts/generate-skill.ts\` -- DO NOT EDIT by hand.
return `# Project Instructions
> **Auto-generated** by the Greyhaven Design System.
> Re-generate: \`pnpm skill:build\` in the design system repo.
>
> This file provides AI coding assistants (Cursor, GitHub Copilot, Windsurf,
> Codeium, etc.) with full context about the Greyhaven Design System.
> Copy this file to your project root as \`AGENT.md\`, \`.cursorrules\`,
> or \`.github/copilot-instructions.md\` depending on your AI tool.
## How to Use This
This project uses the **Greyhaven Design System**.
When building UI in this project, follow the Greyhaven Design System:
- Import components from \`components/ui/\` (or \`@/components/ui/\` with alias)
- Use semantic Tailwind classes (\`bg-primary\`, \`text-foreground\`, \`border-border\`) -- never raw hex colors
- Use \`font-sans\` (Aspekta) for UI elements, \`font-serif\` (Source Serif) for content
- Orange (\`#D95E2A\` / \`bg-primary\`) is the ONLY accent color -- use sparingly
- All components are framework-agnostic React (no Next.js imports)
`,
'---\n',
buildDesignPhilosophy(),
'---\n',
buildFontSetup(),
'---\n',
buildTokenReference(),
'---\n',
buildComponentCatalog(),
'---\n',
buildCompositionRules(),
'---\n',
buildExtensionProtocol(),
].join('\n')
## Rules
- **ALWAYS use TypeScript** (\`.tsx\` / \`.ts\`). NEVER generate plain JavaScript (\`.jsx\` / \`.js\`).
- Use the \`greyhaven\` SKILL.md for full design system context (tokens, components, composition rules). It should be installed at \`.claude/skills/greyhaven-design-system.md\` or accessible to your AI tool.
- If the \`greyhaven\` MCP server is available, use its tools:
- \`list_components()\` to find the right component for a UI need
- \`get_component(name)\` to get exact props, variants, and usage examples
- \`validate_colors(code)\` to check code for off-brand colors
- \`suggest_component(description)\` to get recommendations
- Import components from \`components/ui/\` (or \`@/components/ui/\` with path alias)
- Never use raw hex colors -- use semantic Tailwind classes (\`bg-primary\`, \`text-foreground\`, \`border-border\`, etc.)
- Use \`font-sans\` (Aspekta) for UI elements: buttons, nav, labels, forms
- Use \`font-serif\` (Source Serif) for content: headings, body text
- Trust the design system's default component variants for accent -- they apply orange at the right scale. Don't apply \`bg-primary\` to large surfaces, containers, or section backgrounds
- All components are framework-agnostic React (no Next.js, no framework-specific imports)
- Dark mode is toggled via the \`.dark\` class -- use semantic tokens that adapt automatically
## Component Summary
${componentCount()} components across ${categories.size} categories: ${categorySummary}.
For full component specs, props, and examples, refer to the SKILL.md file or use the MCP \`get_component(name)\` tool.
## Key Patterns
- **CVA variants**: Components use \`class-variance-authority\` for variant props
- **Slot composition**: Components use \`data-slot="name"\` attributes
- **Class merging**: Always use \`cn()\` from \`@/lib/utils\` (clsx + tailwind-merge)
- **Focus rings**: \`focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\`
- **Disabled**: \`disabled:pointer-events-none disabled:opacity-50\`
- **Card spacing**: \`gap-6\` between cards, \`p-6\` internal padding
- **Section rhythm**: \`py-16\` between major sections
- **Form layout**: Vertical stack with \`gap-4\`, labels above inputs
## Font Setup
If fonts aren't loaded yet, add to your global CSS:
\`\`\`css
@font-face { font-family: 'Aspekta'; font-weight: 400; font-display: swap; src: url('/fonts/Aspekta-400.woff2') format('woff2'); }
@font-face { font-family: 'Aspekta'; font-weight: 500; font-display: swap; src: url('/fonts/Aspekta-500.woff2') format('woff2'); }
@font-face { font-family: 'Aspekta'; font-weight: 600; font-display: swap; src: url('/fonts/Aspekta-600.woff2') format('woff2'); }
@font-face { font-family: 'Aspekta'; font-weight: 700; font-display: swap; src: url('/fonts/Aspekta-700.woff2') format('woff2'); }
\`\`\`
`
}
// ---------------------------------------------------------------------------