Tailwind Design-System Discipline
Enforces design-token-only Tailwind usage with a fixed class ordering, cn() merging, and a ban on arbitrary values.
Use when: Attach to TSX files in Tailwind v4 projects that define semantic tokens and want every class traceable to the design system.
The skill file
Cursor · .cursor/rules/*.mdc.cursor/rules/*.mdc2833 chars
---
description: Tailwind class conventions — tokens only, ordered classes, cn() merging
globs: "**/*.tsx"
alwaysApply: false
---
# Tailwind rules for this codebase
## Tokens only
- Color classes must reference semantic tokens defined in the theme: `bg-background`, `bg-card`, `text-foreground`, `text-muted-foreground`, `border-border`, `bg-primary text-primary-foreground`, `bg-destructive`. Never use palette colors (`bg-zinc-900`, `text-blue-500`) or hex/rgb values in components.
- Spacing, radius, and shadow come from the scale: `p-4`, `gap-2`, `rounded-md`, `shadow-sm`. If a value isn't on the scale, the design is wrong or the scale needs a token — raise it, don't improvise.
- Dark mode is handled by the tokens themselves. Do not write `dark:` variants for colors; `dark:` is acceptable only for non-color tweaks (e.g. `dark:shadow-none`).
## No arbitrary values
- Square-bracket values are banned: no `w-[417px]`, `text-[13px]`, `bg-[#1a1a2e]`, `mt-[7px]`, `grid-cols-[1fr_2fr]` with magic numbers.
- The only exceptions: CSS-variable passthroughs the system defines (`h-[var(--header-height)]`) and truly content-driven grid templates — and each needs a `// why` comment.
- If you are about to write a bracket, first check: is there a token one step up or down the scale that works? Use it.
## Class ordering
Write classes in this fixed order so diffs stay readable:
1. layout (`flex`, `grid`, `hidden`, `relative`)
2. flex/grid children & alignment (`items-center`, `justify-between`, `gap-2`)
3. sizing (`h-9`, `w-full`, `max-w-md`)
4. spacing (`p-4`, `mx-auto`)
5. typography (`text-sm`, `font-medium`, `tracking-tight`)
6. color & background (`bg-card`, `text-muted-foreground`)
7. borders & radius (`border`, `border-border`, `rounded-lg`)
8. effects (`shadow-sm`, `opacity-50`)
9. transitions & animation (`transition-colors`, `duration-200`)
10. state & responsive variants last (`hover:bg-accent`, `focus-visible:ring-2`, `md:flex-row`)
## Merging with cn()
- Every component that accepts `className` must merge it with `cn()` from `@/lib/utils`, last: `className={cn("flex items-center gap-2", className)}`. Never template-string classes together — `` `${base} ${className}` `` loses Tailwind conflict resolution.
- Conditionals go inside `cn()` as object or `&&` entries: `cn("rounded-md", isActive && "bg-accent")`. No nested ternaries building class strings.
- Variant components use `cva()` with named `variants` and `defaultVariants`; do not branch on a `variant` prop with if/else class assembly.
## Misc
- Prefer `gap-*` over child margins for spacing between siblings. `space-y-*` only for simple text stacks.
- `focus-visible:` (never bare `focus:`) for focus rings, and never remove an outline without replacing it.
- No `@apply` in CSS files except inside the design-system layer itself.
Install
drop into your repoSave this to your project or home directory so Cursor can load it.
path./.cursor/rules/tailwind-design-system-rules.mdc
Discussion
What people are saying
Forks
0 forks of this skillLoading forks…