Skip to content

Commit b762239

Browse files
committed
🤖 Consolidate theme variables to Tailwind native colors
Reduced custom CSS variables from 146 to 31 (79% reduction) by migrating to Tailwind's native color system. ## Changes ### Removed (115 variables) - 50+ gray variants → Tailwind gray-100 through gray-950 - 7 accent blue variants → Tailwind sky-{400,500,600,700,800} - 40+ unused colors (toasts, overlays, review backgrounds) ### Kept (31 semantic variables) - Mode colors: plan, exec, edit, editing, thinking, debug (17 vars) - Status: interrupted, review-accent, git-dirty, pending (4 vars) - Special: code-bg, user-border, assistant-border (3 vars) - Tokens: input, output, cached (3 vars) - Errors: error, error-bg, error-bg-dark (3 vars) - Alpha: plan-mode-alpha, editing-mode-alpha (2 vars) ### Files Updated - globals.css: -114 lines (replaced var() with @apply and theme()) - 60 component files: replaced custom classes with Tailwind equivalents - text-muted → text-gray-500 - text-foreground → text-gray-200 - bg-dark → bg-gray-950 - border-border → border-gray-800 - text-accent → text-sky-600 ## Benefits - Simplified color system using standard Tailwind scale - Better developer experience with documented color classes - Easier theming via Tailwind's built-in system - Reduced maintenance burden (79% fewer variables) _Generated with `cmux`_
1 parent 366eb38 commit b762239

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+362
-514
lines changed

