Skip to main content

Theming

A theme sets the presentation's colors, typography, and surfaces. Start with a preset, then override the values you need.

TypeScript or CSS?​

Use TypeScript to choose values. Use CSS to define how components display them.

TaskWhere
Set shared colors, fonts, and surfacesnew Stage({ theme }) or stage.theme(...) in TypeScript
Override tokens for one elementThe element's theme option in TypeScript
Set content, position, size, or animated stateComponent options and element properties in TypeScript
Define a component's appearanceA CSS class that uses theme variables
Adjust one instance's CSS detailsclassName for reusable styles, or style for a small override

Theme options become CSS variables. Component styles read those variables, so the same CSS works with different palettes.

Choose a theme​

The default is themes.defaultDark. Set a preset when creating the stage:

import { Stage, themes } from "stageroutine";

const stage = new Stage({ theme: themes.tokyoNight });
PresetPalette
themes.defaultDarkDark canvas, cyan and indigo accents
themes.defaultLightLight canvas, blue and indigo accents
themes.tokyoNightNavy canvas, blue and cyan accents
themes.draculaDark violet canvas, pink and purple accents
themes.cyberpunkDeep purple canvas, crimson and purple accents, cyan text

Preview these palettes on the brand page.

Use stage.theme(...) to change values for later steps. Omitted values keep their current settings. Going backward restores the theme saved for the earlier step.

stage.theme(themes.dracula);

Customize the palette​

Four colors control the main palette. All are optional.

PropertyDefaultRole
background#0c0d12Stage canvas
text#ffffffHeadings and source color for text tints
primary#38bdf8Kickers, focus borders, connectors
secondary#818cf8Decorative glow and surface highlights
stage.theme({
background: "#1e1e2e",
text: "#cdd6f4",
primary: "#cba6f7",
secondary: "#89b4fa",
});

Muted text, glass fills, borders, and shadows follow these colors automatically. gradient() uses the palette; glow() uses secondary. See Visual Effects for effect options and backgrounds.

Automatic Palette Derivation

Adjust surfaces​

Override a derived value when you need a different appearance:

stage.theme({
surface: "#1e293b",
surfaceBorderColor: "#475569",
surfaceBorderWidth: "2px",
radius: "0.75rem",
});

These defaults apply to the dark theme at scale: 1:

PropertyDefault
textMutedText color at 72% opacity
textDimText color at 50% opacity
surfaceGlass gradient mixed from text and canvas colors
surfaceBorderColorText color at 15% opacity
surfaceBorderWidth1px
surfaceHighlightText color at 25% opacity
surfaceShadowDark drop shadow, primary outer glow, secondary inset highlight
surfaceBackdropblur(16px)
surfaceSolid#18181b
surfaceSubtle#1e293b
radius0.5rem

surfaceBackdrop is a CSS backdrop-filter value. Set it to "none" to remove blur.

surfaceSolid and surfaceSubtle are fixed colors. The light preset overrides them with #f4f4f5 and #e2e8f0. They are not derived from background.

Style one element​

Use color for an element's foreground. Use style for CSS details such as letter spacing:

import { Title } from "stageroutine";

const title = Title("Architecture", {
color: "#38bdf8",
style: { letterSpacing: "-0.04em" },
});

Use element properties for position, dimensions, scale, rotation, and opacity. The runtime manages these values during transitions. The style option accepts CSS properties typed with csstype.

Set a local theme​

An element's theme overrides tokens for that element and its DOM children:

import { TerminalBlock } from "stageroutine";

const terminal = TerminalBlock({
title: "zsh",
theme: {
surface: "#11111b",
primary: "#a6e3a1",
secondary: "#cba6f7",
},
});

Omitted tokens inherit from the surrounding theme. Local primary and secondary overrides are independent. Changing one preserves the other.

Derived values recalculate where their source colors change. For example, local text changes recalculate text tints, borders, and the glass fill. Local accent changes recalculate the surface shadow. To keep a specific derived value, set it explicitly in the same local theme.

Change typography​

The bundled fonts are:

PropertyDefaultUsed for
fontSansInterTitles, body text, lists, tables
fontSerifNewsreaderSerif titles and italic emphasis inside standard titles
fontMonoJetBrains MonoCode, terminals, kickers, connector labels

Adjust text size​

The stage scale option defaults to 1. It multiplies default font sizes, spacing, and radii. Explicit theme lengths keep their supplied values.

PropertyDefault at scale: 1Used for
fontSizeHero5remTitle({ variant: "hero" })
fontSizeTitle2.75remTitle()
fontSizeLead1.875remTitle({ variant: "serif" })
fontSizeBody1.375remBody text, lists, tables
fontSizeCode1.125remCode and terminal body text
fontSizeKicker1remKickers and window labels
stage.theme({
fontSizeTitle: "3.2rem",
fontSizeBody: "1.6rem",
});

Body text uses a line height of 1.5. Code and terminal text also use 1.5.

Add a custom font​

Install a font package so the build can bundle it for offline use:

pnpm add @fontsource/plus-jakarta-sans

Import the weights you use in your presentation entry file:

import "@fontsource/plus-jakarta-sans/400.css";
import "@fontsource/plus-jakarta-sans/700.css";

Assign the family. Include a fallback font:

stage.theme({
fontSans: '"Plus Jakarta Sans", sans-serif',
});

Use CSS overrides​

Add a className to an element and write a CSS rule:

const title = Title("Architecture", { className: "section-title" });
.section-title {
letter-spacing: -0.04em;
text-transform: uppercase;
color: var(--sr-secondary);
}

Import your stylesheet from the presentation entry file, for example import "./presentation.css".

Normal CSS rules outside a cascade layer override the library's normal layered rules. Inline options such as color and runtime geometry take precedence over normal stylesheet rules. Host-page CSS can also affect stage content.

Stage tokens are scoped to .sr-stage. Shared brand colors and font families are defined on :root. The stylesheet leaves host-page margins and scrolling to your application.

When building a custom component, define its defaults in a companion stylesheet inside @layer sr-components. Keep content and behavior in TypeScript. Reference theme tokens in CSS instead of copying preset colors into component code. Common mappings are:

Theme propertyCSS variable
primary--sr-primary
secondary--sr-secondary
textMuted--sr-text-muted
surface--sr-surface
surfaceBorderColor--sr-surface-border-color
fontSans--sr-font-sans

Use border: var(--sr-surface-border) for the combined border width, style, and color. CSS-only appearance changes are not saved as step state; use theme and element properties for changes that must restore on backward navigation. See the ThemeConfig API for all configurable properties.