# Styling

> Customize Honest UI's semantic CSS tokens, themes, and copied component classes.

Source: https://www.honestui.com/docs/styling

Honest UI separates visual decisions into CSS tokens and component classes. Tokens keep shared decisions consistent; copied component files give you local control when one component needs to change.

For the complete token reference, start with [Theme](/docs/theme/overview), then open the page for [colors](/docs/theme/colors), [typography](/docs/theme/typography), [spacing](/docs/theme/spacing), [radius](/docs/theme/radius), or [effects](/docs/theme/effects). This page focuses on deciding where a customization belongs.

## Install the shared styles [#install-the-shared-styles]

The `init` command installs the shared style setup and records the stylesheet path in `components.json`:

```bash
npx honestui@latest init
```

Run initialization once before adding UI components. If the project is already initialized, inspect `components.json` instead of replacing it.

## How the token system works [#how-the-token-system-works]

Every Honest UI token starts with `--hui-`; `hui` stands for Honest UI. Tokens are organized from low-level values to semantic roles:

| Layer            | Examples                                                                       | Use it for                        |
| ---------------- | ------------------------------------------------------------------------------ | --------------------------------- |
| Primitive colors | `--hui-neutral-9`, `--hui-accent-10`                                           | Building or replacing a palette   |
| Semantic colors  | `--hui-color-background-base-primary`, `--hui-color-foreground-danger-primary` | Styling components by purpose     |
| Spacing          | `--hui-space-3`, `--hui-space-6`                                               | Gaps, padding, and layout rhythm  |
| Radius           | `--hui-radius-2`, `--hui-radius-full`                                          | Corners and pill shapes           |
| Typography       | `--hui-font-body`, `--hui-font-size-regular`                                   | Type families, sizes, and weights |
| Effects          | `--hui-shadow-floating`, `--hui-focus-ring`                                    | Elevation and focus visibility    |

Components should normally use semantic tokens rather than primitive palette values. For example, a destructive action uses a danger role so the component remains meaningful when the palette changes.

## Use tokens in Tailwind [#use-tokens-in-tailwind]

Copied Honest UI components pass tokens through Tailwind CSS arbitrary-value utilities. Use the same pattern in your own component code:

```tsx
<div
  className="
    rounded-[var(--hui-radius-3)]
    border border-[var(--hui-color-border-base-primary)]
    bg-[var(--hui-color-background-base-secondary)]
    p-[var(--hui-space-5)]
    text-[var(--hui-color-foreground-base-primary)]
    shadow-[var(--hui-shadow-feather)]
  "
/>
```

The same classes resolve in light and dark themes because the browser reads the current variable values. Tailwind v4 also supports shorter custom-property syntax and optional semantic aliases; see [Tailwind CSS](/docs/theme/tailwind) for the complete guidance.

## Light and dark themes [#light-and-dark-themes]

Theme values are scoped with `data-theme`:

```html
<html data-theme="light">
```

Switch the value to `dark` for the dark theme. If you use a theme library, configure it to write the same `data-theme` values.

The primitive gray and accent scales resolve differently for each theme, while semantic roles keep their names. A component can therefore continue using `--hui-color-background-base-primary` without knowing which theme is active.

## Change the palette [#change-the-palette]

Set theme and palette attributes on a shared ancestor:

```html
<html
  data-theme="light"
  data-gray-color="gray"
  data-accent-color="orange"
>
```

Change primitive palette values when you are adapting the entire system. Change semantic values when your product needs a different meaning for a role.

Keep semantic token names stable when possible. Changing a token's value updates every component that uses that role; renaming it requires updating each reference.

## Customize one component [#customize-one-component]

Copied UI components are normal source files. Edit their class names when a change belongs to one component:

```tsx
<Button className="min-w-32">Save profile</Button>
```

Add or adjust a variant when the same option must be reused. Do not create a new shared token for a single isolated value unless it represents a product-wide decision.

## Check every state [#check-every-state]

After changing tokens or classes, verify:

* Default, hover, active, focus, disabled, and invalid states.
* Light and dark themes.
* Text and non-text contrast.
* Focus visibility in keyboard use.
* Meaning without color alone.
* Content at 200% and 400% zoom or equivalent reflow.
* Forced-colors behavior where the component supports system colors.

Use text, icons, labels, or patterns alongside color when a state must be understood. A new palette should not turn warning, success, or destructive states into color-only distinctions.
