Kulcare Docs
General

Kulcare Platform Style Guide

Status: ✅ Current for Tailwind CSS v4.2.x Last Updated: 2026-04-27


Table of Contents

  1. Principles
  2. Design Tokens
  3. Component Usage
  4. Theming
  5. Tailwind v4 Rules
  6. Anti-patterns
  7. Migration Guide

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.

AppPortImport Pattern
shell3000@import "@kulcare/ui-kit/src/styles/globals.css"
cms3001@import "@kulcare/ui-kit/src/styles/globals.css"
growth3003@import "@kulcare/ui-kit/src/styles/globals.css"
reports3004@import "@kulcare/ui-kit/src/styles/globals.css"
connect3005@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 VariableTailwind UtilityUsage
--backgroundbg-background, text-backgroundPage background
--foregroundtext-foregroundPrimary text
--primarybg-primary, text-primaryBrand/primary actions
--primary-foregroundtext-primary-foregroundText on primary
--secondarybg-secondarySecondary elements
--secondary-foregroundtext-secondary-foregroundText on secondary
--mutedbg-muted, text-muted-foregroundSubtle backgrounds
--accentbg-accentAccent highlights
--destructivebg-destructiveError/danger states
--destructive-foregroundtext-destructive-foregroundText on destructive
--borderborder, border-borderBorders
--inputborder-input, bg-inputInput fields
--ringring-ringFocus rings

2.3 Semantic Tokens

CSS VariableTailwind UtilityLight ModeDark ModeUsage
--successbg-success, text-successhsl(142 71% 45%) greenhsl(142 60% 38%)Success/positive states
--warningbg-warning, text-warninghsl(38 92% 50%) amber-orangehsl(38 88% 45%)Caution, high contrast
--infobg-info, text-infohsl(199 89% 48%) sky bluehsl(199 89% 48%)Informational

2.4 App Identity Colors

Identity colors do NOT theme-switch — they are fixed brand colors.

AppCSS VariableHexUsage
CMS--color-cms#078DFFClinical management
Growth--color-growth#52c41aMarketing/growth
Doctor--color-doctor#722ed1Doctor features
Connect--color-connect#1890ffNetworking
Reports--color-reports#13c2c2Analytics
Hospital--color-hospital#eb2f96Hospital features
Network--color-network#fa8c16Network 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 VariableHexTailwind UtilityUsage
--color-kulcare-primary#078DFFbg-kulcare-primaryPrimary brand blue
--color-kulcare-primary-light#3DA4FFbg-kulcare-primary-lightLight variant
--color-kulcare-primary-dark#0570CCbg-kulcare-primary-darkDark variant
--color-kulcare-secondary#722ed1bg-kulcare-secondarySecondary 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:

ColorLight ModeDark ModeSubtle LightSubtle Dark
Indigoaccent-indigoaccent-indigo (lighter)accent-indigo-subtleaccent-indigo-subtle (16%)
Purpleaccent-purpleaccent-purple (lighter)accent-purple-subtleaccent-purple-subtle (16%)
Pinkaccent-pinkaccent-pink (lighter)accent-pink-subtleaccent-pink-subtle (16%)
Cyanaccent-cyanaccent-cyan (lighter)accent-cyan-subtleaccent-cyan-subtle (14%)
Tealaccent-tealaccent-teal (lighter)accent-teal-subtleaccent-teal-subtle (14%)
Orangeaccent-orangeaccent-orange (lighter)accent-orange-subtleaccent-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):

