- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Avatar
- Badge
- Breadcrumb
- Button
- CalendarNew
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Command
- Date PickerNew
- Dialog
- Empty
- Field
- Fieldset
- Form
- Frame
- Group
- Input
- Input Group
- Kbd
- Label
- Menu
- Meter
- Number Field
- Pagination
- Popover
- Preview Card
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Skeleton
- Slider
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Toolbar
- Tooltip
Styling
A guide to styling components with our color system.
Overview
This UI library is optimized to work with specific color tokens that provide crisp, contrasted borders and enhanced visual depth. Our styling system builds upon shadcn/ui's CSS variables approach to ensure consistency and maintainability.
Our components use opaque borders instead of solid ones to ensure crisp, contrasted borders even when backgrounds lack sufficient contrast. These opaque borders mix with bottom shadows to create enhanced contrast and visual depth.
While this color system is optional, it's designed to provide optimal visual results. Using conventional color tokens may result in inconsistent borders and shadows that don't achieve the intended design quality.
Installation
See Get Started for installing with the CLI. If you prefer to add the theme manually, paste the following into your globals.css:
@theme inline {
--font-sans: var(--font-sans);
--font-heading: var(--font-heading);
--font-mono: var(--font-mono);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--animate-skeleton: skeleton 2s -1s infinite linear;
@keyframes skeleton {
to {
background-position: -200% 0;
}
}
}
:root {
--radius: 0.625rem;
--background: var(--color-white);
--foreground: var(--color-neutral-800);
--card: var(--color-white);
--card-foreground: var(--color-neutral-800);
--popover: var(--color-white);
--popover-foreground: var(--color-neutral-800);
--primary: var(--color-neutral-800);
--primary-foreground: var(--color-neutral-50);
--secondary: --alpha(var(--color-black) / 4%);
--secondary-foreground: var(--color-neutral-800);
--muted: --alpha(var(--color-black) / 4%);
--muted-foreground: color-mix(
in srgb,
var(--color-neutral-500) 90%,
var(--color-black)
);
--accent: --alpha(var(--color-black) / 4%);
--accent-foreground: var(--color-neutral-800);
--destructive: var(--color-red-500);
--destructive-foreground: var(--color-red-700);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-700);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-700);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-700);
--border: --alpha(var(--color-black) / 8%);
--input: --alpha(var(--color-black) / 10%);
--ring: var(--color-neutral-400);
--sidebar: var(--color-neutral-50);
--sidebar-foreground: color-mix(
in srgb,
var(--color-neutral-800) 64%,
var(--sidebar)
);
--sidebar-primary: var(--color-neutral-800);
--sidebar-primary-foreground: var(--color-neutral-50);
--sidebar-accent: --alpha(var(--color-black) / 4%);
--sidebar-accent-foreground: var(--color-neutral-800);
--sidebar-border: --alpha(var(--color-black) / 6%);
--sidebar-ring: var(--color-neutral-400);
}
.dark {
--background: color-mix(
in srgb,
var(--color-neutral-950) 95%,
var(--color-white)
);
--foreground: var(--color-neutral-100);
--card: color-mix(in srgb, var(--background) 98%, var(--color-white));
--card-foreground: var(--color-neutral-100);
--popover: color-mix(in srgb, var(--background) 98%, var(--color-white));
--popover-foreground: var(--color-neutral-100);
--primary: var(--color-neutral-100);
--primary-foreground: var(--color-neutral-800);
--secondary: --alpha(var(--color-white) / 4%);
--secondary-foreground: var(--color-neutral-100);
--muted: --alpha(var(--color-white) / 4%);
--muted-foreground: color-mix(
in srgb,
var(--color-neutral-500) 90%,
var(--color-white)
);
--accent: --alpha(var(--color-white) / 4%);
--accent-foreground: var(--color-neutral-100);
--destructive: color-mix(
in srgb,
var(--color-red-500) 90%,
var(--color-white)
);
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-400);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-400);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-400);
--border: --alpha(var(--color-white) / 6%);
--input: --alpha(var(--color-white) / 8%);
--ring: var(--color-neutral-500);
--sidebar: color-mix(
in srgb,
var(--color-neutral-950) 97%,
var(--color-white)
);
--sidebar-foreground: color-mix(
in srgb,
var(--color-neutral-100) 64%,
var(--sidebar)
);
--sidebar-primary: var(--color-neutral-100);
--sidebar-primary-foreground: var(--color-neutral-800);
--sidebar-accent: --alpha(var(--color-white) / 4%);
--sidebar-accent-foreground: var(--color-neutral-100);
--sidebar-border: --alpha(var(--color-white) / 5%);
--sidebar-ring: var(--color-neutral-400);
}Font Variables
Components like Dialog, AlertDialog, Sheet, and Empty use the font-heading class for titles. The coss style preset defines --font-sans, --font-heading, and --font-mono with system font fallbacks. To use custom fonts, define these variables in your layout using next/font:
import { Geist, Geist_Mono } from "next/font/google";
const fontSans = Geist({ variable: "--font-sans", subsets: ["latin"] });
const fontHeading = Geist({ variable: "--font-heading", subsets: ["latin"], weight: "600" });
const fontMono = Geist_Mono({ variable: "--font-mono", subsets: ["latin"] });
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={`${fontSans.variable} ${fontHeading.variable} ${fontMono.variable} font-sans`}>
{children}
</body>
</html>
);
}Apply the variables to html or body so they cascade. The font-sans class sets the default body font.
Base UI Setup
Since this library is built on Base UI, you need to configure CSS isolation to ensure portaled components (Dialogs, Popovers, Selects, etc.) render correctly above page content.
Application Root Isolation
Add isolation: isolate to your application's root wrapper div. This creates a separate stacking context so portaled components always appear above page contents without z-index conflicts.
<body>
<div className="isolate relative flex min-h-svh flex-col">
{children}
</div>
</body>iOS Safari Compatibility
For iOS Safari 26+ compatibility, add position: relative to the body element. This ensures backdrops properly cover the visual viewport after page scrolling.
<body className="relative">
<div className="isolate relative flex min-h-svh flex-col">
{children}
</div>
</body>These styles ensure Base UI components maintain proper rendering hierarchy and visual layering throughout your application. Without isolation, you may experience z-index conflicts where page content appears above modal dialogs or popovers.