> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-llms-scoped-indexes.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Theming

> Customize colors, fonts, spacing, and component styles using CSS custom properties and the data-theme attribute.

<Accordion title="AI Integration Quick Reference">
  | Field | Value |
  | - | - |
  | Theme prop | `theme="light"` or `theme="dark"` on `CometChatProvider` |
  | Root selector | `.cometchat` (wrapper div with `data-theme` attribute) |
  | Token prefix | `--cometchat-*` |
  | Built-in themes | `light` (default), `dark` |
  | Custom theme | Override CSS variables on `.cometchat` or `[data-theme="custom"]` |
</Accordion>

## Overview

The v7 UI Kit uses **CSS custom properties** (design tokens) for all visual styling. Every color, font, spacing value, and border radius is defined as a `--cometchat-*` variable. Components reference these tokens — never hardcoded values.

Theming works through the `data-theme` attribute on the `.cometchat` wrapper div. The built-in `light.css` and `dark.css` files define token values for each theme. You can override any token to create custom themes.

***

## Setting the Theme

Pass the `theme` prop to `CometChatProvider`:

```tsx theme={null}
<CometChatProvider theme="dark">
  <MyChatApp />
</CometChatProvider>
```

This sets `data-theme="dark"` on the wrapper, which activates the dark theme CSS variables.

***

## Switching Themes at Runtime

Use the `useTheme` hook inside any component within the provider:

```tsx theme={null}
import { useTheme } from "@cometchat/chat-uikit-react";

function ThemeToggle() {
  const { theme, setTheme } = useTheme();

  return (
    <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
      Current: {theme}
    </button>
  );
}
```

***

## Follow the System (OS) Theme

The UI Kit ships `light` and `dark` themes but **does not follow the operating system's color-scheme setting on its own** — there is no `theme="system"`. A fresh app stays on the default `light` theme even when the OS is in dark mode. To follow the OS, read `prefers-color-scheme` and drive the theme yourself.

Seed the initial theme from the OS setting when you mount the provider:

```tsx title="src/main.tsx" theme={null}
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;

<CometChatProvider theme={prefersDark ? "dark" : "light"}>
  <App />
</CometChatProvider>;
```

Then keep it in sync at runtime by subscribing to the media query's `change` event from inside the provider (so `useTheme` is available):

```tsx theme={null}
import { useEffect } from "react";
import { useTheme } from "@cometchat/chat-uikit-react";

function useFollowSystemTheme() {
  const { setTheme } = useTheme();

  useEffect(() => {
    const media = window.matchMedia("(prefers-color-scheme: dark)");

    // Apply the current OS setting immediately.
    setTheme(media.matches ? "dark" : "light");

    // Update whenever the OS toggles light/dark.
    const onChange = (event: MediaQueryListEvent) =>
      setTheme(event.matches ? "dark" : "light");
    media.addEventListener("change", onChange);
    return () => media.removeEventListener("change", onChange);
  }, [setTheme]);
}
```

<Note>
  Call `useFollowSystemTheme()` from a component rendered **inside** `CometChatProvider`. If you also expose a manual toggle, stop calling `setTheme` from this hook once the user overrides the theme — otherwise the next OS change will revert their choice.
</Note>

***

## Customizing Tokens

Override CSS variables to change the look of all components at once:

```css title="src/cometchat-overrides.css" theme={null}
.cometchat {
  --cometchat-primary-color: #e91e63;
  --cometchat-font-family: "Inter", sans-serif;
  --cometchat-radius-3: 16px;
}
```

Import this file after the UI Kit styles:

```tsx theme={null}
import "./cometchat-overrides.css";
```

### Per-Theme Overrides

Target a specific theme with the `data-theme` selector. The `data-theme` attribute and the `.cometchat` class sit on the **same** wrapper `<div>`, so use the **same-element** selector `.cometchat[data-theme="dark"]` — not the descendant form `[data-theme="dark"] .cometchat`, which matches only a `.cometchat` *nested inside* another `[data-theme]` element and therefore misses the root wrapper:

