04 · Foundations
Iconography
One icon library, one stroke weight, one set of rules. Lucide ships with every shadcn project and covers every functional icon you’ll need. The diagonal up-right arrow stays as the signature gesture on CTAs, links, and “read more” affordances — rendered via Lucide’s arrow-up-right.
The arrow
Path
M4 12L12 4M12 4H5M12 4V11
Viewbox
0 0 16 16
Stroke
currentColor · 1.5px
Linecap / join
round · round
Default size
14×14 (inline) · 12×12 (small)
File
assets/arrow.svg
<!-- Canonical markup --> <svg width="14" height="14" viewBox="0 0 16 16" fill="none"> <path d="M4 12L12 4M12 4H5M12 4V11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> </svg>
Hover behavior
On hover, the arrow shifts up and to the right: transform: translate(2px, -2px). The transition is 200ms ease. Paired with the pill button, the button fills and the arrow moves together.
Hover the button to see the arrow nudge and the button fill.
The icon library — Lucide
Lucide is the icon library. ~1,400 outline icons, consistent 24×24 grid, stroke-customizable. It’s shadcn’s default, so every Button, Dialog, and Select primitive already uses it.
License
ISC (same family as MIT). Free for commercial use, modification, and redistribution. No attribution required in your UI. Ship it anywhere.
Preview
Every icon renders in currentColor, so it inherits whatever text color surrounds it. Toggle through the brand palette, semantic colors, stroke weight, and size to see every variant:
Semantic colors (destructive, success, warning) are for status badges only. Previewed here to show the icon in context, not recommended as decoration.
1.5 is the brand default (matches pill button border width).
Coloring rules
- Default:
currentColor. Icons inherit the surrounding text color — usually--text-mutedfor inactive states,--foregroundfor primary contexts. - Active / emphasized:
--accent(indigo). For selected sidebar items, active toggles, primary actions. - Disabled / tertiary:
--text-faint. - Never tint a decorative icon in
--destructive,--success, or--warning. Those colors are for status badges, not icons-as-decoration.
Sizing
- 14px — inline with body text, inside small buttons
- 16px — most common; toolbars, row actions, sidebar nav
- 18–20px — featured list items, section headers
- 22–24px — empty states, hero cards, large affordances
Stroke weight: always 1.5 (matches the pill button border).
Install
Shadcn projects already have it. For React without shadcn:
npm install lucide-react
Usage:
import { Search, Settings } from 'lucide-react' <Search className="h-4 w-4" strokeWidth={1.5} />
Animated icons — Lucide Animated
Lucide Animated ships every Lucide icon with a tasteful hover or click animation, built on Motion. Same icon vocabulary, same stroke style — just alive when you need them to be. Use sparingly: marketing pages, empty states, micro-rewards. Never on dense toolbars.
License
MIT. Free for commercial use. Each icon is a copy-pasteable React component (Motion + Lucide). Installs through the shadcn CLI, so it slots into a project alongside the Shibin shadcn theme and inherits brand tokens via currentColor.
Preview
Hover any icon to play its animation. The recreations below use CSS to demonstrate the visual style — production usage installs the React components. The color and stroke toggles above apply here too.
Install
Each icon is its own component. Add one through the shadcn CLI:
pnpm dlx shadcn@latest add @lucide-animated/heart
Browse the full set at lucide-animated.com.
Usage:
import { Heart } from '@/components/ui/heart' <Heart className="text-foreground" />
When to reach for it
- Yes: primary CTA confirmations (heart on save, sparkles on AI), empty-state nudges, hero affordances on the homepage.
- No: dense toolbars, table row actions, sidebar navigation. Motion in those contexts becomes noise.
- Never both: on any single surface, pick animated or static — mixing makes the static icons feel broken.
What to avoid
Even with Lucide, a few rules stay non-negotiable:
- ×Unicode arrows (→ ↗ ➜) — use Lucide’s
arrow-up-right - ×Mixing icon libraries (no Heroicons, no Phosphor)
- ×Emoji (🚀 ✨ 👉) in UI chrome
- ×Filled / solid variants as default (outline only)
- ×Multi-color icons (always single stroke color)
- ×Stroke weights other than 1.5
If a surface seems to need more iconography, it usually needs better typography and spacing instead.
In use
Three common placements: