# Tailwind CSS Migration Plan: v1.4/v2.2 → v4.0 (Standalone CLI)

**Created:** December 2024
**Completed:** December 2024
**Status:** COMPLETE
**Goal:** Eliminate Node.js dependency, use Tailwind Standalone CLI

> **Migration Complete!** All frontends now use Tailwind CSS v4 with the standalone CLI.
> See [Tailwind CSS Build Guide](../../frontend/tailwind-css.md) for current documentation.

---

## Current State

### Two Tailwind Setups (Before Migration)

| Component | Version | Source | Purpose |
|-----------|---------|--------|---------|
| Base styles | 2.2.19 | CDN + local fallback | Core Tailwind utilities for all frontends |
| Custom overrides | 1.4.6 | npm build | Windmill Dashboard theme (admin/store) |

### Current Files (Before Migration)

```
package.json                           # tailwindcss: 1.4.6 (TO BE REMOVED)
package-lock.json                      # (TO BE REMOVED)
node_modules/                          # (TO BE REMOVED)
tailwind.config.js                     # v1.4 format config (TO BE UPDATED)
postcss.config.js                      # (TO BE REMOVED)
static/shared/css/tailwind.min.css     # CDN fallback v2.2.19 (TO BE REMOVED)
static/admin/css/tailwind.output.css   # Built overrides (TO BE REBUILT)
static/store/css/tailwind.output.css  # Built overrides (TO BE REBUILT)
```

### Current Plugins (TO BE REPLACED)

```json
{
  "@tailwindcss/custom-forms": "0.2.1",    // DEPRECATED - replaced by @tailwindcss/forms
  "tailwindcss-multi-theme": "1.0.3"       // DEPRECATED - native darkMode in v3+
}
```

---

## Migration Goals

1. ✅ Eliminate Node.js dependency entirely
2. ✅ Use Tailwind Standalone CLI (single binary, no npm)
3. ✅ Upgrade to Tailwind v4.0 (latest)
4. ✅ Remove CDN dependency (all CSS built locally)
5. ✅ Update config to v4 format
6. ✅ Replace deprecated plugins with native features
7. ✅ Consolidate to single Tailwind version
8. ✅ Verify all frontends work correctly

---

## Step-by-Step Migration

### Phase 1: Install Tailwind Standalone CLI

The standalone CLI bundles Tailwind + Node.js runtime into a single binary.

```bash
# Download latest standalone CLI for Linux x64
curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64
chmod +x tailwindcss-linux-x64
sudo mv tailwindcss-linux-x64 /usr/local/bin/tailwindcss

# Verify installation
tailwindcss --version
```

**For other platforms:**
- macOS (Intel): `tailwindcss-macos-x64`
- macOS (Apple Silicon): `tailwindcss-macos-arm64`
- Windows: `tailwindcss-windows-x64.exe`
- Linux ARM: `tailwindcss-linux-arm64`

### Phase 2: Update tailwind.config.js

Replace the entire config file with v4-compatible format:

```javascript
// tailwind.config.js - Tailwind CSS v4.0 (Standalone CLI)
/** @type {import('tailwindcss').Config} */
module.exports = {
  // v4: 'content' replaces 'purge'
  content: [
    'app/templates/**/*.html',
    'static/**/*.js',
  ],

  // v4: safelist for dynamic classes (Alpine.js)
  safelist: [
    'bg-orange-600',
    'bg-green-600',
    'bg-red-600',
    'bg-blue-600',
    'bg-purple-600',
    'hover:bg-orange-700',
    'hover:bg-green-700',
    'hover:bg-red-700',
    'hover:bg-blue-700',
    'hover:bg-purple-700',
    // Status colors
    'text-green-600',
    'text-red-600',
    'text-yellow-600',
    'text-blue-600',
    'bg-green-100',
    'bg-red-100',
    'bg-yellow-100',
    'bg-blue-100',
  ],

  // v4: darkMode replaces tailwindcss-multi-theme
  darkMode: 'class',

  theme: {
    extend: {
      // Custom colors from Windmill Dashboard
      colors: {
        gray: {
          50: '#f9fafb',
          100: '#f4f5f7',
          200: '#e5e7eb',
          300: '#d5d6d7',
          400: '#9e9e9e',
          500: '#707275',
          600: '#4c4f52',
          700: '#24262d',
          800: '#1a1c23',
          900: '#121317',
        },
        purple: {
          50: '#f6f5ff',
          100: '#edebfe',
          200: '#dcd7fe',
          300: '#cabffd',
          400: '#ac94fa',
          500: '#9061f9',
          600: '#7e3af2',
          700: '#6c2bd9',
          800: '#5521b5',
          900: '#4a1d96',
        },
      },
      fontFamily: {
        sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
      },
      maxHeight: {
        'xl': '36rem',
      },
    },
  },

  plugins: [
    // Note: Standalone CLI includes @tailwindcss/forms by default in v4
    // No external plugins needed
  ],
}
```