```css theme={null}
.cometchat[data-theme="dark"] {
  --cometchat-primary-color: #bb86fc;
  --cometchat-background-color-01: #121212;
}
```

<Note>
  Component-class overrides *are* descendants of the wrapper, so the descendant form is correct for them — e.g. `[data-theme="dark"] .cometchat-message-list { … }`. It's only overriding tokens on the **root wrapper** that requires the same-element `.cometchat[data-theme="dark"]` selector.
</Note>

### Per-Component Overrides

Target a specific component by its BEM class name:

```css theme={null}
.cometchat-conversations {
  --cometchat-background-color-01: #f5f5f5;
}

.cometchat-message-list {
  --cometchat-background-color-01: #fafafa;
}
```

Or wrap the component in your own class:

```css theme={null}
.my-sidebar {
  --cometchat-background-color-01: #f5f5f5;
}
```

### Differentiating the Thread Panel

Some surfaces paint their **own opaque token** rather than inheriting a background from their wrapper. The clearest example is the thread panel: its `CometChatMessageList` fills itself with `--cometchat-message-list-bg` (default `--cometchat-background-color-03`), while the thread header uses `--cometchat-thread-header-background` (which falls back to `--cometchat-background-color-01`). Because the list background is opaque, setting a `background` on the wrapping `<div>` has **no visible effect** — the list paints over it, and the panel looks mismatched against its header and composer.

To style such a surface, override its own token instead of a wrapper background. For example, to make the thread panel's message list match its header:

```css theme={null}
/* Scope to the thread wrapper in your app */
.my-thread-panel {
  --cometchat-message-list-bg: var(--cometchat-background-color-01);
  --cometchat-thread-header-background: var(--cometchat-background-color-01);
}
```

***

## Design Token Categories

### Colors

| Token | Purpose |
| - | - |
| `--cometchat-primary-color` | Brand color (buttons, links, highlights) |
| `--cometchat-extended-primary-color-50` to `900` | Primary color scale (50 = lightest) |
| `--cometchat-neutral-color-50` to `900` | Gray scale for backgrounds, borders, text (includes an intermediate `350` step) |
| `--cometchat-info-color` | Informational (blue) |
| `--cometchat-warning-color` | Warning (amber) |
| `--cometchat-success-color` | Success (green) |
| `--cometchat-error-color` | Error (red) |
| `--cometchat-static-black` | Always black regardless of theme |
| `--cometchat-static-white` | Always white regardless of theme |
| `--cometchat-static-white-70` | `--cometchat-static-white` at 70% opacity — for scrims/overlays on media |
| `--cometchat-static-neutral-100` / `400` / `700` | Fixed neutral tones that stay constant across light and dark themes |

### Semantic Colors

| Token | Purpose |
| - | - |
| `--cometchat-background-color-01` to `04` | Background layers (01 = base, 04 = elevated) |
| `--cometchat-message-list-bg` | Opaque background painted by `CometChatMessageList` (default `--cometchat-background-color-03`). Set this — not a wrapper `background` — to recolor the list surface |
| `--cometchat-thread-header-background` | Background of the thread panel header (falls back to `--cometchat-background-color-01`) |
| `--cometchat-border-color-light` / `default` / `dark` / `highlight` | Border variants |
| `--cometchat-text-color-primary` / `secondary` / `tertiary` / `disabled` / `highlight` | Text colors |
| `--cometchat-icon-color-primary` / `secondary` / `tertiary` / `highlight` | Icon colors |
| `--cometchat-drop-overlay-background` | Scrim behind the drag-and-drop file overlay on the composer |

### Typography

