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

sm
default
lg
xl

Logo Lockup

Origin UI
Origin UI
Origin UI

Construction & Specifications

PropertyValue
ShapeHexagon (lucide-react)
Backgroundbg-primary (brand-800 light / brand-100 dark)
Icon colortext-primary-foreground (brand-50 light / brand-950 dark)
Corner radiusrounded-md (sm/default) / rounded-lg (lg) / rounded-xl (xl)
Paddingp-1 (sm/default) / p-1.5 (lg) / p-2 (xl)
Min clear spaceEqual 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 currentColor by default. Use text-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 fill distorts them. Use text-* 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-label or a sr-only span 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-label or 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 LucideIcon from lucide-react for 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>
  )
}