# Tailwind CSS User Guide

Tailwind CSS is a utility-first CSS framework that lets you build custom designs directly in your HTML using a fixed vocabulary of composable class names like `flex`, `px-4`, `text-lg`, and `bg-blue-500`. Version 4 is a ground-up rewrite: configuration now lives in your CSS through directives like `@theme`, `@source`, and `@plugin` rather than a JavaScript config file. The class scanner runs in Rust via the Oxide engine, and the default theme ships with a curated OKLCH color palette.

This guide covers everything you need to install, configure, and use Tailwind CSS in your projects. For architecture details, plugin authoring internals, Oxide scanner implementation, and monorepo layout, see the Admin Guide.

---

## 1. Quick Start

Get a working Tailwind CSS project in under two minutes.

### 1.1 The Fastest Path: Vite

```bash
npm create vite@latest my-project -- --template vanilla
cd my-project
npm install tailwindcss @tailwindcss/vite
```

Add the Vite plugin to `vite.config.js`:

```js
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    tailwindcss(),
  ],
})
```

Replace the contents of `src/style.css`:

```css
@import 'tailwindcss';
```

Add utility classes to your HTML:

```html
<h1 class="text-3xl font-bold text-blue-600 underline">
  Hello, Tailwind!
</h1>
```

Start the dev server:

```bash
npm run dev
```

That single `@import 'tailwindcss'` line pulls in Preflight (a modern CSS reset), the full default theme, and all utility class generation. Every class you use in your markup is detected automatically and compiled into your CSS output.

### 1.2 The Fastest Path: CLI

If you have no build tool at all:

```bash
npx @tailwindcss/cli -i input.css -o output.css --watch
```

Where `input.css` contains `@import 'tailwindcss';`. The CLI watches your project files and regenerates `output.css` whenever you save.

### 1.3 The Fastest Path: CDN (Browser Build)

For prototyping with zero tooling:

```html
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
</head>
<body>
  <h1 class="text-3xl font-bold text-purple-700">
    Instant Tailwind
  </h1>
</body>
</html>
```

> [!WARNING]
> The browser build is for prototyping only. It compiles in the browser at runtime, does not support `@import` of external files, and does not support JS plugins or config files. Never use it in production.

---

## 2. Installation

Tailwind CSS v4 requires **Node.js 20 or later**. There are six integration paths depending on your build setup.

### 2.1 Requirements

| Requirement | Version |
|---|---|
| Node.js | >= 20 |
| npm / pnpm / yarn / bun | Any current release |
| License | MIT |

> [!NOTE]
> Tailwind v4 ships native binaries for the Oxide scanner. Supported platforms include Linux x64 (glibc and musl), Linux ARM64, macOS x64, macOS ARM64, and Windows x64. If your platform is not supported, you will see an error at install time (see Troubleshooting).

### 2.2 Using the Vite Plugin

The Vite plugin (`@tailwindcss/vite`) is the recommended integration for Vite-based projects. It provides the fastest development experience with hot module replacement (HMR).

```bash
npm install tailwindcss @tailwindcss/vite
```

```js
// vite.config.js
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    tailwindcss(),
  ],
})
```

Create your CSS entry point:

```css
/* src/app.css */
@import 'tailwindcss';
```

Import the CSS in your application entry:

```js
// src/main.js
import './app.css'
```

#### Vite Plugin with React

```bash
npm install tailwindcss @tailwindcss/vite
```

```js
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
  ],
})
```

#### Vite Plugin with Vue

```bash
npm install tailwindcss @tailwindcss/vite
```

```js
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    vue(),
    tailwindcss(),
  ],
})
```

#### Vite Plugin with Svelte

```bash
npm install tailwindcss @tailwindcss/vite
```

```js
// vite.config.js
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    svelte(),
    tailwindcss(),
  ],
})
```

### 2.3 Using PostCSS

The PostCSS plugin (`@tailwindcss/postcss`) integrates Tailwind into any PostCSS-compatible build tool.

```bash
npm install tailwindcss @tailwindcss/postcss
```

Add to your PostCSS configuration:

```js
// postcss.config.js
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
}
```

Create your CSS entry point:

```css
/* src/app.css */
@import 'tailwindcss';
```

> [!TIP]
> If you are using a framework that already has PostCSS configured (like Next.js, Nuxt, or Angular), you only need to add `@tailwindcss/postcss` to the existing PostCSS config. You do not need to install PostCSS separately.

#### PostCSS with Next.js

```bash
npm install tailwindcss @tailwindcss/postcss
```

```js
// postcss.config.mjs
const config = {
  plugins: {
    '@tailwindcss/postcss': {},
  },
}
export default config
```

In your global CSS file (e.g., `app/globals.css`):

```css
@import 'tailwindcss';
```

#### PostCSS with Nuxt

```bash
npm install tailwindcss @tailwindcss/postcss
```

```js
// postcss.config.js
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
}
```

In your Nuxt CSS entry (configured in `nuxt.config.ts`):

```css
@import 'tailwindcss';
```

#### PostCSS with Angular

```bash
npm install tailwindcss @tailwindcss/postcss
```

Angular's CLI reads `.postcssrc.json` automatically:

```json
{
  "plugins": {
    "@tailwindcss/postcss": {}
  }
}
```

In your `src/styles.css`:

```css
@import 'tailwindcss';
```

### 2.4 Using the CLI

The CLI (`@tailwindcss/cli`) is a standalone build tool that requires no framework integration.

```bash
npm install tailwindcss @tailwindcss/cli
```

#### CLI Commands

| Command | Description |
|---|---|
| `build` (default) | Compile CSS input to output |
| `canonicalize` | Normalize and reformat Tailwind CSS input |

#### CLI Flags

| Flag | Short | Description |
|---|---|---|
| `--input` | `-i` | Path to the input CSS file |
| `--output` | `-o` | Path to write the compiled CSS |
| `--watch` | `-w` | Watch for changes and rebuild automatically |
| `--minify` | | Minify the output CSS |
| `--help` | `-h` | Show help information |
| `-` (stdin) | | Read input from stdin |
| `-` (stdout) | | Write output to stdout |

#### Basic Build

```bash
npx @tailwindcss/cli -i src/app.css -o dist/output.css
```

#### Watch Mode

```bash
npx @tailwindcss/cli -i src/app.css -o dist/output.css --watch
```

#### Minified Production Build

```bash
npx @tailwindcss/cli -i src/app.css -o dist/output.css --minify
```

#### Pipe via stdin/stdout

```bash
cat src/app.css | npx @tailwindcss/cli -i - -o -
```

This is useful for integrating with other tools in a Unix pipeline.

#### Canonicalize

The `canonicalize` command normalizes your Tailwind CSS file, reordering directives and formatting consistently:

```bash
npx @tailwindcss/cli canonicalize -i src/app.css -o src/app.css
```

#### Using with npm Scripts

```json
{
  "scripts": {
    "dev": "tailwindcss -i src/app.css -o dist/output.css --watch",
    "build": "tailwindcss -i src/app.css -o dist/output.css --minify"
  }
}
```

### 2.5 Using Webpack

The Webpack loader (`@tailwindcss/webpack`) integrates Tailwind into Webpack-based projects.

```bash
npm install tailwindcss @tailwindcss/webpack
```

```js
// webpack.config.js
const tailwindcss = require('@tailwindcss/webpack')

module.exports = {
  // ...
  plugins: [
    tailwindcss(),
  ],
}
```

Create your CSS entry point:

```css
/* src/app.css */
@import 'tailwindcss';
```

### 2.6 Using the Standalone Binary

The standalone CLI (`@tailwindcss/standalone`) is a self-contained binary that does not require Node.js. It bundles everything needed to compile Tailwind CSS, including several popular first-party plugins.

#### Download

Download the binary for your platform from the GitHub releases page, or install it:

```bash
npm install @tailwindcss/standalone
```

#### Built-in Plugins

The standalone binary includes these plugins with no additional installation:

- `@tailwindcss/forms`
- `@tailwindcss/typography`
- `@tailwindcss/aspect-ratio`

#### Usage

```bash
./tailwindcss -i src/app.css -o dist/output.css --watch
```

The standalone binary accepts the same flags as the standard CLI (`--input`, `--output`, `--watch`, `--minify`).

> [!TIP]
> The standalone binary is ideal for environments where Node.js is not available or not desired, such as CI pipelines, Docker containers with minimal images, or non-Node projects (PHP, Ruby, Python, Go, etc.).

### 2.7 Using the Browser Build

The browser build (`@tailwindcss/browser`) compiles Tailwind CSS entirely in the browser at runtime.

```html
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
```

Or with a specific version:

```html
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.2.2"></script>
```

#### Inline Tailwind CSS

You can write Tailwind directives in a `<style>` tag with `type="text/tailwindcss"`:

```html
<style type="text/tailwindcss">
  @theme {
    --color-primary: #3b82f6;
  }
</style>

<h1 class="text-primary font-bold text-4xl">Hello</h1>
```

#### Browser Build Limitations

The browser build has specific constraints:

- `@import` for external files is not supported
- JS plugins (`@plugin`) are not supported
- JS config files (`@config`) are not supported
- Compilation happens at runtime (performance impact on page load)
- Not suitable for production use

### 2.8 Granular CSS Imports

Instead of importing all of Tailwind with `@import 'tailwindcss'`, you can import individual layers:

```css
/* Preflight only (CSS reset) */
@import 'tailwindcss/preflight';

/* Theme variables only */
@import 'tailwindcss/theme';

/* Utility classes only */
@import 'tailwindcss/utilities';
```

This gives you control over which parts of Tailwind are included. For example, if you already have your own CSS reset:

```css
/* Skip Preflight, use theme + utilities only */
@import 'tailwindcss/theme';
@import 'tailwindcss/utilities';
```

Or if you want to insert custom base styles between Preflight and utilities:

```css
@import 'tailwindcss/preflight';
@import 'tailwindcss/theme';

/* Your custom base styles here */
body {
  font-family: 'Inter', sans-serif;
}

@import 'tailwindcss/utilities';
```

---

## 3. Configuration

Tailwind CSS v4 uses a **CSS-first configuration** model. Instead of a `tailwind.config.js` file, you configure Tailwind directly in your CSS using special directives.

### 3.1 Configuration Directives Overview

| Directive | Purpose |
|---|---|
| `@theme` | Define and override design tokens (colors, spacing, fonts, etc.) |
| `@source` | Control which files are scanned for class candidates |
| `@plugin` | Load JavaScript plugins |
| `@config` | Load a legacy `tailwind.config.js` file |
| `@variant` | Define custom variants |
| `@utility` | Define custom utility classes |
| `@apply` | Use utility classes inside custom CSS |
| `@reference` | Reference another CSS file without including its output |

### 3.2 The `@theme` Directive

The `@theme` directive defines design tokens as CSS custom properties. These tokens generate the utility classes Tailwind provides.

#### Basic Theme Customization

```css
@import 'tailwindcss';

@theme {
  --color-primary: #3b82f6;
  --color-secondary: #8b5cf6;
  --color-accent: #f59e0b;
  --font-family-display: 'Cal Sans', sans-serif;
  --font-family-body: 'Inter', sans-serif;
}
```

This makes classes like `text-primary`, `bg-secondary`, `text-accent`, `font-display`, and `font-body` available throughout your project.

#### Namespace Prefixes

Theme values are organized by namespace prefix. Each prefix maps to a category of utilities:

| Prefix | Generates | Example Class |
|---|---|---|
| `--color-*` | Color utilities | `text-brand`, `bg-brand`, `border-brand` |
| `--spacing-*` | Spacing utilities | `p-gutter`, `m-gutter`, `gap-gutter` |
| `--font-family-*` | Font family utilities | `font-display` |
| `--font-size-*` | Font size utilities | `text-heading` |
| `--font-weight-*` | Font weight utilities | `font-medium` |
| `--breakpoint-*` | Responsive breakpoints | `md:`, `lg:`, `xl:` |
| `--width-*` | Width utilities | `w-sidebar` |
| `--height-*` | Height utilities | `h-header` |
| `--radius-*` | Border radius utilities | `rounded-card` |
| `--shadow-*` | Box shadow utilities | `shadow-card` |
| `--tracking-*` | Letter spacing utilities | `tracking-wide` |
| `--leading-*` | Line height utilities | `leading-relaxed` |
| `--ease-*` | Transition timing | `ease-bounce` |
| `--animate-*` | Animation utilities | `animate-slide-in` |
| `--inset-shadow-*` | Inset shadow utilities | `inset-shadow-lg` |

#### Defining Colors

```css
@theme {
  --color-brand-50: #eff6ff;
  --color-brand-100: #dbeafe;
  --color-brand-200: #bfdbfe;
  --color-brand-300: #93c5fd;
  --color-brand-400: #60a5fa;
  --color-brand-500: #3b82f6;
  --color-brand-600: #2563eb;
  --color-brand-700: #1d4ed8;
  --color-brand-800: #1e40af;
  --color-brand-900: #1e3a8a;
  --color-brand-950: #172554;
}
```

This generates `text-brand-500`, `bg-brand-200`, `border-brand-700`, `ring-brand-400`, and all other color-related utilities for every shade.

#### Defining Spacing

```css
@theme {
  --spacing-gutter: 1.5rem;
  --spacing-section: 4rem;
  --spacing-sidebar: 16rem;
}
```

Generates `p-gutter`, `m-section`, `gap-gutter`, `w-sidebar`, and so on.

#### Defining Breakpoints

```css
@theme {
  --breakpoint-xs: 30rem;
  --breakpoint-sm: 40rem;
  --breakpoint-md: 48rem;
  --breakpoint-lg: 64rem;
  --breakpoint-xl: 80rem;
  --breakpoint-2xl: 96rem;
}
```

Generates responsive variants like `xs:`, `sm:`, `md:`, `lg:`, `xl:`, `2xl:`.

#### Defining Fonts

