# Core Framework Integration for Generating CSS Tokens in Instatic

> Discover how Instatic's Core Framework generates CSS tokens, transforming design system definitions into CSS custom properties and utility classes via a multi-stage pipeline.

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

---

**Instatic's Core Framework module centralizes design-system definitions and transforms them into CSS custom properties and utility classes through a validated, multi-stage pipeline.**

The Core Framework integration is the engine behind Instatic's token-driven CSS generation. It bridges the visual editor's design panels with the static publishing pipeline, ensuring every site emits consistent, namespaced CSS tokens that can be safely overridden by user styles.

This article walks through the complete workflow—from framework settings in the admin UI to the final [`framework.css`](https://github.com/CoreBunch/Instatic/blob/main/framework.css) bundle—using actual source paths and function signatures from the CoreBunch/Instatic repository.

## How Framework Settings Become CSS Tokens

The pipeline begins when site owners configure design tokens through the admin interface. These settings flow through validation, planning, and rendering stages before reaching the published page.

### Step 1: Framework Settings Validation

Site configurations are stored in `site.settings.framework` and validated against `FrameworkSettingsSchema` in [`src/core/framework-schema/schemas.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/framework-schema/schemas.ts). This TypeBox schema enforces type safety for colors, typography, spacing scales, and other design primitives.

Admin panels for **Colors**, **Typography**, and **Spacing** write to this validated structure. Invalid or incomplete settings fail fast at the schema level, preventing downstream errors in CSS generation.

### Step 2: Building the Framework Plan

The `buildFrameworkPlan` function in [`src/core/framework/index.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/framework/index.ts) transforms validated settings into an executable plan. This plan contains:

- **Root custom-property definitions** for color, font-family, and spacing tokens
- **Generated utility classes** for each scale step (e.g., `.font-size-lg`, `.gap-2`)

The plan acts as an intermediate representation—decoupled from both the admin UI and the final CSS output. This separation allows the publisher to optimize without affecting the authoring experience.

### Step 3: CSS Generation and Bundling

The publisher consumes the framework plan in [`src/core/publisher/frameworkCss.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/publisher/frameworkCss.ts). Two key functions orchestrate this stage:

| Function | Location | Purpose |
|----------|----------|---------|
| `buildSiteFrameworkCss(site)` | [`src/core/publisher/frameworkCss.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/publisher/frameworkCss.ts) | Orchestrates the full generation workflow |
| `generateFrameworkCss(site)` | [`src/core/publisher/frameworkCss.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/publisher/frameworkCss.ts) | Renders the final [`framework.css`](https://github.com/CoreBunch/Instatic/blob/main/framework.css) bundle |

The generated CSS includes:

```css
/* Example output: root custom properties */
:root {
  --color-primary: #007bff;
  --font-primary: 'Inter', sans-serif;
  --space-4: 1rem;
}

/* Example output: utility classes */
.font-size-lg { font-size: var(--font-size-lg); }
.gap-2 { gap: var(--space-2); }

```

### Step 4: Token Emission and Cascade Order

In [`src/core/publisher/render.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/publisher/render.ts), the final page CSS is assembled by concatenating four bundles in strict order:

1. `reset` — browser normalization
2. `framework` — the generated design tokens
3. `style` — component-level styles
4. `userStyles` — custom user CSS

This ordering guarantees framework tokens appear **before** user-defined CSS, enabling predictable overrides without specificity battles.

## Token Scale Generation Internals

The framework doesn't hand-write every token. Shared engines in `src/core/framework/` compute systematic scales.

### Spacing and Typography Scales

- [`src/core/framework/spacing.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/framework/spacing.ts) — implements spacing scale math and token generation
- [`src/core/framework/typography.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/framework/typography.ts) — implements typography scale and token generation

Both modules leverage [`src/core/framework/scaleModule.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/framework/scaleModule.ts), the shared engine that creates the token-to-utility-class mapping. This abstraction ensures consistent naming conventions and calculation logic across different token categories.

## Runtime Token Consumption

Framework tokens aren't just for published output. The admin UI itself consumes them through design-token primitives.

### UI Primitive: `pillAccent`

Located at [`src/ui/pillAccent.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/ui/pillAccent.ts), this primitive selects deterministic accent tokens from the framework palette:

```typescript
import { pillAccent } from '@/ui/pillAccent';

const accent = pillAccent('primary'); // → '--pill-primary' custom property

```

Components like pills, badges, and buttons use these primitives to maintain visual consistency with the site's configured theme without hardcoding values.

## Import and Conflict Resolution

When external CSS is imported, the framework handles token extraction and merging through `src/core/siteImport/*`.

### Token Extraction Pipeline

| Module | Function |
|--------|----------|
| [`src/core/siteImport/colorTokens.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/siteImport/colorTokens.ts) | Extracts `:root` color properties, rewrites as framework tokens |
| [`src/core/siteImport/fontTokens.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/siteImport/fontTokens.ts) | Extracts font-family declarations, registers as framework tokens |
| [`src/core/siteImport/conflicts.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/siteImport/conflicts.ts) | Detects and resolves token name collisions |

Imported custom properties are namespace-migrated into the framework registry, preserving their values while ensuring they follow Instatic's token conventions.

## Complete Workflow Example

Here's the full chain from settings to published CSS:

```typescript
// 1️⃣ Resolve framework preferences (with sensible defaults)
import { resolveFrameworkPreferences } from '@core/framework';

const prefs = resolveFrameworkPreferences(site.settings.framework?.preferences);

// 2️⃣ Build the framework plan (scales, colors, utilities)
import { buildFrameworkPlan } from '@core/framework';

const { rootCss, utilityClasses } = buildFrameworkPlan(site.settings.framework);

// 3️⃣ Generate the final CSS bundle for publishing
import { generateFrameworkCss } from '@core/publisher';

const frameworkCss = generateFrameworkCss(site);

// 4️⃣ Use a token in a component (e.g., a Pill)
import { pillAccent } from '@/ui/pillAccent';

const accent = pillAccent('primary'); // → '--pill-primary' custom property

```

Each stage is pure and testable: preferences resolve against defaults, plans build deterministically from settings, and CSS generates without side effects.

## Key Architectural Guarantees

The Core Framework integration provides three invariant properties:

- **Namespace safety** — all tokens use the `--` prefix, preventing collisions with third-party CSS
- **Tree-shaking** — only utility classes actually referenced by site content appear in [`framework.css`](https://github.com/CoreBunch/Instatic/blob/main/framework.css)
- **Zero runtime** — the published [`framework.css`](https://github.com/CoreBunch/Instatic/blob/main/framework.css) contains no editor code or JavaScript dependencies, ensuring fully static output

## Summary

- The Core Framework validates settings through `FrameworkSettingsSchema` in [`src/core/framework-schema/schemas.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/framework-schema/schemas.ts)
- `buildFrameworkPlan` in [`src/core/framework/index.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/framework/index.ts) creates an intermediate plan of tokens and utilities
- `generateFrameworkCss` in [`src/core/publisher/frameworkCss.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/publisher/frameworkCss.ts) renders the final CSS bundle
- [`src/core/publisher/render.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/publisher/render.ts) concatenates bundles with framework tokens first in the cascade
- Scale generation is shared through [`src/core/framework/scaleModule.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/framework/scaleModule.ts) for consistent spacing and typography
- Imported CSS tokens are extracted and merged via [`src/core/siteImport/colorTokens.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/siteImport/colorTokens.ts) and [`src/core/siteImport/fontTokens.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/siteImport/fontTokens.ts)
- UI primitives like [`src/ui/pillAccent.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/ui/pillAccent.ts) consume tokens at both edit-time and publish-time

## Frequently Asked Questions

### What file generates the actual framework.css output?

The `generateFrameworkCss` function in [`src/core/publisher/frameworkCss.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/publisher/frameworkCss.ts) renders the final bundle. It consumes the framework plan built by `buildFrameworkPlan` and outputs CSS containing root custom properties and utility classes.

### How does Instatic handle conflicts between imported CSS tokens and existing framework tokens?

Conflicts are detected and resolved in [`src/core/siteImport/conflicts.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/siteImport/conflicts.ts). The pipeline extracts `:root` custom properties from imported CSS via [`src/core/siteImport/colorTokens.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/siteImport/colorTokens.ts) and [`src/core/siteImport/fontTokens.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/siteImport/fontTokens.ts), rewrites them as framework tokens, and merges them with the existing registry according to conflict resolution rules.

### Can users override framework tokens in their custom CSS?

Yes. The render pipeline in [`src/core/publisher/render.ts`](https://github.com/CoreBunch/Instatic/blob/main/src/core/publisher/render.ts) concatenates bundles with `framework` preceding `userStyles`. This cascade order allows user-defined CSS to override any framework token using standard CSS custom property semantics.

### What ensures that only used utility classes are included in the output?

The framework plan tracks which utility classes are referenced by site content. The publisher performs tree-shaking during `generateFrameworkCss`, emitting only classes that appear in the site's component graph—keeping [`framework.css`](https://github.com/CoreBunch/Instatic/blob/main/framework.css) lean for performance.