# Understanding Instatic's Design Token System: A CSS-First Architecture

> Explore Instatic's CSS-first design token system. Discover how CSS custom properties centralize visual values in globals.css for consistent styling and prevent hardcoded values with lint tests.

- Repository: [CoreBunch/Instatic](https://github.com/CoreBunch/Instatic)
- Tags: deep-dive
- Published: 2026-08-01

---

**Instatic implements a CSS-custom-property-based design token system where all visual values are centralized in [`src/styles/globals.css`](https://github.com/CoreBunch/Instatic/blob/main/src/styles/globals.css) and consumed via `var(--*)` references, enforced by automated lint tests to prevent hardcoded values.**

Instatic's design token system provides a single source of truth for the visual language of the admin UI, canvas editor, and public primitives. By declaring every color, radius, shadow, font, and spacing value as a CSS variable in one central file, the system guarantees consistency across React components while enabling runtime theming without touching component code.

## Core Architecture: CSS Variables in globals.css

The foundation of Instatic's design token system resides in [`src/styles/globals.css`](https://github.com/CoreBunch/Instatic/blob/main/src/styles/globals.css), which serves as the central catalogue for all visual styling decisions. This file declares CSS custom properties for every design primitive used throughout the application, from `--bg-surface-2` and `--text-subtle` to `--card-radius` and `--space-3xl`.

According to the Instatic source code, the token catalogue covers:

- **Colors** – background surfaces, text variants, and brand colors
- **Radii** – card and button border-radius values
- **Shadows** – elevation levels for UI components
- **Typography** – font families, sizes, weights, and line heights
- **Spacing** – margin and padding scale tokens
- **Z-Indices** – layering values for modals, tooltips, and overlays

Components reference these tokens using standard CSS `var()` notation. For example, in [`src/ui/components/Widget/Widget.module.css`](https://github.com/CoreBunch/Instatic/blob/main/src/ui/components/Widget/Widget.module.css):

```css
.widget {
  background: var(--bg-surface-2);
  border-radius: var(--card-radius);
  padding: var(--space-3xl) var(--space-3xl) var(--space-2xl);
  color: var(--text-subtle);
}

```

## Token Consumption and Lint Enforcement

Instatic enforces strict token compliance through automated lint tests that prevent hardcoded values from entering the codebase. The system rejects any CSS containing raw hex codes, rgb values, or inline styles that bypass the token system.

Three specific policy tests guard the codebase:

- **[`css-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/css-token-policy.test.ts)** – Validates that all color and spacing references use CSS variables
- **[`admin-typography-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/admin-typography-token-policy.test.ts)** – Ensures font sizes and families derive from token references
- **[`admin-spacing-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/admin-spacing-token-policy.test.ts)** – Confirms margin and padding values use the spacing scale

This enforcement guarantees that [`globals.css`](https://github.com/CoreBunch/Instatic/blob/main/globals.css) remains the single source of truth. When developers need to style a new component, they must reference existing tokens via `var(--token-name)` rather than inventing one-off values.

## Framework-Level Token Schema

Beyond the raw CSS variables, Instatic maintains a **structured token schema** in `src/core/framework/` that mirrors the CSS definitions using TypeBox. This structured representation powers the "Framework" panel in the editor, enabling bulk token editing and programmatic access.

The framework schema serves multiple purposes:

- **Bulk Editing** – Modify multiple tokens simultaneously through the UI
- **Import/Export** – Serialize token sets to JSON for sharing between projects
- **Site-Shell Management** – Control the visual framework for hosted sites
- **Plugin API** – Expose tokens to third-party extensions in a predictable format

This dual-layer architecture—CSS variables for runtime rendering and a TypeBox schema for editor manipulation—ensures that visual changes made in the Framework panel immediately reflect in the rendered output.

## Cross-Context Token Propagation

When the canvas editor loads a page inside an isolated iframe, Instatic must ensure that tokens remain available without leaking into the customer's site styles. The `EditorChromeInjector` solves this by copying required safe tokens onto the iframe's `:root` element.

To prevent collisions with site-specific framework tokens, Instatic uses namespacing:

- **Chrome Tokens** – Prefixed with `--chrome-*` (e.g., `--chrome-font-sans`, `--chrome-text-subtle`)
- **Site Tokens** – Use the standard `--*` namespace for the actual site being edited

This isolation ensures that `var(--text-subtle)` resolves correctly within the iframe context while maintaining separation between the editor chrome and the site content.

## Extending the Token System

Adding a new design token requires three steps to maintain system integrity:

1. **Declare in globals.css**

Add the new variable to [`src/styles/globals.css`](https://github.com/CoreBunch/Instatic/blob/main/src/styles/globals.css):

```css
:root {
  --brand-primary: #0066ff;
  --brand-primary-hover: #0055dd;
}

```

2. **Update Documentation**

Register the token in [`docs/reference/design-tokens.md`](https://github.com/CoreBunch/Instatic/blob/main/docs/reference/design-tokens.md) with a description and usage guidelines.

3. **Consume in Components**

Reference the new token in component CSS modules:

```css
.button-primary {
  background: var(--brand-primary);
}
.button-primary:hover {
  background: var(--brand-primary-hover);
}

```

After committing changes, the lint suite automatically verifies that the token follows naming conventions and is properly referenced rather than hardcoded.

## Accessing Tokens Programmatically

For dynamic theming or runtime analytics, tokens can be read via the CSSOM:

```tsx
import { useEffect } from 'react';

export const useBrandPrimary = () => {
  useEffect(() => {
    const root = document.documentElement;
    const brand = getComputedStyle(root)
      .getPropertyValue('--brand-primary')
      .trim();
    console.log('Current brand primary:', brand);
  }, []);
};

```

This approach reads computed values directly from the document root, ensuring React hooks and JavaScript logic stay synchronized with the CSS-defined visual system.

## Summary

- **Centralized Source**: All design tokens live in [`src/styles/globals.css`](https://github.com/CoreBunch/Instatic/blob/main/src/styles/globals.css) as CSS custom properties
- **Enforced Consumption**: Lint tests ([`css-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/css-token-policy.test.ts), [`admin-typography-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/admin-typography-token-policy.test.ts), [`admin-spacing-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/admin-spacing-token-policy.test.ts)) prevent hardcoded values in components
- **Dual Architecture**: Raw CSS variables power the UI while a TypeBox schema in `src/core/framework/` enables editor integration and API access
- **Iframe Isolation**: The `EditorChromeInjector` propagates namespaced tokens (`--chrome-*`) into editor iframes without style collisions
- **Extensibility**: New tokens require editing [`globals.css`](https://github.com/CoreBunch/Instatic/blob/main/globals.css), updating [`docs/reference/design-tokens.md`](https://github.com/CoreBunch/Instatic/blob/main/docs/reference/design-tokens.md), and consuming via `var(--*)`

## Frequently Asked Questions

### Where are Instatic's design tokens defined?

All design tokens are defined as CSS custom properties in [`src/styles/globals.css`](https://github.com/CoreBunch/Instatic/blob/main/src/styles/globals.css). This single file serves as the source of truth for colors, spacing, typography, radii, shadows, and z-indices used throughout the admin UI and editor.

### How does Instatic prevent developers from using hardcoded color values?

The repository includes automated lint tests such as [`css-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/css-token-policy.test.ts), [`admin-typography-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/admin-typography-token-policy.test.ts), and [`admin-spacing-token-policy.test.ts`](https://github.com/CoreBunch/Instatic/blob/main/admin-spacing-token-policy.test.ts) that fail CI builds if components contain raw hex codes, rgb values, or inline styles. This forces all visual styling to reference tokens via `var(--*)`.

### What is the purpose of the framework token schema in `src/core/framework/`?

The framework directory contains a TypeBox-based schema that provides a structured representation of the CSS tokens. This schema powers the "Framework" panel in the editor for bulk token editing, enables JSON import/export functionality, and exposes tokens to the plugin API in a type-safe manner.

### How does Instatic handle design tokens in the canvas editor iframe?

The `EditorChromeInjector` copies necessary tokens onto the iframe's `:root` element using the `--chrome-*` namespace (e.g., `--chrome-font-sans`). This ensures that `var()` references resolve correctly inside the isolated iframe context while preventing namespace collisions with the site being edited.