```css
@theme {
  --font-family-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-family-serif: 'Merriweather', ui-serif, Georgia, serif;
  --font-family-mono: 'JetBrains Mono', ui-monospace, monospace;

  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --font-size-3xl: 1.875rem;
  --font-size-4xl: 2.25rem;

  --font-weight-thin: 100;
  --font-weight-light: 300;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --font-weight-black: 900;
}
```

#### Defining Shadows

```css
@theme {
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --shadow-card: 0 2px 8px rgb(0 0 0 / 0.08);
  --shadow-elevated: 0 8px 24px rgb(0 0 0 / 0.12);
}
```

#### Defining Animations

```css
@theme {
  --animate-fade-in: fade-in 0.3s ease-out;
  --animate-slide-up: slide-up 0.4s ease-out;
  --animate-bounce-in: bounce-in 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slide-up {
  from { transform: translateY(1rem); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

@keyframes bounce-in {
  from { transform: scale(0.9); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}
```

Generates `animate-fade-in`, `animate-slide-up`, `animate-bounce-in`.

#### Defining Transition Timing

```css
@theme {
  --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
  --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
}
```

Generates `ease-bounce`, `ease-smooth`.

#### Defining Border Radius

```css
@theme {
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
  --radius-2xl: 1rem;
  --radius-full: 9999px;
  --radius-card: 0.75rem;
  --radius-button: 0.5rem;
}
```

#### Resetting the Default Theme

To start from scratch with no default theme values, reset all defaults:

```css
@theme {
  --*: initial;
}
```

This removes every built-in design token. You must then define all your own tokens from zero. Classes like `text-blue-500` will no longer work unless you re-define those color tokens.

You can also reset specific namespaces:

```css
@theme {
  --color-*: initial;

  /* Now define only the colors you want */
  --color-primary: #3b82f6;
  --color-gray-100: #f3f4f6;
  --color-gray-900: #111827;
}
```

> [!IMPORTANT]
> Resetting with `--*: initial` removes ALL default Tailwind theme values. This means default colors like `blue-500`, default spacing, default breakpoints, and all other built-in tokens disappear. Only do this if you intend to define a complete custom design system.

#### Multiple `@theme` Blocks

You can use multiple `@theme` blocks. They merge together:

```css
@import 'tailwindcss';

@theme {
  --color-primary: #3b82f6;
}

@theme {
  --color-secondary: #8b5cf6;
}
```

Both `primary` and `secondary` colors will be available.

### 3.3 The `@source` Directive

The `@source` directive tells Tailwind which files to scan for utility class candidates. By default, Tailwind scans all files in your project directory (respecting `.gitignore`), but you can customize this.

#### Adding Source Paths

```css
@import 'tailwindcss';

@source '../components/**/*.jsx';
@source '../layouts/**/*.html';
@source '../node_modules/my-ui-lib/src/**/*.js';
```

#### Glob Pattern Syntax

| Pattern | Matches |
|---|---|
| `*` | Any file in a single directory |
| `**` | Any file recursively |
| `*.jsx` | Any `.jsx` file in a single directory |
| `**/*.{html,jsx,tsx}` | Any `.html`, `.jsx`, or `.tsx` file recursively |
| `../packages/ui/**/*.tsx` | Files in a sibling package |

#### Scanning Node Modules

By default, `node_modules` is excluded. To scan a specific package:

```css
@source '../node_modules/@my-org/ui-components/**/*.js';
```

#### Source Directory Base

The `source(...)` function references a directory that all `@source` glob patterns are relative to:

```css
@import 'tailwindcss' source('../src');
```

This changes the base directory for automatic scanning from your CSS file's location to `../src`.