### Phase 3: Update CSS Source Files

Update `static/admin/css/tailwind.css`:

```css
/* Tailwind CSS v4 directives */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Custom component classes */
@layer components {
  .form-input {
    @apply block w-full rounded-md border-gray-300 shadow-sm
           focus:border-purple-500 focus:ring-purple-500;
  }

  .form-select {
    @apply block w-full rounded-md border-gray-300 shadow-sm
           focus:border-purple-500 focus:ring-purple-500;
  }

  .form-checkbox {
    @apply rounded border-gray-300 text-purple-600
           focus:ring-purple-500;
  }

  .form-textarea {
    @apply block w-full rounded-md border-gray-300 shadow-sm
           focus:border-purple-500 focus:ring-purple-500;
  }
}

/* Dark mode base overrides */
@layer base {
  .dark body {
    @apply bg-gray-900 text-gray-200;
  }
}
```

### Phase 4: Add Makefile Targets

Add these targets to your Makefile (replaces npm scripts):

```makefile
# =============================================================================
# Tailwind CSS (Standalone CLI - No Node.js Required)
# =============================================================================

.PHONY: tailwind-install tailwind-dev tailwind-build tailwind-watch

# Install Tailwind standalone CLI
tailwind-install:
	@echo "Installing Tailwind CSS standalone CLI..."
	curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64
	chmod +x tailwindcss-linux-x64
	sudo mv tailwindcss-linux-x64 /usr/local/bin/tailwindcss
	@echo "Tailwind CLI installed: $$(tailwindcss --version)"

# Development build (includes all classes, faster)
tailwind-dev:
	@echo "Building Tailwind CSS (development)..."
	tailwindcss -i static/admin/css/tailwind.css -o static/admin/css/tailwind.output.css
	tailwindcss -i static/admin/css/tailwind.css -o static/store/css/tailwind.output.css
	@echo "CSS built successfully"

# Production build (purged and minified)
tailwind-build:
	@echo "Building Tailwind CSS (production)..."
	tailwindcss -i static/admin/css/tailwind.css -o static/admin/css/tailwind.output.css --minify
	tailwindcss -i static/admin/css/tailwind.css -o static/store/css/tailwind.output.css --minify
	@echo "CSS built and minified successfully"

# Watch mode for development
tailwind-watch:
	@echo "Watching for CSS changes..."
	tailwindcss -i static/admin/css/tailwind.css -o static/admin/css/tailwind.output.css --watch
```

### Phase 5: Update Dark Mode Implementation

**Old approach (tailwindcss-multi-theme):**
```html
<body class="theme-dark">
  <div class="bg-white dark:bg-gray-800">
```

**New approach (Tailwind v4 native):**
```html
<html class="dark">
  <body>
    <div class="bg-white dark:bg-gray-800">
```

**Files to update:**
1. `app/templates/admin/base.html` - Add `dark` class to `<html>` element
2. `app/templates/store/base.html` - Add `dark` class to `<html>` element
3. `static/admin/js/init-alpine.js` - Update dark mode toggle logic
4. `static/store/js/init-alpine.js` - Update dark mode toggle logic

