Comprehensive UX polish: fix 19 friction points across all pages
CI / build-and-push (push) Successful in 33s

Addresses broken interactions (notification bell, browser dialogs),
missing feedback states (disabled buttons, pricing changes, paused
indicator), unclear affordances (research queue, model tuning, funding
requirements), and navigation gaps (hash routing, keyboard shortcuts,
clickable dashboard cards, sidebar grouping, tutorial hints).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-24 21:44:18 -04:00
parent d25dfe0435
commit f9f6233b69
19 changed files with 540 additions and 121 deletions
+10 -2
View File
@@ -53,6 +53,7 @@ export function DashboardPage() {
subValue={`${netIncome >= 0 ? '+' : ''}${formatMoney(netIncome)}/s`}
trend={netIncome > 0 ? 'up' : netIncome < 0 ? 'down' : 'neutral'}
color="text-green-400"
onClick={() => useGameStore.getState().setActivePage('finance')}
/>
<StatCard
icon={Server}
@@ -60,6 +61,7 @@ export function DashboardPage() {
value={dataCenters.length.toString()}
subValue={`${formatNumber(totalFlops)} FLOPS`}
color="text-blue-400"
onClick={() => useGameStore.getState().setActivePage('infrastructure')}
/>
<StatCard
icon={Brain}
@@ -67,6 +69,7 @@ export function DashboardPage() {
value={trainedModels.length.toString()}
subValue={activeTraining ? `Training: ${Math.floor((activeTraining.progressTicks / activeTraining.totalTicks) * 100)}%` : 'Idle'}
color="text-purple-400"
onClick={() => useGameStore.getState().setActivePage('models')}
/>
<StatCard
icon={Users}
@@ -74,6 +77,7 @@ export function DashboardPage() {
value={formatNumber(subscribers)}
subValue={`Satisfaction: ${formatPercent(useGameStore.getState().market.consumers.satisfaction)}`}
color="text-orange-400"
onClick={() => useGameStore.getState().setActivePage('market')}
/>
</div>
@@ -209,7 +213,7 @@ export function DashboardPage() {
}
function StatCard({
icon: Icon, label, value, subValue, trend, color,
icon: Icon, label, value, subValue, trend, color, onClick,
}: {
icon: typeof DollarSign;
label: string;
@@ -217,9 +221,13 @@ function StatCard({
subValue?: string;
trend?: 'up' | 'down' | 'neutral';
color?: string;
onClick?: () => void;
}) {
return (
<div className="bg-surface-900 border border-surface-700 rounded-xl p-4">
<div
className={`bg-surface-900 border border-surface-700 rounded-xl p-4 ${onClick ? 'cursor-pointer hover:border-accent/30 transition-colors' : ''}`}
onClick={onClick}
>
<div className="flex items-center gap-2 mb-2">
<Icon size={16} className={color ?? 'text-surface-400'} />
<span className="text-xs text-surface-400 uppercase tracking-wider">{label}</span>