diff --git a/src/components/admin/round/ranking-dashboard.tsx b/src/components/admin/round/ranking-dashboard.tsx
index 4b29132..3f63ec9 100644
--- a/src/components/admin/round/ranking-dashboard.tsx
+++ b/src/components/admin/round/ranking-dashboard.tsx
@@ -1136,6 +1136,28 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran
)}
Score: {a.evaluation?.globalScore?.toFixed(1) ?? '—'}
+ {useBalanced && (() => {
+ const userId = a.user?.id
+ const score = a.evaluation?.globalScore
+ if (!userId || score == null) return null
+ const stats = evalScores?.jurorStats?.[userId]
+ const overallMean = evalScores?.overallMean
+ const overallStddev = evalScores?.overallStddev
+ if (!stats || overallMean == null || overallStddev == null || overallStddev === 0) return null
+ const z = stats.stddev > 0
+ ? (score - stats.mean) / stats.stddev
+ : (score - overallMean) / overallStddev
+ const contributesAs = overallMean + z * overallStddev
+ return (
+ e.stopPropagation()}
+ >
+ typical {stats.mean.toFixed(2)} → contributes {contributesAs.toFixed(2)}
+
+ )
+ })()}
{isExpanded && a.evaluation?.feedbackText && (
diff --git a/src/server/routers/ranking.ts b/src/server/routers/ranking.ts
index 2e1e5dd..5757c9a 100644
--- a/src/server/routers/ranking.ts
+++ b/src/server/routers/ranking.ts
@@ -537,6 +537,19 @@ export const rankingRouter = router({
}
}
- return { byProject, balanced }
+ // Per-juror grading stats so the side panel can render each juror's
+ // personal baseline and rescaled contribution.
+ const jurorStats: Record = {}
+ for (const [userId, s] of balanceCtx.jurorStats.entries()) {
+ jurorStats[userId] = { mean: s.mean, stddev: s.stddev, count: s.count }
+ }
+
+ return {
+ byProject,
+ balanced,
+ jurorStats,
+ overallMean: balanceCtx.overallMean,
+ overallStddev: balanceCtx.overallStddev,
+ }
}),
})