diff --git a/packages/buckaroo-js-core/src/components/DFViewerParts/ChartCell.render.test.tsx b/packages/buckaroo-js-core/src/components/DFViewerParts/ChartCell.render.test.tsx
new file mode 100644
index 000000000..d627027cd
--- /dev/null
+++ b/packages/buckaroo-js-core/src/components/DFViewerParts/ChartCell.render.test.tsx
@@ -0,0 +1,77 @@
+/**
+ * Sparkline rendering contract for the chart cell (pinned rows and data
+ * columns):
+ * - every line series draws at 1px with per-point dots disabled — the
+ * 100x24 chart gets CSS-scaled to fill its grid cell, which turns the
+ * recharts defaults (dots + scaled stroke) into a fat blobby squiggle
+ * - a hidden YAxis pads the plot by 2px top and bottom so a series whose
+ * values sit exactly at dataMin/dataMax (e.g. the "after" side of a
+ * diff whose values collapsed) isn't drawn on the plot border where
+ * the clip rect swallows half the stroke
+ */
+jest.mock("react", () => {
+ const actual = jest.requireActual("react");
+ return { __esModule: true, default: actual, ...actual };
+});
+
+import { render } from "@testing-library/react";
+import { getChartCell, LineObservation } from "./ChartCell";
+
+// recharts pulls in DOM-measurement code that doesn't run cleanly under
+// jsdom — stub the exports ChartCell touches, keeping Line/YAxis props
+// inspectable in the rendered tree.
+jest.mock("recharts", () => {
+ const React = require("react");
+ return {
+ Area: () => null,
+ Bar: () => null,
+ Line: ({ dataKey, dot, strokeWidth }: any) =>
+ React.createElement("div", {
+ "data-testid": `line-${dataKey}`,
+ "data-dot": String(dot),
+ "data-stroke-width": String(strokeWidth),
+ }),
+ Tooltip: () => null,
+ YAxis: ({ hide, padding }: any) =>
+ React.createElement("div", {
+ "data-testid": "yaxis-mock",
+ "data-hide": String(hide),
+ "data-padding-top": String(padding?.top),
+ "data-padding-bottom": String(padding?.bottom),
+ }),
+ ComposedChart: ({ children }: any) =>
+ React.createElement("div", { "data-testid": "composedchart-mock" }, children),
+ };
+});
+
+const ChartCell = getChartCell({ displayer: "chart" });
+
+const validChart: LineObservation[] = [{ lineRed: 10 }, { lineRed: 20 }];
+
+const mkProps = (value: any) => ({
+ value,
+ api: {} as any,
+ colDef: { cellClass: "" } as any,
+ column: {} as any,
+ context: {},
+});
+
+describe("ChartCell sparkline rendering", () => {
+ it("draws every line series at 1px with dots disabled", () => {
+ const { container } = render();
+ const lines = container.querySelectorAll('[data-testid^="line-"]');
+ expect(lines.length).toBeGreaterThan(0);
+ lines.forEach((line) => {
+ expect(line.getAttribute("data-dot")).toBe("false");
+ expect(line.getAttribute("data-stroke-width")).toBe("1");
+ });
+ });
+
+ it("pads the y domain via a hidden axis so edge-hugging series are not clipped", () => {
+ const { getByTestId } = render();
+ const axis = getByTestId("yaxis-mock");
+ expect(axis.getAttribute("data-hide")).toBe("true");
+ expect(axis.getAttribute("data-padding-top")).toBe("2");
+ expect(axis.getAttribute("data-padding-bottom")).toBe("2");
+ });
+});
diff --git a/packages/buckaroo-js-core/src/components/DFViewerParts/HistogramCell.colors.test.tsx b/packages/buckaroo-js-core/src/components/DFViewerParts/HistogramCell.colors.test.tsx
new file mode 100644
index 000000000..a367434f7
--- /dev/null
+++ b/packages/buckaroo-js-core/src/components/DFViewerParts/HistogramCell.colors.test.tsx
@@ -0,0 +1,79 @@
+/**
+ * Per-bar color support on the histogram cell: a HistogramBar may carry
+ * `color`, and the population Bar renders one recharts Cell per datum so
+ * the color lands on that individual bar. Diff views use this to paint the
+ * change-distribution histogram with the same color key as the data cells;
+ * bars without a color keep the scheme default.
+ */
+// jsdom's `crypto` lacks `randomUUID`; HistogramCell's gensym() uses it.
+{
+ let n = 0;
+ const existing: any = (globalThis as any).crypto || {};
+ if (typeof existing.randomUUID !== "function") {
+ try {
+ Object.defineProperty(existing, "randomUUID", {
+ configurable: true,
+ value: () => `test-uuid-${++n}`,
+ });
+ } catch {
+ Object.defineProperty(globalThis, "crypto", {
+ configurable: true,
+ value: { ...existing, randomUUID: () => `test-uuid-${++n}` },
+ });
+ }
+ }
+}
+
+// ts-jest in this repo doesn't apply esModuleInterop, so the default import
+// `import React from "react"` in HistogramCell.tsx resolves to `undefined`
+// at runtime without a `.default` on the mock.
+jest.mock("react", () => {
+ const actual = jest.requireActual("react");
+ return { __esModule: true, default: actual, ...actual };
+});
+
+import { render } from "@testing-library/react";
+import type { ColDef, Column, Context, GridApi } from "ag-grid-community";
+import { HistogramCell } from "./HistogramCell";
+
+// recharts pulls in DOM-measurement code that doesn't run cleanly under
+// jsdom — stub the exports HistogramCell touches, keeping Bar/Cell props
+// inspectable in the rendered tree.
+jest.mock("recharts", () => {
+ const React = require("react");
+ return {
+ Bar: ({ children, dataKey }: any) =>
+ React.createElement("div", { "data-testid": `bar-${dataKey}` }, children),
+ BarChart: ({ children }: any) =>
+ React.createElement("div", { "data-testid": "barchart-mock" }, children),
+ Cell: ({ fill }: any) =>
+ React.createElement("div", { "data-testid": "cell-mock", "data-fill": fill }),
+ Tooltip: () => null,
+ };
+});
+
+const mkProps = (value: any) => ({
+ value,
+ api: {} as GridApi,
+ colDef: { cellClass: "" } as ColDef,
+ column: {} as Column,
+ context: {} as Context,
+});
+
+describe("HistogramCell per-bar colors", () => {
+ it("renders one Cell per datum on the population bar, honoring bar.color", () => {
+ const bars = [
+ { name: "<-50%", population: 20, color: "#d62728" },
+ { name: "~0%", population: 80 },
+ ];
+ const { getByTestId } = render();
+ const popBar = getByTestId("bar-population");
+ const cells = popBar.querySelectorAll('[data-testid="cell-mock"]');
+ expect(cells).toHaveLength(2);
+ expect(cells[0].getAttribute("data-fill")).toBe("#d62728");
+ // Uncolored bars keep the scheme default fill — set, and not the
+ // colored bar's value.
+ expect(cells[1].getAttribute("data-fill")).toBeTruthy();
+ expect(cells[1].getAttribute("data-fill")).not.toBe("#d62728");
+ });
+});
diff --git a/tests/unit/compare_test.py b/tests/unit/compare_test.py
index 33d6136bd..e912e060b 100644
--- a/tests/unit/compare_test.py
+++ b/tests/unit/compare_test.py
@@ -464,3 +464,20 @@ def test_merge_column_in_input_rejected():
with pytest.raises(ValueError, match="__buckaroo_merge"):
col_join_dfs(df1, df2, join_columns=["id"], how="outer")
+
+
+def test_join_key_columns_use_color_static():
+ """Join-key columns get the constant color_static rule.
+
+ The categorical-map-of-identical-colors workaround predates color_static
+ landing in the compiled JS; the overrides should now emit the rule
+ directly so the Python types and the wire config say what they mean.
+ """
+ df1 = pd.DataFrame({"id": [1, 2, 3], "val": [10, 20, 30]})
+ df2 = pd.DataFrame({"id": [1, 2, 3], "val": [10, 25, 30]})
+
+ _m_df, overrides, _eqs = col_join_dfs(df1, df2, join_columns=["id"], how="outer")
+
+ cfg = overrides["id"]["color_map_config"]
+ assert cfg["color_rule"] == "color_static"
+ assert cfg["color"]