Theme
Full reference for ThemeConfig, the colour and code token types, the design tokens, ThemeStyles and resolveThemeCss.
import { resolveThemeCss } from "pzzadocs";
import { ThemeStyles } from "pzzadocs/ui";
import type {
ThemeConfig,
ResolvedThemeConfig,
ThemeColors,
CodeTokenColors,
CodeThemePair,
ThemePreset,
ThemeDensity,
ThemeFonts,
ThemeLayout,
} from "pzzadocs";ThemeConfig#
The theme section of DocsConfig. defineConfig fills in defaultTheme, hotKey, preset, codeTheme and density and returns a ResolvedThemeConfig; the override sections stay partial.
interface ThemeConfig {
defaultTheme?: "light" | "dark" | "system";
hotKey?: boolean;
preset?: ThemePreset;
colors?: { light?: Partial<ThemeColors>; dark?: Partial<ThemeColors> };
code?: { light?: Partial<CodeTokenColors>; dark?: Partial<CodeTokenColors> };
codeTheme?: "pzza" | CodeThemePair;
radius?: number | string;
fonts?: ThemeFonts;
layout?: ThemeLayout;
density?: ThemeDensity;
}| Name | Type | Default | Description |
|---|---|---|---|
defaultTheme | "light" | "dark" | "system" | "system" | Theme before the visitor picks one. |
hotKey | boolean | true | Pressing D outside inputs and with the search dialog closed toggles light and dark. |
preset | ThemePreset | "mono" | Built-in palette applied before colors: mono, slate, warm, contrast, ocean, dusk, forest, ember or rose. mono is the stylesheet default and emits nothing. |
colors | { light?: Partial<ThemeColors>; dark?: Partial<ThemeColors> } | - | Colour token overrides per scheme. Only the keys you set are emitted. |
code | { light?: Partial<CodeTokenColors>; dark?: Partial<CodeTokenColors> } | - | Token group overrides for the bundled code themes. Ignored when codeTheme is a custom pair. |
codeTheme | "pzza" | { light: ThemeRegistration; dark: ThemeRegistration } | "pzza" | The bundled subdued pair, or any two shiki theme registrations, for example objects imported from shiki/themes. |
radius | number | string | 4 | Corner radius for every control. Numbers are pixels. Also derives --pd-radius-sm as max(2px, calc(radius - 1px)). |
fonts | ThemeFonts | - | font-family values for text and code. |
layout | ThemeLayout | - | Sidebar, TOC, content and header sizes. |
density | "comfortable" | "compact" | "comfortable" | Row heights and paddings. comfortable matches the stylesheet defaults and emits nothing. |
ResolvedThemeConfig#
interface ResolvedThemeConfig extends ThemeConfig {
defaultTheme: "light" | "dark" | "system";
hotKey: boolean;
preset: ThemePreset;
codeTheme: "pzza" | CodeThemePair;
density: ThemeDensity;
}ThemeColors#
One key per colour token. Any CSS colour string is accepted and used as written.
| Key | Token | Used for |
|---|---|---|
background | --pd-background | Page and header background. |
surface | --pd-surface | Cards, code blocks, dialogs, buttons. |
surface2 | --pd-surface-2 | Hover states, code block headers, inline code, callouts. |
surface3 | --pd-surface-3 | Active sidebar item, selected search row, highlighted code lines. |
foreground | --pd-foreground | Primary text and active states. |
foreground2 | --pd-foreground-2 | Secondary text, callout bodies. |
mutedForeground | --pd-muted-foreground | Descriptions, nav tabs, TOC, section labels. |
faintForeground | --pd-faint-foreground | Placeholders, line numbers, separators. |
border | --pd-border | Every default border. |
borderStrong | --pd-border-strong | Hovered card borders, link underlines, word highlights. |
sidebar | --pd-sidebar | Sidebar background. |
ring | --pd-ring | Focus ring. |
overlay | --pd-overlay | Backdrop behind the search dialog, mobile drawer and image zoom. |
accent | --pd-accent | Prose links, the active header tab underline, active tab and code tab underlines. Equals foreground in the gray presets. |
accentForeground | --pd-accent-foreground | Text on an accent background. |
Preset values for each key are listed on the Presets page.
CodeTokenColors#
Token groups of the bundled pzza-light and pzza-dark themes. Each key maps to a set of TextMate scopes; the defaults below are what codeTheme: "pzza" ships with.
| Key | Scopes | Light | Dark |
|---|---|---|---|
plain | Source text and the theme foreground. | #111111 | #ececec |
keyword | Keywords, storage, control flow, new, typeof; also bold headings in Markdown. | #5b4bb5 | #b4a4f5 |
fn | Function and method names, calls. | #2f5fa6 | #8db4f0 |
string | Strings, template literals, inline code in Markdown. | #3b7f5c | #8fc9a6 |
number | Numbers, booleans, language constants. | #a8632a | #e0a874 |
type | Types, classes, interfaces, namespaces. | #22768a | #7fc3cf |
tag | HTML and JSX tags, components. | #a8403a | #e39a93 |
attribute | Tag attribute names. | #6a6a6a | #c4c4c4 |
property | Object keys, YAML keys, JSON and CSS property names. | #3d3d3d | #d8d8d8 |
variable | Variables and parameters. | #111111 | #ececec |
comment | Comments (rendered italic). | #9a9a9a | #6a6a6a |
punctuation | Operators, braces, separators. | #6a6a6a | #8a8a8a |
regex | Regular expressions. | #3b7f5c | #8fc9a6 |
templatePunctuation | ${ and } in template literals, embedded sections. | #5b4bb5 | #b4a4f5 |
background | Code block background. | #ffffff | #121212 |
CodeThemePair#
interface CodeThemePair {
light: ThemeRegistration;
dark: ThemeRegistration;
}ThemeRegistration is the shiki theme object type. Both themes are loaded into the highlighter and every token carries both colours as CSS variables, so switching schemes does not re-highlight anything.
ThemeFonts#
| Name | Type | Default | Description |
|---|---|---|---|
sans | string | - | font-family for text and UI, written to --pd-font-sans. For next/font pass the published variable, for example var(--font-geist-sans), system-ui, sans-serif. |
mono | string | - | font-family for code, written to --pd-font-mono. |
ThemeLayout#
Numbers are pixels; strings are used verbatim.
| Name | Type | Default | Description |
|---|---|---|---|
sidebarWidth | number | string | 240px | Desktop sidebar width, written to --pd-sidebar-width. |
tocWidth | number | string | 220px | Right-hand TOC column width, written to --pd-toc-width. |
contentWidth | number | string | 72ch | Maximum article width, written to --pd-content-width. |
headerHeight | number | string | 48px | Header height, written to --pd-header-height. Sticky offsets derive from it. |
Design tokens#
Every custom property the stylesheet reads. Colour defaults are the mono preset.
Colour tokens#
| Token | Light | Dark |
|---|---|---|
--pd-background | #fafafa | #0c0c0c |
--pd-surface | #ffffff | #121212 |
--pd-surface-2 | #f2f2f2 | #1a1a1a |
--pd-surface-3 | #e9e9e9 | #232323 |
--pd-foreground | #111111 | #ececec |
--pd-foreground-2 | #3d3d3d | #c4c4c4 |
--pd-muted-foreground | #707070 | #8a8a8a |
--pd-faint-foreground | #a3a3a3 | #5c5c5c |
--pd-border | #e4e4e4 | #242424 |
--pd-border-strong | #cfcfcf | #343434 |
--pd-sidebar | #fafafa | #0c0c0c |
--pd-ring | #111111 | #ececec |
--pd-overlay | rgba(0, 0, 0, 0.4) | rgba(0, 0, 0, 0.6) |
Shape, size and motion tokens#
| Token | Default | Description |
|---|---|---|
--pd-radius | 4px | Border radius for cards, code blocks, buttons, tabs and dialogs. Set by theme.radius. |
--pd-radius-sm | 3px | Radius for inline code, kbd and word highlights. Derived from theme.radius as max(2px, calc(radius - 1px)). |
--pd-header-height | 48px | Header height. Set by theme.layout.headerHeight. |
--pd-banner-height | 0px | Set by Banner while it is visible. |
--pd-sidebar-width | 240px | Desktop sidebar width. Set by theme.layout.sidebarWidth. |
--pd-toc-width | 220px | TOC column width. Set by theme.layout.tocWidth. |
--pd-content-width | 72ch | Maximum article width. Set by theme.layout.contentWidth. |
--pd-content-max-width | calc(76ch + 260px + 48px) | Maximum width of the whole layout row. |
--pd-transition | 120ms ease | Duration and easing for hover and open transitions. 0ms under reduced motion. |
--pd-font-sans | Geist, ui-sans-serif, system-ui, sans-serif | Body and UI font. Set by theme.fonts.sans. |
--pd-font-mono | "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace | Code font. Set by theme.fonts.mono. |
Density tokens#
Emitted only for density: "compact"; the comfortable values are the stylesheet defaults.
| Token | Comfortable | Compact |
|---|---|---|
--pd-row-height | 28px | 24px |
--pd-block-gap | 16px | 12px |
--pd-cell-padding-block | 8px | 5px |
--pd-cell-padding-inline | 12px | 10px |
--pd-box-padding-block | 10px | 8px |
--pd-box-padding-inline | 12px | 10px |
--pd-card-padding | 14px 16px | 10px 12px |
ThemeStyles#
import { ThemeStyles } from "pzzadocs/ui";
function ThemeStyles({ theme }: { theme: ResolvedThemeConfig }): JSX.Element | null;A server component that renders a <style> element with the output of resolveThemeCss(theme). RootProvider renders it for you; include it yourself only when you build a custom provider. Pass config.theme from your defineConfig result.
import { ThemeStyles } from "pzzadocs/ui";
import config from "@/docs.config";
<ThemeStyles theme={config.theme} />resolveThemeCss#
import { resolveThemeCss } from "pzzadocs";
function resolveThemeCss(theme: ResolvedThemeConfig): string;Returns the CSS text ThemeStyles emits: a :root { ... } block followed by a .dark, [data-theme="dark"] { ... } block, each omitted when empty. The empty string means the config changes nothing. Resolution order:
- The preset expands to all thirteen colour tokens for both schemes, unless it is
mono. colors.lightandcolors.darkare layered on top, key by key.radiuswrites--pd-radiusand the derived--pd-radius-sm.fontsandlayoutwrite their tokens; numbers becomepx.density: "compact"appends the compact density tokens.
String values have ;, { and } stripped so a value cannot break out of its declaration. This is a server entry; use it to inline the CSS somewhere other than ThemeStyles, for example in a static export or an email-safe preview.