UI & theming
Import the built-in UI kit. Override theme tokens in styles.css. Copy sources with add.
Vantage ships shadcn/ui (the Base UI variant) and a Tailwind v4 theme. No setup — use them immediately.
Use the UI kit
There are two entry points: the shadcn/ui primitives live in @squadbase/vantage/ui, and the
dashboard parts composed from them live in @squadbase/vantage/components.
import { Button } from "@squadbase/vantage/ui";
import { DashboardCardPreset, MetricValue } from "@squadbase/vantage/components";
export default function Overview() {
return (
<div className="grid gap-4 p-6 md:grid-cols-3">
<DashboardCardPreset title="Revenue">
<MetricValue className="my-0">$12,400</MetricValue>
</DashboardCardPreset>
<DashboardCardPreset title="New customers">
<MetricValue className="my-0">128</MetricValue>
</DashboardCardPreset>
<DashboardCardPreset title="Churn">
<MetricValue className="my-0">2.1%</MetricValue>
</DashboardCardPreset>
</div>
);
}
In /ui (a selection): Button, Card, the Table primitives, Tabs, Input / Select /
Checkbox / Switch / Slider, Calendar, Dialog / Sheet / Popover / Tooltip /
DropdownMenu, Sidebar, Alert / Skeleton / Spinner, Loading / Empty / ErrorState.
In /components (a selection): PageShell, AppShell, DashboardCard, DataTable, EChart,
FunnelSteps, FilterBar, DateRangePicker, MetricValue, TrendIndicator.
Props and usage for every component live in the Components tab.
Tailwind just works
Write Tailwind utilities in className and they apply. You never write tailwind.config or
postcss.config (they’re forbidden files and would error). Use cn() to combine classes.
import { cn } from "@squadbase/vantage/ui";
<div className={cn("p-4", isActive && "bg-accent")} />;
Override theme tokens
Design tokens like colors and radii are CSS variables. To override them, place a styles.css on the
same side as your pages — src/styles.css if the project has a src/, at the project root
otherwise (→ Where pages live) — and override only CSS variables. The file is
auto-imported after the theme.
/* styles.css — CSS variable overrides only */
:root {
--primary: oklch(0.55 0.22 265);
}
.dark,
[data-theme="dark"] {
--primary: oklch(0.72 0.19 265);
}
The tokens are shadcn/ui’s neutral palette (oklch), plus --chart-1 through --chart-5 for charts
and --sidebar-* for the sidebar. Changing --chart-* also changes
EChart’s palette — charts build their theme by reading those CSS
variables directly.
Dark mode is opt-in
The dark tokens apply only when an ancestor carries .dark or [data-theme="dark"]. Vantage
does not read the OS/browser setting (prefers-color-scheme) — a dashboard reads better when it
doesn’t flip with whatever it happens to be embedded in, so the switch stays with the app.
dark: utilities are wired to the same switch (theme.css declares it via @custom-variant dark).
Without a .dark ancestor no dark: utility applies, so the theme can’t split in two — light tokens
under dark-mode utilities.
// With no `.dark` ancestor, the second class does nothing
<div className="text-foreground dark:text-slate-100" />
When you want to edit the source: vantage add
To make a component’s internals your own, copy an editable source into components/.
vantage add ui data-table # copy an editable DataTable
vantage add block sales-overview
What to read next
- Components — the props reference for every component
- CLI reference — every command