diff --git a/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.test.tsx b/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.test.tsx
new file mode 100644
index 000000000..adfb8c40a
--- /dev/null
+++ b/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.test.tsx
@@ -0,0 +1,73 @@
+// @vitest-environment happy-dom
+
+import React, { act } from "react";
+import { createRoot } from "react-dom/client";
+import { afterEach, describe, expect, it, vi } from "vitest";
+import { FlatColorGradingAccessory } from "./propertyPanelFlatColorGradingSection";
+import { normalizeHfColorGrading } from "@hyperframes/core/color-grading";
+
+(globalThis as unknown as { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
+
+afterEach(() => {
+ document.body.innerHTML = "";
+});
+
+function renderInto(node: React.ReactElement) {
+ const host = document.createElement("div");
+ document.body.append(host);
+ const root = createRoot(host);
+ act(() => {
+ root.render(node);
+ });
+ return { host, root };
+}
+
+function neutralGrading() {
+ const grading = normalizeHfColorGrading("neutral");
+ if (!grading) throw new Error("expected a neutral grading");
+ return grading;
+}
+
+describe("FlatColorGradingAccessory", () => {
+ it("shows a 5px status dot colored by runtime status, with the message as its title", () => {
+ const { host, root } = renderInto(
+ ,
+ );
+ const dot = host.querySelector('[data-flat-grade-status-dot="true"]');
+ expect(dot).not.toBeNull();
+ expect(dot?.getAttribute("title")).toBe("Shader active");
+ expect(dot?.className).toContain("bg-emerald-400");
+ act(() => root.unmount());
+ });
+
+ it("disables the compare hold button when grading is inactive, and fires resetGrading on click", () => {
+ const resetGrading = vi.fn();
+ const { host, root } = renderInto(
+ ,
+ );
+ const compareButton = host.querySelector(
+ '[aria-label="Hold to show original"]',
+ );
+ expect(compareButton?.disabled).toBe(true);
+ const resetButton = host.querySelector('[data-flat-grade-reset="true"]');
+ act(() => resetButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })));
+ expect(resetGrading).toHaveBeenCalledTimes(1);
+ act(() => root.unmount());
+ });
+});
diff --git a/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.tsx b/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.tsx
new file mode 100644
index 000000000..2f9c6376d
--- /dev/null
+++ b/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.tsx
@@ -0,0 +1,68 @@
+import { isHfColorGradingActive } from "@hyperframes/core/color-grading";
+import { Compare, RotateCcw } from "../../icons/SystemIcons";
+import type { ColorGradingControllerState } from "./useColorGradingController";
+
+const STATUS_DOT_CLASS: Record = {
+ active: "bg-emerald-400",
+ pending: "bg-amber-300",
+ unavailable: "bg-red-400",
+ missing: "bg-panel-text-5",
+ inactive: "bg-panel-text-5",
+};
+
+export function FlatColorGradingAccessory({
+ state,
+}: {
+ state: Pick<
+ ColorGradingControllerState,
+ "grading" | "compareEnabled" | "runtimeStatus" | "commitCompare" | "resetGrading"
+ >;
+}) {
+ const { grading, compareEnabled, runtimeStatus, commitCompare, resetGrading } = state;
+ const gradingActive = isHfColorGradingActive(grading);
+
+ return (
+
+
+
+
+
+ );
+}