mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-26 02:00:52 +01:00
fix(markdown): separate the code block from the agent bubble in light mode
The code block used --muted. Inside an agent bubble that is the wrong value: --bubble-agent is oklch(0.97 0 0) in light, which is exactly --muted. Block and bubble painted the same fill, so the block vanished and the whole comment read as one flat gray slab. Dark hid the fault because the bubble is oklch(0.185 0 0) and the block oklch(0.269 0 0). No fixed token fixes this. The block renders on the page AND inside bubbles, and --bubble-agent changes per variant: "former" is oklch(0.955 0 0), and "hairline" is var(--background) itself. Any fixed choice collides with one of those surfaces. Use a translucent tint instead. --code-surface shifts whatever is beneath it rather than replacing it, so one value separates on the page and in every bubble variant. Light darkens 5% toward the ink; dark lifts 9%. Add tests: the surface must be a color-mix tint defined in both modes, and the block must never pin itself to --muted or --bubble-agent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
27897e754e
commit
48adddb1f8
2 files changed
+46
-8
No files matched your search
@@ -28,7 +28,7 @@ describe("markdown code block styles", () => {
|
||||
it("rides theme tokens for the rendered code block surface", () => {
|
||||
const block = cssBlock(".paperclip-markdown pre");
|
||||
|
||||
expect(block).toContain("background-color: var(--muted)");
|
||||
expect(block).toContain("background-color: var(--code-surface)");
|
||||
expect(block).toContain("color: var(--foreground)");
|
||||
expect(block).toContain("border: 1px solid var(--border)");
|
||||
expect(block).toContain("border-radius: var(--radius-lg)");
|
||||
@@ -37,7 +37,7 @@ describe("markdown code block styles", () => {
|
||||
it("rides theme tokens for the editor content code block surface", () => {
|
||||
const block = cssBlock(".paperclip-mdxeditor-content pre");
|
||||
|
||||
expect(block).toContain("background: var(--muted)");
|
||||
expect(block).toContain("background: var(--code-surface)");
|
||||
expect(block).toContain("color: var(--foreground)");
|
||||
expect(block).toContain("border: 1px solid var(--border)");
|
||||
expect(block).toContain("border-radius: var(--radius-lg)");
|
||||
@@ -46,9 +46,9 @@ describe("markdown code block styles", () => {
|
||||
it("points the normal and inverted prose variables at the same tokens", () => {
|
||||
const block = cssBlock(".paperclip-markdown");
|
||||
|
||||
expect(block).toContain("--tw-prose-pre-bg: var(--muted)");
|
||||
expect(block).toContain("--tw-prose-pre-bg: var(--code-surface)");
|
||||
expect(block).toContain("--tw-prose-pre-code: var(--foreground)");
|
||||
expect(block).toContain("--tw-prose-invert-pre-bg: var(--muted)");
|
||||
expect(block).toContain("--tw-prose-invert-pre-bg: var(--code-surface)");
|
||||
expect(block).toContain("--tw-prose-invert-pre-code: var(--foreground)");
|
||||
});
|
||||
|
||||
@@ -110,3 +110,22 @@ describe("code syntax palette", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("code block surface separation", () => {
|
||||
it("defines the surface as a translucent tint in both modes", () => {
|
||||
// A fixed token cannot work: --bubble-agent is oklch(0.97 0 0) in light,
|
||||
// identical to --muted, and its "hairline" variant is var(--background).
|
||||
// A tint shifts whatever is beneath it, so it separates everywhere.
|
||||
expect(stylesheet).toMatch(/--code-surface:\s*color-mix\(in oklab, var\(--foreground\) \d+%, transparent\)/);
|
||||
|
||||
const darkBlock = stylesheet.slice(stylesheet.indexOf(".dark {"));
|
||||
expect(darkBlock).toContain("--code-surface:");
|
||||
});
|
||||
|
||||
it("never pins the code surface to the agent bubble fill", () => {
|
||||
const preBlock = cssBlock(".paperclip-markdown pre");
|
||||
|
||||
expect(preBlock).not.toContain("var(--muted)");
|
||||
expect(preBlock).not.toContain("var(--bubble-agent)");
|
||||
});
|
||||
});
|
||||
+23
-4
@@ -1408,7 +1408,7 @@ a.paperclip-mention-chip[data-mention-kind="agent"]::before {
|
||||
padding: 0;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--muted);
|
||||
background: var(--code-surface);
|
||||
color: var(--foreground);
|
||||
overflow-x: auto;
|
||||
}
|
||||
@@ -1487,16 +1487,16 @@ a.paperclip-mention-chip[data-mention-kind="agent"]::before {
|
||||
both modes. Override prose CSS variables so prose-invert can't revert to
|
||||
defaults. */
|
||||
.paperclip-markdown {
|
||||
--tw-prose-pre-bg: var(--muted);
|
||||
--tw-prose-pre-bg: var(--code-surface);
|
||||
--tw-prose-pre-code: var(--foreground);
|
||||
--tw-prose-invert-pre-bg: var(--muted);
|
||||
--tw-prose-invert-pre-bg: var(--code-surface);
|
||||
--tw-prose-invert-pre-code: var(--foreground);
|
||||
}
|
||||
|
||||
.paperclip-markdown pre {
|
||||
border: 1px solid var(--border) !important;
|
||||
border-radius: var(--radius-lg) !important;
|
||||
background-color: var(--muted) !important;
|
||||
background-color: var(--code-surface) !important;
|
||||
color: var(--foreground) !important;
|
||||
padding: 0.5rem 0.65rem !important;
|
||||
margin: 0.4rem 0 !important;
|
||||
@@ -1510,6 +1510,25 @@ a.paperclip-mention-chip[data-mention-kind="agent"]::before {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/* ── Code block surface ──
|
||||
The block must separate from whatever it sits on, and that is not always
|
||||
the page. It also renders inside agent bubbles, whose fill --bubble-agent
|
||||
is oklch(0.97 0 0) in light — the same value as --muted, which made the
|
||||
block vanish into the bubble and read as one flat slab. The bubble fill
|
||||
also changes per variant, and the "hairline" variant IS var(--background),
|
||||
so no fixed token separates in every case.
|
||||
|
||||
A translucent tint shifts whatever is beneath it instead of replacing it,
|
||||
so one value holds on the page and in every bubble variant, in both modes.
|
||||
Light darkens toward the ink; dark lifts toward it. */
|
||||
:root {
|
||||
--code-surface: color-mix(in oklab, var(--foreground) 5%, transparent);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--code-surface: color-mix(in oklab, var(--foreground) 9%, transparent);
|
||||
}
|
||||
|
||||
/* ── Code syntax roles ──
|
||||
Each alias points at a token that already exists and already carries a
|
||||
`.dark` override, so one definition covers both modes. A custom property
|
||||
|
||||
Reference in new issue
Block a user