# Tailwind CSS Build Guide

**Version:** 2.0
**Last Updated:** December 2024
**Audience:** Frontend Developers

---

## Overview

The platform uses [Tailwind CSS v4](https://tailwindcss.com/) with the **Standalone CLI** - no Node.js required. Each frontend (admin, vendor, shop, platform) has its own dedicated CSS configuration.

---

## Architecture

### How It Works

```
Tailwind Standalone CLI (single binary, no npm)
    │
    ├── static/admin/css/tailwind.css     → tailwind.output.css (Admin)
    ├── static/vendor/css/tailwind.css    → tailwind.output.css (Vendor)
    ├── static/shop/css/tailwind.css      → tailwind.output.css (Shop)
    └── static/public/css/tailwind.css  → tailwind.output.css (Platform)
```

### Key Files

| File | Purpose |
|------|---------|
| `~/.local/bin/tailwindcss` | Standalone CLI binary (v4.x) |
| `static/*/css/tailwind.css` | CSS-first source configuration |
| `static/*/css/tailwind.output.css` | Compiled output (do not edit) |

### Template Loading

Each frontend loads its own CSS:

```html
<!-- Admin -->
<link rel="stylesheet" href="{{ url_for('static', path='admin/css/tailwind.output.css') }}" />

<!-- Vendor -->
<link rel="stylesheet" href="{{ url_for('static', path='vendor/css/tailwind.output.css') }}" />

<!-- Shop -->
<link rel="stylesheet" href="{{ url_for('static', path='shop/css/tailwind.output.css') }}" />

<!-- Platform -->
<link rel="stylesheet" href="{{ url_for('static', path='platform/css/tailwind.output.css') }}" />
```

---

## CSS-First Configuration (Tailwind v4)

Tailwind v4 uses **CSS-first configuration** instead of `tailwind.config.js`. All customization happens directly in CSS files.

### Source File Structure

```css
/* static/admin/css/tailwind.css */

/* Import Tailwind */
@import "tailwindcss";

/* Content sources for tree-shaking */
@source "../../../app/templates/admin/**/*.html";
@source "../../js/**/*.js";

/* Custom theme (colors, fonts, spacing) */
@theme {
  --color-gray-50: #f9fafb;
  --color-gray-900: #121317;
  --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
}

/* Dark mode variant */
@variant dark (&:where(.dark, .dark *));

/* Custom utilities */
@layer utilities {
  .shadow-outline-purple {
    box-shadow: 0 0 0 3px hsla(262, 97%, 81%, 0.45);
  }
}

/* Custom components */
@layer components {
  .form-input { ... }
  .btn-primary { ... }
}
```

### Key Directives

| Directive | Purpose | Example |
|-----------|---------|---------|
| `@import "tailwindcss"` | Import Tailwind base | Required at top |
| `@source` | Content paths for purging | `@source "../../../app/templates/**/*.html"` |
| `@theme` | Custom design tokens | `--color-purple-600: #7e3af2;` |
| `@variant` | Custom variants | `@variant dark (&:where(.dark, .dark *))` |
| `@layer utilities` | Custom utility classes | `.shadow-outline-*` |
| `@layer components` | Custom components | `.form-input`, `.btn-*` |

---

## Custom Color Palette

All frontends share the same Windmill Dashboard color palette:

```css
@theme {
  /* Gray (custom darker palette) */
  --color-gray-50: #f9fafb;
  --color-gray-100: #f4f5f7;
  --color-gray-200: #e5e7eb;
  --color-gray-300: #d5d6d7;
  --color-gray-400: #9e9e9e;
  --color-gray-500: #707275;
  --color-gray-600: #4c4f52;
  --color-gray-700: #24262d;
  --color-gray-800: #1a1c23;
  --color-gray-900: #121317;

  /* Purple (primary) */
  --color-purple-600: #7e3af2;

  /* Plus: red, orange, yellow, green, teal, blue, indigo, pink, cool-gray */
}
```

---

## Building Tailwind CSS

### Prerequisites

Install the standalone CLI (one-time setup):

```bash
make tailwind-install
```

Or manually:

```bash
curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64
chmod +x tailwindcss-linux-x64
mv tailwindcss-linux-x64 ~/.local/bin/tailwindcss
```

### Development Build

Build all frontends (includes all classes, larger files):

```bash
make tailwind-dev
```

### Production Build

Build with minification (smaller files):

```bash
make tailwind-build
```

### Watch Mode

Watch for changes during development:

```bash
make tailwind-watch
```

---

## Makefile Targets

| Target | Description |
|--------|-------------|
| `make tailwind-install` | Install Tailwind standalone CLI |
| `make tailwind-dev` | Build all CSS (development) |
| `make tailwind-build` | Build all CSS (production, minified) |
| `make tailwind-watch` | Watch for changes |

---

## Dark Mode

The platform uses class-based dark mode with the `.dark` class on the `<html>` element:

```html
<html :class="{ 'dark': dark }">
  <body class="bg-white dark:bg-gray-900">
```

Toggle dark mode with JavaScript:

```javascript
document.documentElement.classList.toggle('dark');
localStorage.setItem('darkMode', dark);
```

---

## Adding Custom Utilities

Add custom utilities in the source CSS file:

```css
@layer utilities {
  .shadow-outline-purple {
    box-shadow: 0 0 0 3px hsla(262, 97%, 81%, 0.45);
  }

  .text-balance {
    text-wrap: balance;
  }
}
```

---

## Adding Custom Components

Add reusable component classes:

```css
@layer components {
  .form-input {
    @apply block w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm;
    @apply focus:border-purple-500 focus:ring-1 focus:ring-purple-500;
    @apply dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200;
  }

  .btn-primary {
    @apply px-4 py-2 text-sm font-medium text-white bg-purple-600 rounded-lg;
    @apply hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-purple-500;
  }
}
```

---

## Troubleshooting

### Classes not appearing

1. **Check @source paths** - Ensure your templates are in a scanned directory
2. **Check class exists** - Tailwind v4 may have renamed some classes
3. **Rebuild CSS** - Run `make tailwind-dev` after config changes

### Dynamic classes in Alpine.js

Tailwind v4 uses JIT compilation and scans for complete class names. Dynamic classes work automatically if the full class name appears in your templates:

```html
<!-- This works - full class names visible -->
<div :class="isActive ? 'bg-green-600' : 'bg-red-600'">
```

### Class name changes (v2 → v4)

| v2.x | v4.x |
|------|------|
| `overflow-ellipsis` | `text-ellipsis` |
| `flex-grow-0` | `grow-0` |
| `flex-shrink-0` | `shrink-0` |

---

## Best Practices

1. **Always rebuild after CSS changes**
   ```bash
   make tailwind-dev
   ```

2. **Use production builds for deployment**
   ```bash
   make tailwind-build
   ```

3. **Keep each frontend's CSS isolated** - Don't cross-import between frontends

4. **Use @apply sparingly** - Prefer utility classes in templates when possible

5. **Test in both light and dark modes**

---

## Related Documentation

- [UI Components](shared/ui-components.md)
- [Tailwind CSS Official Docs](https://tailwindcss.com/docs)
- [Tailwind CSS v4 Blog Post](https://tailwindcss.com/blog/tailwindcss-v4)
