Kulcare Platform Style Guide
Status: ✅ Current for Tailwind CSS v4.2.x Last Updated: 2026-04-27
Table of Contents
1. Principles
1.1 Single Source of Truth
All styling lives in @kulcare/ui-kit — no exceptions.
@kulcare/ui-kit (Single Source of Truth)
│
├── src/styles/globals.css # Design tokens + @theme inline
├── src/components/ # Shared components
└── src/theme/ # ThemeProvider, colors
│
▼
MFEs (shell, cms, growth, reports, connect)Every micro-frontend (MFE) imports the same globals.css from ui-kit. Vite deduplicates CSS at build time.
1.2 CSS-First Configuration
Tailwind v4 uses CSS-first configuration via @theme inline in globals.css. There is NO tailwind.config.js in v4.
/* ✅ CORRECT - CSS-first configuration */
@theme inline {
--color-primary: var(--primary);
--radius: var(--radius);
}
/* ❌ WRONG - No tailwind.config.js in v4 */
module.exports = { theme: { extend: { ... } } }1.3 MFE Isolation
Each MFE is independently deployable. Styles are consumed via @import from ui-kit, not copied.
| App | Port | Import Pattern |
|---|---|---|
| shell | 3000 | @import "@kulcare/ui-kit/src/styles/globals.css" |
| cms | 3001 | @import "@kulcare/ui-kit/src/styles/globals.css" |
| growth | 3003 | @import "@kulcare/ui-kit/src/styles/globals.css" |
| reports | 3004 | @import "@kulcare/ui-kit/src/styles/globals.css" |
| connect | 3005 | @import "@kulcare/ui-kit/src/styles/globals.css" |
1.4 Healthcare-First Design
The platform is built for healthcare workflows. Typography prioritizes:
- Monospace fonts for medical values (prescriptions, vital signs, patient IDs)
- Status colors for clinical indicators (normal, warning, critical)
- High contrast for accessibility (WCAG 2.1 AA compliant)
2. Design Tokens
2.1 Token Architecture
CSS Variables (:root / .dark)
│
▼
@theme inline mapping
│
▼
Tailwind Utilities (bg-primary, text-foreground, etc.)File Location: frontend/packages/ui-kit/src/styles/globals.css
2.2 Core Color Tokens
| CSS Variable | Tailwind Utility | Usage |
|---|---|---|
--background | bg-background, text-background | Page background |
--foreground | text-foreground | Primary text |
--primary | bg-primary, text-primary | Brand/primary actions |
--primary-foreground | text-primary-foreground | Text on primary |
--secondary | bg-secondary | Secondary elements |
--secondary-foreground | text-secondary-foreground | Text on secondary |
--muted | bg-muted, text-muted-foreground | Subtle backgrounds |
--accent | bg-accent | Accent highlights |
--destructive | bg-destructive | Error/danger states |
--destructive-foreground | text-destructive-foreground | Text on destructive |
--border | border, border-border | Borders |
--input | border-input, bg-input | Input fields |
--ring | ring-ring | Focus rings |
2.3 Semantic Tokens
| CSS Variable | Tailwind Utility | Light Mode | Dark Mode | Usage |
|---|---|---|---|---|
--success | bg-success, text-success | hsl(142 71% 45%) green | hsl(142 60% 38%) | Success/positive states |
--warning | bg-warning, text-warning | hsl(38 92% 50%) amber-orange | hsl(38 88% 45%) | Caution, high contrast |
--info | bg-info, text-info | hsl(199 89% 48%) sky blue | hsl(199 89% 48%) | Informational |
2.4 App Identity Colors
Identity colors do NOT theme-switch — they are fixed brand colors.
| App | CSS Variable | Hex | Usage |
|---|---|---|---|
| CMS | --color-cms | #078DFF | Clinical management |
| Growth | --color-growth | #52c41a | Marketing/growth |
| Doctor | --color-doctor | #722ed1 | Doctor features |
| Connect | --color-connect | #1890ff | Networking |
| Reports | --color-reports | #13c2c2 | Analytics |
| Hospital | --color-hospital | #eb2f96 | Hospital features |
| Network | --color-network | #fa8c16 | Network features |
Usage:
// ✅ CORRECT - Use app color tokens
<div className="bg-cms text-white">CMS Context</div>
<div className="bg-growth text-white">Growth Context</div>
// ❌ WRONG - Hardcoded hex values
<div className="bg-[#078DFF] text-white">CMS Context</div>2.5 Kulcare Brand Colors
Fixed brand colors that do NOT theme-switch:
| CSS Variable | Hex | Tailwind Utility | Usage |
|---|---|---|---|
--color-kulcare-primary | #078DFF | bg-kulcare-primary | Primary brand blue |
--color-kulcare-primary-light | #3DA4FF | bg-kulcare-primary-light | Light variant |
--color-kulcare-primary-dark | #0570CC | bg-kulcare-primary-dark | Dark variant |
--color-kulcare-secondary | #722ed1 | bg-kulcare-secondary | Secondary brand purple |
Usage:
// ✅ CORRECT - Use Kulcare brand tokens
<div className="bg-kulcare-primary text-white">Brand</div>
<div className="bg-kulcare-primary-light">Light Brand</div>
// ❌ WRONG - Hardcoded hex values
<div className="bg-[#078DFF] text-white">Brand</div>2.6 Accent Palette
Accent colors use .subtle for light variants. Dark mode uses lighter hues for legibility on dark surfaces; subtle variants use 14-16% lightness for consistent dim fills:
| Color | Light Mode | Dark Mode | Subtle Light | Subtle Dark |
|---|---|---|---|---|
| Indigo | accent-indigo | accent-indigo (lighter) | accent-indigo-subtle | accent-indigo-subtle (16%) |
| Purple | accent-purple | accent-purple (lighter) | accent-purple-subtle | accent-purple-subtle (16%) |
| Pink | accent-pink | accent-pink (lighter) | accent-pink-subtle | accent-pink-subtle (16%) |
| Cyan | accent-cyan | accent-cyan (lighter) | accent-cyan-subtle | accent-cyan-subtle (14%) |
| Teal | accent-teal | accent-teal (lighter) | accent-teal-subtle | accent-teal-subtle (14%) |
| Orange | accent-orange | accent-orange (lighter) | accent-orange-subtle | accent-orange-subtle (16%) |
Usage:
// ✅ CORRECT - .subtle for accent light variants
<div className="bg-accent-purple-subtle text-accent-purple">Subtle Purple</div>
// ❌ WRONG - /10 pattern for accent colors
<div className="bg-accent-purple/10">Wrong pattern</div>2.7 Gray Scale
Use the Kulcare gray ramp instead of Tailwind's default gray:
// ✅ CORRECT - Use Kulcare gray scale
<div className="bg-gray-50 text-gray-900">Light background</div>
<div className="bg-gray-100 text-gray-700">Subtle background</div>
// ❌ WRONG - Tailwind's default gray
<div className="bg-gray-50">Use --color-gray-50 instead</div>2.8 Typography Scale
Enterprise type scale matching legacy app (12/14/16/18/20/22/24px):
| Token | Size | Line Height | Usage |
|---|---|---|---|
--text-xs | 12px | 1.5 | Small text, labels |
--text-sm | 12px | 1.5 | Small text, errors |
--text-base | 14px | 1.5 | Body text |
--text-md | 16px | 1.5 | Large body, titles |
--text-lg | 18px | 1.4 | h4 |
--text-xl | 20px | 1.35 | h3 |
--text-2xl | 22px | 1.35 | h2 |
--text-3xl | 24px | 1.3 | h1 |
Font Families:
- Sans (Mulish): UI text, headings, body —
font-sans - Mono (JetBrains Mono): Medical data, prescriptions, vital signs —
font-mono
2.9 Radius Scale
Legacy values matching Ant Design:
--radius: 0.1875rem /* 3px - rounded */
--radius-sm: calc(var(--radius) * 1.067) /* rounded-sm */
--radius-md: var(--radius) /* rounded-md */
--radius-lg: calc(var(--radius) * 3.2) /* rounded-lg */
--radius-xl: 0.5rem /* rounded-xl */2.10 Shadow Scale
Layered shadows for depth perception - pure black shadows with appropriate opacity per mode:
/* Light mode - subtle shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
--shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
--shadow-md: 0 2px 8px rgba(0, 0, 0, 0.10);
--shadow-lg: 0 7px 14px rgba(0, 0, 0, 0.12), 0 3px 6px rgba(0, 0, 0, 0.06);
--shadow-xl: 0 5px 25px rgba(0, 0, 0, 0.15);
/* Dark mode - higher opacity for visibility on dark surfaces */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.15);
--shadow: 0 2px 8px rgba(0, 0, 0, 0.20);
--shadow-md: 0 2px 8px rgba(0, 0, 0, 0.25);
--shadow-lg: 0 7px 14px rgba(0, 0, 0, 0.30), 0 3px 6px rgba(0, 0, 0, 0.15);
--shadow-xl: 0 5px 25px rgba(0, 0, 0, 0.15);Usage:
<div className="shadow-sm" /> {/* Subtle card hover */}
<div className="shadow" /> {/* Card default */}
<div className="shadow-md" /> {/* Modal, popover */}
<div className="shadow-lg" /> {/* Dropdown menus */}
<div className="shadow-xl" /> {/* Full-page overlays */}2.11 Chart Colors
Tokens for recharts integration:
| CSS Variable | Tailwind Utility | Maps To | Usage |
|---|---|---|---|
--color-chart-1 | text-chart-1 | var(--primary) | Primary data series |
--color-chart-2 | text-chart-2 | var(--secondary) | Secondary data series |
--color-chart-3 | text-chart-3 | var(--accent) | Tertiary data series |
--color-chart-4 | text-chart-4 | var(--muted) | Background data series |
--color-chart-5 | text-chart-5 | var(--destructive) | Alert/highlight data |
Usage:
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<Line type="monotone" stroke="var(--color-chart-1)" dataKey="revenue" />
<Line type="monotone" stroke="var(--color-chart-2)" dataKey="appointments" />
</LineChart>
</ResponsiveContainer>2.12 Leading Tokens
Line-height tokens for consistent vertical rhythm:
| CSS Variable | Tailwind Utility | Value | Usage |
|---|---|---|---|
--leading-tight | leading-tight | 1.25 | Tight line height |
--leading-normal | leading-normal | 1.5 | Normal line height |
--leading-relaxed | leading-relaxed | 1.75 | Relaxed line height |
Usage:
<p className="leading-tight">Tight text for headings</p>
<p className="leading-normal">Normal body text</p>
<p className="leading-relaxed">Relaxed text for reading</p>2.13 Sidebar Tokens
Adaptive sidebar - light in light mode, dark in dark mode. Fixed values per mode (not theme-switching).
/* Light mode sidebar */
--sidebar: hsl(220 10% 94%); /* Light gray - distinguishable from background */
--sidebar-foreground: hsl(228 14% 24%); /* Dark text on light sidebar */
--sidebar-primary: hsl(211 100% 52%); /* Primary blue accent */
--sidebar-primary-foreground: hsl(0 0% 100%);
--sidebar-accent: hsl(211 100% 52% / 0.1); /* 10% opacity primary */
--sidebar-accent-foreground: hsl(211 100% 52%);
--sidebar-border: hsl(210 18% 92%);
--sidebar-ring: hsl(211 100% 52%);
/* Dark mode sidebar - Ant Design dark sider #001529 */
--sidebar: hsl(220 27% 8%); /* Deep dark blue-gray */
--sidebar-foreground: hsl(0 0% 65%); /* Light gray text */
--sidebar-primary: hsl(211 100% 52%); /* Primary blue accent */
--sidebar-primary-foreground: hsl(0 0% 100%);
--sidebar-accent: hsl(220 13% 14%);
--sidebar-accent-foreground: hsl(211 100% 52%);
--sidebar-border: hsl(220 27% 12%);
--sidebar-ring: hsl(211 100% 52%);Sidebar Tailwind utilities:
| CSS Variable | Tailwind Utility | Usage |
|---|---|---|
--sidebar | bg-sidebar, text-sidebar-foreground | Sidebar background/text |
--sidebar-primary | bg-sidebar-primary, text-sidebar-primary-foreground | Active item highlight |
--sidebar-accent | bg-sidebar-accent, text-sidebar-accent-foreground | Hover states |
--sidebar-border | border-sidebar-border | Sidebar dividers |
Sidebar dimensions:
| CSS Variable | Value | Usage |
|---|---|---|
--sidebar-width | 16rem (256px) | Expanded sidebar |
--sidebar-width-icon | 3rem (48px) | Icon-only collapsed state |
--sidebar-width-mobile | 18rem (288px) | Mobile drawer |
3. Component Usage
3.1 Import Patterns
All components come from @kulcare/ui-kit:
// ✅ CORRECT - Single import from ui-kit
import { Button, Card, Input, PageHeader } from "@kulcare/ui-kit"
// ❌ WRONG - Direct imports from component paths
import { Button } from "@kulcare/ui-kit/src/components/ui/button"
import { Card } from "@kulcare/ui-kit/src/components/ui/card"3.2 Available Core Components
| Component | Import | Notes |
|---|---|---|
| Button | Button | Use variant prop, NOT className for colors |
| Card | Card, CardHeader, CardContent, CardTitle | Composition pattern |
| PageHeader | PageHeader | Standardized page titles |
| Input | Input | Use for text inputs |
| Select | Select, SelectTrigger, SelectContent | For dropdowns |
| Dialog | Dialog, DialogContent, DialogHeader | For modals |
| Table | Table, TableHead, TableRow, TableCell | For data tables |
| Badge | Badge | Use variant prop |
| Alert | Alert, AlertTitle, AlertDescription | For notifications |
| Tabs | Tabs, TabsList, TabsTrigger, TabsContent | For tabbed content |
| Form | Form, FormField, FormLabel, FormControl | React Hook Form integration |
| DatePicker | DatePicker, RangePicker | For date selection |
3.3 Button Usage
Do: Use variant prop for color semantics
// ✅ CORRECT - Using variant prop
<Button variant="default">Primary Action</Button>
<Button variant="destructive">Delete</Button>
<Button variant="outline">Cancel</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Subtle</Button>
<Button variant="link">Text Link</Button>
// ✅ CORRECT - Using size prop
<Button size="default">Default</Button>
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>
<Button size="icon">Icon</Button>Don't: Use className for colors
// ❌ WRONG - className for colors
<Button className="bg-blue-600 hover:bg-blue-700">Primary</Button>
// ❌ WRONG - variant with className override
<Button variant="default" className="bg-red-500">Confusing</Button>Button Variants Reference:
| Variant | Classes | Usage |
|---|---|---|
default | bg-primary text-primary-foreground shadow hover:bg-primary/90 | Primary actions |
destructive | bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 | Danger actions |
outline | border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground | Secondary actions |
secondary | bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80 | Less prominent |
ghost | hover:bg-accent hover:text-accent-foreground | Subtle actions |
link | text-primary underline-offset-4 hover:underline | Text links |
3.4 Card Usage
Do: Use composition pattern
// ✅ CORRECT - Composition pattern
import { Card, CardHeader, CardTitle, CardContent } from "@kulcare/ui-kit"
<Card>
<CardHeader>
<CardTitle>Patient Details</CardTitle>
</CardHeader>
<CardContent>
<p>Patient information here</p>
</CardContent>
</Card>Don't: Use div with border classes
// ❌ WRONG - Div with border classes
<div className="rounded-lg border bg-card p-6">
<h3 className="text-lg font-semibold">Patient Details</h3>
<p>Patient information here</p>
</div>3.5 PageHeader Usage
Always use PageHeader for page titles — never build custom header divs.
// ✅ CORRECT - Using PageHeader
import { PageHeader, Button } from "@kulcare/ui-kit"
import { Plus, Download } from "lucide-react"
<PageHeader
icon={<Users className="h-6 w-6" />}
title="Patients"
description="Manage patient records"
actions={
<div className="flex gap-2">
<Button variant="outline" size="sm">
<Download className="h-4 w-4 mr-2" />
Export
</Button>
<Button size="sm">
<Plus className="h-4 w-4 mr-2" />
Add Patient
</Button>
</div>
}
/>3.6 Typography Classes
Use the type object for semantic typography:
import { type } from "@kulcare/ui-kit/lib/typography"
// Page structure
<span className={type.pageTitle}>Page Title</span>
<span className={type.sectionHeading}>Section</span>
<span className={type.subsectionHeading}>Subsection</span>
<span className={type.cardTitle}>Card Title</span>
// Body content
<span className={type.bodyText}>Body text</span>
<span className={type.bodyTextLarge}>Large body</span>
<span className={type.caption}>Caption</span>
// Forms
<span className={type.formLabel}>Label</span>
<span className={type.formError}>Error message</span>
// Medical data (use monospace)
<span className={type.medicalValue}>120/80 mmHg</span>
<span className={type.vitalSign}>98 bpm</span>
<span className={type.patientId}>MRN: 12345678</span>
<span className={type.prescription}>Amoxicillin 500mg</span>
// Status
<span className={type.statusSuccess}>Normal</span>
<span className={type.statusWarning}>Warning</span>
<span className={type.statusError}>Critical</span>3.7 Table Styling
Use the provided styling constants:
import { tableHeaderStyles, tableCellStyles } from "@kulcare/ui-kit"
<TableHead className={tableHeaderStyles.currency}>Amount</TableHead>
<TableCell className={tableCellStyles.currency}>₹12,500</TableCell>
<TableHead className={tableHeaderStyles.status}>Status</TableHead>
<TableCell className={tableCellStyles.status}>
<span className="status-normal">Active</span>
</TableCell>3.8 Status Classes
Use semantic status classes for healthcare indicators:
// ✅ CORRECT - Status classes
<span className="status-normal">Normal (green)</span>
<span className="status-warning">Warning (amber)</span>
<span className="status-critical">Critical (red)</span>
// ❌ WRONG - Hardcoded status colors
<span className="text-green-500">Normal</span>
<span className="text-amber-500">Warning</span>
<span className="text-red-500">Critical</span>4. Theming
4.1 ThemeProvider Setup
import { ThemeProvider } from "@kulcare/ui-kit"
function App() {
return (
<ThemeProvider defaultTheme="system" storageKey="kulcare-ui-theme">
{children}
</ThemeProvider>
)
}4.2 Theme Toggle
import { useTheme } from "@kulcare/ui-kit"
function ThemeToggle() {
const { theme, setTheme, resolvedTheme } = useTheme()
return (
<Button
variant="ghost"
onClick={() => setTheme(resolvedTheme === "light" ? "dark" : "light")}
>
{resolvedTheme === "light" ? "🌙" : "☀️"}
</Button>
)
}4.3 Dark Mode Implementation
Class-based dark mode — .dark class on <html> element:
/* Light mode - :root defaults */
:root {
--background: hsl(210 20% 98%);
--primary: hsl(211 100% 52%);
}
/* Dark mode - .dark overrides */
.dark {
--background: hsl(220 10% 8%);
--primary: hsl(211 90% 56%);
}How it works:
- User toggles theme → adds/removes
.darkclass on<html> - CSS variables cascade automatically
@theme inlinepropagates to Tailwind utilities
4.4 CSS Variable Usage
In globals.css (what you write):
--primary: hsl(211 100% 52%);In @theme inline (maps to Tailwind):
@theme inline {
--color-primary: var(--primary);
}In components (what you use):
<div className="bg-primary text-primary-foreground">Content</div>4.5 Anti-Flash Script
Include this script in <head> to prevent flash of wrong theme:
import { getThemeScriptTag } from "@kulcare/ui-kit"
const html = `
<head>
${getThemeScriptTag()}
<!-- other head content -->
</head>
`5. Tailwind v4 Rules
5.1 CSS-First Configuration
No tailwind.config.js — use @theme inline in CSS:
/* globals.css */
@theme inline {
--color-primary: var(--primary);
--radius: var(--radius);
}5.2 Tailwind Directives
Use @import instead of @tailwind directives:
/* ✅ CORRECT - v4 pattern */
@import "tailwindcss";
@import "tw-animate-css";
/* ❌ WRONG - v3 pattern */
@tailwind base;
@tailwind components;
@tailwind utilities;5.3 Custom Variants
Dark mode variant definition:
@custom-variant dark (&:where(.dark, .dark *));5.4 Custom Utilities
Define utilities with @utility:
@utility scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}5.5 Source Scanning
Ensure Tailwind scans ui-kit files:
@source "../**/*.{ts,tsx}";5.6 Vite Configuration
All MFEs use @tailwindcss/vite:
// vite.config.ts
import tailwindcss from "@tailwindcss/vite"
import react from "@vitejs/plugin-react"
export default defineConfig({
plugins: [react(), tailwindcss()],
})5.7 Token Naming Conventions
| Type | Convention | Example |
|---|---|---|
| CSS Variables | kebab-case | --primary, --border-color |
| Color Tokens | camelCase | primary, primaryForeground |
| App Colors | lowercase | cms, growth, reports |
| Accent Colors | kebab-case | accent-indigo, accent-purple-subtle |
| Gray Scale | kebab-case | gray-50, gray-100 |
6. Anti-patterns
6.1 Hardcoded Colors
Never use hardcoded hex/RGB values:
// ❌ WRONG - Hardcoded colors
<div className="bg-blue-500 text-white" />
<div className="text-[#078DFF]" />
<div style={{ backgroundColor: "#ffffff" }} />
// ✅ CORRECT - Use design tokens
<div className="bg-primary text-primary-foreground" />
<div className="text-primary" />
<div className="bg-background" />6.2 Non-UI-Kit Components
Don't build custom components that duplicate ui-kit:
// ❌ WRONG - Custom button with hardcoded styles
function CustomButton({ children, variant }) {
return (
<button className={`
${variant === "primary" ? "bg-blue-600" : "bg-gray-200"}
px-4 py-2 rounded-md
`}>
{children}
</button>
)
}
// ✅ CORRECT - Use ui-kit Button
import { Button } from "@kulcare/ui-kit"
<Button variant="default">Primary</Button>6.3 Direct Tailwind Config
Don't configure Tailwind via tailwind.config.js:
// ❌ WRONG - v3 tailwind.config.js
module.exports = {
theme: {
extend: {
colors: { primary: "#078DFF" }
}
}
}
// ✅ CORRECT - CSS-first via @theme inline6.4 Mixed v3/v4 Patterns
Don't mix v3 and v4 patterns:
// ❌ WRONG - Mixed patterns
import { Button } from "@kulcare/ui-kit"
<Button className="hsl(var(--primary))" /> // v3 pattern
// ✅ CORRECT - v4 pattern
<Button variant="default" /> // Using variant prop6.5 Incorrect Radius Usage
// ❌ WRONG - Hardcoded radius
<div className="rounded-[12px]" />
// ✅ CORRECT - Use radius tokens
<div className="rounded-xl" /> /* Uses --radius-xl */6.6 Shadow Token Mismatch
// ❌ WRONG - Non-existent shadow
<div className="shadow-xs" />
// ✅ CORRECT - Use defined shadow tokens
<div className="shadow-sm" /> /* --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06) */
<div className="shadow" /> /* --shadow: 0 2px 8px rgba(0, 0, 0, 0.08) */
<div className="shadow-md" /> /* --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.10) */
<div className="shadow-lg" /> /* --shadow-lg: layered rgba(0, 0, 0, ...) */
<div className="shadow-xl" /> /* --shadow-xl: 0 5px 25px rgba(0, 0, 0, 0.15) */7. Migration Guide (v3 to v4)
7.1 Removed Dependencies
| Old (v3) | New (v4) | Status |
|---|---|---|
tailwind.config.js | @theme inline in CSS | Removed |
tailwind-preset.js | globals.css with @theme | Removed |
postcss.config.js | @tailwindcss/vite | Removed |
tailwindcss-animate | tw-animate-css | Replaced |
autoprefixer | Built into @tailwindcss/vite | Removed |
7.2 Color Pattern Changes
| v3 (Old) | v4 (New) | Notes |
|---|---|---|
hsl(var(--primary)) | var(--primary) | Direct variable reference |
Hardcoded hex #078DFF | --color-cms or bg-cms | Use app identity tokens |
bg-blue-500 | bg-primary or semantic tokens | Never hardcode utility colors |
shadow-xs | shadow-sm | Token removed (doesn't exist in v4) |
7.3 Configuration Changes
Before (v3):
// tailwind.config.js
module.exports = {
presets: [require("@kulcare/ui-kit/tailwind-preset")],
content: ["./src/**/*.{js,jsx}"]
}After (v4):
/* index.css */
@import "@kulcare/ui-kit/src/styles/globals.css";
@import "tailwindcss";7.4 CSS Variable Usage
Before (v3):
background-color: hsl(var(--primary));
color: hsl(var(--foreground));After (v4):
background-color: var(--primary);
color: var(--foreground);7.5 Migration Checklist
- Remove
tailwind.config.jsfrom all MFEs - Remove
postcss.config.jsfrom all MFEs - Update
index.cssto use@import "tailwindcss"instead of@tailwinddirectives - Replace all
hsl(var(--x))withvar(--x)in custom CSS - Replace hardcoded hex colors with design tokens
- Replace
shadow-xswithshadow-sm(token doesn't exist in v4) - Replace
tailwindcss-animatewithtw-animate-cssin package.json - Remove
autoprefixerandpostcssfrom package.json - Update vite.config.ts to use
@tailwindcss/viteplugin - Replace custom button styles with
Button variant="..."prop - Replace custom card divs with
Card, CardHeader, CardContentcomposition
7.6 Common Mistakes
| Mistake | Correction |
|---|---|
Using tailwind.config.js | Delete it, use @theme inline in globals.css |
hsl(var(--primary)) | var(--primary) |
className="bg-blue-500" | variant="default" prop |
Hardcoded #078DFF | bg-cms or semantic token |
shadow-xs | shadow-sm (token doesn't exist in v4) |
@tailwind base/components/utilities | @import "tailwindcss" |
7.7 Import Pattern Changes
Before (v3):
import "@kulcare/ui-kit/src/styles/globals.css"
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";After (v4):
@import "@kulcare/ui-kit/src/styles/globals.css";
@import "tailwindcss";
@import "tw-animate-css";Quick Reference Card
Do's ✅
- Use
@kulcare/ui-kitfor all components - Use
variantprop for button colors - Use design tokens (primary, destructive, etc.)
- Use
PageHeaderfor page titles - Use
typeobject for typography - Use status classes (status-normal, status-warning, status-critical)
- Use
cn()utility for class merging
Don'ts ❌
- Hardcode colors (use tokens)
- Use
classNamefor button colors - Build custom button/card components
- Use
tailwind.config.js(CSS-first) - Use
hsl(var(--x))(directvar(--x)) - Use
shadow-xs(token doesn't exist in v4, useshadow-sm) - Mix v3 and v4 patterns
File Locations
| File | Purpose |
|---|---|
frontend/packages/ui-kit/src/styles/globals.css | Canonical design tokens + @theme |
frontend/packages/ui-kit/src/theme/ThemeProvider.tsx | Dark mode implementation |
frontend/packages/ui-kit/src/index.ts | All component exports |
frontend/packages/ui-kit/src/lib/typography.ts | type object and helpers |
frontend/packages/ui-kit/src/lib/utils.ts | cn() utility |
Related Documentation
- Tailwind CSS v4 Setup - Detailed v4 workflow
- UI Kit Documentation - Component library reference
- Frontend Styling Architecture - ⚠️ Deprecated (v3)