Styling Components

Extending styles via className

All Shavin UI components accept a standard className prop, which is safely merged with internal component styles. Under the hood, we use our customized cn() helper (a wrapper around clsx and tailwind-merge) to ensure clean overrides:

import { cn } from "../../../lib/cn";

export function Button({ className, ...props }) {
  return (
    <button
      className={cn(
        "rounded-[var(--radius-lg)] bg-accent px-4 py-2 text-sm text-accent-fg font-semibold",
        className
      )}
      {...props}
    />
  );
}

Overriding Spacing and Focus rings

Because tailwind-merge resolves utility class conflicts, any class passed via the className prop takes precedence over the internal defaults:

Resolving conflicts

Passing p-6 to a card that defaults to p-4 will merge safely, resulting in a single clean p-6 output class in the DOM.

Inline overrides

You can pass custom inline style block overrides for special cases (e.g. dynamic widths or image background URLs).

Linter Alert: Avoid using arbitrary Tailwind values (like rounded-[12px] or bg-[#ff0000]) inside the class list. Always map overrides back to design system CSS custom variables to prevent breaking theme changes.
Configure Theme
Theme
Accent Color
Custom
Gray Family
Appearance
Radius
Scaling
Panel Style
Heading Font
Body Font