Iconography
Brand icon, icon library reference, sizing conventions, and usage guidelines.
Origin UI Icon
The Origin UI brand mark is a Hexagon set on a bg-primary background with text-primary-foreground fill. It adapts automatically to light and dark themes.
Light Theme
Dark Theme
Size Variants
smdefaultlgxlLogo Lockup
Construction & Specifications
| Property | Value |
|---|---|
| Shape | Hexagon (lucide-react) |
| Background | bg-primary (brand-800 light / brand-100 dark) |
| Icon color | text-primary-foreground (brand-50 light / brand-950 dark) |
| Corner radius | rounded-md (sm/default) / rounded-lg (lg) / rounded-xl (xl) |
| Padding | p-1 (sm/default) / p-1.5 (lg) / p-2 (xl) |
| Min clear space | Equal to icon padding on all sides |
| Component | <OriginUiLogo /> from @/components/branding |
Icons Library
This design system uses Lucide React (lucide-react) as the sole icon library. Lucide provides 1500+ consistent, pixel-perfect SVG icons with tree-shakeable imports.
Installation & Import
import { Hexagon, Search, Check } from "lucide-react";Icon Sizing
Use Tailwind sizing utilities (size-*) on icons to keep them consistent. The recommended default is size-4 (16px) for inline use and size-5 (20px) for standalone use.
12px
14px
16px
20px
24px
32px
40px
48px
Stroke Widths
Lucide icons accept a strokeWidth prop. The default is 1.5. Adjust for visual weight in different contexts.
Thin
Default
Medium
Bold
Icon Catalog
All 58 icons currently used in this design system, organized by category. Click any icon to copy its name. For the full Lucide library, visit lucide.dev/icons.
Navigation
Actions
Status
Content
Formatting
Users
Analytics
Feature
Brand
Design Guidelines
Do
- Use size-4 for icons inside buttons and inputs. 16px is the standard inline size that aligns with text and maintains optical balance within interactive elements.
- Use size-5 for standalone icon buttons. 20px gives icon-only actions enough visual weight to be recognizable without a text label.
- Keep strokeWidth at default (1.5). The default weight is optimized for legibility across all sizes. Only adjust in specific UI contexts like toolbars.
- Import icons individually for tree-shaking. Named imports like
import { Check } from "lucide-react"keep bundle size minimal. - Apply color via text-* utilities. Lucide icons inherit
currentColorby default. Usetext-foreground,text-muted-foreground, etc.
Don't
- Don't mix icon libraries. Using Font Awesome, Heroicons, or other libraries alongside Lucide creates visual inconsistency in stroke weight and style.
- Don't use inline SVGs when a Lucide icon exists. Custom SVGs bypass the icon system and won't match the stroke weight, sizing, or color inheritance of Lucide icons.
- Don't apply fill to stroke-based icons. Lucide icons are designed as stroked paths. Adding
filldistorts them. Usetext-*to change stroke color. - Don't use icons smaller than size-3 (12px). Below 12px, stroke details become indistinguishable and icons lose meaning, especially at non-retina resolutions.
- Don't use icon-only buttons without accessible labels. Always add
aria-labelor asr-onlyspan so screen readers can announce the action.
Developer Reference
Accessibility
- Decorative icons (next to text labels) should have
aria-hidden="true"to avoid redundant announcements. - Icon-only buttons must include an accessible name via
aria-labelor a<span className="sr-only">Label</span>inside the button. - Icons used to convey meaning (status, alerts) should be accompanied by text or
aria-label— color and shape alone are not sufficient for screen readers. - Use
type LucideIconfromlucide-reactfor typing icon props in reusable components.
Usage
import { Search, Check, ChevronRight, type LucideIcon } from "lucide-react"
// Inline icon (inside button)
<Button>
<Search className="size-4" data-icon="inline-start" />
Search
</Button>
// Standalone icon button
<Button size="icon" variant="ghost" aria-label="Settings">
<Settings className="size-5" />
</Button>
// Icon with custom color
<Check className="size-4 text-success" />
<AlertCircle className="size-4 text-error" />
// Icon sizing
<Hexagon className="size-3" /> {/* 12px — minimum */}
<Hexagon className="size-4" /> {/* 16px — inline default */}
<Hexagon className="size-5" /> {/* 20px — standalone default */}
<Hexagon className="size-6" /> {/* 24px — large */}
// Stroke width adjustment
<Hexagon strokeWidth={1} /> {/* Thin */}
<Hexagon strokeWidth={1.5} /> {/* Default */}
<Hexagon strokeWidth={2} /> {/* Medium */}
// Typing icon props
interface NavItemProps {
icon: LucideIcon
label: string
}
function NavItem({ icon: Icon, label }: NavItemProps) {
return (
<div className="flex items-center gap-2">
<Icon className="size-4" />
<span>{label}</span>
</div>
)
}