diff --git a/public/assets/apps/board/main.js b/public/assets/apps/board/main.js
index 9b37651..99e15da 100644
--- a/public/assets/apps/board/main.js
+++ b/public/assets/apps/board/main.js
@@ -28,12 +28,15 @@ import { initFilters, toggleFilter as filtersToggle, normalizeFilterTags, sameSt
 import { initEditor, openItem as editorOpenItem, switchTab as editorSwitchTab, closeTab as editorCloseTab, closeAllTabs as editorCloseAllTabs, updateDraft as editorUpdateDraft, saveItem as editorSaveItem, collectItems as editorCollectItems, findItem as editorFindItem } from './modules/editor.js';
 import { initBoardStructure, createBoardAction, createWorkspace, renameWorkspace, deleteWorkspace, createColumn, renameColumn, createFolder, createColumnItem, renameList, toggleList, createItem, switchWorkspace, refreshBoardsList, replaceBoardQuery } from './modules/board-structure.js';
 import { initDnd, setupDragManager as dndSetupDragManager, teardownDnd as dndTeardown, moveItemWithKeyboard as dndMoveItemWithKeyboard, moveListWithKeyboard as dndMoveListWithKeyboard, moveColumnWithKeyboard as dndMoveColumnWithKeyboard, resetDndState as dndResetState } from './modules/dnd.js';
+import { initSelection } from './modules/selection.js';
+import { initMoveNode, moveNodeViaSelection } from './modules/move-node.js';
 import { initUiActions } from './modules/ui/actions.js';
 import { createImportExportController } from './modules/import-export.js';
 import { applyDebugFromUrl } from '../../packages/services/debug.js';
 import { requestJson, setCsrfProvider } from '../../packages/services/http.js';
 import { goToAuth } from '../../packages/services/navigation.js';
 import { initEditorModalManager } from './modules/ui/editor-modal-manager.js';
+import { initContextMenu, openContextMenu, closeContextMenu } from './modules/ui/context-menu.js';
 
 const app = document.getElementById('app');
 let commandBus = null;
@@ -180,6 +183,21 @@ async function init() {
     boardConfig: { open: false, activeTab: 'general', busy: false, error: null },
   });
 
