From 3b89cf2d5f08c682262ab33cd436d69d8db838e2 Mon Sep 17 00:00:00 2001 From: Zac Gaetano Date: Thu, 21 May 2026 16:41:55 +0000 Subject: [PATCH] web-ui: fix wave-1 build pipeline (primitives missing from bundle) Three bugs found during task 20 verify, all fixed: 1. Tailwind CLI does NOT read postcss.config.js. Switched Dockerfile to npx postcss + postcss-cli so the postcss plugin chain actually runs. 2. postcss-import was not installed but app.css uses @import for the primitive component files. Added postcss-import + cssnano (for prod minification under --env production). 3. @import statements must come BEFORE any other rules per CSS spec. app.css had @tailwind base/components ABOVE @import, so postcss-import silently skipped every component @import. Moved all @imports to the top, @tailwind directives below. Bundle went from 121KB with 0 wd-* classes to 138KB with 116 wd-* classes. Also added tailwind safelist for wd-/is-/nav-dev-badge so the wave-2 migration of HTML files cannot accidentally tree-shake primitives. --- services/web-ui/Dockerfile | 2 +- services/web-ui/package.json | 7 +++++-- services/web-ui/postcss.config.js | 6 ++++-- services/web-ui/src/css/app.css | 29 +++++++++++------------------ services/web-ui/tailwind.config.js | 5 +++++ 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/services/web-ui/Dockerfile b/services/web-ui/Dockerfile index 6f1c9d0..a3f04c1 100644 --- a/services/web-ui/Dockerfile +++ b/services/web-ui/Dockerfile @@ -12,7 +12,7 @@ COPY src/ ./src/ COPY public/ ./public/ # Build into public/dist/app.css -RUN npx tailwindcss -i ./src/css/app.css -o ./public/dist/app.css --minify +RUN npx postcss ./src/css/app.css -o ./public/dist/app.css --env production # Stage 2: runtime FROM nginx:alpine diff --git a/services/web-ui/package.json b/services/web-ui/package.json index 0de73a4..4d7cd31 100644 --- a/services/web-ui/package.json +++ b/services/web-ui/package.json @@ -4,12 +4,15 @@ "private": true, "description": "Build-time-only deps for the Wild Dragon web-ui Tailwind/flyon-ui pipeline. Not shipped at runtime.", "scripts": { - "build:css": "tailwindcss -i ./src/css/app.css -o ./public/dist/app.css --minify" + "build:css": "postcss ./src/css/app.css -o ./public/dist/app.css --env production" }, "devDependencies": { "tailwindcss": "^3.4.0", "postcss": "^8.4.35", "autoprefixer": "^10.4.17", - "flyonui": "^1.0.0" + "flyonui": "^1.0.0", + "postcss-import": "^16.0.0", + "postcss-cli": "^11.0.0", + "cssnano": "^7.0.0" } } diff --git a/services/web-ui/postcss.config.js b/services/web-ui/postcss.config.js index 12a703d..2e9af7a 100644 --- a/services/web-ui/postcss.config.js +++ b/services/web-ui/postcss.config.js @@ -1,6 +1,8 @@ -module.exports = { +module.exports = ({ env }) => ({ plugins: { + 'postcss-import': {}, tailwindcss: {}, autoprefixer: {}, + ...(env === 'production' ? { cssnano: { preset: 'default' } } : {}), }, -}; +}); diff --git a/services/web-ui/src/css/app.css b/services/web-ui/src/css/app.css index 09731e2..fa5497d 100644 --- a/services/web-ui/src/css/app.css +++ b/services/web-ui/src/css/app.css @@ -1,20 +1,12 @@ -/* app.css ─ Tailwind directives + primitive imports. +/* app.css — Tailwind directives + primitive imports. * - * Order matters: - * 1. tokens (CSS custom properties for legacy callers) - * 2. tailwind base (CSS reset) - * 3. tailwind components - * 4. our primitives (use tokens + can be overridden by utilities) - * 5. tailwind utilities (highest specificity, last word) - * 6. motion (animations + reduced-motion override) + * IMPORTANT: All @import must come first per CSS spec / postcss-import + * requirements. Tailwind directives below; cascade order in the emitted + * bundle is: tokens → primitives → tailwind base → tailwind components + * → tailwind utilities. Utilities win on specificity, primitives win + * over base where they share specificity. */ - @import "./components/tokens.css"; - -@tailwind base; -@tailwind components; - -/* Primitives — each one ~50-200 lines, one responsibility per file */ @import "./components/sidebar.css"; @import "./components/topbar.css"; @import "./components/button.css"; @@ -27,12 +19,13 @@ @import "./components/empty-state.css"; @import "./components/badge.css"; @import "./components/toast.css"; - -@tailwind utilities; - @import "./components/motion.css"; -/* Global base — self-hosted fonts */ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Self-hosted fonts */ @font-face { font-family: 'Inter'; src: url('/fonts/inter-400.woff2') format('woff2'); diff --git a/services/web-ui/tailwind.config.js b/services/web-ui/tailwind.config.js index a17d18d..7e55fec 100644 --- a/services/web-ui/tailwind.config.js +++ b/services/web-ui/tailwind.config.js @@ -4,6 +4,11 @@ module.exports = { './public/**/*.html', './src/**/*.{css,js}', ], + safelist: [ + { pattern: /^wd-/ }, + { pattern: /^is-/ }, + 'nav-dev-badge', + ], darkMode: 'class', theme: { extend: {