style(settings,views): elevate AccountSettings and ProfileView to SaaS Premium

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
senke 2026-02-07 15:09:53 +01:00
parent 8a3da49fbd
commit 0218035f53
11 changed files with 36 additions and 36 deletions

View file

@ -9,7 +9,7 @@ const meta: Meta<typeof ProfileView> = {
tags: ['autodocs'],
decorators: [
(Story) => (
<div className="bg-kodo-background min-h-layout-page w-full">
<div className="bg-background min-h-layout-page w-full">
<Story />
</div>
),

View file

@ -12,7 +12,7 @@ export function ProfileViewAboutTab({ profile }: ProfileViewAboutTabProps) {
<h3 className="text-xl font-display font-bold text-white mb-6">
Biography
</h3>
<p className="text-kodo-text-main leading-relaxed mb-6 whitespace-pre-line">
<p className="text-foreground leading-relaxed mb-6 whitespace-pre-line">
{profile.bio || 'No biography provided.'}
</p>
</Card>

View file

@ -22,7 +22,7 @@ export function ProfileViewOverview({
return (
<div className="space-y-8 animate-fadeIn">
{tracks.length > 0 ? (
<div className="relative rounded-2xl overflow-hidden bg-kodo-ink border border-kodo-steel">
<div className="relative rounded-2xl overflow-hidden bg-card border border-border">
<div className="p-8 flex flex-col md:flex-row gap-8 items-center">
<div className="w-32 h-32 md:w-48 md:h-48 shrink-0 shadow-2xl rounded-lg overflow-hidden">
<img
@ -39,10 +39,10 @@ export function ProfileViewOverview({
variant="cyan"
className="mb-2"
/>
<h2 className="text-2xl md:text-4xl font-display font-bold text-white mb-2">
<h2 className="text-2xl md:text-4xl font-display font-bold text-foreground mb-2 tracking-tight">
{tracks[0].title}
</h2>
<p className="text-kodo-content-dim mb-6">
<p className="text-muted-foreground mb-6">
Latest upload from {profile.username}.
</p>
<div className="flex justify-center md:justify-start gap-4">
@ -72,7 +72,7 @@ export function ProfileViewOverview({
{tracks.length > 0 && (
<div>
<div className="flex justify-between items-center mb-4">
<h3 className="font-bold text-white">Popular Tracks</h3>
<h3 className="font-bold text-foreground tracking-tight">Popular Tracks</h3>
<Button variant="ghost" size="sm" onClick={onViewAllTracks}>
View All
</Button>
@ -97,10 +97,10 @@ export function ProfileViewOverview({
/>
</div>
<div className="flex-1 min-w-0">
<div className="text-sm font-bold text-white truncate">
<div className="text-sm font-bold text-foreground truncate">
{track.title}
</div>
<div className="text-xs text-kodo-content-dim">
<div className="text-xs text-muted-foreground">
{track.plays?.toLocaleString() || 0} plays
</div>
</div>

View file

@ -11,7 +11,7 @@ export function ProfileViewPlaylistCard({ playlist }: ProfileViewPlaylistCardPro
return (
<Card
variant="glass"
className="p-0 overflow-hidden group cursor-pointer hover:border-kodo-magenta/50"
className="p-0 overflow-hidden group cursor-pointer hover:border-primary/50 transition-colors duration-[var(--duration-normal)]"
>
<div className="aspect-video relative overflow-hidden">
<img

View file

@ -13,7 +13,7 @@ export function ProfileViewPlaylistsTab({ playlists }: ProfileViewPlaylistsTabPr
<ProfileViewPlaylistCard key={playlist.id} playlist={playlist} />
))
) : (
<p className="col-span-full text-center text-kodo-content-dim">
<p className="col-span-full text-center text-muted-foreground">
No playlists found.
</p>
)}

View file

@ -10,13 +10,13 @@ export function ProfileViewSidebar({ profile }: ProfileViewSidebarProps) {
return (
<div className="space-y-8">
<Card variant="default">
<h3 className="text-sm font-bold text-kodo-content-dim uppercase tracking-wider mb-4">
<h3 className="text-sm font-bold text-muted-foreground uppercase tracking-wider mb-4">
Connections
</h3>
<div className="space-y-4">
{profile.website && (
<div className="flex items-center gap-4 text-sm text-kodo-content-dim hover:text-white cursor-pointer transition-colors">
<Globe className="w-4 h-4 text-kodo-steel" />
<div className="flex items-center gap-4 text-sm text-muted-foreground hover:text-foreground cursor-pointer transition-colors duration-[var(--duration-normal)]">
<Globe className="w-4 h-4 text-muted-foreground" />
<a
href={
profile.website.startsWith('http')
@ -32,8 +32,8 @@ export function ProfileViewSidebar({ profile }: ProfileViewSidebarProps) {
</div>
)}
{profile.socials?.twitter && (
<div className="flex items-center gap-4 text-sm text-kodo-content-dim hover:text-white cursor-pointer transition-colors">
<Twitter className="w-4 h-4 text-kodo-steel" />
<div className="flex items-center gap-4 text-sm text-muted-foreground hover:text-foreground cursor-pointer transition-colors duration-[var(--duration-normal)]">
<Twitter className="w-4 h-4 text-muted-foreground" />
<span>{profile.socials.twitter}</span>
</div>
)}
@ -47,14 +47,14 @@ export function ProfileViewSidebar({ profile }: ProfileViewSidebarProps) {
</Card>
<Card variant="glass">
<h3 className="text-sm font-bold text-kodo-gold uppercase tracking-wider mb-4 flex items-center gap-2">
<h3 className="text-sm font-bold text-warning uppercase tracking-wider mb-4 flex items-center gap-2">
<CheckCircle className="w-4 h-4" /> Achievements
</h3>
<div className="grid grid-cols-4 gap-2">
{[1, 2, 3].map((i) => (
<div
key={i}
className="aspect-square bg-kodo-ink rounded-lg flex items-center justify-center text-xl border border-kodo-gold/20 hover:border-kodo-gold hover:bg-kodo-gold/10 transition-all cursor-pointer tooltip group relative"
className="aspect-square bg-card rounded-xl flex items-center justify-center text-xl border border-warning/20 hover:border-warning hover:bg-warning/10 transition-all duration-[var(--duration-normal)] cursor-pointer tooltip group relative"
>
{['🏆', '⚡', '🎹'][i - 1]}
</div>

View file

@ -8,7 +8,7 @@ const meta: Meta<typeof ProfileViewSkeleton> = {
tags: ['autodocs'],
decorators: [
(Story) => (
<div className="bg-kodo-background min-h-layout-story w-full">
<div className="bg-background min-h-layout-story w-full">
<Story />
</div>
),

View file

@ -13,7 +13,7 @@ export function ProfileViewTrackCard({ track, mode }: ProfileViewTrackCardProps)
if (mode === 'grid') {
return (
<div
className="aspect-square relative group cursor-pointer overflow-hidden rounded-xl bg-kodo-graphite"
className="aspect-square relative group cursor-pointer overflow-hidden rounded-xl bg-muted"
onClick={() => playTrack(track)}
>
<img
@ -43,7 +43,7 @@ export function ProfileViewTrackCard({ track, mode }: ProfileViewTrackCardProps)
return (
<Card
variant="default"
className="flex gap-4 p-4 items-center group hover:border-kodo-steel/50 transition-all cursor-pointer"
className="flex gap-4 p-4 items-center group hover:border-primary/50 transition-all duration-[var(--duration-normal)] cursor-pointer"
onClick={() => playTrack(track)}
>
<div className="w-12 h-12 rounded overflow-hidden relative shrink-0">
@ -57,12 +57,12 @@ export function ProfileViewTrackCard({ track, mode }: ProfileViewTrackCardProps)
</div>
</div>
<div className="flex-1 min-w-0">
<h4 className="font-bold text-white text-sm truncate group-hover:text-white">
<h4 className="font-bold text-foreground text-sm truncate group-hover:text-foreground">
{track.title}
</h4>
<p className="text-kodo-content-dim text-xs">{track.artist}</p>
<p className="text-muted-foreground text-xs">{track.artist}</p>
</div>
<div className="hidden md:flex items-center gap-4 text-xs text-kodo-content-dim">
<div className="hidden md:flex items-center gap-4 text-xs text-muted-foreground">
<span className="flex items-center gap-1">
<Play className="w-3 h-3" /> {track.play_count}
</span>

View file

@ -16,7 +16,7 @@ export function ProfileViewTracksTab({ tracks, viewMode }: ProfileViewTracksTabP
<ProfileViewTrackCard key={track.id} track={track} mode={viewMode} />
))
) : (
<p className="col-span-full text-center text-kodo-content-dim">
<p className="col-span-full text-center text-muted-foreground">
No tracks found.
</p>
)}

View file

@ -7,7 +7,7 @@ const meta = {
tags: ['autodocs'],
decorators: [
(Story) => (
<div className="max-w-2xl mx-auto p-4 bg-kodo-background">
<div className="max-w-2xl mx-auto p-4 bg-background">
<Story />
</div>
),

View file

@ -14,31 +14,31 @@ export function AccountSettingsSkeleton({ className }: AccountSettingsSkeletonPr
<div className={cn('space-y-6', className)}>
<Card>
<CardHeader>
<div className="h-6 w-1/3 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-4 w-2/3 mt-2 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-6 w-1/3 rounded bg-muted animate-pulse" />
<div className="h-4 w-2/3 mt-2 rounded bg-muted animate-pulse" />
</CardHeader>
<CardContent className="space-y-4">
<div className="h-10 w-full rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-10 w-full rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-10 w-24 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-10 w-full rounded bg-muted animate-pulse" />
<div className="h-10 w-full rounded bg-muted animate-pulse" />
<div className="h-10 w-24 rounded bg-muted animate-pulse" />
</CardContent>
</Card>
<Card>
<CardHeader>
<div className="h-6 w-1/4 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-4 w-1/2 mt-2 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-6 w-1/4 rounded bg-muted animate-pulse" />
<div className="h-4 w-1/2 mt-2 rounded bg-muted animate-pulse" />
</CardHeader>
<CardContent>
<div className="h-10 w-32 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-10 w-32 rounded bg-muted animate-pulse" />
</CardContent>
</Card>
<Card>
<CardHeader>
<div className="h-6 w-1/4 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-4 w-2/3 mt-2 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-6 w-1/4 rounded bg-muted animate-pulse" />
<div className="h-4 w-2/3 mt-2 rounded bg-muted animate-pulse" />
</CardHeader>
<CardContent>
<div className="h-10 w-36 rounded bg-kodo-slate/30 dark:bg-kodo-slate/20 animate-pulse" />
<div className="h-10 w-36 rounded bg-muted animate-pulse" />
</CardContent>
</Card>
</div>