Documentation
Documentation
Introduction

Getting Started

Getting StartedInstallationQuick StartProject Structure

Architecture

Architecture OverviewTech StacktRPC MiddlewareDesign Principles

Patterns

Code Patterns & ConventionsFeature ModulesError HandlingType Safety

Database

DatabaseSchema DefinitionDatabase OperationsMigrationsCaching

API

tRPCProceduresRouterstRPC Proxy Setup
APIsOpenAPIREST Endpoints

Auth & Access

AuthenticationConfigurationOAuth ProvidersRolesSession Management
AuthorizationUser RolesPermissions

Routing & i18n

RoutingDeclarative RoutingNavigation
InternationalizationTranslationsLocale Routing

Components & UI

ComponentsButtonsFormsNavigationDialogs
StylesTailwind CSSThemingTypography

Storage

StorageConfigurationUsageBuckets

Configuration

ConfigurationEnvironment VariablesFeature Flags

Templates

Template GuidesCreate New FeatureCreate New PageCreate Database TableCreate tRPC RouterAdd Translations

Development

DevelopmentCommandsAI AgentsBest Practices

Tailwind CSS

Tailwind configuration and utilities

Tailwind CSS provides utility-first styling with a customized configuration for this project.

Configuration

Tailwind is configured in tailwind.config.ts:

import type { Config } from "tailwindcss";

const config: Config = {
  darkMode: ["class"],
  content: [
    "./src/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        // Semantic color tokens
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        // ... more colors
      },
      // Custom spacing, fonts, etc.
    },
  },
};

Design Tokens

Colors

Always use semantic color tokens instead of specific colors:

// ✅ Good - semantic tokens
<div className="bg-primary text-primary-foreground" />
<p className="text-muted-foreground" />

// ❌ Bad - specific colors
<div className="bg-blue-500 text-white" />
<p className="text-gray-600" />

Color Tokens

TokenPurposeCSS Variable
backgroundPage background--background
foregroundPrimary text--foreground
primaryPrimary actions--primary
primary-foregroundText on primary--primary-foreground
secondarySecondary actions--secondary
mutedMuted backgrounds--muted
muted-foregroundMuted text--muted-foreground
accentAccent highlights--accent
destructiveDestructive actions--destructive
borderBorder colors--border
ringFocus rings--ring

Spacing

Use the default Tailwind spacing scale:

<div className="p-4">       {/* 16px padding */}
<div className="m-8">       {/* 32px margin */}
<div className="gap-2">     {/* 8px gap */}
<div className="space-y-6"> {/* 24px vertical spacing */}
ClassSize
*-00px
*-14px
*-28px
*-312px
*-416px
*-624px
*-832px
*-1248px
*-1664px

cn() Helper

Use the cn() utility for combining classes:

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

<div className={cn(
  "base-class",
  isActive && "active-class",
  variant === "primary" && "primary-class"
)} />

This function:

  • Combines multiple class strings
  • Handles conditional classes
  • Resolves Tailwind conflicts using tailwind-merge

Example

// Without cn()
<div className={`p-4 ${isActive ? "bg-primary" : "bg-secondary"} ${className}`} />

// With cn()
<div className={cn(
  "p-4",
  isActive ? "bg-primary" : "bg-secondary",
  className
)} />

Customization

Extending Colors

Add custom colors in tailwind.config.ts:

theme: {
  extend: {
    colors: {
      brand: {
        50: "#f0f9ff",
        100: "#e0f2fe",
        // ... more shades
      },
    },
  },
},

Then use: bg-brand-500, text-brand-600, etc.

Custom Utilities

Add custom utilities using @layer:

/* src/styles/globals.css */
@layer utilities {
  .text-balance {
    text-wrap: balance;
  }
  
  .scrollbar-hide {
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
}

Common Patterns

Container

<div className="container mx-auto px-4">
  {/* Centered container with padding */}
</div>

Card

<div className="rounded-lg border bg-card p-6 shadow-sm">
  {/* Card with border, background, padding, shadow */}
</div>

Flex Layout

<div className="flex items-center justify-between gap-4">
  {/* Horizontal flex with center alignment and gap */}
</div>

Grid Layout

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  {/* Responsive grid */}
</div>

Responsive Design

Use breakpoint prefixes:

<div className="w-full md:w-1/2 lg:w-1/3">
  {/* Responsive widths */}
</div>
PrefixBreakpoint
sm:640px
md:768px
lg:1024px
xl:1280px
2xl:1536px

Dark Mode

Use the dark: prefix for dark mode styles:

<div className="bg-white dark:bg-gray-900">
  {/* White in light mode, dark gray in dark mode */}
</div>

Dark mode uses the class strategy, controlled by the theme provider.

Arbitrary Values

Avoid Arbitrary Values

Do not use arbitrary values like w-[100px] or text-[#ff0000]. Use design tokens and semantic classes for consistency.

// ❌ Bad - arbitrary values
<div className="w-[123px] text-[#ff0000]" />

// ✅ Good - design tokens
<div className="w-32 text-destructive" />

Best Practices

  1. Use semantic colors - Always use color tokens like primary, never specific colors
  2. Follow spacing scale - Use the standard spacing scale for consistency
  3. Use cn() helper - For combining and conditional classes
  4. Avoid arbitrary values - Stick to design tokens and theme values
  5. Mobile-first - Write base styles for mobile, add responsive variants

On this page

Configuration
Design Tokens
Colors
Color Tokens
Spacing
cn() Helper
Example
Customization
Extending Colors
Custom Utilities
Common Patterns
Container
Card
Flex Layout
Grid Layout
Responsive Design
Dark Mode
Arbitrary Values
Best Practices