Theming

Cubix is themed with CSS variables and semantic tokens. Override those tokens in your CSS to restyle the product without rewriting component classes.

Components consume tokens like background, foreground, and primary. Tailwind maps them to utilities such as bg-background and text-foreground:

Example
<div className="bg-background text-foreground" />

CSS variables are enabled by default in cubix.json:

cubix.json
{
  "style": "cubix",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "app/globals.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  }
}

Token convention

Cubix uses semantic background and foreground pairs. The base token sets the surface color; the -foreground token sets text and icons on that surface. The background suffix is omitted on the surface token - for example primary pairs with primary-foreground.

app/globals.css
--primary: oklch(0% 0 0);
--primary-foreground: oklch(0.985 0 0);

That maps to:

Example
<div className="bg-primary text-primary-foreground">
  Hello
</div>

Color palette

Defaults live under :root and .dark in app/globals.css. Preview chips use the live CSS variables, so they follow the current theme.

TokenPreviewLightDark
--backgroundoklch(1 0 0)oklch(0.145 0 0)
--foregroundoklch(0% 0 0)oklch(0.985 0 0)
--cardoklch(1 0 0)oklch(0.205 0 0)
--primaryoklch(0% 0 0)oklch(0.922 0 0)
--secondaryoklch(0.97 0 0)oklch(0.269 0 0)
--mutedoklch(0.97 0 0)oklch(0.269 0 0)
--accentoklch(0.97 0 0)oklch(0.371 0 0)
--destructiveoklch(0.577 0.245 27.325)oklch(0.704 0.191 22.216)
--borderoklch(0.922 0 0)oklch(1 0 0 / 10%)
--inputoklch(0.922 0 0)oklch(1 0 0 / 15%)
--ringoklch(0.708 0 0)oklch(0.556 0 0)
--overlayoklch(0% 0 0 / 10%)oklch(0% 0 0 / 10%)
--overlay-strongoklch(0% 0 0 / 30%)oklch(0% 0 0 / 30%)
--chart-1oklch(0.646 0.222 41.116)oklch(0.488 0.243 264.376)
--chart-2oklch(0.6 0.118 184.704)oklch(0.696 0.17 162.48)
--chart-3oklch(0.398 0.07 227.392)oklch(0.769 0.188 70.08)
--chart-4oklch(0.828 0.189 84.429)oklch(0.627 0.265 303.9)
--chart-5oklch(0.769 0.188 70.08)oklch(0.645 0.246 16.439)
--sidebaroklch(0.985 0 0)oklch(0.205 0 0)

Theme tokens

What each token controls, and where it shows up in Cubix components:

TokenControlsUsed by
background / foregroundDefault app background and text.Page shell, sections, default copy.
card / card-foregroundElevated surfaces and content on them.Card, panels, settings surfaces.
popover / popover-foregroundFloating surfaces and overlay content.Popover, Dropdown Menu, Context Menu.
primary / primary-foregroundHigh-emphasis actions and brand fills.Default Button, selected states, badges.
secondary / secondary-foregroundLower-emphasis filled actions.Secondary buttons and supporting UI.
muted / muted-foregroundSubtle surfaces and quieter text.Descriptions, placeholders, empty states.
accent / accent-foregroundHover, focus, and active surfaces.Ghost buttons, menu highlights, hovered rows.
destructive / destructive-foregroundDestructive actions and error emphasis.Destructive buttons, invalid states.
borderDefault borders and separators.Cards, tables, menus, layout dividers.
inputForm control borders and outlines.Input, Textarea, Select, outline controls.
ringFocus rings.Buttons, inputs, checkboxes, menus.
overlay / overlay-strongDimmed scrims behind floating UI.Dialog, Sheet, Drawer.
chart-1 … chart-5Default chart palette.Chart and dashboard blocks.
sidebar / sidebar-foregroundSidebar surface and default text.Sidebar container and content.
sidebar-primary / sidebar-primary-foregroundHigh-emphasis actions in the sidebar.Active items, icon tiles, sidebar CTAs.
sidebar-accent / sidebar-accent-foregroundHover and selected states in the sidebar.Sidebar menu rows and open items.
sidebar-border / sidebar-ringSidebar borders and focus rings.Sidebar headers, groups, focused controls.
radiusBase corner radius; drives radius-* scale.Cards, inputs, buttons, popovers.

Radius scale

--radius is the base corner radius (default 0.625rem). Tailwind utilities derive from it so one change updates the whole scale:

