Theming
Numa centralizes UI tokens in @numa/config/ui/theme. ThemeVariables injects them as CSS variables at the root.
How it works
config/ui/theme.ts— single source of truth for all theme valuesThemeVariables— injected at app root inapp/layout.tsx, converts config to CSS variables- Components — use
var(--radius-lg),var(--ui-border-width-input), etc.
What you can customize
| Property | Description | Example |
|---|---|---|
radius.base | Corner radius for buttons, inputs, cards | 6 (6px) or 10 (10px) |
radius.scale | Multipliers for sm/md/lg/xl variants | { sm: 0.6, md: 0.8, lg: 1 } |
border.input | Input border width | 1 or 2 |
border.button | Button border width | 1 |
border.card | Card/container border width | 1 |
ring.width | Focus ring width | 3 |
sizes.input | Input height, padding, icon size | { height: 32, paddingX: 10 } |
sizes.button | Button heights per size variant | { default: 32, sm: 28, lg: 36 } |
Quick example
// config/ui/theme.ts
export const uiTheme = {
radius: {
base: 6,
},
border: {
input: 2,
button: 1,
card: 1,
},
};Using theme variables in components
When adding or modifying components, use theme variables instead of hardcoded values:
| Use case | CSS variable |
|---|---|
| Border radius | rounded-[var(--radius-lg)] |
| Border width | [border-width:var(--ui-border-width-input)] |
| Focus ring | ring-[var(--ui-ring-width)] |
| Input height | h-[var(--ui-input-height-default)] |
Colors
Color theming uses shadcn color tokens in globals.css (:root and .dark). Edit those for brand colors, or use config/styles/colors.ts for app-specific tokens.
Tailwind v4
Numa uses Tailwind CSS v4 with CSS-first configuration. There is no tailwind.config.js. Instead:
- Theme is defined in
packages/ui/globals.cssusing@themeand@sourcedirectives - PostCSS plugin
@tailwindcss/postcsshandles compilation - Apps import this via their own
globals.css
Last updated on