Theming
Modern and performant theme system for Maz-UI built on native CSS features (light-dark(), color-scheme, color-mix(in oklch)) for v5.
Features
- Native
light-dark()+color-scheme- Modern CSS theming with zero JS overhead for the light/dark switch - Native widget theming -
color-schememakes scrollbars, native<select>, date pickers and autofill follow the active mode automatically - Animated theme switch - Optional full-page View Transitions via
setColorMode(..., { animate: true }) - Anti-FART -
<meta name="color-scheme">injected at boot to prevent any Flash of inAccurate coloR Theme (no setup needed) - Automatic color scales -
--maz-X-50through--maz-X-950derived via OKLCh relative color syntax — perceptually uniform and chroma-preserving - Performance Strategies - Runtime injection or build-time generation according to your needs
- Strict TypeScript - Complete types for perfect DX
- Zero FOUC - Pass the preset object up front; the full CSS is injected synchronously on first paint
- Flexible Presets - Ready-to-use and customizable configurations
Theme Editor
Create your own theme with the Theme Editor.
Quick Usage
1. Plugin Configuration with MazUi plugin
To avoid FOUC (Flash of Unstyled Content), you should provide the theme preset.
// main.ts
import { MazUi } from 'maz-ui/plugins/maz-ui'
import { mazUi } from '@maz-ui/themes/presets/mazUi'
import { createApp } from 'vue'
const app = createApp(App)
app.use(MazUi, {
theme: {
preset: mazUi, // pristine | ocean | obsidian | nova
strategy: 'runtime', // 'runtime' | 'buildtime'
darkModeStrategy: 'class', // 'class' | 'media' (only if mode is `both`)
mode: 'both', // 'light' | 'dark' | 'both' (supported color modes)
colorMode: 'auto', // 'auto' | 'light' | 'dark' (initial color mode, only if mode is 'both')
// Class added to <html> when dark mode is forced (default: 'dark')
darkClass: 'dark',
// Class added to <html> when light mode is forced (default: 'light')
lightClass: 'light',
persistPreset: true, // remember the active preset name across reloads
}
})Alternative: MazUiProvider
You can also initialize the theme via the MazUiProvider component for lazy-loaded pages or subtree-scoped themes.
2. Setup your CSS to support theme foundation and dark mode
html {
font-size: var(--maz-base-font-size);
font-family: var(--maz-font-family);
background-color: var(--maz-surface);
color: var(--maz-foreground);
}3. Using in your components
<script setup>
import { useTheme } from '@maz-ui/themes'
const { toggleDarkMode, isDark, updateTheme } = useTheme()
</script>
<template>
<div class="maz:bg-surface maz:text-foreground">
<button
class="maz:rounded-md maz:bg-primary maz:text-primary-foreground"
@click="toggleDarkMode"
>
{{ isDark ? '☀️' : '🌙' }} Toggle theme
</button>
</div>
</template>Configuration
preset: The theme preset to useoverrides(optional): Override specific parts of the themestrategy(optional, default'runtime'): The rendering strategy to use —'runtime' | 'buildtime'darkModeStrategy(optional, default'class'): The dark mode strategy —'class' | 'media', only if you use modebothmode(optional, default'both'): The supported color modes —'light' | 'dark' | 'both'colorMode(optional, default'auto'): The initial color mode —'light' | 'dark' | 'auto'(only if mode is'both')darkClass(optional, default'dark'): Class added to<html>whencolorMode === 'dark'lightClass(optional, default'light'): Class added to<html>whencolorMode === 'light'— mirror ofdarkClasspersistPreset(optional, defaulttrue): Persist the active preset name in themaz-presetcookie so it is restored on reload.
Preset persistence
When persistPreset is enabled (default), @maz-ui/themes stores the resolved preset name in a maz-preset cookie (1-year TTL, SameSite=Lax) — exactly like maz-color-mode for the dark/light state. The cookie is:
- Read at boot and used to resolve the active preset — even when
options.presetis provided.options.preset(string name or preset object) is treated as the default the app boots with, while the cookie carries the user's last explicit choice. The cookie wins. - Written after every successful preset resolution and after every
useTheme().updateTheme()call (idempotent — no write if the value already matches). - Auto-cleared when the saved name no longer resolves (e.g. typo, preset removed in a downgrade) — the runtime falls back to
options.preset(or default) and clears the cookie silently.
Custom preset names are stored exactly like bundled ones: @maz-ui/themes does not maintain a whitelist. Switch the option off to disable any cookie read/write:
app.use(MazUi, {
theme: {
preset: mazUi,
persistPreset: false, // never write or read the maz-preset cookie
},
})Useful when:
- You want zero theme-related cookies (privacy / regulatory).
- The active preset is fully driven by the consumer app and no end-user switching is exposed.
Color modes and class toggling
darkClass and lightClass interact with darkModeStrategy to control how <html> is decorated when the user picks an explicit mode.
darkModeStrategy: 'class' (default)
setColorMode('dark')addsdarkClass(default.dark) to<html>→color-scheme: only dark.setColorMode('light')addslightClass(default.light) to<html>→color-scheme: only light.setColorMode('auto')removes both classes →color-scheme: light darklets the browser follow the systemprefers-color-scheme.
Forcing both classes on the root ensures native widgets (scrollbars, native <select>, date pickers, autofill backgrounds, …) match the explicit user choice rather than the OS preference.
darkModeStrategy: 'media'
- No class is ever added to
<html>. - The browser always follows
prefers-color-schemeviacolor-scheme: light dark. setColorMode()still updates the persisted cookie but does not force a visual override.
Animated theme switch
For a full-page animated swap (rather than per-variable color tweens), pass { animate: true } to setColorMode or toggleDarkMode:
<script setup>
import { useTheme } from '@maz-ui/themes'
const { toggleDarkMode, setColorMode } = useTheme()
async function onToggle() {
await toggleDarkMode({ animate: true })
}
async function forceDark() {
await setColorMode('dark', { animate: true })
}
</script>- Wraps the switch in
document.startViewTransition()so the browser captures a snapshot of the page before/after and crossfades between them. - The View Transition glue is lazy-imported — when
animateis not used, it stays out of the boot bundle. - Graceful degradation: in browsers that don't support the API, the change is applied immediately with no animation (no error thrown).
Interactive Demo
Real-time theme control
Available Presets
Maz-UI (Default)
The default theme inspired by Maz-UI identity with vibrant and modern colors.
import { mazUi } from '@maz-ui/themes/presets'Pristine
A minimalist and elegant theme inspired by Apple design with pure black and white aesthetics.
import { pristine } from '@maz-ui/themes/presets'Ocean
A vibrant ocean-inspired theme with deep blues, aquatic greens, and coral accents. Features rounded borders and Poppins font for a fresh, modern look.
import { ocean } from '@maz-ui/themes/presets'Obsidian
A dark and elegant theme with a focus on readability and minimalism.
import { obsidian } from '@maz-ui/themes/presets'Nova
A modern startup / AI / creative preset — electric violet primary, hot coral secondary, cyan accent. Tight 0.5rem md radius, Geist + Inter font stack, snappy ease-out spring. Built for product / AI surfaces (think Linear, Vercel, OpenAI energy) where the UI itself should feel alive.
import { nova } from '@maz-ui/themes/presets'Rendering Strategies
⚡ Runtime (Recommended)
CSS is generated and injected synchronously on first paint. Pass the preset object directly (preset: mazUi) so the full stylesheet is rendered before the first frame — no FOUC.
import { mazUi } from '@maz-ui/themes/presets'
app.use(MazUi, {
theme: {
preset: mazUi,
strategy: 'runtime'
}
})🏗️ Buildtime
CSS generated at build-time and included in the bundle. You have to build your CSS files before running your app.
See Build-time for more details.
import { mazUi } from '@maz-ui/themes/presets'
app.use(MazUi, {
theme: {
preset: mazUi,
strategy: 'buildtime'
}
})Creating Custom Themes
Basic Theme
Create your own theme
Default theme
Advanced Theme with Overrides
import { definePreset } from '@maz-ui/themes'
const brandTheme = await definePreset({
base: 'maz-ui',
overrides: {
name: 'brand',
foundation: {
'border-width': '2px',
'font-family': 'Inter, sans-serif'
},
scales: {
rounded: { md: '0.75rem' }
},
colors: {
light: {
primary: 'oklch(0.6 0.18 254)',
secondary: 'oklch(0.96 0.01 254)',
surface: 'oklch(0.99 0.005 254)',
accent: 'oklch(0.7 0.22 305)'
},
dark: {
primary: 'oklch(0.7 0.18 254)',
secondary: 'oklch(0.22 0.03 254)',
surface: 'oklch(0.18 0.02 254)',
accent: 'oklch(0.78 0.2 305)'
}
}
}
})Customizing scales
Each ThemeScales entry maps to a Tailwind utility — override the keys you care about and the rest stays untouched:
const denseTheme = definePreset({
base: 'maz-ui',
overrides: {
name: 'dense',
foundation: {
// Tighter spacing — every p-N / gap-N / m-N rescales
space: '0.2rem',
},
scales: {
// Sharper corners on the whole radius scale
rounded: {
'xs': '0.0625rem',
'sm': '0.125rem',
'md': '0.375rem',
'lg': '0.5rem',
'xl': '0.75rem',
'2xl': '1rem',
'3xl': '1.5rem',
},
// Custom elevated-surface shadow
shadow: {
elevation: '0 8px 24px rgba(0, 0, 0, 0.15)',
},
},
},
})Foundation gets new optional keys for fonts and disabled-state behaviour:
const codeTheme = definePreset({
base: 'maz-ui',
overrides: {
foundation: {
'font-mono-stack': '"JetBrains Mono", ui-monospace, SFMono-Regular, monospace',
'font-display-stack': '"Cal Sans", Manrope, sans-serif',
'disabled-opacity': '0.4',
'disabled-cursor': 'wait',
},
},
})Per-component overrides
components is a small, validated set of per-component knobs. Every entry is per-mode where appropriate so light and dark can drift independently:
const surfaceTheme = definePreset({
base: 'maz-ui',
overrides: {
name: 'cool-surfaces',
components: {
btn: {
// Bias every button text heavier
'font-weight': '600',
},
container: {
// Cards / dialogs / popovers / drawers — light = page surface, dark = a tier above
bg: { light: 'var(--maz-surface)', dark: 'var(--maz-surface-300)' },
},
input: {
// All form-control surfaces
bg: { light: 'var(--maz-surface-100)', dark: 'var(--maz-surface-400)' },
},
},
},
})Components consume these via maz:bg-container / maz:bg-input Tailwind utilities, so a single override propagates everywhere — no per-component class hunt.
Dialog sizing
components.dialog controls the width of MazDialog on tablet and up. The two keys are emitted as --maz-dialog-max-width / --maz-dialog-min-width and consumed by the component through var(--maz-dialog-max-width, 38rem) / var(--maz-dialog-min-width, 32rem):
const wideDialogTheme = definePreset({
base: 'maz-ui',
overrides: {
name: 'wide-dialogs',
components: {
dialog: {
'max-width': '48rem',
'min-width': '36rem',
},
},
},
})Both values are in rem, so they scale with the preset's base-font-size. Bundled presets anchored on 14px use 38rem / 32rem; ocean (16px) ships scaled rem values (33.25rem / 28rem) to keep the same rendered pixel width. The max-width / min-width props on MazDialog still override the preset per instance.
useTheme Composable API
const {
// Reactive state
preset, // ComputedRef<ThemePreset>
presetName, // ComputedRef<string>
colorMode, // Ref<'light' | 'dark' | 'auto'> — also accepts assignment (computed setter)
isDark, // ComputedRef<boolean>
strategy, // ComputedRef<'runtime' | 'buildtime'>
mode, // ComputedRef<'light' | 'dark' | 'both'>
darkModeStrategy, // ComputedRef<'class' | 'media'>
// Actions
updateTheme, // (preset: ThemePreset | ThemePresetName | ThemePresetOverrides) => Promise<void>
setColorMode, // (mode: 'light' | 'dark' | 'auto', options?: { animate?: boolean }) => Promise<void>
toggleDarkMode, // (options?: { animate?: boolean }) => Promise<void>
} = useTheme()
// Set the color mode imperatively
await setColorMode('dark')
// Or assign to `colorMode` — it's a computed with a setter
colorMode.value = 'dark'
// Animated full-page switch via View Transitions
await toggleDarkMode({ animate: true })setColorMode and toggleDarkMode are async (Promise<void>). The promise resolves once the change — and the optional View Transition — has been applied. Callers can ignore the return value when no transition is needed.
Advanced Usage Examples
<script setup>
import { useTheme } from '@maz-ui/themes'
import { computed } from 'vue'
const { presetName, isDark, updateTheme, setColorMode } = useTheme()
// Computed for interface
const themeIcon = computed(() => isDark.value ? '☀️' : '🌙')
// Function to apply a temporary custom theme
function previewColor(color: string) {
updateTheme({
colors: {
light: { primary: color },
dark: { primary: color }
}
})
}
// Auto mode with system detection
function enableAutoMode() {
setColorMode('auto')
}
</script>Build-time Strategy: Complete Guide
The build-time strategy allows you to generate your theme CSS files at compile time, offering the best performance in production.
Step-by-step configuration
1. Generate CSS
import { mkdirSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'
import {
// Build all css in one file
buildThemeCSS,
// Build multiple themes with one file each
generateThemeBundle,
// Build separate css files
buildSeparateThemeFiles,
definePreset,
mazUi,
} from '@maz-ui/themes'
import App from './App.vue'
const _dirname = dirname(fileURLToPath(import.meta.url))
// Custom theme
const customPreset = definePreset({
base: mazUi,
overrides: {
name: 'custom',
colors: {
light: { primary: 'oklch(0.6 0.18 254)' },
dark: { primary: 'oklch(0.7 0.18 254)' },
},
},
})
/**
* Generate complete CSS
*/
const fullCSS = buildThemeCSS({
preset: customPreset,
mode: 'both',
})
writeFileSync(join(_dirname, 'public/custom.css'), fullCSS)
/**
* Or generate per-mode CSS files
*/
const { full, lightOnly, darkOnly } = buildSeparateThemeFiles(customPreset, {
darkSelector: 'class',
})
writeFileSync(join(_dirname, 'public/custom-full.css'), full)
/**
* Or generate bundle for multiple themes in one file each
*/
const themeBundle = generateThemeBundle([customPreset, mazUi], {
mode: 'both',
})
Object.entries(themeBundle).forEach(([name, css]) => {
writeFileSync(join(_dirname, `public/${name}.css`), css)
})
const app = createApp(App)
app.use(MazUiTheme, {
preset: customPreset,
strategy: 'buildtime', // Important!
darkModeStrategy: 'class',
})
app.mount('#app')import {
buildThemeCSS,
generateThemeBundle,
buildSeparateThemeFiles,
createThemeStylesheet,
definePreset,
mazUi,
CSS_ID,
} from '@maz-ui/themes'
// Custom theme
const customPreset = definePreset({
base: mazUi,
overrides: {
name: 'custom',
colors: {
light: { primary: 'oklch(0.6 0.18 254)' },
dark: { primary: 'oklch(0.7 0.18 254)' },
},
},
})
// Generate complete CSS
const fullCSS = buildThemeCSS({
preset: customPreset,
mode: 'both',
})
// Or generate per-mode CSS files
const { full, lightOnly, darkOnly } = buildSeparateThemeFiles(customPreset, {
darkSelector: 'class',
})
// Or generate bundle for multiple themes
const themeBundle = generateThemeBundle([customPreset, mazUi], {
mode: 'both',
})
export default defineConfig<DefaultTheme.Config>({
head: [
['style', { id: CSS_ID, type: 'text/css' }, full],
] satisfies HeadConfig[],
})/*
* You dont need to do anything,
* The module will handle it for you.
*
* Just provide a preset to the module
*/
const customPreset = definePreset({
base: mazUi,
overrides: {
name: 'custom',
colors: {
light: { primary: 'oklch(0.6 0.18 254)' },
dark: { primary: 'oklch(0.7 0.18 254)' },
},
},
})
export default defineConfig({
modules: ['@maz-ui/nuxt'],
mazUi: {
theme: {
preset: customPreset,
mode: 'both',
colorMode: 'auto',
},
},
})2. Include in your HTML (Only for Vue users)
<link rel="stylesheet" href="/themes/custom-full.css">Utility functions
buildThemeCSS(options)
Generates complete CSS for a theme.
const css = buildThemeCSS({
preset: customPreset,
mode: 'both', // 'light' | 'dark' | 'both'
darkSelector: 'class', // 'class' | 'media'
})generateThemeBundle(presets, options)
Generates a bundle containing multiple themes.
const bundle = generateThemeBundle([theme1, theme2], {
mode: 'both',
darkSelector: 'class',
})
// Result: { 'theme1': 'css...', 'theme2': 'css...' }buildSeparateThemeFiles(preset, options)
Generates separate files for different use cases.
const files = buildSeparateThemeFiles(preset)
// Result: { full, lightOnly, darkOnly }createThemeStylesheet(css, options)
Creates a <style> @reference "../../.vitepress/theme/main.css"; tag with the provided CSS.
const styleTag = createThemeStylesheet(css, {
id: 'my-theme',
media: 'screen', // optional
})Build-time strategy advantages
- Optimal performance - No client-side CSS generation
- Efficient caching - CSS files cached by CDN
- Reduced bundle - Generation utilities excluded from client
- Full compatibility - Works even with JavaScript disabled
Recommended use cases
- Production applications with static themes
- Sites with critical performance requirements
- Projects with multiple predefined themes
- Applications requiring fine control over CSS loading
Token Reference
Every preset emits the same set of CSS variables on :root. With mode: 'both', each base color is a single light-dark(L, D) declaration that the browser resolves to the active scheme. Use these names directly in your own CSS — var(--maz-primary), calc(var(--maz-space) * 4), etc.
Foundation
Single-value design tokens. Set via foundation.<key> on the preset.
| Preset key | CSS variable | Default | Notes |
|---|---|---|---|
base-font-size | --maz-base-font-size | 14px | Anchors rem for the whole app. Apply on html { font-size: var(--maz-base-font-size) }. |
border-width | --maz-border-width | 1px | Default border for components and the global *::before/::after reset. |
space | --maz-space | 0.25rem | Base step for every Tailwind spacing utility (maz:p-1, maz:gap-2, …). |
font-family | --maz-font-family | preset-specific | Sans / body font stack. Bridged to Tailwind --font-sans. |
font-mono-stack | --maz-font-mono-stack | ui-monospace, … | Monospace stack — MazInputCode, <code>, <kbd>. Bridged to --font-mono. |
font-display-stack | --maz-font-display-stack | same as font-family | Display / heading stack. Bridged to --font-display. |
motion-fast | --maz-motion-fast | 100ms | Bridged to Tailwind --duration-fast. |
motion-normal | --maz-motion-normal | 200ms | Default transition duration (--default-transition-duration). |
motion-slow | --maz-motion-slow | 300ms | Bridged to --duration-slow. |
easing-out | --maz-easing-out | cubic-bezier(0.4, 0, 0.2, 1) | Default easing (--ease-out, also --default-transition-timing-function). |
easing-in | --maz-easing-in | cubic-bezier(0.4, 0, 1, 1) | Bridged to --ease-in. |
easing-in-out | --maz-easing-in-out | cubic-bezier(0.4, 0, 0.2, 1) | Bridged to --ease-in-out. |
disabled-opacity | --maz-disabled-opacity | 0.5 | Applied to disabled buttons / inputs. |
disabled-cursor | --maz-disabled-cursor | not-allowed | Cursor for disabled interactive elements. |
Why
font-mono-stack/font-display-stack/motion-*? Under Tailwind v4prefix(maz), the bridge LHS gets prefixed (--font-mono→--maz-font-mono), so a same-named source token would self-cycle. The-stackandmotion-suffixes break the collision.
Colors
Defined per mode under colors.light / colors.dark. Each base color also gets an automatic 50–950 scale.
| Preset key | CSS variable (base) | Auto scale | Notes |
|---|---|---|---|
surface | --maz-surface | --maz-surface-50..900 | Page / container background. |
foreground | --maz-foreground | --maz-foreground-50..900 | Default text color. |
primary | --maz-primary | --maz-primary-50..900 | Brand color. |
primary-foreground | --maz-primary-foreground | — | Text on bg-primary. |
secondary | --maz-secondary | --maz-secondary-50..900 | |
secondary-foreground | --maz-secondary-foreground | — | |
accent | --maz-accent | --maz-accent-50..900 | |
accent-foreground | --maz-accent-foreground | — | |
info | --maz-info | --maz-info-50..900 | Status — informational. |
info-foreground | --maz-info-foreground | — | |
success | --maz-success | --maz-success-50..900 | Status — success. |
success-foreground | --maz-success-foreground | — | |
warning | --maz-warning | --maz-warning-50..900 | Status — warning. |
warning-foreground | --maz-warning-foreground | — | |
destructive | --maz-destructive | --maz-destructive-50..900 | Status — error / danger. |
destructive-foreground | --maz-destructive-foreground | — | |
contrast | --maz-contrast | --maz-contrast-50..900 | High-contrast accent (light = near-black, dark = near-white). |
contrast-foreground | --maz-contrast-foreground | — | |
divider | --maz-divider | --maz-divider-50..900 | Default border / separator color. |
muted | --maz-muted | --maz-muted-50..900 | Muted / secondary text. |
overlay | --maz-overlay | --maz-overlay-50..900 | Backdrop / dialog scrim. |
shadow | --maz-shadow | --maz-shadow-50..900 | Tint used by Tailwind shadow-* utilities (via --color-elevation). |
Scales
Multi-step scales under scales.<key>.
| Preset key | CSS variables | Tailwind utility |
|---|---|---|
rounded.xs..3xl | --maz-rounded-xs..3xl | maz:rounded-{key} (bridged to --radius-{key}) |
shadow.{sm, md, lg, xl, elevation} | --maz-shadow-style-{key} | maz:shadow-{key} (bridged to --shadow-{key}) |
Same naming-collision avoidance as foundation:
rounded.*(instead ofradius.*) andshadow-style-*(instead of plainshadow-*) keep the bridge cycle-free underprefix(maz).
Components
Per-component knobs under components.<key>. All optional — omit to fall back to the surface tokens.
| Preset key | CSS variable | Notes |
|---|---|---|
btn.font-weight | --maz-btn-font-weight | Font-weight on .m-btn. Defaults to '500'. |
container.bg.light / .dark | --maz-container-bg (per mode) | Background of Card, Container, Dialog, Popover, Drawer, … Defaults to var(--maz-surface). Bridged to --color-container. |
input.bg.light / .dark | --maz-input-bg (per mode) | Background of Input, Textarea, Select, Checkbox, … Defaults to var(--maz-surface) light, var(--maz-surface-400) dark. Bridged to --color-input. |
dialog.max-width | --maz-dialog-max-width | Max-width of MazDialog on tablet and up. Defaults to 38rem (33.25rem on ocean). Overridable via the max-width prop. |
dialog.min-width | --maz-dialog-min-width | Min-width of MazDialog on tablet and up. Defaults to 32rem (28rem on ocean). Overridable via the min-width prop. |
Sample output
Each base color is emitted as a light-dark() value; scales --maz-X-50 through --maz-X-950 are derived via OKLCh relative color syntax so they automatically follow base color overrides at runtime, preserving chroma at every step.
:root {
color-scheme: light dark;
/* Base colors — one declaration each, resolved by the browser */
--maz-primary: light-dark(oklch(0.65 0.19 254), oklch(0.72 0.18 254));
--maz-primary-foreground: light-dark(oklch(1 0 0), oklch(0.16 0.01 254));
--maz-surface: light-dark(oklch(1 0 0), oklch(0.18 0.01 254));
--maz-foreground: light-dark(oklch(0.26 0.01 254), oklch(0.96 0.005 254));
/* Auto-generated 50–950 scale — derived via relative color syntax */
--maz-primary-500: var(--maz-primary);
--maz-primary-600: oklch(from var(--maz-primary) clamp(0, calc(l - 0.07), 1) c h);
/* ... */
/* Foundation */
--maz-base-font-size: 14px;
--maz-border-width: 1px;
--maz-space: 0.25rem;
--maz-font-family: Manrope, sans-serif, …;
--maz-motion-normal: 200ms;
/* Scales */
--maz-rounded-md: 0.7rem;
--maz-shadow-style-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), …;
}
/* With darkModeStrategy: 'class' — explicit user choice overrides the system */
.dark { color-scheme: only dark; }
.light { color-scheme: only light; }For deeper detail on the generated CSS contract, see the @maz-ui/themes README.
Usage with Nuxt
For Nuxt users, check the dedicated Nuxt documentation which covers installation and framework-specific configuration.
Migration from Legacy System
If you're using the legacy theme system with CLI:
// maz-ui.config.ts
export default defineConfig({
theme: {
colors: {
primary: 'hsl(210, 100%, 56%)',
secondary: 'hsl(164, 76%, 46%)'
}
}
})// main.ts
import { definePreset, mazUi } from '@maz-ui/themes'
import { MazUiTheme } from '@maz-ui/themes/plugin'
const myTheme = definePreset({
base: mazUi,
overrides: {
colors: {
light: {
primary: 'oklch(0.65 0.19 254)',
secondary: 'oklch(0.72 0.16 168)'
}
}
}
})
app.use(MazUiTheme, { preset: myTheme })The new system offers much more flexibility and performance!