From e141938a6f81c2128e940a6384ac362f63689603 Mon Sep 17 00:00:00 2001 From: Che <30403707+Che-Zhu@users.noreply.github.com> Date: Mon, 1 Dec 2025 20:35:13 +0800 Subject: [PATCH 1/5] style: Introduce brand color CSS variable and remove unused sidebar theme variables. --- app/globals.css | 56 ++++++++++++++++++++++------------------ components/home-page.tsx | 2 +- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/app/globals.css b/app/globals.css index 4083b72..8eabdc3 100644 --- a/app/globals.css +++ b/app/globals.css @@ -19,6 +19,7 @@ --muted-foreground: oklch(0.55 0.02 264.41); --accent: oklch(0.95 0.03 233.56); --accent-foreground: oklch(0.38 0.14 265.59); + --brand-claude: #d97757; --destructive: oklch(0.64 0.21 25.39); --border: oklch(0.93 0.01 261.82); --input: oklch(0.93 0.01 261.82); @@ -32,12 +33,8 @@ --sidebar-foreground: oklch(0.14 0 0); --sidebar-background: oklch(1.0 0 0); --sidebar-project-background: oklch(1.0 0 0); - --sidebar-primary: oklch(0.20 0 0); - --sidebar-primary-foreground: oklch(0.98 0 0); --sidebar-accent: oklch(0.97 0 0); - --sidebar-accent-foreground: oklch(0.20 0 0); --sidebar-border: oklch(0.92 0 0); - --sidebar-ring: oklch(0.71 0 0); --destructive-foreground: oklch(1.0000 0 0); --content-background: oklch(1.00 0 0); --font-serif: Source Serif 4, serif; @@ -93,12 +90,8 @@ --sidebar-foreground: oklch(0.99 0 0); --sidebar-background: #333333; --sidebar-project-background: #242426; - --sidebar-primary: oklch(0.49 0.24 264.40); - --sidebar-primary-foreground: oklch(0.99 0 0); --sidebar-accent: #2B2D2E; - --sidebar-accent-foreground: oklch(0.99 0 0); --sidebar-border: oklch(1.00 0 0 / 10%); - --sidebar-ring: oklch(0.55 0.02 285.93); --content-background: #1E1E1E; --tabs-background: #252526; --tab-background: #292929; @@ -121,43 +114,57 @@ } .stealth { + /* === Base Colors === */ --background: #1e1e1e; --foreground: #cccccc; + + /* === UI Components === */ --card: #252526; --card-foreground: #cccccc; --popover: #2d2d30; --popover-foreground: #cccccc; + + /* === Brand Colors === */ --primary: #007acc; --primary-foreground: #ffffff; --primary-hover: #0062a3; + --secondary: #2d2d30; --secondary-foreground: #dcdcdc; - --muted: #2d2d30; - --muted-foreground: #858585; + --accent: #264f78; --accent-foreground: #ffffff; + + --muted: #2d2d30; + --muted-foreground: #858585; + --destructive: #7f1d1d; --destructive-foreground: #ffffff; + + /* === Borders & Inputs === */ --border: #3e3e42; --input: #3e3e42; --ring: #007fd4; - --chart-1: #007acc; - --chart-2: #57a64a; - --chart-3: #d69d85; - --chart-4: #569cd6; - --chart-5: #b5cea8; + + /* === Sidebar (VS Code Style) === */ --sidebar: #2d2d30; --sidebar-foreground: #dcdcdc; --sidebar-background: #2d2d30; - --sidebar-project-background: #1e1e1e; - --sidebar-primary: #007acc; - --sidebar-primary-foreground: #ffffff; + --sidebar-project-background: #252526; --sidebar-accent: #264f78; - --sidebar-accent-foreground: #ffffff; --sidebar-border: #1e1e1e; - --sidebar-ring: #007fd4; - --destructive-foreground: #ffffff; + + /* === Charts === */ + --chart-1: #007acc; + --chart-2: #57a64a; + --chart-3: #d69d85; + --chart-4: #569cd6; + --chart-5: #b5cea8; + + /* === Custom/Specific Overrides === */ --content-background: #1e1e1e; + + /* Tabs */ --tabs-background: #2d2d30; --tab-background: #2d2d30; --tab-foreground: #969696; @@ -182,6 +189,7 @@ --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); + --color-brand-claude: var(--brand-claude); --color-destructive: var(--destructive); --color-border: var(--border); --color-input: var(--input); @@ -195,12 +203,10 @@ --color-sidebar-foreground: var(--sidebar-foreground); --color-sidebar-background: var(--sidebar-background); --color-sidebar-project-background: var(--sidebar-project-background); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); + --color-destructive-foreground: var(--destructive-foreground); --color-content-background: var(--content-background); --color-tabs-background: var(--tabs-background); diff --git a/components/home-page.tsx b/components/home-page.tsx index 105ca63..0279c93 100644 --- a/components/home-page.tsx +++ b/components/home-page.tsx @@ -108,7 +108,7 @@ export function HomePage() {

