feat(ui): full frontend redesign to the Sentry-style design system

Replace the legacy UI with the dark, mono-accent design language from
design/23-sentry.html across every non-canvas surface.

- PlatformShell: fixed 252px sidebar with grouped nav (Platform /
  Operate / Workspace), brand mark, user card, and a topbar with
  search (Cmd+K palette), env badge, upgrade, notifications, and
  theme toggle; mobile collapses to a top bar with horizontal nav
- New shared component kit in shared/components/sentry.tsx:
  SPageHead, SStat, SCard, STable, SSection, SPill, Ticks, Seg,
  GhostBtn/QuietBtn/IconBtn, status tone helpers
- New DashboardPage at / — stats row, per-node CPU chart with
  1h/24h/7d ranges, resource usage tick strips, anomaly box,
  node summary table, recent deployments and project cards;
  real API data with demo-mode fixtures
- Landing page moved to /landing and rebuilt: live host telemetry
  window, install strip, feature grid, template catalog, docs
- Every page (Projects, Templates, Builds, Databases, HA,
  Operations, Activity, Security, Usage, Docs, People, Settings,
  Audit Logs, Webhooks, Admin, NodeDetail, ServiceDetail, auth,
  setup, not-found) migrated to the new kit and tokens
- Nav active state resolves by longest matching href
- Canvas internals intentionally untouched — separate pass

Verified: tsc --noEmit, eslint, vite build, Playwright walkthrough
of every route at desktop and mobile widths (demo + live session).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-10-10 16:42:26 +02:00
1 parent a05d225016
commit 24b9b1267e
42 files changed
+4077 -3018

No files matched your search

@@ -134,6 +134,17 @@ function CommandPaletteContent({
onClose();
},
},
{
id: 'goto-dashboard',
label: 'Go to Dashboard',
icon: LayoutGrid,
shortcut: 'H',
category: 'Navigate',
action: () => {
onNavigate?.('dashboard');
onClose();
},
},
{
id: 'goto-canvas',
label: 'Go to Canvas',
@@ -205,7 +216,7 @@ function CommandPaletteContent({
/>
<div className="absolute left-1/2 top-[20%] -translate-x-1/2 w-full max-w-xl">
<Command
className="panel overflow-hidden"
className="s-card !p-0 overflow-hidden shadow-2xl shadow-black/50"
loop
>
<div className="flex items-center gap-3 px-4 py-3 border-b border-[var(--border-subtle)]">
@@ -228,7 +239,7 @@ function CommandPaletteContent({
{Object.entries(groupedCommands).map(([category, items]) => (
<Command.Group key={category} heading={category} className="mb-2">
<div className="px-2 py-1.5 text-[10px] font-semibold uppercase tracking-widest text-[var(--text-muted)]">
<div className="px-2 py-1.5 v-mono text-[10px] uppercase tracking-[0.14em] text-[var(--text-muted)]">
{category}
</div>
{items.map((item) => {
@@ -238,9 +249,9 @@ function CommandPaletteContent({
key={item.id}
value={item.label}
onSelect={item.action}
className="flex items-center gap-3 px-3 py-2.5 rounded-[var(--radius-md)] cursor-pointer text-[var(--text-secondary)] hover:bg-[var(--surface-muted)] hover:text-[var(--text-primary)] aria-selected:bg-[var(--accent-primary-soft)] aria-selected:text-[var(--accent-primary)] transition-colors"
className="flex items-center gap-3 px-3 py-2 rounded-[var(--radius-md)] cursor-pointer text-[var(--text-secondary)] hover:bg-[var(--surface-muted)] hover:text-[var(--text-primary)] aria-selected:bg-[var(--accent-primary-soft)] aria-selected:text-[var(--accent-primary)] transition-colors"
>
<Icon size={18} className="text-[var(--text-muted)]" />
<span className="s-ibox !h-7 !w-7"><Icon /></span>
<div className="flex-1">
<div className="text-sm font-medium">{item.label}</div>
{item.description && (