Theming

Understand the shared palette, typography, motion, and CSS variables installed by the Afterglow theme.

Phosphor preset

Foundations

--voidpage background
--panelsurfaces
--phosphortext and controls
--phosphor-brightemphasis and glow
--phosphor-dimmuted text and borders

Semantic roles

--signalactions and live states
--infoinformational states
--warningwarnings
--destructivedestructive states
--metricnumeric emphasis

Pigments

--amberwarm accent
--azurecool accent
--violetpurple accent
--emberred accent

Chart series

--chart-1series 1
--chart-2series 2
--chart-3series 3
--chart-4series 4
--chart-5series 5

Install the theme

Every Afterglow component declares @afterglow/theme as a registry dependency. Installing a component through the namespace normally adds the theme for you.

You can also install it directly:

npx shadcn@latest add @afterglow/theme

The shadcn CLI merges its variables, keyframes, and Tailwind theme entries into the CSS file configured in components.json.

What the theme controls

The theme supplies:

  • the phosphor, signal, panel, status, and window palettes
  • monospace and sans-serif font stacks
  • square component radii
  • terminal tracking and small text sizes
  • stepped entrances, exits, carets, alarms, and scan effects
  • glow, panel, keyboard, slider, and window shadows

Stock shadcn components can use the same semantic variables after the theme is installed.

Use role tokens such as --info, --warning, --destructive, and --metric for interface meaning. Use --amber, --azure, --violet, and --ember when a fixed pigment is intentional. Charts have their own --chart-1 through --chart-5 series, so data colours do not inherit status semantics.

Phosphor presets

Set data-phosphor on the root element to change the screen colour:

<html data-phosphor="orange">

The theme includes green, orange, yellow, cyan, blue, magenta, red, and grey. Green is the default. Each preset remaps the phosphor ramp, panels, borders, focus rings, and semantic controls. A role may shift hue when the selected phosphor would make it difficult to distinguish, but its name and meaning stay the same.

Afterglow only reads the attribute. Use any state library to manage it. The documentation site uses next-themes to apply the attribute before paint and store the selection:

import { ThemeProvider } from "next-themes";

<ThemeProvider
  attribute="data-phosphor"
  defaultTheme="green"
  enableColorScheme={false}
  enableSystem={false}
  storageKey="afterglow-phosphor"
  themes={[
    "green",
    "orange",
    "yellow",
    "cyan",
    "blue",
    "magenta",
    "red",
    "grey",
  ]}
>
  {children}
</ThemeProvider>

With the Next.js App Router, add suppressHydrationWarning to <html> because the provider updates that element.

Typeset rendered content

The theme includes a typeset class for HTML or markdown output that does not carry component classes:

<article className="typeset">{content}</article>

It styles headings, paragraphs, lists, links, code, quotes, rules, and tables with the theme's existing font and colour tokens. Four inherited variables control the reading width and rhythm:

.release-notes {
  --typeset-size: 16px;
  --typeset-leading: 1.75;
  --typeset-flow: 1.25em;
  --typeset-measure: 70ch;
}

Use the Typeset builder to preview those values against a full specimen and copy the result.

Change a token

Edit the generated variables in your project's configured CSS file. Keep the semantic names used by components:

:root {
  --phosphor: #9dffe7;
  --signal: #ff6d94;
  --void: #030707;
}

Afterglow does not install font files. Change --font-mono or --font-sans if your project needs a bundled web font.

Dark by design

Afterglow uses the same terminal palette for the shadcn light and dark variable sets. Switching the application to a light theme will not produce a light Afterglow interface.

Create and maintain a separate light palette if the product requires one. Components should keep the same semantic token names so their styles continue to resolve.