
Design Guide
- 229k installs
- 9 repo stars
- Updated July 20, 2026
- getpaperclipai/paperclip
How to build consistent, reusable React UI components following Paperclip's design language, token system, and composition patterns.
About
Paperclip Design Guide is a comprehensive UI design system for a professional control-plane frontend built with React 19, TypeScript, Tailwind CSS v4, and shadcn/ui. It defines design principles (dense, keyboard-driven, dark-themed), establishes reusable component hierarchy in three tiers (primitives, custom composites, pages), and specifies composition patterns for entity rows, status systems, metrics, and layouts. Developers use this when creating new UI components, modifying existing ones, or styling pages. The /design-guide showcase page serves as the living source of truth; any new reusable component must be added there. Always pair with frontend-design and web-design-guidelines skills.
- Design tokens as CSS variables in OKLCH color space; semantic names (--background, --primary, --destructive) replace raw
- Three-tier component hierarchy: shadcn/ui primitives, Paperclip custom composites (StatusBadge, EntityRow, MetricCard),
- Composition patterns for common UI structures: entity rows with status/priority icons, grouped lists, property rows, met
- Status and priority systems with consistent color mappings across all entity types (agents, issues, approvals); priority
- /design-guide page at /design-guide is mandatory source of truth; any new reusable component must be added with all vari
Design Guide by the numbers
- 228,707 all-time installs (skills.sh)
- +114,489 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #7 of 1,896 Design & UI/UX skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
design-guide capabilities & compatibility
- Capabilities
- define and enforce design tokens as css variable · document component variants and composition patt · map status and priority colors consistently acro · generate reusable component scaffolding and inde · audit existing components against design guide s
- Works with
- github
- Use cases
- ui design · frontend · code review
- Platforms
- macOS · Windows · Linux
- Runs
- Runs locally
- Pricing
- Free
npx skills add https://github.com/getpaperclipai/paperclip --skill design-guideAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 229k |
|---|---|
| repo stars | ★ 9 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 20, 2026 |
| Repository | getpaperclipai/paperclip ↗ |
What it does
Build and maintain consistent React UI components using Paperclip's design system tokens, typography, and composition patterns.
Who is it for?
Frontend developers building or extending React components in a design-system-first codebase; teams maintaining a professional, dense, keyboard-driven UI.
Skip if: Backend API development, mobile app design (native), single-page one-off styling without reusable patterns.
When should I use this skill?
Creating new UI components, modifying existing component APIs, adding pages or features to the frontend, styling UI elements, needing to understand design language and conventions.
What you get
Developers build UI components and pages that conform to established design tokens, typography scale, status/priority systems, and composition patterns, with all reusable components documented in the /design-guide showca
- Reusable component code following tier hierarchy
- Updated /design-guide page sections
- Component index reference documentation
By the numbers
- Three-tier component hierarchy: shadcn/ui primitives, custom composites, page components
- 13 status colors mapped across 9 entity types with consistent semantics
- Single --radius variable with 5 derived rounded sizes (sm, md, lg, xl, full)
Files
Paperclip Design Guide
Paperclip's UI is a professional-grade control plane — dense, keyboard-driven, dark-themed by default. Every pixel earns its place.
Always use with: frontend-design (visual polish) and web-design-guidelines (web best practices).
---
1. Design Principles
- Dense but scannable. Maximum information without clicks to reveal. Whitespace separates, not pads.
- Keyboard-first. Global shortcuts (Cmd+K, C, [, ]). Power users rarely touch the mouse.
- Contextual, not modal. Inline editing over dialog boxes. Dropdowns over page navigations.
- Dark theme default. Neutral grays (OKLCH), not pure black. Accent colors for status/priority only. Text is the primary visual element.
- Component-driven. Prefer reusable components that capture style conventions. Build at the right abstraction — not too granular, not too monolithic.
---
2. Tech Stack
- React 19 + TypeScript + Vite
- Tailwind CSS v4 with CSS variables (OKLCH color space)
- shadcn/ui (new-york style, neutral base, CSS variables enabled)
- Radix UI primitives (accessibility, focus management)
- Lucide React icons (16px nav, 14px inline)
- class-variance-authority (CVA) for component variants
- clsx + tailwind-merge via
cn()utility
Config: ui/components.json (aliases: @/components, @/components/ui, @/lib, @/hooks)
---
3. Design Tokens
All tokens defined as CSS variables in ui/src/index.css. Both light and dark themes use OKLCH.
Colors
Use semantic token names, never raw color values:
| Token | Usage |
|---|---|
--background / --foreground | Page background and primary text |
--card / --card-foreground | Card surfaces |
--primary / --primary-foreground | Primary actions, emphasis |
--secondary / --secondary-foreground | Secondary surfaces |
--muted / --muted-foreground | Subdued text, labels |
--accent / --accent-foreground | Hover states, active nav items |
--destructive | Destructive actions |
--border | All borders |
--ring | Focus rings |
--sidebar-* | Sidebar-specific variants |
--chart-1 through --chart-5 | Data visualization |
Radius
Single --radius variable (0.625rem) with derived sizes:
rounded-sm— small inputs, pillsrounded-md— buttons, inputs, small componentsrounded-lg— cards, dialogsrounded-xl— card containers, large componentsrounded-full— badges, avatars, status dots
Shadows
Minimal shadows: shadow-xs (outline buttons), shadow-sm (cards). No heavy shadows.
---
4. Typography Scale
Use these exact patterns — do not invent new ones:
| Pattern | Classes | Usage |
|---|---|---|
| Page title | text-xl font-bold | Top of pages |
| Section title | text-lg font-semibold | Major sections |
| Section heading | text-sm font-semibold text-muted-foreground uppercase tracking-wide | Section headers in design guide, sidebar |
| Card title | text-sm font-medium or text-sm font-semibold | Card headers, list item titles |
| Body | text-sm | Default body text |
| Muted | text-sm text-muted-foreground | Descriptions, secondary text |
| Tiny label | text-xs text-muted-foreground | Metadata, timestamps, property labels |
| Mono identifier | text-xs font-mono text-muted-foreground | Issue keys (PAP-001), CSS vars |
| Large stat | text-2xl font-bold | Dashboard metric values |
| Code/log | font-mono text-xs | Log output, code snippets |
---
5. Status & Priority Systems
Status Colors (consistent across all entities)
Defined in StatusBadge.tsx and StatusIcon.tsx:
| Status | Color | Entity types |
|---|---|---|
| active, achieved, completed, succeeded, approved, done | Green shades | Agents, goals, issues, approvals |
| running | Cyan | Agents |
| paused | Orange | Agents |
| idle, pending | Yellow | Agents, approvals |
| failed, error, rejected, blocked | Red shades | Runs, agents, approvals, issues |
| archived, planned, backlog, cancelled | Neutral gray | Various |
| todo | Blue | Issues |
| in_progress | Indigo | Issues |
| in_review | Violet | Issues |
Priority Icons
Defined in PriorityIcon.tsx: critical (red/AlertTriangle), high (orange/ArrowUp), medium (yellow/Minus), low (blue/ArrowDown).
Agent Status Dots
Inline colored dots: running (cyan, animate-pulse), active (green), paused (yellow), error (red), offline (neutral).
---
6. Component Hierarchy
Three tiers:
1. shadcn/ui primitives (ui/src/components/ui/) — Button, Card, Input, Badge, Dialog, Tabs, etc. Do not modify these directly; extend via composition. 2. Custom composites (ui/src/components/) — StatusBadge, EntityRow, MetricCard, etc. These capture Paperclip-specific design language. 3. Page components (ui/src/pages/) — Compose primitives and composites into full views.
See [references/component-index.md](references/component-index.md) for the complete component inventory with usage guidance.
When to Create a New Component
Create a reusable component when:
- The same visual pattern appears in 2+ places
- The pattern has interactive behavior (status changing, inline editing)
- The pattern encodes domain logic (status colors, priority icons)
Do NOT create a component for:
- One-off layouts specific to a single page
- Simple className combinations (use Tailwind directly)
- Thin wrappers that add no semantic value
---
7. Composition Patterns
These patterns describe how components work together. They may not be their own component, but they must be used consistently across the app.
Entity Row with Status + Priority
The standard list item for issues and similar entities:
<EntityRow
leading={<><StatusIcon status="in_progress" /><PriorityIcon priority="high" /></>}
identifier="PAP-001"
title="Implement authentication flow"
subtitle="Assigned to Agent Alpha"
trailing={<StatusBadge status="in_progress" />}
onClick={() => {}}
/>Leading slot always: StatusIcon first, then PriorityIcon. Trailing slot: StatusBadge or timestamp.
Grouped List
Issues grouped by status header + entity rows:
<div className="flex items-center gap-2 px-4 py-2 bg-muted/50 rounded-t-md">
<StatusIcon status="in_progress" />
<span className="text-sm font-medium">In Progress</span>
<span className="text-xs text-muted-foreground ml-1">2</span>
</div>
<div className="border border-border rounded-b-md">
<EntityRow ... />
<EntityRow ... />
</div>Property Row
Key-value pairs in properties panels:
<div className="flex items-center justify-between py-1.5">
<span className="text-xs text-muted-foreground">Status</span>
<StatusBadge status="active" />
</div>Label is always text-xs text-muted-foreground, value on the right. Wrap in a container with space-y-1.
Metric Card Grid
Dashboard metrics in a responsive grid:
<div className="grid md:grid-cols-2 xl:grid-cols-4 gap-4">
<MetricCard icon={Bot} value={12} label="Active Agents" description="+3 this week" />
...
</div>Progress Bar (Budget)
Color by threshold: green (<60%), yellow (60-85%), red (>85%):
<div className="w-full h-2 bg-muted rounded-full overflow-hidden">
<div className="h-full rounded-full bg-green-400" style={{ width: `${pct}%` }} />
</div>Comment Thread
Author header (name + timestamp) then body, in bordered cards with space-y-3. Add comment textarea + button below.
Cost Table
Standard <table> with text-xs, header row with bg-accent/20, font-mono for numeric values.
Log Viewer
bg-neutral-950 rounded-lg p-3 font-mono text-xs container. Color lines by level: default (foreground), WARN (yellow-400), ERROR (red-400), SYS (blue-300). Include live indicator dot when streaming.
---
8. Interactive Patterns
Hover States
- Entity rows:
hover:bg-accent/50 - Nav items:
hover:bg-accent/50 hover:text-accent-foreground - Active nav:
bg-accent text-accent-foreground
Focus
focus-visible:ring-ring focus-visible:ring-[3px] — standard Tailwind focus-visible ring.
Disabled
disabled:opacity-50 disabled:pointer-events-none
Inline Editing
Use InlineEditor component — click text to edit, Enter saves, Escape cancels.
Popover Selectors
StatusIcon and PriorityIcon use Radix Popover for inline selection. Follow this pattern for any clickable property that opens a picker.
---
9. Layout System
Three-zone layout defined in Layout.tsx:
┌──────────┬──────────────────────────────┬──────────────────────┐
│ Sidebar │ Breadcrumb bar │ │
│ (w-60) ├──────────────────────────────┤ Properties panel │
│ │ Main content (flex-1) │ (w-80, optional) │
└──────────┴──────────────────────────────┴──────────────────────┘- Sidebar:
w-60, collapsible, contains CompanySwitcher + SidebarSections - Properties panel:
w-80, shown on detail views, hidden on lists - Main content: scrollable,
flex-1
---
10. The /design-guide Page
Location: ui/src/pages/DesignGuide.tsx Route: /design-guide
This is the living showcase of every component and pattern in the app. It is the source of truth for how things look.
Rules
1. When you add a new reusable component, you MUST add it to the design guide page. Show all variants, sizes, and states. 2. When you modify an existing component's API, update its design guide section. 3. When you add a new composition pattern, add a section demonstrating it. 4. Follow the existing structure: <Section title="..."> wrapper with <SubSection> for grouping. 5. Keep sections ordered logically: foundational (colors, typography) first, then primitives, then composites, then patterns.
Adding a New Section
<Section title="My New Component">
<SubSection title="Variants">
{/* Show all variants */}
</SubSection>
<SubSection title="Sizes">
{/* Show all sizes */}
</SubSection>
<SubSection title="States">
{/* Show interactive/disabled states */}
</SubSection>
</Section>---
11. Component Index
See [references/component-index.md](references/component-index.md) for the full component inventory.
When you create a new reusable component: 1. Add it to the component index reference file 2. Add it to the /design-guide page 3. Follow existing naming and file conventions
---
12. File Conventions
- shadcn primitives:
ui/src/components/ui/{component}.tsx— lowercase, kebab-case - Custom components:
ui/src/components/{ComponentName}.tsx— PascalCase - Pages:
ui/src/pages/{PageName}.tsx— PascalCase - Utilities:
ui/src/lib/{name}.ts - Hooks:
ui/src/hooks/{useName}.ts - API modules:
ui/src/api/{entity}.ts - Context providers:
ui/src/context/{Name}Context.tsx
All components use cn() from @/lib/utils for className merging. All components use CVA for variant definitions when they have multiple visual variants.
---
13. Common Mistakes to Avoid
- Using raw hex/rgb colors instead of CSS variable tokens
- Creating ad-hoc typography styles instead of using the established scale
- Hardcoding status colors instead of using StatusBadge/StatusIcon
- Building one-off styled elements when a reusable component exists
- Adding components without updating the design guide page
- Using
shadow-mdor heavier — keep shadows minimal (xs, sm only) - Using
rounded-2xlor larger — max isrounded-xl(exceptrounded-fullfor pills) - Forgetting dark mode — always use semantic tokens, never hardcode light/dark values
Paperclip Component Index
Complete inventory of all UI components. Update this file when adding new reusable components.
---
Table of Contents
1. shadcn/ui Primitives 2. Custom Components 3. Layout Components 4. Dialog & Form Components 5. Property Panel Components 6. Agent Configuration 7. Utilities & Hooks
---
shadcn/ui Primitives
Location: ui/src/components/ui/
These are shadcn/ui base components. Do not modify directly — extend via composition.
| Component | File | Key Props | Notes |
|---|---|---|---|
| Button | button.tsx | variant (default, secondary, outline, ghost, destructive, link), size (xs, sm, default, lg, icon, icon-xs, icon-sm, icon-lg) | Primary interactive element. Uses CVA. |
| Card | card.tsx | CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter | Compound component. py-6 default padding. |
| Input | input.tsx | disabled | Standard text input. |
| Badge | badge.tsx | variant (default, secondary, outline, destructive, ghost) | Generic label/tag. For status, use StatusBadge instead. |
| Label | label.tsx | — | Form label, wraps Radix Label. |
| Select | select.tsx | Trigger, Content, Item, etc. | Radix-based dropdown select. |
| Separator | separator.tsx | orientation (horizontal, vertical) | Divider line. |
| Checkbox | checkbox.tsx | checked, onCheckedChange | Radix checkbox with indicator. |
| Textarea | textarea.tsx | Standard textarea props | Multi-line input. |
| Avatar | avatar.tsx | size (sm, default, lg). Includes AvatarGroup, AvatarGroupCount | Image or fallback initials. |
| Breadcrumb | breadcrumb.tsx | BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator, BreadcrumbPage | Navigation breadcrumbs. |
| Command | command.tsx | CommandInput, CommandList, CommandGroup, CommandItem | Command palette / search. Based on cmdk. |
| Dialog | dialog.tsx | DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter | Modal overlay. |
| DropdownMenu | dropdown-menu.tsx | Trigger, Content, Item, Separator, etc. | Context/action menus. |
| Popover | popover.tsx | PopoverTrigger, PopoverContent | Floating content panel. |
| Tabs | tabs.tsx | variant (pill, line). TabsList, TabsTrigger, TabsContent | Tabbed navigation. Pill = default, line = underline style. |
| Tooltip | tooltip.tsx | TooltipTrigger, TooltipContent | Hover tooltips. App is wrapped in TooltipProvider. |
| ScrollArea | scroll-area.tsx | — | Custom scrollable container. |
| Collapsible | collapsible.tsx | CollapsibleTrigger, CollapsibleContent | Expand/collapse sections. |
| Skeleton | skeleton.tsx | className for sizing | Loading placeholder with shimmer. |
| Sheet | sheet.tsx | SheetTrigger, SheetContent, SheetHeader, etc. | Side panel overlay. |
---
Custom Components
Location: ui/src/components/
StatusBadge
File: StatusBadge.tsx Props: status: string Usage: Colored pill showing entity status. Supports 20+ statuses with mapped colors.
<StatusBadge status="in_progress" />Use for displaying status in properties panels, entity rows, and list views. Never hardcode status colors — always use this component.
StatusIcon
File: StatusIcon.tsx Props: status: string, onChange?: (status: string) => void Usage: Circle icon representing issue status. When onChange provided, opens a popover picker.
<StatusIcon status="todo" onChange={setStatus} />Supports: backlog, todo, in_progress, in_review, done, cancelled, blocked. Use in entity row leading slots and grouped list headers.
PriorityIcon
File: PriorityIcon.tsx Props: priority: string, onChange?: (priority: string) => void Usage: Priority indicator icon. Interactive when onChange provided.
<PriorityIcon priority="high" onChange={setPriority} />Supports: critical, high, medium, low. Use alongside StatusIcon in entity row leading slots.
EntityRow
File: EntityRow.tsx Props: leading, identifier, title, subtitle?, trailing?, onClick?, selected? Usage: Standard list row for issues, agents, projects. Supports hover highlight and selected state.
<EntityRow
leading={<><StatusIcon status="todo" /><PriorityIcon priority="medium" /></>}
identifier="PAP-003"
title="Write API documentation"
trailing={<StatusBadge status="todo" />}
onClick={() => navigate(`/issues/${id}`)}
/>Wrap multiple EntityRows in a border border-border rounded-md container.
MetricCard
File: MetricCard.tsx Props: icon: LucideIcon, value: string | number, label: string, description?: string Usage: Dashboard stat card with icon, large value, label, and optional description.
<MetricCard icon={Bot} value={12} label="Active Agents" description="+3 this week" />Always use in a responsive grid: grid md:grid-cols-2 xl:grid-cols-4 gap-4.
EmptyState
File: EmptyState.tsx Props: icon: LucideIcon, message: string, action?: string, onAction?: () => void Usage: Empty list placeholder with icon, message, and optional CTA button.
<EmptyState icon={Inbox} message="No items yet." action="Create Item" onAction={handleCreate} />FilterBar
File: FilterBar.tsx Props: filters: FilterValue[], onRemove: (key) => void, onClear: () => void Type: FilterValue = { key: string; label: string; value: string } Usage: Filter chip display with remove buttons and clear all.
<FilterBar filters={filters} onRemove={handleRemove} onClear={() => setFilters([])} />Identity
File: Identity.tsx Props: name: string, avatarUrl?: string, initials?: string, size?: "sm" | "default" | "lg" Usage: Avatar + name display for users and agents. Derives initials from name automatically. Three sizes matching Avatar sizes.
<Identity name="Agent Alpha" size="sm" />
<Identity name="CEO Agent" />
<Identity name="Backend Service" size="lg" avatarUrl="/img/bot.png" />Use in property rows, comment headers, assignee displays, and anywhere a user/agent reference is shown.
InlineEditor
File: InlineEditor.tsx Props: value: string, onSave: (val: string) => void, as?: string, className?: string Usage: Click-to-edit text. Renders as display text, clicking enters edit mode. Enter saves, Escape cancels.
<InlineEditor value={title} onSave={updateTitle} as="h2" className="text-xl font-bold" />PageSkeleton
File: PageSkeleton.tsx Props: variant: "list" | "detail" Usage: Full-page loading skeleton matching list or detail layout.
<PageSkeleton variant="list" />CommentThread
File: CommentThread.tsx Usage: Comment list with add-comment form. Used on issue and entity detail views.
GoalTree
File: GoalTree.tsx Usage: Hierarchical goal tree with expand/collapse. Used on the goals page.
CompanySwitcher
File: CompanySwitcher.tsx Usage: Company selector dropdown in sidebar header.
---
Layout Components
Layout
File: Layout.tsx Usage: Main app shell. Three-zone layout: Sidebar + Main content + Properties panel. Wraps all routes.
Sidebar
File: Sidebar.tsx Usage: Left navigation sidebar (w-60). Contains CompanySwitcher, search button, new issue button, and SidebarSections.
SidebarSection
File: SidebarSection.tsx Usage: Collapsible sidebar group with header label and chevron toggle.
SidebarNavItem
File: SidebarNavItem.tsx Props: Icon, label, optional badge count Usage: Individual nav item within a SidebarSection.
BreadcrumbBar
File: BreadcrumbBar.tsx Usage: Top breadcrumb navigation spanning main content + properties panel.
PropertiesPanel
File: PropertiesPanel.tsx Usage: Right-side properties panel (w-80). Closeable. Shown on detail views.
CommandPalette
File: CommandPalette.tsx Usage: Cmd+K global search modal. Searches issues, projects, agents.
---
Dialog & Form Components
NewIssueDialog
File: NewIssueDialog.tsx Usage: Create new issue with project/assignee/priority selection. Supports draft saving.
NewProjectDialog
File: NewProjectDialog.tsx Usage: Create new project dialog.
NewAgentDialog
File: NewAgentDialog.tsx Usage: Create new agent dialog.
OnboardingWizard
File: OnboardingWizard.tsx Usage: Multi-step onboarding flow for new users/companies.
---
Property Panel Components
These render inside the PropertiesPanel for different entity types:
| Component | File | Entity |
|---|---|---|
| IssueProperties | IssueProperties.tsx | Issues |
| AgentProperties | AgentProperties.tsx | Agents |
| ProjectProperties | ProjectProperties.tsx | Projects |
| GoalProperties | GoalProperties.tsx | Goals |
All follow the property row pattern: text-xs text-muted-foreground label on left, value on right, py-1.5 spacing.
---
Agent Configuration
agent-config-primitives
File: agent-config-primitives.tsx Exports: Field, ToggleField, ToggleWithNumber, CollapsibleSection, AutoExpandTextarea, DraftInput Usage: Reusable form field primitives for agent configuration forms.
AgentConfigForm
File: AgentConfigForm.tsx Usage: Full agent creation/editing form with adapter type selection.
---
Utilities & Hooks
cn() — Class Name Merger
File: ui/src/lib/utils.ts Usage: Merges class names with clsx + tailwind-merge. Use in every component.
import { cn } from "@/lib/utils";
<div className={cn("base-classes", conditional && "extra", className)} />Formatting Utilities
File: ui/src/lib/utils.ts
| Function | Usage |
|---|---|
formatCents(cents) | Money display: $12.34 |
formatDate(date) | Date display: Jan 15, 2025 |
relativeTime(date) | Relative time: 2m ago, Jan 15 |
formatTokens(count) | Token counts: 1.2M, 500k |
useKeyboardShortcuts
File: ui/src/hooks/useKeyboardShortcuts.ts Usage: Global keyboard shortcut handler. Registers Cmd+K, C, [, ], Cmd+Enter.
Query Keys
File: ui/src/lib/queryKeys.ts Usage: Structured React Query key factories for cache management.
groupBy
File: ui/src/lib/groupBy.ts Usage: Generic array grouping utility.
Related skills
Forks & variants (1)
Design Guide has 1 known copy in the catalog totaling 247 installs. They canonicalize to this original listing.
- paperclipai - 247 installs
FAQ
When should I create a new reusable component?
Create one when the same visual pattern appears in 2+ places, has interactive behavior, or encodes domain logic (like status colors). Do not create components for one-off layouts, simple className combinations, or thin wrappers.
What must I do after adding a new reusable component?
Add it to the component index reference file (references/component-index.md), add it to the /design-guide page showing all variants/sizes/states, and follow file naming conventions (PascalCase in ui/src/components/).
How do I handle colors and styling?
Use semantic CSS variable tokens (--background, --primary, --destructive, etc.) defined in ui/src/index.css, never raw hex/rgb. For component variants, use class-variance-authority (CVA) and cn() for className merging.
Is Design Guide safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.