Theming

DuskMoon Elements uses CSS custom properties from @duskmoon-dev/core for theming. This allows you to customize colors, typography, and spacing across all components.

Available Themes

The design system provides two built-in themes:

Moonlight (Dark Theme)

@import '@duskmoon-dev/core/dist/moonlight.css';
<html data-theme="moonlight">

Sunshine (Light Theme)

@import '@duskmoon-dev/core/dist/sunshine.css';
<html data-theme="sunshine">

CSS Custom Properties

All components use these CSS custom properties for styling:

Colors

PropertyDescription
--color-primaryPrimary brand color
--color-primary-contentText color on primary backgrounds
--color-secondarySecondary accent color
--color-surfaceBackground color for surfaces
--color-surface-variantAlternative surface color
--color-on-surfaceText color on surfaces
--color-outlineBorder and divider color
--color-errorError state color
--color-successSuccess state color
--color-warningWarning state color

Typography

PropertyDescription
--font-familyBase font family
--font-size-smSmall text size
--font-size-baseDefault text size
--font-size-lgLarge text size

Spacing

PropertyDescription
--spacing-xsExtra small spacing (4px)
--spacing-smSmall spacing (8px)
--spacing-mdMedium spacing (16px)
--spacing-lgLarge spacing (24px)
--spacing-xlExtra large spacing (32px)

Customizing the Theme

Override CSS custom properties to customize the appearance:

:root {
  /* Override primary color */
  --color-primary: oklch(55% 0.2 265);
  --color-primary-content: white;

  /* Override fonts */
  --font-family: 'Inter', system-ui, sans-serif;
}

Theme Switching

Implement theme switching with JavaScript:

function toggleTheme() {
  const html = document.documentElement;
  const currentTheme = html.dataset.theme;
  const newTheme = currentTheme === 'moonlight' ? 'sunshine' : 'moonlight';

  html.dataset.theme = newTheme;
  localStorage.setItem('duskmoon-theme', newTheme);
}

// Restore saved theme on page load
const savedTheme = localStorage.getItem('duskmoon-theme');
if (savedTheme) {
  document.documentElement.dataset.theme = savedTheme;
}

Respecting System Preferences

Detect the user’s preferred color scheme:

const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const defaultTheme = prefersDark ? 'moonlight' : 'sunshine';
document.documentElement.dataset.theme = defaultTheme;

Listen for changes:

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
  document.documentElement.dataset.theme = e.matches ? 'moonlight' : 'sunshine';
});

Component-Specific Customization

Each component may have additional CSS custom properties for fine-grained control. Check individual component documentation for details.

Example: Button Customization

el-dm-button {
  --btn-padding-x: 1.5rem;
  --btn-padding-y: 0.75rem;
  --btn-border-radius: 0.5rem;
}

Best Practices

  1. Use CSS custom properties instead of hardcoded values
  2. Import both theme files if you support theme switching
  3. Set data-theme on the <html> element for consistent styling
  4. Persist theme preference in localStorage for returning users
  5. Respect system preferences as the initial default