Claude-skill-registry brief-design

Brief-specific design system, typography, colors, and component patterns

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/brief-design" ~/.claude/skills/majiayu000-claude-skill-registry-brief-design && rm -rf "$T"
manifest: skills/data/brief-design/SKILL.md
source content

Brief Design Skill

Use this skill when creating or modifying UI components. Brief has a complete design system—always use it instead of inventing new patterns.

Quick Reference

CategoryUseAvoid
Sans font
font-sans
(Spline Sans)
Inter, Roboto, Arial, system fonts
Serif font
font-serif
(Piazzolla)
Times, Georgia
Mono font
font-mono
(Spline Sans Mono)
Courier, Monaco
Primary color
bg-primary
(fern green)
Purple gradients, arbitrary hex
Focus rings
ring-ring
(sky-blue)
Custom ring colors
Components
@/components/ui/*
Custom from-scratch implementations

Typography

Font Families

Brief uses three font families configured in

web/lib/fonts.ts
:

// ✅ Correct - use CSS variables
<h1 className="font-sans">Spline Sans (default)</h1>
<blockquote className="font-serif">Piazzolla for accents</blockquote>
<code className="font-mono">Spline Sans Mono</code>

// ❌ Wrong - hardcoded fonts
<h1 style={{ fontFamily: 'Inter' }}>Never do this</h1>

Semantic Typography Classes

Use these predefined classes from

globals.css
instead of ad-hoc combinations:

ClassSizeWeightUse For
.large-title
3xlnormalHero headlines
.large-title-heavy
3xlsemiboldEmphasized headlines
.title-1
2xlnormalPage titles
.title-2
xlnormalSection headers
.title-3
lgnormalCard headers
.body
basenormalDefault body text
.callout
smnormalSupporting info
.subhead
xsnormalLabels, metadata
.caption-1
xxsnormalFine print

Add

-heavy
suffix for semibold variants (e.g.,
.title-1-heavy
).

// ✅ Good
<h1 className="title-1">Page Title</h1>
<p className="body">Content goes here</p>

// ❌ Bad - recreating what exists
<h1 className="text-2xl font-normal tracking-tight leading-7">Page Title</h1>

Color System

Layer 1: OKLCH Primitives

All colors are OKLCH-based. Key ramps defined in

globals.css
:

  • brand-fern
    — Primary brand green (050–095 stops)
  • neutral
    — Grays for backgrounds/borders
  • sky-blue
    — Focus states and interactive chrome
// Primitive utilities (use sparingly, prefer semantics)
<div className="bg-brand-fern-050">Primary brand surface</div>
<div className="border-neutral-090">High-contrast border</div>

Layer 2: Semantic Tokens

Always prefer semantic tokens over primitives.

⚠️ CRITICAL: Only use tokens that exist. Do NOT invent tokens by pattern-matching (e.g., don't create

bg-background-secondary
because
bg-background
exists).

Complete Token Allowlist

These are the only semantic tokens available. If it's not listed, it doesn't exist:

TokenForeground VariantUsage
background
foreground
Page/app background
card
card-foreground
Card surfaces
popover
popover-foreground
Dropdowns, tooltips
primary
primary-foreground
Primary actions, CTAs
secondary
secondary-foreground
Secondary actions
muted
muted-foreground
Subdued surfaces, hint text
accent
accent-foreground
Highlighted items
destructive
destructive-foreground
Danger/delete actions
Utility TokensUsage
border
Dividers, card edges
input
Form input backgrounds
ring
Focus rings (sky-blue)
Sidebar TokensUsage
sidebar
/
sidebar-foreground
Sidebar surfaces
sidebar-primary
/
sidebar-primary-foreground
Sidebar primary
sidebar-accent
/
sidebar-accent-foreground
Sidebar highlights
sidebar-border
/
sidebar-ring
Sidebar chrome
Chart TokensUsage
chart-1
through
chart-5
Data visualization

Common Invented Tokens (DON'T USE)

// ❌ These tokens DO NOT EXIST - don't invent them
bg-background-secondary    // Use: bg-secondary
bg-background-muted        // Use: bg-muted
text-primary               // Use: text-foreground or text-primary-foreground
bg-surface                 // Use: bg-card or bg-background
text-subtle                // Use: text-muted-foreground
border-muted               // Use: border-border
bg-hover                   // Use: hover:bg-accent
// ✅ Semantic (preferred)
<Button className="bg-primary text-primary-foreground">Save</Button>
<div className="border border-border rounded-lg">Card</div>
<span className="text-muted-foreground">Optional hint</span>

// ❌ Avoid raw values
<Button className="bg-[#2d6a4f]">Save</Button>
<div style={{ borderColor: '#e5e5e5' }}>Card</div>

Focus Rings

All interactive elements use consistent focus rings:

className="focus-visible:ring-ring/50 focus-visible:ring-[3px]"

Component Reuse

CRITICAL: Search Before Creating

Before writing any component:

  1. Check
    @/components/ui/*
    (TailStack components)
  2. Search codebase:
    grep -r "ComponentName" components/
  3. Check
    packages/chat-ui/src/
    for shared components

TailStack Components

Always use existing primitives from

/components/ui/
:

// ✅ Use design system
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Card, CardHeader, CardContent } from "@/components/ui/card";

// ❌ Never recreate
const MyButton = () => <button className="px-4 py-2 bg-blue-500">...</button>;

Composition Over Duplication

Extend existing components via composition:

// ✅ Good - compose from Button
export function SubmitButton({ children, ...props }) {
  return (
    <Button variant="default" size="lg" {...props}>
      <CheckIcon className="mr-2 h-4 w-4" />
      {children}
    </Button>
  );
}

// ❌ Bad - duplicate Button internals
export function SubmitButton({ children }) {
  return (
    <button className="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground">
      <CheckIcon className="mr-2 h-4 w-4" />
      {children}
    </button>
  );
}

Anti-Patterns (AI Slop Prevention)

❌ Typography Anti-Patterns

// NEVER use these fonts
fontFamily: 'Inter'           // Generic AI default
fontFamily: 'Roboto'          // Google generic
fontFamily: 'Arial'           // System fallback
fontFamily: 'system-ui'       // Platform default
className="font-['Inter']"    // Hardcoded font

❌ Color Anti-Patterns

// NEVER use these patterns
className="bg-gradient-to-r from-purple-500 to-pink-500"  // Purple gradient slop
className="bg-indigo-600"      // Arbitrary Tailwind color
style={{ backgroundColor: '#6366f1' }}  // Hardcoded hex
className="bg-blue-500"        // Generic blue

❌ Layout Anti-Patterns

// NEVER nest cards in cards
<Card>
  <Card>  {/* Card inception = bad */}
    <CardContent>...</CardContent>
  </Card>
