diff --git a/frontend/src/features/guilds/components/Leaderboard.tsx b/frontend/src/features/guilds/components/Leaderboard.tsx
new file mode 100644
index 00000000..ff092631
--- /dev/null
+++ b/frontend/src/features/guilds/components/Leaderboard.tsx
@@ -0,0 +1,209 @@
+'use client'
+
+import { useMemo, useState } from 'react'
+import { motion } from 'framer-motion'
+import { ArrowDownUp, Award, Medal, Trophy } from 'lucide-react'
+import { cn } from '@/lib/utils'
+
+type LeaderboardUser = {
+ id: string
+ displayName: string
+ avatarColor: string
+ reputationScore: number
+ totalBountiesCompleted: number
+}
+
+type SortKey = 'reputationScore' | 'totalBountiesCompleted'
+
+const leaderboardUsers: LeaderboardUser[] = [
+ { id: 'user-01', displayName: 'Nova Patel', avatarColor: 'from-amber-400 to-orange-500', reputationScore: 9875, totalBountiesCompleted: 42 },
+ { id: 'user-02', displayName: 'Orion Vega', avatarColor: 'from-slate-300 to-slate-500', reputationScore: 9340, totalBountiesCompleted: 38 },
+ { id: 'user-03', displayName: 'Lyra Chen', avatarColor: 'from-yellow-700 to-orange-900', reputationScore: 8990, totalBountiesCompleted: 35 },
+ { id: 'user-04', displayName: 'Mira Sol', avatarColor: 'from-indigo-500 to-purple-600', reputationScore: 8420, totalBountiesCompleted: 34 },
+ { id: 'user-05', displayName: 'Kai Morgan', avatarColor: 'from-cyan-500 to-blue-600', reputationScore: 8015, totalBountiesCompleted: 31 },
+ { id: 'user-06', displayName: 'Astra Quinn', avatarColor: 'from-pink-500 to-rose-600', reputationScore: 7880, totalBountiesCompleted: 29 },
+ { id: 'user-07', displayName: 'Juno Vale', avatarColor: 'from-emerald-500 to-teal-600', reputationScore: 7425, totalBountiesCompleted: 27 },
+ { id: 'user-08', displayName: 'Riven Atlas', avatarColor: 'from-violet-500 to-fuchsia-600', reputationScore: 7190, totalBountiesCompleted: 25 },
+ { id: 'user-09', displayName: 'Sage Rivera', avatarColor: 'from-blue-500 to-sky-600', reputationScore: 6950, totalBountiesCompleted: 24 },
+ { id: 'user-10', displayName: 'Echo Stone', avatarColor: 'from-lime-500 to-green-600', reputationScore: 6725, totalBountiesCompleted: 22 },
+ { id: 'user-11', displayName: 'Talia Brooks', avatarColor: 'from-red-500 to-pink-600', reputationScore: 6490, totalBountiesCompleted: 21 },
+ { id: 'user-12', displayName: 'Niko Frost', avatarColor: 'from-sky-400 to-cyan-600', reputationScore: 6215, totalBountiesCompleted: 20 },
+ { id: 'user-13', displayName: 'Vesper Moon', avatarColor: 'from-purple-400 to-indigo-700', reputationScore: 6040, totalBountiesCompleted: 19 },
+ { id: 'user-14', displayName: 'Rune Carter', avatarColor: 'from-stone-500 to-zinc-700', reputationScore: 5890, totalBountiesCompleted: 18 },
+ { id: 'user-15', displayName: 'Iris Hale', avatarColor: 'from-teal-400 to-emerald-700', reputationScore: 5710, totalBountiesCompleted: 18 },
+ { id: 'user-16', displayName: 'Cassian Reed', avatarColor: 'from-orange-400 to-red-600', reputationScore: 5565, totalBountiesCompleted: 17 },
+ { id: 'user-17', displayName: 'Zara Knox', avatarColor: 'from-fuchsia-400 to-purple-700', reputationScore: 5390, totalBountiesCompleted: 16 },
+ { id: 'user-18', displayName: 'Atlas Noor', avatarColor: 'from-blue-600 to-indigo-800', reputationScore: 5215, totalBountiesCompleted: 16 },
+ { id: 'user-19', displayName: 'Pax Wilder', avatarColor: 'from-lime-400 to-emerald-600', reputationScore: 5080, totalBountiesCompleted: 15 },
+ { id: 'user-20', displayName: 'Elio Park', avatarColor: 'from-amber-500 to-yellow-700', reputationScore: 4925, totalBountiesCompleted: 15 },
+ { id: 'user-21', displayName: 'Rhea Kim', avatarColor: 'from-rose-400 to-red-700', reputationScore: 4760, totalBountiesCompleted: 14 },
+ { id: 'user-22', displayName: 'Dax Mercer', avatarColor: 'from-cyan-600 to-teal-800', reputationScore: 4635, totalBountiesCompleted: 14 },
+ { id: 'user-23', displayName: 'Mina Fox', avatarColor: 'from-indigo-400 to-blue-700', reputationScore: 4510, totalBountiesCompleted: 13 },
+ { id: 'user-24', displayName: 'Theo Vale', avatarColor: 'from-violet-600 to-purple-800', reputationScore: 4385, totalBountiesCompleted: 13 },
+ { id: 'user-25', displayName: 'Luca Reyes', avatarColor: 'from-green-400 to-lime-700', reputationScore: 4260, totalBountiesCompleted: 12 },
+ { id: 'user-26', displayName: 'Nyx Arden', avatarColor: 'from-slate-500 to-slate-800', reputationScore: 4115, totalBountiesCompleted: 12 },
+ { id: 'user-27', displayName: 'Aria Wells', avatarColor: 'from-pink-400 to-fuchsia-700', reputationScore: 3980, totalBountiesCompleted: 11 },
+ { id: 'user-28', displayName: 'Kian Cross', avatarColor: 'from-yellow-500 to-amber-800', reputationScore: 3845, totalBountiesCompleted: 11 },
+ { id: 'user-29', displayName: 'Nia Blake', avatarColor: 'from-sky-500 to-blue-800', reputationScore: 3720, totalBountiesCompleted: 10 },
+ { id: 'user-30', displayName: 'Milo Hart', avatarColor: 'from-emerald-400 to-teal-700', reputationScore: 3595, totalBountiesCompleted: 10 },
+ { id: 'user-31', displayName: 'Sora Finch', avatarColor: 'from-purple-500 to-pink-700', reputationScore: 3470, totalBountiesCompleted: 9 },
+ { id: 'user-32', displayName: 'Leah Storm', avatarColor: 'from-red-400 to-orange-700', reputationScore: 3355, totalBountiesCompleted: 9 },
+ { id: 'user-33', displayName: 'Owen Ash', avatarColor: 'from-zinc-500 to-stone-800', reputationScore: 3240, totalBountiesCompleted: 8 },
+ { id: 'user-34', displayName: 'Vera Holt', avatarColor: 'from-blue-400 to-cyan-700', reputationScore: 3125, totalBountiesCompleted: 8 },
+ { id: 'user-35', displayName: 'Remy Cole', avatarColor: 'from-lime-500 to-green-800', reputationScore: 3010, totalBountiesCompleted: 8 },
+ { id: 'user-36', displayName: 'Ayla West', avatarColor: 'from-rose-500 to-pink-800', reputationScore: 2895, totalBountiesCompleted: 7 },
+ { id: 'user-37', displayName: 'Idris Lane', avatarColor: 'from-indigo-500 to-violet-800', reputationScore: 2780, totalBountiesCompleted: 7 },
+ { id: 'user-38', displayName: 'Lena Quinn', avatarColor: 'from-teal-500 to-cyan-800', reputationScore: 2665, totalBountiesCompleted: 7 },
+ { id: 'user-39', displayName: 'Cleo North', avatarColor: 'from-orange-500 to-amber-800', reputationScore: 2550, totalBountiesCompleted: 6 },
+ { id: 'user-40', displayName: 'Bryn Ellis', avatarColor: 'from-fuchsia-500 to-rose-800', reputationScore: 2435, totalBountiesCompleted: 6 },
+ { id: 'user-41', displayName: 'Ezra Pike', avatarColor: 'from-sky-600 to-indigo-800', reputationScore: 2320, totalBountiesCompleted: 6 },
+ { id: 'user-42', displayName: 'Tess Vale', avatarColor: 'from-green-500 to-emerald-800', reputationScore: 2205, totalBountiesCompleted: 5 },
+ { id: 'user-43', displayName: 'Finn Ro', avatarColor: 'from-yellow-600 to-orange-800', reputationScore: 2090, totalBountiesCompleted: 5 },
+ { id: 'user-44', displayName: 'Mae Orion', avatarColor: 'from-purple-600 to-indigo-900', reputationScore: 1975, totalBountiesCompleted: 5 },
+ { id: 'user-45', displayName: 'Hugo Ray', avatarColor: 'from-red-600 to-rose-900', reputationScore: 1860, totalBountiesCompleted: 4 },
+ { id: 'user-46', displayName: 'Gia Star', avatarColor: 'from-cyan-500 to-blue-900', reputationScore: 1745, totalBountiesCompleted: 4 },
+ { id: 'user-47', displayName: 'Noah Drift', avatarColor: 'from-stone-400 to-slate-700', reputationScore: 1630, totalBountiesCompleted: 4 },
+ { id: 'user-48', displayName: 'Skye Moss', avatarColor: 'from-lime-400 to-teal-700', reputationScore: 1515, totalBountiesCompleted: 3 },
+ { id: 'user-49', displayName: 'Rosa Beam', avatarColor: 'from-pink-500 to-purple-800', reputationScore: 1400, totalBountiesCompleted: 3 },
+ { id: 'user-50', displayName: 'Jett Rowan', avatarColor: 'from-slate-600 to-indigo-900', reputationScore: 1285, totalBountiesCompleted: 3 },
+]
+
+const podiumStyles = [
+ {
+ label: 'Gold',
+ icon: Trophy,
+ className: 'border-amber-400/60 bg-amber-500/10 shadow-[0_0_24px_rgba(251,191,36,0.18)]',
+ badgeClassName: 'bg-amber-400 text-slate-950',
+ },
+ {
+ label: 'Silver',
+ icon: Medal,
+ className: 'border-slate-300/60 bg-slate-300/10 shadow-[0_0_24px_rgba(203,213,225,0.14)]',
+ badgeClassName: 'bg-slate-300 text-slate-950',
+ },
+ {
+ label: 'Bronze',
+ icon: Award,
+ className: 'border-orange-700/70 bg-orange-700/10 shadow-[0_0_24px_rgba(194,65,12,0.16)]',
+ badgeClassName: 'bg-orange-700 text-white',
+ },
+]
+
+const sortOptions: { key: SortKey; label: string }[] = [
+ { key: 'reputationScore', label: 'Reputation Score' },
+ { key: 'totalBountiesCompleted', label: 'Total Bounties Completed' },
+]
+
+const formatNumber = new Intl.NumberFormat('en-US').format
+
+export function Leaderboard() {
+ const [sortKey, setSortKey] = useState
('reputationScore')
+
+ const sortedUsers = useMemo(() => {
+ return [...leaderboardUsers]
+ .sort((a, b) => {
+ const primary = b[sortKey] - a[sortKey]
+ return primary !== 0 ? primary : b.reputationScore - a.reputationScore
+ })
+ .map((user, index) => ({ ...user, rank: index + 1 }))
+ }, [sortKey])
+
+ const visibleUsers = sortedUsers.slice(0, 10)
+
+ return (
+
+
+
+
+ Monthly reputation
+
+
+ Guild Leaderboard
+
+
+ Top contributors ranked from a 50-user mocked dataset. The top three receive distinct podium styling while ranks 4-10 use compact rows.
+
+
+
+
+ {sortOptions.map((option) => (
+
+ ))}
+
+
+
+
+ {visibleUsers.map((user) => {
+ const podiumStyle = podiumStyles[user.rank - 1]
+ const PodiumIcon = podiumStyle?.icon
+
+ return (
+
+
+ #{user.rank}
+
+
+
+ {user.displayName.split(' ').map((name) => name[0]).join('')}
+
+
+
+
+
+ {user.displayName}
+
+ {PodiumIcon && (
+
+
+ {podiumStyle.label}
+
+ )}
+
+
+ {formatNumber(user.reputationScore)} reputation points
+
+
+
+
+
+ {formatNumber(user.totalBountiesCompleted)}
+
+
+ Bounties
+
+
+
+ )
+ })}
+
+
+ )
+}