<!--
Source: https://www.theui.dev/docs/colors
Part of the theui-svelte documentation. Index: https://www.theui.dev/llms.txt
-->

# Colors and Branding

One of the main features of theui-svelte components library is its customizable color options, allowing you to maintain brand identity and ensure consistent theming efficiently.

On top of Tailwind's own palette, the library defines a set of brand and status colors in a `@theme` block. They behave exactly like Tailwind's native color classes, shades included, and every component reads from them, so changing one variable restyles the whole library.

## Available Color Classes

The library exposes these colors as utility classes you can use in your own markup. Here is the full list:

#### Shaded Colors

        50
        100
        200
        300
        400
        500
        600
        700
        800
        900
        950

> **Note:** **[T]** = **Type** (e.g., `bg`, `text`, `border`, `fill`, etc.) **[S]** = **Shade** (e.g., 50, 100-900, 950) **Class example**: `bg-brand-500`, `text-brand-600`, `bg-error-400` The foreground colors have no shades: `text-on-brand`, `text-default`, `text-muted`.

#### Non-shaded Colors

|  | Light mode | Dark mode |  |
| --- | --- | --- | --- |
| {colorData.propertyName} | {color.title} ({color.className}) {color.variable} |  |  |

## What Each Color Controls

Before changing anything, it helps to know which token does what. Most of the library runs on a handful of them.

| Token | Where you see it |
| --- | --- |
| `--color-brand-*` | Primary buttons, the active tab, the selected day of a calendar, the filled part of a range, wizard steps, links and every focus ring. Shade `500` carries most of it, with `600` for hover and `300` for lighter accents. |
| `--text-color-on-brand` | The text and icons that sit on top of a brand background. It is one value, not a scale. |
| `--color-error-*`, `info`, `success`, `warning` | Alerts, badges, notifications, and the states of a form field. |
| `--background-color-*` | Surfaces: the page (`primary`), cards, menus and panels (`secondary`), the layer above those (`tertiary`), and the inverted one (`alt`). |
| `--text-color-*` | Body text (`default`), secondary text such as helper text and placeholders (`muted`), and text on the inverted surface (`alt`). |

So a rebrand is usually two things: the brand scale, and the foreground that goes on top of it. Everything else follows.

## Rebrand In One Step

The library's own brand scale is nothing but aliases of Tailwind's rose palette. Point those eleven variables at another Tailwind palette and every component moves with it.

**./src/app.css**

```css
@import 'tailwindcss';
@import 'theui-svelte/style';

@theme {
  --color-brand-50: var(--color-indigo-50);
  --color-brand-100: var(--color-indigo-100);
  --color-brand-200: var(--color-indigo-200);
  --color-brand-300: var(--color-indigo-300);
  --color-brand-400: var(--color-indigo-400);
  --color-brand-500: var(--color-indigo-500);
  --color-brand-600: var(--color-indigo-600);
  --color-brand-700: var(--color-indigo-700);
  --color-brand-800: var(--color-indigo-800);
  --color-brand-900: var(--color-indigo-900);
  --color-brand-950: var(--color-indigo-950);
}
```

Your own palette works the same way, with values in place of the aliases. Any CSS color will do, though `oklch` is what Tailwind itself uses, and it keeps the steps between shades even.

**./src/app.css**

```css
@theme {
  --color-brand-500: oklch(0.62 0.19 264);
  --color-brand-600: oklch(0.55 0.19 264);
  /* ... and the rest of the scale */
}
```

**Where you put this matters.** The override has to come after `@import 'theui-svelte/style'`. Both declarations land in the same layer, so the later one wins; put it above the import and nothing changes.

