# Styling (/docs/styling)



## Overview [#overview]

LoveUI uses CSS variables for colors and Tailwind CSS for component classes.

CSS variables make the components easier to theme because the same token can be reused across buttons, alerts, badges, forms, popovers, and dark mode.

You can use the default palette, replace values with your own brand colors, or add more tokens for your app.

## How styling works [#how-styling-works]

The default components use semantic variables instead of hard-coded colors.

For example:

* `--background` controls the app background.
* `--foreground` controls default text.
* `--card` and `--card-foreground` control card surfaces.
* `--border` controls borders.
* `--ring` controls focus rings.
* `--success`, `--warning`, `--info`, and `--destructive` control state UI.

This keeps the component code readable. A button can use `bg-primary` instead of a fixed color value.

## Installation [#installation]

<CodeTabs>
  <TabsList>
    <TabsTab value="cli">
      CLI
    </TabsTab>

    <TabsTab value="manual">
      Manual
    </TabsTab>
  </TabsList>

  <TabsPanel value="cli">
    ```bash
    npx love-ui@latest add colors-zinc
    ```

    This adds the default color variables.
  </TabsPanel>

  <TabsPanel value="manual">
    <Steps>
      <Step>
        Copy these variables into your global stylesheet (for example `app/globals.css`):
      </Step>

      ```css title="app/globals.css"
      @theme inline {
        --color-destructive-foreground: var(--destructive-foreground);
        --color-info: var(--info);
        --color-info-foreground: var(--info-foreground);
        --color-success: var(--success);
        --color-success-foreground: var(--success-foreground);
        --color-warning: var(--warning);
        --color-warning-foreground: var(--warning-foreground);
      }

      :root {
        --background: oklch(1 0 0);
        --foreground: oklch(0.21 0.006 285.885);
        --card: oklch(1 0 0);
        --card-foreground: oklch(0.21 0.006 285.885);
        --popover: oklch(1 0 0);
        --popover-foreground: oklch(0.21 0.006 285.885);
        --primary: oklch(0.274 0.006 286.033);
        --primary-foreground: oklch(0.985 0 0);
        --secondary: oklch(0 0 0 / 4%);
        --secondary-foreground: oklch(0.21 0.006 285.885);
        --muted: oklch(0 0 0 / 4%);
        --muted-foreground: oklch(0.442 0.017 285.786);
        --accent: oklch(0 0 0 / 4%);
        --accent-foreground: oklch(0.21 0.006 285.885);
        --destructive: oklch(0.637 0.237 25.331);
        --destructive-foreground: oklch(0.505 0.213 27.518);
        --info: oklch(0.623 0.214 259.815);
        --info-foreground: oklch(0.488 0.243 264.376);
        --success: oklch(0.696 0.17 162.48);
        --success-foreground: oklch(0.508 0.118 165.612);
        --warning: oklch(0.769 0.188 70.08);
        --warning-foreground: oklch(0.555 0.163 48.998);
        --border: oklch(0 0 0 / 10%);
        --input: oklch(0 0 0 / 10%);
        --ring: oklch(0.705 0.015 286.067);
      }

      .dark {
        --background: oklch(0.141 0.005 285.823);
        --foreground: oklch(0.967 0.001 286.375);
        --card: color-mix(
          in srgb,
          oklch(0.21 0.006 285.885) 80%,
          oklch(0.141 0.005 285.823)
        );
        --card-foreground: oklch(0.967 0.001 286.375);
        --popover: oklch(0.21 0.006 285.885);
        --popover-foreground: oklch(0.967 0.001 286.375);
        --primary: oklch(0.967 0.001 286.375);
        --primary-foreground: oklch(0.21 0.006 285.885);
        --secondary: oklch(1 0 0 / 8%);
        --secondary-foreground: oklch(0.967 0.001 286.375);
        --muted: oklch(1 0 0 / 8%);
        --muted-foreground: oklch(0.705 0.015 286.067);
        --accent: oklch(1 0 0 / 8%);
        --accent-foreground: oklch(0.967 0.001 286.375);
        --destructive: oklch(0.637 0.237 25.331);
        --destructive-foreground: oklch(0.704 0.191 22.216);
        --info: oklch(0.623 0.214 259.815);
        --info-foreground: oklch(0.707 0.165 254.624);
        --success: oklch(0.696 0.17 162.48);
        --success-foreground: oklch(0.765 0.177 163.223);
        --warning: oklch(0.769 0.188 70.08);
        --warning-foreground: oklch(0.828 0.189 84.429);
        --border: oklch(1 0 0 / 12%);
        --input: oklch(1 0 0 / 12%);
        --ring: oklch(0.552 0.016 285.938);
      }
      ```
    </Steps>
  </TabsPanel>
</CodeTabs>

## Extended Color Variables [#extended-color-variables]

LoveUI adds extra variables for state-based UI such as alerts, badges, validation, and status messages:

* `--destructive-foreground`: Foreground color for destructive actions
* `--info`: Information state color
* `--info-foreground`: Foreground color for information states
* `--success`: Success state color
* `--success-foreground`: Foreground color for success states
* `--warning`: Warning state color
* `--warning-foreground`: Foreground color for warning states

If you install with CLI, these are added automatically.

## Customizing the theme [#customizing-the-theme]

To customize LoveUI, change the values in `:root` and `.dark`.

Keep the token names stable when possible. Components expect those names, and changing only the values lets every component update together.

When changing colors, check:

* Text contrast on light and dark backgrounds.
* Focus ring visibility.
* Disabled state visibility.
* Alert and badge readability.
* Destructive action clarity.

## Adding component-specific styles [#adding-component-specific-styles]

For one-off changes, update the class names in the copied component file.

For reusable changes, add or adjust variants in the component. This is useful for buttons, badges, cards, alerts, and other components that need a small set of approved styles.

Avoid hiding important state with only color. Pair color with text, icons, or labels when the state matters.