AI-Powered Full-Stack Development Platform

Create, develop, and deploy production-ready web applications using natural language. - Powered by Claude Code in isolated sandbox environments. + Powered by Claude Code in isolated sandbox environments.

From 14d20c58b4e690ad2ec926c844fe8b0dde42cafd Mon Sep 17 00:00:00 2001 From: Che <30403707+Che-Zhu@users.noreply.github.com> Date: Tue, 2 Dec 2025 10:46:07 +0800 Subject: [PATCH 2/5] refactor: Simplify ProjectListHeader and update UI styling with new color variables, rounded elements, and button states. --- app/globals.css | 8 ++-- .../projectList/ProjectCardDropdown.tsx | 2 +- .../projectList/ProjectListHeader.tsx | 47 +++++-------------- components/home-page.tsx | 4 +- components/ui/alert-dialog-vscode.tsx | 6 +-- components/ui/button.tsx | 2 +- components/ui/dropdown-menu.tsx | 8 ++-- 7 files changed, 26 insertions(+), 51 deletions(-) diff --git a/app/globals.css b/app/globals.css index 8eabdc3..1efedca 100644 --- a/app/globals.css +++ b/app/globals.css @@ -132,14 +132,14 @@ --secondary: #2d2d30; --secondary-foreground: #dcdcdc; - --accent: #264f78; + --accent: #2d2d30; --accent-foreground: #ffffff; --muted: #2d2d30; --muted-foreground: #858585; - --destructive: #7f1d1d; - --destructive-foreground: #ffffff; + --destructive: #F14C4C; + --destructive-foreground: #F14C4C; /* === Borders & Inputs === */ --border: #3e3e42; @@ -151,7 +151,7 @@ --sidebar-foreground: #dcdcdc; --sidebar-background: #2d2d30; --sidebar-project-background: #252526; - --sidebar-accent: #264f78; + --sidebar-accent: #2d2d30; --sidebar-border: #1e1e1e; /* === Charts === */ diff --git a/components/features/projectList/ProjectCardDropdown.tsx b/components/features/projectList/ProjectCardDropdown.tsx index 43d5e81..0a5379b 100644 --- a/components/features/projectList/ProjectCardDropdown.tsx +++ b/components/features/projectList/ProjectCardDropdown.tsx @@ -143,7 +143,7 @@ export default function ProjectCardDropdown({ project }: ProjectCardDropdownProp Cancel Delete diff --git a/components/features/projectList/ProjectListHeader.tsx b/components/features/projectList/ProjectListHeader.tsx index 84b99f0..63e7f32 100644 --- a/components/features/projectList/ProjectListHeader.tsx +++ b/components/features/projectList/ProjectListHeader.tsx @@ -6,53 +6,26 @@ 'use client'; -import { memo, useState } from 'react'; +import { useState } from 'react'; import { Plus, User } from 'lucide-react'; -import { useSession } from 'next-auth/react'; import CreateProjectDialog from '@/components/dialog/create-project-dialog'; import SettingsDialog from '@/components/dialog/settings-dialog'; import { Button } from '@/components/ui/button'; -interface ProjectListHeaderProps { - - className?: string; -} - -const ProjectListHeader = memo(({ className }: ProjectListHeaderProps) => { - const { data: session } = useSession(); +const ProjectListHeader = () => { const [showSettings, setShowSettings] = useState(false); const [showCreateProject, setShowCreateProject] = useState(false); - // Get user initials for avatar fallback - // const getUserInitials = () => { - // if (!session?.user?.name) return 'U'; - // const names = session.user.name.split(' '); - // if (names.length >= 2) { - // return `${names[0][0]}${names[1][0]}`.toUpperCase(); - // } - // return session.user.name[0].toUpperCase(); - // }; - return ( <> -
+
-

Projects

-

Manage your full-stack applications

+

Projects

+

Manage your full-stack applications

