# shadcn/ui conventions ## You own the components - shadcn/ui is **open code copied into your project**, not a runtime dependency. The components live in `components/ui` and you edit them. - Customize in place. Don't build a wrapper layer around them or try to `npm install` the components. - Add with the CLI: `npx shadcn@latest add button dialog …` (run `npx shadcn@latest init` once to scaffold `components.json` + `@/lib/utils`). ## Styling - Merge classes with `cn()` from `@/lib/utils` (clsx + tailwind-merge). Never concatenate class strings by hand — `cn()` resolves Tailwind conflicts. - Define variants with `cva` (class-variance-authority) and surface them via props (e.g. `variant`, `size`). One component, many variants — not many components. - Forward `className` and spread `...props` so callers can extend a component without forking it. ## Radix + accessibility - Components are built on Radix primitives — keep their structure (Trigger / Content / Portal) and `data-[state=…]` styling hooks intact. - Interactive components are client components: keep the `"use client"` directive. Use `lucide-react` for icons. ## Theming - Use semantic tokens (`bg-background`, `text-foreground`, `text-muted-foreground`, `border-input`, `ring`), driven by CSS variables — not raw color utilities like `bg-zinc-900`. - Keep light/dark in the CSS variables; don't branch colors in component logic. ## Anti-patterns - ❌ Re-publishing `components/ui` as an internal package instead of editing in place. - ❌ `` `px-2 ${cond ? "bg-red-500" : ""}` `` instead of `cn("px-2", cond && "bg-red-500")`. - ❌ Hardcoded hex/`bg-*-500` colors that bypass the theme tokens. - ❌ Dropping Radix sub-parts or `"use client"` and reimplementing primitives by hand.