The whole kit, one link tag
The component library is built entirely on CSS variables, so a theme is just one more block of declarations — which means we can generate a stylesheet that already wears your brand and serve it from a URL. No npm, no bundler, no build step. Paste one tag into plain HTML, WordPress, Rails, Django, Laravel or anything else that serves a page.
<link rel="stylesheet" href="https://developer.lacspace.com/css/v1">Anywhere that can serve a page
Components are plain markup: a class and a few data-* attributes. That is the whole API when you use it this way — no JavaScript is loaded or required.
<link rel="stylesheet" href="https://developer.lacspace.com/css/v1?accent=%2300b894&radius=12">
<button class="lac lac-btn" data-variant="solid">Save changes</button>
<span class="lac lac-badge" data-tone="success" data-variant="soft">Live</span>add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_style(
'lacspace',
'https://developer.lacspace.com/css/v1?accent=%237c3aed&radius=14&dark=class',
[],
null
);
} );<%= stylesheet_link_tag "https://developer.lacspace.com/css/v1?accent=%23ec4899&only=form,overlay",
media: "all", "data-turbo-track": "reload" %>// app/layout.tsx — no install needed for the styles
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<link rel="stylesheet" href="https://developer.lacspace.com/css/v1?dark=class" />
</head>
<body>{children}</body>
</html>
);
}Every knob, and what it does
Anything unrecognised is ignored and falls back to the default — a malformed value can never end up inside the stylesheet.
| Parameter | Values | What it does |
|---|---|---|
| accent | #hex | Brand colour. Hover, active, soft, ring and the label colour on top are derived from it — the label flips to dark or light by luminance so it stays readable. |
| radius | 0–40 | Corner radius in px. The small, large and extra-large steps scale with it. |
| control | 24–72 | Height of a medium control in px. Small and large scale with it. |
| font | system · inter · manrope · space-grotesk · dm-sans · sora · serif · mono | Typeface stack. An allowlist, never your own text. |
| webfont | 1 | With a Google font, also emit the @import so you don't need a second tag. |
| dark | media · class · attr · off | How your app switches to dark. `class` rewrites the kit's theme blocks to a `.dark` class; `off` drops the dark palette entirely and halves the file. |
| darkClass | a class name | Use with dark=class when your class isn't `dark`. |
| only | overlay,navigation,display,form,layout | Include only these families. Tokens, buttons, inputs and cards are always in. |
| packs | components,charts,table,date | Add the chart, data-table or date-picker stylesheets. |
| pretty | 1 | Skip minifying, for reading it. |
What you can rely on
v1 will not break your page
The v1 in the path pins the major version of the kit. The bytes behind a given query string can gain fixes, but nothing that already works will stop working. A breaking change would arrive as v2, at its own URL.
Cached, and cheap to re-fetch
Every response carries an ETag and long edge-cache headers, so repeat visits answer 304 with no body. The response depends only on the query string, so two sites asking for the same theme share the same cached object.
Nothing you send reaches the CSS
Colours are parsed as hex, sizes as bounded integers, fonts and modes matched against an allowlist. Every declaration is re-emitted from our own literals, so a stylesheet served from this domain can never be made to carry someone else’s rules.
Or install it properly
If you already have a build step, npm i @lacspace/components gives you the React components, the types and the same stylesheet locally. The CDN exists for everywhere that doesn’t. See all 143 components →