app/globals.css
@theme inline {
  --radius-sm: calc(var(--radius) * 0.6);
  --radius-md: calc(var(--radius) * 0.8);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) * 1.4);
  --radius-2xl: calc(var(--radius) * 1.8);
  --radius-3xl: calc(var(--radius) * 2.2);
  --radius-4xl: calc(var(--radius) * 2.6);
}
TokenValuePreview
--radius-smcalc(var(--radius) * 0.6)
--radius-mdcalc(var(--radius) * 0.8)
--radius-lgvar(--radius)
--radius-xlcalc(var(--radius) * 1.4)
--radius-2xlcalc(var(--radius) * 1.8)
--radius-3xlcalc(var(--radius) * 2.2)
--radius-4xlcalc(var(--radius) * 2.6)

Dark mode

Dark mode is class-based. The same token names are overridden under .dark. This docs site uses next-themes with attribute="class" on <html>. Toggle the sun / moon control in the header to try it.

Customize

Re-brand Cubix by overriding variables in app/globals.css. Everything built on those tokens updates automatically:

app/globals.css
:root {
  --primary: oklch(0.55 0.2 262);
  --primary-foreground: oklch(0.98 0 0);
  --radius: 0.75rem;
}

.dark {
  --primary: oklch(0.72 0.14 262);
  --primary-foreground: oklch(0.2 0.02 262);
}

Adding new tokens

Define the variable under :root and .dark, then expose it to Tailwind with @theme inline:

app/globals.css
:root {
  --warning: oklch(0.84 0.16 84);
  --warning-foreground: oklch(0.28 0.07 46);
}

.dark {
  --warning: oklch(0.41 0.11 46);
  --warning-foreground: oklch(0.99 0.02 95);
}

@theme inline {
  --color-warning: var(--warning);
  --color-warning-foreground: var(--warning-foreground);
}

Then use the utilities in your UI:

Example
<div className="bg-warning text-warning-foreground" />

Default theme CSS

Neutral defaults from this project. Copy into your global CSS and adjust as needed:

app/globals.css
@custom-variant dark (&:is(.dark *));

:root {
  --radius: 0.625rem;

  --background: oklch(1 0 0);
  --foreground: oklch(0% 0 0);

  --card: oklch(1 0 0);
  --card-foreground: oklch(0% 0 0);

  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0% 0 0);

  --primary: oklch(0% 0 0);
  --primary-foreground: oklch(0.985 0 0);

  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);

  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);

  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);

  --destructive: oklch(0.577 0.245 27.325);
  --destructive-foreground: oklch(0.97 0.01 17);

  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);

  --overlay: oklch(0% 0 0 / 10%);
  --overlay-strong: oklch(0% 0 0 / 30%);

  --chart-1: oklch(0.646 0.222 41.116);
  --chart-2: oklch(0.6 0.118 184.704);
  --chart-3: oklch(0.398 0.07 227.392);
  --chart-4: oklch(0.828 0.189 84.429);
  --chart-5: oklch(0.769 0.188 70.08);

  --sidebar: oklch(0.985 0 0);
  --sidebar-foreground: oklch(0% 0 0);
  --sidebar-primary: oklch(0.205 0 0);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-accent: oklch(0.97 0 0);
  --sidebar-accent-foreground: oklch(0.205 0 0);
  --sidebar-border: oklch(0.922 0 0);
  --sidebar-ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);

  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);

  --popover: oklch(0.205 0 0);
  --popover-foreground: oklch(0.985 0 0);

  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);

  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);

  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);

  --accent: oklch(0.371 0 0);
  --accent-foreground: oklch(0.985 0 0);

  --destructive: oklch(0.704 0.191 22.216);
  --destructive-foreground: oklch(0.985 0 0);

  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);

  --overlay: oklch(0% 0 0 / 10%);
  --overlay-strong: oklch(0% 0 0 / 30%);

  --chart-1: oklch(0.488 0.243 264.376);
  --chart-2: oklch(0.696 0.17 162.48);
  --chart-3: oklch(0.769 0.188 70.08);
  --chart-4: oklch(0.627 0.265 303.9);
  --chart-5: oklch(0.645 0.246 16.439);

  --sidebar: oklch(0.205 0 0);
  --sidebar-foreground: oklch(0.985 0 0);
  --sidebar-primary: oklch(0.488 0.243 264.376);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-accent: oklch(0.269 0 0);
  --sidebar-accent-foreground: oklch(0.985 0 0);
  --sidebar-border: oklch(1 0 0 / 10%);
  --sidebar-ring: oklch(0.439 0 0);
}

Next: Installation, CLI, or browse Components.