Docs
Next

Theming and dark mode

Apply a token-defined palette to a page or region without hardcoded color utilities.

On this page

GoalLink to this section

Give one page a light body and an intentional dark enquiry band. The example assumes the shipped default and dark modes and main and alternative backgrounds.

1. Confirm the available modesLink to this section

cat .systhema/references/tokens/_index.toon

Read the colorSystem reference and config overrides. If a mode is absent, import or define the design first; a prop does not create a mode.

2. Apply the theme to the containerLink to this section

src/app/(site)/theme-example/page.tsx
import { Article, Section, Heading, Paragraph, Button, ButtonTitle } from '@systhemaui/next'

export default function ThemeExample() {
  return (
    <main id="main-content">
      <Article theme="default" layoutBackground="main">
        <Section>
          <Heading.h1>A workplace that fits your team</Heading.h1>
          <Paragraph>Our process starts with how you work.</Paragraph>
        </Section>
        <Section theme="dark" layoutBackground="alternative">
          <Heading.h2>Plan your next move</Heading.h2>
          <Paragraph>
            <Button.a href="/contact" variant="primary">
              <ButtonTitle>Send an enquiry</ButtonTitle>
            </Button.a>
          </Paragraph>
        </Section>
      </Article>
    </main>
  )
}

theme establishes a data-theme scope. layoutBackground selects a layout ground in that scope. Descendants use semantic colors from the selected palette.

3. Change the design, not each elementLink to this section

For a Design CLI session, inspect and change a foundation color:

systhema design color get foundations.bg --mode dark --resolve
systhema design color set foundations.bg '#0B0B0F' --mode dark
systhema design color check --mode dark
systhema design apply --dry-run

Review, then run systhema design apply from a clean tree. Do not add text-white or a raw hex background to every child of the dark section.

4. Keep mode names stable in PayloadLink to this section

Theme names can be stored in published page and block fields. Renaming a mode requires migrating those stored values before applying the design. Follow Database migrations; do not treat a stored design key as a cosmetic rename.

This recipe applies a fixed region palette. A site-wide preference switch also needs project-owned state, persistence and initial-render handling. Do not assume a theme prop implements those behaviors.

Check your workLink to this section

  • Text, controls and media overlays inherit the selected palette.
  • Focus states and contrast work in each supported mode.
  • The two section bands keep the expected spacing.
  • No stored theme value points at a removed mode.

See Themes and backgrounds and Color tokens.