Build standalone MelodyMuse SPA

Drop the Supabase backend and call the AI provider directly from the
browser. The endpoint URL, API key, and model name are stored in
localStorage and used for direct /chat/completions requests.

- src/lib/llm.ts: config persistence, direct fetch, JSON extraction,
  shape validation, connection test
- src/lib/prompts.ts: full + partial-regeneration system prompts and
  user-message builder
- src/lib/{api,supabase}.ts removed
- supabase/ directory removed
- @supabase/supabase-js dropped from package.json
- README updated to describe the standalone architecture and CORS caveats
- .gitignore: drop Supabase entries, exclude *.tsbuildinfo
This commit is contained in:
2026-06-03 01:25:22 +02:00
parent f2401d0c57
commit d42410560f
37 changed files with 5443 additions and 376 deletions
+149
View File
@@ -0,0 +1,149 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
color-scheme: dark;
}
html.dark {
color-scheme: dark;
}
html:not(.dark) {
color-scheme: light;
}
html, body, #root {
height: 100%;
}
body {
@apply bg-bg text-fg antialiased font-sans;
margin: 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
html:not(.dark) body {
@apply bg-bgLight text-fg-dark;
}
}
@layer components {
.card {
@apply bg-bg-card border border-border rounded-2xl;
}
html:not(.dark) .card {
@apply bg-bgLight-card border-borderLight;
}
.card-hover {
@apply hover:bg-bg-hover transition-colors duration-150;
}
html:not(.dark) .card-hover:hover {
@apply bg-slate-50;
}
.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-hover border border-border text-fg hover:bg-bg
transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed;
}
html:not(.dark) .btn-secondary {
@apply bg-white border-borderLight text-fg-dark hover:bg-slate-50;
}
.btn-ghost {
@apply inline-flex items-center justify-center gap-1.5 px-2.5 py-1.5 rounded-md text-sm
text-fg-muted hover:text-fg hover:bg-bg-hover
transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed;
}
html:not(.dark) .btn-ghost {
@apply text-slate-500 hover:text-fg-dark hover:bg-slate-100;
}
.input {
@apply w-full bg-bg-card border border-border rounded-lg px-3 py-2 text-fg
placeholder-fg-muted focus:outline-none focus:border-accent-primary
focus:ring-1 focus:ring-accent-primary/40 transition-colors duration-150;
}
html:not(.dark) .input {
@apply bg-white border-borderLight text-fg-dark placeholder:text-slate-400;
}
.textarea {
@apply input resize-y;
}
.chip {
@apply inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full border border-border
bg-bg-card text-sm font-medium text-fg hover:bg-bg-hover
transition-colors duration-150;
}
html:not(.dark) .chip {
@apply bg-white border-borderLight text-fg-dark hover:bg-slate-50;
}
.gradient-text {
@apply bg-gradient-to-r from-violet-400 via-fuchsia-400 to-cyan-400 bg-clip-text text-transparent;
}
.gradient-bg {
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%);
}
.animated-gradient-bg {
background: linear-gradient(135deg, rgba(124, 58, 237, 0.25) 0%, rgba(6, 182, 212, 0.20) 35%, rgba(8, 8, 16, 0) 70%, rgba(124, 58, 237, 0.15) 100%);
background-size: 200% 200%;
animation: gradient-shift 8s ease infinite;
}
.stagger-0 { animation-delay: 0ms; }
.stagger-1 { animation-delay: 80ms; }
.stagger-2 { animation-delay: 160ms; }
.stagger-3 { animation-delay: 240ms; }
.stagger-4 { animation-delay: 320ms; }
}
@layer utilities {
.scrollbar-thin {
scrollbar-width: thin;
scrollbar-color: rgba(255, 255, 255, 0.1) transparent;
}
html:not(.dark) .scrollbar-thin {
scrollbar-color: rgba(0, 0, 0, 0.15) transparent;
}
.scrollbar-thin::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.1);
border-radius: 4px;
}
html:not(.dark) .scrollbar-thin::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.15);
}
}