**Check the contrast while you are here.** `--text-color-on-brand` is white, which suits a mid or dark brand color. Pick a light one, such as amber or lime, and every primary button becomes white on light, which nobody can read. Set the foreground with the brand, aiming for at least 4.5:1 against shade `500`; the [accessibility guide](https://www.theui.dev/docs/accessibility) covers the targets.

**./src/app.css**

```css
@theme {
  --color-brand-500: var(--color-amber-400);
  --text-color-on-brand: #16161D;   /* dark text on a light brand */
}
```

## Colors In Dark Mode

Surfaces and text colors are declared twice: once for light mode in `@theme`, and again inside `.dark` in the base layer. The base layer comes after the theme layer, so the dark values win whenever the `dark` class is on the page. An override in `@theme` alone therefore changes light mode only, and the change appears to vanish the moment you switch to dark.

To change both, write both. Surfaces and text go in two places; the brand and status scales are not re-declared for dark mode, so those need the `@theme` block only.

**./src/app.css**

```css
@import 'tailwindcss';
@import 'theui-svelte/style';

@theme {
  /* light mode, and the brand scale for both modes */
  --color-brand-500: var(--color-indigo-500);
  --background-color-primary: #ffffff;
  --background-color-secondary: #f4f4f7;
  --text-color-muted: #5a5a63;
}

@layer base {
  .dark {
    /* dark mode only */
    --background-color-primary: #0b0b10;
    --background-color-secondary: #14141b;
    --text-color-muted: #9b9ba3;
  }
}
```

The `dark` class itself belongs on the `<html>` element. The [DarkMode](https://www.theui.dev/docs/dark-mode) component puts it there and remembers the choice.

## Reskin Every Surface At Once

Behind the surface and text tokens sit eight raw values. Six are the surfaces, three for light and three for dark: every `bg-*` token is built from those, and `text-default` and `text-alt` borrow from them too. That makes them the shortest way to change the feel of a whole app without touching a single component.

The other two are `--text-muted-on-light` and `--text-muted-on-dark`, which feed `--text-color-muted`, the color of the `text-muted` class: helper text, placeholders, timestamps and other secondary text. They stand apart from the six because muted text is not a surface. It has to stay readable against the page while still sitting back from the body text, and the value that does that in light mode is not the one that does it in dark mode. The library picks the right one for the current mode, so you set both and think no further about it.

**./src/app.css**

```css
:root {
  --theui-light1: #FFFFFF;   /* the page */
  --theui-light2: #F4F4F7;   /* cards, menus, panels */
  --theui-light3: #E8E8EE;   /* the layer above those */
  --theui-dark1: #0B0B10;    /* the page, in dark mode */
  --theui-dark2: #14141B;
  --theui-dark3: #1C1C26;
  --text-muted-on-light: #5A5A63;
  --text-muted-on-dark: #9B9BA3;
}
```

These are plain CSS variables rather than theme tokens, so they build no utilities of their own; they only feed the tokens above. That also makes them simpler to override than a theme token: they live on `:root`, so a `:root` block of your own in `app.css` replaces them, with no `@theme` and no separate rule for dark mode. Redefine them after the import, as with everything else on this page.

Set only the ones you want to move. Anything you leave out keeps the library's value, so changing `--text-muted-on-dark` alone is a perfectly good edit.

## Modify Existing Colors

You can override the library's default colors by assigning new values to the corresponding CSS theme variables:

**./src/app.css**

```css
@theme {
  /* Modify brand primary colors */
  --color-brand-50: #f0f9ff;
  --color-brand-100: #e0f2fe;
  --color-brand-200: #bae6fd;
  --color-brand-300: #7dd3fc;
  --color-brand-400: #38bdf8;
  --color-brand-500: #0ea5e9;
  --color-brand-600: #0284c7;
  --color-brand-700: #0369a1;
  --color-brand-800: #075985;
  --color-brand-900: #0c4a6e;
  --color-brand-950: #082f49;

  /* Modify background colors */
  --background-color-primary: #ffffff;
  --background-color-secondary: #f8fafc;

  /* Modify text colors */
  --text-color-default: #1e293b;
  --text-color-muted: #64748b;
}
```

## Add New Color

Colors of your own go in the same `@theme` block, and the name you choose decides which utilities Tailwind builds from it. Get the prefix wrong and nothing is reported: the variable is defined, the class simply never exists.

#### Add Shaded Colors

A name under `--color-*` gives you the whole family of utilities for that color: background, text, border, ring, fill, and the rest.

**./src/app.css**

```css
@theme {
  --color-accent-50: #f0f9ff;
  --color-accent-100: #e0f2fe;
  /* ... add more shades as needed */
  --color-accent-500: #0ea5e9;
  --color-accent-950: #082f49;
}
```

Use them as `bg-accent-500`, `text-accent-300`, `border-accent-700`, `ring-accent-500`.

#### Add Non-shaded Colors

A single color for one purpose belongs under the namespace of the property it serves: `--background-color-*` for backgrounds and `--text-color-*` for text, the same namespaces this library uses for its own surfaces. `--background-*` and `--text-*` are **not** color namespaces, and `--text-*` in particular belongs to font sizes, so a color defined there quietly produces nothing.

**./src/app.css**

```css
@theme {
  /* Right: these build bg-surface and text-highlight */
  --background-color-surface: #f8fafc;
  --text-color-highlight: #4338ca;

  /* Wrong: no utility comes out of either of these */
  --background-surface: #f8fafc;
  --text-highlight: #4338ca;
}
```

Then write `bg-surface` and `text-highlight` as you would any other utility. The same pattern holds for `--border-color-*`, `--fill-*` and `--ring-color-*`.

## Remove A Color

To completely remove a color from your theme, set its namespace to initial:

**./src/app.css**

```css
@theme {
  /* Remove the warning color palette */
  --color-warning-*: initial;

  /* Remove specific non-shaded colors */
  --background-color-tertiary: initial;
  --text-color-alt: initial;
}
```

This will remove all the `warning` color classes, `bg-tertiary` and `text-alt` class from the application!

## Available Color Palette

This is what `theui-svelte/style.css` defines. The brand and status scales are aliases of Tailwind's own palettes, which is why pointing one at another palette takes a single line each.

**theui-svelte/style.css**

```css
:root {
  /* The raw surface values every light and dark background is built from */
  --theui-light1: #FFFDFD;
  --theui-light2: #F5F3F3;
  --theui-light3: #EBE9E9;
  --theui-dark1: #16161D;
  --theui-dark2: #1E1E26;
  --theui-dark3: #26262F;
  --text-muted-on-light: #636369;
  --text-muted-on-dark: #A1A1AA;
}

@theme {
  /* Brand: 50 to 950, aliased to Tailwind's rose scale */
  --color-brand-50: var(--color-rose-50);
  --color-brand-100: var(--color-rose-100);
  --color-brand-200: var(--color-rose-200);
  --color-brand-300: var(--color-rose-300);
  --color-brand-400: var(--color-rose-400);
  --color-brand-500: var(--color-rose-500);
  --color-brand-600: var(--color-rose-600);
  --color-brand-700: var(--color-rose-700);
  --color-brand-800: var(--color-rose-800);
  --color-brand-900: var(--color-rose-900);
  --color-brand-950: var(--color-rose-950);

  /* What text and icons use on top of a brand background */
  --text-color-on-brand: #FFFFFF;

  /* Status colors, each aliased the same way across all 11 shades */
  --color-error-50 ... --color-error-950:   var(--color-red-*);
  --color-info-50 ... --color-info-950:     var(--color-sky-*);
  --color-success-50 ... --color-success-950: var(--color-green-*);
  --color-warning-50 ... --color-warning-950: var(--color-yellow-*);

  /* Text */
  --text-color-default: var(--theui-dark1);
  --text-color-muted: var(--text-muted-on-light);
  --text-color-alt: var(--theui-light1);

  /* Surfaces */
  --background-color-primary: var(--theui-light1);
  --background-color-secondary: var(--theui-light2);
  --background-color-tertiary: var(--theui-light3);
  --background-color-alt: var(--theui-dark1);
}

/* Dark mode swaps the same names, so every component follows */
@layer base {
  .dark {
    --text-color-default: var(--theui-light2);
    --text-color-muted: var(--text-muted-on-dark);
    --text-color-alt: var(--theui-dark1);

    --background-color-primary: var(--theui-dark1);
    --background-color-secondary: var(--theui-dark2);
    --background-color-tertiary: var(--theui-dark3);
    --background-color-alt: var(--theui-light2);
  }
}
```

The status scales are written out in full in the stylesheet; they are shortened here because every shade follows the same pattern. Read the file in the [GitHub repository](https://github.com/mbparvezme/theui-svelte) for the literal source.

---

Category: Guides
Keywords: colors, branding, style, guide, theme, customization, theui-svelte, svelte, component-library
Full documentation set: https://www.theui.dev/llms-full.txt
