diff --git a/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.test.tsx b/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.test.tsx
index 5cded9e4a..6a0ead5b0 100644
--- a/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.test.tsx
+++ b/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.test.tsx
@@ -344,3 +344,29 @@ describe("FlatColorGradingSection — Vignette and Grain", () => {
act(() => root.unmount());
});
});
+
+describe("FlatColorGradingSection — Effects", () => {
+ it("renders Blur and Pixelate sliders under an Effects micro-label", () => {
+ const { host, root } = renderInto();
+ expect(host.textContent).toContain("Effects");
+ const rows = host.querySelectorAll('[data-flat-grade-effect="true"]');
+ expect(rows).toHaveLength(2);
+ act(() => root.unmount());
+ });
+
+ it("commits a dragged Pixelate value on slider track pointerdown, scaled from percent to the 0..1 effect range", () => {
+ const onCommitColorGrading = vi.fn();
+ const { host, root } = renderInto(
+ ,
+ );
+ const pixelateRow = findRowByText(host, '[data-flat-grade-effect="true"]', "Pixelate");
+ // min=0, max=100, step=1, ratio=0.75 -> raw=75 -> commit(75) -> effects.pixelate = 75/100 = 0.75
+ dragSliderTrack(pixelateRow, 75, 100);
+ expect(onCommitColorGrading).toHaveBeenCalledTimes(1);
+ expect(onCommitColorGrading.mock.calls[0][0].effects.pixelate).toBe(0.75);
+ act(() => root.unmount());
+ });
+});
diff --git a/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.tsx b/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.tsx
index fc817c258..b325ae590 100644
--- a/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.tsx
+++ b/packages/studio/src/components/editor/propertyPanelFlatColorGradingSection.tsx
@@ -5,6 +5,7 @@ import {
normalizeHfColorGrading,
type HfColorGradingAdjustKey,
type HfColorGradingDetailKey,
+ type HfColorGradingEffectKey,
type NormalizedHfColorGrading,
} from "@hyperframes/core/color-grading";
import { Compare, Plus, RotateCcw, Settings } from "../../icons/SystemIcons";
@@ -132,6 +133,11 @@ const VIGNETTE_TUNE_KEYS: HfColorGradingDetailKey[] = [
];
const GRAIN_TUNE_KEYS: HfColorGradingDetailKey[] = ["grainSize", "grainRoughness"];
+const EFFECT_SLIDERS: Array<{ key: HfColorGradingEffectKey; label: string }> = [
+ { key: "blur", label: "Blur" },
+ { key: "pixelate", label: "Pixelate" },
+];
+
// fallow-ignore-next-line complexity
export function FlatColorGradingSection({
grading,
@@ -384,6 +390,40 @@ export function FlatColorGradingSection({
)}
+
+
+
+ Effects
+
+ {EFFECT_SLIDERS.map((slider) => {
+ const value = grading.effects[slider.key];
+ const isSet = value > 1e-6;
+ return (
+
+
+ onCommitColorGrading({
+ ...grading,
+ effects: { ...grading.effects, [slider.key]: next / 100 },
+ })
+ }
+ onReset={() =>
+ onCommitColorGrading({
+ ...grading,
+ effects: { ...grading.effects, [slider.key]: 0 },
+ })
+ }
+ />
+
+ );
+ })}
+
);
}