**JavaScript update:**
```javascript
// Old
document.body.classList.toggle('theme-dark');

// New
document.documentElement.classList.toggle('dark');
```

### Phase 6: Update Base Templates

**Remove CDN loading, use only local built CSS:**

```html
<!-- OLD: CDN with fallback (REMOVE THIS) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css"
      onerror="this.onerror=null; this.href='{{ url_for('static', path='shared/css/tailwind.min.css') }}';">
<link rel="stylesheet" href="{{ url_for('static', path='admin/css/tailwind.output.css') }}" />

<!-- NEW: Local only (v4) -->
<link rel="stylesheet" href="{{ url_for('static', path='admin/css/tailwind.output.css') }}" />
```

### Phase 7: Build and Test

```bash
# Build CSS
make tailwind-build

# Start development server
make dev

# Test all frontends:
# - http://localhost:8000/admin/dashboard
# - http://localhost:8000/store/{code}/dashboard
# - http://localhost:8000/ (shop)
```

### Phase 8: Remove Node.js Artifacts

After successful testing, remove all Node.js related files:

```bash
# Remove Node.js files
rm -rf node_modules/
rm package.json
rm package-lock.json
rm postcss.config.js

# Remove unused CDN fallback
rm static/shared/css/tailwind.min.css
```

---

## Verification Checklist

- [x] Tailwind CLI installed and working (`tailwindcss --version`)
- [x] Admin dashboard loads correctly
- [x] Store dashboard loads correctly
- [x] Shop frontend loads correctly
- [x] Platform pages load correctly
- [x] Dark mode toggle works
- [x] All buttons have correct colors
- [x] Forms display correctly (inputs, selects, checkboxes)
- [x] Responsive design works (mobile/tablet/desktop)
- [x] No console errors
- [x] Production build works (`make tailwind-build`)
- [x] node_modules removed
- [x] package.json removed
- [x] Each frontend has its own CSS source file
- [x] Store theming (CSS variables) still works

---

## Breaking Changes Reference

### Class Name Changes (v2 → v4)

| v2.x | v4.x | Notes |
|------|------|-------|
| `overflow-ellipsis` | `text-ellipsis` | Renamed |
| `flex-grow-0` | `grow-0` | Shortened |
| `flex-shrink-0` | `shrink-0` | Shortened |
| `decoration-clone` | `box-decoration-clone` | Renamed |

### Plugin Changes

| Old Plugin | New Approach | Notes |
|------------|--------------|-------|
| `@tailwindcss/custom-forms` | Built-in form styles | Native in v4 |
| `tailwindcss-multi-theme` | `darkMode: 'class'` | Native support |

### Config Changes

| v1.x/v2.x | v4.x |
|-----------|------|
| `purge: [...]` | `content: [...]` |
| `variants: {...}` | Removed (JIT generates all) |
| `mode: 'jit'` | Default (not needed) |

---

## Rollback Plan

If issues arise, the old setup can be restored:

```bash
# Reinstall Node dependencies
npm install

# Rebuild with old config
npm run build
```

---

## Benefits of This Migration

| Aspect | Before | After |
|--------|--------|-------|
| **Node.js required** | Yes | No |
| **Dependencies** | ~200MB node_modules | ~50MB single binary |
| **Build speed** | Slower (npm + PostCSS) | Faster (standalone) |
| **Tailwind versions** | 2 (v1.4 + v2.2) | 1 (v4.0) |
| **CSS loading** | CDN + local | Local only |
| **Maintenance** | npm updates, security patches | Single binary updates |

---

## Resources

- [Tailwind CSS Standalone CLI](https://tailwindcss.com/blog/standalone-cli)
- [Tailwind CSS v4 Documentation](https://tailwindcss.com/docs)
- [Dark Mode in Tailwind](https://tailwindcss.com/docs/dark-mode)
- [Standalone CLI Releases](https://github.com/tailwindlabs/tailwindcss/releases)