</Card>

// Use flat hierarchy with spacing instead
<Card>
  <CardContent className="space-y-4">
    <section>...</section>
    <section>...</section>
  </CardContent>
</Card>

❌ Component Anti-Patterns

// NEVER recreate existing components
const MyModal = ({ children }) => (
  <div className="fixed inset-0 bg-black/50 flex items-center justify-center">
    <div className="bg-white rounded-lg p-6">{children}</div>
  </div>
);
// Use: import { Dialog, DialogContent } from "@/components/ui/dialog";

// NEVER hardcode shadows
className="shadow-[0_4px_6px_rgba(0,0,0,0.1)]"
// Use: className="shadow-sm" or "shadow-md"

Icons

Brief is transitioning from Lucide to custom icons:

// Preferred - Custom Brief icons (when available)
import { BriefIcon } from "@/components/icons/react";

// Fallback - Lucide (still installed)
import { Check, X, ChevronDown } from "lucide-react";

// Icon sizing follows Button conventions
<Button size="icon">
  <Check className="h-4 w-4" />
</Button>

Spacing & Layout

Use
gap
Over Margin

// ✅ Good
<div className="flex flex-col gap-4">
  <Item />
  <Item />
</div>

// ❌ Avoid
<div className="flex flex-col">
  <Item className="mb-4" />
  <Item />
</div>

Standard Spacing Scale

GapPixelsUse For
gap-1
4pxTight groupings
gap-2
8pxRelated items
gap-4
16pxSection spacing
gap-6
24pxMajor sections
gap-8
32pxPage sections

Border Radius

className="rounded-md"   // 6px - default for inputs/buttons
className="rounded-lg"   // 8px - cards, dialogs
className="rounded-xl"   // 12px - large containers

Verification

After creating/modifying a component:

  1. Check Storybook — Run
    pnpm run storybook
    in
    packages/ui-storybook
  2. Verify tokens — Inspect computed styles, confirm OKLCH/semantic usage
  3. Test focus states — Tab through, verify ring color is sky-blue
  4. No hardcoded values — Search for hex codes, arbitrary colors

Resources

  • Design System Docs:
    docs/design/system.md
  • Storybook:
    packages/ui-storybook
    (run with
    pnpm run storybook
    )
  • UI Components:
    web/components/ui/
  • Color Tokens:
    web/app/globals.css
    (
    :root
    and
    @theme inline
    sections)
  • Font Config:
    web/lib/fonts.ts

Deep-Dive Reference Docs

For detailed context beyond this quick reference, see the

reference/
subdirectory:

DocWhen to Use
reference/typography.md
Font stack rationale, type scale, semantic classes, font loading
reference/color.md
OKLCH color architecture, token layers, contrast requirements
reference/motion.md
Animation timing, easing curves, CSS vs Motion library, a11y

Use these for edge cases, advanced patterns, or when you need to explain why a pattern exists.