| 1 | # Styling & Customization |
| 2 | |
| 3 | See [customization.md](../customization.md |
| 4 | |
| 5 | ## Contents |
| 6 | |
| 7 | - Semantic colors |
| 8 | - Built-in variants first |
| 9 | - className for layout only |
| 10 | - No space-x-_ / space-y-_ |
| 11 | - Prefer size-_ over w-_ h-\* when equal |
| 12 | - Prefer truncate shorthand |
| 13 | - No manual dark: color overrides |
| 14 | - Use cn() for conditional classes |
| 15 | - No manual z-index on overlay components |
| 16 | |
| 17 | --- |
| 18 | |
| 19 | ## Semantic colors |
| 20 | |
| 21 | **Incorrect:** |
| 22 | |
| 23 | ```tsx |
| 24 | <div className="bg-blue-500 text-white |
| 25 | <p className=" |
| 26 | </div> |
| 27 | ``` |
| 28 | |
| 29 | **Correct:** |
| 30 | |
| 31 | ```tsx |
| 32 | <div className="bg-primary text-primary-foreground |
| 33 | <p className=" |
| 34 | </div> |
| 35 | ``` |
| 36 | |
| 37 | --- |
| 38 | |
| 39 | ## No raw color values for status/state indicators |
| 40 | |
| 41 | For positive, negative, or status indicators, use Badge variants, semantic tokens like `text-destructive`, or define custom CSS variables - don't reach for raw Tailwind colors. |
| 42 | |
| 43 | **Incorrect:** |
| 44 | |
| 45 | ```tsx |
| 46 | <span className="text-emerald-600 |
| 47 | <span className="text-green-500 |
| 48 | <span className="text-red-600 |
| 49 | ``` |
| 50 | |
| 51 | **Correct:** |
| 52 | |
| 53 | ```tsx |
| 54 | <Badge variant=" |
| 55 | <Badge>Active</Badge |
| 56 | <span className="text-destructive |
| 57 | ``` |
| 58 | |
| 59 | If you need a success/positive color that doesn't exist as a semantic token, use a Badge variant or ask the user about adding a custom CSS variable to the theme (see [customization.md](../customization.md |
| 60 | |
| 61 | --- |
| 62 | |
| 63 | ## Built-in variants first |
| 64 | |
| 65 | **Incorrect:** |
| 66 | |
| 67 | ```tsx |
| 68 | <Button className=" |
| 69 | ``` |
| 70 | |
| 71 | **Correct:** |
| 72 | |
| 73 | ```tsx |
| 74 | <Button variant=" |
| 75 | ``` |
| 76 | |
| 77 | --- |
| 78 | |
| 79 | ## className for layout only |
| 80 | |
| 81 | Use `className` for layout (e.g. `max-w-md`, ` |
| 82 | |
| 83 | **Incorrect:** |
| 84 | |
| 85 | ```tsx |
| 86 | <Card className=" |
| 87 | <CardContent>Dashboard</CardContent |
| 88 | </Card> |
| 89 | ``` |
| 90 | |
| 91 | **Correct:** |
| 92 | |
| 93 | ```tsx |
| 94 | <Card className=" |
| 95 | <CardContent>Dashboard</CardContent |
| 96 | </Card> |
| 97 | ``` |
| 98 | |
| 99 | To customize a component's appearance, prefer these approaches in order: |
| 100 | |
| 101 | 1. **Built-in variants** - |
| 102 | 2. **Semantic color tokens** - |
| 103 | 3. **CSS variables** - define custom colors in the global CSS file (see |
| 104 | |
| 105 | --- |
| 106 | |
| 107 | ## No space-x-_ / space-y-_ |
| 108 | |
| 109 | Use `gap-*` instead. `space-y-4` → ` |
| 110 | |
| 111 | ```tsx |
| 112 | <div className="flex flex-col gap-4 |
| 113 | <Input /> |
| 114 | <Input /> |
| 115 | <Button>Submit</Button |
| 116 | </div> |
| 117 | ``` |
| 118 | |
| 119 | --- |
| 120 | |
| 121 | ## Prefer size-_ over w-_ h-\* |
| 122 | |
| 123 | `size-10` not `w-10 h-10`. Applies to icons, avatars, skeletons, etc. |
| 124 | |
| 125 | --- |
| 126 | |
| 127 | ## Prefer truncate shorthand |
| 128 | |
| 129 | `truncate` not `overflow-hidden text-ellipsis whitespace-nowrap`. |
| 130 | |
| 131 | --- |
| 132 | |
| 133 | ## No manual dark: color overrides |
| 134 | |
| 135 | Use semantic tokens - they handle light/dark via CSS variables. `bg-background text-foreground` not `bg-white dark:bg-gray-950`. |
| 136 | |
| 137 | --- |
| 138 | |
| 139 | ## Use cn() for conditional classes |
| 140 | |
| 141 | Use the `cn()` utility from the project for conditional or merged class names. Don't write manual ternaries in className strings. |
| 142 | |
| 143 | **Incorrect:** |
| 144 | |
| 145 | ```tsx |
| 146 | <div className={` |
| 147 | ``` |
| 148 | |
| 149 | **Correct:** |
| 150 | |
| 151 | ```tsx |
| 152 | import { cn } |
| 153 | |
| 154 | <div className={cn |
| 155 | ``` |
| 156 | |
| 157 | --- |
| 158 | |
| 159 | ## No manual z-index on overlay components |
| 160 | |
| 161 | `Dialog`, `Sheet`, `Drawer |