diff --git a/package-lock.json b/package-lock.json index 44e944e..73da11b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "melodymuse", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "melodymuse", - "version": "0.1.0", + "version": "0.2.0", "dependencies": { "jszip": "^3.10.1", "lucide-react": "^0.451.0", diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..f24ef63 --- /dev/null +++ b/postcss.config.js @@ -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: {}, + }, +}; diff --git a/src/index.css b/src/index.css index f2bc3de..4047bf7 100644 --- a/src/index.css +++ b/src/index.css @@ -40,16 +40,6 @@ @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 { @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 @@ -91,15 +81,6 @@ 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-0 { animation-delay: 0ms; diff --git a/tailwind.config.js b/tailwind.config.js index e12d116..ab11dee 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,56 +1,68 @@ /** @type {import('tailwindcss').Config} */ export default { - content: ['./index.html', './src/**/*.{ts,tsx}'], - darkMode: 'class', + content: ["./index.html", "./src/**/*.{ts,tsx}"], + // 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: { extend: { colors: { // Dark mode (default) palette bg: { - DEFAULT: '#080810', - card: '#111118', - hover: '#16161f', + DEFAULT: "#080810", + card: "#111118", + hover: "#16161f", }, // Light mode palette (applied via :root when not .dark) bgLight: { - DEFAULT: '#f8fafc', - card: '#ffffff', + DEFAULT: "#f8fafc", + card: "#ffffff", }, border: { - DEFAULT: 'rgba(255, 255, 255, 0.06)', + DEFAULT: "rgba(255, 255, 255, 0.06)", }, borderLight: { - DEFAULT: 'rgba(0, 0, 0, 0.08)', + DEFAULT: "rgba(0, 0, 0, 0.08)", }, accent: { - primary: '#7c3aed', - secondary: '#06b6d4', - secondaryLight: '#0891b2', + primary: "#7c3aed", + secondary: "#06b6d4", + secondaryLight: "#0891b2", }, fg: { - DEFAULT: '#e2e8f0', - muted: '#64748b', - dark: '#0f172a', + DEFAULT: "#e2e8f0", + muted: "#64748b", + dark: "#0f172a", }, - tag: '#a78bfa', + tag: "#a78bfa", }, animation: { - 'gradient-shift': 'gradient-shift 8s ease infinite', - 'fade-up': 'fade-up 300ms ease-out forwards', - 'pulse-slow': 'pulse 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite', + "gradient-shift": "gradient-shift 8s ease infinite", + "fade-up": "fade-up 300ms ease-out forwards", + "pulse-slow": "pulse 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite", }, keyframes: { - 'gradient-shift': { - '0%, 100%': { backgroundPosition: '0% 50%' }, - '50%': { backgroundPosition: '100% 50%' }, + "gradient-shift": { + "0%, 100%": { backgroundPosition: "0% 50%" }, + "50%": { backgroundPosition: "100% 50%" }, }, - 'fade-up': { - '0%': { opacity: '0', transform: 'translateY(20px)' }, - '100%': { opacity: '1', transform: 'translateY(0)' }, + "fade-up": { + "0%": { opacity: "0", transform: "translateY(20px)" }, + "100%": { opacity: "1", transform: "translateY(0)" }, }, }, fontFamily: { - mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'monospace'], + mono: [ + "ui-monospace", + "SFMono-Regular", + "Menlo", + "Monaco", + "Consolas", + "monospace", + ], }, }, },