---
title: "Themes and backgrounds"
description: "Color-system modes, the theme and layoutBackground props, data-theme and how regions switch palettes."
requested_language: nl
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/nl/next/concepts/themes
version: unreleased (main)
docs_index: https://docs.systhema.app/nl/next/llms.txt
---
> This page isn't translated yet. Showing English.


A Systhema theme is a mode of the `colorSystem` token collection: one complete set of semantic colors. Any region of a page can switch to another theme, and any region can paint one of the theme's page backgrounds. With the default tokens the themes are `default` and `dark`, and the backgrounds are `main` and `alternative`. This page explains how the two props that control this, `theme` and `layoutBackground`, work together.

```tsx preview iframe bleed height=720 title="One Section, four combinations"
import { Button, Heading, Paragraph, Section } from '@systhemaui/next'

const bands = [
  { theme: 'default', layoutBackground: 'main' },
  { theme: 'default', layoutBackground: 'alternative' },
  { theme: 'dark', layoutBackground: 'main' },
  { theme: 'dark', layoutBackground: 'alternative' },
] as const

export default function Demo() {
  return (
    <div className="w-full">
      {bands.map(({ theme, layoutBackground }) => (
        <Section key={theme + layoutBackground} theme={theme} layoutBackground={layoutBackground}>
          <Heading.h3>
            theme=&quot;{theme}&quot; layoutBackground=&quot;{layoutBackground}&quot;
          </Heading.h3>
          <Paragraph>The same markup resolves every color from the theme it sits in.</Paragraph>
          <Paragraph>
            <Button.a href="#" variant="primary">
              Get started
            </Button.a>
          </Paragraph>
        </Section>
      ))}
    </div>
  )
}
```

## How a theme works

Each `colorSystem` mode becomes a block of `--color-*` variables. The first mode is the default and is bound to `:root` as well as its own selector; every other mode is bound to a `data-theme` attribute:

```css
:root,
[data-theme='default'] {
  --color-foundations-bg: #ffffff;
  --color-foundations-text: #000000;
  --color-typography-heading: var(--color-foundations-text);
}

[data-theme='dark'] {
  --color-foundations-bg: #0a0a0a;
  --color-foundations-text: #ffffff;
  --color-typography-heading: var(--color-foundations-text);
}
```

Every mode declares the same variable names with its own values. Components never name a theme; they read the variables, so a `data-theme` attribute on any ancestor switches everything inside it. The nearest `data-theme` wins, so themed regions can nest.

The variables start from a set of **foundations** (`bg`, `text`, `text-muted`, `surface-bg`, `primary-bg`, `line`, …) and every component color (`--color-button-primary-normal-background`, `--color-card-…`) refers back to them. See [Color tokens](https://docs.systhema.app/nl/next/design/color-tokens.md) for the structure and [Colors](https://docs.systhema.app/nl/next/reference/tokens/colors.md) for every value.

## The `theme` prop

Layout components take `theme?: ColorSystem` and set `data-theme` on their root: [`Article`](https://docs.systhema.app/nl/next/components/article.md), [`Section`](https://docs.systhema.app/nl/next/components/section.md), [`Feature`](https://docs.systhema.app/nl/next/components/feature.md), [`Card`](https://docs.systhema.app/nl/next/components/card.md), the heroes, [`Header`](https://docs.systhema.app/nl/next/components/header.md), [`Footer`](https://docs.systhema.app/nl/next/components/footer.md), [`Gallery`](https://docs.systhema.app/nl/next/components/gallery.md) and the posts components. `ColorSystem` is generated from your tokens, so it lists your project's themes.

A theme only changes variables. It sets no `color` and no `background` of its own, which has two consequences:

- Systhema components set their own colors from the variables (`Heading` carries `color-heading`, `Paragraph` `color-body`), so they follow the theme. A plain `<span>` you write inside a themed region inherits whatever color its parent set; give it a token color such as `text-(--color-foundations-text)`.
- A themed region without a background keeps the page background behind it. Pair `theme` with `layoutBackground` whenever the region should look different, or light text ends up on a light page. In the preview the first band is there, but its white text is invisible on the light page:

```tsx preview iframe bleed height=360 title="theme without a background"
import { Heading, Paragraph, Section } from '@systhemaui/next'

export default function Demo() {
  return (
    <div data-theme="default" className="bg-layout-main w-full">
      <Section theme="dark">
        <Heading.h3>theme=&quot;dark&quot; only</Heading.h3>
        <Paragraph>The dark text colors land on the light page background.</Paragraph>
      </Section>
      <Section theme="dark" layoutBackground="main">
        <Heading.h3>theme=&quot;dark&quot; layoutBackground=&quot;main&quot;</Heading.h3>
        <Paragraph>The section paints the dark theme's own background.</Paragraph>
      </Section>
    </div>
  )
}
```

## The `layoutBackground` prop

`layoutBackground?: LayoutBackground` paints one of the theme's page backgrounds with a `bg-layout-<name>` class, which sets `background-color: var(--color-layout-bg-<name>)`. With the default tokens `main` is the theme's `foundations.bg` and `alternative` its `foundations.surface-bg`. Because the class reads a variable, `bg-layout-alternative` on a `dark` section paints the dark alternative.

`Article`, `Section`, `Feature` and `Gallery` take `layoutBackground`. Elsewhere, use the class directly: `<div className="bg-layout-alternative">`. Add backgrounds in Figma, or with `customTokens.colorSystem.<theme>.layout.bg`; the `LayoutBackground` type follows.

## Backgrounds and section spacing

Inside an [`Article`](https://docs.systhema.app/nl/next/components/article.md), backgrounds also decide spacing. Adjacent sections with neither a `theme` nor a `layoutBackground` read as one band, so the padding between them is removed. Adjacent sections with the same `theme` and the same `layoutBackground` also merge. Give one of two neighbours a different background when they should read as two bands. See [Spacing model](https://docs.systhema.app/nl/next/concepts/spacing-model.md#section-padding).

## Setting the page theme

The root layout sets the page's theme and background once:

```tsx title="src/app/layout.tsx"
<html lang="en" data-theme="default">
  <body className="bg-layout-main">{children}</body>
</html>
```

To let visitors switch the whole site to `dark`, change the `data-theme` attribute on `<html>`; every region without its own `theme` follows. Regions with an explicit `theme` keep it. The [theming and dark mode recipe](https://docs.systhema.app/nl/next/guides/recipes/theming-and-dark-mode.md) shows a complete toggle.

## Adding a theme

Add a mode to the `colorSystem` collection in Figma and re-export; the new name appears in `ColorSystem` and as a `[data-theme='<name>']` block after `pnpm sync`. A mode added only through `customTokens` must declare every variable: anything it leaves out is inherited, already resolved, from the nearest themed ancestor, not from `default`. See [Custom tokens](https://docs.systhema.app/nl/next/design/custom-tokens.md).

## Related

- [Color tokens](https://docs.systhema.app/nl/next/design/color-tokens.md)
- [Colors](https://docs.systhema.app/nl/next/styling/colors.md)
- [Spacing model](https://docs.systhema.app/nl/next/concepts/spacing-model.md)
- [Generated types](https://docs.systhema.app/nl/next/reference/generated-types.md)
