Files
cloudflare-domain-manager/.agents/skills/shadcn/rules/styling.md
T
Denozordec b1467575c5
Build, Test, and Push CFDM Docker Image / test (push) Failing after 3h13m2s
Build, Test, and Push CFDM Docker Image / create-release (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been cancelled
Refactor project structure to use pnpm monorepo; update Dockerfile and related configurations for frontend build process. Adjust .dockerignore and .gitignore to reflect new paths. Modify .env.example for cron job timing. Update CONTRIBUTING.md and README.md for new development instructions.
2026-06-15 15:37:36 +07:00

3.7 KiB

Styling & Customization

See customization.md for theming, CSS variables, and adding custom colors.

Contents

  • Semantic colors
  • Built-in variants first
  • className for layout only
  • No space-x-* / space-y-*
  • Prefer size-* over w-* h-* when equal
  • Prefer truncate shorthand
  • No manual dark: color overrides
  • Use cn() for conditional classes
  • No manual z-index on overlay components

Semantic colors

Incorrect:

<div className="bg-blue-500 text-white">
  <p className="text-gray-600">Secondary text</p>
</div>

Correct:

<div className="bg-primary text-primary-foreground">
  <p className="text-muted-foreground">Secondary text</p>
</div>

No raw color values for status/state indicators

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.

Incorrect:

<span className="text-emerald-600">+20.1%</span>
<span className="text-green-500">Active</span>
<span className="text-red-600">-3.2%</span>

Correct:

<Badge variant="secondary">+20.1%</Badge>
<Badge>Active</Badge>
<span className="text-destructive">-3.2%</span>

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).


Built-in variants first

Incorrect:

<Button className="border border-input bg-transparent hover:bg-accent">
  Click me
</Button>

Correct:

<Button variant="outline">Click me</Button>

className for layout only

Use className for layout (e.g. max-w-md, mx-auto, mt-4), not for overriding component colors or typography. To change colors, use semantic tokens, built-in variants, or CSS variables.

Incorrect:

<Card className="bg-blue-100 text-blue-900 font-bold">
  <CardContent>Dashboard</CardContent>
</Card>

Correct:

<Card className="max-w-md mx-auto">
  <CardContent>Dashboard</CardContent>
</Card>

To customize a component's appearance, prefer these approaches in order:

  1. Built-in variants — variant="outline", variant="destructive", etc.
  2. Semantic color tokens — bg-primary, text-muted-foreground.
  3. CSS variables — define custom colors in the global CSS file (see customization.md).

No space-x-* / space-y-*

Use gap-* instead. space-y-4 → flex flex-col gap-4. space-x-2 → flex gap-2.

<div className="flex flex-col gap-4">
  <Input />
  <Input />
  <Button>Submit</Button>
</div>

Prefer size-* over w-* h-* when equal

size-10 not w-10 h-10. Applies to icons, avatars, skeletons, etc.


Prefer truncate shorthand

truncate not overflow-hidden text-ellipsis whitespace-nowrap.


No manual dark: color overrides

Use semantic tokens — they handle light/dark via CSS variables. bg-background text-foreground not bg-white dark:bg-gray-950.


Use cn() for conditional classes

Use the cn() utility from the project for conditional or merged class names. Don't write manual ternaries in className strings.

Incorrect:

<div className={`flex items-center ${isActive ? "bg-primary text-primary-foreground" : "bg-muted"}`}>

Correct:

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

<div className={cn("flex items-center", isActive ? "bg-primary text-primary-foreground" : "bg-muted")}>

No manual z-index on overlay components

Dialog, Sheet, Drawer, AlertDialog, DropdownMenu, Popover, Tooltip, HoverCard handle their own stacking. Never add z-50 or z-[999].