| Token | Value format |
| - | - |
| `--cometchat-font-family` | Font stack (default: `'Roboto', 'Inter', sans-serif`) |
| `--cometchat-font-title-bold` | `700 32px/38.4px var(--cometchat-font-family)` |
| `--cometchat-font-heading1-bold` through `heading4-regular` | Heading scales |
| `--cometchat-font-body-bold` / `medium` / `regular` | Body text (14px) |
| `--cometchat-font-caption1-bold` / `medium` / `regular` | Small text (12px) |
| `--cometchat-font-caption2-bold` / `medium` / `regular` | Smallest text (10px) |

### Spacing & Layout

| Token | Purpose |
| - | - |
| `--cometchat-spacing` to `--cometchat-spacing-20` | Spacing scale (2px increments: 2, 4, 8, 12, 16, ..., 80) |
| `--cometchat-padding` to `--cometchat-padding-10` | Padding (maps to spacing) |
| `--cometchat-margin` to `--cometchat-margin-20` | Margin (maps to spacing) |
| `--cometchat-radius` to `--cometchat-radius-6` | Border radius scale |
| `--cometchat-radius-max` | Fully rounded (1000px) |

### Buttons

| Token | Purpose |
| - | - |
| `--cometchat-primary-button-background` | Primary button background |
| `--cometchat-primary-button-text` | Primary button text color |
| `--cometchat-primary-button-icon` | Primary button icon color |
| `--cometchat-secondary-button-background` | Secondary button background |
| `--cometchat-secondary-button-text` | Secondary button text color |
| `--cometchat-fab-button-background` | Floating action button background |

***

## Component CSS Classes

The UI Kit uses plain, unhashed BEM class names in the DOM. All component class names follow the pattern `cometchat-{component}` with BEM modifiers (e.g., `cometchat-message-bubble__content--outgoing`). You can target them directly with standard class selectors.

### What Works

**1. The `.cometchat` wrapper class** — the root div. Override tokens here to affect all components:

```css theme={null}
.cometchat {
  --cometchat-primary-color: #e91e63;
  --cometchat-font-family: "Inter", sans-serif;
}
```

**2. Plain class selectors** — target any component by its BEM class name:

```css theme={null}
.cometchat-conversations {
  --cometchat-background-color-01: #f5f5f5;
}

.cometchat-message-list {
  --cometchat-background-color-01: #fafafa;
}
```

**3. Wrap in your own class** — add a wrapper div with your own class and set tokens there:

```tsx theme={null}
<div className="my-chat-sidebar">
  <CometChatConversations />
</div>
```

```css theme={null}
.my-chat-sidebar {
  --cometchat-background-color-01: #f5f5f5;
  --cometchat-primary-color: #1976d2;
}
```

<Note>
  CSS variable overrides work at any level of the tree. Set them on `.cometchat` (the root wrapper) to affect all components, or use class selectors / wrapper classes to scope the change. Variables cascade down — a value set on a parent will be inherited by all CometChat components within it.
</Note>

***

## Creating a Custom Theme

Define a complete set of tokens under a custom `data-theme` value:

```css title="src/themes/brand.css" theme={null}
[data-theme="brand"] {
  --cometchat-primary-color: #e91e63;
  --cometchat-extended-primary-color-500: #e91e63;
  --cometchat-background-color-01: #fce4ec;
  --cometchat-background-color-02: #f8bbd0;
  --cometchat-font-family: "Poppins", sans-serif;
  /* ... override all tokens as needed */
}
```

Then pass your theme name:

```tsx theme={null}
<CometChatProvider theme="brand">
```

<Note>
  When creating a custom theme, start from the light or dark theme file and override only what you need. Unset tokens will fall back to the `:root` defaults (light theme).
</Note>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Color Resources" icon="palette" href="/ui-kit/react/theme/color-resources">
    Full color token reference with swatches
  </Card>

  <Card title="Message Bubble Styling" icon="message" href="/ui-kit/react/theme/message-bubble-styling">
    Customize bubble appearance, alignment, and spacing
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.