+ {shouldFloat ? (
+ // Floating mode: kanban at min width, preview overlays
+ <>
+
+
+
+
+ {/* Backdrop */}
+
+
+ {/* Floating Panel */}
+
+ {/* Resize handle on the left edge */}
+
+
+ {/* Panel content */}
+
+
+
+
+ >
+ ) : (
+ // Inline mode: side by side with custom resize
+
+ {/* Kanban Board */}
+
+
+
+
+ {/* Preview Panel */}
+ {isOpen && (
+
+ {/* Resize handle */}
+
+
+ {/* Panel content */}
+
+
+
+
+ )}
+
+ )}
+
+ );
+}
diff --git a/apps/web/components/task-preview-panel.tsx b/apps/web/components/task-preview-panel.tsx
new file mode 100644
index 0000000000..8c90383c04
--- /dev/null
+++ b/apps/web/components/task-preview-panel.tsx
@@ -0,0 +1,155 @@
+"use client";
+
+import { IconX, IconCircleCheck, IconCircleX, IconLoader2, IconAlertTriangle, IconArrowsMaximize } from "@tabler/icons-react";
+import { Button } from "@kandev/ui/button";
+import { Badge } from "@kandev/ui/badge";
+import { getRepositoryDisplayName } from "@/lib/utils";
+import type { Task } from "./kanban-card";
+
+interface TaskPreviewPanelProps {
+ task: Task | null;
+ onClose: () => void;
+ onMaximize?: (task: Task) => void;
+}
+
+function getStateDisplay(state?: string) {
+ switch (state) {
+ case "IN_PROGRESS":
+ case "SCHEDULING":
+ return {
+ label: state === "SCHEDULING" ? "Scheduling" : "In Progress",
+ icon: