Lorre Blocks
GitHub

Theming

A theme is data: five color seeds plus radius, shadow, motion and typography values. Everything else — 12-step OKLCH scales, semantic aliases, dark mode — is generated.

basic
The root theme: blue accent, balanced radii and shadows, 200ms motion. Every other theme extends it.
dreamy
Violet accent, large radii, plush shadows, slower motion. For expressive marketing and creative work.
utilitarian
Monochrome accent, sharp radii, minimal shadows, fast motion. For dense professional dashboards.

How it works

  • Each color axis (neutral, accent, danger, success, warning) grows from one seed into a Radix-style 12-step OKLCH scale — light and dark.
  • Components only reference semantic tokens (bg-primary, text-muted-foreground, ring-ring), which map onto scale steps. That indirection is what makes themes swappable.
  • Tokens ship as Tailwind v4 CSS for your app and as W3C DTCG JSON (/r/tokens/<name>.json) for design tooling and agents.
  • Try it now: the palette icon in this site's header applies a theme the same way the CLI does — swap tokens, touch no components.

Commands

npx lorre-blocks theme list
npx lorre-blocks theme apply utilitarian

theme apply replaces the token block between the lorre-blocks theme markers in your global CSS, in place. The active theme is recorded in components.json.

Custom themes

Presets are the starting point, not the ceiling. A custom theme is a lorre.theme.json file — the contract shared by the Theme Studio, the CLI, and agents. It extends a preset and overrides only what you care about:

{
  "name": "acme",
  "description": "Acme brand theme",
  "extends": "basic",
  "colors": {
    "accent":    { "hue": 293, "chroma": 0.25, "lightness": 0.54 },
    "secondary": { "hue": 70,  "chroma": 0.16, "lightness": 0.77 }
  },
  "typography": {
    "fontSans": ["Geist", "ui-sans-serif", "system-ui", "sans-serif"],
    "typeScale": { "base": "1rem", "ratio": 1.2 }
  },
  "radius": { "base": "1rem", "sm": "0.5rem", "md": "0.75rem",
              "lg": "1rem", "xl": "1.5rem", "2xl": "2rem" },
  "spacing": { "scaling": 1.05 },
  "components": { "button": { "radius": "9999px" } },
  "icons": { "set": "phosphor", "style": "duotone" }
}
  • colors.* — OKLCH seeds (hue 0–360, chroma, lightness); each grows into the full 12-step scale, light and dark. secondary is an optional sixth scale; when present, the bg-secondary semantics point at it automatically.
  • typography.typeScale — modular headings; emitted as fluid clamp() tokens, so text-h1text-h6 are responsive with zero media queries.
  • spacing.scaling — 0.9–1.1 density factor; every spacing utility follows.
  • components.* — per-component knobs (button, input, card, panel, badge, tabs, control, tooltip): radius, padding, size.
  • icons — the set your app uses; see Icons.

Two front doors, one engine

Humans tailor visually in the Theme Studio and copy the CSS or the JSON. Agents write the JSON directly and run one command — the same engine generates the CSS locally, so both paths produce byte-identical output:

npx lorre-blocks theme create --from lorre.theme.json
npx lorre-blocks theme create --accent "#7C3AED" --radius xl --scaling 105
npx lorre-blocks theme show --json

Edit lorre.theme.json later and re-run theme apply (no argument) to regenerate. theme show prints the resolved design system — scales, semantics, type scale, component tokens — so nothing has to parse CSS.