TuMarca

Theming

Customize the look and feel of your components using CSS variables and Tailwind CSS.

Theming

Saastro UI uses CSS variables for theming, making it easy to customize colors and styles across all components.

CSS Variables

The theme is defined using CSS variables in your global stylesheet:

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 0 0% 3.9%;

    --card: 0 0% 100%;
    --card-foreground: 0 0% 3.9%;

    --popover: 0 0% 100%;
    --popover-foreground: 0 0% 3.9%;

    --primary: 0 0% 9%;
    --primary-foreground: 0 0% 98%;

    --secondary: 0 0% 96.1%;
    --secondary-foreground: 0 0% 9%;

    --muted: 0 0% 96.1%;
    --muted-foreground: 0 0% 45.1%;

    --accent: 0 0% 96.1%;
    --accent-foreground: 0 0% 9%;

    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 0 0% 98%;

    --border: 0 0% 89.8%;
    --input: 0 0% 89.8%;
    --ring: 0 0% 3.9%;

    --radius: 0.5rem;
  }
}

Color Format

Colors are defined using HSL values without the hsl() function:

--primary: 0 0% 9%;

This allows Tailwind to apply opacity modifiers:

<div class="bg-primary/50">50% opacity</div>

Customizing Colors

Using Base Colors

Saastro supports several base color schemes:

  • slate (default)
  • gray
  • zinc
  • neutral
  • stone

Set your preferred base color during initialization:

npx saastro init --base-color zinc

Custom Colors

To create a custom color scheme, update the CSS variables:

:root {
  /* Custom blue theme */
  --primary: 221.2 83.2% 53.3%;
  --primary-foreground: 210 40% 98%;

  /* Custom accent */
  --accent: 210 40% 96.1%;
  --accent-foreground: 222.2 47.4% 11.2%;
}

Using the cn Utility

The cn utility merges Tailwind classes and handles conflicts:

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

// Merge classes
cn("px-4 py-2", "px-6") // => "py-2 px-6"

// Conditional classes
cn("base-class", isActive && "active-class")

// With variants
cn(buttonVariants({ variant, size }), className)

Component Variants

Components use tailwind-variants for variant management:

import { tv } from "tailwind-variants";

const button = tv({
  base: "inline-flex items-center justify-center rounded-md text-sm font-medium",
  variants: {
    variant: {
      default: "bg-primary text-primary-foreground hover:bg-primary/90",
      destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
      outline: "border border-input bg-background hover:bg-accent",
      secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
      ghost: "hover:bg-accent hover:text-accent-foreground",
      link: "text-primary underline-offset-4 hover:underline",
    },
    size: {
      default: "h-10 px-4 py-2",
      sm: "h-9 rounded-md px-3",
      lg: "h-11 rounded-md px-8",
      icon: "h-10 w-10",
    },
  },
  defaultVariants: {
    variant: "default",
    size: "default",
  },
});

Typography

Base typography styles are applied automatically:

@layer base {
  body {
    @apply bg-background text-foreground;
  }
}

Next Steps