ArtisanPack UI
DocsDesign SystemThemes

Themes

Design System v1.0.0

Three themes ship with the system: light, dark and high contrast. Each is a complete set of color, surface and shadow tokens, checked for contrast on its...

Three themes ship with the system: light, dark and high contrast. Each is a complete set of color, surface and shadow tokens, checked for contrast on its own.

<html data-theme="dark">

With no data-theme attribute, the tokens use the light theme.

High contrast

High contrast raises every contrast pair, removes shadows in favor of edges, makes glass opaque and gives soft status surfaces a visible edge. It's an explicit choice, never picked automatically. Windows forced-colors mode is handled separately: the focus ring and the components that draw state with color keep it visible there.

Letting visitors choose

The ThemeToggle component offers four choices: Light, Dark, High contrast and System. System follows the operating system's light or dark setting and updates live when it changes. The choice is stored in localStorage under apui-theme, so it persists across visits, and every toggle on the page, and in other tabs, stays in sync.

Applying the theme before the first paint

A stored theme has to be applied before the browser paints, or a dark-mode visitor sees a flash of the light theme. A small blocking script in <head> does it:

Stack Add
Livewire / Blade @apuiThemeScript
React <ThemeScript /> from @artisanpack-ui/react
Vue <ThemeScript /> from @artisanpack-ui/vue, or useHead({ script: [{ innerHTML: themeScript() }] }) in Nuxt
Static index.html Inline the output of themeScript() from @artisanpack-ui/behavior

Put it first in <head>, before any stylesheet. Until a visitor makes a choice, the script applies their system's light or dark setting. All four produce the same script.

From JavaScript

The helpers behind ThemeToggle are exported from @artisanpack-ui/behavior:

import { applyTheme, resolveTheme } from '@artisanpack-ui/behavior';

applyTheme('dark'); // sets data-theme on <html>, stores the choice, tells every toggle
resolveTheme('system'); // 'light' or 'dark', from the OS setting

Themed regions

Any element can set its own theme:

<section data-theme="dark" style="background: var(--apui-surface-page)">
  …
</section>

An element with data-theme resets its text color and color-scheme for its subtree, but doesn't paint a background. Put a themed region on a surface: a component such as Card, or background: var(--apui-surface-page).

Stay in the Loop

Monthly tips, tutorials and package updates — plus a free Quick Start cheat sheet.

Subscribe
Edit this page on GitHub