Usage

Always use semantic tokens instead of raw Tailwind colors. This ensures your UI automatically adapts to light and dark mode.

Correct

<div className="bg-kumo-base text-kumo-default border-kumo-line">
  <button className="bg-kumo-brand text-white">Primary</button>
  <button className="bg-kumo-control text-kumo-default">Secondary</button>
</div>

Incorrect

<!-- Never use raw Tailwind colors -->
<div className="bg-white dark:bg-gray-900 text-black dark:text-white">
  <button className="bg-blue-500">Primary</button>
</div>
Lint rules enforce this: The no-primitive-colors rule will flag any raw Tailwind colors like bg-blue-500.

Mode

Set data-mode on a parent element to control light/dark mode. Never use Tailwind's dark: variant—semantic tokens handle dark mode automatically via CSS light-dark().

// Set mode on html or body
<html data-mode="light">  // Light mode
<html data-mode="dark">   // Dark mode

// Components automatically adapt - no dark: variants needed
<div className="bg-kumo-base text-kumo-default" />

Themes

Themes override semantic token values while preserving the same token names. Set data-theme on a parent element to apply a theme.

Available Themes

  • kumo — Default theme (no attribute needed)
  • fedramp — Government compliance styling
// Apply a theme to a section or the whole app
<div data-theme="fedramp">
  {/* All Kumo components inside use fedramp token overrides */}
  <Button>FedRAMP Styled</Button>
</div>

// Themes work with both light and dark mode
<html data-mode="dark" data-theme="fedramp">

Theme Generator

Themes are defined in a centralized config and generated as CSS files. The theme generator ensures consistency across all themes.

# List all tokens and their theme overrides
pnpm --filter @cloudflare/kumo codegen:themes --list

# Generate theme CSS files
pnpm --filter @cloudflare/kumo codegen:themes

# Preview changes without writing files
pnpm --filter @cloudflare/kumo codegen:themes --dry-run

Theme config: packages/kumo/scripts/theme-generator/config.ts

Creating a New Theme

Add theme overrides in the config file. Only override tokens that need to change—all other tokens inherit from the base kumo theme.

// In scripts/theme-generator/config.ts
export const THEME_CONFIG: ThemeConfig = {
  color: {
    "kumo-base": {
      newName: "",
      theme: {
        kumo: {
          light: "var(--color-white, #fff)",
          dark: "var(--color-black, #000)",
        },
        // Add your theme override
        myTheme: {
          light: "#f0f4f8",
          dark: "#1a1f2e",
        },
      },
    },
    // ... other tokens
  },
};

// Add to available themes
export const AVAILABLE_THEMES = ["kumo", "fedramp", "myTheme"] as const;

Then run pnpm codegen:themes to generate the CSS.

Token Reference

Toggle the theme in the header to see how tokens adapt. Tokens marked as "global" are explicit opt-in classes available regardless of theme.

Colors

Displaying 32 tokens

Text Colors (10)

--text-color-kumo-default
Lightvar(--color-neutral-900, oklch(21% 0.006 285.885))
Darkvar(--color-neutral-100, oklch(97% 0 0))
--text-color-kumo-inverse
Lightvar(--color-neutral-100, oklch(97% 0 0))
Darkvar(--color-neutral-900, oklch(20.5% 0 0))
--text-color-kumo-strong
Lightvar(--color-neutral-600, oklch(43.9% 0 0))
Darkvar(--color-neutral-400, oklch(70.8% 0 0))
--text-color-kumo-subtle
Lightvar(--color-neutral-500, oklch(55.6% 0 0))
Darkvar(--color-neutral-50, oklch(98.5% 0 0))
--text-color-kumo-inactive
Lightvar(--color-neutral-400, oklch(70.8% 0 0))
Darkvar(--color-neutral-400, oklch(70.8% 0 0))
--text-color-kumo-brand
Light#f6821f
Dark#f6821f
--text-color-kumo-link
Lightvar(--color-blue-800, oklch(42.4% 0.199 265.638))
Darkvar(--color-blue-400, oklch(70.7% 0.165 254.624))
--text-color-kumo-success
Lightvar(--color-green-500, oklch(72.3% 0.219 149.579))
Darkvar(--color-green-500, oklch(72.3% 0.219 149.579))
--text-color-kumo-danger
Lightvar(--color-red-500, oklch(63.7% 0.237 25.331))
Darkvar(--color-red-400, oklch(70.4% 0.191 22.216))
--text-color-kumo-warning
Lightvar(--color-yellow-800, oklch(47.6% 0.114 61.907))
Darkvar(--color-yellow-400, oklch(85.2% 0.199 91.936))

