# Theming

> Restyle ZenithDocs with CSS custom properties.

Source: https://aymericchaverot.github.io/zenith-docs/customization/theming/

ZenithDocs styles are built on the design tokens of [Lumos](https://lumosframework.com). Changing a handful of custom properties is enough to make the site yours. To try everything below at once and leave with the files to paste, use the [theme builder](/customization/builder/).

## Packaged themes

A theme sets an accent, a backdrop and a font preset that go together, and a few tokens of its own, such as corner radii.

```js title="astro.config.mjs"
zenith({
  title: 'My Docs',
  theme: 'paper', // [!code highlight]
});
```

| Theme      | Accent  | Backdrop | Fonts        | Also                                    |
| ---------- | ------- | -------- | ------------ | --------------------------------------- |
| `zenith`   | emerald | dither   | `instrument` | The defaults, named                    |
| `slate`    | neutral | grid     | `schibsted`  | Squarer corners                        |
| `terminal` | teal    | grain    | `space`      | Sharp corners, thinner scrollbars      |
| `paper`    | amber   | none     | `literata`   | Rounder corners, narrower reading width |
| `aurora`   | violet  | aurora   | `geist`      | Rounder corners                        |

A theme only fills in what you leave unset: `theme: 'paper', accent: 'rose'` keeps everything from Paper except the accent. Its other tokens can be overridden in a `customCss` file like any other.

## Accent presets

The default accent is `emerald`. Pick another preset with the `accent` option: `teal`, `amber`, `rose`, `violet`, or `neutral` for a black and white theme. Try them in the [theme builder](/customization/builder/), which also takes any custom color.

```js title="astro.config.mjs"
zenith({
  title: 'My Docs',
  accent: 'violet', // [!code highlight]
});
```

## Backdrop

Pages are drawn over a decorative background, tinted with the accent color. Pick its style with the `backdrop` option, and compare them in the [theme builder](/customization/builder/).

```js title="astro.config.mjs"
zenith({
  title: 'My Docs',
  backdrop: 'grid', // [!code highlight]
});
```

| Style           | Looks like                                                     |
| --------------- | -------------------------------------------------------------- |
| `dither`        | Two offset dot grids, like a halftone print. The default       |
| `aurora`        | Blurred color fields                                           |
| `grid`          | A ruled grid fading downwards                                  |
| `dots`          | Evenly spaced dots                                             |
| `rays`          | Light rays coming from above the page                          |
| `grain`         | Film grain over the whole viewport                             |
| `horizon`       | A glowing line under the header                                |
| `horizon-glow`  | The same line, over a wider glow                               |
| `glow`          | A soft accent glow, nothing else                               |
| `none`          | No background                                                  |

`aurora`, `dither` and `grain` stay in place while the page scrolls; the other styles sit at the top of the page. `dither` is anchored to the top left, and `backdropPosition: 'center'` or `'right'` moves it.

Every style is plain CSS, with no image file to download and no JavaScript: `grain` draws its noise with an SVG filter inlined in the stylesheet. Tune them with `--zd-backdrop-strength`, for the dither dots, and `--zd-backdrop-line`, for the grid and dots.

```css
.theme-light {
  --zd-backdrop-line: color-mix(in oklab, var(--text) 5%, transparent);
}
```

## Add a stylesheet

Create a CSS file and register it with the `customCss` option.

```js title="astro.config.mjs"
zenith({
  title: 'My Docs',
  customCss: ['./src/styles/theme.css'], // [!code highlight]
});
```

Custom stylesheets are loaded after the built-in styles and are not part of any cascade layer, so they always win without `!important`.

## Colors

Set your own accent for each color scheme:

```css title="src/styles/theme.css"
:root {
  --zd-accent-light: oklch(55% 0.16 145);
  --zd-accent-dark: oklch(80% 0.15 145);
}
```

Light and dark themes are defined with the Lumos `theme-light` and `theme-dark` classes. Each redeclares the same tokens, so you can tune them independently:

```css
.theme-dark {
  --background: oklch(15% 0.02 260);
  --background-2: oklch(19% 0.02 260);
}
```

| Token                | Used for                                          |
| -------------------- | ------------------------------------------------- |
| `--zd-accent-light`  | Accent in light mode: links, active items, tabs   |
| `--zd-accent-dark`   | Accent in dark mode                               |
| `--background`       | Page background                                   |
| `--background-2`     | Raised surfaces: code blocks, hovers              |
| `--text`             | Body text                                         |
| `--text-2`           | Secondary text                                    |
| `--border`           | Hairlines                                         |

The [theme builder](/customization/builder/) writes these for any color you pick, and derives the dark accent from the light one.

## Typography

ZenithDocs ships seven font presets, self-hosted through the Astro Fonts API. The default, `instrument`, sets Instrument Serif over Instrument Sans with Martian Mono for code. Pick another with the `fonts` option, and compare them on the [typography](/customization/typography/) page.

The same page covers the three family tokens, `--font-body`, `--font-mono` and `--font-display`, [fonts of your own](/customization/typography/#setting-your-own), and the [scales](/customization/typography/#sizes) that make all text larger or smaller at once.

## Layout

The width of the sidebar, the maximum width of the content column, and the radius of every rounded corner:

```css
:root {
  --zd-sidebar-width: 18rem;
  --zd-content-width: 52rem;
  --radius-main: 0;
}
```

## Scrollbars

The page, the sidebar, the table of contents, code blocks and the search results all share one thin scrollbar style: a rounded thumb over a transparent track, so the background shows through.

The thumb is mixed from `--text` instead of being given a color of its own, which means it follows the light and dark themes, and any background you set, without being redefined.

```css
:root {
  --zd-scrollbar-size: 0.75rem;
  --zd-scrollbar-thumb: color-mix(in oklab, var(--accent) 30%, transparent);
}
```

| Token                         | Used for                                  |
| ----------------------------- | ----------------------------------------- |
| `--zd-scrollbar-size`         | Width of the scrollbar                    |
| `--zd-scrollbar-inset`        | Space kept around the thumb               |
| `--zd-scrollbar-thumb`        | Thumb at rest                             |
| `--zd-scrollbar-thumb-hover`  | Thumb while the pointer is over the box   |
| `--zd-scrollbar-thumb-active` | Thumb while it is being dragged           |

Firefox has no fine-grained control over scrollbars, so it gets `scrollbar-width: thin` and the same thumb color, without the rounding.

## Cascade layers

Built-in styles are split into layers, from lowest to highest priority:

```css
@layer lumos.base, zenith.theme, zenith.layout, zenith.content, zenith.components;
```