Logo

Getting Started

Theme Tokens

Theme tokens are the CSS variables the components read. In Tailwind projects, define the Tailwind color tokens first, then map the FrameUI tokens to those values.

Use this page as a reference for how token-based styling is structured. Shared tokens define the base palette and surface system. Component pages list the component-specific tokens on top of that.

What this page is

This page lists the shared CSS variables that shape FrameUI. Change these first when the whole app should look different. Use component variables only when one primitive needs a local adjustment.

The most important shared values are primary color, background, text, surface, border, focus color, status colors, light/dark values, radius, density, and shadow.

Shared tokens

Shared tokens cover the values many components reuse. In the preferred Tailwind setup, --color-* owns the palette and --frame-* follows it.

App-level shared tokens

@theme {
  --color-background: oklch(0.99 0 0);
  --color-foreground: oklch(0.15 0 0);
  --color-surface: oklch(1 0 0);
  --color-surface-foreground: oklch(0.15 0 0);
  --color-surface-raised: oklch(0.985 0.002 247);
  --color-border: oklch(0.92 0 0);
  --color-border-strong: oklch(0.72 0 0);
  --color-primary: oklch(0.21 0 0);
  --color-primary-foreground: oklch(0.98 0 0);
  --color-destructive: oklch(0.58 0.2 25);
  --color-destructive-foreground: oklch(0.98 0 0);
  --color-success: oklch(0.62 0.18 149);
  --color-success-foreground: oklch(0.98 0 0);
  --color-warning: oklch(0.68 0.16 65);
  --color-warning-foreground: oklch(0.15 0 0);
  --color-info: oklch(0.58 0.19 255);
  --color-info-foreground: oklch(0.98 0 0);
  --color-muted: oklch(0.96 0 0);
  --color-muted-foreground: oklch(0.45 0 0);
  --color-accent: oklch(0.96 0 0);
  --color-accent-foreground: oklch(0.15 0 0);
  --color-ring: oklch(0.7 0 0);
  --shadow-frame-sm: none;
  --shadow-frame-md: 0 10px 15px -3px rgb(0 0 0 / 0.1);
  --shadow-frame-lg: 0 24px 80px rgb(0 0 0 / 0.18), 0 8px 24px rgb(0 0 0 / 0.12);
}

:root {
  --frame-background: var(--color-background);
  --frame-foreground: var(--color-foreground);
  --frame-surface: var(--color-surface);
  --frame-surface-foreground: var(--color-surface-foreground);
  --frame-surface-raised: var(--color-surface-raised);
  --frame-border: var(--color-border);
  --frame-border-strong: var(--color-border-strong);
  --frame-primary: var(--color-primary);
  --frame-primary-foreground: var(--color-primary-foreground);
  --frame-destructive: var(--color-destructive);
  --frame-destructive-foreground: var(--color-destructive-foreground);
  --frame-success: var(--color-success);
  --frame-success-foreground: var(--color-success-foreground);
  --frame-warning: var(--color-warning);
  --frame-warning-foreground: var(--color-warning-foreground);
  --frame-info: var(--color-info);
  --frame-info-foreground: var(--color-info-foreground);
  --frame-muted: var(--color-muted);
  --frame-muted-foreground: var(--color-muted-foreground);
  --frame-accent: var(--color-accent);
  --frame-accent-foreground: var(--color-accent-foreground);
  --frame-ring: var(--color-ring);
  --frame-shadow-sm: var(--shadow-frame-sm);
  --frame-shadow-md: var(--shadow-frame-md);
  --frame-shadow-lg: var(--shadow-frame-lg);
}

Component tokens

Component tokens refine a specific primitive. Use them when a component needs local spacing, typography, border, or state adjustments without changing the whole system.

Start with the shared values first: color, background, text, surface, border, focus, status colors, radius, density, and shadow. Component tokens are for precise overrides when one component or one section needs a different treatment. FrameUI defines component defaults with low specificity, so overrides can live on :root, html, a theme selector, or a local wrapper.

Component-specific override

