diff --git a/.changeset/fn-6985-automations-spacing.md b/.changeset/fn-6985-automations-spacing.md
new file mode 100644
index 0000000000..b040367e20
--- /dev/null
+++ b/.changeset/fn-6985-automations-spacing.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": patch
+---
+
+summary: Fix excessive spacing in the embedded Automations pane.
+category: fix
+dev: Top-pack embedded Automations grid rows and add regression coverage for the list/detail layout.
diff --git a/packages/dashboard/app/components/ScriptsModal.css b/packages/dashboard/app/components/ScriptsModal.css
index b74d8270ea..12873c1a77 100644
--- a/packages/dashboard/app/components/ScriptsModal.css
+++ b/packages/dashboard/app/components/ScriptsModal.css
@@ -1278,15 +1278,27 @@ With the header now edge-to-edge and dividerless, the first body row still needs
padding-left: 0;
}
-/* Two-pane body: single column by default (narrow); two columns when the container is wide enough. */
+/*
+FNXC:Automations 2026-06-24-23:30:
+The embedded single-column Automations list/detail grid must not stretch implicit rows to fill the pane; stretch pushes the selected detail card far below the list row on tall/narrow surfaces. Keep rows content-sized and top-aligned so toolbar, list, and detail stay packed while the wide breakpoint only changes the column template.
+*/
.automations-two-pane {
display: grid;
grid-template-columns: 1fr;
+ grid-auto-rows: max-content;
+ align-content: start;
+ align-items: start;
gap: var(--space-lg);
min-height: 0;
flex: 1;
}
+@media (max-width: 768px) {
+ .automations-two-pane {
+ grid-template-columns: 1fr;
+ }
+}
+
.automations-single-pane {
min-height: 0;
flex: 1;
diff --git a/packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx b/packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx
index 8d2952e741..a3248da83b 100644
--- a/packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx
+++ b/packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx
@@ -392,6 +392,58 @@ describe("ScheduledTasksModal", () => {
expect(screen.queryByRole("button", { name: "Close" })).toBeNull();
});
+ it("packs populated list and selected detail panes in the embedded list/detail structure", async () => {
+ mockFetchRoutines.mockResolvedValue([
+ makeRoutine({ id: "routine-backup", name: "Database Backup", command: "fn backup --create" }),
+ makeRoutine({ id: "routine-disabled", name: "Disabled Import", command: "fn import", enabled: false }),
+ ]);
+
+ const { container } = render(
+ ,
+ );
+
+ await waitFor(() => {
+ expect(screen.getByRole("option", { name: /database backup/i })).toBeDefined();
+ });
+
+ const twoPane = container.querySelector(".automations-two-pane");
+ const listPane = container.querySelector(".automations-list-pane");
+ const detailPane = container.querySelector(".automations-detail-pane");
+ expect(twoPane).not.toBeNull();
+ expect(listPane).not.toBeNull();
+ expect(detailPane).not.toBeNull();
+ expect(twoPane?.children[0]).toBe(listPane);
+ expect(twoPane?.children[1]).toBe(detailPane);
+ expect(screen.getByText("Select an automation")).toBeDefined();
+ expect(screen.getByText("Disabled")).toBeDefined();
+
+ fireEvent.click(screen.getByRole("option", { name: /database backup/i }));
+
+ await waitFor(() => {
+ expect(detailPane?.querySelector(".routine-card .routine-card-name")?.textContent).toBe("Database Backup");
+ });
+ expect(screen.getByText("fn backup --create")).toBeDefined();
+ expect(container.querySelector(".automations-single-pane")).toBeNull();
+ });
+
+ it("keeps embedded automation grid rows top-packed while preserving wide two-pane rules", () => {
+ const source = readFileSync(resolve(__dirname, "../ScriptsModal.css"), "utf8");
+ const baseRule = source.match(/\.automations-two-pane\s*\{[^}]*\}/)?.[0] ?? "";
+ const containerRule = source.match(/@container \(min-width: 900px\)\s*\{\s*\.automations-two-pane\s*\{[^}]*\}/)?.[0] ?? "";
+ const mediaRule = source.match(/@media \(min-width: 900px\)\s*\{\s*\.automations-two-pane\s*\{[^}]*\}/)?.[0] ?? "";
+ const mobileRule = source.match(/@media \(max-width: 768px\)\s*\{[\s\S]*?\.automations-two-pane\s*\{[^}]*\}/)?.[0] ?? "";
+
+ expect(baseRule).toContain("grid-template-columns: 1fr;");
+ expect(baseRule).toContain("align-content: start;");
+ expect(baseRule).toContain("align-items: start;");
+ expect(baseRule).toContain("grid-auto-rows: max-content;");
+ expect(containerRule).toContain("grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);");
+ expect(containerRule).toContain("align-items: start;");
+ expect(mediaRule).toContain("grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);");
+ expect(mediaRule).toContain("align-items: start;");
+ expect(mobileRule).toContain("grid-template-columns: 1fr;");
+ });
+
it("does not dismiss on Escape in embedded mode", async () => {
render();