> [!NOTE]
> The `@source` directive respects your `.gitignore` file. If a file or directory is listed in `.gitignore`, Tailwind will not scan it for class candidates even if it matches a `@source` glob pattern. This can cause confusion when `@source` appears to silently ignore paths (see Troubleshooting for issue #19844).

#### Source with `none`

Disable automatic source detection entirely:

```css
@import 'tailwindcss' source(none);

/* Only scan explicitly listed sources */
@source '../app/**/*.tsx';
@source '../components/**/*.tsx';
```

#### Scanning Non-Standard File Types

The Oxide engine automatically detects and extracts class candidates from many file types beyond HTML and JavaScript:

| Language/Format | File Extensions |
|---|---|
| Clojure | `.clj`, `.cljs`, `.cljc` |
| Elixir | `.ex`, `.exs`, `.heex`, `.leex` |
| Haml | `.haml` |
| JSON | `.json` |
| Markdown | `.md`, `.mdx` |
| Pug | `.pug`, `.jade` |
| Razor | `.cshtml`, `.razor` |
| Ruby | `.rb`, `.erb` |
| Rust | `.rs` |
| Slim | `.slim` |
| Svelte | `.svelte` |
| Vue | `.vue` |

### 3.4 The `@plugin` Directive

Load JavaScript plugins directly from your CSS:

```css
@import 'tailwindcss';

@plugin '@tailwindcss/typography';
@plugin '@tailwindcss/forms';
@plugin './my-custom-plugin.js';
```

Plugins must be installed in your `node_modules` or referenced as a relative path. Each plugin can register new utilities, variants, base styles, and components.

#### Popular First-Party Plugins

| Plugin | Purpose |
|---|---|
| `@tailwindcss/typography` | Beautiful typographic defaults for prose content |
| `@tailwindcss/forms` | Improved form element styling |
| `@tailwindcss/aspect-ratio` | Aspect ratio utilities (v3 compat) |

### 3.5 The `@config` Directive

For backward compatibility, you can load a legacy `tailwind.config.js` file:

```css
@import 'tailwindcss';

@config '../tailwind.config.js';
```

This is a migration path from v3. The CSS-first configuration (`@theme`, `@plugin`, etc.) is the recommended approach for new projects.

> [!TIP]
> Use the `@tailwindcss/upgrade` tool to automatically migrate your v3 `tailwind.config.js` to v4 CSS-first configuration. See the "Upgrading from Tailwind v3" section for details.

### 3.6 The `@reference` Directive

The `@reference` directive lets you reference another CSS file for type-checking and IntelliSense without actually including its output in your build:

```css
@reference '../app.css';

.my-component {
  @apply text-primary bg-secondary;
}
```

This is useful when you have component-level CSS files that need access to your theme tokens and custom utilities defined in a different file, without duplicating that file's output.

### 3.7 Theme Functions

Tailwind v4 provides CSS functions for referencing theme values dynamically.

#### `--theme(...)`

Reference any theme token value:

```css
.custom-element {
  color: var(--color-primary);
  background-color: --theme(--color-brand-100);
  border: 1px solid --theme(--color-brand-300);
}
```

> [!CAUTION]
> The `--theme(...)` function can only be used with CSS variables defined in your `@theme` block. Attempting to use it with non-theme variables produces: `The --theme(...) function can only be used with CSS variables from your theme.`

#### `--spacing(...)`

Reference the spacing scale:

```css
.custom-element {
  padding: --spacing(4);
  margin-bottom: --spacing(8);
  gap: --spacing(2);
}
```

The argument maps to your spacing scale (e.g., `--spacing(4)` = `1rem` in the default theme). Passing no argument produces an error: `The --spacing(...) function requires an argument, but received none.`

### 3.8 Compatibility Exports

For backward compatibility with v3-era tooling and plugins, Tailwind CSS v4 provides these JavaScript exports:

| Export | Import Path |
|---|---|
| Default colors | `tailwindcss/colors` |
| Default theme values | `tailwindcss/defaultTheme` |
| Plugin helper | `tailwindcss/plugin` |
| Color utility | `tailwindcss/lib/util/flattenColorPalette` |

```js
// Accessing default colors in a plugin or config
import colors from 'tailwindcss/colors'

console.log(colors.blue[500]) // '#3b82f6'
```

```js
// Using the plugin helper
import plugin from 'tailwindcss/plugin'

export default plugin(function({ addUtilities }) {
  addUtilities({
    '.content-auto': {
      'content-visibility': 'auto',
    },
  })
})
```

---

## 4. Core Usage

### 4.1 How Utility Classes Work

Every Tailwind utility class maps to one or a small number of CSS property declarations. You compose them in your HTML `class` attribute to build designs:

```html
<div class="flex items-center gap-4 p-6 bg-white rounded-lg shadow-md">
  <img class="w-12 h-12 rounded-full" src="avatar.jpg" alt="">
  <div>
    <h3 class="text-lg font-semibold text-gray-900">Jane Smith</h3>
    <p class="text-sm text-gray-500">Product Designer</p>
  </div>
</div>
```

This renders a card with flexbox layout, centered items, a gap between children, padding, white background, rounded corners, and a shadow. No custom CSS written.

### 4.2 Layout Utilities

#### Flexbox

```html
<!-- Row layout (default) -->
<div class="flex gap-4">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

<!-- Column layout -->
<div class="flex flex-col gap-2">
  <div>Row 1</div>
  <div>Row 2</div>
  <div>Row 3</div>
</div>

<!-- Center content -->
<div class="flex items-center justify-center h-screen">
  <p>Perfectly centered</p>
</div>

<!-- Space between -->
<nav class="flex items-center justify-between px-6 py-4">
  <div class="text-xl font-bold">Logo</div>
  <div class="flex gap-6">
    <a href="#">Home</a>
    <a href="#">About</a>
    <a href="#">Contact</a>
  </div>
</nav>

<!-- Wrap items -->
<div class="flex flex-wrap gap-2">
  <span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full">Tag 1</span>
  <span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full">Tag 2</span>
  <span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full">Tag 3</span>
</div>

<!-- Flex grow and shrink -->
<div class="flex">
  <div class="w-64 shrink-0">Sidebar</div>
  <div class="grow">Main content</div>
</div>
```

#### Grid

```html
<!-- Basic grid -->
<div class="grid grid-cols-3 gap-4">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

<!-- Responsive grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  <div>Card 1</div>
  <div>Card 2</div>
  <div>Card 3</div>
</div>

<!-- Spanning columns -->
<div class="grid grid-cols-4 gap-4">
  <div class="col-span-2">Wide item</div>
  <div>Normal</div>
  <div>Normal</div>
</div>

<!-- Auto-fit columns -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
  <div>Auto-sized card</div>
  <div>Auto-sized card</div>
  <div>Auto-sized card</div>
</div>
```

#### Container

```html
<div class="container mx-auto px-4">
  <!-- Constrained-width content centered on the page -->
</div>
```

#### Position

```html
<!-- Sticky header -->
<header class="sticky top-0 z-50 bg-white shadow-sm">
  <nav class="container mx-auto px-4 py-3">...</nav>
</header>

<!-- Absolute positioning -->
<div class="relative">
  <img src="hero.jpg" class="w-full h-96 object-cover">
  <div class="absolute inset-0 bg-black/50 flex items-center justify-center">
    <h1 class="text-4xl font-bold text-white">Hero Title</h1>
  </div>
</div>

<!-- Fixed footer -->
<footer class="fixed bottom-0 inset-x-0 bg-gray-900 text-white p-4">
  Fixed footer content
</footer>
```

### 4.3 Spacing Utilities

Tailwind's spacing scale uses a consistent 0.25rem (4px) increment by default.

| Class | CSS | Pixels (at 16px base) |
|---|---|---|
| `p-0` | `padding: 0` | 0px |
| `p-px` | `padding: 1px` | 1px |
| `p-0.5` | `padding: 0.125rem` | 2px |
| `p-1` | `padding: 0.25rem` | 4px |
| `p-2` | `padding: 0.5rem` | 8px |
| `p-3` | `padding: 0.75rem` | 12px |
| `p-4` | `padding: 1rem` | 16px |
| `p-6` | `padding: 1.5rem` | 24px |
| `p-8` | `padding: 2rem` | 32px |
| `p-12` | `padding: 3rem` | 48px |
| `p-16` | `padding: 4rem` | 64px |
| `p-24` | `padding: 6rem` | 96px |
| `p-32` | `padding: 8rem` | 128px |
| `p-48` | `padding: 12rem` | 192px |
| `p-64` | `padding: 16rem` | 256px |

The same scale applies to margin (`m-*`), gap (`gap-*`), width (`w-*`), height (`h-*`), `top`/`right`/`bottom`/`left` inset utilities, and more.

#### Directional Spacing

```html
<!-- All sides -->
<div class="p-4 m-4">...</div>

<!-- Horizontal / Vertical -->
<div class="px-6 py-4 mx-auto my-8">...</div>

<!-- Individual sides -->
<div class="pt-2 pr-4 pb-6 pl-8 mt-4 mr-2 mb-6 ml-0">...</div>

<!-- Logical properties (start/end for RTL support) -->
<div class="ps-4 pe-6 ms-2 me-4">...</div>
```

#### Negative Margins

Prefix with a dash:

```html
<div class="-mt-4 -mx-2">Overlapping content</div>
```

#### Space Between Children

```html
<div class="space-y-4">
  <p>First paragraph</p>
  <p>Second paragraph (4 spacing units below first)</p>
  <p>Third paragraph (4 spacing units below second)</p>
</div>

<div class="flex space-x-3">
  <button>One</button>
  <button>Two</button>
  <button>Three</button>
</div>
```

### 4.4 Typography Utilities

#### Font Size

```html
<p class="text-xs">Extra small (0.75rem / 12px)</p>
<p class="text-sm">Small (0.875rem / 14px)</p>
<p class="text-base">Base (1rem / 16px)</p>
<p class="text-lg">Large (1.125rem / 18px)</p>
<p class="text-xl">Extra large (1.25rem / 20px)</p>
<p class="text-2xl">2XL (1.5rem / 24px)</p>
<p class="text-3xl">3XL (1.875rem / 30px)</p>
<p class="text-4xl">4XL (2.25rem / 36px)</p>
<p class="text-5xl">5XL (3rem / 48px)</p>
<p class="text-6xl">6XL (3.75rem / 60px)</p>
<p class="text-7xl">7XL (4.5rem / 72px)</p>
<p class="text-8xl">8XL (6rem / 96px)</p>
<p class="text-9xl">9XL (8rem / 128px)</p>
```

#### Font Weight

```html
<p class="font-thin">Thin (100)</p>
<p class="font-light">Light (300)</p>
<p class="font-normal">Normal (400)</p>
<p class="font-medium">Medium (500)</p>
<p class="font-semibold">Semibold (600)</p>
<p class="font-bold">Bold (700)</p>
<p class="font-extrabold">Extrabold (800)</p>
<p class="font-black">Black (900)</p>
```

#### Font Family

```html
<p class="font-sans">Sans-serif text</p>
<p class="font-serif">Serif text</p>
<p class="font-mono">Monospace text</p>
```

#### Text Color

```html
<p class="text-gray-900">Dark text</p>
<p class="text-gray-500">Muted text</p>
<p class="text-blue-600">Accent text</p>
<p class="text-red-500">Error text</p>
<p class="text-white">White text</p>
```

#### Text Alignment

```html
<p class="text-left">Left-aligned</p>
<p class="text-center">Centered</p>
<p class="text-right">Right-aligned</p>
<p class="text-justify">Justified text</p>
```

#### Text Decoration

```html
<a class="underline">Underlined link</a>
<a class="no-underline">No underline</a>
<p class="line-through">Strikethrough</p>
<p class="underline decoration-blue-500 decoration-2">Custom underline</p>
<p class="underline decoration-wavy decoration-red-500">Wavy underline</p>
<p class="underline underline-offset-4">Offset underline</p>
```

#### Text Transform

```html
<p class="uppercase">UPPERCASE</p>
<p class="lowercase">lowercase</p>
<p class="capitalize">Capitalize Each Word</p>
<p class="normal-case">Normal Case</p>
```

#### Line Height (Leading)

```html
<p class="leading-none">Tight (1)</p>
<p class="leading-tight">Tight (1.25)</p>
<p class="leading-snug">Snug (1.375)</p>
<p class="leading-normal">Normal (1.5)</p>
<p class="leading-relaxed">Relaxed (1.625)</p>
<p class="leading-loose">Loose (2)</p>
```

#### Letter Spacing (Tracking)

```html
<p class="tracking-tighter">Tighter</p>
<p class="tracking-tight">Tight</p>
<p class="tracking-normal">Normal</p>
<p class="tracking-wide">Wide</p>
<p class="tracking-wider">Wider</p>
<p class="tracking-widest">Widest</p>
```

#### Text Overflow

```html
<!-- Truncate with ellipsis -->
<p class="truncate w-64">
  This very long text will be truncated with an ellipsis...
</p>

<!-- Line clamp (multi-line truncation) -->
<p class="line-clamp-3">
  This text will show at most 3 lines and then be
  truncated with an ellipsis at the end of the third line.
</p>
```

#### Whitespace

```html
<p class="whitespace-nowrap">Text that won't wrap</p>
<p class="whitespace-pre">Preserves    whitespace</p>
<p class="whitespace-pre-line">Preserves line breaks only</p>
<p class="whitespace-pre-wrap">Preserves whitespace and wraps</p>
<p class="break-words">Break words to prevent overflow</p>
<p class="break-all">Break at any character</p>
```

### 4.5 Color Utilities

Colors apply to many properties. Each color in your theme generates utilities across all color-aware properties:

```html
<!-- Text color -->
<p class="text-blue-600">Blue text</p>

<!-- Background color -->
<div class="bg-gray-100">Gray background</div>

<!-- Border color -->
<div class="border border-gray-300">Gray border</div>

<!-- Ring color (focus rings) -->
<button class="ring-2 ring-blue-500">Focused button</button>

<!-- Divide color -->
<div class="divide-y divide-gray-200">
  <div>Item 1</div>
  <div>Item 2</div>
</div>

<!-- Outline color -->
<button class="outline-2 outline-blue-500">Outlined button</button>

<!-- Placeholder color -->
<input class="placeholder-gray-400" placeholder="Enter text...">

<!-- Accent color (for form elements) -->
<input type="checkbox" class="accent-blue-600">

<!-- Caret color -->
<input class="caret-blue-600" type="text">

<!-- Shadow color -->
<div class="shadow-lg shadow-blue-500/20">Blue-tinted shadow</div>
```

#### Opacity Modifier

Apply opacity to any color utility with the `/` syntax:

```html
<div class="bg-blue-500/50">50% opacity blue background</div>
<div class="bg-black/75">75% opacity black overlay</div>
<p class="text-red-600/80">80% opacity red text</p>
<div class="border border-gray-900/10">10% opacity border</div>
```

The number after `/` is the opacity percentage (0-100).

#### Current Color and Inherit

```html
<p class="text-blue-600">
  <a class="text-current underline">Inherits parent blue</a>
</p>
<p class="text-inherit">Inherits from CSS cascade</p>
```

### 4.6 Background Utilities

```html
<!-- Solid colors -->
<div class="bg-white">White</div>
<div class="bg-gray-50">Light gray</div>
<div class="bg-transparent">Transparent</div>

<!-- Gradients -->
<div class="bg-gradient-to-r from-blue-500 to-purple-600">
  Left to right gradient
</div>
<div class="bg-gradient-to-br from-green-400 via-blue-500 to-purple-600">
  Diagonal gradient with midpoint
</div>

<!-- Background size -->
<div class="bg-cover bg-center" style="background-image: url('hero.jpg')">
  Cover image
</div>
<div class="bg-contain bg-no-repeat bg-center">
  Contained image
</div>

<!-- Background position -->
<div class="bg-top">Top</div>
<div class="bg-center">Center</div>
<div class="bg-bottom">Bottom</div>
<div class="bg-left-top">Top left</div>
```

### 4.7 Border Utilities

```html
<!-- Border width -->
<div class="border">1px border all sides</div>
<div class="border-2">2px border</div>
<div class="border-4">4px border</div>
<div class="border-t-2">2px top border only</div>
<div class="border-b">1px bottom border</div>
<div class="border-x-2">2px horizontal borders</div>
<div class="border-y">1px vertical borders</div>

<!-- Border color -->
<div class="border border-gray-300">Gray border</div>
<div class="border-2 border-blue-500">Blue border</div>

<!-- Border style -->
<div class="border-solid">Solid</div>
<div class="border-dashed">Dashed</div>
<div class="border-dotted">Dotted</div>
<div class="border-none">No border</div>

<!-- Border radius -->
<div class="rounded">Default radius</div>
<div class="rounded-md">Medium radius</div>
<div class="rounded-lg">Large radius</div>
<div class="rounded-xl">Extra-large radius</div>
<div class="rounded-2xl">2XL radius</div>
<div class="rounded-full">Full (pill/circle)</div>
<div class="rounded-none">No radius</div>
<div class="rounded-t-lg">Top corners only</div>
<div class="rounded-b-lg">Bottom corners only</div>
<div class="rounded-l-lg">Left corners only</div>
<div class="rounded-r-lg">Right corners only</div>

<!-- Ring (outline ring) -->
<button class="ring-2 ring-blue-500 ring-offset-2">Focus ring</button>

<!-- Divide (borders between children) -->
<div class="divide-y divide-gray-200">
  <div class="py-3">Item 1</div>
  <div class="py-3">Item 2</div>
  <div class="py-3">Item 3</div>
</div>
```

### 4.8 Shadow Utilities

```html
<div class="shadow-sm">Small shadow</div>
<div class="shadow">Default shadow</div>
<div class="shadow-md">Medium shadow</div>
<div class="shadow-lg">Large shadow</div>
<div class="shadow-xl">Extra-large shadow</div>
<div class="shadow-2xl">2XL shadow</div>
<div class="shadow-none">No shadow</div>

<!-- Colored shadows -->
<div class="shadow-lg shadow-blue-500/25">Blue tinted shadow</div>

<!-- Inset shadows -->
<div class="inset-shadow-sm">Small inset shadow</div>
```

### 4.9 Sizing Utilities

#### Width

```html
<div class="w-full">100% width</div>
<div class="w-1/2">50% width</div>
<div class="w-1/3">33.33% width</div>
<div class="w-2/3">66.67% width</div>
<div class="w-1/4">25% width</div>
<div class="w-64">16rem width</div>
<div class="w-screen">100vw width</div>
<div class="w-auto">Auto width</div>
<div class="w-fit">Fit-content width</div>
<div class="w-min">Min-content width</div>
<div class="w-max">Max-content width</div>

<!-- Min/Max width -->
<div class="min-w-0">Min-width 0</div>
<div class="min-w-full">Min-width 100%</div>
<div class="max-w-sm">Max-width 24rem</div>
<div class="max-w-md">Max-width 28rem</div>
<div class="max-w-lg">Max-width 32rem</div>
<div class="max-w-xl">Max-width 36rem</div>
<div class="max-w-2xl">Max-width 42rem</div>
<div class="max-w-prose">Max-width 65ch</div>
<div class="max-w-none">No max-width</div>
```

#### Height

```html
<div class="h-full">100% height</div>
<div class="h-screen">100vh height</div>
<div class="h-dvh">100dvh (dynamic viewport height)</div>
<div class="h-svh">100svh (small viewport height)</div>
<div class="h-lvh">100lvh (large viewport height)</div>
<div class="h-64">16rem height</div>
<div class="h-auto">Auto height</div>
<div class="h-fit">Fit-content height</div>

<!-- Min/Max height -->
<div class="min-h-screen">Min-height 100vh</div>
<div class="min-h-full">Min-height 100%</div>
<div class="max-h-96">Max-height 24rem</div>
```

#### Size (Width + Height)

```html
<div class="size-8">2rem width and height</div>
<div class="size-12">3rem width and height</div>
<div class="size-full">100% width and height</div>
```

### 4.10 Variants (Responsive, State, Dark Mode)

Variants are modifiers you prepend to any utility class with a colon `:`. They apply the utility conditionally.

#### Responsive Variants

Tailwind uses a mobile-first breakpoint system. Unprefixed utilities apply at all screen sizes. Prefixed utilities apply at that breakpoint and above.

Default breakpoints:

| Breakpoint | Min Width | CSS |
|---|---|---|
| `sm:` | 40rem (640px) | `@media (min-width: 40rem)` |
| `md:` | 48rem (768px) | `@media (min-width: 48rem)` |
| `lg:` | 64rem (1024px) | `@media (min-width: 64rem)` |
| `xl:` | 80rem (1280px) | `@media (min-width: 80rem)` |
| `2xl:` | 96rem (1536px) | `@media (min-width: 96rem)` |

```html
<!-- Single column on mobile, two columns on medium, three on large -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  <div>Card 1</div>
  <div>Card 2</div>
  <div>Card 3</div>
</div>

<!-- Hidden on mobile, visible on large screens -->
<nav class="hidden lg:flex gap-6">
  <a href="#">Home</a>
  <a href="#">About</a>
</nav>

<!-- Different padding at different breakpoints -->
<div class="p-4 md:p-8 lg:p-12">
  Responsive padding
</div>

<!-- Different text size at breakpoints -->
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold">
  Responsive heading
</h1>
```

#### Hover, Focus, and Other State Variants

```html
<!-- Hover -->
<button class="bg-blue-500 hover:bg-blue-700 text-white px-4 py-2 rounded">
  Hover me
</button>

<!-- Focus -->
<input class="border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none px-3 py-2 rounded">

<!-- Focus-visible (keyboard focus only) -->
<button class="focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:outline-none">
  Keyboard focus ring
</button>

<!-- Active -->
<button class="bg-blue-500 active:bg-blue-800">Press me</button>

<!-- Disabled -->
<button class="bg-blue-500 disabled:bg-gray-300 disabled:cursor-not-allowed" disabled>
  Disabled
</button>

<!-- First/Last child -->
<ul>
  <li class="first:pt-0 last:pb-0 py-2 border-b last:border-b-0">Item</li>
</ul>

<!-- Odd/Even -->
<tr class="odd:bg-gray-50 even:bg-white">
  <td>Row content</td>
</tr>

<!-- Required/Invalid/Valid -->
<input class="invalid:border-red-500 valid:border-green-500" required>

<!-- Checked -->
<input type="checkbox" class="checked:bg-blue-500">

<!-- Placeholder shown -->
<input class="placeholder-shown:border-gray-300">
```

#### Group and Peer Variants

Style children based on parent state:

```html
<!-- Group hover -->
<a class="group block p-6 bg-white rounded-lg shadow hover:shadow-lg transition">
  <h3 class="text-gray-900 group-hover:text-blue-600 font-semibold">
    Card Title
  </h3>
  <p class="text-gray-500 group-hover:text-gray-700">
    Card description text
  </p>
</a>

<!-- Group focus -->
<label class="group">
  <input type="text" class="border rounded px-3 py-2">
  <span class="text-gray-400 group-focus-within:text-blue-500">
    Helper text
  </span>
</label>

<!-- Named groups -->
<div class="group/sidebar">
  <button class="group-hover/sidebar:bg-gray-100">Toggle</button>
</div>
```

Style siblings based on sibling state:

```html
<!-- Peer (sibling-based styling) -->
<div>
  <input type="email" class="peer" placeholder="Email">
  <p class="hidden peer-invalid:block text-red-500 text-sm mt-1">
    Please enter a valid email address.
  </p>
</div>
```

#### Dark Mode

```html
<!-- Dark mode variants -->
<div class="bg-white dark:bg-gray-900">
  <h1 class="text-gray-900 dark:text-white">Heading</h1>
  <p class="text-gray-600 dark:text-gray-300">Body text</p>
</div>

<!-- Card with dark mode -->
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-6 shadow dark:shadow-gray-900/20">
  <h3 class="text-gray-900 dark:text-gray-100 font-semibold">Card</h3>
  <p class="text-gray-500 dark:text-gray-400 mt-2">Card content</p>
</div>
```

Dark mode uses the `prefers-color-scheme` media query by default.

#### Print Variant

```html
<div class="print:hidden">Hidden when printing</div>
<div class="hidden print:block">Visible only when printing</div>
```

#### Motion Variants

```html
<!-- Respect user's motion preferences -->
<div class="transition-transform motion-safe:hover:scale-105 motion-reduce:transition-none">
  Animated on hover (unless user prefers reduced motion)
</div>
```

#### Portrait and Landscape

```html
<div class="portrait:hidden">Hidden in portrait orientation</div>
<div class="landscape:hidden">Hidden in landscape orientation</div>
```

#### RTL and LTR

```html
<div class="rtl:text-right ltr:text-left">
  Direction-aware alignment
</div>
```

#### Container Queries

```html
<div class="@container">
  <div class="@sm:flex @lg:grid @lg:grid-cols-2 gap-4">
    Container-query responsive layout
  </div>
</div>
```

#### Stacking Variants

Variants can be stacked. They read left to right:

```html
<!-- Dark mode + hover + medium breakpoint -->
<button class="md:dark:hover:bg-blue-800">
  Hover on medium+ screens in dark mode
</button>

<!-- Focus-within on large screens -->
<div class="lg:focus-within:ring-2 lg:focus-within:ring-blue-500">
  Focus ring on large screens
</div>
```

### 4.11 Arbitrary Values

When the default utilities do not provide the exact value you need, use square bracket notation:

```html
<!-- Arbitrary values -->
<div class="w-[137px]">Exact width</div>
<div class="h-[calc(100vh-4rem)]">Calculated height</div>
<div class="bg-[#1da1f2]">Exact hex color</div>
<div class="text-[22px]">Exact font size</div>
<div class="grid-cols-[200px_1fr_200px]">Custom grid template</div>
<div class="top-[117px]">Exact positioning</div>
<div class="p-[clamp(1rem,5vw,3rem)]">Clamped padding</div>

<!-- Arbitrary properties (for any CSS property) -->
<div class="[mask-type:luminance]">Arbitrary CSS property</div>
<div class="[--my-var:16px]">Set a custom property</div>

<!-- Arbitrary variants -->
<div class="[&>p]:text-gray-600">Direct child paragraphs</div>
<div class="[@supports(display:grid)]:grid">Supports query</div>
<div class="[@media(min-width:900px)]:flex">Custom media query</div>
```

Underscores in arbitrary values are treated as spaces:

```html
<!-- Underscore = space -->
<div class="bg-[url('/image_with_space.jpg')]">Background image</div>
<div class="grid-cols-[1fr_auto_1fr]">Grid columns: 1fr auto 1fr</div>
```

To use an actual underscore, escape it with a backslash:

```html
<div class="bg-[url('/image\_name.jpg')]">Literal underscore in value</div>
```

### 4.12 The `@apply` Directive

The `@apply` directive lets you use utility classes inside your CSS:

```css
.btn {
  @apply px-4 py-2 rounded-lg font-semibold text-sm transition-colors;
}

.btn-primary {
  @apply btn bg-blue-500 text-white hover:bg-blue-700;
}

.btn-secondary {
  @apply btn bg-gray-200 text-gray-800 hover:bg-gray-300;
}
```

```css
/* Card component */
.card {
  @apply bg-white rounded-xl shadow-md p-6 border border-gray-100;
}

.card-title {
  @apply text-xl font-semibold text-gray-900 mb-2;
}

.card-body {
  @apply text-gray-600 leading-relaxed;
}
```

#### `@apply` Limitations

- Cannot use `@apply` inside `@keyframes` blocks. Attempting to do so produces: `You cannot use @apply inside @keyframes.`
- If you reference a utility that does not exist, you get: `Cannot apply unknown utility class '{candidate}'`
- If your project uses a prefix and you forget it: `Cannot apply unprefixed utility class '{candidate}'. Did you mean '{prefix}:{candidate}'?`
- Circular references produce: `Cannot apply utility class '{candidate}' because it creates a circular dependency.`

> [!NOTE]
> While `@apply` is useful for extracting repeated patterns, Tailwind's recommended approach is to use component abstractions in your framework (React components, Vue components, partials, etc.) rather than creating CSS classes with `@apply`. Reserve `@apply` for cases where you cannot use component abstractions, such as styling third-party markup or CMS content.

### 4.13 Custom Utilities with `@utility`

Define entirely new utility classes:

```css
@utility content-auto {
  content-visibility: auto;
}

@utility scrollbar-hidden {
  scrollbar-width: none;
  &::-webkit-scrollbar {
    display: none;
  }
}

@utility text-balance {
  text-wrap: balance;
}
```

These become available as regular utility classes:

```html
<div class="content-auto">Lazy-rendered content</div>
<div class="scrollbar-hidden overflow-y-auto">No visible scrollbar</div>
<h1 class="text-balance text-4xl">Balanced headline text</h1>
```

Custom utilities support variants:

```html
<div class="md:content-auto hover:content-auto">
  Variant-aware custom utility
</div>
```

#### Functional Utilities with Values

```css
@utility tab-size-* {
  tab-size: --value(--tab-size-*);
}
```

This generates `tab-size-2`, `tab-size-4`, `tab-size-8`, etc., from your theme.

### 4.14 Custom Variants with `@variant`

Define new variants for conditional styling.

#### Selector-Based Variant

```css
@variant pointer-coarse (@media (pointer: coarse));
@variant pointer-fine (@media (pointer: fine));
```

Usage:

```html
<button class="pointer-coarse:p-4 pointer-fine:p-2">
  Larger padding on touch devices
</button>
```

#### Complex Selector Variants

```css
@variant hocus (&:hover, &:focus);
```

```html
<button class="hocus:bg-blue-600">Hover or focus</button>
```

### 4.15 Transition and Animation

```html
<!-- Basic transition -->
<button class="transition-colors duration-200 hover:bg-blue-600">
  Smooth color change
</button>

<!-- Multiple transition properties -->
<div class="transition-all duration-300 ease-in-out hover:scale-105 hover:shadow-lg">
  Scale and shadow on hover
</div>

<!-- Specific transition durations -->
<div class="transition duration-75">75ms</div>
<div class="transition duration-100">100ms</div>
<div class="transition duration-150">150ms (default)</div>
<div class="transition duration-200">200ms</div>
<div class="transition duration-300">300ms</div>
<div class="transition duration-500">500ms</div>
<div class="transition duration-700">700ms</div>
<div class="transition duration-1000">1000ms</div>

<!-- Transition delay -->
<div class="transition delay-150 hover:bg-blue-500">150ms delay</div>

<!-- Easing functions -->
<div class="transition ease-linear">Linear</div>
<div class="transition ease-in">Ease in</div>
<div class="transition ease-out">Ease out</div>
<div class="transition ease-in-out">Ease in-out</div>

<!-- Built-in animations -->
<div class="animate-spin">Spinning</div>
<div class="animate-ping">Pinging</div>
<div class="animate-pulse">Pulsing</div>
<div class="animate-bounce">Bouncing</div>
```

### 4.16 Transforms

```html
<!-- Scale -->
<div class="scale-95">95% scale</div>
<div class="hover:scale-105">105% on hover</div>
<div class="scale-x-110 scale-y-90">Different X/Y scale</div>

<!-- Rotate -->
<div class="rotate-45">45 degrees</div>
<div class="-rotate-12">-12 degrees</div>
<div class="hover:rotate-6">Rotate on hover</div>

<!-- Translate -->
<div class="translate-x-4">Move right 1rem</div>
<div class="-translate-y-2">Move up 0.5rem</div>
<div class="hover:translate-y-1">Move down on hover</div>

<!-- Skew -->
<div class="skew-x-3">Skew X 3 degrees</div>
<div class="skew-y-6">Skew Y 6 degrees</div>

<!-- Transform origin -->
<div class="origin-top-left rotate-12">Rotate from top-left corner</div>
<div class="origin-center scale-150">Scale from center</div>
```

### 4.17 Filters and Effects

```html
<!-- Blur -->
<div class="blur-sm">Slight blur</div>
<div class="blur-md">Medium blur</div>
<div class="blur-lg">Large blur</div>
<div class="blur-none">No blur</div>

<!-- Brightness -->
<img class="brightness-50" src="photo.jpg">
<img class="brightness-110" src="photo.jpg">

<!-- Contrast -->
<img class="contrast-125" src="photo.jpg">

<!-- Grayscale -->
<img class="grayscale" src="photo.jpg">
<img class="grayscale-0" src="photo.jpg">

<!-- Hue rotate -->
<img class="hue-rotate-90" src="photo.jpg">

<!-- Invert -->
<img class="invert" src="photo.jpg">

<!-- Saturate -->
<img class="saturate-150" src="photo.jpg">

<!-- Sepia -->
<img class="sepia" src="photo.jpg">

<!-- Drop shadow -->
<img class="drop-shadow-lg" src="icon.png">
<img class="drop-shadow-xl" src="icon.png">

<!-- Backdrop blur (glassmorphism) -->
<div class="backdrop-blur-md bg-white/30">
  Frosted glass effect
</div>

<!-- Backdrop brightness -->
<div class="backdrop-brightness-75">Darkened backdrop</div>

<!-- Opacity -->
<div class="opacity-50">50% opacity</div>
<div class="opacity-0">Invisible (but in DOM)</div>
<div class="hover:opacity-100 transition-opacity">Fade in on hover</div>

<!-- Mix blend mode -->
<div class="mix-blend-multiply">Multiply blend</div>
<div class="mix-blend-screen">Screen blend</div>
<div class="mix-blend-overlay">Overlay blend</div>
```

### 4.18 Overflow and Scroll

```html
<!-- Overflow -->
<div class="overflow-auto">Auto scrollbar when needed</div>
<div class="overflow-hidden">Hidden overflow</div>
<div class="overflow-scroll">Always show scrollbar</div>
<div class="overflow-x-auto">Horizontal scroll when needed</div>
<div class="overflow-y-auto">Vertical scroll when needed</div>
<div class="overflow-visible">Visible overflow</div>
<div class="overflow-clip">Clip overflow (no scroll)</div>

<!-- Scroll behavior -->
<div class="scroll-smooth">Smooth scrolling</div>

<!-- Scroll snap -->
<div class="snap-x snap-mandatory overflow-x-auto flex gap-4">
  <div class="snap-center shrink-0 w-80">Slide 1</div>
  <div class="snap-center shrink-0 w-80">Slide 2</div>
  <div class="snap-center shrink-0 w-80">Slide 3</div>
</div>

<!-- Scroll padding/margin -->
<div class="scroll-pt-16">16rem scroll padding-top</div>
<div class="scroll-mt-4">4 scroll margin-top</div>

<!-- Overscroll behavior -->
<div class="overscroll-contain">Contain overscroll</div>
<div class="overscroll-none">No overscroll</div>
```

### 4.19 Interactivity

```html
<!-- Cursor -->
<div class="cursor-pointer">Pointer cursor</div>
<div class="cursor-not-allowed">Not-allowed cursor</div>
<div class="cursor-wait">Wait cursor</div>
<div class="cursor-grab">Grab cursor</div>
<div class="cursor-move">Move cursor</div>
<div class="cursor-text">Text cursor</div>
<div class="cursor-default">Default cursor</div>

<!-- Pointer events -->
<div class="pointer-events-none">Click-through</div>
<div class="pointer-events-auto">Normal pointer events</div>

<!-- User select -->
<p class="select-none">Cannot be selected</p>
<p class="select-text">Can be selected</p>
<p class="select-all">Select all on click</p>

<!-- Touch action -->
<div class="touch-none">Disable touch gestures</div>
<div class="touch-pan-x">Allow horizontal panning only</div>
<div class="touch-pan-y">Allow vertical panning only</div>
<div class="touch-manipulation">Allow pan and zoom only</div>

<!-- Resize -->
<textarea class="resize">Resizable both ways</textarea>
<textarea class="resize-x">Horizontal resize only</textarea>
<textarea class="resize-y">Vertical resize only</textarea>
<textarea class="resize-none">No resize</textarea>

<!-- Appearance -->
<select class="appearance-none">Remove native appearance</select>

<!-- Caret color -->
<input class="caret-blue-500" type="text">

<!-- Accent color (for checkboxes, radios, range) -->
<input type="checkbox" class="accent-pink-500">
<input type="range" class="accent-green-600">

<!-- Will-change (performance hint) -->
<div class="will-change-transform">Optimize for transform changes</div>
<div class="will-change-scroll">Optimize for scroll changes</div>
```

### 4.20 Tables

```html
<table class="w-full border-collapse">
  <thead>
    <tr class="bg-gray-50 text-left">
      <th class="px-4 py-3 text-sm font-semibold text-gray-600 border-b">Name</th>
      <th class="px-4 py-3 text-sm font-semibold text-gray-600 border-b">Status</th>
      <th class="px-4 py-3 text-sm font-semibold text-gray-600 border-b">Role</th>
    </tr>
  </thead>
  <tbody class="divide-y divide-gray-200">
    <tr class="hover:bg-gray-50">
      <td class="px-4 py-3 text-sm text-gray-900">Jane Cooper</td>
      <td class="px-4 py-3">
        <span class="inline-flex items-center rounded-full bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-green-600/20 ring-inset">Active</span>
      </td>
      <td class="px-4 py-3 text-sm text-gray-500">Admin</td>
    </tr>
    <tr class="hover:bg-gray-50">
      <td class="px-4 py-3 text-sm text-gray-900">John Smith</td>
      <td class="px-4 py-3">
        <span class="inline-flex items-center rounded-full bg-yellow-50 px-2 py-1 text-xs font-medium text-yellow-700 ring-1 ring-yellow-600/20 ring-inset">Pending</span>
      </td>
      <td class="px-4 py-3 text-sm text-gray-500">Editor</td>
    </tr>
  </tbody>
</table>

<!-- Table layout -->
<table class="table-fixed w-full">Fixed layout</table>
<table class="table-auto">Auto layout</table>

<!-- Caption side -->
<table>
  <caption class="caption-bottom text-sm text-gray-500">Table caption</caption>
</table>
```

### 4.21 SVG

```html
<!-- Fill -->
<svg class="fill-current text-blue-500">...</svg>
<svg class="fill-blue-500">...</svg>
<svg class="fill-none">...</svg>

<!-- Stroke -->
<svg class="stroke-current text-gray-400">...</svg>
<svg class="stroke-blue-500">...</svg>
<svg class="stroke-2">2px stroke width</svg>
<svg class="stroke-[3px]">3px stroke width</svg>
```

### 4.22 Accessibility

```html
<!-- Screen reader only (visually hidden but accessible) -->
<span class="sr-only">Screen reader text</span>

<!-- Undo sr-only (useful with focus) -->
<a class="sr-only focus:not-sr-only focus:absolute focus:p-4 focus:bg-white">
  Skip to content
</a>

<!-- Focus management -->
<button class="focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500">
  Keyboard-accessible focus ring
</button>

<!-- Forced colors (Windows high contrast) -->
<div class="forced-colors:border forced-colors:border-current">
  High contrast border
</div>
```

---

## 5. Common Tasks

### 5.1 Building a Responsive Navigation Bar

```html
<nav class="bg-white shadow-sm border-b border-gray-100">
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <div class="flex items-center justify-between h-16">
      <!-- Logo -->
      <a href="/" class="text-xl font-bold text-gray-900">
        MyApp
      </a>

      <!-- Desktop navigation -->
      <div class="hidden md:flex items-center gap-8">
        <a href="#" class="text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors">
          Features
        </a>
        <a href="#" class="text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors">
          Pricing
        </a>
        <a href="#" class="text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors">
          Docs
        </a>
        <a href="#" class="text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg transition-colors">
          Sign Up
        </a>
      </div>

      <!-- Mobile menu button -->
      <button class="md:hidden p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100">
        <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
        </svg>
      </button>
    </div>
  </div>

  <!-- Mobile menu (toggle visibility with JS) -->
  <div class="md:hidden border-t border-gray-100">
    <div class="px-4 py-3 space-y-2">
      <a href="#" class="block px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-md">Features</a>
      <a href="#" class="block px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-md">Pricing</a>
      <a href="#" class="block px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-md">Docs</a>
      <a href="#" class="block px-3 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md text-center">Sign Up</a>
    </div>
  </div>
</nav>
```

### 5.2 Building a Card Component

```html
<!-- Basic card -->
<div class="bg-white rounded-xl shadow-md overflow-hidden max-w-md">
  <img class="w-full h-48 object-cover" src="image.jpg" alt="Card image">
  <div class="p-6">
    <span class="text-xs font-semibold uppercase tracking-wider text-blue-600">Category</span>
    <h3 class="mt-2 text-xl font-bold text-gray-900">Card Title</h3>
    <p class="mt-2 text-gray-600 line-clamp-3">
      Card description text that can be truncated to three lines maximum.
    </p>
    <div class="mt-4 flex items-center justify-between">
      <span class="text-sm text-gray-500">5 min read</span>
      <a href="#" class="text-sm font-semibold text-blue-600 hover:text-blue-800">
        Read more &rarr;
      </a>
    </div>
  </div>
</div>

<!-- Horizontal card -->
<div class="flex bg-white rounded-xl shadow-md overflow-hidden max-w-2xl">
  <img class="w-48 object-cover shrink-0" src="image.jpg" alt="">
  <div class="p-6">
    <h3 class="text-lg font-bold text-gray-900">Horizontal Card</h3>
    <p class="mt-2 text-gray-600">Description text here.</p>
  </div>
</div>
```

### 5.3 Building Form Elements

```html
<!-- Text input -->
<div>
  <label for="email" class="block text-sm font-medium text-gray-700 mb-1">
    Email address
  </label>
  <input
    id="email"
    type="email"
    class="w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm
           placeholder-gray-400
           focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500
           disabled:bg-gray-50 disabled:text-gray-500 disabled:cursor-not-allowed
           invalid:border-red-500 invalid:focus:ring-red-500"
    placeholder="[email removed]"
  >
</div>

<!-- Select -->
<div>
  <label class="block text-sm font-medium text-gray-700 mb-1">Country</label>
  <select class="w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm
                 bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
    <option>United States</option>
    <option>Canada</option>
    <option>Mexico</option>
  </select>
</div>

<!-- Textarea -->
<div>
  <label class="block text-sm font-medium text-gray-700 mb-1">Message</label>
  <textarea
    rows="4"
    class="w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm
           placeholder-gray-400 resize-y
           focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
    placeholder="Write your message..."
  ></textarea>
</div>

<!-- Checkbox -->
<label class="flex items-center gap-3">
  <input type="checkbox" class="w-4 h-4 rounded border-gray-300 text-blue-600 accent-blue-600
                                 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
  <span class="text-sm text-gray-700">I agree to the terms</span>
</label>

<!-- Radio group -->
<fieldset class="space-y-3">
  <legend class="text-sm font-medium text-gray-700">Plan</legend>
  <label class="flex items-center gap-3">
    <input type="radio" name="plan" class="w-4 h-4 border-gray-300 text-blue-600 accent-blue-600">
    <span class="text-sm text-gray-700">Free</span>
  </label>
  <label class="flex items-center gap-3">
    <input type="radio" name="plan" class="w-4 h-4 border-gray-300 text-blue-600 accent-blue-600">
    <span class="text-sm text-gray-700">Pro — $9/month</span>
  </label>
</fieldset>

<!-- Toggle switch pattern -->
<button
  role="switch"
  aria-checked="false"
  class="relative inline-flex h-6 w-11 items-center rounded-full
         bg-gray-200 transition-colors
         aria-checked:bg-blue-600"
>
  <span class="inline-block h-4 w-4 rounded-full bg-white shadow transform transition-transform
               translate-x-1 aria-checked:translate-x-6"></span>
</button>
```

### 5.4 Building a Hero Section

```html
<section class="relative bg-gray-900 overflow-hidden">
  <!-- Background pattern -->
  <div class="absolute inset-0 bg-gradient-to-br from-blue-600/20 to-purple-600/20"></div>

  <div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-24 sm:py-32 lg:py-40">
    <div class="max-w-3xl">
      <span class="inline-flex items-center rounded-full bg-blue-500/10 px-3 py-1 text-sm font-medium text-blue-400 ring-1 ring-blue-500/20 ring-inset mb-6">
        What's new &mdash; v4.2 released
      </span>
      <h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold text-white tracking-tight leading-tight">
        Build modern websites without ever leaving your HTML
      </h1>
      <p class="mt-6 text-lg sm:text-xl text-gray-300 leading-relaxed max-w-2xl">
        A utility-first CSS framework packed with classes that can be composed
        to build any design, directly in your markup.
      </p>
      <div class="mt-10 flex flex-wrap gap-4">
        <a href="#" class="inline-flex items-center px-6 py-3 text-sm font-semibold text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors shadow-lg shadow-blue-600/25">
          Get Started
        </a>
        <a href="#" class="inline-flex items-center px-6 py-3 text-sm font-semibold text-gray-300 bg-white/10 hover:bg-white/20 rounded-lg transition-colors ring-1 ring-white/20">
          Documentation &rarr;
        </a>
      </div>
    </div>
  </div>
</section>
```

### 5.5 Building a Pricing Table

```html
<div class="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-5xl mx-auto px-4">
  <!-- Free tier -->
  <div class="bg-white rounded-2xl border border-gray-200 p-8">
    <h3 class="text-lg font-semibold text-gray-900">Free</h3>
    <p class="mt-2 text-sm text-gray-500">For individuals getting started.</p>
    <p class="mt-6">
      <span class="text-4xl font-bold text-gray-900">$0</span>
      <span class="text-sm text-gray-500">/month</span>
    </p>
    <a href="#" class="mt-8 block w-full py-2.5 text-center text-sm font-semibold text-blue-600 bg-blue-50 hover:bg-blue-100 rounded-lg transition-colors">
      Get started
    </a>
    <ul class="mt-8 space-y-3">
      <li class="flex items-center gap-3 text-sm text-gray-600">
        <svg class="w-5 h-5 text-green-500 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
        5 projects
      </li>
      <li class="flex items-center gap-3 text-sm text-gray-600">
        <svg class="w-5 h-5 text-green-500 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
        Community support
      </li>
    </ul>
  </div>

  <!-- Pro tier (highlighted) -->
  <div class="bg-blue-600 rounded-2xl p-8 shadow-xl shadow-blue-600/20 ring-2 ring-blue-600 relative">
    <span class="absolute -top-4 left-1/2 -translate-x-1/2 bg-blue-600 text-white text-xs font-bold uppercase tracking-wider px-3 py-1 rounded-full">
      Popular
    </span>
    <h3 class="text-lg font-semibold text-white">Pro</h3>
    <p class="mt-2 text-sm text-blue-200">For professionals and small teams.</p>
    <p class="mt-6">
      <span class="text-4xl font-bold text-white">$29</span>
      <span class="text-sm text-blue-200">/month</span>
    </p>
    <a href="#" class="mt-8 block w-full py-2.5 text-center text-sm font-semibold text-blue-600 bg-white hover:bg-blue-50 rounded-lg transition-colors">
      Get started
    </a>
    <ul class="mt-8 space-y-3">
      <li class="flex items-center gap-3 text-sm text-blue-100">
        <svg class="w-5 h-5 text-blue-300 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
        Unlimited projects
      </li>
      <li class="flex items-center gap-3 text-sm text-blue-100">
        <svg class="w-5 h-5 text-blue-300 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
        Priority support
      </li>
      <li class="flex items-center gap-3 text-sm text-blue-100">
        <svg class="w-5 h-5 text-blue-300 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
        Advanced analytics
      </li>
    </ul>
  </div>

  <!-- Enterprise tier -->
  <div class="bg-white rounded-2xl border border-gray-200 p-8">
    <h3 class="text-lg font-semibold text-gray-900">Enterprise</h3>
    <p class="mt-2 text-sm text-gray-500">For large organizations.</p>
    <p class="mt-6">
      <span class="text-4xl font-bold text-gray-900">$99</span>
      <span class="text-sm text-gray-500">/month</span>
    </p>
    <a href="#" class="mt-8 block w-full py-2.5 text-center text-sm font-semibold text-blue-600 bg-blue-50 hover:bg-blue-100 rounded-lg transition-colors">
      Contact sales
    </a>
    <ul class="mt-8 space-y-3">
      <li class="flex items-center gap-3 text-sm text-gray-600">
        <svg class="w-5 h-5 text-green-500 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
        Everything in Pro
      </li>
      <li class="flex items-center gap-3 text-sm text-gray-600">
        <svg class="w-5 h-5 text-green-500 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
        SSO & SAML
      </li>
      <li class="flex items-center gap-3 text-sm text-gray-600">
        <svg class="w-5 h-5 text-green-500 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
        Dedicated support
      </li>
    </ul>
  </div>
</div>
```

### 5.6 Building a Modal / Dialog

```html
<!-- Backdrop -->
<div class="fixed inset-0 z-50 flex items-center justify-center">
  <!-- Overlay -->
  <div class="fixed inset-0 bg-black/50 backdrop-blur-sm"></div>

  <!-- Modal -->
  <div class="relative bg-white rounded-2xl shadow-2xl max-w-md w-full mx-4 p-6 z-10">
    <!-- Close button -->
    <button class="absolute top-4 right-4 text-gray-400 hover:text-gray-600">
      <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
      </svg>
    </button>

    <h2 class="text-lg font-semibold text-gray-900">Delete project?</h2>
    <p class="mt-2 text-sm text-gray-500">
      This action cannot be undone. All project data will be permanently removed.
    </p>

    <div class="mt-6 flex gap-3 justify-end">
      <button class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">
        Cancel
      </button>
      <button class="px-4 py-2 text-sm font-medium text-white bg-red-600 rounded-lg hover:bg-red-700 transition-colors">
        Delete
      </button>
    </div>
  </div>
</div>
```

### 5.7 Building a Sidebar Layout

```html
<div class="flex h-screen">
  <!-- Sidebar -->
  <aside class="w-64 shrink-0 bg-gray-900 text-white flex flex-col">
    <div class="p-6">
      <h2 class="text-lg font-bold">Dashboard</h2>
    </div>
    <nav class="flex-1 px-3 space-y-1 overflow-y-auto">
      <a href="#" class="flex items-center gap-3 px-3 py-2 text-sm font-medium text-white bg-gray-800 rounded-lg">
        <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/></svg>
        Home
      </a>
      <a href="#" class="flex items-center gap-3 px-3 py-2 text-sm font-medium text-gray-400 hover:text-white hover:bg-gray-800 rounded-lg transition-colors">
        <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/></svg>
        Analytics
      </a>
      <a href="#" class="flex items-center gap-3 px-3 py-2 text-sm font-medium text-gray-400 hover:text-white hover:bg-gray-800 rounded-lg transition-colors">
        <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
        Settings
      </a>
    </nav>
    <div class="p-4 border-t border-gray-800">
      <div class="flex items-center gap-3">
        <div class="w-8 h-8 rounded-full bg-gray-700"></div>
        <div>
          <p class="text-sm font-medium">Jane Smith</p>
          <p class="text-xs text-gray-400">[email removed]</p>
        </div>
      </div>
    </div>
  </aside>

  <!-- Main content -->
  <main class="flex-1 overflow-y-auto bg-gray-50">
    <div class="p-8">
      <h1 class="text-2xl font-bold text-gray-900">Dashboard</h1>
      <!-- Content here -->
    </div>
  </main>
</div>
```

### 5.8 Building a Notification / Toast

```html
<!-- Success toast -->
<div class="flex items-center gap-3 bg-white rounded-lg shadow-lg ring-1 ring-black/5 p-4 max-w-sm">
  <div class="shrink-0 w-10 h-10 bg-green-100 rounded-full flex items-center justify-center">
    <svg class="w-5 h-5 text-green-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
    </svg>
  </div>
  <div class="flex-1 min-w-0">
    <p class="text-sm font-semibold text-gray-900">Successfully saved!</p>
    <p class="text-sm text-gray-500 mt-0.5">Your changes have been saved.</p>
  </div>
  <button class="shrink-0 text-gray-400 hover:text-gray-600">
    <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
    </svg>
  </button>
</div>

<!-- Error alert -->
<div class="bg-red-50 border border-red-200 rounded-lg p-4">
  <div class="flex items-start gap-3">
    <svg class="w-5 h-5 text-red-500 mt-0.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
    </svg>
    <div>
      <h3 class="text-sm font-semibold text-red-800">Error occurred</h3>
      <p class="text-sm text-red-700 mt-1">Something went wrong. Please try again.</p>
    </div>
  </div>
</div>

<!-- Warning alert -->
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
  <div class="flex items-start gap-3">
    <svg class="w-5 h-5 text-yellow-500 mt-0.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
    </svg>
    <div>
      <h3 class="text-sm font-semibold text-yellow-800">Warning</h3>
      <p class="text-sm text-yellow-700 mt-1">Your trial expires in 3 days.</p>
    </div>
  </div>
</div>

<!-- Info alert -->
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
  <div class="flex items-start gap-3">
    <svg class="w-5 h-5 text-blue-500 mt-0.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
    </svg>
    <div>
      <h3 class="text-sm font-semibold text-blue-800">Information</h3>
      <p class="text-sm text-blue-700 mt-1">A new version is available.</p>
    </div>
  </div>
</div>
```

### 5.9 Building a Badge / Tag System

```html
<!-- Solid badges -->
<span class="inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-700">
  Badge
</span>
<span class="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-700">
  Active
</span>
<span class="inline-flex items-center rounded-full bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-700">
  Error
</span>
<span class="inline-flex items-center rounded-full bg-yellow-100 px-2.5 py-0.5 text-xs font-medium text-yellow-700">
  Pending
</span>
<span class="inline-flex items-center rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium text-gray-700">
  Draft
</span>

<!-- Ring badges -->
<span class="inline-flex items-center rounded-full bg-blue-50 px-2.5 py-0.5 text-xs font-medium text-blue-700 ring-1 ring-blue-600/20 ring-inset">
  Ring Badge
</span>

<!-- Dot badges -->
<span class="inline-flex items-center gap-1.5 rounded-full bg-green-50 px-2.5 py-0.5 text-xs font-medium text-green-700">
  <span class="w-1.5 h-1.5 rounded-full bg-green-500"></span>
  Online
</span>

<!-- Removable tags -->
<span class="inline-flex items-center gap-1 rounded-full bg-blue-100 px-3 py-1 text-sm text-blue-700">
  React
  <button class="ml-1 hover:text-blue-900">
    <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
    </svg>
  </button>
</span>
```

### 5.10 Building a Responsive Footer

```html
<footer class="bg-gray-900 text-gray-300">
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
    <div class="grid grid-cols-2 md:grid-cols-4 gap-8">
      <div>
        <h3 class="text-sm font-semibold text-white uppercase tracking-wider">Product</h3>
        <ul class="mt-4 space-y-3">
          <li><a href="#" class="text-sm hover:text-white transition-colors">Features</a></li>
          <li><a href="#" class="text-sm hover:text-white transition-colors">Pricing</a></li>
          <li><a href="#" class="text-sm hover:text-white transition-colors">Changelog</a></li>
          <li><a href="#" class="text-sm hover:text-white transition-colors">Docs</a></li>
        </ul>
      </div>
      <div>
        <h3 class="text-sm font-semibold text-white uppercase tracking-wider">Company</h3>
        <ul class="mt-4 space-y-3">
          <li><a href="#" class="text-sm hover:text-white transition-colors">About</a></li>
          <li><a href="#" class="text-sm hover:text-white transition-colors">Blog</a></li>
          <li><a href="#" class="text-sm hover:text-white transition-colors">Careers</a></li>
        </ul>
      </div>
      <div>
        <h3 class="text-sm font-semibold text-white uppercase tracking-wider">Legal</h3>
        <ul class="mt-4 space-y-3">
          <li><a href="#" class="text-sm hover:text-white transition-colors">Privacy</a></li>
          <li><a href="#" class="text-sm hover:text-white transition-colors">Terms</a></li>
        </ul>
      </div>
      <div>
        <h3 class="text-sm font-semibold text-white uppercase tracking-wider">Connect</h3>
        <ul class="mt-4 space-y-3">
          <li><a href="#" class="text-sm hover:text-white transition-colors">Twitter</a></li>
          <li><a href="#" class="text-sm hover:text-white transition-colors">GitHub</a></li>
          <li><a href="#" class="text-sm hover:text-white transition-colors">Discord</a></li>
        </ul>
      </div>
    </div>
    <div class="mt-12 pt-8 border-t border-gray-800 text-center">
      <p class="text-sm text-gray-400">&copy; 2026 MyApp. All rights reserved.</p>
    </div>
  </div>
</footer>
```

### 5.11 Building an Avatar Group

```html
<div class="flex -space-x-2">
  <img class="w-10 h-10 rounded-full ring-2 ring-white" src="avatar1.jpg" alt="User 1">
  <img class="w-10 h-10 rounded-full ring-2 ring-white" src="avatar2.jpg" alt="User 2">
  <img class="w-10 h-10 rounded-full ring-2 ring-white" src="avatar3.jpg" alt="User 3">
  <img class="w-10 h-10 rounded-full ring-2 ring-white" src="avatar4.jpg" alt="User 4">
  <span class="flex items-center justify-center w-10 h-10 rounded-full ring-2 ring-white bg-gray-200 text-xs font-medium text-gray-600">
    +5
  </span>
</div>
```

### 5.12 Building a Breadcrumb

```html
<nav class="flex" aria-label="Breadcrumb">
  <ol class="flex items-center gap-2 text-sm">
    <li>
      <a href="#" class="text-gray-500 hover:text-gray-700">Home</a>
    </li>
    <li class="text-gray-400">/</li>
    <li>
      <a href="#" class="text-gray-500 hover:text-gray-700">Products</a>
    </li>
    <li class="text-gray-400">/</li>
    <li>
      <span class="text-gray-900 font-medium">Widget Pro</span>
    </li>
  </ol>
</nav>
```

### 5.13 Building a Skeleton Loader

```html
<div class="animate-pulse space-y-4">
  <div class="h-48 bg-gray-200 rounded-xl"></div>
  <div class="space-y-3">
    <div class="h-4 bg-gray-200 rounded w-3/4"></div>
    <div class="h-4 bg-gray-200 rounded w-1/2"></div>
    <div class="h-4 bg-gray-200 rounded w-5/6"></div>
  </div>
</div>
```

### 5.14 Building a Dropdown Menu

```html
<div class="relative inline-block">
  <button class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">
    Options
    <svg class="inline w-4 h-4 ml-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
    </svg>
  </button>

  <!-- Dropdown panel (toggle with JS) -->
  <div class="absolute right-0 z-10 mt-2 w-56 bg-white rounded-lg shadow-lg ring-1 ring-black/5">
    <div class="py-1">
      <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Edit</a>
      <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Duplicate</a>
      <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Archive</a>
      <div class="border-t border-gray-100 my-1"></div>
      <a href="#" class="block px-4 py-2 text-sm text-red-600 hover:bg-red-50">Delete</a>
    </div>
  </div>
</div>
```

### 5.15 Building a Tab Interface

```html
<div>
  <div class="border-b border-gray-200">
    <nav class="flex gap-8 px-4" aria-label="Tabs">
      <a href="#" class="py-3 text-sm font-medium text-blue-600 border-b-2 border-blue-600">
        General
      </a>
      <a href="#" class="py-3 text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 border-b-2 border-transparent">
        Security
      </a>
      <a href="#" class="py-3 text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 border-b-2 border-transparent">
        Notifications
      </a>
      <a href="#" class="py-3 text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 border-b-2 border-transparent">
        Billing
      </a>
    </nav>
  </div>
  <div class="p-4">
    <!-- Tab content -->
  </div>
</div>
```

### 5.16 Building a Progress Bar

```html
<!-- Simple progress bar -->
<div class="w-full bg-gray-200 rounded-full h-2.5">
  <div class="bg-blue-600 h-2.5 rounded-full" style="width: 65%"></div>
</div>

<!-- With label -->
<div>
  <div class="flex justify-between mb-1">
    <span class="text-sm font-medium text-gray-700">Uploading...</span>
    <span class="text-sm text-gray-500">65%</span>
  </div>
  <div class="w-full bg-gray-200 rounded-full h-2">
    <div class="bg-blue-600 h-2 rounded-full transition-all duration-300" style="width: 65%"></div>
  </div>
</div>

<!-- Segmented steps -->
<div class="flex gap-2">
  <div class="flex-1 h-2 rounded-full bg-blue-600"></div>
  <div class="flex-1 h-2 rounded-full bg-blue-600"></div>
  <div class="flex-1 h-2 rounded-full bg-blue-600"></div>
  <div class="flex-1 h-2 rounded-full bg-gray-200"></div>
  <div class="flex-1 h-2 rounded-full bg-gray-200"></div>
</div>
```

### 5.17 Building a Pagination Component

```html
<nav class="flex items-center justify-between">
  <p class="text-sm text-gray-500">
    Showing <span class="font-medium text-gray-900">1</span> to
    <span class="font-medium text-gray-900">10</span> of
    <span class="font-medium text-gray-900">97</span> results
  </p>
  <div class="flex items-center gap-1">
    <button class="px-3 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-lg disabled:opacity-50" disabled>
      Previous
    </button>
    <button class="px-3 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg">1</button>
    <button class="px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 rounded-lg">2</button>
    <button class="px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 rounded-lg">3</button>
    <span class="px-2 text-gray-400">...</span>
    <button class="px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 rounded-lg">10</button>
    <button class="px-3 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-lg">
      Next
    </button>
  </div>
</nav>
```

### 5.18 Building a Tooltip

```html
<div class="relative group inline-block">
  <button class="px-3 py-1.5 text-sm bg-gray-900 text-white rounded-lg">
    Hover me
  </button>
  <div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2
              hidden group-hover:block
              px-3 py-1.5 text-xs text-white bg-gray-900 rounded-lg
              whitespace-nowrap shadow-lg">
    Tooltip content
    <div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-gray-900"></div>
  </div>
</div>
```

### 5.19 Dark Mode Complete Pattern

```html
<div class="bg-white dark:bg-gray-950 min-h-screen transition-colors">
  <header class="bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-800">
    <div class="max-w-7xl mx-auto px-4 py-4 flex items-center justify-between">
      <h1 class="text-xl font-bold text-gray-900 dark:text-white">MyApp</h1>
      <!-- Dark mode toggle button (implement with JS) -->
      <button class="p-2 rounded-lg bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700">
        <svg class="w-5 h-5 hidden dark:block" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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"/>
        </svg>
        <svg class="w-5 h-5 dark:hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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"/>
        </svg>
      </button>
    </div>
  </header>

  <main class="max-w-7xl mx-auto px-4 py-8">
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
      <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 shadow-sm dark:shadow-gray-900/20">
        <h3 class="font-semibold text-gray-900 dark:text-gray-100">Card Title</h3>
        <p class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
          Card content with proper dark mode colors.
        </p>
        <a href="#" class="mt-4 inline-block text-sm font-medium text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300">
          Learn more &rarr;
        </a>
      </div>
    </div>
  </main>
</div>
```

### 5.20 Building a Glassmorphism Card

```html
<div class="relative">
  <!-- Colorful background -->
  <div class="absolute inset-0 bg-gradient-to-br from-purple-500 via-pink-500 to-orange-400"></div>

  <!-- Glass card -->
  <div class="relative m-16 p-8 rounded-2xl bg-white/10 backdrop-blur-lg border border-white/20 shadow-2xl">
    <h3 class="text-xl font-bold text-white">Glassmorphism</h3>
    <p class="mt-2 text-white/80">
      A frosted glass effect achieved with backdrop-blur and semi-transparent backgrounds.
    </p>
  </div>
</div>
```

### 5.21 Responsive Image Gallery

```html
<div class="columns-1 sm:columns-2 lg:columns-3 gap-4 space-y-4">
  <img class="w-full rounded-lg" src="photo1.jpg" alt="">
  <img class="w-full rounded-lg" src="photo2.jpg" alt="">
  <img class="w-full rounded-lg" src="photo3.jpg" alt="">
  <img class="w-full rounded-lg" src="photo4.jpg" alt="">
  <img class="w-full rounded-lg" src="photo5.jpg" alt="">
  <img class="w-full rounded-lg" src="photo6.jpg" alt="">
</div>
```

### 5.22 Aspect Ratio

```html
<!-- Video embed -->
<div class="aspect-video rounded-lg overflow-hidden">
  <iframe class="w-full h-full" src="https://www.youtube.com/embed/..."></iframe>
</div>

<!-- Square -->
<div class="aspect-square rounded-lg overflow-hidden">
  <img class="w-full h-full object-cover" src="photo.jpg" alt="">
</div>

<!-- Custom aspect ratio -->
<div class="aspect-[4/3] rounded-lg overflow-hidden">
  <img class="w-full h-full object-cover" src="photo.jpg" alt="">
</div>
```

### 5.23 Extracting Components with `@apply`

When the same pattern repeats across many pages and you cannot use a framework component abstraction:

```css
@import 'tailwindcss';

/* Button components */
.btn {
  @apply inline-flex items-center justify-center px-4 py-2 text-sm font-semibold rounded-lg transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed;
}

.btn-primary {
  @apply btn bg-blue-600 text-white hover:bg-blue-700 focus-visible:ring-blue-500;
}

.btn-secondary {
  @apply btn bg-gray-100 text-gray-700 hover:bg-gray-200 focus-visible:ring-gray-500;
}

.btn-danger {
  @apply btn bg-red-600 text-white hover:bg-red-700 focus-visible:ring-red-500;
}

.btn-ghost {
  @apply btn text-gray-600 hover:bg-gray-100 focus-visible:ring-gray-500;
}

/* Input component */
.input {
  @apply w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm text-sm placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500;
}

.input-error {
  @apply input border-red-500 focus:ring-red-500 focus:border-red-500;
}
```

### 5.24 Production Builds

#### Minification

All integration methods support minified output for production:

**Vite**: Minification happens automatically in `vite build`.

**PostCSS**: Minification is handled by your build tool (Vite, Webpack, etc.).

**CLI**: Use the `--minify` flag:

```bash
npx @tailwindcss/cli -i src/app.css -o dist/output.css --minify
```

#### What Gets Removed

Tailwind CSS only includes the CSS for utility classes it detects in your source files. If a class like `bg-purple-500` appears nowhere in your scanned files, it will not be in the output. This is automatic and requires no configuration.

#### Safelist Patterns

If you generate class names dynamically (e.g., `bg-${color}-500`), Tailwind cannot detect them at build time. Use explicit class names instead:

```html
<!-- BAD: Dynamic class construction (will NOT be detected) -->
<div class="bg-{{ color }}-500">

<!-- GOOD: Explicit full class names -->
<div class="{{ color === 'red' ? 'bg-red-500' : color === 'blue' ? 'bg-blue-500' : 'bg-gray-500' }}">
```

Or ensure the full class names appear somewhere in your source (even in a comment or unused variable) so the scanner detects them.

### 5.25 Upgrading from Tailwind CSS v3

The `@tailwindcss/upgrade` tool automates migration from v3 to v4.

#### Running the Upgrade

```bash
npx @tailwindcss/upgrade
```

This tool:

- Converts `tailwind.config.js` to CSS-first `@theme` configuration
- Updates `@tailwind base/components/utilities` to `@import 'tailwindcss'`
- Migrates PostCSS configuration
- Updates template files with renamed utilities
- Converts plugin references to `@plugin` directives

> [!WARNING]
> Always commit your code before running the upgrade tool. Review all changes it makes. The tool handles most cases automatically, but complex configurations or custom plugin setups may need manual adjustment.

#### What the Upgrade Tool Converts

| v3 Pattern | v4 Equivalent |
|---|---|
| `tailwind.config.js` theme | `@theme { ... }` in CSS |
| `@tailwind base` | `@import 'tailwindcss/preflight'` |
| `@tailwind components` | (removed, use `@layer`) |
| `@tailwind utilities` | `@import 'tailwindcss/utilities'` |
| `content: [...]` in config | `@source` directives in CSS |
| `require('plugin')` in config | `@plugin 'plugin'` in CSS |
| `theme.extend.colors` | `@theme { --color-*: ... }` |

#### Common Manual Steps After Upgrade

1. Review `@theme` output for correctness
2. Check that `@source` paths cover all your template files
3. Verify custom plugin compatibility with v4
4. Test dark mode behavior (v4 uses `prefers-color-scheme` by default)
5. Check for renamed or removed utility classes

### 5.26 Using Tailwind with TypeScript Projects

Tailwind works with any file that contains class strings. For TypeScript projects, ensure your `@source` patterns include `.ts` and `.tsx` files:

```css
@import 'tailwindcss';

/* TypeScript files are scanned by default if in the project directory */
/* Add explicit sources if they're outside the default scan path */
@source '../src/**/*.tsx';
@source '../src/**/*.ts';
```

### 5.27 Using Tailwind with Markdown/MDX Content

For content sites that use Markdown or MDX:

```css
@import 'tailwindcss';

@source '../content/**/*.md';
@source '../content/**/*.mdx';
```

The `@tailwindcss/typography` plugin provides beautiful default styling for rendered Markdown:

```css
@import 'tailwindcss';
@plugin '@tailwindcss/typography';
```

```html
<article class="prose lg:prose-lg dark:prose-invert max-w-none">
  <!-- Rendered Markdown content gets beautiful typography -->
</article>
```

### 5.28 Using Tailwind with CSS Modules

Tailwind works alongside CSS Modules. Use `@reference` to access theme tokens without duplicating output:

```css
/* component.module.css */
@reference '../app.css';

.wrapper {
  @apply flex items-center gap-4 p-6;
}

.title {
  @apply text-xl font-bold text-gray-900;
}
```

### 5.29 Controlling Specificity with `@layer`

While Tailwind v4 handles specificity automatically, you can use standard CSS `@layer` for custom styles:

```css
@import 'tailwindcss';

@layer base {
  h1 {
    @apply text-3xl font-bold;
  }
  h2 {
    @apply text-2xl font-semibold;
  }
}
```

Base layer styles have lower specificity than utility classes, so utilities always win when applied via the `class` attribute.

### 5.30 Using Custom Fonts

```css
@import 'tailwindcss';

/* Import the font */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

@theme {
  --font-family-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
}
```

Or with local font files:

```css
@import 'tailwindcss';

@font-face {
  font-family: 'CalSans';
  src: url('/fonts/CalSans-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-display: swap;
}

@theme {
  --font-family-display: 'CalSans', sans-serif;
}
```

Use in HTML:

```html
<h1 class="font-display text-4xl">Custom Display Font</h1>
<p class="font-sans text-base">Inter body text</p>
```

---

## 6. Troubleshooting

### 6.1 Build and Compilation Errors

#### Error: `Cannot find module '../lightningcss.linux-x64-musl.node'`

**Cause:** The native Lightning CSS binary for your platform is missing. This commonly occurs in Alpine Linux Docker containers or musl-based environments where the glibc binary was installed instead. (GitHub issue #17958)

**Solution:**

1. Ensure you are running a clean install:
   ```bash
   rm -rf node_modules package-lock.json
   npm install
   ```
2. If using Alpine Linux, ensure the musl variant is available:
   ```bash
   npm install lightningcss-linux-x64-musl
   ```
3. If using Docker, make sure `npm install` runs inside the container (not on the host), so the correct platform binaries are resolved.

**Prevention:** Run `npm install` in the same OS/architecture as your build environment.

---

#### Error: `Tailwind CSS is not installed`

**Cause:** The `@tailwindcss/upgrade` tool cannot find a Tailwind CSS installation in the project.

**Solution:**

1. Install Tailwind CSS first:
   ```bash
   npm install tailwindcss
   ```
2. Then run the upgrade tool:
   ```bash
   npx @tailwindcss/upgrade
   ```

---

#### Error: `Could not resolve '{id}' from '{base}'`

**Cause:** An `@import`, `@plugin`, or `@config` directive references a module or file that cannot be found relative to the CSS file or in `node_modules`.

**Solution:**

1. Verify the import path is correct and the file exists.
2. For npm packages, ensure they are installed: `npm install <package-name>`.
3. Check that the path is relative to the CSS file containing the directive, not your project root.

---

#### Error: `The browser build does not support @import for "{id}"`

**Cause:** You are using `@import` to include an external CSS file while using the `@tailwindcss/browser` build. The browser build compiles inline CSS only.

**Solution:** The browser build does not support importing external files. Either:
- Switch to a build tool (Vite, PostCSS, CLI) for full `@import` support.
- Inline all your CSS in `<style type="text/tailwindcss">` tags.

---

#### Error: `The browser build does not support plugins or config files.`

**Cause:** You used `@plugin` or `@config` in a `<style type="text/tailwindcss">` block with the browser build.

**Solution:** The browser build is intentionally limited. Switch to a Node.js-based build tool (Vite plugin, PostCSS, or CLI) if you need plugins or config files.

---

#### Error: `The source(...) does not exist or is not a directory.`

**Cause:** The `source(...)` function references a path that does not exist on disk.

**Solution:**

1. Verify the path exists: `ls -la ../src` (or whatever path you specified).
2. Ensure the path is a directory, not a file.
3. Use a path relative to the CSS file location.

---

### 6.2 `@apply` Errors

#### Error: `You cannot use @apply inside @keyframes.`

**Cause:** Tailwind does not support `@apply` within `@keyframes` blocks because keyframe declarations have different semantics than regular CSS rules.

**Solution:** Write raw CSS properties inside `@keyframes`:

```css
/* BAD */
@keyframes fade-in {
  from { @apply opacity-0; }
  to { @apply opacity-100; }
}

/* GOOD */
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
```

---

#### Error: `Cannot apply unknown utility class '{candidate}'`

**Cause:** The class name referenced in `@apply` does not correspond to any known Tailwind utility or custom utility defined with `@utility`.

**Solution:**

1. Check for typos in the class name.
2. Verify the utility exists in the current Tailwind version (some v3 utilities were renamed or removed in v4).
3. If it is a custom utility, ensure it is defined with `@utility` before the `@apply` usage.

---

#### Error: `Cannot apply unprefixed utility class '{candidate}'. Did you mean '{prefix}:{candidate}'?`

**Cause:** Your project uses a class prefix, and you used the unprefixed form in `@apply`.

**Solution:** Include the prefix:

```css
/* If your prefix is 'tw' */
.my-class {
  @apply tw:px-4 tw:py-2 tw:bg-blue-500;
}
```

---

#### Error: `Cannot apply utility class '{candidate}' because it creates a circular dependency.`

**Cause:** A class defined with `@apply` references another class that eventually references the original class, creating an infinite loop.

**Solution:** Break the circular chain by inlining the CSS properties directly for one of the classes:

```css
/* BAD: Circular */
.foo { @apply bar; }
.bar { @apply foo; }

/* GOOD: Break the cycle */
.foo { @apply bar; }
.bar { padding: 1rem; color: blue; }
```

---

### 6.3 Theme Function Errors

#### Error: `The --theme(...) function can only be used with CSS variables from your theme.`

**Cause:** You passed a CSS variable to `--theme()` that is not defined in any `@theme` block.

**Solution:**

1. Ensure the variable is defined in `@theme`:
   ```css
   @theme {
     --color-brand: #3b82f6;
   }
   ```
2. Use `var()` instead if referencing non-theme custom properties:
   ```css
   .element {
     /* For theme variables */
     color: --theme(--color-brand);
     /* For non-theme custom properties */
     color: var(--my-custom-color);
   }
   ```

---

#### Error: `The --spacing(...) function requires an argument, but received none.`

**Cause:** `--spacing()` was called with empty parentheses.

**Solution:** Provide a spacing scale value:

```css
.element {
  padding: --spacing(4);
  margin: --spacing(2);
}
```

---

### 6.4 Scanner and Source Detection Issues

#### Classes not being generated (scanner misses)

**Cause:** The Oxide scanner could not find your class candidates. Common reasons:

1. Files are outside the scan path.
2. Files are in `.gitignore`.
3. Class names are dynamically constructed.
4. File type is not recognized by the scanner.

**Solution:**

1. Add explicit `@source` directives:
   ```css
   @source '../path/to/templates/**/*.html';
   ```
2. For dynamically constructed classes, use complete class names:
   ```html
   <!-- BAD: Scanner can't detect this -->
   <div class="text-{{ color }}-500">

   <!-- GOOD: Full class names the scanner can detect -->
   <div class="{{ color === 'red' ? 'text-red-500' : 'text-blue-500' }}">
   ```

---

#### Oxide scanner fails on arbitrary value classes (GitHub issue #19863)

**Cause:** In v4.2.2, certain arbitrary value patterns like `max-h-[85vh]` may not be detected by the Oxide scanner in some contexts.

**Solution:**

1. Verify the class name syntax is correct.
2. Try writing the value as a custom utility if the arbitrary value is not detected:
   ```css
   @utility max-h-85vh {
     max-height: 85vh;
   }
   ```
3. Check the GitHub issue for updates and patches.

---

#### `@source` silently ignores paths excluded by `.gitignore` (GitHub issue #19844)

**Cause:** The Oxide scanner respects `.gitignore` rules even for explicitly declared `@source` paths. If a directory appears in an allow-list `.gitignore` (a `.gitignore` that ignores everything except specific patterns), the `@source` directive may silently skip matching files.

**Solution:**

1. Check your `.gitignore` for patterns that might exclude the targeted files.
2. If the files must remain gitignored, consider copying them to a non-ignored location during build.
3. As a workaround, restructure your `.gitignore` so the source files are not excluded.

---

#### Source glob does not match Next.js catchall routes like `[...slug]` (GitHub issue #16287)

**Cause:** The bracket characters in Next.js dynamic route segments (e.g., `pages/[...slug].tsx`) can interfere with glob pattern matching.

**Solution:**

1. Use a broader glob pattern that does not require matching the brackets:
   ```css
   @source '../pages/**/*.tsx';
   @source '../app/**/*.tsx';
   ```
2. Avoid overly specific glob patterns that try to match bracket characters.

---

### 6.5 Platform and Environment Issues

#### Error: `Unsupported OS: openbsd` (GitHub issue #17452)

**Cause:** Tailwind CSS v4's native Oxide addon does not ship prebuilt binaries for OpenBSD.

**Solution:**

1. Use the standalone CLI binary if a compatible build exists for your platform.
2. Use a Docker container with a supported Linux distribution for building.
3. Cross-compile the CSS on a supported platform and copy the output.

---

#### Can't build on Linux ARM (missing `@tailwindcss/oxide-linux-arm64-gnu`) (GitHub issue #15806)

**Cause:** The native Oxide binary for Linux ARM64 may not be included in some installation scenarios.

**Solution:**

1. Ensure you install with a clean `node_modules`:
   ```bash
   rm -rf node_modules
   npm install
   ```
2. Explicitly install the ARM64 binary:
   ```bash
   npm install @tailwindcss/oxide-linux-arm64-gnu
   ```
3. If building in CI, ensure the CI runner architecture matches your deployment target.

---

#### Invalid code point error on Windows with backslash + hex UUID in path (GitHub issue #19910)

**Cause:** On Windows, file paths containing backslashes followed by hexadecimal characters can be misinterpreted as Unicode escape sequences, causing invalid code point errors.

**Solution:**

1. Avoid file paths that combine backslashes with hex-like characters.
2. Move your project to a path without special characters.
3. Use forward slashes in path configurations where possible.

---

#### CLI no longer works with Docker bind mounts (GitHub issue #18540)

**Cause:** The file watching mechanism in the Oxide scanner may not properly detect changes through Docker bind mount boundaries.

**Solution:**

1. Use polling mode if available.
2. Run the Tailwind build process inside the Docker container rather than on the host.
3. Consider using volume mounts instead of bind mounts.

---

### 6.6 Vite Integration Issues

#### `@tailwindcss/vite` emits SOURCEMAP_BROKEN warnings in Nuxt/Vite (GitHub issue #19930)

**Cause:** The Vite plugin may emit source map warnings when used with Nuxt or certain Vite configurations.

**Solution:**

1. These warnings are cosmetic and do not affect the generated CSS.
2. Check the GitHub issue for a patch or workaround specific to your Nuxt version.
3. Suppressing source map warnings in Vite config may help:
   ```js
   // vite.config.js
   export default defineConfig({
     css: {
       devSourcemap: false,
     },
   })
   ```

---

#### HMR not working with Vite 7 + SolidStart v2 (GitHub issue #19818)

**Cause:** Compatibility issue between the Tailwind Vite plugin and Vite 7 / SolidStart v2's HMR implementation.

**Solution:**

1. Check the GitHub issue for updates.
2. As a workaround, use the PostCSS plugin instead of the Vite plugin.
3. Manually refresh the browser during development until a fix is released.

---

#### `@tailwindcss/vite` forces full reload for Angular component stylesheets (GitHub issue #19903)

**Cause:** When editing Angular component CSS files, the Vite plugin may trigger a full page reload instead of a hot update.

**Solution:**

1. This is a known issue with the interaction between Angular's component stylesheet pipeline and the Tailwind Vite plugin.
2. Consider using the PostCSS integration for Angular projects instead.

---

#### DeprecationWarning: `module.register()` deprecated (GitHub issue #19893)

**Cause:** Node.js deprecation warning for `module.register()` used internally by the Tailwind Vite plugin or related tooling.

**Solution:**

1. This is a Node.js-level deprecation warning, not a Tailwind bug. It is informational and does not affect functionality.
2. Upgrading to the latest Tailwind CSS and Vite versions may resolve it.

---

### 6.7 Watch Mode Issues

#### Watch mode not refreshing files in assets folder (GitHub issue #17632)

**Cause:** The file watcher may not detect changes in certain directories, especially those outside the default scan path.

**Solution:**

1. Add an explicit `@source` directive for the assets directory:
   ```css
   @source '../assets/**/*.html';
   ```
2. Ensure the directory is not excluded by `.gitignore`.
3. Restart the watch process after adding new directories.

---

### 6.8 General Troubleshooting Steps

#### Classes appear in source but are not styled

1. **Check the CSS import**: Ensure `@import 'tailwindcss'` is present in your CSS entry file.
2. **Check source scanning**: Add `@source` directives if your templates are outside the project root.
3. **Check `.gitignore`**: Scanned paths must not be gitignored.
4. **Check for typos**: Tailwind class names are case-sensitive (`bg-Blue-500` will not work, use `bg-blue-500`).
5. **Check build output**: Inspect the compiled CSS to see if the class is present.

#### CSS file is very large in development

This is expected. In development, Tailwind may include more CSS for faster HMR. Production builds automatically tree-shake unused classes.

#### Styles appear but are overridden

1. Check CSS source order. Styles loaded later win.
2. Check specificity. Tailwind utilities are single-class selectors. If your custom CSS uses more specific selectors (IDs, nested selectors), they will override utilities.
3. Use `!important` modifier if absolutely necessary: `!bg-blue-500` (prefix with `!`).

#### IntelliSense / autocomplete not working

1. Install the Tailwind CSS IntelliSense VS Code extension.
2. Ensure your CSS file has `@import 'tailwindcss'` (the extension needs this to activate).
3. Restart VS Code after installing Tailwind CSS packages.

#### Preflight (CSS reset) is unwanted

Import only the layers you need:

```css
/* Skip Preflight entirely */
@import 'tailwindcss/theme';
@import 'tailwindcss/utilities';
```

#### Colors look different from v3

Tailwind v4 uses the OKLCH color space by default, which provides perceptually uniform colors. The hex values may differ from v3's sRGB-based palette. If you need exact v3 colors, define them explicitly in `@theme`.

---

## 7. FAQ

**Q: What version of Node.js do I need?**

Tailwind CSS v4 requires Node.js 20 or later. This is enforced in the `package.json` `engines` field. Earlier Node versions will fail at install or build time.

---

**Q: Do I still need a `tailwind.config.js` file?**

No. Tailwind CSS v4 uses CSS-first configuration with directives like `@theme`, `@source`, and `@plugin` directly in your CSS. The `@config` directive exists as a backward-compatibility bridge for v3 config files during migration, but new projects should use CSS-first configuration exclusively.

---

**Q: How do I migrate from Tailwind CSS v3 to v4?**

Run `npx @tailwindcss/upgrade` in your project. It automatically converts your `tailwind.config.js` to CSS `@theme` blocks, updates `@tailwind` directives to `@import`, and migrates PostCSS configuration. Always commit before running and review the changes.

---

**Q: Can I use Tailwind without Node.js?**

Yes. The `@tailwindcss/standalone` binary is a self-contained executable built with Bun. It includes the Tailwind compiler and several first-party plugins (`@tailwindcss/forms`, `@tailwindcss/typography`, `@tailwindcss/aspect-ratio`). Download it and run it directly.

---

**Q: Which build tool integration should I choose?**

- **Vite projects**: Use `@tailwindcss/vite` (fastest HMR, recommended).
- **Webpack projects**: Use `@tailwindcss/webpack`.
- **Any PostCSS setup (Next.js, Nuxt, Angular)**: Use `@tailwindcss/postcss`.
- **No build tool**: Use `@tailwindcss/cli`.
- **No Node.js**: Use `@tailwindcss/standalone`.
- **Prototyping**: Use `@tailwindcss/browser` (CDN, not for production).

---

**Q: How does Tailwind know which classes I'm using?**

The Oxide engine (written in Rust) scans your source files for strings that look like utility class names. It does not execute your code or parse templates semantically -- it performs string extraction. Any string matching a valid utility pattern in a scanned file will generate the corresponding CSS.

---

**Q: What file types does the scanner detect classes in?**

Beyond standard HTML, JS, and TS files, the Oxide scanner handles: Clojure, Elixir (`.heex`, `.leex`), Haml, JSON, Markdown, Pug, Razor (`.cshtml`, `.razor`), Ruby (`.rb`, `.erb`), Rust, Slim, Svelte, and Vue files. Custom file types can be included via `@source` glob patterns.

---

**Q: Why are my dynamically constructed class names not working?**

Tailwind's scanner looks for complete class name strings. It cannot resolve dynamic concatenation like `bg-${color}-500`. Use complete, literal class names in conditional expressions or map objects:

```js
const colorClasses = {
  red: 'bg-red-500 text-red-50',
  blue: 'bg-blue-500 text-blue-50',
  green: 'bg-green-500 text-green-50',
}
```

---

**Q: How do I add custom colors?**

Define them in a `@theme` block:

```css
@theme {
  --color-brand: #3b82f6;
  --color-brand-light: #93c5fd;
  --color-brand-dark: #1d4ed8;
}
```

This generates `text-brand`, `bg-brand`, `border-brand`, `ring-brand`, etc.

---

**Q: How do I add custom breakpoints?**

Define them in a `@theme` block:

```css
@theme {
  --breakpoint-xs: 30rem;
  --breakpoint-3xl: 120rem;
}
```

Then use them as responsive variants: `xs:flex`, `3xl:grid-cols-4`.

---

**Q: How do I completely replace the default theme?**

Use `--*: initial` in a `@theme` block to reset all defaults, then define your complete design system:

```css
@theme {
  --*: initial;
  --color-primary: #000;
  --color-secondary: #666;
  --spacing-1: 0.25rem;
  --spacing-2: 0.5rem;
  /* ... define everything you need */
}
```

---

**Q: Can I use Tailwind with CSS Modules?**

Yes. Use the `@reference` directive in your CSS Module file to access theme tokens and utilities via `@apply` without duplicating CSS output:

```css
/* component.module.css */
@reference '../app.css';

.wrapper {
  @apply flex items-center gap-4;
}
```

---

**Q: How do I use Tailwind with a CSS preprocessor (Sass, Less)?**

Tailwind v4 does not require a preprocessor. The `@theme`, `@utility`, `@variant`, and nesting features cover most preprocessor use cases. If you must use a preprocessor alongside Tailwind, run the preprocessor first and pipe its output to Tailwind via PostCSS.

---

**Q: What is Preflight and can I disable it?**

Preflight is Tailwind's CSS reset (based on modern-normalize). It provides consistent cross-browser defaults. To disable it, import only the layers you need:

```css
@import 'tailwindcss/theme';
@import 'tailwindcss/utilities';
```

---

**Q: How do I use dark mode?**

Add `dark:` variant to any utility: `dark:bg-gray-900`, `dark:text-white`. By default, dark mode follows the operating system preference via `prefers-color-scheme`. See the Admin Guide for details on implementing class-based dark mode toggling.

---

**Q: How do I make a utility `!important`?**

Prefix the utility with `!`:

```html
<div class="!bg-blue-500">Always blue, regardless of specificity conflicts</div>
```

---

**Q: Can I use `@apply` inside `@keyframes`?**

No. The error `You cannot use @apply inside @keyframes.` is intentional. Write raw CSS properties inside keyframes:

```css
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
```

---

**Q: How do I reference theme values in custom CSS?**

Use the `--theme()` function or standard `var()` with theme custom properties:

```css
.custom {
  color: --theme(--color-brand);
  padding: --spacing(4);
  /* Or using var() */
  color: var(--color-brand);
}
```

---

**Q: How do I use container queries?**

Wrap the parent in `@container` and use `@sm:`, `@md:`, `@lg:` etc. on children:

```html
<div class="@container">
  <div class="@md:flex @md:gap-4">
    Responsive to container width
  </div>
</div>
```

---

**Q: Why is my output CSS file very large?**

In development, Tailwind may include extra CSS for faster HMR. In production builds, only the CSS for detected utility classes is included. Check:
1. That you are running a production build (not a dev build).
2. That your `@source` patterns are not too broad (scanning unnecessary files).
3. That you do not have many unused custom `@theme` tokens.

---

**Q: How do I use Tailwind with server-side rendered (SSR) frameworks?**

Tailwind works with any SSR framework (Next.js, Nuxt, SvelteKit, Remix, Astro, etc.) through the PostCSS or Vite plugin. The CSS is generated at build time, not at runtime. No special SSR configuration is needed.

---

**Q: What is the `@reference` directive for?**

`@reference` imports another CSS file's theme tokens and utility definitions for use with `@apply` and IntelliSense, without including that file's generated CSS in the output. It is useful for component-level CSS files that need access to the global theme.

---

**Q: How do I handle right-to-left (RTL) layouts?**

Use logical property utilities (`ps-*`, `pe-*`, `ms-*`, `me-*`) which map to `padding-inline-start`, `padding-inline-end`, etc. These automatically flip in RTL contexts. You can also use `rtl:` and `ltr:` variants for direction-specific styles.

---

**Q: How does the `source(none)` option work?**

Adding `source(none)` to your Tailwind import disables automatic source detection. You must then explicitly list every path:

```css
@import 'tailwindcss' source(none);
@source '../app/**/*.tsx';
@source '../components/**/*.tsx';
```

This gives you exact control over what is scanned.

---

**Q: Can I use Tailwind with Web Components / Shadow DOM?**

Yes, but Tailwind's styles need to be available inside the Shadow DOM. You can either adopt the stylesheet programmatically or include Tailwind's output inside each component's shadow root. See the Admin Guide for implementation patterns.

---

**Q: What is the difference between `@import 'tailwindcss'` and importing individual layers?**

`@import 'tailwindcss'` is a shorthand that includes Preflight + Theme + Utilities. The granular imports (`tailwindcss/preflight`, `tailwindcss/theme`, `tailwindcss/utilities`) let you selectively include layers or insert custom CSS between them.

---

**Q: How do I use the `canonicalize` CLI command?**

The `canonicalize` command normalizes your Tailwind CSS file, reordering directives and formatting consistently:

```bash
npx @tailwindcss/cli canonicalize -i src/app.css -o src/app.css
```

This is useful for maintaining consistent CSS file formatting across a team.

---

**Q: Can I use multiple `@theme` blocks?**

Yes. Multiple `@theme` blocks merge together. This is useful for organizing tokens across multiple CSS files or logical groupings:

```css
@theme { --color-brand: blue; }
@theme { --font-family-display: 'Cal Sans'; }
```

Both tokens are available.

---

**Q: How do I use the opacity modifier syntax?**

Append `/{percentage}` to any color utility:

```html
<div class="bg-black/50">50% opacity black</div>
<div class="text-blue-600/75">75% opacity blue text</div>
<div class="border-gray-900/10">10% opacity border</div>
```

The number is a percentage from 0 to 100.

---

**Q: My Tailwind IntelliSense shows v3 completions. How do I fix it?**

Ensure the Tailwind CSS IntelliSense VS Code extension is up to date and that your project has Tailwind CSS v4 installed (not v3). The extension detects the installed version automatically. Restart VS Code after upgrading.

---

_Generated May 2026 from tailwindlabs/tailwindcss at 5a835e1. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