Surface, State & Theme Colors (22)

--color-kumo-base
Lightvar(--color-white, #fff)
Darkvar(--color-black, #000)
--color-kumo-elevated
Lightvar(--color-neutral-25, oklch(0.99 0 0))
Darkvar(--color-neutral-950, oklch(14.5% 0 0))
--color-kumo-recessed
Lightvar(--color-neutral-250, oklch(0.9 0 0))
Darkvar(--color-neutral-750, oklch(0.31 0 0))
--color-kumo-overlay
Lightvar(--color-neutral-50, oklch(98.5% 0 0))
Darkvar(--color-neutral-800, oklch(26.9% 0 0))
--color-kumo-contrast
Lightvar(--color-neutral-900, oklch(20.5% 0 0))
Darkvar(--color-neutral-100, oklch(97% 0 0))
--color-kumo-control
Lightvar(--color-white, #fff)
Darkvar(--color-neutral-900, oklch(21% 0.006 285.885))
--color-kumo-tint
Lightvar(--color-neutral-150, oklch(0.96 0 0))
Darkvar(--color-neutral-850, oklch(0.23 0 0))
--color-kumo-interact
Lightvar(--color-neutral-300, oklch(87% 0 0))
Darkvar(--color-neutral-700, oklch(37.1% 0 0))
--color-kumo-fill
Lightvar(--color-neutral-200, oklch(92.2% 0 0))
Darkvar(--color-neutral-800, oklch(26.9% 0 0))
--color-kumo-fill-hover
Lightvar(--color-neutral-200, oklch(92.2% 0 0))
Darkvar(--color-neutral-700, oklch(37.1% 0 0))
--color-kumo-brand
Lightoklch(0.5772 0.2324 260)
Darkoklch(0.5772 0.2324 260)
--color-kumo-brand-hover
Lightvar(--color-blue-700, oklch(48.8% 0.243 264.376))
Darkvar(--color-blue-700, oklch(48.8% 0.243 264.376))
--color-kumo-line
Lightoklch(14.5% 0 0 / 0.1)
Darkvar(--color-neutral-800, oklch(26.9% 0 0))
--color-kumo-ring
Lightvar(--color-neutral-400, oklch(70.8% 0 0))
Darkvar(--color-neutral-600, oklch(43.9% 0 0))
--color-kumo-tip-shadow
Lightvar(--color-gray-200, oklch(92.8% 0.006 264.531))
Darktransparent
--color-kumo-tip-stroke
Lighttransparent
Darkvar(--color-neutral-800, oklch(26.9% 0 0))
--color-kumo-info
Lightvar(--color-blue-500, oklch(62.3% 0.214 259.815))
Darkvar(--color-blue-700, oklch(48.8% 0.243 264.376))
--color-kumo-info-tint
Lightvar(--color-blue-300, oklch(80.9% 0.105 251.813))
Darkvar(--color-blue-900, oklch(37.9% 0.146 265.522))
--color-kumo-warning
Lightvar(--color-yellow-500, oklch(79.5% 0.184 86.047))
Darkvar(--color-yellow-700, oklch(55.4% 0.135 66.442))
--color-kumo-warning-tint
Lightvar(--color-yellow-300, oklch(90.5% 0.182 98.111))
Darkvar(--color-yellow-900, oklch(42.1% 0.095 57.708))
--color-kumo-danger
Lightvar(--color-red-500, oklch(63.7% 0.237 25.331))
Darkvar(--color-red-700, oklch(50.5% 0.213 27.518))
--color-kumo-danger-tint
Lightvar(--color-red-300, oklch(80.8% 0.114 19.571))
Darkvar(--color-red-900, oklch(39.6% 0.141 25.723))