04 · Foundations
Iconography
Lucide is the icon library: restrained outlines, a consistent 1.5px default stroke, and a small set of rules. It covers the functional icons you’ll need, while arrow-up-right remains the signature gesture on text actions and external links.
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 a quiet underlined action, the border darkens as the arrow moves.
Hover the underlined text link to see the rule darken and the arrow nudge.
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: present, but never heavy.
Coloring rules
- Default:
currentColor. Icons inherit the surrounding text color — usually--text-mutedfor inactive states,--foregroundfor primary contexts. - Active / emphasized:
--accent(graphite). For selected sidebar items, active toggles, and primary controls. - 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: 1.5 for web UI. Keep the outline clear and restrained.
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: