# 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, store, 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/store/css/tailwind.css → tailwind.output.css (Store) ├── static/storefront/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 ``` --- ## 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 `` element: ```html ``` 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
``` ### 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)