CSS Contract

The single canonical CSS import for the Interlace DS, the cascade-layer model behind it, and the override surface for forking the brand. If you only read one page in this docs, read this.

TL;DR

One import gives you the entire DS contract:

@import "tailwindcss";
@import "@interlace/ui/styles/index.css";

That barrel resolves to six CSS files imported in cascade-correct order. Read on for the why.

The six layers

`index.css` declares the layer order up front, so the cascade is self-documenting:

@layer interlace.primitives, interlace.foundation, interlace.preflight,
       interlace.bridge, interlace.brand, interlace.semantics;

@import "./tokens.css";
@import "./foundation.css";
@import "./preflight.css";
@import "./theme.css";
@import "./interlace-theme.css";
LayerOwnsFile
interlace.primitivesKeyframes, motion timings, animation utility classestokens.css
interlace.foundationType scale, spacing scale, radius, container widths, font families (Tailwind @theme tokens)foundation.css
interlace.preflightbody bg/fg/font, focus ring (WCAG 2.2 SC 2.4.13), scrollbar tint, placeholder contrast, min-viewport contractpreflight.css
interlace.bridgefumadocs ↔ shadcn token bridge (--background: var(--color-fd-background))theme.css
interlace.brandConcrete brand hex literals (--interlace-primary, --interlace-background, …) for light + darkinterlace-theme.css
interlace.semanticsAlias bindings: --background → var(--interlace-background), etc. Plus Tailwind @theme inline registration.interlace-theme.css

Left-to-right in the layer declaration = ascending cascade priority (later wins). So interlace.semantics overrides interlace.brand, which overrides everything before it.

Fork the brand

The supported override surface is @layer interlace.brand. Declare it AFTER importing index.css and your hex values deterministically win — regardless of declaration order or specificity. Without cascade layers, brand override is source-order roulette.

/* consumer's global.css */
@import "tailwindcss";
@import "@interlace/ui/styles/index.css";

@layer interlace.brand {
  :root {
    --interlace-primary: oklch(0.55 0.22 264);
    --interlace-primary-hover: oklch(0.50 0.22 264);
    --interlace-background: #ffffff;
    /* ... */
  }
  .dark {
    --interlace-primary: oklch(0.78 0.18 264);
    --interlace-background: #0a0a0f;
    /* ... */
  }
}

Walk every brand token → theme authoring guide. Browse the resolved semantic-token table → semantics catalogue.

What NOT to override

Layers other than interlace.brand are internal and may change without notice:

  • interlace.preflight — overriding this loses the WCAG 2.2 SC 2.4.13 focus ring, scrollbar tint, and [data-min-viewport] dev-mode outline contract.
  • interlace.bridge — fumadocs ↔ shadcn token bridge. Touching it breaks cross-framework primitive resolution.
  • interlace.primitives + interlace.foundation — keyframes, motion timings, type scale, spacing scale. These are structural; the brand layer is the authoring seam.

References