Design Tokens

Last updated on 2026-08-26

The Booking Kit uses an oklch-based design token system defined in app/globals.css and consumed by Tailwind CSS 4. Every color, radius, and font is controlled by CSS custom properties, so you can rebrand the entire kit by editing one file.

The oklch Color System

All colors use the oklch color space -- a perceptually uniform model where adjusting lightness, chroma, or hue produces predictable results. The format is:

oklch(lightness chroma hue)
  • Lightness (0-1): 0 is black, 1 is white
  • Chroma (0-0.4): 0 is gray, higher is more saturated
  • Hue (0-360): the color angle on the color wheel

Default Palette -- Soft Coral

The Booking Kit ships with a warm coral primary (hue 30) and teal-gray neutrals (hue 175-200):

:root {
  --primary: oklch(0.55 0.11 30);         /* Coral */
  --secondary: oklch(0.75 0.1 55);        /* Warm amber */
  --background: oklch(0.98 0.006 175);    /* Soft teal-white */
  --foreground: oklch(0.22 0.02 200);     /* Dark teal-gray */
}

Changing the Primary Hue

To rebrand the kit, change the hue value (the third number) in the --primary token:

/* Blue brand */
--primary: oklch(0.55 0.11 240);
--ring: oklch(0.55 0.11 240);
--sidebar-primary: oklch(0.55 0.11 240);

/* Green brand */
--primary: oklch(0.55 0.11 150);
--ring: oklch(0.55 0.11 150);
--sidebar-primary: oklch(0.55 0.11 150);

/* Purple brand */
--primary: oklch(0.55 0.11 300);
--ring: oklch(0.55 0.11 300);
--sidebar-primary: oklch(0.55 0.11 300);

Update the same hue in both :root (light mode) and .dark (dark mode) blocks, and across --primary, --ring, --sidebar-primary, and --sidebar-ring.

Semantic Color Tokens

Surface & Text

Token Light Mode Purpose
--background oklch(0.98 0.006 175) Page background
--foreground oklch(0.22 0.02 200) Body text
--card oklch(1 0 0) Card backgrounds
--card-foreground oklch(0.22 0.02 200) Card text
--popover oklch(1 0 0) Popover/dropdown backgrounds
--muted oklch(0.96 0.006 175) Muted backgrounds (empty states, secondary surfaces)
--muted-foreground oklch(0.45 0.02 195) Secondary text, captions, placeholders

Interactive

Token Light Mode Purpose
--primary oklch(0.55 0.11 30) Primary buttons, active states, links
--primary-foreground oklch(0.98 0.005 30) Text on primary backgrounds
--secondary oklch(0.75 0.1 55) Secondary buttons, less prominent actions
--accent oklch(0.94 0.01 175) Hover states, subtle highlights
--accent-foreground oklch(0.35 0.08 30) Text on accent backgrounds
--border oklch(0.91 0.008 175) Borders, dividers
--input oklch(0.91 0.008 175) Input borders
--ring oklch(0.55 0.11 30) Focus ring color

Status Colors

Token Light Mode Purpose
--destructive oklch(0.58 0.22 27) Errors, cancel actions, destructive buttons
--success oklch(0.55 0.15 150) Confirmed bookings, positive trends
--success-foreground oklch(0.98 0.01 150) Text on success backgrounds
--warning oklch(0.6 0.14 75) Pending states, caution messages
--warning-foreground oklch(0.2 0.05 75) Text on warning backgrounds
--info oklch(0.55 0.16 240) Informational badges, links
--info-foreground oklch(0.98 0.01 240) Text on info backgrounds

Chart Colors

Five chart colors for Recharts visualizations:

--chart-1: oklch(0.55 0.11 30);   /* Primary coral */
--chart-2: oklch(0.65 0.1 201);   /* Teal */
--chart-3: oklch(0.6 0.12 276);   /* Purple */
--chart-4: oklch(0.55 0.1 96);    /* Green */
--chart-5: oklch(0.65 0.1 326);   /* Pink */

Dedicated tokens for the admin sidebar:

--sidebar: oklch(0.975 0.006 175);
--sidebar-foreground: oklch(0.22 0.02 200);
--sidebar-primary: oklch(0.55 0.11 30);
--sidebar-primary-foreground: oklch(0.98 0.005 30);
--sidebar-accent: oklch(0.93 0.01 175);
--sidebar-accent-foreground: oklch(0.35 0.08 30);
--sidebar-border: oklch(0.91 0.008 175);
--sidebar-ring: oklch(0.55 0.11 30);

Dark Mode Tokens

Dark mode values are defined in the .dark selector. The dark palette uses the same hue angles with adjusted lightness and chroma:

.dark {
  --background: oklch(0.17 0.015 195);
  --foreground: oklch(0.96 0.005 195);
  --primary: oklch(0.7 0.11 30);
  --primary-foreground: oklch(0.17 0.015 195);
  /* ... */
}

Dark mode is activated by the ThemeToggle component and powered by next-themes with class-based switching.

Font Configuration

Three fonts are loaded in app/layout.tsx via next/font/google:

Font CSS Variable Usage
Figtree --font-figtree Headings (font-heading)
Mulish --font-mulish Body text (font-sans)
IBM Plex Mono --font-plex-mono Code and monospace (font-mono)

Swapping Fonts

To change fonts, update the imports in app/layout.tsx:

import { Inter, DM_Sans, JetBrains_Mono } from "next/font/google"

const inter = Inter({ variable: "--font-mulish", subsets: ["latin"] })
const dmSans = DM_Sans({ variable: "--font-figtree", subsets: ["latin"] })
const jetBrains = JetBrains_Mono({ variable: "--font-plex-mono", subsets: ["latin"], weight: ["400", "500"] })

The CSS variable names in globals.css remain the same, so no other changes are needed.

Radius System

Border radius uses a base --radius value with computed scales:

--radius: 0.875rem;              /* Base: 14px */
--radius-sm: calc(var(--radius) * 0.6);   /* 8.4px */
--radius-md: calc(var(--radius) * 0.8);   /* 11.2px */
--radius-lg: var(--radius);               /* 14px */
--radius-xl: calc(var(--radius) * 1.4);   /* 19.6px */
--radius-2xl: calc(var(--radius) * 1.8);  /* 25.2px */

Change the base --radius value to adjust all border radii proportionally.

Usage in Tailwind

Design tokens are consumed via Tailwind CSS utility classes:

<div className="bg-background text-foreground border-border">
  <button className="bg-primary text-primary-foreground rounded-lg">
    Confirm Booking
  </button>
  <span className="text-muted-foreground">Last updated 2 hours ago</span>
  <Badge className="bg-success text-success-foreground">Confirmed</Badge>
</div>

Next Steps