Theming & branding
The dashboard's look is driven by app config and CSS design tokens, both of which your frontend layer can override — no component forking required. The surfaces below are ordered by how often you'll touch them: the logo, the colors, deeper token overrides, and the sizing system.
Everything here lives in a frontend layer. Values merge across layers; if an override doesn't take effect, make your layer win precedence the same way as a component override — a negative priority on AddNuxtLayer (Frontend layer).
Your logo
The shell reads its logos from appConfig.branding.logo — two variants (full and collapsed sidebar), each with a light and dark asset. Override the block in your layer's app.config.ts and ship the files in your layer's public/ directory:
export default defineAppConfig({
branding: {
logo: {
default: {
light: "/images/acme/logo-light.svg",
dark: "/images/acme/logo-dark.svg",
},
collapsed: {
light: "/images/acme/icon.svg",
dark: "/images/acme/icon.svg",
},
},
},
});
The default pair renders in the expanded sidebar and on auth pages; the collapsed pair when the sidebar is icon-only. Light/dark selection follows the color mode automatically.
The document title and description are not app config — they come from the DMS backend config's meta block (Configuration).
Colors
The dashboard is themed with Nuxt UI's semantic color tokens. The base layer maps them in app.config.ts:
ui: {
colors: {
primary: "dms", // the DMS cyan — a custom palette
neutral: "neutral", // re-tuned neutral scale
success: "emerald",
warning: "amber",
error: "red",
info: "cyan",
},
}
To rebrand, point primary (or any semantic token) at another palette in your own app.config.ts — a stock Tailwind palette name works as-is:
export default defineAppConfig({
ui: { colors: { primary: "violet" } },
});
For a brand-exact palette, do what the DMS does for dms: declare the 11 shade variables in a CSS @theme block, then reference the palette by name:
@theme static {
--color-acme-50: #f2f8ff;
/* … --color-acme-100 through --color-acme-900 … */
--color-acme-950: #0a1a2e;
}
export default defineAppConfig({
ui: { colors: { primary: "acme" } },
});
Charts, badges, buttons, and the component vocabulary all resolve their colors from these tokens (the chart renderer reads the live theme), so one palette change restyles data-viz and chrome together.
Deeper token overrides
Beyond the palette, four surfaces give finer control. All of them are standard Nuxt UI / Tailwind mechanics, not DMS inventions.
Component theme slots. The ui app-config key also carries per-component overrides (ui.card.slots, ui.navigationMenu, …). Use one to restyle a component family everywhere. To see what the DMS already overrides, read the base layer's app.config.ts.
CSS variables. The base layer's stylesheet defines the surface system as CSS variables, each with a dark-mode variant: --ui-bg* for canvas and elevated surfaces, --ui-border* for hairlines, --ui-radius for corner rounding, --cms-surface-card for card frames, plus the shadow tokens. Override them in your own unlayered :root CSS to shift the whole surface palette at once.
Fonts. The DMS self-hosts Geist and Geist Mono, wired through --font-sans / --font-mono (plus Tailwind's --default-font-family). Declare your own @font-face and reassign those variables to change the typeface globally.
Icons. The shell's icons resolve through ui.icons in app config — the base layer maps them to Phosphor. Remap them there to use another icon set.
Interface scale
The whole UI scales from the root font size: the data-scale attribute on <html> switches between small (87.5%), normal, and large (112.5%). Users pick theirs on the built-in Appearance settings page; your code reads or sets it through the useInterfaceScale() cookie ref (Page context).
Because everything is rem-based, custom components inherit the scaling for free — prefer rem/em units in your own CSS to keep it that way.
Dashboard chrome
The registries a frontend layer calls to add header buttons, command-palette groups, app widgets, sidebar widgets, global overlays, footer links, and auth-page links to the dashboard shell.
Custom data types
Register your own DataType — a backend type declaration paired with the frontend Vue that renders its values.