Skip to content

Commit 49bc8af

Browse files
🤖 refactor: replace hardcoded hex colors with CSS variables (#1197)
Replace hardcoded hex colors in React components with CSS variables from `globals.css` for consistency and maintainability. ## Changes ### New CSS Variables (globals.css) - `--color-code-string`: `hsl(40 53% 67%)` - string literals (#d7ba7d) - `--color-syntax-error`: `hsl(355 65% 65%)` - One Dark error red (#e06c75) - `--color-terminal-bg/fg`: terminal colors for xterm.js - `--color-info`: `hsl(207 90% 54%)` - info blue (#2196f3) - `--color-init-bg/border`: init message styling - `--color-init-error-bg/border`: error state styling - `--color-text-lighter`: `hsl(0 0% 87%)` - lighter text (#ddd) ### Components Updated (9 files) | File | Before | After | |------|--------|-------| | FileEditToolCall.tsx | `#888` | `var(--color-muted)` | | TerminalView.tsx | `#1e1e1e`, `#d4d4d4` | getComputedStyle() for xterm.js canvas | | FileTree.tsx | `#666` | `var(--color-dim)` | | ThresholdSlider.tsx | `#2d2d30`, `#cccccc` | `var(--color-modal-bg)`, `var(--color-bright)` | | TodoList.tsx | `#4caf50`, `#2196f3`, `#888`, `#666` | semantic variables | | InitMessage.tsx | Tailwind arbitrary values | Tailwind theme classes | | Mermaid.tsx | `#e06c75` | `var(--color-syntax-error)` | | AIView.tsx | `#888`, `#2d2d30`, `#d7ba7d` | semantic variables | ### AGENTS.md Fix Corrected styling directive from non-existent `src/styles/colors.tsx` to actual location `src/browser/styles/globals.css`. ## Verification All color mappings verified to produce identical or imperceptibly different colors (±1-2 RGB units max for new variables). --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
1 parent d2e6617 commit 49bc8af

File tree

10 files changed

+51
-23
lines changed

10 files changed

+51
-23
lines changed

docs/AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ Avoid mock-heavy tests that verify implementation details rather than behavior.
113113

114114
## Styling
115115

116-
- Colors defined in `src/styles/colors.tsx`; fonts in `src/styles/fonts.tsx`. Reference them via CSS variables (e.g., `var(--color-plan-mode)`), never hardcode values.
116+
- Colors defined in `src/browser/styles/globals.css` (`:root @theme` block). Reference via CSS variables (e.g., `var(--color-plan-mode)`), never hardcode hex values.
117117

118118
## TypeScript Discipline
119119

src/browser/components/AIView.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,9 @@ const AIViewInner: React.FC<AIViewProps> = ({
594594
<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]">
595595
<h3>No Messages Yet</h3>
596596
<p>Send a message below to begin</p>
597-
<p className="mt-5 text-xs text-[#888]">
597+
<p className="text-muted mt-5 text-xs">
598598
💡 Tip: Add a{" "}
599-
<code className="rounded-[3px] bg-[#2d2d30] px-1.5 py-0.5 font-mono text-[11px] text-[#d7ba7d]">
599+
<code className="bg-inline-code-dark-bg text-code-string rounded-[3px] px-1.5 py-0.5 font-mono text-[11px]">
600600
.mux/init
601601
</code>{" "}
602602
hook to your project to run setup commands

src/browser/components/Messages/InitMessage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ export const InitMessage = React.memo<InitMessageProps>(({ message, className })
1313
return (
1414
<div
1515
className={cn(
16-
"flex flex-col gap-1.5 border-b p-3 font-mono text-xs text-[#ddd]",
17-
isError ? "bg-[#3a1e1e] border-[#653737]" : "bg-[#1e2a3a] border-[#2f3f52]",
16+
"flex flex-col gap-1.5 border-b p-3 font-mono text-xs text-text-lighter",
17+
isError ? "bg-init-error-bg border-init-error-border" : "bg-init-bg border-init-border",
1818
className
1919
)}
2020
>
21-
<div className="flex items-center gap-2 text-[#ccc]">
21+
<div className="text-bright flex items-center gap-2">
2222
<span>🔧</span>
2323
<div>
2424
{message.status === "running" ? (
@@ -31,7 +31,7 @@ export const InitMessage = React.memo<InitMessageProps>(({ message, className })
3131
failed.
3232
</span>
3333
)}
34-
<div className="mt-0.5 font-mono text-[11px] text-[#888]">{message.hookPath}</div>
34+
<div className="text-muted mt-0.5 font-mono text-[11px]">{message.hookPath}</div>
3535
</div>
3636
</div>
3737
{message.lines.length > 0 && (

src/browser/components/Messages/Mermaid.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,13 @@ export const Mermaid: React.FC<{ chart: string }> = ({ chart }) => {
204204

205205
// Not streaming - show actual error
206206
return (
207-
<pre style={{ color: "#e06c75", background: "rgba(224, 108, 117, 0.1)", padding: "12px" }}>
207+
<pre
208+
style={{
209+
color: "var(--color-syntax-error)",
210+
background: "hsl(from var(--color-syntax-error) h s l / 0.1)",
211+
padding: "12px",
212+
}}
213+
>
208214
Mermaid Error: {error}
209215
</pre>
210216
);

src/browser/components/RightSidebar/CodeReview/FileTree.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ const TreeNodeContent: React.FC<{
162162
(node.totalStats.additions > 0 || node.totalStats.deletions > 0) && (
163163
<span
164164
className="flex gap-2 text-[11px] opacity-70"
165-
style={{ color: isOpen ? "#666" : "inherit" }}
165+
style={{ color: isOpen ? "var(--color-dim)" : "inherit" }}
166166
>
167167
{node.totalStats.additions > 0 &&
168168
(isOpen ? (

src/browser/components/RightSidebar/ThresholdSlider.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ const VerticalSliderTooltip: React.FC<VerticalSliderTooltipProps> = ({
101101
const style: React.CSSProperties = {
102102
position: "fixed",
103103
zIndex: 9999,
104-
background: "#2d2d30",
105-
color: "#cccccc",
104+
background: "var(--color-modal-bg)",
105+
color: "var(--color-bright)",
106106
padding: "6px 10px",
107107
borderRadius: 4,
108108
fontSize: 12,

src/browser/components/TerminalView.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,18 @@ export function TerminalView({ workspaceId, sessionId, visible }: TerminalViewPr
8181
// Initialize ghostty-web WASM module (idempotent, safe to call multiple times)
8282
await init();
8383

84+
// Resolve CSS variables for xterm.js (canvas rendering doesn't support CSS vars)
85+
const styles = getComputedStyle(document.documentElement);
86+
const terminalBg = styles.getPropertyValue("--color-terminal-bg").trim() || "#1e1e1e";
87+
const terminalFg = styles.getPropertyValue("--color-terminal-fg").trim() || "#d4d4d4";
88+
8489
terminal = new Terminal({
8590
fontSize: 14,
8691
fontFamily: "JetBrains Mono, Menlo, Monaco, monospace",
8792
cursorBlink: true,
8893
theme: {
89-
background: "#1e1e1e",
90-
foreground: "#d4d4d4",
94+
background: terminalBg,
95+
foreground: terminalFg,
9196
},
9297
});
9398

@@ -231,7 +236,7 @@ export function TerminalView({ workspaceId, sessionId, visible }: TerminalViewPr
231236
style={{
232237
width: "100%",
233238
height: "100%",
234-
backgroundColor: "#1e1e1e",
239+
backgroundColor: "var(--color-terminal-bg)",
235240
}}
236241
>
237242
{errorMessage && (

src/browser/components/TodoList.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ import { cn } from "@/common/lib/utils";
33
import type { TodoItem } from "@/common/types/tools";
44

55
const statusBgColors: Record<TodoItem["status"], string> = {
6-
completed: "color-mix(in srgb, #4caf50, transparent 92%)",
7-
in_progress: "color-mix(in srgb, #2196f3, transparent 92%)",
8-
pending: "color-mix(in srgb, #888, transparent 96%)",
6+
completed: "color-mix(in srgb, var(--color-success), transparent 92%)",
7+
in_progress: "color-mix(in srgb, var(--color-info), transparent 92%)",
8+
pending: "color-mix(in srgb, var(--color-muted), transparent 96%)",
99
};
1010

1111
const statusBorderColors: Record<TodoItem["status"], string> = {
12-
completed: "#4caf50",
13-
in_progress: "#2196f3",
14-
pending: "#666",
12+
completed: "var(--color-success)",
13+
in_progress: "var(--color-info)",
14+
pending: "var(--color-dim)",
1515
};
1616

1717
const statusTextColors: Record<TodoItem["status"], string> = {
18-
completed: "#888",
19-
in_progress: "#2196f3",
18+
completed: "var(--color-muted)",
19+
in_progress: "var(--color-info)",
2020
pending: "var(--color-text)",
2121
};
2222

src/browser/components/tools/FileEditToolCall.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function renderDiff(
5353
try {
5454
const patches = parsePatch(diff);
5555
if (patches.length === 0) {
56-
return <div style={{ padding: "8px", color: "#888" }}>No changes</div>;
56+
return <div style={{ padding: "8px", color: "var(--color-muted)" }}>No changes</div>;
5757
}
5858

5959
// Render each hunk using SelectableDiffRenderer if we have a callback, otherwise DiffRenderer

src/browser/styles/globals.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@
193193
--color-subtle: hsl(0 0% 60%); /* #999 - subtle */
194194
--color-dim: hsl(0 0% 42%); /* #666 - dimmed */
195195
--color-light: hsl(0 0% 83%); /* #d4d4d4 - light */
196+
--color-text-lighter: hsl(0 0% 87%); /* #dddddd - lighter text */
196197
--color-lighter: hsl(0 0% 90%); /* #e5e5e5 - lighter */
197198
--color-bright: hsl(0 0% 80%); /* #cccccc - bright */
198199
--color-subdued: hsl(0 0% 60%); /* #9a9a9a - subdued */
@@ -217,6 +218,7 @@
217218
--color-separator: #262626; /* neutral-800 - dividers/separators */
218219
--color-separator-light: hsl(0 0% 27%); /* #464647 - lighter separator */
219220
--color-modal-bg: hsl(0 0% 18%); /* #2d2d30 - modal backgrounds */
221+
--color-inline-code-dark-bg: hsl(0 0% 18%); /* #2d2d30 - always dark, for inline code that should stay dark in all themes */
220222

221223
--color-accent: hsl(207 100% 40%); /* #007acc - VS Code blue */
222224
--color-accent-hover: hsl(207 100% 45%); /* #1177bb - accent hover */
@@ -239,6 +241,21 @@
239241
/* Code syntax highlighting */
240242
--color-code-type: hsl(197 71% 73%); /* #9cdcfe - type annotations */
241243
--color-code-keyword: hsl(210 59% 63%); /* #6496ff - keywords */
244+
--color-code-string: hsl(40 53% 67%); /* #d7ba7d - string literals */
245+
--color-syntax-error: hsl(355 65% 65%); /* #e06c75 - One Dark error red */
246+
247+
/* Terminal */
248+
--color-terminal-bg: hsl(0 0% 12%); /* #1e1e1e */
249+
--color-terminal-fg: hsl(0 0% 83%); /* #d4d4d4 */
250+
251+
/* Info (blue accent for in-progress states) */
252+
--color-info: hsl(207 90% 54%); /* #2196f3 */
253+
254+
/* Init message surfaces */
255+
--color-init-bg: hsl(210 33% 17%); /* #1e2a3a */
256+
--color-init-border: hsl(210 27% 25%); /* #2f3f52 */
257+
--color-init-error-bg: hsl(0 33% 17%); /* #3a1e1e */
258+
--color-init-error-border: hsl(0 28% 30%); /* #653737 */
242259

243260
/* Toast and notification backgrounds */
244261
--color-toast-success-bg: hsl(207 100% 37% / 0.13); /* #0e639c with 20% opacity */

0 commit comments

Comments
 (0)