Getting started Overview
Docs · Integration

Vanilla / HTML integration

For plain HTML pages, prototypes, internal tools, or any project without a build pipeline. Two stylesheet imports, then use Caster class names. This is exactly how the USA Clean prototype consumes Caster.

1 · Get the files

Two options. Pick one.

Option A — Vendor into your project (recommended for production)

Copy the two files into your project. They're stable enough to vendor; updates are infrequent.

your-project/
├── css/
│   ├── caster-tokens.css      # copy of design-system/tokens/tokens.css
│   └── caster-components.css  # copy of design-system/components/components.css
└── index.html

Option B — Load from the deployed showcase (prototypes only)

Quick & dirty for sandboxes. Don't ship to real users this way — the showcase isn't a CDN, and it can't guarantee uptime.

<link rel="stylesheet" href="https://demo.thecxlabs.com/design-system/tokens/tokens.css?v=0.16.3">
<link rel="stylesheet" href="https://demo.thecxlabs.com/design-system/components/components.css?v=0.16.3">

2 · Import order matters

Caster uses Open Sans. Tokens reference the font family, so the font import has to come before tokens.

<!-- 1. Open Sans (Caster's only typeface) -->
<link rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700;800&display=swap">

<!-- 2. Caster tokens — defines all --caster-* CSS custom properties -->
<link rel="stylesheet" href="css/caster-tokens.css">

<!-- 3. Caster components — defines .btn, .pill, .product-card etc. -->
<link rel="stylesheet" href="css/caster-components.css">

<!-- 4. Your own CSS (overrides Caster as needed) -->
<link rel="stylesheet" href="css/site.css">

3 · Use the components

Reference the showcase pages for full markup. Quick examples:

Button

<button class="btn btn-primary">Add to cart</button>
<button class="btn btn-brand">Save changes</button>
<button class="btn btn-outline">Cancel</button>

Pill

OEM In stock · 47 units ↺ Subscribe & Save 10%
<span class="pill pill-brand">OEM</span>
<span class="pill pill-success">In stock · 47 units</span>
<span class="pill pill-accent">↺ Subscribe & Save 10%</span>

4 · Theming via CSS variables

Caster components read --caster-* custom properties. Override at any scope to retheme — globally on :root, or scoped to a specific element.

Global override

<!-- In your site.css, after caster-components.css -->
<style>
  :root {
    /* Make all brand-colored buttons green instead of blue */
    --caster-color-brand-default: #1a8a3f;
    --caster-color-brand-hover:   #0d6f2a;
  }
</style>

Scoped override

Useful for "this section uses a different palette" — promo zones, holiday banners, white-label pages.

<section style="--caster-color-brand-default: #1a8a3f;
                --caster-color-brand-hover: #0d6f2a;">
  <!-- Caster components inside this section see the green brand color -->
  <button class="btn btn-brand">Now green</button>
</section>

5 · Using tokens in your own CSS

If you're writing custom components alongside Caster, reference the same token system to stay consistent.

<!-- In your site.css -->
<style>
.my-promo-banner {
  background: var(--caster-color-brand-deep);
  color:      var(--caster-color-text-inverted);
  padding:    var(--caster-spacing-4) var(--caster-spacing-6);
  border-radius: var(--caster-radius-card);
  font-family: var(--caster-font-family-sans);
  font-weight: var(--caster-font-weight-semibold);
  font-size:   var(--caster-font-size-sm);
}
</style>
Always reference semantic tokens, not primitives. Use --caster-color-brand-default, not --caster-color-blue-700. The semantic layer is the contract — primitives can shift between versions.

6 · Responsive considerations

Caster components are mobile-first by default. Three breakpoints:

RangeTokenMin width
Mobile / Small--caster-breakpoint-small0 (default)
Tablet / Medium--caster-breakpoint-medium768px
Desktop / Large--caster-breakpoint-large1200px

CSS variables can't drive media queries directly, so write breakpoints with literal values matched to the tokens:

<style>
.my-grid {
  display: grid;
  grid-template-columns: 1fr;       /* mobile default */
}
@media (min-width: 768px) {
  .my-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1200px) {
  .my-grid { grid-template-columns: repeat(4, 1fr); }
}
</style>

Common pitfalls

"My buttons look unstyled"

Both stylesheets need to load. Open DevTools → Network and confirm both tokens.css and components.css are 200 OK. Then check the order — tokens must come before components, since components reference token variables.

"My font looks wrong"

Open Sans must load. Add the Google Fonts link before the Caster stylesheets. Check DevTools → Network for the font request.

"My existing classes are conflicting with Caster"

Caster uses common class names (.btn, .pill, .product-card). If your project defines these elsewhere, the later import wins. Either rename your existing classes or load Caster first and let your CSS override specifically.

"I changed a primitive but components didn't update"

Source files (tokens/*.json) are inputs. Run npm run build in design-system/build/ to regenerate tokens.css. Or override the semantic token directly in your own CSS and skip the rebuild.