ToroUI

Styling

How to style Toro UI components with Tailwind CSS.


Toro UI is built on Tailwind CSS v4 and ships no bundled styles. Components are styled with utility classes, giving you full control over their appearance.

Tailwind CSS

All components use Tailwind utility classes for styling. Since the component source lives in your project, you can modify styles directly:

<Button className="rounded-full px-6">
  Rounded Button
</Button>

The cn() utility merges your classes with the component defaults using tailwind-merge, so conflicts are resolved correctly:

import { cn } from "@/lib/utils"

// Your "rounded-full" overrides the component's default border-radius
<Button className={cn("rounded-full", isActive && "bg-green-500")} />

Theming with CSS Variables

Toro UI uses CSS custom properties for theming. All color tokens are defined in OKLCH color space for perceptually uniform color mixing:

:root {
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --muted: oklch(0.97 0 0);
  --accent: oklch(0.97 0 0);
  --destructive: oklch(0.58 0.22 27);
  --border: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
  --radius: 0.625rem;
}

To create a custom theme, override these variables in your globals.css. The same tokens are available for dark mode via the .dark class.

Color Tokens

Each semantic color has a foreground pair for contrast:

TokenUsage
--background / --foregroundPage background and body text
--primary / --primary-foregroundPrimary actions and emphasis
--secondary / --secondary-foregroundSecondary actions
--muted / --muted-foregroundSubdued backgrounds and text
--accent / --accent-foregroundHighlights and hover states
--destructiveErrors and destructive actions
--borderBorders and dividers
--inputInput borders
--ringFocus rings

Use these tokens in your Tailwind classes:

<div className="bg-primary text-primary-foreground">
  Themed content
</div>

Border Radius

The radius scale is derived from a single --radius variable:

--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);

Change --radius once and the entire scale adjusts.

Dark Mode

Toro UI supports dark mode via the .dark class on a parent element, powered by next-themes:

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.87 0 0);
  --primary-foreground: oklch(0.205 0 0);
}

All components automatically adapt — no conditional logic needed in your code.

Data Attributes

Components use data-slot attributes for semantic styling hooks. You can target these in CSS or with Tailwind's arbitrary selectors:

[data-slot="button"] {
  /* Target all buttons */
}
<div className="[&_[data-slot=button]]:w-full">
  <Button>Full width in this context</Button>
</div>

Variants with CVA

Components define variants using class-variance-authority. You can extend or modify variants by editing the component source:

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/80",
        outline: "border border-border bg-background hover:bg-muted",
        ghost: "hover:bg-muted hover:text-foreground",
      },
      size: {
        default: "h-9 px-2.5",
        sm: "h-8 px-2.5 text-xs",
        lg: "h-10 px-4",
      },
    },
  }
)

Since you own the component code, adding a new variant is as simple as adding a new key.