feat: Discord Dark theme overhaul — darker palette, floating controls, UI polish

Shift entire color palette from Discord's Ash theme to the darker Dark theme.
Redesign VoiceControlBar as floating auto-show pill, add gradient Join Voice
screen, move invite icon to server header, add voice channel user status
badges, update auth pages with subtle gradient backgrounds, and sweep all
hardcoded hex colors across 14 files to match the new darker palette.
This commit is contained in:
Jannis Braun
2026-02-19 06:49:50 +01:00
parent cd48261f54
commit 1f813395e2
28 changed files with 311 additions and 277 deletions
@@ -14,6 +14,7 @@ interface VoiceChannelProps {
export function VoiceChannel({ channelId, channelName, onClick }: VoiceChannelProps) {
const voiceUsers = useVoiceStore((s) => s.voiceUsers.get(channelId)) ?? EMPTY_VOICE_USERS;
const currentVoiceChannel = useVoiceStore((s) => s.currentVoiceChannelId);
const participants = useVoiceStore((s) => s.participants);
const members = useServerStore((s) => s.members);
const isActive = currentVoiceChannel === channelId;
@@ -21,16 +22,16 @@ export function VoiceChannel({ channelId, channelName, onClick }: VoiceChannelPr
<div>
<button
onClick={onClick}
className={`w-full flex items-center gap-1.5 px-2 py-1.5 rounded text-sm group ${
className={`w-full flex items-center gap-1.5 px-2 h-8 rounded-[4px] group transition-colors ${
isActive
? 'bg-discord-bg-active text-white'
: 'text-discord-text-muted hover:text-discord-text-secondary hover:bg-discord-bg-hover'
? 'bg-discord-modifier-selected text-white'
: 'text-discord-text-muted hover:text-discord-text-secondary hover:bg-discord-modifier-hover'
}`}
>
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" className="flex-shrink-0 opacity-60">
<path d="M11 5L6 9H2V15H6L11 19V5ZM15.54 8.46C16.48 9.4 17 10.67 17 12S16.48 14.6 15.54 15.54L14.12 14.12C14.69 13.55 15 12.79 15 12S14.69 10.45 14.12 9.88L15.54 8.46ZM19.07 4.93C20.91 6.77 22 9.28 22 12C22 14.72 20.91 17.23 19.07 19.07L17.66 17.66C19.11 16.21 20 14.21 20 12C20 9.79 19.11 7.79 17.66 6.34L19.07 4.93Z" />
</svg>
<span className="truncate">{channelName}</span>
<span className="truncate text-[15px] font-medium">{channelName}</span>
</button>
{/* Connected users */}
@@ -40,15 +41,40 @@ export function VoiceChannel({ channelId, channelName, onClick }: VoiceChannelPr
const member = members.find(m => m.userId === userId);
if (!member) return null;
const displayName = member.user.displayName ?? member.user.username;
// Find participant for status badges
const participant = participants.find(p => p.identity === userId || p.username === member.user.username);
const isMuted = participant ? !participant.audioTrack : false;
const hasCamera = participant ? participant.videoTrack !== null : false;
const isScreenSharing = participant ? participant.screenTrack !== null : false;
return (
<div key={userId} className="flex items-center gap-2 px-2 py-0.5 rounded hover:bg-discord-bg-hover transition-colors">
<div key={userId} className="flex items-center gap-2 px-2 py-0.5 rounded hover:bg-discord-modifier-hover transition-colors">
<Avatar
src={member.user.avatar}
name={displayName}
size={20}
status={member.user.status}
/>
<span className="text-xs text-discord-text-secondary truncate">{displayName}</span>
<span className="text-[13px] text-discord-text-secondary truncate flex-1 min-w-0">{displayName}</span>
{/* Status badges */}
<div className="flex items-center gap-1 flex-shrink-0">
{isMuted && (
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" className="text-discord-red">
<path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z" />
<path d="M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z" />
<line x1="3" y1="3" x2="21" y2="21" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" />
</svg>
)}
{hasCamera && (
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" className="text-discord-text-muted">
<path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z" />
</svg>
)}
{isScreenSharing && (
<span className="bg-discord-green text-white text-[9px] font-bold px-1 rounded leading-[14px]">LIVE</span>
)}
</div>
</div>
);
})}