---
title: "Theming"
description: "Restyle GistUI with theme presets, tokens, CSS variables and style hooks, and make it work with Tailwind."
---

> Documentation Index
> Fetch the complete documentation index at: https://gistui.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Theming

There are four levels of control, from least to most. Most apps stop at the second.

## 1. Presets

```tsx
<GistUI library={ui} stream={stream} theme="system" color="violet" />
```

- `theme`: `"system"` (default), `"light"` or `"dark"`.
- `color`: `neutral`, `slate`, `stone`, `rose`, `pink`, `violet`, `indigo`, `blue`, `teal`, `green`, `orange`, `amber`, `red`.

A program can pick its own accent with `Page(…, accent:teal)`. Your `tokens` (below) override it.

```gistui
root = Grid(Box(Header("Teal", size:sm), Progress(64, "Progress"), Button("Action"), accent:teal, pad:md, surface:card, gap:md), Box(Header("Rose", size:sm), Progress(64, "Progress"), Button("Action"), accent:rose, pad:md, surface:card, gap:md), Box(Header("Amber", size:sm), Progress(64, "Progress"), Button("Action"), accent:amber, pad:md, surface:card, gap:md), cols:3)
```

## 2. Tokens from code

Tokens are scoped to one instance and override presets and model accents.

```tsx
import { defineTheme } from "@gistui/react";

const brand = defineTheme({
  primary: "#0f766e",
  accent: "#0d9488",
  radius: 14,
  density: 0.9,
  font: "Geist, sans-serif",
  chart: ["#0d9488", "#f59e0b"],
});

<GistUI library={ui} tokens={brand} darkTokens={{ primary: "#2dd4bf", primaryFg: "#042f2e" }} stream={stream} />;
```

> **Caution**
>
> `tokens` are for values from your own code. Never build them from model output or user input: a token is inserted into CSS.

## 3. CSS variables and style hooks

Every token is a `--gistui-*` custom property, and you can set any of them in plain CSS:

```css
.gistui {
  --gistui-radius: 6px;
  --gistui-font: "Geist", sans-serif;
}
```

Every component also carries attributes to select on:

```css
[data-gistui="Card"] { box-shadow: 0 1px 2px rgb(0 0 0 / 0.06); }
[data-gistui="Tag"][data-tone="success"] { font-weight: 600; }
[data-gistui="Button"][data-v="primary"] { text-transform: uppercase; }
```

- `data-gistui="Name"` on the root of each component.
- `data-v`, `data-tone`, `data-size` for its variants.
- `data-gistui-color`, `data-gistui-radius`, `data-gistui-density` on the container for presets.

All GistUI CSS is in `@layer gistui`. Unlayered CSS in your app wins without `!important`.

## 4. Your own components

When CSS is not enough, replace the component and keep its schema: [Custom components](/docs/guides/custom-components/).

## With Tailwind

Tailwind's reset and utilities are in cascade layers too. The order must be: reset, then GistUI, then utilities.

```css
@layer theme, base, gistui, components, utilities;
```

`@gistui/styles/styles.css` declares that order itself, so **import it before your Tailwind CSS**:

```ts
import "@gistui/styles/styles.css";
import "./app.css"; // @import "tailwindcss";
```

Utility classes passed through `classNames` then win over component styles:

```tsx
<GistUI library={ui} classNames={{ Card: "shadow-lg", Button: "rounded-full" }} stream={stream} />
```

## Light and dark

`theme="system"` follows `prefers-color-scheme`. If your app has its own toggle, pass `"light"` or `"dark"` from it. These docs do exactly that for every live preview.

Source: https://gistui.com/docs/guides/theming/index.mdx
