fix(workspace): ensure chat markdown readability on forced-dark surface
This commit is contained in:
@@ -116,6 +116,39 @@ html.workspace-viewport-lock body {
|
|||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The chat always renders on the light workspace surface
|
||||||
|
* (`bg-[#f2f0e7]`, near-black text), but the app forces the dark theme
|
||||||
|
* app-wide (`forcedTheme="dark"`). Streamdown's code/table/mermaid chrome and
|
||||||
|
* the rules below read theme tokens, which under `.dark` resolve to near-black
|
||||||
|
* values — producing unreadable dark-on-dark blocks. Re-declare the relevant
|
||||||
|
* tokens to warm-light values inside the markdown context so every token-driven
|
||||||
|
* chrome (headers, copy/download/fullscreen controls, table borders/cells,
|
||||||
|
* inline code) reads correctly on the light surface without touching the
|
||||||
|
* global theme or unrelated UI.
|
||||||
|
*/
|
||||||
|
.workspace-surface .chat-markdown {
|
||||||
|
--background: #ffffff;
|
||||||
|
--foreground: #232321;
|
||||||
|
--muted: #f4f4f2;
|
||||||
|
--muted-foreground: #69675f;
|
||||||
|
--card: #ffffff;
|
||||||
|
--card-foreground: #232321;
|
||||||
|
--popover: #ffffff;
|
||||||
|
--popover-foreground: #232321;
|
||||||
|
--secondary: #f4f4f2;
|
||||||
|
--secondary-foreground: #232321;
|
||||||
|
--accent: #efece4;
|
||||||
|
--accent-foreground: #232321;
|
||||||
|
--sidebar: #ffffff;
|
||||||
|
--sidebar-foreground: #232321;
|
||||||
|
--sidebar-accent: #f4f4f2;
|
||||||
|
--sidebar-accent-foreground: #232321;
|
||||||
|
--border: #e2e0d6;
|
||||||
|
--input: #e2e0d6;
|
||||||
|
--ring: #b6b7b4;
|
||||||
|
}
|
||||||
|
|
||||||
.workspace-surface .chat-markdown,
|
.workspace-surface .chat-markdown,
|
||||||
.workspace-surface .chat-reasoning,
|
.workspace-surface .chat-reasoning,
|
||||||
.workspace-surface .thinking-line {
|
.workspace-surface .thinking-line {
|
||||||
@@ -223,6 +256,16 @@ html.workspace-viewport-lock body {
|
|||||||
text-align: start;
|
text-align: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Readable header band + zebra rows so tables stand out on the surface. */
|
||||||
|
.chat-markdown thead th {
|
||||||
|
background: var(--muted);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-markdown tbody tr:nth-child(even) {
|
||||||
|
background: color-mix(in oklch, var(--muted) 55%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
.chat-markdown *,
|
.chat-markdown *,
|
||||||
.chat-message,
|
.chat-message,
|
||||||
|
|||||||
@@ -59,4 +59,20 @@ describe("Workspace frontend regression contracts", () => {
|
|||||||
expect(messageRenderer).toContain("mermaid");
|
expect(messageRenderer).toContain("mermaid");
|
||||||
expect(messageRenderer).toContain("plugins={streamdownPlugins}");
|
expect(messageRenderer).toContain("plugins={streamdownPlugins}");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("keeps markdown readable on the forced-dark workspace surface", () => {
|
||||||
|
const styles = source("../../index.css");
|
||||||
|
|
||||||
|
// The workspace surface is light, but the app forces the dark theme, so
|
||||||
|
// the markdown context must re-declare the theme tokens streamdown and the
|
||||||
|
// table/code rules read from. Without these the dark tokens (~22-28%
|
||||||
|
// lightness) produce near-black text, borders, and backgrounds.
|
||||||
|
expect(styles).toContain(".workspace-surface .chat-markdown");
|
||||||
|
expect(styles).toContain("--muted: #f4f4f2");
|
||||||
|
expect(styles).toContain("--border: #e2e0d6");
|
||||||
|
expect(styles).toContain("--sidebar: #ffffff");
|
||||||
|
// Table headers and zebra rows must stand out on the surface.
|
||||||
|
expect(styles).toContain(".chat-markdown thead th");
|
||||||
|
expect(styles).toContain(".chat-markdown tbody tr:nth-child(even)");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user