# Customizing Tailwind CSS Theme (Colors, Radius, and Variants) in prompts.chat

> Learn to customize Tailwind CSS theme colors, radius, and variants in prompts.chat by editing prompts.config.ts or using environment variables for dynamic styling.

- Repository: [Fatih Kadir Akın/prompts.chat](https://github.com/f/prompts.chat)
- Tags: how-to-guide
- Published: 2026-04-02

---

**You customize the Tailwind CSS theme in prompts.chat by editing [`prompts.config.ts`](https://github.com/f/prompts.chat/blob/main/prompts.config.ts) or setting `PCHAT_` environment variables; [`src/app/layout.tsx`](https://github.com/f/prompts.chat/blob/main/src/app/layout.tsx) converts these values into CSS custom properties like `--radius` and `--primary` that components consume via Tailwind's arbitrary value syntax such as `rounded-[var(--radius)]` and `bg-primary`.**

The prompts.chat codebase implements a runtime theme system that bridges TypeScript configuration with Tailwind CSS utility classes. Instead of modifying [`tailwind.config.ts`](https://github.com/f/prompts.chat/blob/main/tailwind.config.ts) and rebuilding your bundle, you control colors, border radius, and UI variants through a centralized configuration object that gets injected into the DOM as CSS variables at runtime.

## Theme Configuration Architecture

The theming system centers on a TypeScript configuration object that defines your brand identity, corner roundness, and interface density preferences.

### The prompts.config.ts Entry Point

All visual customization starts in [`prompts.config.ts`](https://github.com/f/prompts.chat/blob/main/prompts.config.ts) at the project root. This file exports a configuration object via `defineConfig()` from [`src/lib/config/index.ts`](https://github.com/f/prompts.chat/blob/main/src/lib/config/index.ts), which provides full type safety through the `ThemeConfig` interface.

```ts
// prompts.config.ts
import { defineConfig } from "@/lib/config";

export default defineConfig({
  branding: {
    name: "My Prompt Hub",
    logo: "/logo.svg",
  },
  theme: {
    radius: "lg",                // none | sm | md | lg
    variant: "brutal",           // flat | default | brutal
    density: "comfortable",      // compact | default | comfortable
    colors: {
      primary: "#ff4500",        // Hex value converted to OKLCH at runtime
    },
  },
});

```

The configuration supports three distinct **ui variants** (`flat`, `default`, `brutal`) and three **density modes** (`compact`, `default`, `comfortable`), allowing you to adjust visual weight and spacing without writing custom CSS.

### Type Definitions and Validation

The `ThemeConfig` interface and runtime logic reside in [`src/lib/config/index.ts`](https://github.com/f/prompts.chat/blob/main/src/lib/config/index.ts). This file exports `applyEnvOverrides()`, which checks for environment variables at runtime and merges them over your static configuration.

Supported environment variables include:
- `PCHAT_THEME_RADIUS` – overrides the `radius` enum
- `PCHAT_THEME_VARIANT` – overrides the `variant` setting
- `PCHAT_THEME_DENSITY` – overrides the `density` setting
- `PCHAT_COLOR` – overrides the `colors.primary` value

## Runtime CSS Variable Injection

The conversion from configuration to rendered styles happens server-side in [`src/app/layout.tsx`](https://github.com/f/prompts.chat/blob/main/src/app/layout.tsx) (lines 116-176), where the layout component transforms your config values into CSS custom properties on the `<html>` element.

### Color Space Conversion with hexToOklch

Inside [`layout.tsx`](https://github.com/f/prompts.chat/blob/main/layout.tsx), the `hexToOklch()` function converts your configured hex color (e.g., `#ff4500`) into the OKLCH color space. This conversion ensures perceptual uniformity when the system generates contrast colors and opacity variants. The result is injected as `--primary`, while a calculated accessible contrast color becomes `--primary-foreground`.

### Radius Mapping via radiusValues

The file defines a lookup table called `radiusValues` that maps configuration enums to concrete CSS lengths:

```ts
const radiusValues = {
  none: "0",
  sm: "0.25rem",
  md: "0.5rem",
  lg: "0.75rem",
};

```

Your selected radius is written to the `--radius` CSS variable, which components reference for consistent corner rounding throughout the application.

### Variant and Density Classes

Beyond CSS variables, [`layout.tsx`](https://github.com/f/prompts.chat/blob/main/layout.tsx) constructs `themeClasses` by mapping your config to class names like `theme-brutal` and `density-comfortable`. These classes are applied directly to the `<html>` tag, enabling scoped CSS rules that adjust shadows, borders, and internal spacing without requiring Tailwind configuration changes.

## Consuming Theme Variables in Components

UI components reference these runtime variables using Tailwind's arbitrary value syntax. In [`src/components/ui/button.tsx`](https://github.com/f/prompts.chat/blob/main/src/components/ui/button.tsx), you will see patterns like:

```tsx
// src/components/ui/button.tsx
<button 
  className="inline-flex items-center rounded-[var(--radius)] bg-primary text-primary-foreground hover:bg-primary/90 px-4 py-2"
>
  Click me
</button>

```

- `rounded-[var(--radius)]` dynamically applies your configured border radius.
- `bg-primary` maps to the `--primary` variable injected by the layout.
- `text-primary-foreground` ensures WCAG-compliant contrast against your primary color.

Because these values are standard CSS custom properties, changes to [`prompts.config.ts`](https://github.com/f/prompts.chat/blob/main/prompts.config.ts) reflect immediately across all components after a page refresh without requiring a Tailwind CSS rebuild.

## Environment Variable Overrides

For deployment flexibility—such as running different brands on the same codebase—use the environment override system. Create a `.env` file in your project root:

```bash
PCHAT_THEME_RADIUS=md
PCHAT_THEME_VARIANT=default
PCHAT_THEME_DENSITY=compact
PCHAT_COLOR=#4f46e5

```

The `applyEnvOverrides` function in [`src/lib/config/index.ts`](https://github.com/f/prompts.chat/blob/main/src/lib/config/index.ts) (lines 94-100) reads these variables and deep-merges them into the configuration object before [`layout.tsx`](https://github.com/f/prompts.chat/blob/main/layout.tsx) processes it. This approach is ideal for Docker deployments or Vercel preview environments where you need environment-specific branding.

## Extending the Design System with Custom Radius Values

If the default four radius options are insufficient for your design language, you can extend the system by modifying the lookup table in [`src/app/layout.tsx`](https://github.com/f/prompts.chat/blob/main/src/app/layout.tsx):

```ts
const radiusValues = {
  none: "0",
  sm: "0.25rem",
  md: "0.5rem",
  lg: "0.75rem",
  xl: "1.25rem",  // Custom addition
  "2xl": "2rem",  // Another custom option
};

```

Then reference your new value in [`prompts.config.ts`](https://github.com/f/prompts.chat/blob/main/prompts.config.ts):

```ts
theme: { 
  radius: "xl",
  variant: "default",
  density: "default",
  colors: { primary: "#3b82f6" }
}

```

All components using `rounded-[var(--radius)]` will automatically adopt the new `1.25rem` value, ensuring global consistency without hunting through individual component files.

## Summary

- **Configuration centralization**: Edit [`prompts.config.ts`](https://github.com/f/prompts.chat/blob/main/prompts.config.ts) to set `radius`, `variant`, `density`, and `colors.primary` using the `ThemeConfig` type from [`src/lib/config/index.ts`](https://github.com/f/prompts.chat/blob/main/src/lib/config/index.ts).
- **Runtime conversion**: [`src/app/layout.tsx`](https://github.com/f/prompts.chat/blob/main/src/app/layout.tsx) uses `hexToOklch()` and the `radiusValues` lookup to generate `--radius`, `--primary`, and `--primary-foreground` CSS variables.
- **Component consumption**: UI elements reference these variables via Tailwind arbitrary values like `rounded-[var(--radius)]` and utility classes like `bg-primary`.
- **Environment flexibility**: Use `PCHAT_THEME_*` and `PCHAT_COLOR` variables to override settings without touching code, handled by `applyEnvOverrides`.
- **No rebuild required**: The system uses a bundled Tailwind plugin and CSS custom properties, eliminating the need to modify [`tailwind.config.ts`](https://github.com/f/prompts.chat/blob/main/tailwind.config.ts) or recompile stylesheets when theming changes.

## Frequently Asked Questions

### Where is the tailwind.config.ts file in prompts.chat?

The project does not expose a user-editable [`tailwind.config.ts`](https://github.com/f/prompts.chat/blob/main/tailwind.config.ts). Instead, it relies on a bundled Tailwind plugin that maps utility classes (like `bg-primary`) to CSS variables. These variables are generated at runtime by [`src/app/layout.tsx`](https://github.com/f/prompts.chat/blob/main/src/app/layout.tsx) based on your [`prompts.config.ts`](https://github.com/f/prompts.chat/blob/main/prompts.config.ts) settings, allowing dynamic theming without CSS rebuilds.

### Can I add multiple custom colors beyond the primary color?

The current `ThemeConfig` interface in [`src/lib/config/index.ts`](https://github.com/f/prompts.chat/blob/main/src/lib/config/index.ts) is optimized for a single `primary` color. To add secondary or semantic colors (success, warning, danger), extend the `ThemeConfig` type definition, add the new properties to your [`prompts.config.ts`](https://github.com/f/prompts.chat/blob/main/prompts.config.ts), and update [`src/app/layout.tsx`](https://github.com/f/prompts.chat/blob/main/src/app/layout.tsx) (around lines 116-176) to inject additional CSS variables (e.g., `--secondary`) alongside the existing `--primary` logic.

### How do I change the border radius for only specific components?

Since the global theme sets `--radius` on the `<html>` element, all components using `rounded-[var(--radius)]` share that value. For component-specific overrides, use static Tailwind utility classes (e.g., `rounded-md` or `rounded-none`) directly in that component's JSX, or define a new CSS variable in [`layout.tsx`](https://github.com/f/prompts.chat/blob/main/layout.tsx) and reference it selectively.

### Why does prompts.chat use OKLCH instead of HSL or RGB?

The `hexToOklch()` function in [`src/app/layout.tsx`](https://github.com/f/prompts.chat/blob/main/src/app/layout.tsx) converts hex colors to the OKLCH color space because it provides perceptual uniformity—meaning equal changes in lightness values produce visually consistent results regardless of hue. This ensures that generated accessibility colors and opacity variations (like `bg-primary/90`) remain harmonious and predictable across different brand palettes.