diff --git a/resources/js/wysiwyg/services/keyboard-handling.ts b/resources/js/wysiwyg/services/keyboard-handling.ts
index 6a1345fac..08eed7645 100644
--- a/resources/js/wysiwyg/services/keyboard-handling.ts
+++ b/resources/js/wysiwyg/services/keyboard-handling.ts
@@ -3,7 +3,7 @@ import {
     $createParagraphNode,
     $getSelection,
     $isDecoratorNode,
-    COMMAND_PRIORITY_LOW,
+    COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND,
     KEY_BACKSPACE_COMMAND,
     KEY_DELETE_COMMAND,
     KEY_ENTER_COMMAND, KEY_TAB_COMMAND,
@@ -13,9 +13,10 @@ import {
 import {$isImageNode} from "@lexical/rich-text/LexicalImageNode";
 import {$isMediaNode} from "@lexical/rich-text/LexicalMediaNode";
 import {getLastSelection} from "../utils/selection";
-import {$getNearestNodeBlockParent} from "../utils/nodes";
+import {$getNearestNodeBlockParent, $getParentOfType} from "../utils/nodes";
 import {$setInsetForSelection} from "../utils/lists";
 import {$isListItemNode} from "@lexical/list";
+import {$isDetailsNode, DetailsNode} from "@lexical/rich-text/LexicalDetailsNode";
 
 function isSingleSelectedNode(nodes: LexicalNode[]): boolean {
     if (nodes.length === 1) {
@@ -28,6 +29,10 @@ function isSingleSelectedNode(nodes: LexicalNode[]): boolean {
     return false;
 }
 
+/**
+ * Delete the current node in the selection if the selection contains a single
+ * selected node (like image, media etc...).
+ */
 function deleteSingleSelectedNode(editor: LexicalEditor) {
     const selectionNodes = getLastSelection(editor)?.getNodes() || [];
     if (isSingleSelectedNode(selectionNodes)) {
@@ -37,6 +42,10 @@ function deleteSingleSelectedNode(editor: LexicalEditor) {
     }
 }
 
+/**
+ * Insert a new empty node after the selection if the selection contains a single
+ * selected node (like image, media etc...).
+ */
 function insertAfterSingleSelectedNode(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
     const selectionNodes = getLastSelection(editor)?.getNodes() || [];
     if (isSingleSelectedNode(selectionNodes)) {
@@ -58,6 +67,94 @@ function insertAfterSingleSelectedNode(editor: LexicalEditor, event: KeyboardEve
     return false;
 }
 
+/**
+ * Insert a new node after a details node, if inside a details node that's
+ * the last element, and if the cursor is at the last block within the details node.
+ */
+function insertAfterDetails(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
+    const scenario = getDetailsScenario(editor);
+    if (scenario === null || scenario.detailsSibling) {
+        return false;
+    }
+
+    editor.update(() => {
+        const newParagraph = $createParagraphNode();
+        scenario.parentDetails.insertAfter(newParagraph);
+        newParagraph.select();
+    });
+    event?.preventDefault();
+
+    return true;
+}
+
+/**
+ * If within a details block, move after it, creating a new node if required, if we're on
+ * the last empty block element within the details node.
+ */
+function moveAfterDetailsOnEmptyLine(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
+    const scenario = getDetailsScenario(editor);
+    if (scenario === null) {
+        return false;
+    }
+
+    if (scenario.parentBlock.getTextContent() !== '') {
+        return false;
+    }
+
+    event?.preventDefault()
+
+    const nextSibling = scenario.parentDetails.getNextSibling();
+    editor.update(() => {
+        if (nextSibling) {
+            nextSibling.selectStart();
+        } else {
+            const newParagraph = $createParagraphNode();
+            scenario.parentDetails.insertAfter(newParagraph);
+            newParagraph.select();
+        }
+        scenario.parentBlock.remove();
+    });
+
+    return true;
+}
+
+/**
+ * Get the common nodes used for a details node scenario, relative to current selection.
+ * Returns null if not found, or if the parent block is not the last in the parent details node.
+ */
+function getDetailsScenario(editor: LexicalEditor): {
+    parentDetails: DetailsNode;
+    parentBlock: LexicalNode;
+    detailsSibling: LexicalNode | null
+} | null {
+    const selection = getLastSelection(editor);
+    const firstNode = selection?.getNodes()[0];
+    if (!firstNode) {
+        return null;
+    }
+
+    const block = $getNearestNodeBlockParent(firstNode);
+    const details = $getParentOfType(firstNode, $isDetailsNode);
+    if (!$isDetailsNode(details) || block === null) {
+        return null;
+    }
+
+    if (block.getKey() !== details.getLastChild()?.getKey()) {
+        return null;
+    }
+
+    const nextSibling = details.getNextSibling();
+    return {
+        parentDetails: details,
+        parentBlock: block,
+        detailsSibling: nextSibling,
+    }
+}
+
+/**
+ * Inset the nodes within selection when a range of nodes is selected
+ * or if a list node is selected.
+ */
 function handleInsetOnTab(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
     const change = event?.shiftKey ? -40 : 40;
     const selection = $getSelection();
@@ -85,17 +182,23 @@ export function registerKeyboardHandling(context: EditorUiContext): () => void {
     }, COMMAND_PRIORITY_LOW);
 
     const unregisterEnter = context.editor.registerCommand(KEY_ENTER_COMMAND, (event): boolean => {
-        return insertAfterSingleSelectedNode(context.editor, event);
+        return insertAfterSingleSelectedNode(context.editor, event)
+            || moveAfterDetailsOnEmptyLine(context.editor, event);
     }, COMMAND_PRIORITY_LOW);
 
     const unregisterTab = context.editor.registerCommand(KEY_TAB_COMMAND, (event): boolean => {
         return handleInsetOnTab(context.editor, event);
     }, COMMAND_PRIORITY_LOW);
 
+    const unregisterDown = context.editor.registerCommand(KEY_ARROW_DOWN_COMMAND, (event): boolean => {
+        return insertAfterDetails(context.editor, event);
+    }, COMMAND_PRIORITY_LOW);
+
     return () => {
         unregisterBackspace();
         unregisterDelete();
         unregisterEnter();
         unregisterTab();
+        unregisterDown();
     };
 }
\ No newline at end of file