Luke UI
Theming

Theming overview

Apply a bundled identity, choose a colour mode, or author a static theme.

Luke UI themes are static stylesheets. An identity defines the visual foundation. A colour mode selects its light or dark values. Components keep the same API in every combination.

Choose an identity

Luke UI ships with two bundled identities:

  • Tactile is the default. It uses stronger depth and a compact material treatment.
  • Paper is flatter, with lighter borders and depth.

Apply the matching CSS file and identity class at the same themed root as themeRootClassName. The identity supplies semantic colour, typography, spacing, radii, material, and depth to its subtree.

import '@luke-ui/react/stylesheet.css';import '@luke-ui/react/themes/tactile.css';import { themeRootClassName } from '@luke-ui/react/theme';import { tactileThemeClassName } from '@luke-ui/react/themes';import { cx } from '@luke-ui/react/utils';import type { PropsWithChildren } from 'react';export function App({ children }: PropsWithChildren) {	return (		<div className={cx(themeRootClassName, tactileThemeClassName)} data-color-mode="dark">			{children}		</div>	);}

Use one identity for an application or independent themed subtree. Identity classes are not nestable, so a child scope cannot switch from Tactile to Paper without becoming a separate themed boundary.

Choose a colour mode

Each identity provides light and dark values. Omit data-color-mode to follow prefers-color-scheme, or set it to light or dark to force a mode. Modes can nest within an identity, which is useful for previews and intentional light-on-dark or dark-on-light boundaries.

<main data-color-mode="dark">
	<App />
	<section data-color-mode="light">
		<Preview />
	</section>
</main>

See Colour modes for server-rendering and portal behaviour.

Identity and colour mode
Identity
Colour mode
Preview

Theme values and component variants

Themes supply the values behind a component. Components expose the safe choices that use those values. For example, Button uses tone and appearance to communicate intent and hierarchy, while the theme supplies the final colours, finish, and depth.

<Button appearance="solid" tone="accent">
	Save changes
</Button>

Use a component API before custom CSS. For a custom element, use the public vars token contract. Do not depend on a component's selectors, generated palette values, or theme implementation details.

Author a theme

When neither bundled identity fits a product, call defineTheme with a curated accent and neutral character. The generated stylesheet contains the full semantic contract for both colour modes and validates contrast before it is written.