Customization
Everything is driven by design tokens and a few config files, so most rebrands take minutes.
Colors
All colors live as CSS variables in src/app/globals.css. There are two
blocks: :root (light mode) and .dark (dark mode). Change a value in both to
keep the theme consistent.
/* src/app/globals.css */
:root {
--primary: #6366f1; /* indigo-500 — buttons, links, accents */
--background: #ffffff; /* page background */
--success: #10b981; /* emerald — positive trends */
--warning: #f59e0b; /* amber — pending states */
--destructive: #dc2626; /* red — errors */
/* ...and more */
}
.dark {
--primary: #6366f1;
--background: #0f172a; /* slate-900 */
/* ...dark equivalents */
}
To rebrand, change --primary (and its dark value) — buttons, links, focus
rings, the logo gradient and chart accents all derive from it.
The chart palette is --chart-1 … --chart-6. Adjust these to recolor every
Recharts visualization at once.
Border radius
One variable controls roundness everywhere:
:root {
--radius: 0.75rem; /* cards = 12px; buttons/inputs derive smaller radii */
}
Fonts
Fonts are loaded with next/font in src/app/layout.tsx:
import { Inter, JetBrains_Mono } from "next/font/google";
const inter = Inter({ variable: "--font-inter", subsets: ["latin"] });
const jetbrainsMono = JetBrains_Mono({
variable: "--font-jetbrains-mono",
subsets: ["latin"],
});
To swap the UI font, replace Inter with another next/font/google font and
keep the --font-inter variable name (or update the matching --font-sans
mapping in globals.css). JetBrains Mono is used for code, API keys and
prompts.
Logo
The logo is a single component at src/components/layout/logo.tsx — a
neural-node SVG mark plus the "Nexus AI" wordmark. Replace the SVG and the text
there; it updates the sidebar, auth screens, the 404 page and invoices
automatically.
Navigation
The sidebar and the ⌘K command palette read from one file:
src/lib/navigation.ts. Edit navSections to add, remove or reorder items:
{
label: "AI",
items: [
{ title: "Usage Analytics", href: "/analytics", icon: BarChart3 },
// add your own:
{ title: "My New Page", href: "/my-page", icon: Sparkles },
],
}
Icons come from lucide-react. (Note: brand icons like
Github/Slack were removed from lucide v1.x — use generic icons or inline
SVGs.)
Adding a new page
-
Create
src/app/(dashboard)/my-page/page.tsx:import { PageHeader } from "@/components/common/page-header"; export default function MyPage() { return ( <div className="space-y-6"> <PageHeader title="My Page" breadcrumbs={[ { label: "Dashboard", href: "/dashboard" }, { label: "My Page" }, ]} /> {/* your content */} </div> ); } -
Add it to
navSectionsinsrc/lib/navigation.ts(step above).
That's it — the page inherits the AppShell layout, sidebar, top bar and theming.
Dark mode
Dark mode uses next-themes,
configured in src/app/layout.tsx. The default theme is dark; change
defaultTheme="dark" to "light" or "system". The toggle component is
src/components/layout/theme-toggle.tsx.
Accent colors
The navbar includes an accent color picker (the palette icon) with seven
built-in accents — Indigo (default), Violet, Blue, Emerald, Rose, Amber and
Orange. The choice is saved to localStorage and applied via a data-accent
attribute on <html>, so buttons, links, focus rings, the active nav item and
the primary chart color all recolor instantly in both light and dark mode.
Where it lives:
src/lib/accents.ts— the list of accents (id, label, swatch color).src/components/accent-provider.tsx— applies/persists the choice, plus a no-flash inline script.src/components/layout/accent-picker.tsx— the navbar dropdown.src/app/globals.css— the per-accent token overrides, keyed by[data-accent="…"]and.dark[data-accent="…"].
Add a new accent in two steps:
// 1. src/lib/accents.ts
export const accents = [
// …existing…
{ id: "teal", label: "Teal", swatch: "#14b8a6" },
];
/* 2. src/app/globals.css */
[data-accent="teal"] {
--primary: #14b8a6;
--ring: #14b8a6;
--sidebar-primary: #14b8a6;
--sidebar-ring: #14b8a6;
--chart-1: #14b8a6;
}
.dark[data-accent="teal"] {
--primary: #2dd4bf;
}
To change the default accent, set DEFAULT_ACCENT in src/lib/accents.ts.
To remove the picker, delete <AccentPicker /> from the navbar
(app-shell.tsx and the docs layout).
Sidebar
The sidebar collapses to an icon-only rail via the round toggle that floats on
its edge. Layout and behavior live in
src/components/layout/app-shell.tsx (the collapsed state) and the items come
from src/lib/navigation.ts. It becomes a slide-over drawer on mobile.
Next: Pages Overview →