From d97a98b686f59767cdc8fb4bb2c432491ddab0e0 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 22 Feb 2026 18:06:39 -0600 Subject: [PATCH] fix(web,ui): visual polish aligned to design reference (#457) - Add responsive CSS classes for dashboard grid and metrics strip (3-col tablet, 2-col mobile, single-col stacking) - Fix QuickActions layout from vertical to horizontal per design ref - Replace non-existent var(--r-md) token with var(--r) in OrchestratorSessions and QuickActions - Fix NavItem borderRadius to var(--r-sm) matching reference - Fix ActivityFeed spacing (gap 12px, padding 10px per reference) - Refactor MetricsStrip to CSS class-based responsive grid Task: MS-P1-003 Co-Authored-By: Claude Opus 4.6 --- apps/web/src/app/(authenticated)/page.tsx | 8 +-- apps/web/src/app/globals.css | 56 +++++++++++++++++++ .../src/components/dashboard/ActivityFeed.tsx | 4 +- .../dashboard/OrchestratorSessions.tsx | 2 +- .../src/components/dashboard/QuickActions.tsx | 33 +++++------ apps/web/src/components/layout/AppSidebar.tsx | 2 +- packages/ui/src/components/MetricsStrip.tsx | 22 ++++---- 7 files changed, 84 insertions(+), 43 deletions(-) diff --git a/apps/web/src/app/(authenticated)/page.tsx b/apps/web/src/app/(authenticated)/page.tsx index 85ace31..bf09ec1 100644 --- a/apps/web/src/app/(authenticated)/page.tsx +++ b/apps/web/src/app/(authenticated)/page.tsx @@ -11,13 +11,7 @@ export default function DashboardPage(): ReactElement { return (
-
+
diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index f19b900..090d5d2 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -765,6 +765,62 @@ body::before { animation: scaleIn 0.1s ease-out; } +/* ----------------------------------------------------------------------------- + Dashboard Layout — Responsive Grids + ----------------------------------------------------------------------------- */ +.metrics-strip { + display: grid; + grid-template-columns: repeat(var(--ms-cols, 6), 1fr); + gap: 0; + border-radius: var(--r-lg); + overflow: hidden; + border: 1px solid var(--border); +} + +.metric-cell { + border-left: 1px solid var(--border); +} + +.metric-cell:first-child { + border-left: none; +} + +@media (max-width: 900px) { + .metrics-strip { + grid-template-columns: repeat(3, 1fr); + } + + .metric-cell:nth-child(3n + 1) { + border-left: none; + } +} + +@media (max-width: 640px) { + .metrics-strip { + grid-template-columns: repeat(2, 1fr); + } + + .metric-cell:nth-child(3n + 1) { + border-left: 1px solid var(--border); + } + + .metric-cell:nth-child(2n + 1) { + border-left: none; + } +} + +.dash-grid { + display: grid; + grid-template-columns: 1fr 320px; + gap: 16px; +} + +@media (max-width: 900px) { + .dash-grid { + grid-template-columns: 1fr; + } +} + /* ----------------------------------------------------------------------------- Responsive Typography Adjustments ----------------------------------------------------------------------------- */ diff --git a/apps/web/src/components/dashboard/ActivityFeed.tsx b/apps/web/src/components/dashboard/ActivityFeed.tsx index 97389cb..3a623bf 100644 --- a/apps/web/src/components/dashboard/ActivityFeed.tsx +++ b/apps/web/src/components/dashboard/ActivityFeed.tsx @@ -102,8 +102,8 @@ function ActivityItemRow({ item }: ActivityItemRowProps): ReactElement { style={{ display: "flex", alignItems: "flex-start", - gap: 10, - padding: "8px 0", + gap: 12, + padding: "10px 0", borderBottom: "1px solid var(--border)", }} > diff --git a/apps/web/src/components/dashboard/OrchestratorSessions.tsx b/apps/web/src/components/dashboard/OrchestratorSessions.tsx index d496470..c9e9732 100644 --- a/apps/web/src/components/dashboard/OrchestratorSessions.tsx +++ b/apps/web/src/components/dashboard/OrchestratorSessions.tsx @@ -169,7 +169,7 @@ function OrchCard({ session }: OrchCardProps): ReactElement { style={{ background: "var(--bg-mid)", border: "1px solid var(--border)", - borderRadius: "var(--r-md)", + borderRadius: "var(--r)", padding: "12px 14px", marginBottom: 10, }} diff --git a/apps/web/src/components/dashboard/QuickActions.tsx b/apps/web/src/components/dashboard/QuickActions.tsx index 0bf4f08..e688e9a 100644 --- a/apps/web/src/components/dashboard/QuickActions.tsx +++ b/apps/web/src/components/dashboard/QuickActions.tsx @@ -12,10 +12,10 @@ interface QuickAction { } const actions: QuickAction[] = [ - { id: "new-project", label: "New Project", icon: "🚀", iconBg: "rgba(47,128,255,0.15)" }, - { id: "spawn-agent", label: "Spawn Agent", icon: "🤖", iconBg: "rgba(139,92,246,0.15)" }, - { id: "view-telemetry", label: "View Telemetry", icon: "📊", iconBg: "rgba(20,184,166,0.15)" }, - { id: "review-tasks", label: "Review Tasks", icon: "📋", iconBg: "rgba(245,158,11,0.15)" }, + { id: "new-project", label: "New Project", icon: "🚀", iconBg: "rgba(47,128,255,0.12)" }, + { id: "spawn-agent", label: "Spawn Agent", icon: "🤖", iconBg: "rgba(139,92,246,0.12)" }, + { id: "view-telemetry", label: "View Telemetry", icon: "📊", iconBg: "rgba(20,184,166,0.12)" }, + { id: "review-tasks", label: "Review Tasks", icon: "📋", iconBg: "rgba(245,158,11,0.12)" }, ]; interface ActionButtonProps { @@ -36,24 +36,25 @@ function ActionButton({ action }: ActionButtonProps): ReactElement { }} style={{ display: "flex", - flexDirection: "column", alignItems: "center", - justifyContent: "center", gap: 8, - padding: "16px 12px", - borderRadius: "var(--r-md)", + padding: "10px 12px", + borderRadius: "var(--r)", border: `1px solid ${hovered ? "var(--ms-border-700)" : "var(--border)"}`, background: hovered ? "var(--surface)" : "var(--bg-mid)", cursor: "pointer", - transition: "border-color 0.15s, background 0.15s", + transition: "border-color 0.15s, background 0.15s, color 0.15s", width: "100%", + fontSize: "0.8rem", + fontWeight: 600, + color: hovered ? "var(--text)" : "var(--text-2)", }} >
{action.icon}
- - {action.label} - + {action.label} ); } @@ -84,7 +77,7 @@ export function QuickActions(): ReactElement { style={{ display: "grid", gridTemplateColumns: "1fr 1fr", - gap: 10, + gap: 8, }} > {actions.map((action) => ( diff --git a/apps/web/src/components/layout/AppSidebar.tsx b/apps/web/src/components/layout/AppSidebar.tsx index eca49de..67ea1ec 100644 --- a/apps/web/src/components/layout/AppSidebar.tsx +++ b/apps/web/src/components/layout/AppSidebar.tsx @@ -356,7 +356,7 @@ function NavItem({ item, isActive, collapsed }: NavItemProps): React.JSX.Element alignItems: "center", gap: "11px", padding: "9px 10px", - borderRadius: "6px", + borderRadius: "var(--r-sm)", fontSize: "0.875rem", fontWeight: 500, color: isActive ? "var(--text)" : "var(--muted)", diff --git a/packages/ui/src/components/MetricsStrip.tsx b/packages/ui/src/components/MetricsStrip.tsx index 5cd84b0..081277c 100644 --- a/packages/ui/src/components/MetricsStrip.tsx +++ b/packages/ui/src/components/MetricsStrip.tsx @@ -16,7 +16,7 @@ export interface MetricsStripProps { className?: string; } -function MetricCellItem({ cell, isFirst }: { cell: MetricCell; isFirst: boolean }): ReactElement { +function MetricCellItem({ cell }: { cell: MetricCell }): ReactElement { const [hovered, setHovered] = useState(false); const trendColor = @@ -28,6 +28,7 @@ function MetricCellItem({ cell, isFirst }: { cell: MetricCell; isFirst: boolean return (
{ setHovered(true); }} @@ -37,7 +38,6 @@ function MetricCellItem({ cell, isFirst }: { cell: MetricCell; isFirst: boolean style={{ padding: "14px 16px", background: hovered ? "var(--surface-2)" : "var(--surface)", - borderLeft: isFirst ? "none" : "1px solid var(--border)", borderTop: `2px solid ${cell.color}`, transition: "background 0.15s ease", }} @@ -82,17 +82,15 @@ function MetricCellItem({ cell, isFirst }: { cell: MetricCell; isFirst: boolean export function MetricsStrip({ cells, className = "" }: MetricsStripProps): ReactElement { return (
- {cells.map((cell, index) => ( - + {cells.map((cell) => ( + ))}
);