From fa01a02a6df35de7969f1ce80925f44c6a1c3a3d Mon Sep 17 00:00:00 2001
From: Michael Han <107991372+shimmyshimmer@users.noreply.github.com>
Date: Wed, 10 Jun 2026 07:28:28 -0700
Subject: [PATCH] Studio UI polish: search dialog shadow, model picker pills,
sidebar spacing, white Hub background (#6147)
* Studio UI polish: search dialog shadow, picker pills, sidebar spacing, white Hub
- Chat search dialog: keep a page-bg shadow in dark mode so the dialog
does not merge into same-color content behind it
- Model selector: hover and selected rows are fully rounded pills
- Sidebar: nudge nav items, recents and section labels 2px right and
widen the hover pill 2px left so its side gaps match
- Hub: pure white page background in light mode and drop the ambient
card glow that tinted the page gray
* Lighten sidebar border, widen model picker rows
- Sidebar border is #f2f2f2 in light mode
- Model picker rows extend 4px further left and right, lining up with
the search bar
* Plus menu: restore the intended 18px corner radius
The global 14px !important dropdown radius overrode the menu's own
18px, so the plus menu and its submenus rendered squarer than designed.
Mark the menu radius !important so it wins.
* Projects: borderless import/export button; picker search border #f2f2f2
- The import/export button on the Projects page drops its outline
border and matches the Sort by pill next to it
- The model picker search inputs use a #f2f2f2 border in light mode,
dark mode keeps the default
* Model selector: align the popup with the trigger label
The popover lined up with the trigger button edge, 14px left of the
label text. A 10px alignOffset starts it just before the label.
* Model picker: shorten search placeholder to Search models
* Pill-shaped model trigger and panel controls; chat template edit button
- Select model trigger: rounded pill with slightly tighter horizontal
padding
- KV cache, speculative decoding, draft N and preset controls in the
chat settings panel are rounded pills
- Chat Template: replace the three-line preview box with an edit icon
button next to the label; it opens the existing editor dialog
* Training overlay: borderless console, sloth attached to the box
- Drop the terminal border for the training start console
- Remove the gap between the sloth image and the console so they touch
* Settings panel: more left padding in pill controls, smaller template edit icon
- f16, Auto and draft N pills get 12px left padding, widths bumped 4px
to keep the values from truncating
- Chat template edit icon shrinks to 14px and the Chat Template label
also opens the editor
* Model picker: more padding inside row pills, hugeicons delete icon
- Row pills get 12px horizontal padding so text is not pressed against
the highlight boundary
- The cached model delete button uses the hugeicons Delete02 icon
instead of the lucide trash icon
* Address review: hub bg layering, dead shadow utilities, merged paddings
- Remove bg-background from the Hub root: the white rule lives in the
base layer and the utility was winning the cascade, so the white
background never applied
- Drop the inline shadow utilities on the chat search dialog: the
chat-search-surface rules sit later in the utilities layer and
already win, making the inline ones dead
- Merge symmetric pl/pr pairs into px on the sidebar group wrappers
---
.../frontend/src/components/app-sidebar.tsx | 6 +--
.../assistant-ui/model-selector.tsx | 13 ++---
.../model-selector/model-delete-action.tsx | 9 +++-
.../assistant-ui/model-selector/pickers.tsx | 14 ++---
.../src/features/chat/chat-settings-sheet.tsx | 54 ++++++++++++-------
.../chat/components/chat-search-dialog.tsx | 2 +-
.../src/features/chat/projects-page.tsx | 7 ++-
studio/frontend/src/features/hub/hub-page.tsx | 2 +-
studio/frontend/src/features/hub/hub.css | 7 ++-
.../studio/training-start-overlay.tsx | 4 +-
studio/frontend/src/index.css | 19 ++++---
11 files changed, 84 insertions(+), 53 deletions(-)
diff --git a/studio/frontend/src/components/app-sidebar.tsx b/studio/frontend/src/components/app-sidebar.tsx
index 14131c3c1c..575fd20a06 100644
--- a/studio/frontend/src/components/app-sidebar.tsx
+++ b/studio/frontend/src/components/app-sidebar.tsx
@@ -217,7 +217,7 @@ function NavItem({
onClick={onClick}
isActive={active}
data-tour={dataTour}
- className="sidebar-nav-btn h-[33px] rounded-full gap-[8.5px] px-2.5 font-medium group-data-[collapsible=icon]:!w-[32px] group-data-[collapsible=icon]:!rounded-full group-data-[collapsible=icon]:mx-auto"
+ className="sidebar-nav-btn h-[33px] rounded-full gap-[8.5px] pl-3 pr-2.5 font-medium group-data-[collapsible=icon]:px-2.5 group-data-[collapsible=icon]:!w-[32px] group-data-[collapsible=icon]:!rounded-full group-data-[collapsible=icon]:mx-auto"
>
{label}
@@ -558,7 +558,7 @@ export function AppSidebar() {
: "sidebar-row-action group-hover/recent-item:opacity-100 group-hover/recent-item:pointer-events-auto focus-visible:opacity-100 focus-visible:pointer-events-auto";
const buttonClass = cn(
"sidebar-nav-btn h-[33px] cursor-pointer rounded-full pr-4 text-[14.5px] leading-[19px] tracking-nav font-medium",
- variant === "project" ? "pl-[37px]" : "pl-2.5",
+ variant === "project" ? "pl-[39px]" : "pl-3",
variant === "project"
? "group-hover/project-chat-item:pr-8 group-has-[.sidebar-row-action[data-state=open]]/project-chat-item:pr-8"
: "group-hover/recent-item:pr-8 group-has-[.sidebar-row-action[data-state=open]]/recent-item:pr-8",
@@ -966,7 +966,7 @@ export function AppSidebar() {
>
{
setSelectedHistoryRunId(run.id);
closeMobileIfOpen();
diff --git a/studio/frontend/src/components/assistant-ui/model-selector.tsx b/studio/frontend/src/components/assistant-ui/model-selector.tsx
index f8a3ce4e20..b8d1bc0f00 100644
--- a/studio/frontend/src/components/assistant-ui/model-selector.tsx
+++ b/studio/frontend/src/components/assistant-ui/model-selector.tsx
@@ -148,12 +148,12 @@ function ModelSelectorTrigger({
className={cn(
"unsloth-model-selector-trigger flex min-w-0 items-center gap-2 transition-colors",
variant === "outline" &&
- "rounded-[10px] border border-border/60 hover:bg-[#ececec] dark:hover:bg-[#2d2e32]",
- variant === "ghost" && "rounded-[10px] hover:bg-[#ececec] dark:hover:bg-[#2d2e32]",
- variant === "muted" && "rounded-[10px] bg-muted hover:bg-muted/80",
- size === "sm" && "h-8 px-3 text-xs",
- size === "default" && "h-9 px-3.5 text-sm",
- size === "lg" && "h-10 px-4 text-sm",
+ "rounded-full border border-border/60 hover:bg-[#ececec] dark:hover:bg-[#2d2e32]",
+ variant === "ghost" && "rounded-full hover:bg-[#ececec] dark:hover:bg-[#2d2e32]",
+ variant === "muted" && "rounded-full bg-muted hover:bg-muted/80",
+ size === "sm" && "h-8 px-2.5 text-xs",
+ size === "default" && "h-9 px-3 text-sm",
+ size === "lg" && "h-10 px-3.5 text-sm",
className,
)}
>
@@ -244,6 +244,7 @@ function ModelSelectorContent({
return (
-
+
@@ -386,7 +386,7 @@ function GgufVariantExpander({
handleVariantClick(v.quant, v.downloaded, v.size_bytes)
}
className={cn(
- "flex min-w-0 flex-1 items-center justify-between gap-2 rounded-[8px] px-2.5 py-1 text-left text-sm transition-colors hover:bg-[#ececec] dark:hover:bg-[#3a3d44]",
+ "flex min-w-0 flex-1 items-center justify-between gap-2 rounded-full px-3 py-1 text-left text-sm transition-colors hover:bg-[#ececec] dark:hover:bg-[#3a3d44]",
)}
>
@@ -887,8 +887,8 @@ export function HubModelPicker({
setQuery(event.target.value)}
- placeholder="Search Hugging Face models"
- className="h-9 pl-8 pr-8"
+ placeholder="Search models"
+ className="h-9 border-[#f2f2f2] dark:border-input pl-8 pr-8"
/>
{isLoading && (
@@ -896,7 +896,7 @@ export function HubModelPicker({