Skip to main content

Theme config

Theme mode

Color palette

Grays

Border radii/radiuses/radiopedes/you know
Border radius
Field border radius
Button border radius
All
Components
Guides
API
Recent

Guide

Getting started

OPUI ships first-class Astro components. Install the package, import what you need, and you're set.

Install via NPM

Install the package to get access to the components.

Terminal window
pnpm add opui -S
Terminal window
npm install opui -S

Use a component

Components can be imported from @opui/astro:

---
import { Button } from "@opui/astro"
---
<Button variant="filled">Click me</Button>

Load the CSS

Astro components ship markup only — the CSS still has to be loaded once per app. Import the pre-bundled theme from your global stylesheet (or a shared layout):

@import "opui/css/imports.css";

Or pick and choose pieces if you want a lighter footprint:

@import "opui/core/normalize.css";
@import "opui/core/utils.css";
@import "opui/css/theme.css";
@import "opui/css/components.css";

Theming

Once installed, here's how the theming system fits together: a single palette source feeds intent tokens, which components read from. The focus ring, control sizes, and shadows are separate scales you can tune independently.

Palette source

The 16-step --color-N ramp is generated from a single OKLCH input: --palette-source. Setting it on :where(html) (or any ancestor) regenerates the entire palette in place.

:where(html) {
--palette-source: oklch(0.58 0.18 264);
--palette-hue-rotate-by: 0;
}
  • Must be oklch(). Hex, rgb(), and named colors won't work — the relative-color math reads the source's c and h channels directly.
  • Hue and chroma propagate; lightness is not used. The ramp keeps its own L curve, so the literal source color won't necessarily appear at any step.
  • --palette-hue-rotate-by is a separate knob for per-step warm/cool drift, in degrees.

To re-source the palette in a sub-tree (e.g. for status colors), override --palette-source on a scoped selector:

:where(.warning) {
--palette-source: oklch(0.58 0.21 var(--hue-orange));
}