TokenSizeLine HeightUsage
--text-xs12px1.5Small text, labels
--text-sm12px1.5Small text, errors
--text-base14px1.5Body text
--text-md16px1.5Large body, titles
--text-lg18px1.4h4
--text-xl20px1.35h3
--text-2xl22px1.35h2
--text-3xl24px1.3h1

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 VariableTailwind UtilityMaps ToUsage
--color-chart-1text-chart-1var(--primary)Primary data series
--color-chart-2text-chart-2var(--secondary)Secondary data series
--color-chart-3text-chart-3var(--accent)Tertiary data series
--color-chart-4text-chart-4var(--muted)Background data series
--color-chart-5text-chart-5var(--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 VariableTailwind UtilityValueUsage
--leading-tightleading-tight1.25Tight line height
--leading-normalleading-normal1.5Normal line height
--leading-relaxedleading-relaxed1.75Relaxed 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 VariableTailwind UtilityUsage
--sidebarbg-sidebar, text-sidebar-foregroundSidebar background/text
--sidebar-primarybg-sidebar-primary, text-sidebar-primary-foregroundActive item highlight
--sidebar-accentbg-sidebar-accent, text-sidebar-accent-foregroundHover states
--sidebar-borderborder-sidebar-borderSidebar dividers

Sidebar dimensions:

CSS VariableValueUsage
--sidebar-width16rem (256px)Expanded sidebar
--sidebar-width-icon3rem (48px)Icon-only collapsed state
--sidebar-width-mobile18rem (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

ComponentImportNotes
ButtonButtonUse variant prop, NOT className for colors
CardCard, CardHeader, CardContent, CardTitleComposition pattern
PageHeaderPageHeaderStandardized page titles
InputInputUse for text inputs
SelectSelect, SelectTrigger, SelectContentFor dropdowns
DialogDialog, DialogContent, DialogHeaderFor modals
TableTable, TableHead, TableRow, TableCellFor data tables
BadgeBadgeUse variant prop
AlertAlert, AlertTitle, AlertDescriptionFor notifications
TabsTabs, TabsList, TabsTrigger, TabsContentFor tabbed content
FormForm, FormField, FormLabel, FormControlReact Hook Form integration
DatePickerDatePicker, RangePickerFor 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:

VariantClassesUsage
defaultbg-primary text-primary-foreground shadow hover:bg-primary/90Primary actions
destructivebg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90Danger actions
outlineborder border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foregroundSecondary actions
secondarybg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80Less prominent
ghosthover:bg-accent hover:text-accent-foregroundSubtle actions
linktext-primary underline-offset-4 hover:underlineText 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:

  1. User toggles theme → adds/removes .dark class on <html>
  2. CSS variables cascade automatically
  3. @theme inline propagates 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

TypeConventionExample
CSS Variableskebab-case--primary, --border-color
Color TokenscamelCaseprimary, primaryForeground
App Colorslowercasecms, growth, reports
Accent Colorskebab-caseaccent-indigo, accent-purple-subtle
Gray Scalekebab-casegray-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 inline

6.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 prop

6.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 CSSRemoved
tailwind-preset.jsglobals.css with @themeRemoved
postcss.config.js@tailwindcss/viteRemoved
tailwindcss-animatetw-animate-cssReplaced
autoprefixerBuilt into @tailwindcss/viteRemoved

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-cmsUse app identity tokens
bg-blue-500bg-primary or semantic tokensNever hardcode utility colors
shadow-xsshadow-smToken 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.js from all MFEs
  • Remove postcss.config.js from all MFEs
  • Update index.css to use @import "tailwindcss" instead of @tailwind directives
  • Replace all hsl(var(--x)) with var(--x) in custom CSS
  • Replace hardcoded hex colors with design tokens
  • Replace shadow-xs with shadow-sm (token doesn't exist in v4)
  • Replace tailwindcss-animate with tw-animate-css in package.json
  • Remove autoprefixer and postcss from package.json
  • Update vite.config.ts to use @tailwindcss/vite plugin
  • Replace custom button styles with Button variant="..." prop
  • Replace custom card divs with Card, CardHeader, CardContent composition

7.6 Common Mistakes

MistakeCorrection
Using tailwind.config.jsDelete it, use @theme inline in globals.css
hsl(var(--primary))var(--primary)
className="bg-blue-500"variant="default" prop
Hardcoded #078DFFbg-cms or semantic token
shadow-xsshadow-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-kit for all components
  • Use variant prop for button colors
  • Use design tokens (primary, destructive, etc.)
  • Use PageHeader for page titles
  • Use type object for typography
  • Use status classes (status-normal, status-warning, status-critical)
  • Use cn() utility for class merging

Don'ts ❌

  • Hardcode colors (use tokens)
  • Use className for button colors
  • Build custom button/card components
  • Use tailwind.config.js (CSS-first)
  • Use hsl(var(--x)) (direct var(--x))
  • Use shadow-xs (token doesn't exist in v4, use shadow-sm)
  • Mix v3 and v4 patterns

File Locations

FilePurpose
frontend/packages/ui-kit/src/styles/globals.cssCanonical design tokens + @theme
frontend/packages/ui-kit/src/theme/ThemeProvider.tsxDark mode implementation
frontend/packages/ui-kit/src/index.tsAll component exports
frontend/packages/ui-kit/src/lib/typography.tstype object and helpers
frontend/packages/ui-kit/src/lib/utils.tscn() utility

On this page