# How the AI Website Cloner Template Handles Dark Mode Theming with Tailwind CSS v4 oklch Tokens

> Discover how the AI Website Cloner Template masters dark mode with Tailwind CSS v4 oklch tokens. Learn about seamless OS-based theme switching via CSS custom properties and the dark variant without JavaScript.

- Repository: [JCodesMore/ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
- Tags: how-to-guide
- Published: 2026-07-01

---

**The template implements dark mode by storing oklch color values as CSS custom properties in [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css), using Tailwind CSS v4's `dark:` variant to automatically switch themes based on the user's OS preference without JavaScript.**

The JCodesMore/ai-website-cloner-template repository provides a token-driven theming system built on the perceptually uniform oklch color space. By defining design tokens in a global stylesheet and leveraging Tailwind CSS v4's built-in dark mode support, the template delivers automatic color scheme switching that applies consistently across all UI components.

## CSS Custom Properties with oklch Tokens

The foundation of the dark mode system lies in [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css), where all color values are declared as CSS custom properties using the `oklch()` color function. This approach separates design decisions from component markup, enabling a single source of truth for both light and dark themes.

### Light Mode Definitions

The default color scheme is defined within the `:root` selector starting at line 52. These variables establish the baseline palette using oklch lightness, chroma, and hue values:

```css
/* src/app/globals.css (lines 52-77) */
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
}

```

### Dark Mode Overrides

When the browser detects a dark color scheme preference, the values are overridden inside a `@media (prefers-color-scheme: dark)` block beginning at line 87:

```css
/* src/app/globals.css (lines 87-117) */
@media (prefers-color-scheme: dark) {
  :root {
    --background: oklch(0.145 0 0);
    --foreground: oklch(0.985 0 0);
    --card: oklch(0.205 0 0);
    --card-foreground: oklch(0.985 0 0);
    --border: oklch(1 0 0 / 10%);
    --input: oklch(1 0 0 / 15%);
    --primary: oklch(0.922 0 0);
    --primary-foreground: oklch(0.205 0 0);
  }
}

```

## Tailwind CSS v4 Configuration

The template uses Tailwind CSS version 4, which provides native support for the `dark:` variant without requiring manual configuration in [`tailwind.config.js`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/tailwind.config.js). According to the dependencies listed in [`package.json`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/package.json) at line 56, the project specifies `"tailwindcss": "^4"`:

```json
// package.json (line 56)
"tailwindcss": "^4"

```

Tailwind v4 processes these utilities through the PostCSS plugin registered in `postcss.config.mjs`. When the user's OS reports `prefers-color-scheme: dark`, Tailwind automatically applies the `dark:` prefixed utilities, which reference the overridden CSS variable values defined in the media query.

## Component-Level Implementation

UI components consume these tokens through Tailwind utility classes that map to the CSS custom properties. The `Button` component in [`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx) demonstrates this pattern between lines 9 and 21:

```tsx
// src/components/ui/button.tsx (lines 9-21)
const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
  {
    variants: {
      variant: {
        default:
          "bg-primary text-primary-foreground hover:bg-primary/90 dark:bg-input/30 dark:hover:bg-input/50",
        outline:
          "border-border bg-background hover:bg-muted hover:text-foreground dark:border-input",
      },
    },
  }
);

```

In this implementation, the `dark:` variants (such as `dark:border-input` and `dark:bg-input/30`) reference the CSS variables (`--border`, `--input`) that swap values based on the active color scheme.

## Practical Usage Examples

Components automatically adapt to the user's preferred color scheme without additional logic. Here is how to use the dark-mode-aware button:

```tsx
import { Button } from "@/components/ui/button";

export default function Example() {
  return (
    <Button className="bg-primary text-primary-foreground hover:bg-primary/90">
      Click me
    </Button>
  );
}

```

The `bg-primary` class resolves to the `--primary` CSS variable, which changes from `oklch(0.205 0 0)` in light mode to `oklch(0.922 0 0)` in dark mode.

For custom components, reference the design tokens directly to ensure consistency:

```tsx
export function Card({ children }: { children: React.ReactNode }) {
  return (
    <div className="rounded-lg bg-card text-card-foreground p-4 shadow">
      {children}
    </div>
  );
}

```

Both `bg-card` and `text-card-foreground` pull from the token system, automatically rendering in the appropriate color space based on the `prefers-color-scheme` media query.

## Summary

- **Token Architecture**: Colors are defined as `oklch()` values in CSS custom properties within [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css), providing a perceptually uniform color space that maintains contrast ratios across themes.
- **Automatic Switching**: Dark mode activates through the `@media (prefers-color-scheme: dark)` media query at line 87, overriding the default `:root` values without JavaScript.
- **Tailwind v4 Integration**: The template leverages Tailwind CSS v4's native `dark:` variant (confirmed by `"tailwindcss": "^4"` in [`package.json`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/package.json) line 56) to conditionally apply styles based on the active color scheme.
- **Component Consistency**: UI elements like the `Button` component in [`src/components/ui/button.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/ui/button.tsx) use utility classes that reference these variables, ensuring the entire interface updates cohesively when the OS theme changes.

## Frequently Asked Questions

### What are oklch color tokens?

**oklch** is a CSS color function representing the OKLab color space, which provides perceptual uniformity—meaning color changes appear consistent to the human eye regardless of hue. The template uses `oklch(lightness chroma hue)` syntax (e.g., `oklch(1 0 0)` for pure white) to define tokens that maintain accessibility contrast ratios better than HSL or RGB equivalents when switching between light and dark modes.

### How does Tailwind CSS v4 handle dark mode differently?

Tailwind CSS v4 moves configuration into CSS files and provides the `dark:` variant automatically without requiring a `darkMode` setting in [`tailwind.config.js`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/tailwind.config.js). As implemented in this template, the variant works immediately with the standard `prefers-color-scheme` media query, applying `dark:` prefixed utilities only when the user's OS is set to dark mode.

### Where are the color tokens defined in this template?

All color tokens reside in [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css). Light mode defaults appear starting at line 52 under the `:root` selector, while dark mode overrides begin at line 87 inside `@media (prefers-color-scheme: dark)`. This centralizes theming logic and allows any component to reference semantic variables like `--background`, `--foreground`, or `--card` without hardcoding color values.

### Can components override the global theme colors?

Yes. While components typically reference semantic tokens (e.g., `bg-primary` or `text-muted-foreground`), they can also use arbitrary values or explicit oklch colors for specific branding needs. However, the template encourages using the CSS variable system to maintain consistency with the automatic dark mode switching defined in [`globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/globals.css).