Theme

Use NgOatThemeRef to manipulate Oat design tokens at runtime. Every --oat-* token maps to an upstream Oat CSS variable so your overrides apply globally.

Live token editor

Spacing & radius

Preview

Sample card

This card reflects the current token values.

Form elements

Preset themes

Click a preset to apply it. Each theme provides light-dark() values so it works in both light & dark modes.


Token reference

All available --oat-* tokens grouped by category. Each maps to an upstream Oat CSS variable.

Color tokens

TokenUpstream CSS varDescriptionDefault (light)Default (dark)
--oat-background--backgroundPage background#fff#09090b
--oat-foreground--foregroundDefault text color#09090b#fafafa
--oat-card--cardCard / surface background#fff#18181b
--oat-card-foreground--card-foregroundText on cards#09090b#fafafa
--oat-primary--primaryPrimary brand color#574747#fafafa
--oat-primary-foreground--primary-foregroundText on primary bg#fafafa#18181b
--oat-secondary--secondarySecondary surfaces#f4f4f5#27272a
--oat-secondary-foreground--secondary-foregroundText on secondary#574747#fafafa
--oat-muted--mutedMuted / disabled bg#f4f4f5#27272a
--oat-muted-foreground--muted-foregroundMuted / placeholder text#71717a#a1a1aa
--oat-accent--accentAccent / hover bg#f4f4f5#27272a
--oat-faint--faintFaintest background layer#fafafa#1e1e21
--oat-faint-foreground--faint-foregroundText on faint bg#a1a1aa#71717a
--oat-danger--dangerError / destructive color#d32f2f#f4807b
--oat-danger-foreground--danger-foregroundText on danger bg#fafafa#18181b
--oat-success--successSuccess color#008032#6cc070
--oat-success-foreground--success-foregroundText on success bg#fafafa#18181b
--oat-warning--warningWarning color#a65b00#f0a030
--oat-warning-foreground--warning-foregroundText on warning bg#09090b
--oat-border--borderDefault border color#d4d4d8#52525b
--oat-input--inputInput field border#d4d4d8#52525b
--oat-ring--ringFocus ring color#574747#d4d4d8

Spacing tokens

TokenUpstreamDefault
--oat-space-1--space-10.25rem (4px)
--oat-space-2--space-20.5rem (8px)
--oat-space-3--space-30.75rem (12px)
--oat-space-4--space-41rem (16px)
--oat-space-5--space-51.25rem (20px)
--oat-space-6--space-61.5rem (24px)
--oat-space-8--space-82rem (32px)
--oat-space-10--space-102.5rem (40px)
--oat-space-12--space-123rem (48px)
--oat-space-14--space-143.5rem (56px)
--oat-space-16--space-164rem (64px)
--oat-space-18--space-184.5rem (72px)

Border radius tokens

TokenUpstreamDefault
--oat-radius-small--radius-small0.125rem (2px)
--oat-radius-medium--radius-medium0.375rem (6px)
--oat-radius-large--radius-large0.75rem (12px)
--oat-radius-full--radius-full9999px

Typography tokens

TokenUpstreamDefault
--oat-font-sans--font-sanssystem-ui, sans-serif
--oat-font-mono--font-monoui-monospace, Consolas, monospace
--oat-text-1 … --oat-text-8--text-1 … --text-8Fluid scale from 2.25rem β†’ 0.75rem
--oat-font-normal--font-normal400
--oat-font-medium--font-medium500
--oat-font-semibold--font-semibold600
--oat-font-bold--font-bold700

Shadow & misc tokens

TokenUpstreamDescription
--oat-shadow-small--shadow-smallSubtle shadow for cards, tooltips
--oat-shadow-medium--shadow-mediumMedium shadow for dropdowns
--oat-shadow-large--shadow-largeProminent shadow for modals
--oat-transition--transitionDefault transition duration
--oat-transition-fast--transition-fastFast transition duration
--oat-z-dropdown--z-dropdownz-index for dropdowns
--oat-z-modal--z-modalz-index for modals
--oat-bar-height--bar-heightProgress/meter bar height

Customization examples

1 β€” Override tokens in CSS (zero JS)

The simplest approach. Add overrides in your global stylesheet:

/* styles.css */
:root {
  --primary: #3b82f6;          /* Override upstream Oat variable directly */
  --radius-medium: 0.75rem;    /* Rounder corners */
  --border: #e2e8f0;
}

2 β€” Use provideNgOatTheme() at bootstrap

Set tokens via Angular DI so they're applied before the first render:

// app.config.ts
import { provideNgOatTheme } from '@letsprogram/ng-oat';

export const appConfig = {
  providers: [
    provideNgOatTheme({
      tokens: {
        '--oat-primary':            '#3b82f6',
        '--oat-primary-foreground': '#ffffff',
        '--oat-radius-medium':      '0.75rem',
      },
    }),
  ],
};

3 β€” Switch themes at runtime

Inject NgOatThemeRef and call setTokens() whenever you want:

// my-settings.component.ts
import { NgOatThemeRef } from '@letsprogram/ng-oat';

export class SettingsComponent {
  private theme = inject(NgOatThemeRef);

  applyBrand() {
    this.theme.setTokens({
      '--oat-primary':            '#0ea5e9',
      '--oat-primary-foreground': '#ffffff',
      '--oat-background':         'light-dark(#f8fafc, #0f172a)',
      '--oat-foreground':         'light-dark(#0f172a, #f1f5f9)',
      '--oat-border':             'light-dark(#cbd5e1, #334155)',
    });
  }

  reset() {
    this.theme.resetTokens();
  }
}

4 β€” Scope tokens to a section

Apply tokens to a specific container instead of :root:

provideNgOatTheme({
  tokens: { '--oat-primary': '#e11d48' },
  scope: '#admin-panel',          // CSS selector
})

// Or change scope at runtime:
this.theme.setScope('#admin-panel');

5 β€” Support light-dark() for both modes

Use light-dark(lightValue, darkValue) to ensure your theme works in both color schemes:

this.theme.setTokens({
  '--oat-primary':     'light-dark(#2563eb, #60a5fa)',
  '--oat-background':  'light-dark(#ffffff, #0c0a09)',
  '--oat-foreground':  'light-dark(#1c1917, #fafaf9)',
  '--oat-card':        'light-dark(#ffffff, #1c1917)',
  '--oat-border':      'light-dark(#d6d3d1, #44403c)',
});