feat(theme): replace purple accent with teal/turquoise color scheme
Swaps violet (#8b5cf6) for teal (#14b8a6/#0d9488) across all components and updates dark backgrounds to have a green-tinted hue instead of blue-navy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -95,8 +95,8 @@ function Input(props: React.InputHTMLAttributes<HTMLInputElement>) {
|
||||
onBlur={(e) => { setFocused(false); props.onBlur?.(e); }}
|
||||
style={{
|
||||
width: "100%", padding: "8px 12px",
|
||||
background: "#151828",
|
||||
border: `1px solid ${focused ? "rgba(139,92,246,0.4)" : border}`,
|
||||
background: "#101c18",
|
||||
border: `1px solid ${focused ? "rgba(20,184,166,0.4)" : border}`,
|
||||
borderRadius: 8, color: "#e8e9f0",
|
||||
fontSize: 13, fontFamily: "inherit",
|
||||
outline: "none", boxSizing: "border-box",
|
||||
@@ -114,13 +114,13 @@ function SaveBtn({ pending, saved, onClick }: { pending: boolean; saved: boolean
|
||||
disabled={pending}
|
||||
style={{
|
||||
padding: "8px 20px", borderRadius: 8,
|
||||
background: saved ? "rgba(52,211,153,0.12)" : "linear-gradient(135deg, #7b5cf6, #06b6d4)",
|
||||
background: saved ? "rgba(52,211,153,0.12)" : "linear-gradient(135deg, #0d9488, #06b6d4)",
|
||||
border: saved ? "1px solid rgba(52,211,153,0.3)" : "none",
|
||||
color: saved ? "#34d399" : "white",
|
||||
cursor: pending ? "default" : "pointer",
|
||||
fontSize: 13, fontWeight: 600, fontFamily: "inherit",
|
||||
transition: "all 0.2s",
|
||||
boxShadow: saved ? "none" : "0 2px 12px rgba(139,92,246,0.3)",
|
||||
boxShadow: saved ? "none" : "0 2px 12px rgba(20,184,166,0.3)",
|
||||
}}
|
||||
>
|
||||
{pending ? "Saving…" : saved ? "Saved ✓" : "Save"}
|
||||
@@ -211,7 +211,7 @@ function ProfileSection({ me }: { me: MemberRead }) {
|
||||
} finally { setUploading(false); }
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="avatar-upload" style={{ padding: "7px 14px", borderRadius: 8, background: "rgba(139,92,246,0.12)", border: "1px solid rgba(139,92,246,0.3)", color: "#a78bfa", cursor: "pointer", fontSize: 12, fontWeight: 600 }}>
|
||||
<label htmlFor="avatar-upload" style={{ padding: "7px 14px", borderRadius: 8, background: "rgba(20,184,166,0.12)", border: "1px solid rgba(20,184,166,0.3)", color: "#2dd4bf", cursor: "pointer", fontSize: 12, fontWeight: 600 }}>
|
||||
{uploading ? "Uploading…" : "Upload"}
|
||||
</label>
|
||||
<button
|
||||
@@ -421,7 +421,7 @@ function StorageSection({ bandId, band, amAdmin, me }: { bandId: string; band: B
|
||||
<Input value={folderInput} onChange={(e) => setFolderInput(e.target.value)} placeholder={defaultPath} style={{ fontFamily: "monospace" }} />
|
||||
<div style={{ display: "flex", gap: 8, marginTop: 8 }}>
|
||||
<button onClick={() => pathMutation.mutate(folderInput)} disabled={pathMutation.isPending}
|
||||
style={{ padding: "6px 14px", background: "rgba(139,92,246,0.12)", border: "1px solid rgba(139,92,246,0.3)", borderRadius: 6, color: "#a78bfa", cursor: "pointer", fontSize: 12, fontWeight: 600, fontFamily: "inherit" }}>
|
||||
style={{ padding: "6px 14px", background: "rgba(20,184,166,0.12)", border: "1px solid rgba(20,184,166,0.3)", borderRadius: 6, color: "#2dd4bf", cursor: "pointer", fontSize: 12, fontWeight: 600, fontFamily: "inherit" }}>
|
||||
{pathMutation.isPending ? "Saving…" : "Save"}
|
||||
</button>
|
||||
<button onClick={() => setEditingPath(false)}
|
||||
@@ -498,16 +498,16 @@ function MembersSection({ bandId, band, amAdmin, members, membersLoading }: { ba
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<button
|
||||
onClick={() => inviteMutation.mutate()} disabled={inviteMutation.isPending}
|
||||
style={{ padding: "8px 16px", background: "rgba(139,92,246,0.12)", border: "1px solid rgba(139,92,246,0.3)", borderRadius: 8, color: "#a78bfa", cursor: "pointer", fontSize: 13, fontWeight: 600, fontFamily: "inherit" }}>
|
||||
style={{ padding: "8px 16px", background: "rgba(20,184,166,0.12)", border: "1px solid rgba(20,184,166,0.3)", borderRadius: 8, color: "#2dd4bf", cursor: "pointer", fontSize: 13, fontWeight: 600, fontFamily: "inherit" }}>
|
||||
{inviteMutation.isPending ? "Generating…" : "+ Generate invite link"}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{inviteLink && (
|
||||
<div style={{ background: "rgba(139,92,246,0.06)", border: "1px solid rgba(139,92,246,0.22)", borderRadius: 10, padding: "12px 16px", marginBottom: 16 }}>
|
||||
<div style={{ background: "rgba(20,184,166,0.06)", border: "1px solid rgba(20,184,166,0.22)", borderRadius: 10, padding: "12px 16px", marginBottom: 16 }}>
|
||||
<p style={{ color: "rgba(232,233,240,0.35)", fontSize: 11, margin: "0 0 5px" }}>Invite link (copied · valid 72h):</p>
|
||||
<code style={{ color: "#a78bfa", fontSize: 12, wordBreak: "break-all", fontFamily: "monospace" }}>{inviteLink}</code>
|
||||
<code style={{ color: "#2dd4bf", fontSize: 12, wordBreak: "break-all", fontFamily: "monospace" }}>{inviteLink}</code>
|
||||
<button onClick={() => setInviteLink(null)} style={{ display: "block", marginTop: 6, background: "none", border: "none", color: "rgba(232,233,240,0.28)", cursor: "pointer", fontSize: 11, padding: 0, fontFamily: "inherit" }}>
|
||||
Dismiss
|
||||
</button>
|
||||
@@ -528,7 +528,7 @@ function MembersSection({ bandId, band, amAdmin, members, membersLoading }: { ba
|
||||
<div style={{ fontSize: 13, color: "rgba(232,233,240,0.75)" }}>{m.display_name}</div>
|
||||
<div style={{ fontSize: 11, color: "rgba(232,233,240,0.28)", marginTop: 1 }}>{m.email}</div>
|
||||
</div>
|
||||
<span style={{ fontSize: 10, fontFamily: "monospace", padding: "2px 7px", borderRadius: 4, background: m.role === "admin" ? "rgba(139,92,246,0.1)" : "rgba(255,255,255,0.05)", color: m.role === "admin" ? "#a78bfa" : "rgba(232,233,240,0.38)", border: `1px solid ${m.role === "admin" ? "rgba(139,92,246,0.28)" : border}`, whiteSpace: "nowrap" }}>
|
||||
<span style={{ fontSize: 10, fontFamily: "monospace", padding: "2px 7px", borderRadius: 4, background: m.role === "admin" ? "rgba(20,184,166,0.1)" : "rgba(255,255,255,0.05)", color: m.role === "admin" ? "#2dd4bf" : "rgba(232,233,240,0.38)", border: `1px solid ${m.role === "admin" ? "rgba(20,184,166,0.28)" : border}`, whiteSpace: "nowrap" }}>
|
||||
{m.role}
|
||||
</span>
|
||||
{amAdmin && m.role !== "admin" && (
|
||||
@@ -545,7 +545,7 @@ function MembersSection({ bandId, band, amAdmin, members, membersLoading }: { ba
|
||||
{/* Role legend */}
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: amAdmin ? 0 : 0 }}>
|
||||
<div style={{ padding: "10px 12px", background: "rgba(255,255,255,0.02)", border: `1px solid ${border}`, borderRadius: 8 }}>
|
||||
<div style={{ fontSize: 12, color: "#a78bfa", marginBottom: 3 }}>Admin</div>
|
||||
<div style={{ fontSize: 12, color: "#2dd4bf", marginBottom: 3 }}>Admin</div>
|
||||
<div style={{ fontSize: 11, color: "rgba(232,233,240,0.28)", lineHeight: 1.55 }}>Upload, delete, manage members and storage</div>
|
||||
</div>
|
||||
<div style={{ padding: "10px 12px", background: "rgba(255,255,255,0.02)", border: `1px solid ${border}`, borderRadius: 8 }}>
|
||||
@@ -627,9 +627,9 @@ function BandSection({ bandId, band }: { bandId: string; band: Band }) {
|
||||
<Label>Genre tags</Label>
|
||||
<div style={{ display: "flex", gap: 5, flexWrap: "wrap", marginBottom: 8 }}>
|
||||
{tags.map((t) => (
|
||||
<span key={t} style={{ background: "rgba(139,92,246,0.1)", color: "#a78bfa", fontSize: 11, padding: "3px 10px", borderRadius: 20, display: "flex", alignItems: "center", gap: 5 }}>
|
||||
<span key={t} style={{ background: "rgba(20,184,166,0.1)", color: "#2dd4bf", fontSize: 11, padding: "3px 10px", borderRadius: 20, display: "flex", alignItems: "center", gap: 5 }}>
|
||||
{t}
|
||||
<button onClick={() => setTags((p) => p.filter((x) => x !== t))} style={{ background: "none", border: "none", color: "#a78bfa", cursor: "pointer", fontSize: 13, padding: 0, lineHeight: 1, fontFamily: "inherit" }}>×</button>
|
||||
<button onClick={() => setTags((p) => p.filter((x) => x !== t))} style={{ background: "none", border: "none", color: "#2dd4bf", cursor: "pointer", fontSize: 13, padding: 0, lineHeight: 1, fontFamily: "inherit" }}>×</button>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
@@ -671,13 +671,13 @@ function NavItem({ label, active, onClick }: { label: string; active: boolean; o
|
||||
padding: "8px 10px", borderRadius: 8,
|
||||
border: "none", cursor: "pointer",
|
||||
fontSize: 13, fontFamily: "inherit", fontWeight: active ? 600 : 400,
|
||||
background: active ? "rgba(139,92,246,0.1)" : hovered ? "rgba(255,255,255,0.04)" : "transparent",
|
||||
color: active ? "#a78bfa" : hovered ? "rgba(232,233,240,0.75)" : "rgba(232,233,240,0.45)",
|
||||
background: active ? "rgba(20,184,166,0.1)" : hovered ? "rgba(255,255,255,0.04)" : "transparent",
|
||||
color: active ? "#2dd4bf" : hovered ? "rgba(232,233,240,0.75)" : "rgba(232,233,240,0.45)",
|
||||
transition: "all 0.12s",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
{active && <div style={{ position: "absolute", left: 0, top: "20%", bottom: "20%", width: 2, borderRadius: "0 2px 2px 0", background: "linear-gradient(to bottom, #7b5cf6, #22d3ee)" }} />}
|
||||
{active && <div style={{ position: "absolute", left: 0, top: "20%", bottom: "20%", width: 2, borderRadius: "0 2px 2px 0", background: "linear-gradient(to bottom, #0d9488, #22d3ee)" }} />}
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
@@ -744,7 +744,7 @@ export function SettingsPage() {
|
||||
{section !== "profile" || searchParams.has("section") ? (
|
||||
<div>
|
||||
<button onClick={() => setSearchParams({})}
|
||||
style={{ display: "flex", alignItems: "center", gap: 6, padding: "12px 16px", background: "none", border: "none", cursor: "pointer", color: "#a78bfa", fontSize: 13, fontFamily: "inherit" }}>
|
||||
style={{ display: "flex", alignItems: "center", gap: 6, padding: "12px 16px", background: "none", border: "none", cursor: "pointer", color: "#2dd4bf", fontSize: 13, fontFamily: "inherit" }}>
|
||||
← Settings
|
||||
</button>
|
||||
<div style={{ padding: "0 16px 24px" }}>
|
||||
@@ -782,7 +782,7 @@ export function SettingsPage() {
|
||||
<div style={{ display: "flex", height: "100%", overflow: "hidden" }}>
|
||||
|
||||
{/* Left nav */}
|
||||
<nav style={{ width: 220, minWidth: 220, background: "#10131f", borderRight: `1px solid ${border}`, padding: "20px 12px", display: "flex", flexDirection: "column", overflow: "hidden", flexShrink: 0 }}>
|
||||
<nav style={{ width: 220, minWidth: 220, background: "#0c1612", borderRight: `1px solid ${border}`, padding: "20px 12px", display: "flex", flexDirection: "column", overflow: "hidden", flexShrink: 0 }}>
|
||||
<h1 style={{ fontSize: 16, fontWeight: 800, color: "#e8e9f0", margin: "0 0 4px 8px", letterSpacing: -0.3 }}>Settings</h1>
|
||||
<div style={{ height: 1, background: border, margin: "12px 0" }} />
|
||||
|
||||
@@ -803,7 +803,7 @@ export function SettingsPage() {
|
||||
// Stay on same section if possible
|
||||
setSearchParams({ section }, { replace: true });
|
||||
}}
|
||||
style={{ width: "100%", padding: "6px 8px", background: "#151828", border: `1px solid ${borderBright}`, borderRadius: 7, color: "#e8e9f0", fontSize: 12, fontFamily: "inherit", cursor: "pointer", outline: "none" }}
|
||||
style={{ width: "100%", padding: "6px 8px", background: "#101c18", border: `1px solid ${borderBright}`, borderRadius: 7, color: "#e8e9f0", fontSize: 12, fontFamily: "inherit", cursor: "pointer", outline: "none" }}
|
||||
>
|
||||
{bands?.map((b) => (
|
||||
<option key={b.id} value={b.id}>{b.name}</option>
|
||||
|
||||
Reference in New Issue
Block a user