‎src/App.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ function AppInner() {
662662

663663
return (
664664
<>
665-
<div className="bg-bg-dark flex h-screen overflow-hidden [@media(max-width:768px)]:flex-col">
665+
<div className="bg-bg-gray-950 flex h-screen overflow-hidden [@media(max-width:768px)]:flex-col">
666666
<LeftSidebar
667667
projects={projects}
668668
workspaceMetadata={workspaceMetadata}
@@ -701,7 +701,7 @@ function AppInner() {
701701
</ErrorBoundary>
702702
) : (
703703
<div
704-
className="[&_p]:text-muted mx-auto w-full max-w-3xl text-center [&_h2]:mb-4 [&_h2]:font-bold [&_h2]:tracking-tight [&_h2]:text-white [&_p]:leading-[1.6]"
704+
className="mx-auto w-full max-w-3xl text-center [&_h2]:mb-4 [&_h2]:font-bold [&_h2]:tracking-tight [&_h2]:text-white [&_p]:leading-[1.6] [&_p]:text-gray-500"
705705
style={{
706706
padding: "clamp(40px, 10vh, 100px) 20px",
707707
fontSize: "clamp(14px, 2vw, 16px)",

‎src/components/AIView.tsx‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,12 @@ const AIViewInner: React.FC<AIViewProps> = ({
245245
return (
246246
<div
247247
className={cn(
248-
"flex flex-1 flex-row bg-dark text-light overflow-x-auto overflow-y-hidden [@media(max-width:768px)]:flex-col",
248+
"flex flex-1 flex-row bg-gray-950 text-gray-200 overflow-x-auto overflow-y-hidden [@media(max-width:768px)]:flex-col",
249249
className
250250
)}
251251
style={{ containerType: "inline-size" }}
252252
>
253-
<div className="text-placeholder flex h-full flex-1 flex-col items-center justify-center text-center">
253+
<div className="flex h-full flex-1 flex-col items-center justify-center text-center text-gray-500">
254254
<h3 className="m-0 mb-2.5 text-base font-medium">Loading workspace...</h3>
255255
</div>
256256
</div>
@@ -286,12 +286,12 @@ const AIViewInner: React.FC<AIViewProps> = ({
286286
return (
287287
<div
288288
className={cn(
289-
"flex flex-1 flex-row bg-dark text-light overflow-x-auto overflow-y-hidden [@media(max-width:768px)]:flex-col",
289+
"flex flex-1 flex-row bg-gray-950 text-gray-200 overflow-x-auto overflow-y-hidden [@media(max-width:768px)]:flex-col",
290290
className
291291
)}
292292
style={{ containerType: "inline-size" }}
293293
>
294-
<div className="text-placeholder flex h-full flex-1 flex-col items-center justify-center text-center">
294+
<div className="flex h-full flex-1 flex-col items-center justify-center text-center text-gray-500">
295295
<h3 className="m-0 mb-2.5 text-base font-medium">Loading workspace...</h3>
296296
</div>
297297
</div>
@@ -302,12 +302,12 @@ const AIViewInner: React.FC<AIViewProps> = ({
302302
return (
303303
<div
304304
className={cn(
305-
"flex flex-1 flex-row bg-dark text-light overflow-x-auto overflow-y-hidden [@media(max-width:768px)]:flex-col",
305+
"flex flex-1 flex-row bg-gray-950 text-gray-200 overflow-x-auto overflow-y-hidden [@media(max-width:768px)]:flex-col",
306306
className
307307
)}
308308
style={{ containerType: "inline-size" }}
309309
>
310-
<div className="text-placeholder flex h-full flex-1 flex-col items-center justify-center text-center">
310+
<div className="flex h-full flex-1 flex-col items-center justify-center text-center text-gray-500">
311311
<h3 className="m-0 mb-2.5 text-base font-medium">No Workspace Selected</h3>
312312
<p className="m-0 text-[13px]">
313313
Select a workspace from the sidebar to view and interact with Claude
@@ -320,7 +320,7 @@ const AIViewInner: React.FC<AIViewProps> = ({
320320
return (
321321
<div
322322
className={cn(
323-
"flex flex-1 flex-row bg-dark text-light overflow-x-auto overflow-y-hidden [@media(max-width:768px)]:flex-col",
323+
"flex flex-1 flex-row bg-gray-950 text-gray-200 overflow-x-auto overflow-y-hidden [@media(max-width:768px)]:flex-col",
324324
className
325325
)}
326326
style={{ containerType: "inline-size" }}
@@ -329,8 +329,8 @@ const AIViewInner: React.FC<AIViewProps> = ({
329329
ref={chatAreaRef}
330330
className="flex min-w-96 flex-1 flex-col [@media(max-width:768px)]:max-h-full [@media(max-width:768px)]:w-full [@media(max-width:768px)]:min-w-0"
331331
>
332-
<div className="bg-separator border-border-light flex items-center justify-between border-b px-[15px] py-1 [@media(max-width:768px)]:flex-wrap [@media(max-width:768px)]:gap-2 [@media(max-width:768px)]:py-2 [@media(max-width:768px)]:pl-[60px]">
333-
<div className="text-foreground flex min-w-0 items-center gap-2 overflow-hidden font-semibold">
332+
<div className="flex items-center justify-between border-b border-gray-800 bg-gray-900 px-[15px] py-1 [@media(max-width:768px)]:flex-wrap [@media(max-width:768px)]:gap-2 [@media(max-width:768px)]:py-2 [@media(max-width:768px)]:pl-[60px]">
333+
<div className="flex min-w-0 items-center gap-2 overflow-hidden font-semibold text-gray-200">
334334
<StatusIndicator
335335
streaming={canInterrupt}
336336
title={
@@ -345,13 +345,13 @@ const AIViewInner: React.FC<AIViewProps> = ({
345345
<span className="min-w-0 truncate font-mono text-xs">
346346
{projectName} / {branch}
347347
</span>
348-
<span className="text-muted min-w-0 truncate font-mono text-[11px] font-normal">
348+
<span className="min-w-0 truncate font-mono text-[11px] font-normal text-gray-500">
349349
{namedWorkspacePath}
350350
</span>
351351
<TooltipWrapper inline>
352352
<button
353353
onClick={handleOpenTerminal}
354-
className="text-muted hover:text-foreground flex cursor-pointer items-center justify-center border-none bg-transparent p-1 transition-colors [&_svg]:h-4 [&_svg]:w-4"
354+
className="flex cursor-pointer items-center justify-center border-none bg-transparent p-1 text-gray-500 transition-colors hover:text-gray-200 [&_svg]:h-4 [&_svg]:w-4"
355355
>
356356
<svg viewBox="0 0 16 16" fill="currentColor">
357357
<path d="M0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0114.25 15H1.75A1.75 1.75 0 010 13.25V2.75zm1.75-.25a.25.25 0 00-.25.25v10.5c0 .138.112.25.25.25h12.5a.25.25 0 00.25-.25V2.75a.25.25 0 00-.25-.25H1.75zM7.25 8a.75.75 0 01-.22.53l-2.25 2.25a.75.75 0 01-1.06-1.06L5.44 8 3.72 6.28a.75.75 0 111.06-1.06l2.25 2.25c.141.14.22.331.22.53zm1.5 1.5a.75.75 0 000 1.5h3a.75.75 0 000-1.5h-3z" />
@@ -378,7 +378,7 @@ const AIViewInner: React.FC<AIViewProps> = ({
378378
className="h-full overflow-y-auto p-[15px] leading-[1.5] break-words whitespace-pre-wrap"
379379
>
380380
{mergedMessages.length === 0 ? (
381-
<div className="text-placeholder flex h-full flex-1 flex-col items-center justify-center text-center [&_h3]:m-0 [&_h3]:mb-2.5 [&_h3]:text-base [&_h3]:font-medium [&_p]:m-0 [&_p]:text-[13px]">
381+
<div className="flex h-full flex-1 flex-col items-center justify-center text-center text-gray-500 [&_h3]:m-0 [&_h3]:mb-2.5 [&_h3]:text-base [&_h3]:font-medium [&_p]:m-0 [&_p]:text-[13px]">
382382
<h3>No Messages Yet</h3>
383383
<p>Send a message below to begin</p>
384384
</div>

‎src/components/ChatInput.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ export const ChatInput: React.FC<ChatInputProps> = ({
704704

705705
return (
706706
<div
707-
className="bg-separator border-border-light relative flex flex-col gap-1 border-t px-[15px] pt-[5px] pb-[15px]"
707+
className="relative flex flex-col gap-1 border-t border-gray-800 bg-gray-900 px-[15px] pt-[5px] pb-[15px]"
708708
style={{ containerType: "inline-size" }}
709709
data-component="ChatInputSection"
710710
>
@@ -782,7 +782,7 @@ export const ChatInput: React.FC<ChatInputProps> = ({
782782
<div className="max-@[700px]:hidden ml-auto flex items-center gap-1.5">
783783
<div
784784
className={cn(
785-
"flex gap-0 bg-toggle-bg rounded",
785+
"flex gap-0 bg-gray-900 rounded",
786786
"[&>button:first-of-type]:rounded-l [&>button:last-of-type]:rounded-r",
787787
mode === "exec" &&
788788
"[&>button:first-of-type]:bg-exec-mode [&>button:first-of-type]:text-white [&>button:first-of-type]:hover:bg-exec-mode-hover",

‎src/components/ChatInputToast.tsx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { useEffect, useCallback } from "react";
33
import { cn } from "@/lib/utils";
44

55
const toastTypeStyles: Record<"success" | "error", string> = {
6-
success: "bg-toast-success-bg border border-accent-dark text-toast-success-text",
6+
success: "bg-toast-success-bg border border-sky-700 text-toast-success-text",
77
error: "bg-toast-error-bg border border-toast-error-border text-toast-error-text",
88
};
99

@@ -22,7 +22,7 @@ interface ChatInputToastProps {
2222
}
2323

2424
export const SolutionLabel: React.FC<{ children: ReactNode }> = ({ children }) => (
25-
<div className="text-muted-light mb-1 text-[10px] uppercase">{children}</div>
25+
<div className="text-gray-500-light mb-1 text-[10px] uppercase">{children}</div>
2626
);
2727

2828
export const ChatInputToast: React.FC<ChatInputToastProps> = ({ toast, onDismiss }) => {
@@ -71,9 +71,9 @@ export const ChatInputToast: React.FC<ChatInputToastProps> = ({ toast, onDismiss
7171
<span className="text-sm leading-none">âš </span>
7272
<div className="flex-1">
7373
{toast.title && <div className="mb-1.5 font-semibold">{toast.title}</div>}
74-
<div className="text-light mt-1.5 leading-[1.4]">{toast.message}</div>
74+
<div className="mt-1.5 leading-[1.4] text-gray-200">{toast.message}</div>
7575
{toast.solution && (
76-
<div className="bg-dark font-monospace text-code-type mt-2 rounded px-2 py-1.5 text-[11px]">
76+
<div className="font-monospace text-code-type mt-2 rounded bg-gray-950 px-2 py-1.5 text-[11px]">
7777
{toast.solution}
7878
</div>
7979
)}

‎src/components/ChatMetaSidebar.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const ChatMetaSidebarComponent: React.FC<ChatMetaSidebarProps> = ({ workspaceId,
5959
return (
6060
<div
6161
className={cn(
62-
"bg-separator border-l border-border-light flex flex-col overflow-hidden transition-[width] duration-200 flex-shrink-0",
62+
"bg-gray-900 border-l border-gray-800 flex flex-col overflow-hidden transition-[width] duration-200 flex-shrink-0",
6363
showCollapsed ? "w-5 sticky right-0 z-10 shadow-[-2px_0_4px_rgba(0,0,0,0.2)]" : "w-80"
6464
)}
6565
role="complementary"

‎src/components/CommandPalette.stories.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ type Story = StoryObj<typeof meta>;
174174

175175
export const Default: Story = {
176176
render: () => (
177-
<div className="bg-dark flex min-h-[600px] flex-col gap-5 p-5">
178-
<div className="bg-separator border-border-light text-bright font-primary [&_kbd]:bg-dark [&_kbd]:border-border-light [&_kbd]:font-monospace rounded border p-4 text-[13px] leading-[1.6] [&_kbd]:rounded-[3px] [&_kbd]:border [&_kbd]:px-1.5 [&_kbd]:py-0.5 [&_kbd]:text-[11px]">
177+
<div className="flex min-h-[600px] flex-col gap-5 bg-gray-950 p-5">
178+
<div className="font-primary [&_kbd]:font-monospace rounded border border-gray-800 bg-gray-900 p-4 text-[13px] leading-[1.6] text-gray-300 [&_kbd]:rounded-[3px] [&_kbd]:border [&_kbd]:border-gray-800 [&_kbd]:bg-gray-950 [&_kbd]:px-1.5 [&_kbd]:py-0.5 [&_kbd]:text-[11px]">
179179
<strong>Command Palette</strong>
180180
<br />
181181
<br />

‎src/components/CommandPalette.tsx‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,12 @@ export const CommandPalette: React.FC<CommandPaletteProps> = ({ getSlashContext
364364
}}
365365
>
366366
<Command
367-
className="bg-separator border-border text-lighter font-primary w-[min(720px,92vw)] overflow-hidden rounded-lg border shadow-[0_10px_40px_rgba(0,0,0,0.4)]"
367+
className="text-lighter font-primary w-[min(720px,92vw)] overflow-hidden rounded-lg border border-gray-800 bg-gray-900 shadow-[0_10px_40px_rgba(0,0,0,0.4)]"
368368
onMouseDown={(e: React.MouseEvent) => e.stopPropagation()}
369369
shouldFilter={shouldUseCmdkFilter}
370370
>
371371
<Command.Input
372-
className="bg-darker text-lighter border-hover w-full border-b border-none px-3.5 py-3 text-sm outline-none"
372+
className="text-lighter border-hover w-full border-b border-none bg-gray-950 px-3.5 py-3 text-sm outline-none"
373373
value={query}
374374
onValueChange={handleQueryChange}
375375
placeholder={
@@ -405,12 +405,12 @@ export const CommandPalette: React.FC<CommandPaletteProps> = ({ getSlashContext
405405
<Command.Group
406406
key={group.name}
407407
heading={group.name}
408-
className="[&[cmdk-group-heading]]:text-subdued [&[cmdk-group-heading]]:px-2.5 [&[cmdk-group-heading]]:py-1 [&[cmdk-group-heading]]:text-[11px] [&[cmdk-group-heading]]:tracking-[0.08em] [&[cmdk-group-heading]]:uppercase [&[cmdk-group]]:px-1.5 [&[cmdk-group]]:py-2"
408+
className="[&[cmdk-group-heading]]:px-2.5 [&[cmdk-group-heading]]:py-1 [&[cmdk-group-heading]]:text-[11px] [&[cmdk-group-heading]]:tracking-[0.08em] [&[cmdk-group-heading]]:text-gray-400 [&[cmdk-group-heading]]:uppercase [&[cmdk-group]]:px-1.5 [&[cmdk-group]]:py-2"
409409
>
410410
{group.items.map((item) => (
411411
<Command.Item
412412
key={item.id}
413-
className="hover:bg-hover aria-selected:bg-hover mx-1 my-0.5 grid cursor-pointer grid-cols-[1fr_auto] items-center gap-2 rounded-md px-3 py-2 text-[13px]"
413+
className="mx-1 my-0.5 grid cursor-pointer grid-cols-[1fr_auto] items-center gap-2 rounded-md px-3 py-2 text-[13px] hover:bg-gray-900 aria-selected:bg-gray-900"
414414
onSelect={() => {
415415
if ("prompt" in item && item.prompt) {
416416
addRecent(item.id);
@@ -435,12 +435,12 @@ export const CommandPalette: React.FC<CommandPaletteProps> = ({ getSlashContext
435435
{"subtitle" in item && item.subtitle && (
436436
<>
437437
<br />
438-
<span className="text-subdued text-xs">{item.subtitle}</span>
438+
<span className="text-xs text-gray-400">{item.subtitle}</span>
439439
</>
440440
)}
441441
</div>
442442
{"shortcutHint" in item && item.shortcutHint && (
443-
<span className="text-subdued font-monospace text-[11px]">
443+
<span className="font-monospace text-[11px] text-gray-400">
444444
{item.shortcutHint}
445445
</span>
446446
)}

‎src/components/CommandSuggestions.tsx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export const CommandSuggestions: React.FC<CommandSuggestionsProps> = ({
9393
activeSuggestion ? `${resolvedListId}-option-${activeSuggestion.id}` : undefined
9494
}
9595
data-command-suggestions
96-
className="bg-separator border-border-light absolute right-0 bottom-full left-0 z-[100] mb-2 flex max-h-[200px] flex-col overflow-y-auto rounded border shadow-[0_-4px_12px_rgba(0,0,0,0.4)]"
96+
className="absolute right-0 bottom-full left-0 z-[100] mb-2 flex max-h-[200px] flex-col overflow-y-auto rounded border border-gray-800 bg-gray-900 shadow-[0_-4px_12px_rgba(0,0,0,0.4)]"
9797
>
9898
{suggestions.map((suggestion, index) => (
9999
<div
@@ -108,13 +108,13 @@ export const CommandSuggestions: React.FC<CommandSuggestionsProps> = ({
108108
index === selectedIndex ? "bg-accent-darker" : "bg-transparent"
109109
)}
110110
>
111-
<div className="text-accent font-monospace shrink-0 text-xs">{suggestion.display}</div>
112-
<div className="text-medium truncate text-right text-[11px]">
111+
<div className="font-monospace shrink-0 text-xs text-sky-600">{suggestion.display}</div>
112+
<div className="truncate text-right text-[11px] text-gray-400">
113113
{suggestion.description}
114114
</div>
115115
</div>
116116
))}
117-
<div className="border-border-light bg-dark text-placeholder [&_span]:text-medium shrink-0 border-t px-2.5 py-1 text-center text-[10px] [&_span]:font-medium">
117+
<div className="shrink-0 border-t border-gray-800 bg-gray-950 px-2.5 py-1 text-center text-[10px] text-gray-500 [&_span]:font-medium [&_span]:text-gray-400">
118118
<span>Tab</span> to complete • <span>↑↓</span> to navigate • <span>Esc</span> to dismiss
119119
</div>
120120
</div>

‎src/components/Context1MCheckbox.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ export const Context1MCheckbox: React.FC<Context1MCheckboxProps> = ({ modelStrin
1717

1818
return (
1919
<div className="ml-2 flex items-center gap-1.5">
20-
<label className="text-foreground flex cursor-pointer items-center gap-1 truncate text-[10px] select-none hover:text-white">
20+
<label className="flex cursor-pointer items-center gap-1 truncate text-[10px] text-gray-200 select-none hover:text-white">
2121
<input
2222
type="checkbox"
2323
checked={use1M}
2424
onChange={(e) => setUse1M(e.target.checked)}
25-
className="border-border-light bg-dark hover:border-accent checked:bg-accent checked:border-accent relative m-0 h-[11px] w-3 cursor-pointer appearance-none rounded-sm border checked:after:absolute checked:after:top-0 checked:after:left-[3px] checked:after:h-[6px] checked:after:w-1 checked:after:rotate-45 checked:after:border-r-[1.5px] checked:after:border-b-[1.5px] checked:after:border-solid checked:after:border-white checked:after:content-['']"
25+
className="checked:bg-accent relative m-0 h-[11px] w-3 cursor-pointer appearance-none rounded-sm border border-gray-800 bg-gray-950 checked:border-sky-600 checked:after:absolute checked:after:top-0 checked:after:left-[3px] checked:after:h-[6px] checked:after:w-1 checked:after:rotate-45 checked:after:border-r-[1.5px] checked:after:border-b-[1.5px] checked:after:border-solid checked:after:border-white checked:after:content-[''] hover:border-sky-600"
2626
/>
2727
1M Context
2828
</label>
2929
<TooltipWrapper inline>
30-
<span className="text-muted flex cursor-help items-center text-[10px] leading-none">?</span>
30+
<span className="flex cursor-help items-center text-[10px] leading-none text-gray-500">?</span>
3131
<Tooltip className="tooltip" align="center" width="auto">
3232
Enable 1M token context window (beta feature for Claude Sonnet 4/4.5)
3333
</Tooltip>

‎src/components/DirectorySelectModal.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export const DirectorySelectModal: React.FC = () => {
8282
onKeyDown={handleKeyDown}
8383
placeholder="/home/user/projects/my-project"
8484
autoFocus
85-
className="bg-modal-bg border-border-medium focus:border-accent placeholder:text-muted mb-5 w-full rounded border px-3 py-2 font-mono text-sm text-white focus:outline-none"
85+
className="border-gray-800-medium mb-5 w-full rounded border bg-gray-900 px-3 py-2 font-mono text-sm text-white placeholder:text-gray-500 focus:border-sky-600 focus:outline-none"
8686
/>
8787
{error && <div className="text-error -mt-3 mb-3 text-xs">{error}</div>}
8888
<ModalActions>

0 commit comments

Comments
 (0)