Colors
Semantic token guideA reference list of Airy semantic color tokens and primitive ramps. Prefer semantic tokens for UI usage, and use raw primitive values only for one-off, highly specific color needs.
background Main application canvas. | var(--color-white) | var(--color-deep-abyss-900) |
foreground Default text and icon color. | var(--color-neutral-900) | var(--color-neutral-100) |
card Elevated container surfaces. | var(--color-white) | var(--color-deep-abyss-800) |
card-foreground Text and icon color on card surfaces. | var(--color-neutral-900) | var(--color-neutral-100) |
popover Popover, menu, and dropdown surfaces. | var(--color-white) | var(--color-deep-abyss-800) |
popover-foreground Text and icon color on popover surfaces. | var(--color-neutral-900) | var(--color-neutral-100) |
primary Primary actions and emphasis. | var(--color-green-900) | var(--color-mint-400) |
primary-foreground Text and icon color on primary surfaces. | var(--color-white) | var(--color-neutral-950) |
secondary Lower-emphasis actions and supportive surfaces. | oklch(var(--primitive-neutral-900) / 10%) | var(--color-deep-abyss-700) |
secondary-foreground Text and icon color on secondary surfaces. | var(--color-neutral-900) | var(--color-neutral-100) |
muted Subdued backgrounds for low-priority content. | var(--color-neutral-100) | var(--color-deep-abyss-700) |
muted-foreground Text and icon color on muted surfaces. | var(--color-neutral-500) | var(--color-neutral-400) |
accent Interactive hover/active emphasis surfaces. | oklch(var(--primitive-neutral-900) / 10%) | var(--color-deep-abyss-500) |
accent-foreground Text and icon color on accent surfaces. | var(--color-neutral-900) | var(--color-neutral-100) |
destructive Error and dangerous actions. | var(--color-red-700) | var(--color-red-400) |
destructive-foreground Text and icon color on destructive surfaces. | var(--color-white) | var(--color-white) |
border Default dividers and component outlines. | oklch(var(--primitive-black) / 10%) | oklch(var(--primitive-white) / 10%) |
input Input and control chrome. | var(--color-neutral-200) | oklch(var(--primitive-white) / 15%) |
ring Focus ring and active outline color. | var(--color-neutral-400) | var(--color-deep-abyss-200) |
sidebar Sidebar base surface. | var(--color-mud-50) | var(--color-deep-abyss-950) |
sidebar-foreground Text and icon color on sidebar surfaces. | var(--color-neutral-900) | var(--color-neutral-300) |
sidebar-primary Sidebar-specific semantic color token. | var(--color-neutral-900) | var(--color-deep-abyss-50) |
sidebar-primary-foreground Text and icon color on sidebar primary surfaces. | var(--color-neutral-900) | var(--color-neutral-950) |
sidebar-accent Sidebar-specific semantic color token. | oklch(var(--primitive-neutral-500) / 10%) | var(--color-deep-abyss-600) |
sidebar-accent-foreground Text and icon color on sidebar accent surfaces. | var(--color-neutral-900) | var(--color-neutral-50) |
sidebar-border Border color for sidebar UI. | oklch(var(--primitive-black) / 10%) | oklch(var(--primitive-white) / 10%) |
sidebar-ring Sidebar-specific semantic color token. | var(--color-neutral-400) | var(--color-deep-abyss-200) |
success-background Background surface color for success UI. | var(--color-success-50) | var(--color-success-700) |
success-foreground Text and icon color on success surfaces. | var(--color-success-700) | var(--color-success-200) |
success-border Border color for success UI. | oklch(var(--primitive-black) / 2%) | oklch(var(--primitive-white) / 10%) |
info-background Background surface color for info UI. | var(--levender-background) | var(--levender-background) |
info-foreground Text and icon color on info surfaces. | var(--levender-foreground) | var(--levender-foreground) |
info-border Border color for info UI. | var(--levender-border) | var(--levender-border) |
ai-background AI and automation feedback surfaces. | var(--color-mint-50) | var(--color-mint-200) |
ai-foreground Text and icons on AI feedback surfaces. | var(--color-mint-600) | var(--color-mint-800) |
ai-border Borders for AI feedback surfaces. | var(--color-mint-200) | var(--color-mint-800) |
warning-background Background surface color for warning UI. | var(--color-warning-100) | var(--color-warning-900) |
warning-foreground Text and icon color on warning surfaces. | var(--color-warning-700) | var(--color-warning-300) |
warning-border Border color for warning UI. | oklch(var(--primitive-black) / 2%) | oklch(var(--primitive-white) / 10%) |
error-background Background surface color for error UI. | var(--color-error-100) | var(--color-error-700) |
error-foreground Text and icon color on error surfaces. | var(--color-error-700) | var(--color-error-300) |
error-border Border color for error UI. | oklch(var(--primitive-black) / 2%) | oklch(var(--primitive-white) / 10%) |
levender-background Background surface color for levender UI. | var(--color-levender-50) | var(--color-levender-800) |
levender-foreground Text and icon color on levender surfaces. | var(--color-levender-800) | var(--color-levender-400) |
levender-border Border color for levender UI. | oklch(var(--primitive-black) / 5%) | oklch(var(--primitive-white) / 15%) |
banner-default-background Background surface color for banner default UI. | var(--color-mud-50) | var(--color-terra-800) |
banner-default-foreground Text and icon color on banner default surfaces. | var(--color-mud-950) | var(--color-neutral-400) |
banner-default-border Border color for banner default UI. | oklch(var(--primitive-black) / 2%) | oklch(var(--primitive-white) / 10%) |
chart-1 Data visualization series color. | var(--color-purple-300) | var(--color-violet-500) |
chart-2 Data visualization series color. | var(--color-blue-400) | var(--color-blue-400) |
chart-3 Data visualization series color. | var(--color-green-300) | var(--color-orange-300) |
chart-4 Data visualization series color. | var(--color-red-400) | var(--color-green-300) |
chart-5 Data visualization series color. | var(--color-yellow-200) | var(--color-fuchsia-200) |
cta Semantic color token. | var(--color-green-700) | var(--color-green-200) |
cta-hover Semantic color token. | var(--color-green-800) | var(--color-green-300) |
shadow-2xl Semantic color token. | 0 25px 50px -12px rgb(0 0 0 / 0.25) | — |
shadow-2xs Semantic color token. | 0 1px rgb(0 0 0 / 0.03) | — |
shadow-lg Semantic color token. | 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1) | — |
shadow-md Semantic color token. | 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1) | — |
shadow-sm Semantic color token. | 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1) | — |
shadow-xl Semantic color token. | 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1) | — |
shadow-xs Semantic color token. | 0 1px 2px 0 rgb(0 0 0 / 0.03) | — |
success Semantic color token. | var(--color-emerald-600) | var(--color-green-400) |
Primitive ramps (reference)
Full ramps for building and evolving semantic tokens.
Airy custom palettes
neutral-*abyss-*terra-*green-*mint-*mud-*levender-*Status palettes
info-*success-*warning-*error-*Standard utility palettes
red-*orange-*amber-*yellow-*emerald-*cyan-*blue-*violet-*purple-*rose-*Typography
Type scale and font styles used across the design system.
Heading 1
text-4xl font-semibold tracking-tight lg:text-5xlHeading 2
text-3xl font-semibold tracking-tightHeading 3
text-2xl font-semibold tracking-tightHeading 4
text-xl font-semibold tracking-tightBody text. The king thought long and hard, and finally came up with a brilliant plan: he would host a royal banquet.
leading-7Muted text for secondary information.
text-sm text-muted-foregroundSmall text with medium weight.
text-sm font-mediumSpacing
Spacing scale tokens used across the design system.
00.25rem0.5rem0.75rem1rem1.25rem1.5rem2rem2.5rem3rem4rem5rem6remGradients & animations
Theme utilitiesShared Airy utilities for brand text, AI gradients, border beams, streaming states, and motion-safe loading affordances.
Borrower patterns
These examples mirror the production patterns from borrower portal: the chat launcher, lender loading state, credit surfaces, and shared-with-Lev mark.
<span className="gradient-brand text-sm font-medium">Shared with Lev</span><div className="flex flex-wrap items-center gap-3">
<Button
className="border-beam-hover gradient-ai-hover h-8 gap-1.5 border-0 bg-clip-border px-2.5 text-sm font-medium"
type="button"
variant="ghost"
>
<AiSparkIcon beam="hover" className="size-4" id="ai-action-icon" linearWipe />
<span className="animate-linear-wipe gradient-ai-text-hover">Lev Agent</span>
</Button>
<Button className="gradient-ai-hover text-ai-foreground" type="button" variant="outline">
<AiSparkIcon beam="hover" className="size-3" id="ai-upload-icon" />
<span className="gradient-ai-text-hover">Upload with AI</span>
</Button>
</div>Analyzing lender matches and recent activity
<p className="animate-streaming text-sm font-medium text-ai-foreground">
Analyzing lender matches and recent activity
</p><div className="flex items-center gap-3">
<AiSparkIcon className="size-8 animate-morphing-rotate text-ai-foreground" id="ai-loading-icon" />
<div className="flex items-center gap-1" aria-label="Loading">
<span className="size-1.5 rounded-full bg-mint-500/60 motion-safe:animate-[typing-dot_1.2s_ease-in-out_infinite]" />
<span className="size-1.5 rounded-full bg-mint-500/60 motion-safe:animate-[typing-dot_1.2s_ease-in-out_infinite] motion-safe:[animation-delay:200ms]" />
<span className="size-1.5 rounded-full bg-mint-500/60 motion-safe:animate-[typing-dot_1.2s_ease-in-out_infinite] motion-safe:[animation-delay:400ms]" />
</div>
</div>Facts extracted
24 fields reviewed
Credit balance
Beam fill remains visible
<div className="grid gap-3 sm:grid-cols-2">
<div className="surface-ai flex items-center gap-3 rounded-xl px-4 py-3">
<span className="grid size-9 place-items-center rounded-full bg-mint/30 text-ai-foreground">
<Sparkles className="size-4" />
</span>
<div className="space-y-0.5">
<p className="text-sm font-medium">Facts extracted</p>
<p className="text-xs text-muted-foreground">24 fields reviewed</p>
</div>
</div>
<div className="border-beam flex items-center gap-3 rounded-xl px-4 py-3">
<AiSparkIcon beam="always" className="size-5 text-ai-foreground" id="ai-surface-credit-icon" />
<div className="space-y-0.5">
<p className="text-sm font-medium">Credit balance</p>
<p className="text-xs text-muted-foreground">Beam fill remains visible</p>
</div>
</div>
</div>Utility reference
gradient-brandAnimated brand gradient text.
gradient-ai-hoverParent hover state for AI gradient text and icon fills.
gradient-ai-text-hoverChild text that clips to the AI gradient on hover.
animate-linear-wipeOne-shot AI gradient sweep for short labels.
animate-streamingContinuous shimmer for streaming status text.
animate-morphing-rotateRotating mark animation for active AI loading states.
surface-aiAlways-on AI beam surface with subdued glow.
border-beam / border-beam-hoverConic border beam for cards and hover states.
svg-beam-fillSVG fill hook for AI icons using gradient stops.
Icons
1671 iconsAiry uses Lucide for all iconography. Click any icon to copy its import statement.
Usage
Import icons individually from lucide-react:
import { ChevronRight, Search, Settings } from "lucide-react"
<Search className="size-4" />
<Settings className="size-5 text-muted-foreground" />For icon props in component interfaces, use the LucideIcon type:
import { type LucideIcon } from "lucide-react"
interface NavItem {
title: string
icon: LucideIcon
}