- {/* TODO: to be implemented */} - {/*
- - -
*/} {/* Avatar / Settings Button */} - +
@@ -78,7 +53,7 @@ const ProjectListHeader = memo(({ className }: ProjectListHeaderProps) => { ); -}); +}; ProjectListHeader.displayName = 'ProjectListHeader'; diff --git a/components/home-page.tsx b/components/home-page.tsx index 0279c93..15bfc1f 100644 --- a/components/home-page.tsx +++ b/components/home-page.tsx @@ -83,7 +83,7 @@ export function HomePage() { return ( <> {/* Base marketing page - always visible */} -
+
{/* Matrix Background Effect */} @@ -99,7 +99,7 @@ export function HomePage() { height={80} className="w-16 h-16 md:w-20 md:h-20" /> -

+

Fulling

diff --git a/components/ui/alert-dialog-vscode.tsx b/components/ui/alert-dialog-vscode.tsx index 7cfe50d..8cd8f6d 100644 --- a/components/ui/alert-dialog-vscode.tsx +++ b/components/ui/alert-dialog-vscode.tsx @@ -60,7 +60,7 @@ function AlertDialogContent({ e.stopPropagation()} @@ -139,7 +139,7 @@ function AlertDialogAction({ }: React.ComponentProps) { return ( ) @@ -151,7 +151,7 @@ function AlertDialogCancel({ }: React.ComponentProps) { return ( ) diff --git a/components/ui/button.tsx b/components/ui/button.tsx index cedf7fb..ca0c4c8 100644 --- a/components/ui/button.tsx +++ b/components/ui/button.tsx @@ -17,7 +17,7 @@ const buttonVariants = cva( secondary: "bg-secondary text-secondary-foreground border border-border hover:bg-border", ghost: - "text-secondary-foreground hover:bg-border", + "text-muted-foreground hover:bg-border hover:text-foreground", link: "text-primary underline-offset-4 hover:underline", }, size: { diff --git a/components/ui/dropdown-menu.tsx b/components/ui/dropdown-menu.tsx index bbe6fb0..6e16441 100644 --- a/components/ui/dropdown-menu.tsx +++ b/components/ui/dropdown-menu.tsx @@ -74,7 +74,7 @@ function DropdownMenuItem({ data-inset={inset} data-variant={variant} className={cn( - "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "focus:bg-muted focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className )} {...props} @@ -92,7 +92,7 @@ function DropdownMenuCheckboxItem({ Date: Tue, 2 Dec 2025 10:55:44 +0800 Subject: [PATCH 3/5] feat: update toaster position from top-right to bottom-right --- app/layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/layout.tsx b/app/layout.tsx index 4c5a4ff..58984a7 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -24,7 +24,7 @@ export default function RootLayout({ {children} Date: Tue, 2 Dec 2025 11:15:56 +0800 Subject: [PATCH 4/5] style: Remove status item hover background, update status bar divider color, and clear default status icon text color. --- components/layout/status-bar.tsx | 6 +++--- lib/util/status-colors.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/layout/status-bar.tsx b/components/layout/status-bar.tsx index dd4fae0..3a81432 100644 --- a/components/layout/status-bar.tsx +++ b/components/layout/status-bar.tsx @@ -28,12 +28,12 @@ export function StatusBar({ project }: StatusBarProps) {
-
+
Sandbox: {sbStatus}
-
-
+
+
Database: {dbStatus}
diff --git a/lib/util/status-colors.ts b/lib/util/status-colors.ts index da1ca79..dfd0401 100644 --- a/lib/util/status-colors.ts +++ b/lib/util/status-colors.ts @@ -105,7 +105,7 @@ export function getStatusIconColor(status: Status): string { case 'STOPPED': case 'TERMINATED': default: - return 'text-[#858585]' + return '' } } From c27e374fcedd6e37424817d48800d49281cfb268 Mon Sep 17 00:00:00 2001 From: Che <30403707+Che-Zhu@users.noreply.github.com> Date: Tue, 2 Dec 2025 13:54:46 +0800 Subject: [PATCH 5/5] refactor: Update dropdown menu Tailwind CSS classes for data attribute targeting and width. --- components/ui/dropdown-menu.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/ui/dropdown-menu.tsx b/components/ui/dropdown-menu.tsx index 6e16441..c97a2d8 100644 --- a/components/ui/dropdown-menu.tsx +++ b/components/ui/dropdown-menu.tsx @@ -42,7 +42,7 @@ function DropdownMenuContent({ data-slot="dropdown-menu-content" sideOffset={sideOffset} className={cn( - "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md", + "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md", className )} {...props} @@ -74,7 +74,7 @@ function DropdownMenuItem({ data-inset={inset} data-variant={variant} className={cn( - "focus:bg-muted focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "focus:bg-muted focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className )} {...props} @@ -92,7 +92,7 @@ function DropdownMenuCheckboxItem({