fix: banner/avatar overlap in settings preview and refine profile color system
Move bg-surface-channel from info section to card wrapper in AccountPanel so the avatar's negative margin overlaps into the banner correctly. Replace accent color presets with 7×3 banner color palette, remove accent color tinting from display names in popout/modal, and refactor gradient entries to expose from/to hex stops.
This commit is contained in:
@@ -251,7 +251,7 @@ export function UserProfileModal() {
|
||||
</div>
|
||||
|
||||
{/* Header (avatar + name) */}
|
||||
<div className="px-5 flex-shrink-0">
|
||||
<div className="px-5 flex-shrink-0 relative">
|
||||
<div
|
||||
className="mt-[-48px] mb-2 w-fit rounded-full"
|
||||
style={{ border: '4px solid var(--color-surface-elevated, #1e1e2a)' }}
|
||||
@@ -269,7 +269,6 @@ export function UserProfileModal() {
|
||||
<Username
|
||||
username={displayName}
|
||||
className="text-[20px] font-bold leading-tight"
|
||||
style={user.accentColor ? { color: user.accentColor } : undefined}
|
||||
/>
|
||||
<div className="text-[14px] text-txt-tertiary mt-0.5">
|
||||
{domain ? (
|
||||
@@ -346,23 +345,6 @@ export function UserProfileModal() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Accent color */}
|
||||
{user.accentColor && (
|
||||
<div>
|
||||
<span className="text-[11px] uppercase tracking-wide font-semibold text-txt-tertiary">
|
||||
Accent Color
|
||||
</span>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<div
|
||||
className="w-5 h-5 rounded-full border border-white/10"
|
||||
style={{ backgroundColor: user.accentColor }}
|
||||
/>
|
||||
<span className="text-[12px] text-txt-tertiary font-mono">
|
||||
{user.accentColor}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useAuthStore } from '../../../stores/authStore';
|
||||
import { Avatar } from '../../ui/Avatar';
|
||||
import { ImageCropModal } from '../../ui/ImageCropModal';
|
||||
import { api } from '../../../api/client';
|
||||
import { getAvatarGradient, adjustColor, AVATAR_GRADIENT_MAP, ACCENT_PRESETS } from '../../../utils/gradients';
|
||||
import { getAvatarGradient, adjustColor, AVATAR_GRADIENT_MAP, BANNER_COLOR_PRESETS } from '../../../utils/gradients';
|
||||
import { AVATAR_COLORS } from '@backspace/shared';
|
||||
import type { User, UserStatus, AvatarColor } from '@backspace/shared';
|
||||
|
||||
@@ -212,17 +212,17 @@ export function AccountPanel() {
|
||||
</div>
|
||||
|
||||
{/* Live Preview Card */}
|
||||
<div className="rounded-lg overflow-hidden border border-white/[0.06] mb-4">
|
||||
<div className="rounded-lg overflow-hidden border border-white/[0.06] mb-4 bg-surface-channel">
|
||||
{/* Banner area */}
|
||||
<div
|
||||
className="h-[80px] relative"
|
||||
className="h-[80px]"
|
||||
style={displayBannerSrc
|
||||
? { backgroundImage: `url(${displayBannerSrc})`, backgroundSize: 'cover', backgroundPosition: 'center' }
|
||||
: { background: bannerFallback, opacity: 0.6 }
|
||||
}
|
||||
/>
|
||||
{/* Avatar + info */}
|
||||
<div className="px-4 pb-3 bg-surface-channel">
|
||||
<div className="px-4 pb-3">
|
||||
<div
|
||||
className="mt-[-28px] mb-2 w-fit rounded-full"
|
||||
style={{ border: '4px solid var(--color-surface-channel, #1e1e2a)' }}
|
||||
@@ -244,8 +244,7 @@ export function AccountPanel() {
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className="font-semibold text-[15px] leading-tight"
|
||||
style={{ color: effectiveAccent ?? 'var(--color-txt-primary)' }}
|
||||
className="font-semibold text-[15px] leading-tight text-txt-primary"
|
||||
>
|
||||
{effectiveDisplayName}
|
||||
</div>
|
||||
@@ -410,24 +409,29 @@ export function AccountPanel() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Accent Color */}
|
||||
{/* Banner Color */}
|
||||
<div>
|
||||
<label className="block text-xs text-txt-secondary mb-1.5">Accent Color</label>
|
||||
<label className="block text-xs text-txt-secondary mb-1.5">Banner Color</label>
|
||||
<div className="grid grid-cols-7 gap-1.5 mb-2">
|
||||
{ACCENT_PRESETS.map((color) => (
|
||||
<button
|
||||
key={color}
|
||||
type="button"
|
||||
onClick={() => { setAccentColor(color); setCustomHex(color); }}
|
||||
className="w-7 h-7 rounded-full border-2 transition-all hover:scale-110"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
borderColor: accentColor === color ? 'white' : 'transparent',
|
||||
boxShadow: accentColor === color ? `0 0 0 2px ${color}40` : 'none',
|
||||
}}
|
||||
title={color}
|
||||
/>
|
||||
))}
|
||||
{[0, 1, 2].map((row) =>
|
||||
BANNER_COLOR_PRESETS.map((family) => {
|
||||
const color = family[row]!;
|
||||
return (
|
||||
<button
|
||||
key={color}
|
||||
type="button"
|
||||
onClick={() => { setAccentColor(color); setCustomHex(color); }}
|
||||
className="w-7 h-7 rounded-full border-2 transition-all hover:scale-110"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
borderColor: accentColor === color ? 'white' : 'transparent',
|
||||
boxShadow: accentColor === color ? `0 0 0 2px ${color}40` : 'none',
|
||||
}}
|
||||
title={color}
|
||||
/>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
|
||||
@@ -97,7 +97,7 @@ export function UserProfilePopout({ user, onClose, position }: UserProfilePopout
|
||||
/>
|
||||
|
||||
{/* Body */}
|
||||
<div className="px-4 pb-4">
|
||||
<div className="px-4 pb-4 relative">
|
||||
{/* Avatar */}
|
||||
<div
|
||||
className="mt-[-40px] mb-3 w-fit rounded-full"
|
||||
@@ -117,7 +117,6 @@ export function UserProfilePopout({ user, onClose, position }: UserProfilePopout
|
||||
<Username
|
||||
username={user.displayName ?? baseName}
|
||||
className="text-[16px] font-semibold leading-tight"
|
||||
style={user.accentColor ? { color: user.accentColor } : undefined}
|
||||
/>
|
||||
<div className="text-[13px] text-txt-tertiary">
|
||||
{domain ? (
|
||||
|
||||
Reference in New Issue
Block a user