diff --git a/FEEDBACK.md b/FEEDBACK.md
index aaae571..7ad2852 100644
--- a/FEEDBACK.md
+++ b/FEEDBACK.md
@@ -649,10 +649,17 @@
## Item #60
- **Date:** 2026-02-13
- **Priority:** high
-- **Status:** pending
+- **Status:** done
+- **Completed:** 2026-02-13 — commit `e596eea`
- **Description:** Light theme fixes — 4 issues:
- 1. Progress bar colors (sidebar + header) should follow accent color, not hardcoded cyan
- 2. Send button gradient should adapt to theme/accent
- 3. Tool call badges are unreadable in light theme (dark-only Tailwind classes like amber-950, sky-950)
- 4. User message bubble background too subtle in light theme — needs more contrast
- - Sub-agent working on this (session pinchchat-light-theme-fix)
+ 1. Progress bar colors (sidebar + header) should follow accent color, not hardcoded cyan — ✅ already using `--pc-accent-rgb`
+ 2. Send button gradient should adapt to theme/accent — ✅ already using `var(--pc-accent)`
+ 3. Tool call badges are unreadable in light theme (dark-only Tailwind classes like amber-950, sky-950) — ✅ fixed: darker text + higher bg opacity in light mode
+ 4. User message bubble background too subtle in light theme — needs more contrast — ✅ fixed: higher opacity bg + border in light mode
+ - Added `resolvedTheme` to ThemeContext for components to adapt to current theme
+
+## Item #61
+- **Date:** 2026-02-13
+- **Priority:** medium
+- **Status:** pending
+- **Description:** Markdown unordered lists (- item, * item) are not rendered properly in chat messages. They appear as raw text instead of formatted bullet points. Need to verify remarkGfm/ReactMarkdown config handles list rendering correctly, and ensure CSS styles are applied for ul/ol elements in the markdown-body class.
diff --git a/src/components/ChatMessage.tsx b/src/components/ChatMessage.tsx
index f0010fa..be1ec0c 100644
--- a/src/components/ChatMessage.tsx
+++ b/src/components/ChatMessage.tsx
@@ -7,6 +7,7 @@ import remarkBreaks from 'remark-breaks';
import rehypeHighlight from 'rehype-highlight';
import { rehypeHighlightOptions } from '../lib/highlight';
import type { ChatMessage as ChatMessageType, MessageBlock } from '../types';
+import { useTheme } from '../hooks/useTheme';
import { ThinkingBlock } from './ThinkingBlock';
import { ThinkingIndicator } from './ThinkingIndicator';
import { CodeBlock } from './CodeBlock';
@@ -382,6 +383,8 @@ function SystemEventMessage({ message }: { message: ChatMessageType }) {
export function ChatMessageComponent({ message: rawMessage, onRetry, agentAvatarUrl }: { message: ChatMessageType; onRetry?: (text: string) => void; agentAvatarUrl?: string }) {
useLocale(); // re-render on locale change
+ const { resolvedTheme } = useTheme();
+ const isLight = resolvedTheme === 'light';
const [showRawJson, setShowRawJson] = useState(false);
// Strip webhook/hook scaffolding from user messages before rendering
@@ -446,7 +449,9 @@ export function ChatMessageComponent({ message: rawMessage, onRetry, agentAvatar
{/* Action buttons */}
diff --git a/src/components/ToolCall.tsx b/src/components/ToolCall.tsx
index 860513f..6ab2b89 100644
--- a/src/components/ToolCall.tsx
+++ b/src/components/ToolCall.tsx
@@ -2,6 +2,7 @@ import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
import { ChevronRight, ChevronDown, Check, Copy, WrapText, AlignLeft } from 'lucide-react';
import hljs from '../lib/highlight';
import { useT } from '../hooks/useLocale';
+import { useTheme } from '../hooks/useTheme';
import { ImageBlock } from './ImageBlock';
import { useToolCollapse } from '../hooks/useToolCollapse';
@@ -31,13 +32,19 @@ const defaultRGB: ToolRGB = { r: 161, g: 161, b: 170 }; // zinc
function rgbStr(c: ToolRGB): string { return `${c.r},${c.g},${c.b}`; }
-function getColorStyles(name: string): { badge: React.CSSProperties; text: React.CSSProperties; expand: React.CSSProperties; glow: string } {
+function getColorStyles(name: string, isLight = false): { badge: React.CSSProperties; text: React.CSSProperties; expand: React.CSSProperties; glow: string } {
const c = toolRGBs[name] || defaultRGB;
const rgb = rgbStr(c);
+ // Use darker text and higher bg opacity in light theme for readability
+ const badgeBgAlpha = isLight ? 0.15 : 0.10;
+ const expandBgAlpha = isLight ? 0.08 : 0.05;
+ const textColor = isLight
+ ? `rgb(${Math.round(c.r * 0.6)},${Math.round(c.g * 0.6)},${Math.round(c.b * 0.6)})`
+ : `rgb(${c.r},${c.g},${c.b})`;
return {
- badge: { borderColor: `rgba(${rgb},0.3)`, backgroundColor: `rgba(${rgb},0.10)` },
- text: { color: `rgb(${c.r},${c.g},${c.b})` },
- expand: { borderColor: `rgba(${rgb},0.2)`, backgroundColor: `rgba(${rgb},0.05)` },
+ badge: { borderColor: `rgba(${rgb},0.3)`, backgroundColor: `rgba(${rgb},${badgeBgAlpha})` },
+ text: { color: textColor },
+ expand: { borderColor: `rgba(${rgb},0.2)`, backgroundColor: `rgba(${rgb},${expandBgAlpha})` },
glow: `shadow-[0_0_8px_rgba(${rgb},0.15)]`,
};
}
@@ -253,8 +260,9 @@ export function ToolCall({ name, input, result }: { name: string; input?: Record
const [open, setOpen] = useState(false);
const [wrap, setWrap] = useState(true);
const { globalState, version } = useToolCollapse();
+ const { resolvedTheme } = useTheme();
const lastVersion = useRef(version);
- const cs = getColorStyles(name);
+ const cs = getColorStyles(name, resolvedTheme === 'light');
// Respond to global collapse/expand commands
useEffect(() => {
diff --git a/src/contexts/ThemeContext.tsx b/src/contexts/ThemeContext.tsx
index f07ed6b..eb8e7c9 100644
--- a/src/contexts/ThemeContext.tsx
+++ b/src/contexts/ThemeContext.tsx
@@ -180,8 +180,10 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
return () => mq.removeEventListener('change', handler);
}, [theme]);
+ const resolvedTheme = resolveTheme(theme);
+
return (
-
+
{children}
);
diff --git a/src/contexts/ThemeContextDef.ts b/src/contexts/ThemeContextDef.ts
index 6e7cb5d..950f704 100644
--- a/src/contexts/ThemeContextDef.ts
+++ b/src/contexts/ThemeContextDef.ts
@@ -6,6 +6,8 @@ export type AccentColor = 'cyan' | 'violet' | 'emerald' | 'amber' | 'rose' | 'bl
export interface ThemeContextValue {
theme: ThemeName;
accent: AccentColor;
+ /** Resolved concrete theme (never 'system'). */
+ resolvedTheme: 'dark' | 'light' | 'oled';
setTheme: (t: ThemeName) => void;
setAccent: (a: AccentColor) => void;
}
@@ -13,6 +15,7 @@ export interface ThemeContextValue {
export const ThemeContext = createContext({
theme: 'dark',
accent: 'cyan',
+ resolvedTheme: 'dark',
setTheme: () => {},
setAccent: () => {},
});