+  initSelection({ app, store });
+  initMoveNode({
+    store,
+    sendCommand: (type, payload) => sendCommand(type, payload),
+  });
+  initContextMenu({
+    app,
+    onRequestClose: () => {},
+    onActionSelect: ({ action, nodeId }) => {
+      if (action === 'context-move-node') {
+        moveNodeViaSelection(nodeId);
+      }
+    },
+  });
+
   configureSlotRuntime({
     sendCommand: (type, payload) => sendCommand(type, payload),
     tags: () => {
@@ -263,6 +281,9 @@ async function init() {
     dndMoveItemWithKeyboard,
     dndMoveListWithKeyboard,
     dndMoveColumnWithKeyboard,
+    moveNodeViaSelection,
+    openContextMenu,
+    closeContextMenu,
     logout,
   });
   registerLifecycleGuards();
diff --git a/public/assets/apps/board/modules/dnd.js b/public/assets/apps/board/modules/dnd.js
index 33be211..f56ac63 100644
--- a/public/assets/apps/board/modules/dnd.js
+++ b/public/assets/apps/board/modules/dnd.js
@@ -2,6 +2,7 @@ import { createDragManager } from '../../../packages/ui/drag-manager.js';
 import { showToast } from '../../../packages/ui/toast.js';
 import { findListLocation, findColumn, findColumnLocation, isContainer } from './domain-utils.js';
 import { findItem as editorFindItem } from './editor.js';
+import { moveNode } from './move-node.js';
 
 let appRef = null;
 let storeRef = null;
@@ -116,14 +117,11 @@ export function moveItemWithKeyboard(itemId, delta) {
   }
 
   const position = targetIndex;
-  const promise = sendCommandRef('MoveNode', {
+  moveNode({
     nodeId: itemId,
     toParentId: list.id,
     toIndex: position,
   });
-  if (promise?.catch) {
-    promise.catch(console.error);
-  }
 }
 
 export function moveListWithKeyboard(listId, delta) {
@@ -172,14 +170,11 @@ export function moveListWithKeyboard(listId, delta) {
   }
 
   // V3: lists are nodes; move as node
-  const promise = sendCommandRef('MoveNode', {
+  moveNode({
     nodeId: listId,
     toParentId: location.columnId,
     toIndex: position,
   });
-  if (promise?.catch) {
-    promise.catch(console.error);
-  }
 }
 
 export function moveColumnWithKeyboard(columnId, delta) {
@@ -508,8 +503,7 @@ function handleItemDrop(data) {
   }
   const nodeId = data.nodeId || data.id;
   if (!nodeId) return;
-  const outcome = sendCommandRef('MoveNode', { nodeId, toParentId: dropIntent.toParentId, toIndex: dropIntent.toIndex });
-  handleCommandRejection(outcome, 'Déplacement impossible à cet emplacement');
+  moveNode({ nodeId, toParentId: dropIntent.toParentId, toIndex: dropIntent.toIndex });
 }
 
 function handleListDrop(data) {
@@ -551,12 +545,11 @@ function handleListDrop(data) {
     }
   }
 
-  const outcome = sendCommandRef('MoveNode', {
+  moveNode({
     nodeId,
     toParentId: dropIntent.toParentId,
     toIndex: dropIntent.position,
   });
-  handleCommandRejection(outcome, 'Déplacement impossible à cet emplacement');
 }
 
 function handleColumnDrop(data) {
diff --git a/public/assets/apps/board/modules/ui/actions.js b/public/assets/apps/board/modules/ui/actions.js
index 342eed8..8ae9c7b 100644
--- a/public/assets/apps/board/modules/ui/actions.js
+++ b/public/assets/apps/board/modules/ui/actions.js
@@ -50,6 +50,9 @@ export function initUiActions({
   dndMoveItemWithKeyboard,
   dndMoveListWithKeyboard,
   dndMoveColumnWithKeyboard,
+  moveNodeViaSelection,
+  openContextMenu,
+  closeContextMenu,
   logout,
 }) {
   if (!app) {
@@ -285,6 +288,10 @@ export function initUiActions({
       case 'filter-none':
         filtersToggle('__NONE__').catch(console.error);
         break;
+      case 'context-move-node':
+        closeContextMenu?.();
+        moveNodeViaSelection?.(actionEl.dataset.node);
+        break;
       default:
         break;
     }
@@ -338,6 +345,22 @@ export function initUiActions({
     }
   };
 
+  const handleContextMenu = (event) => {
+    if (!(event instanceof MouseEvent) || !openContextMenu) {
+      return;
+    }
+    let el = event.target instanceof Element ? event.target : (event.target?.parentNode ?? null);
+    while (el && !(el instanceof Element)) {
+      el = el.parentNode || null;
+    }
+    const nodeEl = el ? el.closest('[data-node]') : null;
+    if (!nodeEl) return;
+    const nodeId = nodeEl.dataset.node || nodeEl.dataset.id || '';
+    if (!nodeId) return;
+    event.preventDefault();
+    openContextMenu({ x: event.clientX, y: event.clientY, nodeId });
+  };
+
   const handleInput = (event) => {
     const target = event.target;
     if (!(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement)) {
@@ -567,6 +590,7 @@ export function initUiActions({
   app.addEventListener('input', handleInput);
   app.addEventListener('submit', handleSubmit);
   app.addEventListener('sb-modal-close', handleModalClose);
+  app.addEventListener('contextmenu', handleContextMenu);
   document.addEventListener('keydown', handleKeydown);
 
   return () => {
@@ -575,6 +599,7 @@ export function initUiActions({
     app.removeEventListener('input', handleInput);
     app.removeEventListener('submit', handleSubmit);
     app.removeEventListener('sb-modal-close', handleModalClose);
+    app.removeEventListener('contextmenu', handleContextMenu);
     document.removeEventListener('keydown', handleKeydown);
   };
 }
diff --git a/public/assets/apps/board/styles/board.css b/public/assets/apps/board/styles/board.css
index be5537f..e76b79c 100644
--- a/public/assets/apps/board/styles/board.css
+++ b/public/assets/apps/board/styles/board.css
@@ -1734,3 +1734,77 @@ textarea.note-editor {
   border-color: rgba(180, 83, 9, 0.6);
   background: rgba(245, 158, 11, 0.2);
 }
+
+/* Selection overlay (UiSelection) */
+[data-selection-active] {
+  cursor: crosshair;
+}
+.selection-overlay {
+  position: fixed;
+  inset: 0;
+  pointer-events: none;
+  z-index: 1300;
+}
+.selection-overlay__panel {
+  position: fixed;
+  top: 12px;
+  left: 50%;
+  transform: translateX(-50%);
+  background: #fff;
+  border: 1px solid #e3e5eb;
+  border-radius: 6px;
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
+  padding: 10px 14px;
+  font-size: 14px;
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  pointer-events: auto;
+}
+.selection-overlay__label {
+  font-weight: 600;
+  color: #1f2430;
+}
+.selection-overlay__cancel {
+  border: 1px solid #d3d6df;
+  background: #f7f9fc;
+  color: #1f2430;
+  border-radius: 4px;
+  padding: 6px 10px;
+  cursor: pointer;
+}
+.selection-overlay__cancel:hover {
+  border-color: #c4c8d2;
+}
+.selection-hover {
+  outline: 2px solid #3b82f6;
+  outline-offset: 2px;
+  background: rgba(59, 130, 246, 0.08);
+  border-radius: 8px;
+}
+
+/* Context menu (clic droit) */
+.board-context-menu {
+  position: fixed;
+  min-width: 180px;
+  background: #fff;
+  border: 1px solid #dfe3eb;
+  border-radius: 6px;
+  box-shadow: 0 10px 40px rgba(31, 36, 48, 0.18);
+  z-index: 1400;
+  padding: 6px 0;
+}
+.board-context-menu__group {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+.board-context-menu__item {
+  padding: 10px 14px;
+  cursor: pointer;
+  font-size: 14px;
+  color: #1f2430;
+}
+.board-context-menu__item:hover {
+  background: #eef2f8;
+}
