Fix CSS: add postcss config, safelist stagger-N, drop dead rules
The page was loading with effectively no Tailwind utility classes
because there was no postcss.config.js — Vite didn't know to run
Tailwind's PostCSS plugin. The preflight and @apply references in
src/index.css were partially working (because some Tailwind processing
was happening implicitly), but the JIT content scanner wasn't running,
so all utility classes (flex, grid, p-*, text-fg, bg-bg, …) were
missing from the build. The page rendered as unstyled HTML.
postcss.config.js — newly added. Tells Vite to run tailwindcss +
autoprefixer. Written in plain UTF-8 (the earlier draft saved as
UTF-16 with BOM, which Node couldn't parse, hence the 'Syntax Error'
in the file viewer).
tailwind.config.js — added a safelist for the dynamic
`stagger-${index}` classes used in ResultCard.tsx. The JIT
content scanner can't resolve a template literal, so without the
safelist the four matching rules (stagger-0 … stagger-4) got purged
from the build even though they're used at runtime. Adding them to
the safelist keeps them alive.
src/index.css — dropped three dead rules (card-hover, btn-primary,
gradient-bg-soft) that the modern UI redesign made unused. They
were in the file but never referenced by any .tsx, so the
content-aware purger was stripping them anyway; explicit removal
keeps the source honest.
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "melodymuse",
|
"name": "melodymuse",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "melodymuse",
|
"name": "melodymuse",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"lucide-react": "^0.451.0",
|
"lucide-react": "^0.451.0",
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// PostCSS config for Vite. Tells Vite to run Tailwind's JIT compiler and
|
||||||
|
// Autoprefixer on every CSS file it processes. Without this, Vite has no
|
||||||
|
// way of knowing which PostCSS plugins to apply, and the @tailwind
|
||||||
|
// directives in src/index.css would either be ignored or only partially
|
||||||
|
// processed (preflight + @apply but no utility classes).
|
||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -40,16 +40,6 @@
|
|||||||
@apply bg-bg-card border border-border rounded-2xl;
|
@apply bg-bg-card border border-border rounded-2xl;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-hover {
|
|
||||||
@apply hover:bg-bg-hover transition-colors duration-150;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
@apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg font-medium text-white
|
|
||||||
bg-accent-primary hover:bg-violet-500 active:bg-violet-700
|
|
||||||
transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-secondary {
|
.btn-secondary {
|
||||||
@apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg font-medium
|
@apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg font-medium
|
||||||
bg-bg-card border border-border text-fg hover:bg-bg-hover
|
bg-bg-card border border-border text-fg hover:bg-bg-hover
|
||||||
@@ -91,15 +81,6 @@
|
|||||||
background: linear-gradient(135deg, #7c3aed 0%, #06b6d4 100%);
|
background: linear-gradient(135deg, #7c3aed 0%, #06b6d4 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gradient-bg-soft {
|
|
||||||
background: linear-gradient(
|
|
||||||
135deg,
|
|
||||||
rgba(124, 58, 237, 0.18) 0%,
|
|
||||||
rgba(6, 182, 212, 0.12) 50%,
|
|
||||||
rgba(8, 8, 16, 0) 100%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stagger delays for the result cards' fade-up animation. */
|
/* Stagger delays for the result cards' fade-up animation. */
|
||||||
.stagger-0 {
|
.stagger-0 {
|
||||||
animation-delay: 0ms;
|
animation-delay: 0ms;
|
||||||
|
|||||||
+38
-26
@@ -1,56 +1,68 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
export default {
|
export default {
|
||||||
content: ['./index.html', './src/**/*.{ts,tsx}'],
|
content: ["./index.html", "./src/**/*.{ts,tsx}"],
|
||||||
darkMode: 'class',
|
// The result cards use a dynamic class `stagger-${index}` for the
|
||||||
|
// per-card animation delay. Tailwind's content scanner can't statically
|
||||||
|
// resolve that template literal, so without the safelist the four
|
||||||
|
// matching rules from src/index.css get purged from the build.
|
||||||
|
safelist: [{ pattern: /^stagger-[0-4]$/ }],
|
||||||
|
darkMode: "class",
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
// Dark mode (default) palette
|
// Dark mode (default) palette
|
||||||
bg: {
|
bg: {
|
||||||
DEFAULT: '#080810',
|
DEFAULT: "#080810",
|
||||||
card: '#111118',
|
card: "#111118",
|
||||||
hover: '#16161f',
|
hover: "#16161f",
|
||||||
},
|
},
|
||||||
// Light mode palette (applied via :root when not .dark)
|
// Light mode palette (applied via :root when not .dark)
|
||||||
bgLight: {
|
bgLight: {
|
||||||
DEFAULT: '#f8fafc',
|
DEFAULT: "#f8fafc",
|
||||||
card: '#ffffff',
|
card: "#ffffff",
|
||||||
},
|
},
|
||||||
border: {
|
border: {
|
||||||
DEFAULT: 'rgba(255, 255, 255, 0.06)',
|
DEFAULT: "rgba(255, 255, 255, 0.06)",
|
||||||
},
|
},
|
||||||
borderLight: {
|
borderLight: {
|
||||||
DEFAULT: 'rgba(0, 0, 0, 0.08)',
|
DEFAULT: "rgba(0, 0, 0, 0.08)",
|
||||||
},
|
},
|
||||||
accent: {
|
accent: {
|
||||||
primary: '#7c3aed',
|
primary: "#7c3aed",
|
||||||
secondary: '#06b6d4',
|
secondary: "#06b6d4",
|
||||||
secondaryLight: '#0891b2',
|
secondaryLight: "#0891b2",
|
||||||
},
|
},
|
||||||
fg: {
|
fg: {
|
||||||
DEFAULT: '#e2e8f0',
|
DEFAULT: "#e2e8f0",
|
||||||
muted: '#64748b',
|
muted: "#64748b",
|
||||||
dark: '#0f172a',
|
dark: "#0f172a",
|
||||||
},
|
},
|
||||||
tag: '#a78bfa',
|
tag: "#a78bfa",
|
||||||
},
|
},
|
||||||
animation: {
|
animation: {
|
||||||
'gradient-shift': 'gradient-shift 8s ease infinite',
|
"gradient-shift": "gradient-shift 8s ease infinite",
|
||||||
'fade-up': 'fade-up 300ms ease-out forwards',
|
"fade-up": "fade-up 300ms ease-out forwards",
|
||||||
'pulse-slow': 'pulse 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite',
|
"pulse-slow": "pulse 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite",
|
||||||
},
|
},
|
||||||
keyframes: {
|
keyframes: {
|
||||||
'gradient-shift': {
|
"gradient-shift": {
|
||||||
'0%, 100%': { backgroundPosition: '0% 50%' },
|
"0%, 100%": { backgroundPosition: "0% 50%" },
|
||||||
'50%': { backgroundPosition: '100% 50%' },
|
"50%": { backgroundPosition: "100% 50%" },
|
||||||
},
|
},
|
||||||
'fade-up': {
|
"fade-up": {
|
||||||
'0%': { opacity: '0', transform: 'translateY(20px)' },
|
"0%": { opacity: "0", transform: "translateY(20px)" },
|
||||||
'100%': { opacity: '1', transform: 'translateY(0)' },
|
"100%": { opacity: "1", transform: "translateY(0)" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'monospace'],
|
mono: [
|
||||||
|
"ui-monospace",
|
||||||
|
"SFMono-Regular",
|
||||||
|
"Menlo",
|
||||||
|
"Monaco",
|
||||||
|
"Consolas",
|
||||||
|
"monospace",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user