Skip to content

Customize the Theme

Override Lucode Starlight tokens and extend the visual system without forking the package.

Lucode Starlight keeps most visual decisions in CSS custom properties. Override them from your app-level stylesheet, usually src/styles/global.css, and include that file in Starlight’s customCss.

astro.config.mjs
starlight({
customCss: ['./src/styles/global.css'],
plugins: [lucode()],
});

The theme appends its own CSS after your custom CSS. Use cascade layers and matching selectors when you intentionally want to override Lucode tokens:

src/styles/global.css
@layer lucode {
:root {
--radius: 0.5rem;
--sidebar-width: 17rem;
--container-max-width: 1440px;
}
}
TokenPurpose
--spacingBase spacing unit used by the layout and custom components.
--radiusShared radius for buttons, asides, tabs, and cards.
--header-heightSticky header height.
--sidebar-widthDesktop sidebar width.
--container-max-widthMaximum width for the top-level page container.
--foregroundPrimary text and high-contrast UI color.
--backgroundMain page background.
--primaryPrimary button background.
--secondarySecondary surfaces and quiet controls.
--mutedLow-emphasis backgrounds.
--muted-foregroundSecondary text.
--accentHover and active backgrounds.
--borderBorders and separators.
--code-backgroundCode blocks, cards, tabs, and file trees.

Define light and dark values separately with Starlight’s data-theme attribute.

@layer lucode {
:root[data-theme='light'] {
--foreground: oklch(18% 0.015 250);
--background: oklch(99% 0.003 250);
--primary: oklch(24% 0.03 250);
--primary-foreground: white;
--border: oklch(88% 0.01 250);
}
:root[data-theme='dark'] {
--foreground: oklch(97% 0.005 250);
--background: oklch(14% 0.015 250);
--primary: oklch(97% 0.005 250);
--primary-foreground: oklch(14% 0.015 250);
--border: oklch(28% 0.015 250);
}
}

Lucode maps Starlight’s built-in colors to its own tokens:

--sl-color-bg: var(--background);
--sl-color-text: var(--foreground);
--sl-color-text-accent: var(--foreground);
--sl-color-accent: var(--border);
--sl-color-accent-high: var(--foreground);
--sl-color-gray-1: var(--gray-1);
--sl-color-gray-7: var(--gray-7);

This means Starlight components, Markdown content, badges, asides, and custom theme chrome stay visually aligned when you update Lucode tokens.

The theme refines Starlight’s default Markdown typography, but it does not force a font import. Set fonts globally from your app CSS:

@layer lucode {
:root {
--sl-font: Inter, ui-sans-serif, system-ui, sans-serif;
--sl-font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
}
}

Use the Typography page to review headings, paragraphs, links, tables, lists, images, keyboard shortcuts, and code after changing fonts.

Cards, tabs, file trees, code blocks, and asides use --code-background as their shared surface. For a lighter docs interface, keep it close to the page background:

@layer lucode {
:root[data-theme='light'] {
--code-background: oklch(98% 0.006 250);
}
:root[data-theme='dark'] {
--code-background: oklch(18% 0.01 250);
}
}

For a more panelled interface, increase contrast between --background, --secondary, and --code-background.

Splash pages are regular Starlight docs pages with template: splash. Lucode adds a hero.layout field:

---
title: Developer Portal
description: API docs, examples, and integration guides.
template: splash
hero:
layout: banner
announcement:
text: Version 2.0 is ready
link: /guides/migration/
actions:
- text: Get started
link: /guides/getting-started/
icon: right-arrow
---

Use Splash Pages to compare each layout in context.