From 1abf0c6cbf3c508e520384a4e3ae1c570a251b64 Mon Sep 17 00:00:00 2001 From: Austin Pickett Date: Mon, 29 Jun 2026 09:09:50 -0400 Subject: [PATCH] fix(web): polish dashboard sidebar chrome and model card menus Use momentum easing for sidebar transitions, switch sidebar typography to sans-serif, replace the profile native select with the DS Select, and stop clipping the Models page Use-as dropdown inside model cards. Co-authored-by: Cursor --- web/src/App.tsx | 16 +++--- web/src/components/LanguageSwitcher.tsx | 3 +- web/src/components/ProfileSwitcher.tsx | 60 +++++++++++++++-------- web/src/components/SidebarFooter.tsx | 2 +- web/src/components/SidebarStatusStrip.tsx | 2 +- web/src/components/ThemeSwitcher.tsx | 4 -- web/src/pages/ModelsPage.tsx | 4 +- 7 files changed, 52 insertions(+), 39 deletions(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index 9a599f66eb0..d68eca1c93b 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -544,13 +544,13 @@ export default function App() { id="app-sidebar" aria-label={t.app.navigation} className={cn( - "fixed top-0 left-0 z-50 flex h-dvh max-h-dvh w-64 min-h-0 flex-col", + "fixed top-0 left-0 z-50 flex h-dvh max-h-dvh w-64 min-h-0 flex-col font-sans", "border-r border-current/20", "bg-background-base", - "transition-[transform] duration-200 ease-out", + "transition-[transform] duration-200 ease-[cubic-bezier(0.23,1,0.32,1)]", mobileOpen ? "translate-x-0" : "-translate-x-full", "lg:sticky lg:top-0 lg:translate-x-0 lg:shrink-0 lg:overflow-hidden", - "lg:transition-[width] lg:duration-[600ms] lg:ease-[cubic-bezier(0.33,1.35,0.62,1)]", + "lg:transition-[width] lg:duration-300 lg:ease-[cubic-bezier(0.23,1,0.32,1)]", collapsed && "lg:w-14", )} style={{ @@ -636,7 +636,7 @@ export default function App() { @@ -1009,7 +1009,7 @@ function SystemActionButton({ className={cn( "group/action relative flex w-full items-center gap-3", "px-5 py-2.5", - "font-mondwest text-display text-xs tracking-[0.1em]", + "font-sans text-display text-xs tracking-[0.1em]", "whitespace-nowrap transition-colors cursor-pointer", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-midground", busy @@ -1183,7 +1183,7 @@ function SidebarTooltip({ anchor, label, warmRef }: SidebarTooltipProps) { "fixed z-[100] pointer-events-none", "px-2 py-1", "bg-background-base border border-current/20 shadow-lg", - "font-mondwest text-display text-xs tracking-[0.1em] text-midground uppercase", + "font-sans text-display text-xs tracking-[0.1em] text-midground uppercase", )} style={{ top: rect.top + rect.height / 2, diff --git a/web/src/components/LanguageSwitcher.tsx b/web/src/components/LanguageSwitcher.tsx index fa3e99949c6..2d6c7201369 100644 --- a/web/src/components/LanguageSwitcher.tsx +++ b/web/src/components/LanguageSwitcher.tsx @@ -78,7 +78,6 @@ export function LanguageSwitcher({ collapsed = false, dropUp = false }: Language > {locale === "en" ? "EN" : current.name} @@ -151,7 +150,7 @@ function LanguageSwitcherOptions({ aria-selected={selected} className={cn( "w-full text-left px-3 py-1.5 flex items-center gap-2 cursor-pointer", - "font-mondwest text-display text-xs tracking-[0.08em]", + "font-sans text-display text-xs tracking-[0.08em]", "hover:bg-accent hover:text-accent-foreground transition-colors", selected ? "font-semibold text-foreground" : "text-muted-foreground", )} diff --git a/web/src/components/ProfileSwitcher.tsx b/web/src/components/ProfileSwitcher.tsx index 827ea881f6f..206c7299887 100644 --- a/web/src/components/ProfileSwitcher.tsx +++ b/web/src/components/ProfileSwitcher.tsx @@ -1,4 +1,9 @@ +import { useMemo } from "react"; import { Users } from "lucide-react"; +import { + Select, + SelectOption, +} from "@nous-research/ui/ui/components/select"; import { useProfileScope } from "@/contexts/useProfileScope"; import { useI18n } from "@/i18n"; import { cn } from "@/lib/utils"; @@ -10,14 +15,24 @@ import { cn } from "@/lib/utils"; * Keys, Skills, MCP, Models) reads/writes the selected profile via the * fetchJSON ?profile= injection. Hidden when only one profile exists. */ -export function ProfileSwitcher({ collapsed }: { collapsed?: boolean }) { +export function ProfileSwitcher({ collapsed }: ProfileSwitcherProps) { const { profile, currentProfile, profiles, setProfile } = useProfileScope(); const { t } = useI18n(); + const currentDashboardLabel = useMemo( + () => + (t.app.currentProfileOption ?? "this dashboard ({name})").replace( + "{name}", + currentProfile || "default", + ), + [currentProfile, t.app.currentProfileOption], + ); + if (profiles.length < 2) return null; const managed = profile || currentProfile || "default"; const isOther = !!profile && profile !== currentProfile; + const managingLabel = t.app.managingProfile ?? "Managing profile"; return (
- - {collapsed && ( - {managed} - )} + + + {collapsed && {managed}}
); } + +interface ProfileSwitcherProps { + collapsed?: boolean; +} diff --git a/web/src/components/SidebarFooter.tsx b/web/src/components/SidebarFooter.tsx index 4e88c0e573e..310ccad7b22 100644 --- a/web/src/components/SidebarFooter.tsx +++ b/web/src/components/SidebarFooter.tsx @@ -25,7 +25,7 @@ export function SidebarFooter({ status }: SidebarFooterProps) { target="_blank" rel="noopener noreferrer" className={cn( - "font-mondwest text-display text-xs tracking-[0.12em] text-midground", + "font-sans text-display text-xs tracking-[0.12em] text-midground", "transition-opacity hover:opacity-90", "focus-visible:rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-midground/40", )} diff --git a/web/src/components/SidebarStatusStrip.tsx b/web/src/components/SidebarStatusStrip.tsx index 10612ace641..418d8696a7f 100644 --- a/web/src/components/SidebarStatusStrip.tsx +++ b/web/src/components/SidebarStatusStrip.tsx @@ -31,7 +31,7 @@ export function SidebarStatusStrip({ status }: SidebarStatusStripProps) { "focus-visible:ring-inset", )} > -
+

{gatewayStatusLabel}{" "} {gw.label} diff --git a/web/src/components/ThemeSwitcher.tsx b/web/src/components/ThemeSwitcher.tsx index 109acf22536..8823363813c 100644 --- a/web/src/components/ThemeSwitcher.tsx +++ b/web/src/components/ThemeSwitcher.tsx @@ -81,7 +81,6 @@ export function ThemeSwitcher({ collapsed = false, dropUp = false }: ThemeSwitch {!collapsed && ( {label} @@ -134,7 +133,6 @@ export function ThemeSwitcher({ collapsed = false, dropUp = false }: ThemeSwitch >

{sheetTitle} @@ -192,7 +190,6 @@ function ThemeSwitcherOptions({
{th.label} @@ -235,7 +232,6 @@ function FontSection({ fontChoices, fontId, setFont }: FontSectionProps) { {t.theme?.fontTitle ?? "Font"} diff --git a/web/src/pages/ModelsPage.tsx b/web/src/pages/ModelsPage.tsx index 401e22c9122..504c8ddb54e 100644 --- a/web/src/pages/ModelsPage.tsx +++ b/web/src/pages/ModelsPage.tsx @@ -268,7 +268,7 @@ function UseAsMenu({ }, [open]); return ( -
+