polish(ui): founder feedback batch - inset sidebar hairline, calmer dialogs, Discord mark, chat skeleton (#1158)

- Sidebar: the hairline above the user block is inset to the content
  edges instead of running edge-to-edge (concept language).
- User menu: the Discord community link renders the actual Discord mark
  (inlined simple-icons path, CC0) instead of lucide MessagesSquare.
- Dialogs: open/close animation toned down, zoom 98 instead of 95 and
  150ms instead of 200ms.
- Settings modal: switching tabs no longer remounts the intercepted
  route (and replayed the whole open animation on every click). The rail
  now swaps sections via history.replaceState, which Next syncs into
  usePathname(), so the dialog stays mounted and tab switches are
  instant. Verified via Playwright: dialog DOM node survives three tab
  switches, URL tracks the section, Esc still closes back.
- /chat loading: the shared dashboard skeleton stretched edge-to-edge in
  chat's full-bleed wrapper (chat's own layout is what suspends, so a
  chat/loading.tsx cannot catch it). The shared fallback is now route-
  aware and renders a two-pane chat silhouette for /chat.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-24 19:36:45 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 15300aa8e2
commit bb551d1d59
7 changed files with 83 additions and 21 deletions
+17 -13
View File
@@ -876,20 +876,24 @@ export default function DashboardNav({ companyName: _companyName, entityType, pa
{/* Sticky user block (bottom-left): avatar, name, active company.
Opens the upward user menu with the company-switcher flyout,
account links and logout (concept PR 2). */}
<div
className={cn(
'flex-shrink-0 border-t border-border/60',
collapsed ? 'px-2 py-2' : 'px-3 py-2',
)}
>
<UserMenu
userName={userName}
userEmail={userEmail}
isSandbox={isSandbox}
collapsed={collapsed}
onLogout={() => void handleLogout()}
account links and logout (concept PR 2). The hairline above is
inset to the content edges, not edge-to-edge (concept). */}
<div className="flex-shrink-0">
<div
className={cn(
'border-t border-border/60',
collapsed ? 'mx-2' : 'mx-3',
)}
/>
<div className={cn(collapsed ? 'px-2 py-2' : 'px-3 py-2')}>
<UserMenu
userName={userName}
userEmail={userEmail}
isSandbox={isSandbox}
collapsed={collapsed}
onLogout={() => void handleLogout()}
/>
</div>
</div>
</div>
</aside>
+11 -2
View File
@@ -18,7 +18,6 @@ import {
HelpCircle,
Loader2,
LogOut,
MessagesSquare,
Plus,
Search,
Settings,
@@ -30,6 +29,16 @@ import {
// actually asks for that.
const DISCORD_INVITE_URL = 'https://discord.gg/D9SxtTgvx'
// Lucide ships no brand marks, so the Discord logo is inlined (simple-icons
// path, CC0). Sized and colored like the surrounding lucide icons.
function DiscordLogo({ className }: { className?: string }) {
return (
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" className={className}>
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z" />
</svg>
)
}
interface UserMenuProps {
userName: string | null
userEmail: string | null
@@ -333,7 +342,7 @@ export default function UserMenu({
onClick={close}
className={menuRow}
>
<MessagesSquare className="h-4 w-4 flex-shrink-0" />
<DiscordLogo className="h-4 w-4 flex-shrink-0" />
{tNav('discord_community')}
</a>
<SupportLink variant="muted" className={menuRow} />