> For the complete documentation index, see [llms.txt](https://beamline.gitbook.io/beamline-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://beamline.gitbook.io/beamline-docs/guides/build-your-own-react-ui-style-with-beamline.md).

# Build your own React UI style with Beamline

Build your own Beamline style from any look: local files, your fonts, public tokens, radii, density, motion and per-part CSS, by hand or with your agent.

> The original of this page is on beamline.io: [beamline.io/guides/theme-react-components-brand-colour](https://beamline.io/guides/theme-react-components-brand-colour).

By Danylo Pravda, 2026-10-11

**Build your own style from any look.** One brand colour is a quick start; public tokens let you change fonts, corner radii, roundness, spacing density, motion, and every surface, text and chart colour. Your editable style files live in `src/styles/beamline`, which source and package upgrades leave alone. Beamline's component code also lives in your repo, and your app never depends on Beamline servers at runtime.

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.

## Build your own style

Use the local studio when your bundle includes it, or ask your agent to use the local `style` CLI: `create` starts from a look, `set` changes a public token the look declares, `parameter` changes settings such as radius and motion scale, `export` writes the preset CSS, and `add` puts the style in your app. Install your chosen fonts explicitly. The [customise guide](https://beamline.io/docs/customize#custom-styles-by-hand-or-with-an-agent) gives the commands and file contract.

For individual parts, use `className`, `data-slot` and `data-state`; component CSS sits in `@layer components`, below normal unlayered app CSS. The normal cascade still applies. Your own components can use the same role classes, including `m-control`, `m-field` and `m-surface`. With [editable source](https://beamline.io/docs/install), change a component directly. You own your end products and changes under the [licence](https://beamline.io/docs/licence); the paid packs remain licensed code.

## Choice one: the brand colour

```tsx
import type { ReactNode } from "react";
import { UIRoot } from "@beamline/runtime";
import { prism } from "@beamline/look-prism";
export function Example({ children }: { children: ReactNode }) {
  return (
    <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 light is just as complete, in every look; `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](https://beamline.io/components/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           | iOS 27 Liquid Glass: controls and menus bend what is behind their rims, lit edges, capsule controls                     |
| 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:

Install both looks first so the generated stylesheet includes their CSS. A component inherits the look of its nearest root:

```tsx
import { UIRoot } from "@beamline/runtime";
import { Button } from "@beamline/button";
import { glass } from "@beamline/look-glass";
import { glow } from "@beamline/look-glow";

export function Looks() {
  return (
    <UIRoot preset={glass} theme="light">
      <p>A region, including its menus and dialogs.</p>
      <UIRoot preset={glow}>
        <Button variant="accent">Upgrade</Button>
      </UIRoot>
    </UIRoot>
  );
}
```

Every look is live in the [component library](https://beamline.io/components/foundations/looks): 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:

```tsx
import type { ReactNode } from "react";
import { UIRoot } from "@beamline/runtime";

export function Example({ children }: { children: ReactNode }) {
  return (
    <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](https://beamline.io/docs/customize) 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

For your own design system, ask: "Start from our chosen look and build our style with our fonts, radii, density, motion and surface, text and chart tokens. Save the editable files in src/styles/beamline, apply them to our root, and use per-part CSS or source edits where needed. Keep our data and handlers." The [customise guide](https://beamline.io/docs/customize) is the supported contract for that work.

With Beamline connected ([setup for your agent](https://beamline.io/connect)): "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](https://beamline.io/docs/customize) and the [design language](https://beamline.io/docs/design-language).