.release-alert {
  --frame-alert-root-bg: color-mix(in srgb, var(--frame-primary) 8%, var(--frame-surface));
  --frame-alert-root-border: color-mix(in srgb, var(--frame-primary) 20%, var(--frame-border));
  --frame-alert-root-icon-size: 1.125rem;
  --frame-alert-title-font-size: 1rem;
}

Radius

FrameUI starts with square corners. --frame-radius-sm, --frame-radius-md, and --frame-radius-lg are 0px by default so components keep the technical look. --frame-radius-full stays available for circles and pill-shaped elements.

If an app needs softer corners, change the shared radius values once. Components that expose radius tokens read from these shared values unless a local override says otherwise.

Radius values

:root {
  /* FrameUI default: technical, square surfaces */
  --frame-radius-sm: 0px;
  --frame-radius-md: 0px;
  --frame-radius-lg: 0px;
  --frame-radius-full: 9999px;
}

/* Example: softer app theme */
:root {
  --frame-radius-sm: 0.25rem;
  --frame-radius-md: 0.5rem;
  --frame-radius-lg: 0.75rem;
}

Density

Density changes how compact controls, menus, panels, and tables feel without changing color or shape. Set density: 'compact' in provideFrameUI for tighter screens, or density: 'comfortable' when controls need more room.

For most apps, switch the density attribute first. Override individual --frame-density-* values only when the presets are close but not quite right.

App density

import { provideFrameUI } from '@frame-ui-ng/foundation';

export const appConfig = {
  providers: [
    provideFrameUI({
      density: 'compact',
    }),
  ],
};

Density values

:root {
  --frame-density-control-height-md: 2.25rem;
  --frame-density-control-height-lg: 2.5rem;
  --frame-density-control-padding-x-md: 0.875rem;
  --frame-density-inline-height: 1.375rem;
  --frame-density-item-height: 2rem;
  --frame-density-overlay-padding-block: 0.375rem;
  --frame-density-panel-padding-md: 1rem;
  --frame-density-table-cell-padding-block: 0.75rem;
  --frame-density-table-cell-padding-block-sm: 0.5rem;
  --frame-density-table-cell-padding-block-lg: 1rem;
}

[data-density='compact'] {
  --frame-density-control-height-md: 2rem;
  --frame-density-control-height-lg: 2.25rem;
  --frame-density-control-padding-x-md: 0.75rem;
  --frame-density-inline-height: 1.25rem;
  --frame-density-item-height: 1.75rem;
  --frame-density-overlay-padding-block: 0.25rem;
  --frame-density-panel-padding-md: 0.75rem;
  --frame-density-table-cell-padding-block: 0.5rem;
  --frame-density-table-cell-padding-block-sm: 0.375rem;
  --frame-density-table-cell-padding-block-lg: 0.75rem;
}

Shadows

Shadows change how much overlays and raised surfaces stand out without changing color, shape, or spacing. Set shadow: 'flat' in provideFrameUI for a flatter interface, or shadow: 'raised' when overlays need more separation.

For most apps, switch the shadow preset first. Override individual --frame-shadow-* values only when the presets are close but not quite right.

App shadows

import { provideFrameUI } from '@frame-ui-ng/foundation';

export const appConfig = {
  providers: [
    provideFrameUI({
      shadow: 'flat',
    }),
  ],
};

Shadow values

:root {
  --frame-shadow-sm: none;
  --frame-shadow-md: 0 10px 15px -3px rgb(0 0 0 / 0.1);
  --frame-shadow-lg: 0 24px 80px rgb(0 0 0 / 0.18), 0 8px 24px rgb(0 0 0 / 0.12);
}

html[data-shadow='flat'] {
  --frame-shadow-sm: none;
  --frame-shadow-md: none;
  --frame-shadow-lg: none;
}

html[data-shadow='raised'] {
  --frame-shadow-sm: 0 2px 8px rgb(0 0 0 / 0.1);
  --frame-shadow-md: 0 16px 32px -12px rgb(0 0 0 / 0.22);
  --frame-shadow-lg: 0 32px 90px rgb(0 0 0 / 0.24), 0 12px 32px rgb(0 0 0 / 0.16);
}

Where to look

Start with shared tokens when the whole app should change. Go to a component page when only one primitive needs a local adjustment. Each component page includes its own token list in the Design Tokens section.