---
title: Tailwind CSS
description: Use Tailwind CSS utility classes to style consent components via the slot system.
---
c15t works with Tailwind CSS out of the box. Use the `slots` theme option to apply Tailwind utility classes to any component part.

## Setup

Import the standard c15t stylesheet once in your app-level CSS entrypoint:

```css
/* React: src/index.css */
@import "@c15t/react/styles.css";

/* Next.js: app/globals.css */
@import "@c15t/nextjs/styles.css";
```

Keeping the c15t stylesheet in your global CSS entrypoint makes layer and cascade order explicit. JS/TSX side-effect imports can load in a different order across framework and Tailwind tooling, which makes style regressions harder to debug.

### Tailwind v4

Tailwind v4 automatically scans your source files. Import Tailwind normally, then place the c15t stylesheet immediately after it. c15t component styles join Tailwind's `components` layer automatically, so no extra c15t-specific layer declaration is needed:

```css title="src/index.css"
@import "tailwindcss";
@import "@c15t/react/styles.css";
```

```css title="app/globals.css"
@import "tailwindcss";
@import "@c15t/nextjs/styles.css";
```

### Tailwind v3

Import the Tailwind 3-compatible c15t stylesheet after `@tailwind components;` and before `@tailwind utilities;`:

```css title="src/index.css"
@tailwind base;
@tailwind components;
@import "@c15t/react/styles.tw3.css";
@tailwind utilities;
```

```css title="app/globals.css"
@tailwind base;
@tailwind components;
@import "@c15t/nextjs/styles.tw3.css";
@tailwind utilities;
```

## Using Tailwind with Slots

Apply Tailwind classes via the theme's `slots` object:

```tsx
import { type ReactNode } from 'react';
import { type Theme, ConsentManagerProvider } from '@c15t/nextjs';

const theme = {
  slots: {
    consentBanner: 'fixed bottom-0 inset-x-0 z-50',
    consentBannerCard: 'mx-auto max-w-2xl rounded-t-2xl bg-white p-6 shadow-2xl',
    consentBannerTitle: 'text-lg font-semibold text-gray-900',
    consentBannerDescription: 'mt-2 text-sm text-gray-600',
    consentBannerFooter: 'mt-4 flex flex-wrap gap-3',
    buttonPrimary: 'rounded-full bg-indigo-600 px-6 py-2.5 text-sm font-medium text-white hover:bg-indigo-700',
    buttonSecondary: 'rounded-full border border-gray-300 px-6 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50',
    toggle: 'data-[state=checked]:bg-indigo-600',
  },
} satisfies Theme;

export function ConsentManager({ children }: { children: ReactNode }) {
  return (
    <ConsentManagerProvider options={{ theme, mode: 'hosted', backendURL: '/api/c15t' }}>
      {children}
    </ConsentManagerProvider>
  );
}
```

## Dark Mode with Tailwind

Combine Tailwind's dark mode with c15t's `dark` tokens:

```tsx
const theme = {
  colors: {
    primary: '#6366f1',
    surface: '#ffffff',
    text: '#1f2937',
  },
  dark: {
    primary: '#818cf8',
    surface: '#1f2937',
    text: '#f9fafb',
  },
  slots: {
    consentBannerCard: 'bg-white dark:bg-gray-900 shadow-lg dark:shadow-gray-900/30',
    consentBannerTitle: 'text-gray-900 dark:text-gray-100',
  },
} satisfies Theme;
```

## Optional: noStyle Mode

If you want Tailwind to own all layout and visual styling, use `noStyle: true`.

> ℹ️ **Info:**
> When using noStyle: true with Tailwind, you're responsible for all layout and visual styling. Start with slots first, then switch to noStyle only when you need full control.

For full custom markup (not just styles), see [Headless Mode](../headless).
