diff --git a/src/browser/components/RuntimeBadge.tsx b/src/browser/components/RuntimeBadge.tsx index e70bdf3bde..d0608bf7e7 100644 --- a/src/browser/components/RuntimeBadge.tsx +++ b/src/browser/components/RuntimeBadge.tsx @@ -14,20 +14,24 @@ interface RuntimeBadgeProps { } // Runtime-specific color schemes - each type has consistent colors in idle/working states +// Colors use CSS variables (--color-runtime-*) so they adapt to theme (e.g., solarized) // Idle: subtle with visible colored border for discrimination // Working: brighter colors with pulse animation const RUNTIME_STYLES = { ssh: { - idle: "bg-transparent text-muted border-blue-500/50", - working: "bg-blue-500/20 text-blue-400 border-blue-500/60 animate-pulse", + idle: "bg-transparent text-muted border-[var(--color-runtime-ssh)]/50", + working: + "bg-[var(--color-runtime-ssh)]/20 text-[var(--color-runtime-ssh-text)] border-[var(--color-runtime-ssh)]/60 animate-pulse", }, worktree: { - idle: "bg-transparent text-muted border-purple-500/50", - working: "bg-purple-500/20 text-purple-400 border-purple-500/60 animate-pulse", + idle: "bg-transparent text-muted border-[var(--color-runtime-worktree)]/50", + working: + "bg-[var(--color-runtime-worktree)]/20 text-[var(--color-runtime-worktree-text)] border-[var(--color-runtime-worktree)]/60 animate-pulse", }, local: { - idle: "bg-transparent text-muted border-muted/50", - working: "bg-muted/30 text-muted border-muted/60 animate-pulse", + idle: "bg-transparent text-muted border-[var(--color-runtime-local)]/50", + working: + "bg-[var(--color-runtime-local)]/30 text-[var(--color-runtime-local)] border-[var(--color-runtime-local)]/60 animate-pulse", }, } as const; diff --git a/src/browser/components/RuntimeIconSelector.tsx b/src/browser/components/RuntimeIconSelector.tsx index e95da78d86..a19ba2fcd1 100644 --- a/src/browser/components/RuntimeIconSelector.tsx +++ b/src/browser/components/RuntimeIconSelector.tsx @@ -16,19 +16,23 @@ interface RuntimeIconSelectorProps { } // Runtime-specific color schemes matching RuntimeBadge +// Colors use CSS variables (--color-runtime-*) so they adapt to theme (e.g., solarized) // Selected (active) uses the "working" styling, unselected uses "idle" const RUNTIME_STYLES = { ssh: { - idle: "bg-transparent text-muted border-blue-500/30 hover:border-blue-500/50", - active: "bg-blue-500/20 text-blue-400 border-blue-500/60", + idle: "bg-transparent text-muted border-[var(--color-runtime-ssh)]/30 hover:border-[var(--color-runtime-ssh)]/50", + active: + "bg-[var(--color-runtime-ssh)]/20 text-[var(--color-runtime-ssh-text)] border-[var(--color-runtime-ssh)]/60", }, worktree: { - idle: "bg-transparent text-muted border-purple-500/30 hover:border-purple-500/50", - active: "bg-purple-500/20 text-purple-400 border-purple-500/60", + idle: "bg-transparent text-muted border-[var(--color-runtime-worktree)]/30 hover:border-[var(--color-runtime-worktree)]/50", + active: + "bg-[var(--color-runtime-worktree)]/20 text-[var(--color-runtime-worktree-text)] border-[var(--color-runtime-worktree)]/60", }, local: { - idle: "bg-transparent text-muted border-muted/30 hover:border-muted/50", - active: "bg-muted/30 text-foreground border-muted/60", + idle: "bg-transparent text-muted border-[var(--color-runtime-local)]/30 hover:border-[var(--color-runtime-local)]/50", + active: + "bg-[var(--color-runtime-local)]/30 text-foreground border-[var(--color-runtime-local)]/60", }, } as const; diff --git a/src/browser/components/ThinkingSlider.tsx b/src/browser/components/ThinkingSlider.tsx index c18c4f29d8..ad2f4b50cd 100644 --- a/src/browser/components/ThinkingSlider.tsx +++ b/src/browser/components/ThinkingSlider.tsx @@ -7,48 +7,52 @@ import { getThinkingPolicyForModel } from "@/browser/utils/thinking/policy"; import { updatePersistedState } from "@/browser/hooks/usePersistedState"; import { getLastThinkingByModelKey } from "@/common/constants/storage"; -// Subtle consistent glow for active levels -const GLOW = { - track: "0 0 6px 1px hsl(271 76% 53% / 0.3)", - thumb: "0 0 4px 1px hsl(271 76% 53% / 0.3)", -}; - +// Uses CSS variable --color-thinking-mode for theme compatibility +// Glow is applied via CSS using color-mix with the theme color const GLOW_INTENSITIES: Record = { 0: { track: "none", thumb: "none" }, - 1: GLOW, - 2: GLOW, - 3: GLOW, + 1: { + track: "0 0 6px 1px color-mix(in srgb, var(--color-thinking-mode) 30%, transparent)", + thumb: "0 0 4px 1px color-mix(in srgb, var(--color-thinking-mode) 30%, transparent)", + }, + 2: { + track: "0 0 6px 1px color-mix(in srgb, var(--color-thinking-mode) 30%, transparent)", + thumb: "0 0 4px 1px color-mix(in srgb, var(--color-thinking-mode) 30%, transparent)", + }, + 3: { + track: "0 0 6px 1px color-mix(in srgb, var(--color-thinking-mode) 30%, transparent)", + thumb: "0 0 4px 1px color-mix(in srgb, var(--color-thinking-mode) 30%, transparent)", + }, }; -// Continuous function for text styling based on level (n: 0-3) -const getTextStyle = (n: number) => { +// Text styling based on level (n: 0-3) +// Uses CSS variables for theme compatibility +const getTextStyle = (n: number): React.CSSProperties => { if (n === 0) { return { - color: "#606060", + color: "var(--color-text-secondary)", fontWeight: 400, textShadow: "none", fontSize: "10px", }; } - // Continuous interpolation for n = 1-3 - const hue = 271 + (n - 1) * 7; // 271 → 278 → 285 - const lightness = 65 - (n - 1) * 5; // 65 → 60 → 55 + // Active levels use the thinking mode color + // Low uses lighter variant, medium/high use main color const fontWeight = 400 + n * 100; // 500 → 600 → 700 - const shadowBlur = n * 4; // 4 → 8 → 12 - const shadowOpacity = 0.3 + n * 0.15; // 0.45 → 0.6 → 0.75 return { - color: `hsl(${hue} 76% ${lightness}%)`, + color: n === 1 ? "var(--color-thinking-mode-light)" : "var(--color-thinking-mode)", fontWeight, - textShadow: `0 0 ${shadowBlur}px hsl(${hue} 76% ${lightness}% / ${shadowOpacity})`, + textShadow: "none", fontSize: "10px", }; }; const getSliderStyles = (value: number, isHover = false) => { const effectiveValue = isHover ? Math.min(value + 1, 3) : value; - const thumbBg = value === 0 ? "#606060" : `hsl(271 76% ${53 + value * 5}%)`; + // Use CSS variable for thumb color when active + const thumbBg = value === 0 ? "var(--color-text-secondary)" : "var(--color-thinking-mode)"; return { trackShadow: GLOW_INTENSITIES[effectiveValue].track, diff --git a/src/browser/styles/globals.css b/src/browser/styles/globals.css index dda9054231..d032fa4068 100644 --- a/src/browser/styles/globals.css +++ b/src/browser/styles/globals.css @@ -62,6 +62,13 @@ --color-thinking-mode-light: hsl(271 76% 65%); --color-thinking-border: hsl(271 76% 53%); + /* Runtime icon colors (matches Tailwind blue-500/purple-500) */ + --color-runtime-ssh: #3b82f6; + --color-runtime-ssh-text: #60a5fa; /* blue-400 */ + --color-runtime-worktree: #a855f7; + --color-runtime-worktree-text: #c084fc; /* purple-400 */ + --color-runtime-local: hsl(0 0% 60%); /* matches --color-muted-foreground */ + /* Background & Layout */ --color-background: hsl(0 0% 12%); --color-background-secondary: hsl(60 1% 15%); @@ -300,6 +307,13 @@ --color-thinking-mode-light: hsl(271 70% 62%); --color-thinking-border: hsl(271 70% 46%); + /* Runtime icon colors (matches Tailwind blue-500/purple-500) */ + --color-runtime-ssh: #3b82f6; + --color-runtime-ssh-text: #60a5fa; + --color-runtime-worktree: #a855f7; + --color-runtime-worktree-text: #c084fc; + --color-runtime-local: hsl(210 14% 48%); /* matches --color-muted-foreground */ + --color-background: hsl(210 33% 98%); --color-background-secondary: hsl(210 36% 95%); --color-border: hsl(210 24% 82%); @@ -519,9 +533,16 @@ --color-debug-light: hsl(205 69% 62%); --color-debug-text: hsl(205 69% 35%); - --color-thinking-mode: hsl(237 43% 60%); - --color-thinking-mode-light: hsl(237 43% 70%); - --color-thinking-border: hsl(237 43% 60%); + --color-thinking-mode: #6c71c4; /* violet */ + --color-thinking-mode-light: #8589d0; + --color-thinking-border: #6c71c4; + + /* Runtime icon colors - using solarized palette */ + --color-runtime-ssh: #268bd2; /* blue */ + --color-runtime-ssh-text: #268bd2; + --color-runtime-worktree: #6c71c4; /* violet */ + --color-runtime-worktree-text: #6c71c4; + --color-runtime-local: #839496; /* base0 */ /* Background & Layout - Solarized base colors */ --color-background: #fdf6e3; /* base3 */ @@ -633,14 +654,15 @@ --color-border-subtle: #93a1a1; --color-border-gray: #93a1a1; - --color-dark: #fdf6e3; - --color-darker: #eee8d5; + /* Three-zone backgrounds: sidebar (base2), workspace (base3), input (between) */ + --color-dark: #fdf6e3; /* base3 - main workspace */ + --color-darker: #eee8d5; /* base2 */ --color-hover: #e5dfcc; --color-bg-medium: #ddd6c3; --color-bg-light: #d5ceb8; --color-bg-subtle: #eee8d5; - --color-separator: #eee8d5; + --color-separator: #eee8d5; /* base2 - sidebar background */ --color-separator-light: #f5efdc; --color-modal-bg: #fdf6e3; @@ -724,13 +746,26 @@ --color-debug-light: hsl(205 69% 62%); --color-debug-text: hsl(205 69% 70%); - --color-thinking-mode: hsl(237 43% 60%); - --color-thinking-mode-light: hsl(237 43% 70%); - --color-thinking-border: hsl(237 43% 60%); - - /* Background & Layout - Solarized dark base colors */ - --color-background: #002b36; /* base03 */ - --color-background-secondary: #073642; /* base02 */ + --color-thinking-mode: #6c71c4; /* violet */ + --color-thinking-mode-light: #8589d0; + --color-thinking-border: #6c71c4; + + /* Runtime icon colors - using solarized palette */ + --color-runtime-ssh: #268bd2; /* blue */ + --color-runtime-ssh-text: #268bd2; + --color-runtime-worktree: #6c71c4; /* violet */ + --color-runtime-worktree-text: #6c71c4; + --color-runtime-local: #839496; /* base0 */ + + /* Background & Layout - Solarized dark base colors + Palette reference: + base03 #002b36 (darkest) base3 #fdf6e3 (lightest) + base02 #073642 base2 #eee8d5 + base01 #586e75 base1 #93a1a1 + base00 #657b83 base0 #839496 + */ + --color-background: #002b36; /* base03 - main background */ + --color-background-secondary: #073642; /* base02 - secondary surfaces */ --color-border: #586e75; /* base01 */ --color-foreground: #839496; /* base0 */ --color-text: #839496; @@ -838,15 +873,16 @@ --color-border-subtle: #586e75; --color-border-gray: #586e75; - --color-dark: #002b36; - --color-darker: #00232d; + /* Three-zone backgrounds: sidebar (base02), workspace (base03), input (between) */ + --color-dark: #001f29; /* slightly darker than base03 for workspace */ + --color-darker: #001a22; --color-hover: #0a4555; --color-bg-medium: #0d5566; --color-bg-light: #106577; --color-bg-subtle: #073642; - --color-separator: #073642; - --color-separator-light: #0a4555; + --color-separator: #073642; /* base02 - sidebar background */ + --color-separator-light: #094555; /* slightly lighter for hover states */ --color-modal-bg: #073642; --color-accent: #268bd2; /* blue */ @@ -1594,7 +1630,7 @@ pre code { width: 12px; height: 12px; border-radius: 50%; - background: var(--thumb-bg, #606060); + background: var(--thumb-bg, var(--color-muted)); cursor: pointer; transition: background 0.2s ease, @@ -1606,7 +1642,7 @@ pre code { width: 12px; height: 12px; border-radius: 50%; - background: var(--thumb-bg, #606060); + background: var(--thumb-bg, var(--color-muted)); cursor: pointer; border: none; transition: