Documentation

Theming

Customize Angular AI Kit components with CSS variables and Tailwind classes.

Overview

How theming works in Angular AI Kit

Angular AI Kit uses CSS custom properties (variables) for theming. This approach provides:

  • Automatic light/dark mode switching
  • Easy customization without rebuilding
  • Consistent styling across all components
  • Full Tailwind CSS v4 compatibility

CSS Variables Reference

All available CSS custom properties

Core Colors

Variable Description Light Dark
--background Page/app background color whitezinc-950
--foreground Primary text color zinc-950zinc-50
--card Card backgrounds zinc-50zinc-900
--card-foreground Text on cards zinc-950zinc-50
--muted Muted/subtle backgrounds zinc-100zinc-900
--muted-foreground Muted text color zinc-500zinc-400
--accent Accent/hover backgrounds zinc-100zinc-800
--accent-foreground Text on accent backgrounds zinc-900zinc-50

Border & Input

Variable Description Light Dark
--border Default border color zinc-200zinc-800
--border-hover Border on hover/focus zinc-300zinc-600
--input Input field backgrounds zinc-50zinc-900
--ring Focus ring color zinc-400zinc-500

Actions & Buttons

Variable Description Light Dark
--primary Primary actions/buttons zinc-900zinc-50
--primary-foreground Text on primary zinc-50zinc-900
--secondary Secondary actions zinc-100zinc-800
--secondary-foreground Text on secondary zinc-900zinc-50
--destructive Destructive/danger actions red-500red-500
--destructive-foreground Text on destructive zinc-50zinc-50

Message Components

Variable Description Light Dark
--message-user-bg User message background zinc-100zinc-800
--message-assistant-bg Assistant message background whitezinc-900
--avatar-user User avatar color zinc-700zinc-600
--avatar-assistant Assistant avatar color zinc-800zinc-700

Basic Setup

Add CSS variables to your styles.css

Light Theme (Default)

1:root {2  /* Core Colors */3  --background: theme('colors.white');4  --foreground: theme('colors.zinc.950');5 6  /* Card */7  --card: theme('colors.zinc.50');8  --card-foreground: theme('colors.zinc.950');9 10  /* Muted */11  --muted: theme('colors.zinc.100');12  --muted-foreground: theme('colors.zinc.500');13 14  /* Border */15  --border: theme('colors.zinc.200');16  --ring: theme('colors.zinc.400');17 18  /* Primary */19  --primary: theme('colors.zinc.900');20  --primary-foreground: theme('colors.zinc.50');21}

Dark Theme

1.dark {2  /* Core Colors */3  --background: theme('colors.zinc.950');4  --foreground: theme('colors.zinc.50');5 6  /* Card */7  --card: theme('colors.zinc.900');8  --card-foreground: theme('colors.zinc.50');9 10  /* Muted */11  --muted: theme('colors.zinc.900');12  --muted-foreground: theme('colors.zinc.400');13 14  /* Border */15  --border: theme('colors.zinc.800');16  --ring: theme('colors.zinc.500');17 18  /* Primary (inverted for dark) */19  --primary: theme('colors.zinc.50');20  --primary-foreground: theme('colors.zinc.900');21}

Using Tailwind Classes

How to use semantic color classes

Use Tailwind's semantic color classes which automatically reference CSS variables:

1<!-- Use semantic classes (recommended) -->2<div class="bg-background text-foreground">3  <div class="border border-border rounded-lg bg-card p-4">4    <h2 class="text-foreground font-semibold">Title</h2>5    <p class="text-muted-foreground">Description</p>6    <button class="bg-primary text-primary-foreground px-4 py-2 rounded">7      Click me8    </button>9  </div>10</div>11 12<!-- These classes auto-switch between light/dark themes! -->

Key Classes

bg-background - Page background
bg-card - Card backgrounds
bg-muted - Muted backgrounds
bg-primary - Primary buttons
text-foreground - Main text
text-muted-foreground - Subtle text
border-border - Borders
ring-ring - Focus rings

Dark Mode Implementation

How to implement theme switching

Dark mode is activated by adding the .dark class to the <html> element.

Theme Toggle Component

1import { Component, signal, inject, PLATFORM_ID } from '@angular/core';2import { isPlatformBrowser, DOCUMENT } from '@angular/common';3 4@Component({5  selector: 'app-theme-toggle',6  template: `7    <button8      (click)="toggleTheme()"9      class="rounded-lg border border-border p-2 hover:bg-muted"10      [attr.aria-label]="isDark() ? 'Switch to light mode' : 'Switch to dark mode'"11    >12      @if (isDark()) {13        <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">14          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"15            d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />16        </svg>17      } @else {18        <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">19          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"20            d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />21        </svg>22      }23    </button>24  `,25})26export class ThemeToggleComponent {27  private document = inject(DOCUMENT);28  private platformId = inject(PLATFORM_ID);29 30  isDark = signal(false);31 32  constructor() {33    if (isPlatformBrowser(this.platformId)) {34      // Check system preference35      const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;36      // Check saved preference37      const savedTheme = localStorage.getItem('theme');38      const isDark = savedTheme === 'dark' || (!savedTheme && prefersDark);39 40      this.isDark.set(isDark);41      this.updateTheme(isDark);42    }43  }44 45  toggleTheme() {46    const newValue = !this.isDark();47    this.isDark.set(newValue);48    this.updateTheme(newValue);49    localStorage.setItem('theme', newValue ? 'dark' : 'light');50  }51 52  private updateTheme(isDark: boolean) {53    if (isDark) {54      this.document.documentElement.classList.add('dark');55    } else {56      this.document.documentElement.classList.remove('dark');57    }58  }59}

Key Points

  • Check prefers-color-scheme for system preference
  • Store user preference in localStorage
  • Toggle .dark class on <html>
  • All components automatically adapt!

Custom Color Schemes

Create your own color theme

Override the default zinc color scheme with your own colors:

1:root {2  /* Custom Blue Theme */3  --primary: theme('colors.blue.600');4  --primary-foreground: theme('colors.white');5 6  /* Custom accent */7  --accent: theme('colors.blue.100');8  --accent-foreground: theme('colors.blue.900');9 10  /* Keep neutral tones for backgrounds */11  --background: theme('colors.slate.50');12  --foreground: theme('colors.slate.900');13  --card: theme('colors.white');14  --muted: theme('colors.slate.100');15}16 17.dark {18  --primary: theme('colors.blue.400');19  --primary-foreground: theme('colors.blue.950');20 21  --accent: theme('colors.blue.950');22  --accent-foreground: theme('colors.blue.100');23 24  --background: theme('colors.slate.950');25  --foreground: theme('colors.slate.50');26  --card: theme('colors.slate.900');27  --muted: theme('colors.slate.800');28}

Tips

  • Use theme('colors.xxx') to reference Tailwind colors
  • Keep neutral backgrounds for readability
  • Ensure sufficient contrast for accessibility
  • Test both light and dark modes

Component Customization

Override styles on individual components

Most components accept a customClasses input for additional styling:

1import { Component } from '@angular/core';2import { ChatInputComponent } from '@angular-ai-kit/core';3 4@Component({5  selector: 'app-custom-chat',6  imports: [ChatInputComponent],7  template: `8    <ai-chat-input9      placeholder="Send a message..."10      customClasses="rounded-full border-2 border-blue-500"11    />12  `,13})14export class CustomChatComponent {}

Next Steps

Now that you understand theming, explore more: