Beamline

Guide · By Danylo Pravda · Updated

Theme a React app from one brand colour

Theming usually means a long list of variables: a primary colour, its hover, its pressed state, a focus ring, a text colour that stays readable on it, chart colours that match. Miss one and a button turns unreadable in light mode. Beamline derives all of them from one value, and keeps the rest of the look (type, corners, surfaces, motion) in a separate choice. This guide shows the three choices and what each one changes.

Choice one: the brand colour

import { UIRoot } from "@beamline/runtime";
import { prism } from "@beamline/look-prism";

<UIRoot preset={prism} theme="dark" brand="oklch(0.7 0.15 150)">
  {children}
</UIRoot>

From that one colour come the accent, accent text, hover and pressed states, focus rings, selection tints, glows and the first chart series. Text on a brand fill (a main button, a selected day, a checked box) picks its own ink from the brand's lightness, so any brand keeps at least 4.5:1 contrast without a second colour. In plain CSS it is one custom property, --pui-brand.

Write it in OKLCH and keep the lightness between 0.55 and 0.75: then the brand also reads as text on both themes. Six ready accents swap only the brand (data-accent="neutral|violet|green|amber|orange|rose").

Choice two: light or dark

Dark is the default and the primary design target; theme="light" switches. Both themes define every token, so no component ever branches on the theme, and a region can switch on its own with a UIRoot inside another. Theme switch is a ready control for it.

Choice three: the look

Every part has a core (size, layout, states, keyboard, motion) and a look on top: the fonts, icon weight, corner radii, the page behind everything and the paint of every surface. Changing the look on the root restyles the whole app. There are nine:

look what it is
Prism (default) cut crystal in a dark room: parts drawn by their cut edges, the main action white light, colour only where attention is
Soft clean surfaces with a trace of your brand's hue, hairline rims, short shadows
Blueprint the drafting table for dense tools: cyan wireframes, square corners, mono labels
Glass a liquid lens: clear glass with bright rims over a faint grid
Metal black anodised metal with diamond-cut edges, wide headings, monospaced figures
Glow a calm night with light in one place: spectral light under the main buttons
Pop a sticker sheet: a warm page, ink outlines, a hard lip under every control
Mono monochrome: your brand colour appears only in the data it leads
Ink a pen-and-ink drawing in two inks

A look never changes the size scale (control heights, spacing), so switching it never reflows a layout beyond text following its fonts. You can set one for the app, one region, or a single part:

import { glass } from "@beamline/look-glass";

<UIRoot preset={glass} theme="light">…</UIRoot>         // a region, its menus and dialogs included
<Button variant="accent" look="glow">Upgrade</Button>  // one button

Every look is live in the component library: switch it there and every part on the page follows.

Smaller changes

For the rest, change a token or a default instead of a component:

<UIRoot
  tokens={{ "--pui-radius-control": "12px" }}
  defaults={{ button: { size: "sm" }, table: { density: "compact" } }}
>
  {children}
</UIRoot>
  • Tokens cover corner radii, surfaces, the three ink levels, chart series, motion timing and type faces; the customise docs list them. Trading direction colours (--pui-up, --pui-down) are separate from success and danger, so a market where red means up can swap them.
  • Defaults set a component's design props for a whole region (a smaller button, a compact table); a prop on one part still wins.
  • Your own parts can wear the same paint with the look's role classes (m-control, m-surface, m-field and the rest), so a custom widget matches whichever look is on.

What stays out of the theme

Nothing in a theme changes behaviour: keyboard models, focus order, data handling and motion rules belong to the core, and reduced motion is honoured in every look. Changing the brand or the look is safe to do late, even the day before a launch.

Ask your agent for it

With Beamline connected (setup for your agent): "use our brand colour #2F66D6 and the Soft look, light theme". The agent sets the brand and look on the root once and leaves every component alone. The full set of options is in Customise and the design language.