diff --git a/app/assets/javascripts/batch_comments/components/submit_dropdown.vue b/app/assets/javascripts/batch_comments/components/submit_dropdown.vue
index 9005c1b12209ce555d2bd8bb5671d407473337de..6aa5bb715b2095a0e06d8d5038bc27bc8b4f2eca 100644
--- a/app/assets/javascripts/batch_comments/components/submit_dropdown.vue
+++ b/app/assets/javascripts/batch_comments/components/submit_dropdown.vue
@@ -117,9 +117,7 @@ export default {
           {{ __('Summary comment (optional)') }}
         </template>
         <div class="common-note-form gfm-form">
-          <div
-            class="comment-warning-wrapper gl-border-solid gl-border-1 gl-rounded-base gl-border-gray-100"
-          >
+          <div class="comment-warning-wrapper-large gl-border-0 gl-bg-white">
             <markdown-field
               :is-submitting="isSubmitting"
               :add-spacing-classes="false"
diff --git a/app/assets/javascripts/behaviors/preview_markdown.js b/app/assets/javascripts/behaviors/preview_markdown.js
index dc408f5a950857e57da879a3101a40aa72f854f4..bcd92d090338a3b1ec04fd4fba6ab108fd6abfd9 100644
--- a/app/assets/javascripts/behaviors/preview_markdown.js
+++ b/app/assets/javascripts/behaviors/preview_markdown.js
@@ -121,9 +121,7 @@ MarkdownPreview.prototype.renderReferencedCommands = function (commands, $form)
 const markdownPreview = new MarkdownPreview();
 
 const previewButtonSelector = '.js-md-preview-button';
-const writeButtonSelector = '.js-md-write-button';
 lastTextareaPreviewed = null;
-const markdownToolbar = $('.md-header-toolbar');
 
 $(document).on('markdown-preview:show', (e, $form) => {
   if (!$form) {
@@ -134,13 +132,15 @@ $(document).on('markdown-preview:show', (e, $form) => {
   lastTextareaHeight = lastTextareaPreviewed.height();
 
   // toggle tabs
-  $form.find(writeButtonSelector).parent().removeClass('active');
-  $form.find(previewButtonSelector).parent().addClass('active');
+  $form.find(previewButtonSelector).val('edit');
+  $form.find(previewButtonSelector).children('span.gl-button-text').text(__('Continue editing'));
+  $form.find(previewButtonSelector).addClass('gl-shadow-none! gl-bg-transparent!');
 
   // toggle content
   $form.find('.md-write-holder').hide();
   $form.find('.md-preview-holder').show();
-  markdownToolbar.removeClass('active');
+  $form.find('.md-header-toolbar, .js-zen-enter').addClass('gl-display-none!');
+
   markdownPreview.showPreview($form);
 });
 
@@ -155,14 +155,14 @@ $(document).on('markdown-preview:hide', (e, $form) => {
   }
 
   // toggle tabs
-  $form.find(writeButtonSelector).parent().addClass('active');
-  $form.find(previewButtonSelector).parent().removeClass('active');
+  $form.find(previewButtonSelector).val('preview');
+  $form.find(previewButtonSelector).children('span.gl-button-text').text(__('Preview'));
 
   // toggle content
   $form.find('.md-write-holder').show();
   $form.find('textarea.markdown-area').focus();
   $form.find('.md-preview-holder').hide();
-  markdownToolbar.addClass('active');
+  $form.find('.md-header-toolbar, .js-zen-enter').removeClass('gl-display-none!');
 
   markdownPreview.hideReferencedCommands($form);
 });
@@ -183,13 +183,26 @@ $(document).on('markdown-preview:toggle', (e, keyboardEvent) => {
 $(document).on('click', previewButtonSelector, function (e) {
   e.preventDefault();
   const $form = $(this).closest('form');
-  $(document).triggerHandler('markdown-preview:show', [$form]);
+  const eventName = e.currentTarget.getAttribute('value') === 'preview' ? 'show' : 'hide';
+  $(document).triggerHandler(`markdown-preview:${eventName}`, [$form]);
+});
+
+$(document).on('mousedown', previewButtonSelector, function (e) {
+  e.preventDefault();
+  const $form = $(this).closest('form');
+  $form.find(previewButtonSelector).removeClass('gl-shadow-none! gl-bg-transparent!');
+});
+
+$(document).on('mouseenter', previewButtonSelector, function (e) {
+  e.preventDefault();
+  const $form = $(this).closest('form');
+  $form.find(previewButtonSelector).removeClass('gl-bg-transparent!');
 });
 
-$(document).on('click', writeButtonSelector, function (e) {
+$(document).on('mouseleave', previewButtonSelector, function (e) {
   e.preventDefault();
   const $form = $(this).closest('form');
-  $(document).triggerHandler('markdown-preview:hide', [$form]);
+  $form.find(previewButtonSelector).addClass('gl-bg-transparent!');
 });
 
 export default MarkdownPreview;
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
index 5c6e4665a5c1957d3f0c135b3cafd2517b0ec411..efb462f477805a32605779a09c34ae194c0c4053 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
@@ -186,13 +186,14 @@ export default class Shortcuts {
   }
 
   static toggleMarkdownPreview(e) {
-    // Check if short-cut was triggered while in Write Mode
-    const $target = $(e.target);
-    const $form = $target.closest('form');
+    const $form = $(e.target).closest('form');
+    const toggle = $('.js-md-preview-button', $form).get(0);
+
+    if (!toggle) return;
+
+    toggle.focus();
+    toggle.click();
 
-    if ($target.hasClass('js-note-text')) {
-      $('.js-md-preview-button', $form).focus();
-    }
     $(document).triggerHandler('markdown-preview:toggle', [e]);
   }
 
diff --git a/app/assets/javascripts/content_editor/components/content_editor.vue b/app/assets/javascripts/content_editor/components/content_editor.vue
index f9d48708473f67c3ce208e7c0f532079386e4b83..2b2c4a5ac1c334753756a4e0e18618518dfc4c24 100644
--- a/app/assets/javascripts/content_editor/components/content_editor.vue
+++ b/app/assets/javascripts/content_editor/components/content_editor.vue
@@ -3,7 +3,6 @@ import { EditorContent as TiptapEditorContent } from '@tiptap/vue-2';
 import { GlSprintf, GlLink } from '@gitlab/ui';
 import { __, s__ } from '~/locale';
 import { VARIANT_DANGER } from '~/alert';
-import EditorModeDropdown from '~/vue_shared/components/markdown/editor_mode_dropdown.vue';
 import { createContentEditor } from '../services/create_content_editor';
 import { ALERT_EVENT, TIPTAP_AUTOFOCUS_OPTIONS } from '../constants';
 import ContentEditorAlert from './content_editor_alert.vue';
@@ -30,7 +29,6 @@ export default {
     LinkBubbleMenu,
     MediaBubbleMenu,
     EditorStateObserver,
-    EditorModeDropdown,
   },
   props: {
     renderMarkdown: {
@@ -100,6 +98,11 @@ export default {
       latestMarkdown: null,
     };
   },
+  computed: {
+    showPlaceholder() {
+      return this.placeholder && !this.markdown && !this.focused;
+    },
+  },
   watch: {
     markdown(markdown) {
       if (markdown !== this.latestMarkdown) {
@@ -196,11 +199,6 @@ export default {
         markdown: this.latestMarkdown,
       });
     },
-    handleEditorModeChanged(mode) {
-      if (mode === 'markdown') {
-        this.$emit('enableMarkdownEditor');
-      }
-    },
   },
   i18n: {
     quickActionsText: s__(
@@ -226,34 +224,36 @@ export default {
         :class="{ 'is-focused': focused }"
       >
         <formatting-toolbar ref="toolbar" @enableMarkdownEditor="$emit('enableMarkdownEditor')" />
-        <div class="gl-relative gl-mt-4">
+        <div class="gl-relative">
           <formatting-bubble-menu />
           <code-block-bubble-menu />
           <link-bubble-menu />
           <media-bubble-menu />
-          <div v-if="placeholder && !markdown && !focused" class="gl-absolute gl-text-gray-400">
+          <div v-if="showPlaceholder" class="gl-absolute gl-text-gray-400 gl-px-5 gl-pt-4">
             {{ placeholder }}
           </div>
           <tiptap-editor-content
-            class="md"
+            class="md gl-px-5"
             data-testid="content_editor_editablebox"
             :editor="contentEditor.tiptapEditor"
           />
           <loading-indicator v-if="isLoading" />
-          <div class="gl-display-flex gl-border-t gl-py-2 gl-text-secondary">
-            <div class="gl-w-full">
-              <template v-if="quickActionsDocsPath">
-                <gl-sprintf :message="$options.i18n.quickActionsText">
-                  <template #keyboard="{ content }">
-                    <kbd>{{ content }}</kbd>
-                  </template>
-                  <template #quickActionsDocsLink="{ content }">
-                    <gl-link :href="quickActionsDocsPath" target="_blank">{{ content }}</gl-link>
-                  </template>
-                </gl-sprintf>
-              </template>
+          <div
+            v-if="quickActionsDocsPath"
+            class="gl-display-flex gl-align-items-center gl-rounded-bottom-left-base gl-rounded-bottom-right-base gl-px-4 gl-mx-2 gl-mb-2 gl-bg-gray-10 gl-text-secondary"
+          >
+            <div class="gl-w-full gl-line-height-32 gl-font-sm">
+              <gl-sprintf :message="$options.i18n.quickActionsText">
+                <template #keyboard="{ content }">
+                  <kbd>{{ content }}</kbd>
+                </template>
+                <template #quickActionsDocsLink="{ content }">
+                  <gl-link :href="quickActionsDocsPath" target="_blank" class="gl-font-sm">{{
+                    content
+                  }}</gl-link>
+                </template>
+              </gl-sprintf>
             </div>
-            <editor-mode-dropdown size="small" value="richText" @input="handleEditorModeChanged" />
           </div>
         </div>
       </div>
diff --git a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
index cd9fdeeca465b65ea0e3d472f5ae7989459c3d46..e7e520a55daf75f023437d1fc8ffa6dde76bb485 100644
--- a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
+++ b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
@@ -1,4 +1,5 @@
 <script>
+import EditorModeSwitcher from '~/vue_shared/components/markdown/editor_mode_switcher.vue';
 import trackUIControl from '../services/track_ui_control';
 import ToolbarButton from './toolbar_button.vue';
 import ToolbarAttachmentButton from './toolbar_attachment_button.vue';
@@ -13,94 +14,106 @@ export default {
     ToolbarTableButton,
     ToolbarAttachmentButton,
     ToolbarMoreDropdown,
+    EditorModeSwitcher,
   },
   methods: {
     trackToolbarControlExecution({ contentType, value }) {
       trackUIControl({ property: contentType, value });
     },
+    handleEditorModeChanged() {
+      this.$emit('enableMarkdownEditor');
+    },
   },
 };
 </script>
 <template>
-  <div
-    class="gl-w-full gl-border-b gl-display-flex gl-justify-content-end"
-    data-testid="formatting-toolbar"
-  >
-    <div class="gl-py-2 gl-display-flex gl-flex-wrap gl-align-items-end">
-      <toolbar-text-style-dropdown
-        data-testid="text-styles"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-button
-        data-testid="bold"
-        content-type="bold"
-        icon-name="bold"
-        editor-command="toggleBold"
-        :label="__('Bold text')"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-button
-        data-testid="italic"
-        content-type="italic"
-        icon-name="italic"
-        editor-command="toggleItalic"
-        :label="__('Italic text')"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-button
-        data-testid="blockquote"
-        content-type="blockquote"
-        icon-name="quote"
-        editor-command="toggleBlockquote"
-        :label="__('Insert a quote')"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-button
-        data-testid="code"
-        content-type="code"
-        icon-name="code"
-        editor-command="toggleCode"
-        :label="__('Code')"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-button
-        data-testid="link"
-        content-type="link"
-        icon-name="link"
-        editor-command="editLink"
-        :label="__('Insert link')"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-button
-        data-testid="bullet-list"
-        content-type="bulletList"
-        icon-name="list-bulleted"
-        class="gl-display-none gl-sm-display-inline"
-        editor-command="toggleBulletList"
-        :label="__('Add a bullet list')"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-button
-        data-testid="ordered-list"
-        content-type="orderedList"
-        icon-name="list-numbered"
-        class="gl-display-none gl-sm-display-inline"
-        editor-command="toggleOrderedList"
-        :label="__('Add a numbered list')"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-button
-        data-testid="task-list"
-        content-type="taskList"
-        icon-name="list-task"
-        class="gl-display-none gl-sm-display-inline"
-        editor-command="toggleTaskList"
-        :label="__('Add a checklist')"
-        @execute="trackToolbarControlExecution"
-      />
-      <toolbar-table-button data-testid="table" @execute="trackToolbarControlExecution" />
-      <toolbar-attachment-button data-testid="attachment" @execute="trackToolbarControlExecution" />
-      <toolbar-more-dropdown data-testid="more" @execute="trackToolbarControlExecution" />
+  <div class="gl-mx-2 gl-mt-2">
+    <div
+      class="gl-w-full gl-display-flex gl-align-items-center gl-flex-wrap gl-bg-gray-50 gl-px-2 gl-rounded-base gl-justify-content-space-between"
+      data-testid="formatting-toolbar"
+    >
+      <div class="gl-py-2 gl-display-flex gl-flex-wrap-wrap">
+        <toolbar-text-style-dropdown
+          data-testid="text-styles"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-button
+          data-testid="bold"
+          content-type="bold"
+          icon-name="bold"
+          editor-command="toggleBold"
+          :label="__('Bold text')"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-button
+          data-testid="italic"
+          content-type="italic"
+          icon-name="italic"
+          editor-command="toggleItalic"
+          :label="__('Italic text')"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-button
+          data-testid="blockquote"
+          content-type="blockquote"
+          icon-name="quote"
+          editor-command="toggleBlockquote"
+          :label="__('Insert a quote')"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-button
+          data-testid="code"
+          content-type="code"
+          icon-name="code"
+          editor-command="toggleCode"
+          :label="__('Code')"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-button
+          data-testid="link"
+          content-type="link"
+          icon-name="link"
+          editor-command="editLink"
+          :label="__('Insert link')"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-button
+          data-testid="bullet-list"
+          content-type="bulletList"
+          icon-name="list-bulleted"
+          class="gl-display-none gl-sm-display-inline"
+          editor-command="toggleBulletList"
+          :label="__('Add a bullet list')"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-button
+          data-testid="ordered-list"
+          content-type="orderedList"
+          icon-name="list-numbered"
+          class="gl-display-none gl-sm-display-inline"
+          editor-command="toggleOrderedList"
+          :label="__('Add a numbered list')"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-button
+          data-testid="task-list"
+          content-type="taskList"
+          icon-name="list-task"
+          class="gl-display-none gl-sm-display-inline"
+          editor-command="toggleTaskList"
+          :label="__('Add a checklist')"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-table-button data-testid="table" @execute="trackToolbarControlExecution" />
+        <toolbar-attachment-button
+          data-testid="attachment"
+          @execute="trackToolbarControlExecution"
+        />
+        <toolbar-more-dropdown data-testid="more" @execute="trackToolbarControlExecution" />
+      </div>
+      <div class="content-editor-switcher gl-display-flex gl-align-items-center gl-ml-auto">
+        <editor-mode-switcher size="small" value="richText" @input="handleEditorModeChanged" />
+      </div>
     </div>
   </div>
 </template>
diff --git a/app/assets/javascripts/content_editor/components/toolbar_attachment_button.vue b/app/assets/javascripts/content_editor/components/toolbar_attachment_button.vue
index efb9a5b07b542de0089f74d8b0ad4f8647d88e06..1f18090e7d74c0151abe61fcaf7eda83cba9e57c 100644
--- a/app/assets/javascripts/content_editor/components/toolbar_attachment_button.vue
+++ b/app/assets/javascripts/content_editor/components/toolbar_attachment_button.vue
@@ -46,6 +46,7 @@ export default {
       :title="__('Attach a file or image')"
       category="tertiary"
       icon="paperclip"
+      size="small"
       lazy
       @click="openFileUpload"
     />
diff --git a/app/assets/javascripts/content_editor/components/toolbar_button.vue b/app/assets/javascripts/content_editor/components/toolbar_button.vue
index cef026c5bc6dd5b25e643e85b42c3c7ce5384d71..1f3c7062b67665021462e56bc311af4107fe6e8f 100644
--- a/app/assets/javascripts/content_editor/components/toolbar_button.vue
+++ b/app/assets/javascripts/content_editor/components/toolbar_button.vue
@@ -47,7 +47,7 @@ export default {
     size: {
       type: String,
       required: false,
-      default: 'medium',
+      default: 'small',
     },
   },
   data() {
@@ -82,6 +82,7 @@ export default {
       :aria-label="label"
       :title="label"
       :icon="iconName"
+      class="gl-mr-3"
       @click="execute"
     />
   </editor-state-observer>
diff --git a/app/assets/javascripts/deprecated_notes.js b/app/assets/javascripts/deprecated_notes.js
index 537c810bcffddeffd79b2c0b4262655c66203f6e..a46a8d4affaca755f9d88b47ff610a41bbc16a8c 100644
--- a/app/assets/javascripts/deprecated_notes.js
+++ b/app/assets/javascripts/deprecated_notes.js
@@ -599,7 +599,10 @@ export default class Notes {
     // remove validation errors
     form.find('.js-errors').remove();
     // reset text and preview
-    form.find('.js-md-write-button').click();
+    if (form.find('.js-md-preview-button').val() === 'edit') {
+      form.find('.js-md-preview-button').click();
+    }
+
     form.find('.js-note-text').val('').trigger('input');
     form.find('.js-note-text').each(function reset() {
       this.$autosave.reset();
@@ -939,6 +942,7 @@ export default class Notes {
     const replyLink = $(target).closest('.js-discussion-reply-button');
     // insert the form after the button
     replyLink.closest('.discussion-reply-holder').hide().after(form);
+
     // show the form
     return this.setupDiscussionNoteForm(replyLink, form);
   }
@@ -1241,7 +1245,10 @@ export default class Notes {
     $editForm.find('.js-form-target-id').val(targetId);
     $editForm.find('.js-form-target-type').val(targetType);
     $editForm.find('.js-note-text').focus().val(originalContent);
-    $editForm.find('.js-md-write-button').trigger('click');
+    // reset preview
+    if ($editForm.find('.js-md-preview-button').val() === 'edit') {
+      $editForm.find('.js-md-preview-button').click();
+    }
     $editForm.find('.referenced-users').hide();
   }
 
diff --git a/app/assets/javascripts/notes/components/comment_field_layout.vue b/app/assets/javascripts/notes/components/comment_field_layout.vue
index 02d128eb119ee081432ab1442a5d741d54d96766..cfe4baaa1f93dc593b39be3e801eb3bb72ef2be3 100644
--- a/app/assets/javascripts/notes/components/comment_field_layout.vue
+++ b/app/assets/javascripts/notes/components/comment_field_layout.vue
@@ -67,7 +67,7 @@ export default {
 </script>
 <template>
   <div
-    class="comment-warning-wrapper gl-border-solid gl-border-1 gl-rounded-base gl-border-gray-100"
+    class="comment-warning-wrapper gl-border-solid gl-border-1 gl-rounded-lg gl-border-gray-100 gl-bg-white"
   >
     <div
       v-if="withAlertContainer"
diff --git a/app/assets/javascripts/notes/components/discussion_notes_replies_wrapper.vue b/app/assets/javascripts/notes/components/discussion_notes_replies_wrapper.vue
index 1dd07fe90d2b493563af8bbcdfaa220232289811..a0d2b47c89c4a7faa4c0c5049370ea636419a861 100644
--- a/app/assets/javascripts/notes/components/discussion_notes_replies_wrapper.vue
+++ b/app/assets/javascripts/notes/components/discussion_notes_replies_wrapper.vue
@@ -21,7 +21,7 @@ export default {
         'li',
         {
           class:
-            'discussion-collapsible gl-border-solid gl-border-gray-100 gl-border-1 gl-rounded-base clearfix',
+            'discussion-collapsible gl-border-solid gl-border-gray-100 gl-border-1 gl-rounded-base clearfix gl-pt-5',
         },
         [h('ul', { class: 'notes' }, children)],
       );
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index 3375e366ecf0be80d917dcdef0ebed6c54069e25..375b16f6ce2c52d89b3d24d5ae03c8825ed391cf 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -319,7 +319,7 @@ export default {
                 />
                 <li
                   v-else-if="canShowReplyActions && showReplies"
-                  :class="{ 'is-replying': isReplying }"
+                  :class="{ 'is-replying gl-bg-white! gl-pt-0!': isReplying }"
                   class="discussion-reply-holder gl-border-t-0! clearfix"
                 >
                   <discussion-actions
diff --git a/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue b/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue
index feee132629fdbf1a82c6138e42649dd9122ec811..1377a40fcf066d73ede9da9aa2b761c8c1e42669 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue
@@ -86,6 +86,7 @@ export default {
       category="tertiary"
       placement="right"
       searchable
+      size="small"
       class="comment-template-dropdown"
       :searching="$apollo.queries.savedReplies.loading"
       @shown="fetchCommentTemplates"
diff --git a/app/assets/javascripts/vue_shared/components/markdown/drawio_toolbar_button.vue b/app/assets/javascripts/vue_shared/components/markdown/drawio_toolbar_button.vue
index a66becb5c927eab99579f7a784768f2e9dcadbff..e88c7f75745628f4bd5c5c6176b1a1b499aeff59 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/drawio_toolbar_button.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/drawio_toolbar_button.vue
@@ -43,6 +43,7 @@ export default {
     :aria-label="__('Insert or edit diagram')"
     category="tertiary"
     icon="diagram"
+    size="small"
     @click="launchDrawioEditor"
   />
 </template>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/editor_mode_dropdown.vue b/app/assets/javascripts/vue_shared/components/markdown/editor_mode_dropdown.vue
deleted file mode 100644
index 7803d6f53e0aa793f34b57f1b97a386a425e6c7a..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/vue_shared/components/markdown/editor_mode_dropdown.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-<script>
-import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
-import { __ } from '~/locale';
-
-export default {
-  components: {
-    GlDropdown,
-    GlDropdownItem,
-  },
-  props: {
-    size: {
-      type: String,
-      required: false,
-      default: 'medium',
-    },
-    value: {
-      type: String,
-      required: true,
-    },
-  },
-  computed: {
-    markdownEditorSelected() {
-      return this.value === 'markdown';
-    },
-    text() {
-      return this.markdownEditorSelected ? __('Editing markdown') : __('Editing rich text');
-    },
-  },
-};
-</script>
-<template>
-  <gl-dropdown
-    category="tertiary"
-    data-qa-selector="editing_mode_switcher"
-    :size="size"
-    :text="text"
-    right
-  >
-    <gl-dropdown-item
-      is-check-item
-      :is-checked="!markdownEditorSelected"
-      @click="$emit('input', 'richText')"
-      ><div class="gl-font-weight-bold">{{ __('Rich text') }}</div>
-      <div class="gl-text-secondary">
-        {{ __('View the formatted output in real-time as you edit.') }}
-      </div>
-    </gl-dropdown-item>
-    <gl-dropdown-item
-      is-check-item
-      :is-checked="markdownEditorSelected"
-      @click="$emit('input', 'markdown')"
-      ><div class="gl-font-weight-bold">{{ __('Markdown') }}</div>
-      <div class="gl-text-secondary">
-        {{ __('View and edit markdown, with the option to preview the formatted output.') }}
-      </div></gl-dropdown-item
-    >
-  </gl-dropdown>
-</template>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue b/app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue
new file mode 100644
index 0000000000000000000000000000000000000000..645975ca565edbfb311cc975abcda74ca2c44c4e
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue
@@ -0,0 +1,32 @@
+<script>
+import { GlButton } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+export default {
+  components: {
+    GlButton,
+  },
+  props: {
+    value: {
+      type: String,
+      required: true,
+    },
+  },
+  computed: {
+    markdownEditorSelected() {
+      return this.value === 'markdown';
+    },
+    text() {
+      return this.markdownEditorSelected ? __('Switch to rich text') : __('Switch to Markdown');
+    },
+  },
+};
+</script>
+<template>
+  <gl-button
+    class="btn btn-default btn-sm gl-button btn-default-tertiary"
+    data-qa-selector="editing_mode_switcher"
+    @click="$emit('input')"
+    >{{ text }}</gl-button
+  >
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index cc1537477656a7e067948645211ac85409bb9b2d..3c4070105d1f742016a929dbbc8daed45ae188c5 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -1,5 +1,5 @@
 <script>
-import { GlIcon } from '@gitlab/ui';
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
 import $ from 'jquery';
 import { debounce, unescape } from 'lodash';
 import { createAlert } from '~/alert';
@@ -27,6 +27,7 @@ export default {
   },
   directives: {
     SafeHtml,
+    GlTooltip: GlTooltipDirective,
   },
   mixins: [glFeatureFlagsMixin()],
   props: {
@@ -245,7 +246,7 @@ export default {
       immediate: true,
       handler(newVal) {
         if (!newVal) {
-          this.showWriteTab();
+          this.hidePreview();
         }
       },
     },
@@ -277,7 +278,7 @@ export default {
     }
   },
   methods: {
-    showPreviewTab() {
+    showPreview() {
       if (this.previewMarkdown) return;
 
       this.previewMarkdown = true;
@@ -297,7 +298,7 @@ export default {
         this.renderMarkdown();
       }
     },
-    showWriteTab() {
+    hidePreview() {
       this.markdownPreview = '';
       this.previewMarkdown = false;
     },
@@ -365,9 +366,11 @@ export default {
       :drawio-enabled="drawioEnabled"
       data-testid="markdownHeader"
       :restricted-tool-bar-items="restrictedToolBarItems"
-      @preview-markdown="showPreviewTab"
-      @write-markdown="showWriteTab"
+      :show-content-editor-switcher="showContentEditorSwitcher"
+      @showPreview="showPreview"
+      @hidePreview="hidePreview"
       @handleSuggestDismissed="() => $emit('handleSuggestDismissed')"
+      @enableContentEditor="$emit('enableContentEditor')"
     />
     <div v-show="!previewMarkdown" class="md-write-holder">
       <div class="zen-backdrop">
@@ -384,8 +387,6 @@ export default {
           :quick-actions-docs-path="quickActionsDocsPath"
           :can-attach-file="canAttachFile"
           :show-comment-tool-bar="showCommentToolBar"
-          :show-content-editor-switcher="showContentEditorSwitcher"
-          @enableContentEditor="$emit('enableContentEditor')"
         />
       </div>
     </div>
@@ -393,7 +394,7 @@ export default {
       <div
         v-show="previewMarkdown"
         ref="markdown-preview"
-        class="js-vue-md-preview md-preview-holder"
+        class="js-vue-md-preview md-preview-holder gl-px-5"
       >
         <suggestions
           v-if="hasSuggestion"
@@ -410,13 +411,13 @@ export default {
         v-show="previewMarkdown"
         ref="markdown-preview"
         v-safe-html:[$options.safeHtmlConfig]="markdownPreview"
-        class="js-vue-md-preview md md-preview-holder"
+        class="js-vue-md-preview md md-preview-holder gl-px-5"
       ></div>
     </template>
     <div
       v-if="referencedCommands && previewMarkdown && !markdownPreviewLoading"
       v-safe-html:[$options.safeHtmlConfig]="referencedCommands"
-      class="referenced-commands gl-mx-n5"
+      class="referenced-commands gl-mx-2 gl-mb-2 gl-px-4 gl-rounded-bottom-left-base gl-rounded-bottom-right-base"
       data-testid="referenced-commands"
     ></div>
     <div v-if="shouldShowReferencedUsers" class="referenced-users">
diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue
index 53a3913ebda0d3887af127d495a83ef349023915..17d9a2daf0bfa14bf7f7a46c19eba168784a06db 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue
@@ -1,5 +1,5 @@
 <script>
-import { GlPopover, GlButton, GlTooltipDirective, GlTabs, GlTab } from '@gitlab/ui';
+import { GlPopover, GlButton, GlTooltipDirective } from '@gitlab/ui';
 import $ from 'jquery';
 import {
   keysFor,
@@ -19,17 +19,17 @@ import { updateText } from '~/lib/utils/text_markdown';
 import ToolbarButton from './toolbar_button.vue';
 import DrawioToolbarButton from './drawio_toolbar_button.vue';
 import CommentTemplatesDropdown from './comment_templates_dropdown.vue';
+import EditorModeSwitcher from './editor_mode_switcher.vue';
 
 export default {
   components: {
     ToolbarButton,
     GlPopover,
     GlButton,
-    GlTabs,
-    GlTab,
     DrawioToolbarButton,
     CommentTemplatesDropdown,
     AiActionsDropdown: () => import('ee_component/ai/components/ai_actions_dropdown.vue'),
+    EditorModeSwitcher,
   },
   directives: {
     GlTooltip: GlTooltipDirective,
@@ -91,6 +91,11 @@ export default {
       required: false,
       default: false,
     },
+    showContentEditorSwitcher: {
+      type: Boolean,
+      required: false,
+      default: false,
+    },
   },
   data() {
     return {
@@ -121,6 +126,9 @@ export default {
       const expandText = s__('MarkdownEditor|Click to expand');
       return [`<details><summary>${expandText}</summary>`, `{text}`, '</details>'].join('\n');
     },
+    showEditorModeSwitcher() {
+      return this.showContentEditorSwitcher && !this.previewMarkdown;
+    },
   },
   watch: {
     showSuggestPopover() {
@@ -128,14 +136,14 @@ export default {
     },
   },
   mounted() {
-    $(document).on('markdown-preview:show.vue', this.previewMarkdownTab);
-    $(document).on('markdown-preview:hide.vue', this.writeMarkdownTab);
+    $(document).on('markdown-preview:show.vue', this.showMarkdownPreview);
+    $(document).on('markdown-preview:hide.vue', this.hideMarkdownPreview);
 
     this.updateSuggestPopoverVisibility();
   },
   beforeDestroy() {
-    $(document).off('markdown-preview:show.vue', this.previewMarkdownTab);
-    $(document).off('markdown-preview:hide.vue', this.writeMarkdownTab);
+    $(document).off('markdown-preview:show.vue', this.showMarkdownPreview);
+    $(document).off('markdown-preview:hide.vue', this.hideMarkdownPreview);
   },
   methods: {
     async updateSuggestPopoverVisibility() {
@@ -149,19 +157,15 @@ export default {
         (form.find('.js-vue-markdown-field').length && $(this.$el).closest('form')[0] === form[0])
       );
     },
-
-    previewMarkdownTab(event, form) {
-      if (event.target.blur) event.target.blur();
+    showMarkdownPreview(_, form) {
       if (!this.isValid(form)) return;
 
-      this.$emit('preview-markdown');
+      this.$emit('showPreview');
     },
-
-    writeMarkdownTab(event, form) {
-      if (event.target.blur) event.target.blur();
+    hideMarkdownPreview(_, form) {
       if (!this.isValid(form)) return;
 
-      this.$emit('write-markdown');
+      this.$emit('hidePreview');
     },
     handleSuggestDismissed() {
       this.$emit('handleSuggestDismissed');
@@ -204,6 +208,16 @@ export default {
         });
       }
     },
+    handleEditorModeChanged() {
+      this.$emit('enableContentEditor');
+    },
+    switchPreview() {
+      if (this.previewMarkdown) {
+        this.hideMarkdownPreview();
+      } else {
+        this.showMarkdownPreview();
+      }
+    },
   },
   shortcuts: {
     bold: keysFor(BOLD_TEXT),
@@ -214,225 +228,240 @@ export default {
     outdent: keysFor(OUTDENT_LINE),
   },
   i18n: {
-    writeTabTitle: __('Write'),
-    previewTabTitle: __('Preview'),
+    preview: __('Preview'),
+    hidePreview: __('Continue editing'),
   },
 };
 </script>
 
 <template>
-  <div class="md-header">
-    <gl-tabs content-class="gl-display-none">
-      <gl-tab
-        title-link-class="gl-py-4 gl-px-3 js-md-write-button"
-        :title="$options.i18n.writeTabTitle"
-        :active="!previewMarkdown"
-        data-testid="write-tab"
-        @click="writeMarkdownTab($event)"
-      />
-      <gl-tab
-        v-if="enablePreview"
-        title-link-class="gl-py-4 gl-px-3 js-md-preview-button"
-        :title="$options.i18n.previewTabTitle"
-        :active="previewMarkdown"
-        data-testid="preview-tab"
-        @click="previewMarkdownTab($event)"
-      />
-
-      <template #tabs-end>
-        <div
-          data-testid="md-header-toolbar"
-          :class="{ 'gl-display-none!': previewMarkdown }"
-          class="md-header-toolbar gl-ml-auto gl-py-2 gl-justify-content-center"
-        >
-          <template v-if="canSuggest">
-            <toolbar-button
-              ref="suggestButton"
-              :tag="mdSuggestion"
-              :prepend="true"
-              :button-title="__('Insert suggestion')"
-              :cursor-offset="4"
-              :tag-content="lineContent"
-              icon="doc-code"
-              data-qa-selector="suggestion_button"
-              class="js-suggestion-btn"
-              @click="handleSuggestDismissed"
-            />
-            <gl-popover
-              v-if="suggestPopoverVisible"
-              :target="$refs.suggestButton.$el"
-              :css-classes="['diff-suggest-popover']"
-              placement="bottom"
-              :show="suggestPopoverVisible"
-            >
-              <strong>{{ __('New! Suggest changes directly') }}</strong>
-              <p class="mb-2">
-                {{
-                  __(
-                    'Suggest code changes which can be immediately applied in one click. Try it out!',
-                  )
-                }}
-              </p>
-              <gl-button
-                variant="confirm"
-                category="primary"
-                size="small"
-                data-qa-selector="dismiss_suggestion_popover_button"
-                @click="handleSuggestDismissed"
-              >
-                {{ __('Got it') }}
-              </gl-button>
-            </gl-popover>
-          </template>
-          <ai-actions-dropdown
-            v-if="editorAiActions.length"
-            :actions="editorAiActions"
-            @input="insertIntoTextarea"
-          />
-          <toolbar-button
-            tag="**"
-            :button-title="
-              /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
-              sprintf(s__('MarkdownEditor|Add bold text (%{modifierKey}B)'), {
-                modifierKey,
-              }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */
-            "
-            :shortcuts="$options.shortcuts.bold"
-            icon="bold"
-          />
-          <toolbar-button
-            tag="_"
-            :button-title="
-              /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
-              sprintf(s__('MarkdownEditor|Add italic text (%{modifierKey}I)'), {
-                modifierKey,
-              }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */
-            "
-            :shortcuts="$options.shortcuts.italic"
-            icon="italic"
-          />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('strikethrough')"
-            tag="~~"
-            :button-title="
-              /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
-              sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)'), {
-                modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */,
-              })
-            "
-            :shortcuts="$options.shortcuts.strikethrough"
-            icon="strikethrough"
-          />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('quote')"
-            :prepend="true"
-            :tag="tag"
-            :button-title="__('Insert a quote')"
-            icon="quote"
-            @click="handleQuote"
-          />
-          <toolbar-button tag="`" tag-block="```" :button-title="__('Insert code')" icon="code" />
-          <toolbar-button
-            tag="[{text}](url)"
-            tag-select="url"
-            :button-title="
-              /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
-              sprintf(s__('MarkdownEditor|Add a link (%{modifierKey}K)'), {
-                modifierKey,
-              }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */
-            "
-            :shortcuts="$options.shortcuts.link"
-            icon="link"
-          />
+  <div class="md-header gl-bg-gray-50 gl-px-2 gl-rounded-base gl-mx-2 gl-mt-2">
+    <div
+      class="gl-display-flex gl-align-items-center gl-flex-wrap"
+      :class="{
+        'gl-justify-content-end': previewMarkdown,
+        'gl-justify-content-space-between': !previewMarkdown,
+      }"
+    >
+      <div
+        data-testid="md-header-toolbar"
+        class="md-header-toolbar gl-display-flex gl-py-2 gl-flex-wrap"
+        :class="{ 'gl-display-none!': previewMarkdown }"
+      >
+        <template v-if="canSuggest">
           <toolbar-button
-            v-if="!restrictedToolBarItems.includes('bullet-list')"
+            ref="suggestButton"
+            :tag="mdSuggestion"
             :prepend="true"
-            tag="- "
-            :button-title="__('Add a bullet list')"
-            icon="list-bulleted"
+            :button-title="__('Insert suggestion')"
+            :cursor-offset="4"
+            :tag-content="lineContent"
+            icon="doc-code"
+            data-qa-selector="suggestion_button"
+            class="js-suggestion-btn"
+            @click="handleSuggestDismissed"
           />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('numbered-list')"
-            :prepend="true"
-            tag="1. "
-            :button-title="__('Add a numbered list')"
-            icon="list-numbered"
-          />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('task-list')"
-            :prepend="true"
-            tag="- [ ] "
-            :button-title="__('Add a checklist')"
-            icon="list-task"
-          />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('indent')"
-            class="gl-display-none"
-            :button-title="
-              /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
-              sprintf(s__('MarkdownEditor|Indent line (%{modifierKey}])'), {
-                modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */,
-              })
-            "
-            :shortcuts="$options.shortcuts.indent"
-            command="indentLines"
-            icon="list-indent"
-          />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('outdent')"
-            class="gl-display-none"
-            :button-title="
-              /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
-              sprintf(s__('MarkdownEditor|Outdent line (%{modifierKey}[)'), {
-                modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */,
-              })
-            "
-            :shortcuts="$options.shortcuts.outdent"
-            command="outdentLines"
-            icon="list-outdent"
-          />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('collapsible-section')"
-            :tag="mdCollapsibleSection"
-            :prepend="true"
-            tag-select="Click to expand"
-            :button-title="__('Add a collapsible section')"
-            icon="details-block"
-          />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('table')"
-            :tag="mdTable"
-            :prepend="true"
-            :button-title="__('Add a table')"
-            icon="table"
-          />
-          <gl-button
-            v-if="!restrictedToolBarItems.includes('attach-file')"
-            v-gl-tooltip
-            :title="__('Attach a file or image')"
-            data-testid="button-attach-file"
-            category="tertiary"
-            icon="paperclip"
-            @click="handleAttachFile"
-          />
-          <drawio-toolbar-button
-            v-if="drawioEnabled"
-            :uploads-path="uploadsPath"
-            :markdown-preview-path="markdownPreviewPath"
-          />
-          <comment-templates-dropdown
-            v-if="newCommentTemplatePath && glFeatures.savedReplies"
-            :new-comment-template-path="newCommentTemplatePath"
-          />
-          <toolbar-button
-            v-if="!restrictedToolBarItems.includes('full-screen')"
-            class="js-zen-enter"
-            :prepend="true"
-            :button-title="__('Go full screen')"
-            icon="maximize"
-          />
-        </div>
-      </template>
-    </gl-tabs>
+          <gl-popover
+            v-if="suggestPopoverVisible"
+            :target="$refs.suggestButton.$el"
+            :css-classes="['diff-suggest-popover']"
+            placement="bottom"
+            :show="suggestPopoverVisible"
+          >
+            <strong>{{ __('New! Suggest changes directly') }}</strong>
+            <p class="mb-2">
+              {{
+                __(
+                  'Suggest code changes which can be immediately applied in one click. Try it out!',
+                )
+              }}
+            </p>
+            <gl-button
+              variant="confirm"
+              category="primary"
+              size="small"
+              data-qa-selector="dismiss_suggestion_popover_button"
+              @click="handleSuggestDismissed"
+            >
+              {{ __('Got it') }}
+            </gl-button>
+          </gl-popover>
+        </template>
+        <ai-actions-dropdown
+          v-if="editorAiActions.length"
+          :actions="editorAiActions"
+          @input="insertIntoTextarea"
+        />
+        <toolbar-button
+          tag="**"
+          :button-title="
+            /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
+            sprintf(s__('MarkdownEditor|Add bold text (%{modifierKey}B)'), {
+              modifierKey,
+            }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */
+          "
+          :shortcuts="$options.shortcuts.bold"
+          icon="bold"
+        />
+        <toolbar-button
+          tag="_"
+          :button-title="
+            /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
+            sprintf(s__('MarkdownEditor|Add italic text (%{modifierKey}I)'), {
+              modifierKey,
+            }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */
+          "
+          :shortcuts="$options.shortcuts.italic"
+          icon="italic"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('strikethrough')"
+          tag="~~"
+          :button-title="
+            /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
+            sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)'), {
+              modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */,
+            })
+          "
+          :shortcuts="$options.shortcuts.strikethrough"
+          icon="strikethrough"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('quote')"
+          :prepend="true"
+          :tag="tag"
+          :button-title="__('Insert a quote')"
+          icon="quote"
+          @click="handleQuote"
+        />
+        <toolbar-button tag="`" tag-block="```" :button-title="__('Insert code')" icon="code" />
+        <toolbar-button
+          tag="[{text}](url)"
+          tag-select="url"
+          :button-title="
+            /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
+            sprintf(s__('MarkdownEditor|Add a link (%{modifierKey}K)'), {
+              modifierKey,
+            }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */
+          "
+          :shortcuts="$options.shortcuts.link"
+          icon="link"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('bullet-list')"
+          :prepend="true"
+          tag="- "
+          :button-title="__('Add a bullet list')"
+          icon="list-bulleted"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('numbered-list')"
+          :prepend="true"
+          tag="1. "
+          :button-title="__('Add a numbered list')"
+          icon="list-numbered"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('task-list')"
+          :prepend="true"
+          tag="- [ ] "
+          :button-title="__('Add a checklist')"
+          icon="list-task"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('indent')"
+          class="gl-display-none"
+          :button-title="
+            /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
+            sprintf(s__('MarkdownEditor|Indent line (%{modifierKey}])'), {
+              modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */,
+            })
+          "
+          :shortcuts="$options.shortcuts.indent"
+          command="indentLines"
+          icon="list-indent"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('outdent')"
+          class="gl-display-none"
+          :button-title="
+            /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
+            sprintf(s__('MarkdownEditor|Outdent line (%{modifierKey}[)'), {
+              modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */,
+            })
+          "
+          :shortcuts="$options.shortcuts.outdent"
+          command="outdentLines"
+          icon="list-outdent"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('collapsible-section')"
+          :tag="mdCollapsibleSection"
+          :prepend="true"
+          tag-select="Click to expand"
+          :button-title="__('Add a collapsible section')"
+          icon="details-block"
+        />
+        <toolbar-button
+          v-if="!restrictedToolBarItems.includes('table')"
+          :tag="mdTable"
+          :prepend="true"
+          :button-title="__('Add a table')"
+          icon="table"
+        />
+        <gl-button
+          v-if="!restrictedToolBarItems.includes('attach-file')"
+          v-gl-tooltip
+          :title="__('Attach a file or image')"
+          class="gl-mr-2"
+          data-testid="button-attach-file"
+          category="tertiary"
+          icon="paperclip"
+          size="small"
+          @click="handleAttachFile"
+        />
+        <drawio-toolbar-button
+          v-if="drawioEnabled"
+          :uploads-path="uploadsPath"
+          :markdown-preview-path="markdownPreviewPath"
+        />
+        <comment-templates-dropdown
+          v-if="newCommentTemplatePath && glFeatures.savedReplies"
+          :new-comment-template-path="newCommentTemplatePath"
+        />
+      </div>
+      <div class="switch-preview gl-py-2 gl-display-flex gl-align-items-center gl-ml-auto">
+        <editor-mode-switcher
+          v-if="showEditorModeSwitcher"
+          size="small"
+          class="gl-mr-2"
+          value="markdown"
+          @input="handleEditorModeChanged"
+        />
+        <gl-button
+          v-if="enablePreview"
+          data-testid="preview-toggle"
+          value="preview"
+          :label="$options.i18n.previewTabTitle"
+          class="js-md-preview-button gl-flex-direction-row-reverse gl-align-items-center gl-font-weight-normal!"
+          size="small"
+          category="tertiary"
+          @click="switchPreview"
+          >{{ previewMarkdown ? $options.i18n.hidePreview : $options.i18n.preview }}</gl-button
+        >
+        <gl-button
+          v-if="!restrictedToolBarItems.includes('full-screen')"
+          v-gl-tooltip
+          :class="{ 'gl-display-none!': previewMarkdown }"
+          class="js-zen-enter gl-ml-2"
+          category="tertiary"
+          icon="maximize"
+          size="small"
+          :title="__('Go full screen')"
+          :prepend="true"
+          :button-title="__('Go full screen')"
+        />
+      </div>
+    </div>
   </div>
 </template>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
index e8be242f660511204996027ca7e2ba85f8f50698..4733afb750443d06bdb38dba849802bd4e143e29 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
@@ -1,6 +1,5 @@
 <script>
 import { GlButton, GlLink, GlLoadingIcon, GlSprintf, GlIcon } from '@gitlab/ui';
-import EditorModeDropdown from './editor_mode_dropdown.vue';
 
 export default {
   components: {
@@ -9,7 +8,6 @@ export default {
     GlLoadingIcon,
     GlSprintf,
     GlIcon,
-    EditorModeDropdown,
   },
   props: {
     markdownDocsPath: {
@@ -31,30 +29,21 @@ export default {
       required: false,
       default: true,
     },
-    showContentEditorSwitcher: {
-      type: Boolean,
-      required: false,
-      default: false,
-    },
   },
   computed: {
     hasQuickActionsDocsPath() {
       return this.quickActionsDocsPath !== '';
     },
   },
-  methods: {
-    handleEditorModeChanged(mode) {
-      if (mode === 'richText') {
-        this.$emit('enableContentEditor');
-      }
-    },
-  },
 };
 </script>
 
 <template>
-  <div v-if="showCommentToolBar" class="comment-toolbar clearfix">
-    <div class="toolbar-text">
+  <div
+    v-if="showCommentToolBar"
+    class="comment-toolbar gl-mx-2 gl-mb-2 gl-px-4 gl-bg-gray-10 gl-rounded-bottom-left-base gl-rounded-bottom-right-base clearfix"
+  >
+    <div class="toolbar-text gl-font-sm">
       <template v-if="!hasQuickActionsDocsPath && markdownDocsPath">
         <gl-sprintf
           :message="
@@ -62,7 +51,9 @@ export default {
           "
         >
           <template #markdownDocsLink="{ content }">
-            <gl-link :href="markdownDocsPath" target="_blank">{{ content }}</gl-link>
+            <gl-link :href="markdownDocsPath" target="_blank" class="gl-font-sm">{{
+              content
+            }}</gl-link>
           </template>
         </gl-sprintf>
       </template>
@@ -75,18 +66,22 @@ export default {
           "
         >
           <template #markdownDocsLink="{ content }">
-            <gl-link :href="markdownDocsPath" target="_blank">{{ content }}</gl-link>
+            <gl-link :href="markdownDocsPath" target="_blank" class="gl-font-sm">{{
+              content
+            }}</gl-link>
           </template>
           <template #keyboard="{ content }">
             <kbd>{{ content }}</kbd>
           </template>
           <template #quickActionsDocsLink="{ content }">
-            <gl-link :href="quickActionsDocsPath" target="_blank">{{ content }}</gl-link>
+            <gl-link :href="quickActionsDocsPath" target="_blank" class="gl-font-sm">{{
+              content
+            }}</gl-link>
           </template>
         </gl-sprintf>
       </template>
     </div>
-    <span v-if="canAttachFile" class="uploading-container gl-line-height-32">
+    <span v-if="canAttachFile" class="uploading-container gl-font-sm gl-line-height-32">
       <span class="uploading-progress-container hide">
         <gl-icon name="paperclip" />
         <span class="attaching-file-message"></span>
@@ -111,7 +106,7 @@ export default {
             <gl-button
               variant="link"
               category="primary"
-              class="retry-uploading-link gl-vertical-align-baseline"
+              class="retry-uploading-link gl-vertical-align-baseline gl-font-sm!"
             >
               {{ content }}
             </gl-button>
@@ -120,7 +115,7 @@ export default {
             <gl-button
               variant="link"
               category="primary"
-              class="markdown-selector attach-new-file gl-vertical-align-baseline"
+              class="markdown-selector attach-new-file gl-vertical-align-baseline gl-font-sm!"
             >
               {{ content }}
             </gl-button>
@@ -130,17 +125,10 @@ export default {
       <gl-button
         variant="link"
         category="primary"
-        class="button-cancel-uploading-files gl-vertical-align-baseline hide"
+        class="button-cancel-uploading-files gl-vertical-align-baseline hide gl-font-sm!"
       >
         {{ __('Cancel') }}
       </gl-button>
     </span>
-    <editor-mode-dropdown
-      v-if="showContentEditorSwitcher"
-      size="small"
-      class="gl-float-right gl-line-height-28 gl-display-block"
-      value="markdown"
-      @input="handleEditorModeChanged"
-    />
   </div>
 </template>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue
index 5ca21522d33f53fa58d4b61aaedb42b6bb5ea60b..636c89c99d450fb332f785a591c26fe029a0d144 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue
@@ -92,7 +92,8 @@ export default {
     :icon="icon"
     type="button"
     category="tertiary"
-    class="js-md"
+    size="small"
+    class="js-md gl-mr-3"
     data-container="body"
     @click="$emit('click', $event)"
   />
diff --git a/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue b/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue
index cb682e8b94419681b0ab3094a8e91b83d5345455..32ac5daf5de2efb8437c5d9dce4bb9125bd96f28 100644
--- a/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue
+++ b/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue
@@ -145,7 +145,7 @@ export default {
       return this.isNewDiscussion
         ? 'timeline-entry note-form'
         : // eslint-disable-next-line @gitlab/require-i18n-strings
-          'note note-wrapper note-comment discussion-reply-holder gl-border-t-0! clearfix';
+          'note note-wrapper note-comment discussion-reply-holder gl-border-t-0! clearfix gl-bg-white! gl-pt-0!';
     },
   },
   watch: {
diff --git a/app/assets/stylesheets/components/content_editor.scss b/app/assets/stylesheets/components/content_editor.scss
index 44429b439d9485c71ab84b812aae73637a15a408..a0cbf4fcd434b149227cb308f3dc613a48ff381f 100644
--- a/app/assets/stylesheets/components/content_editor.scss
+++ b/app/assets/stylesheets/components/content_editor.scss
@@ -1,5 +1,6 @@
 .ProseMirror {
-  min-height: 128px;
+  padding-top: $gl-spacing-scale-4;
+  min-height: 140px;
   max-height: 55vh;
   overflow-y: auto;
 
@@ -116,14 +117,8 @@
   }
 }
 
-.content-editor-dropdown .dropdown-menu {
-  width: auto !important;
-
-  @include gl-min-w-0;
-
-  button {
-    @include gl-white-space-nowrap;
-  }
+.content-editor-switcher {
+  min-height: 32px;
 }
 
 
diff --git a/app/assets/stylesheets/framework/diffs.scss b/app/assets/stylesheets/framework/diffs.scss
index 9ec87b4f304db6cad0ffdc189cb8e39d22a41e93..54a4769f66da2c1ba2989d4b18e3fbde3752dca0 100644
--- a/app/assets/stylesheets/framework/diffs.scss
+++ b/app/assets/stylesheets/framework/diffs.scss
@@ -946,7 +946,7 @@ table.code {
   &.popover {
     width: 250px;
     min-width: 250px;
-    z-index: 210;
+    z-index: 610;
   }
 
   .popover-header {
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index 48aacc9606e18f416785ab220b7fb989d97f7916..e57dad9e4cbecaebe49a0aad6155677a1a73f38f 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -44,46 +44,6 @@
   }
 }
 
-.md-header {
-  .nav-links {
-    a {
-      width: 100%;
-      padding-top: 0;
-      line-height: 19px;
-
-      &.btn.btn-sm {
-        padding: 2px 5px;
-      }
-
-      &:focus {
-        margin-top: -10px;
-        padding-top: 10px;
-      }
-    }
-  }
-
-  .gl-tabs-nav {
-    @include media-breakpoint-down(xs) {
-      .nav-item {
-        flex: 1;
-      }
-
-      .gl-tab-nav-item {
-        padding-top: $gl-padding-4;
-        padding-bottom: $gl-padding-8;
-      }
-
-      .md-header-toolbar {
-        width: 100%;
-        display: flex;
-        flex-wrap: wrap;
-        padding-top: $gl-padding-8;
-        border-top: 1px solid $border-color;
-      }
-    }
-  }
-}
-
 .md-header-tab {
   @include media-breakpoint-down(xs) {
     flex: 1;
@@ -131,7 +91,7 @@
 }
 
 .md-preview-holder {
-  min-height: 172px;
+  min-height: 176px;
   padding: 10px 0;
   overflow-x: auto;
 }
diff --git a/app/assets/stylesheets/page_bundles/merge_requests.scss b/app/assets/stylesheets/page_bundles/merge_requests.scss
index 00ef659dcf46b058c2f66792fe020e8846f752a3..d3ebc06a1dd0573c9772beae107813967d676566 100644
--- a/app/assets/stylesheets/page_bundles/merge_requests.scss
+++ b/app/assets/stylesheets/page_bundles/merge_requests.scss
@@ -1027,7 +1027,7 @@ $tabs-holder-z-index: 250;
   }
 
   .md-preview-holder {
-    max-height: 172px;
+    max-height: 182px;
   }
 }
 
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index adeab227670342d8600a2b28530abf9031dba9e4..d029aa01e377a416635e47010335b3fab0b51f0a 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -31,7 +31,7 @@
 
 .note-textarea {
   display: block;
-  padding: 10px 1px;
+  padding: 10px 16px;
   color: $gl-text-color;
   font-family: $regular-font;
   border: 0;
@@ -48,9 +48,8 @@
 
 .common-note-form {
   .md-area {
-    padding: 0 $gl-padding;
     border: 1px solid $border-color;
-    border-radius: $border-radius-base;
+    border-radius: $border-radius-large;
     transition: border-color ease-in-out 0.15s,
       box-shadow ease-in-out 0.15s;
     background-color: $white;
@@ -81,6 +80,10 @@
   @include gl-focus;
 }
 
+.md-header {
+  min-height: 32px;
+}
+
 .md-header .nav-links {
   display: flex;
   flex-flow: row wrap;
@@ -92,6 +95,11 @@
   }
 }
 
+
+.md-header .gl-tabs-nav {
+  border-bottom: 0;
+}
+
 .issuable-note-warning {
   color: $orange-600;
   background-color: $orange-50;
@@ -305,7 +313,6 @@ table {
 
 .comment-toolbar {
   color: $gl-text-color-secondary;
-  border-top: 1px solid $border-color;
 }
 
 .toolbar-button {
@@ -394,6 +401,10 @@ table {
     float: left;
     margin-top: 5px;
   }
+
+  button {
+    font-size: $gl-font-size-sm !important;
+  }
 }
 
 .uploading-error-icon,
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index bec6cccb977e8052eeb865ada065381acb1c2ad0..91fce6d6820f07482092be79599d8d94685a0bef 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -192,7 +192,7 @@ def render_links(text)
 
   def markdown_toolbar_button(options = {})
     data = options[:data].merge({ container: 'body' })
-    css_classes = %w[gl-button btn btn-default-tertiary btn-icon js-md has-tooltip] << options[:css_class].to_s
+    css_classes = %w[gl-button btn btn-default-tertiary btn-icon btn-sm js-md has-tooltip] << options[:css_class].to_s
     content_tag :button,
       type: 'button',
       class: css_classes.join(' '),
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index 5e1a979e2061d57b231278941802e0abb48067a7..621cd251bdf547b3ef8d7e76c03caf52d04a15e4 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -29,7 +29,10 @@
     - unless Feature.enabled?(:source_editor_toolbar, current_user)
       .file-buttons.gl-display-flex.gl-align-items-center.gl-justify-content-end
         - if is_markdown
-          = render 'shared/blob/markdown_buttons', show_fullscreen_button: false, supports_file_upload: false
+          .md-header.gl-display-flex.gl-px-2.gl-rounded-base.gl-mx-2.gl-mt-2
+            .gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-justify-content-space-between
+              .md-header-toolbar.gl-display-flex.gl-py-2.gl-flex-wrap{ class: "gl-m-0!" }
+                = render 'shared/blob/markdown_buttons', supports_file_upload: false
         %span.soft-wrap-toggle
           = render Pajamas::ButtonComponent.new(icon: 'soft-unwrap', button_options: { class: 'no-wrap' }) do
             = _("No wrap")
diff --git a/app/views/shared/_md_preview.html.haml b/app/views/shared/_md_preview.html.haml
index 2fff70cdc741845eab4a4f0fa1f9580c9d1ce677..dd3a31f5a592dc9f9032b9ff7b191faf82f3319e 100644
--- a/app/views/shared/_md_preview.html.haml
+++ b/app/views/shared/_md_preview.html.haml
@@ -8,21 +8,18 @@
       = _('Only project members can comment.')
 
 .md-area.position-relative
-  .md-header
-    = gl_tabs_nav({ class: 'clearfix nav-links'}) do
-      %li.md-header-tab.active
-        %button.js-md-write-button{ class: 'gl-py-3!' }
-          = _("Write")
-      %li.md-header-tab
-        %button.js-md-preview-button{ class: 'gl-py-3!' }
-          = _("Preview")
-
-      %li.md-header-toolbar.active.gl-py-2
-        = render 'shared/blob/markdown_buttons', show_fullscreen_button: true
+  .md-header.gl-bg-gray-50.gl-px-2.gl-rounded-base.gl-mx-2.gl-mt-2
+    .gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-justify-content-space-between
+      .md-header-toolbar.gl-display-flex.gl-py-2.gl-flex-wrap
+        = render 'shared/blob/markdown_buttons'
+      .switch-preview.gl-py-2.gl-display-flex.gl-align-items-center.gl-ml-auto
+        = render Pajamas::ButtonComponent.new(category: :tertiary, size: :small, button_options: { class: 'js-md-preview-button', value: 'preview' }) do
+          = _('Preview')
+        = render Pajamas::ButtonComponent.new(icon: 'maximize', category: :tertiary, size: :small, button_options: { 'tabindex': -1, 'aria-label': _("Go full screen"), class: 'has-tooltip js-zen-enter gl-ml-2', data: { container: 'body' } })
 
   .md-write-holder
     = yield
-  .md.md-preview-holder.js-md-preview.hide{ data: { url: url } }
+  .md.md-preview-holder.gl-px-5.js-md-preview.hide{ data: { url: url } }
   .referenced-commands.hide
 
   - if referenced_users
diff --git a/app/views/shared/_zen.html.haml b/app/views/shared/_zen.html.haml
index 5a4efe7fe7f63a40fa1f72f7a83f97f112458717..05bee9e4d4250f14f985c4fcf92bc7ac2b4e3b33 100644
--- a/app/views/shared/_zen.html.haml
+++ b/app/views/shared/_zen.html.haml
@@ -4,6 +4,7 @@
 - supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
 - qa_selector = local_assigns.fetch(:qa_selector, '')
 - autofocus = local_assigns.fetch(:autofocus, false)
+
 .zen-backdrop
   - classes << ' js-gfm-input js-autosize markdown-area'
   - if defined?(f) && f
diff --git a/app/views/shared/blob/_markdown_buttons.html.haml b/app/views/shared/blob/_markdown_buttons.html.haml
index db53d78dadb8c1e951206f30292013b6c9c9c23c..a3d3c1c82312db23e427a2da1c312c8d8d8936ed 100644
--- a/app/views/shared/blob/_markdown_buttons.html.haml
+++ b/app/views/shared/blob/_markdown_buttons.html.haml
@@ -1,42 +1,44 @@
 - modifier_key = client_js_flags[:isMac] ? '⌘' : s_('KeyboardKey|Ctrl+')
 - supports_file_upload = local_assigns.fetch(:supports_file_upload, true)
 
-.md-header-toolbar.active
-  = markdown_toolbar_button({ icon: "bold",
-                              data: { "md-tag" => "**", "md-shortcuts": '["mod+b"]' },
-                              title: sprintf(s_("MarkdownEditor|Add bold text (%{modifier_key}B)") % { modifier_key: modifier_key }) })
+= markdown_toolbar_button({ icon: "bold",
+                            css_class: 'gl-mr-3',
+                            data: { "md-tag" => "**", "md-shortcuts": '["mod+b"]' },
+                            title: sprintf(s_("MarkdownEditor|Add bold text (%{modifier_key}B)") % { modifier_key: modifier_key }) })
 
-  = markdown_toolbar_button({ icon: "italic",
-                              data: { "md-tag" => "_", "md-shortcuts": '["mod+i"]' },
-                              title: sprintf(s_("MarkdownEditor|Add italic text (%{modifier_key}I)") % { modifier_key: modifier_key }) })
+= markdown_toolbar_button({ icon: "italic",
+                            css_class: 'gl-mr-3',
+                            data: { "md-tag" => "_", "md-shortcuts": '["mod+i"]' },
+                            title: sprintf(s_("MarkdownEditor|Add italic text (%{modifier_key}I)") % { modifier_key: modifier_key }) })
 
-  = markdown_toolbar_button({ icon: "strikethrough",
-                              data: { "md-tag" => "~~", "md-shortcuts": '["mod+shift+x"]' },
-                              title: sprintf(s_("MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)") % { modifier_key: modifier_key }) })
+= markdown_toolbar_button({ icon: "strikethrough",
+                            css_class: 'gl-mr-3',
+                            data: { "md-tag" => "~~", "md-shortcuts": '["mod+shift+x"]' },
+                            title: sprintf(s_("MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)") % { modifier_key: modifier_key }) })
 
-  = markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: _("Insert a quote") })
-  = markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: _("Insert code") })
+= markdown_toolbar_button({ icon: "quote", css_class: 'gl-mr-3', data: { "md-tag" => "> ", "md-prepend" => true }, title: _("Insert a quote") })
+= markdown_toolbar_button({ icon: "code", css_class: 'gl-mr-3', data: { "md-tag" => "`", "md-block" => "```" }, title: _("Insert code") })
 
-  = markdown_toolbar_button({ icon: "link",
-                              data: { "md-tag" => "[{text}](url)", "md-select" => "url", "md-shortcuts": '["mod+k"]' },
-                              title: sprintf(s_("MarkdownEditor|Add a link (%{modifier_key}K)") % { modifier_key: modifier_key }) })
+= markdown_toolbar_button({ icon: "link",
+                            css_class: 'gl-mr-3',
+                            data: { "md-tag" => "[{text}](url)", "md-select" => "url", "md-shortcuts": '["mod+k"]' },
+                            title: sprintf(s_("MarkdownEditor|Add a link (%{modifier_key}K)") % { modifier_key: modifier_key }) })
 
-  = markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "- ", "md-prepend" => true }, title: _("Add a bullet list") })
-  = markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
-  = markdown_toolbar_button({ icon: "list-task", data: { "md-tag" => "- [ ] ", "md-prepend" => true }, title: _("Add a checklist") })
-  = markdown_toolbar_button({ icon: "list-indent",
-                              data: { "md-command" => 'indentLines', "md-shortcuts": '["mod+]"]' },
-                              css_class: 'gl-display-none',
-                              title: sprintf(s_("MarkdownEditor|Indent line (%{modifier_key}])") % { modifier_key: modifier_key }) })
-  = markdown_toolbar_button({ icon: "list-outdent",
-                              data: { "md-command" => 'outdentLines', "md-shortcuts": '["mod+["]' },
-                              css_class: 'gl-display-none',
-                              title: sprintf(s_("MarkdownEditor|Outdent line (%{modifier_key}[)") % { modifier_key: modifier_key }) })
-  = markdown_toolbar_button({ icon: "details-block",
-                              data: { "md-tag" => "<details><summary>Click to expand</summary>\n{text}\n</details>", "md-prepend" => true, "md-select" => "Click to expand" },
-                              title: _("Add a collapsible section") })
-  = markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n|        |        |\n|        |        |", "md-prepend" => true }, title: _("Add a table") })
-  - if supports_file_upload
-    = render Pajamas::ButtonComponent.new(icon: 'paperclip', category: :tertiary, button_options: { 'aria-label': _("Attach a file or image"), class: 'has-tooltip js-attach-file-button', data: { testid: 'button-attach-file', container: 'body' } })
-  - if show_fullscreen_button
-    = render Pajamas::ButtonComponent.new(icon: 'maximize', category: :tertiary, button_options: { 'tabindex': -1, 'aria-label': _("Go full screen"), class: 'has-tooltip js-zen-enter', data: { container: 'body' } })
+= markdown_toolbar_button({ icon: "list-bulleted", css_class: 'gl-mr-3', data: { "md-tag" => "- ", "md-prepend" => true }, title: _("Add a bullet list") })
+= markdown_toolbar_button({ icon: "list-numbered", css_class: 'gl-mr-3', data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
+= markdown_toolbar_button({ icon: "list-task", css_class: 'gl-mr-3', data: { "md-tag" => "- [ ] ", "md-prepend" => true }, title: _("Add a checklist") })
+= markdown_toolbar_button({ icon: "list-indent",
+                            css_class: 'gl-display-none gl-mr-3',
+                            data: { "md-command" => 'indentLines', "md-shortcuts": '["mod+]"]' },
+                            title: sprintf(s_("MarkdownEditor|Indent line (%{modifier_key}])") % { modifier_key: modifier_key }) })
+= markdown_toolbar_button({ icon: "list-outdent",
+                            css_class: 'gl-display-none gl-mr-3',
+                            data: { "md-command" => 'outdentLines', "md-shortcuts": '["mod+["]' },
+                            title: sprintf(s_("MarkdownEditor|Outdent line (%{modifier_key}[)") % { modifier_key: modifier_key }) })
+= markdown_toolbar_button({ icon: "details-block",
+                            css_class: 'gl-mr-3',
+                            data: { "md-tag" => "<details><summary>Click to expand</summary>\n{text}\n</details>", "md-prepend" => true, "md-select" => "Click to expand" },
+                            title: _("Add a collapsible section") })
+= markdown_toolbar_button({ icon: "table", css_class: 'gl-mr-3', data: { "md-tag" => "| header | header |\n| ------ | ------ |\n|        |        |\n|        |        |", "md-prepend" => true }, title: _("Add a table") })
+- if supports_file_upload
+  = render Pajamas::ButtonComponent.new(icon: 'paperclip', category: :tertiary, size: :small, button_options: { 'aria-label': _("Attach a file or image"), class: 'has-tooltip js-attach-file-button gl-mr-3', data: { testid: 'button-attach-file', container: 'body' } })
diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml
index fb000b9aab18e28e3877f457633e624da4ca4357..d7d6e477ab1c70082cdeabde331960fea7fbb43d 100644
--- a/app/views/shared/notes/_hints.html.haml
+++ b/app/views/shared/notes/_hints.html.haml
@@ -1,7 +1,7 @@
 - supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
 - supports_file_upload = local_assigns.fetch(:supports_file_upload, true)
-.comment-toolbar.clearfix
-  .toolbar-text
+.comment-toolbar.gl-mx-2.gl-mb-2.gl-px-4.gl-bg-gray-10.gl-rounded-bottom-left-base.gl-rounded-bottom-right-base.clearfix
+  .toolbar-text.gl-font-sm
     - markdownLinkStart = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/markdown') }
     - quickActionsLinkStart = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/quick_actions') }
     - if supports_quick_actions
@@ -9,7 +9,7 @@
     - else
       = html_escape(s_('MarkdownToolbar|Supports %{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd}')) % { markdownDocsLinkStart: markdownLinkStart, markdownDocsLinkEnd: '</a>'.html_safe }
   - if supports_file_upload
-    %span.uploading-container.gl-line-height-32
+    %span.uploading-container.gl-line-height-32.gl-font-sm
       %span.uploading-progress-container.hide
         = sprite_icon('paperclip', css_class: 'gl-icon gl-vertical-align-text-bottom')
         %span.attaching-file-message
diff --git a/ee/app/assets/javascripts/ai/components/ai_actions_dropdown.vue b/ee/app/assets/javascripts/ai/components/ai_actions_dropdown.vue
index eb90d04e6fbf4e67aab7a1de5babcb547fe5be4a..e3c0718e8eb57797b85f1f4da108537dc92c05f5 100644
--- a/ee/app/assets/javascripts/ai/components/ai_actions_dropdown.vue
+++ b/ee/app/assets/javascripts/ai/components/ai_actions_dropdown.vue
@@ -158,7 +158,7 @@ export default {
     @action="$refs.dropdown.close()"
   >
     <template #toggle>
-      <gl-button category="tertiary" class="gl-px-3!">
+      <gl-button category="tertiary" size="small" class="gl-mr-3 gl-px-2!">
         <gl-loading-icon v-if="loading" />
         <gl-icon v-else name="tanuki" />
       </gl-button>
diff --git a/ee/app/assets/javascripts/vulnerabilities/components/new_vulnerability/section_name.vue b/ee/app/assets/javascripts/vulnerabilities/components/new_vulnerability/section_name.vue
index ebbcd272c64b1c1f63b2ce6f867d80a2c98cd421..fc973c78036f058548b709e6435333d7fb3d24e8 100644
--- a/ee/app/assets/javascripts/vulnerabilities/components/new_vulnerability/section_name.vue
+++ b/ee/app/assets/javascripts/vulnerabilities/components/new_vulnerability/section_name.vue
@@ -77,7 +77,6 @@ export default {
       <div class="gl-border-solid gl-border-gray-100 gl-border-1 gl-rounded-base">
         <markdown-field
           ref="markdownField"
-          class="gl-px-4"
           :can-attach-file="false"
           :add-spacing-classes="false"
           :markdown-preview-path="markdownPreviewPath"
@@ -91,7 +90,7 @@ export default {
               id="form-vulnerability-desc"
               v-model.trim="vulnerabilityDesc"
               rows="8"
-              class="gl-shadow-none! gl-px-0! gl-py-4! gl-h-auto!"
+              class="gl-shadow-none! gl-py-4! gl-h-auto!"
               :aria-label="$options.i18n.vulnerabilityDesc.description"
               :placeholder="$options.i18n.vulnerabilityDesc.description"
               @input="emitChanges"
diff --git a/ee/spec/features/epics/update_epic_spec.rb b/ee/spec/features/epics/update_epic_spec.rb
index 98ea47f05f18f88f1a33f96cf2ccffb27bb3ce8c..2f522dbd289c4cd32889aa4978229f5ddc98f6e3 100644
--- a/ee/spec/features/epics/update_epic_spec.rb
+++ b/ee/spec/features/epics/update_epic_spec.rb
@@ -50,7 +50,7 @@
         fill_in 'issue-description', with: 'New epic description'
 
         page.within('.detail-page-description') do
-          click_link('Preview')
+          click_button("Preview")
           expect(find('.md-preview-holder')).to have_content('New epic description')
         end
 
@@ -65,7 +65,7 @@
         fill_in 'issue-description', with: 'New epic description'
 
         page.within('.detail-page-description') do
-          click_link('Preview')
+          click_button("Preview")
           expect(find('.md-preview-holder')).to have_content('New epic description')
         end
 
@@ -78,7 +78,7 @@
         find('.js-issuable-edit').click
 
         page.within('.detail-page-description') do
-          click_link('Preview')
+          click_button("Preview")
           expect(find('.md-preview-holder')).to have_content('New epic description')
         end
       end
@@ -124,7 +124,7 @@
         expect(page.find_field("issue-description").value).to have_content('banana_sample')
 
         page.within('.detail-page-description') do
-          click_link('Preview')
+          click_button("Preview")
           wait_for_requests
 
           within('.md-preview-holder') do
diff --git a/ee/spec/features/epics/user_comments_on_epic_spec.rb b/ee/spec/features/epics/user_comments_on_epic_spec.rb
index 8aa8bce88a7b47ae40bee15a30682f9efdb39b5c..ea39d7e3e1b1f42b87e698dae091214b1f2d1a9a 100644
--- a/ee/spec/features/epics/user_comments_on_epic_spec.rb
+++ b/ee/spec/features/epics/user_comments_on_epic_spec.rb
@@ -40,7 +40,7 @@
       fill_in 'Comment', with: "#{epic2.to_reference(full: true)}+"
 
       page.within('.new-note') do
-        click_link('Preview')
+        click_button("Preview")
         wait_for_requests
 
         within('.md-preview-holder') do
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 75dfdac6414f2e0b8dc83d12a0fc860ef1f5428f..f061e22dff687613361974bf8a25ded1ab3d6128 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -16251,12 +16251,6 @@ msgstr ""
 msgid "Editing"
 msgstr ""
 
-msgid "Editing markdown"
-msgstr ""
-
-msgid "Editing rich text"
-msgstr ""
-
 msgid "Edits"
 msgstr ""
 
@@ -27044,9 +27038,6 @@ msgstr ""
 msgid "Mark to do as done"
 msgstr ""
 
-msgid "Markdown"
-msgstr ""
-
 msgid "Markdown Help"
 msgstr ""
 
@@ -38333,9 +38324,6 @@ msgstr ""
 msgid "Revoked personal access token %{personal_access_token_name}!"
 msgstr ""
 
-msgid "Rich text"
-msgstr ""
-
 msgid "RightSidebar|Copy email address"
 msgstr ""
 
@@ -43871,6 +43859,12 @@ msgstr ""
 msgid "Switch to GitLab Next"
 msgstr ""
 
+msgid "Switch to Markdown"
+msgstr ""
+
+msgid "Switch to rich text"
+msgstr ""
+
 msgid "Switch to the source to copy the file contents"
 msgstr ""
 
@@ -49090,9 +49084,6 @@ msgstr ""
 msgid "View all projects"
 msgstr ""
 
-msgid "View and edit markdown, with the option to preview the formatted output."
-msgstr ""
-
 msgid "View blame"
 msgstr ""
 
@@ -49222,9 +49213,6 @@ msgstr ""
 msgid "View the documentation"
 msgstr ""
 
-msgid "View the formatted output in real-time as you edit."
-msgstr ""
-
 msgid "View the latest successful deployment to this environment"
 msgstr ""
 
diff --git a/qa/qa/page/component/wiki_page_form.rb b/qa/qa/page/component/wiki_page_form.rb
index 9143a25d9ab2412a7c198168c4a8691c1c475b67..335790c5b27f27b15fa653b3109096ba34b9f53b 100644
--- a/qa/qa/page/component/wiki_page_form.rb
+++ b/qa/qa/page/component/wiki_page_form.rb
@@ -19,7 +19,7 @@ def self.included(base)
             element :markdown_editor_form_field
           end
 
-          base.view 'app/assets/javascripts/vue_shared/components/markdown/editor_mode_dropdown.vue' do
+          base.view 'app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue' do
             element :editing_mode_switcher
           end
 
@@ -59,9 +59,6 @@ def delete_page
 
         def use_new_editor
           click_element(:editing_mode_switcher)
-          within_element(:editing_mode_switcher) do
-            find('button', text: 'Rich text').click
-          end
 
           wait_until(reload: false) do
             has_element?(:content_editor_container)
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index a70a1e2e70ba42a78b0bc4221011b646cebe826a..376e1e6063fd4ab27af4830075e2fdc6390bf5b1 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -25,17 +25,17 @@
 
       description.native.send_keys('')
 
-      click_button('Preview')
+      click_button("Preview")
 
       preview = find('.js-md-preview')
 
       expect(preview).to have_content('Nothing to preview.')
 
-      click_button('Write')
+      click_button("Continue editing")
 
       description.native.send_keys(':+1: Nice')
 
-      click_button('Preview')
+      click_button("Preview")
 
       expect(preview).to have_css('gl-emoji')
       expect(find('#milestone_description', visible: false)).not_to be_visible
diff --git a/spec/features/issuables/markdown_references/jira_spec.rb b/spec/features/issuables/markdown_references/jira_spec.rb
index 52464c6be8b01414cdbdcf5086be7385fc8fe085..887bc7d0c87c0aa098c6bfceba0fbbf4787ea08e 100644
--- a/spec/features/issuables/markdown_references/jira_spec.rb
+++ b/spec/features/issuables/markdown_references/jira_spec.rb
@@ -29,7 +29,7 @@
     end
 
     it "creates a link to the referenced issue on the preview" do
-      find(".js-md-preview-button").click
+      click_button("Preview")
 
       wait_for_requests
 
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 3b1716230cd6e4f02b33c954f5e48286dd2489aa..56c395091d926571288d6d28a434bf4fd2ebcba8 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -61,22 +61,22 @@
         textarea = first(".gfm-form textarea")
 
         page.within(form) do
-          click_link("Preview")
+          click_button("Preview")
 
           preview = find(".js-vue-md-preview") # this element is findable only when the "Preview" link is clicked.
 
           expect(preview).to have_content("Nothing to preview.")
 
-          click_link("Write")
+          click_button("Continue editing")
           fill_in("Description", with: "Bug fixed :smile:")
-          click_link("Preview")
+          click_button("Preview")
 
           expect(preview).to have_css("gl-emoji")
           expect(textarea).not_to be_visible
 
-          click_link("Write")
+          click_button("Continue editing")
           fill_in("Description", with: "/confidential")
-          click_link("Preview")
+          click_button("Preview")
 
           expect(form).to have_content('Makes this issue confidential.')
         end
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index 4ef58918a2bbd80c67fdeebc1fa22899a6f8eefc..c1cf8fada26148b48ede9158aa545cd94d4c02b2 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -39,9 +39,7 @@
           click_button("Preview")
         end
 
-        expect(form).to have_button("Write")
-
-        click_button("Write")
+        click_button("Continue editing")
         fill_in("Description", with: "/confidential")
         click_button("Preview")
 
@@ -121,8 +119,7 @@ def click_edit_issue_description
           expect(issuable_form).to have_selector(markdown_field_focused_selector)
 
           page.within issuable_form do
-            click_on _('Editing markdown')
-            click_on _('Rich text')
+            click_button("Switch to rich text")
           end
 
           expect(issuable_form).not_to have_selector(content_editor_focused_selector)
@@ -134,8 +131,7 @@ def click_edit_issue_description
           expect(issuable_form).to have_selector(content_editor_focused_selector)
 
           page.within issuable_form do
-            click_on _('Editing rich text')
-            click_on _('Markdown')
+            click_button("Switch to Markdown")
           end
 
           expect(issuable_form).not_to have_selector(markdown_field_focused_selector)
diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb
index f167ab8fe8a4a77262f69a87b49324793d22c778..03b01ef4b7a1d75415097f7032638ee8e419107f 100644
--- a/spec/features/merge_request/user_posts_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_notes_spec.rb
@@ -62,7 +62,7 @@
     before do
       page.within('.js-main-target-form') do
         fill_in 'note[note]', with: 'This is awesome!'
-        find('.js-md-preview-button').click
+        click_button("Preview")
         click_button 'Comment'
       end
     end
@@ -138,7 +138,7 @@
 
     it 'hides the toolbar buttons when previewing a note' do
       wait_for_requests
-      find('.js-md-preview-button').click
+      click_button("Preview")
       page.within('.js-main-target-form') do
         expect(page).not_to have_css('.md-header-toolbar')
       end
diff --git a/spec/features/merge_request/user_views_open_merge_request_spec.rb b/spec/features/merge_request/user_views_open_merge_request_spec.rb
index 6118f59df3cabee9a66dffd44538336a43663b9a..1a9d40ae92648ebdcd8c5b853f2aa2b5b4a2fb6d 100644
--- a/spec/features/merge_request/user_views_open_merge_request_spec.rb
+++ b/spec/features/merge_request/user_views_open_merge_request_spec.rb
@@ -59,7 +59,7 @@
         fill_in(:merge_request_description, with: '')
 
         page.within('.js-vue-markdown-field') do
-          click_link('Preview')
+          click_button("Preview")
 
           expect(find('.js-vue-md-preview')).to have_content('Nothing to preview.')
         end
@@ -69,12 +69,12 @@
         fill_in(:merge_request_description, with: ':+1: Nice')
 
         page.within('.js-vue-markdown-field') do
-          click_link('Preview')
+          click_button("Preview")
 
           expect(find('.js-vue-md-preview')).to have_css('gl-emoji')
         end
 
-        expect(find('.js-vue-markdown-field')).to have_css('.js-vue-md-preview').and have_link('Write')
+        expect(find('.js-vue-markdown-field')).to have_css('.js-md-preview-button')
         expect(find('#merge_request_description', visible: false)).not_to be_visible
       end
     end
diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb
index 2b6b09ccc10526358e0884dbe60b744577a2ac56..6e335871ed1e6d786fe27c4f13f5b33816d9beed 100644
--- a/spec/features/projects/blobs/edit_spec.rb
+++ b/spec/features/projects/blobs/edit_spec.rb
@@ -142,7 +142,7 @@ def fill_editor(content: 'class NextFeature\\nend\\n')
       it 'renders content with CommonMark' do
         visit project_edit_blob_path(project, tree_join(branch, readme_file_path))
         fill_editor(content: '1. one\\n  - sublist\\n')
-        click_link 'Preview'
+        click_on "Preview"
         wait_for_requests
 
         # the above generates two separate lists (not embedded) in CommonMark
diff --git a/spec/features/projects/commit/comments/user_adds_comment_spec.rb b/spec/features/projects/commit/comments/user_adds_comment_spec.rb
index 91b838116e9facca16e764c108ded69000a7dcf7..b0cb57f158dd7183b5b3bb4177df2407784506c0 100644
--- a/spec/features/projects/commit/comments/user_adds_comment_spec.rb
+++ b/spec/features/projects/commit/comments/user_adds_comment_spec.rb
@@ -36,7 +36,7 @@
         expect(page).not_to have_css(".js-note-text")
 
         # Check on the `Write` tab
-        click_button("Write")
+        click_button("Continue editing")
 
         expect(page).to have_field("note[note]", with: "#{comment_text} #{emoji}")
 
@@ -107,7 +107,7 @@
           # Test UI elements, then submit.
           page.within("form[data-line-code='#{sample_commit.line_code}']") do
             expect(find(".js-note-text", visible: false).text).to eq("")
-            expect(page).to have_css('.js-md-write-button')
+            expect(page).to have_css('.js-md-preview')
 
             click_button("Comment")
           end
diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb
index c4019b4d123f109d4cf516fd032a384c3118936e..c1d994ca837587d295c2a9e821b95061d4d5aace 100644
--- a/spec/features/projects/commit/user_comments_on_commit_spec.rb
+++ b/spec/features/projects/commit/user_comments_on_commit_spec.rb
@@ -38,7 +38,7 @@
         expect(page).not_to have_css(".js-note-text")
 
         # Check on `Write` tab
-        click_button("Write")
+        click_button("Continue editing")
 
         expect(page).to have_field("note[note]", with: "#{comment_text} #{emoji_code}")
 
diff --git a/spec/features/projects/releases/user_creates_release_spec.rb b/spec/features/projects/releases/user_creates_release_spec.rb
index c282067f3adcee6e21a7e442a8aa64a05be2a03a..ffc319c845335efb76d95568c71803eaf1bbf91c 100644
--- a/spec/features/projects/releases/user_creates_release_spec.rb
+++ b/spec/features/projects/releases/user_creates_release_spec.rb
@@ -108,7 +108,7 @@
 
       fill_release_notes('**some** _markdown_ [content](https://example.com)')
 
-      click_on 'Preview'
+      click_button("Preview")
 
       wait_for_all_requests
     end
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index 5aac27a71e4b533aa40c3f55c979a4af97154ba2..5c1ee729346a548c302a1fcf0420a8eec061b398 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -81,6 +81,7 @@
 
     it 'previews a note' do
       fill_in 'note[note]', with: 'This is **awesome**!'
+
       find('.js-md-preview-button').click
 
       page.within('.new-note .md-preview-holder') do
diff --git a/spec/frontend/content_editor/components/__snapshots__/toolbar_button_spec.js.snap b/spec/frontend/content_editor/components/__snapshots__/toolbar_button_spec.js.snap
index b8e6bcbc3c4f71e09b844316c1be3dbe08c7e918..a328f79e4e7d55d829e8809de5dfb4630bcf0162 100644
--- a/spec/frontend/content_editor/components/__snapshots__/toolbar_button_spec.js.snap
+++ b/spec/frontend/content_editor/components/__snapshots__/toolbar_button_spec.js.snap
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`content_editor/components/toolbar_button displays tertiary, medium button with a provided label and icon 1`] = `
-"<b-button-stub size=\\"md\\" tag=\\"button\\" type=\\"button\\" variant=\\"default\\" aria-label=\\"Bold\\" title=\\"Bold\\" class=\\"gl-button btn-default-tertiary btn-icon\\">
+"<b-button-stub size=\\"sm\\" tag=\\"button\\" type=\\"button\\" variant=\\"default\\" aria-label=\\"Bold\\" title=\\"Bold\\" class=\\"gl-mr-3 gl-button btn-default-tertiary btn-icon\\">
   <!---->
   <gl-icon-stub name=\\"bold\\" size=\\"16\\" class=\\"gl-button-icon\\"></gl-icon-stub>
   <!---->
diff --git a/spec/frontend/content_editor/components/content_editor_spec.js b/spec/frontend/content_editor/components/content_editor_spec.js
index b642ac9c46bf102b3552f0e39d88ec745ab329e2..8bbd79a61af9670acd53cb4fe0c25ebfd8721e52 100644
--- a/spec/frontend/content_editor/components/content_editor_spec.js
+++ b/spec/frontend/content_editor/components/content_editor_spec.js
@@ -2,7 +2,6 @@ import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
 import { EditorContent, Editor } from '@tiptap/vue-2';
 import { nextTick } from 'vue';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import EditorModeDropdown from '~/vue_shared/components/markdown/editor_mode_dropdown.vue';
 import ContentEditor from '~/content_editor/components/content_editor.vue';
 import ContentEditorAlert from '~/content_editor/components/content_editor_alert.vue';
 import ContentEditorProvider from '~/content_editor/components/content_editor_provider.vue';
@@ -44,7 +43,6 @@ describe('ContentEditor', () => {
         ContentEditorAlert,
         GlLink,
         GlSprintf,
-        EditorModeDropdown,
       },
     });
   };
@@ -107,12 +105,6 @@ describe('ContentEditor', () => {
     expect(findEditorElement().text()).not.toContain('For quick actions, type /');
   });
 
-  it('renders an editor mode dropdown', () => {
-    createWrapper();
-
-    expect(wrapper.findComponent(EditorModeDropdown).exists()).toBe(true);
-  });
-
   describe('when setting initial content', () => {
     it('displays loading indicator', async () => {
       createWrapper();
diff --git a/spec/frontend/content_editor/components/formatting_toolbar_spec.js b/spec/frontend/content_editor/components/formatting_toolbar_spec.js
index 5d2a9e493e5aa8bc8cfb8563067ffa57d058f300..2fc7e5e2e1be1fca1dff5576044fe9c889c1173e 100644
--- a/spec/frontend/content_editor/components/formatting_toolbar_spec.js
+++ b/spec/frontend/content_editor/components/formatting_toolbar_spec.js
@@ -6,6 +6,7 @@ import {
   TOOLBAR_CONTROL_TRACKING_ACTION,
   CONTENT_EDITOR_TRACKING_LABEL,
 } from '~/content_editor/constants';
+import EditorModeSwitcher from '~/vue_shared/components/markdown/editor_mode_switcher.vue';
 
 describe('content_editor/components/formatting_toolbar', () => {
   let wrapper;
@@ -16,6 +17,7 @@ describe('content_editor/components/formatting_toolbar', () => {
       stubs: {
         GlTabs,
         GlTab,
+        EditorModeSwitcher,
       },
     });
   };
@@ -64,4 +66,10 @@ describe('content_editor/components/formatting_toolbar', () => {
       });
     });
   });
+
+  it('renders an editor mode dropdown', () => {
+    buildWrapper();
+
+    expect(wrapper.findComponent(EditorModeSwitcher).exists()).toBe(true);
+  });
 });
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js
index fb64551c76b3b262904749b3248526f048768a38..70f25afc5ba23096fc5c5ed77e8eaca5ff9679a7 100644
--- a/spec/frontend/notes/components/comment_form_spec.js
+++ b/spec/frontend/notes/components/comment_form_spec.js
@@ -264,13 +264,13 @@ describe('issue_comment_form component', () => {
     it('hides content editor switcher if feature flag content_editor_on_issues is off', () => {
       mountComponent({ mountFunction: mount, features: { contentEditorOnIssues: false } });
 
-      expect(wrapper.text()).not.toContain('Rich text');
+      expect(wrapper.text()).not.toContain('Switch to rich text');
     });
 
     it('shows content editor switcher if feature flag content_editor_on_issues is on', () => {
       mountComponent({ mountFunction: mount, features: { contentEditorOnIssues: true } });
 
-      expect(wrapper.text()).toContain('Rich text');
+      expect(wrapper.text()).toContain('Switch to rich text');
     });
 
     describe('textarea', () => {
diff --git a/spec/frontend/notes/components/note_form_spec.js b/spec/frontend/notes/components/note_form_spec.js
index 9423af4f05873095f399791ecff8ffe31fac0e50..b5b33607282d021de947073e397227eeea3ce19c 100644
--- a/spec/frontend/notes/components/note_form_spec.js
+++ b/spec/frontend/notes/components/note_form_spec.js
@@ -66,13 +66,13 @@ describe('issue_note_form component', () => {
   it('hides content editor switcher if feature flag content_editor_on_issues is off', () => {
     createComponentWrapper({}, { contentEditorOnIssues: false });
 
-    expect(wrapper.text()).not.toContain('Rich text');
+    expect(wrapper.text()).not.toContain('Switch to rich text');
   });
 
   it('shows content editor switcher if feature flag content_editor_on_issues is on', () => {
     createComponentWrapper({}, { contentEditorOnIssues: true });
 
-    expect(wrapper.text()).toContain('Rich text');
+    expect(wrapper.text()).toContain('Switch to rich text');
   });
 
   describe('conflicts editing', () => {
diff --git a/spec/frontend/shortcuts_spec.js b/spec/frontend/shortcuts_spec.js
index 52615ac3c65adbdc3c2670e65a5866537dfd153e..e72de11d9219c34eee77f655c78647c4c8d032e2 100644
--- a/spec/frontend/shortcuts_spec.js
+++ b/spec/frontend/shortcuts_spec.js
@@ -1,11 +1,10 @@
 import $ from 'jquery';
-import htmlSnippetsShow from 'test_fixtures/snippets/show.html';
 import { flatten } from 'lodash';
+import htmlSnippetsShow from 'test_fixtures/snippets/show.html';
 import { Mousetrap } from '~/lib/mousetrap';
 import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
 import Shortcuts, { LOCAL_MOUSETRAP_DATA_KEY } from '~/behaviors/shortcuts/shortcuts';
-
-jest.mock('mousetrap/plugins/pause/mousetrap-pause', () => {});
+import MarkdownPreview from '~/behaviors/preview_markdown';
 
 describe('Shortcuts', () => {
   const createEvent = (type, target) =>
@@ -21,6 +20,9 @@ describe('Shortcuts', () => {
   beforeEach(() => {
     setHTMLFixture(htmlSnippetsShow);
 
+    new Shortcuts(); // eslint-disable-line no-new
+    new MarkdownPreview(); // eslint-disable-line no-new
+
     jest.spyOn(document.querySelector('.js-new-note-form .js-md-preview-button'), 'focus');
     jest.spyOn(document.querySelector('.edit-note .js-md-preview-button'), 'focus');
     jest.spyOn(document.querySelector('#search'), 'focus');
diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
index 7eb0468c5bee574dfa9e26e7473c7b49c968c58d..af4af45109c11b9f949631f6be8bdcd52870525c 100644
--- a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
+++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
@@ -90,7 +90,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
       </div>
        
       <div
-        class="js-vue-md-preview md md-preview-holder"
+        class="js-vue-md-preview md md-preview-holder gl-px-5"
         style="display: none;"
       />
        
diff --git a/spec/frontend/vue_shared/components/markdown/editor_mode_dropdown_spec.js b/spec/frontend/vue_shared/components/markdown/editor_mode_dropdown_spec.js
deleted file mode 100644
index fd8493e0911e2905d533da2e9b5fa1f86122de48..0000000000000000000000000000000000000000
--- a/spec/frontend/vue_shared/components/markdown/editor_mode_dropdown_spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import EditorModeDropdown from '~/vue_shared/components/markdown/editor_mode_dropdown.vue';
-
-describe('vue_shared/component/markdown/editor_mode_dropdown', () => {
-  let wrapper;
-
-  const createComponent = ({ value, size } = {}) => {
-    wrapper = shallowMount(EditorModeDropdown, {
-      propsData: {
-        value,
-        size,
-      },
-    });
-  };
-
-  const findDropdown = () => wrapper.findComponent(GlDropdown);
-  const findDropdownItem = (text) =>
-    wrapper
-      .findAllComponents(GlDropdownItem)
-      .filter((item) => item.text().startsWith(text))
-      .at(0);
-
-  describe.each`
-    modeText       | value         | dropdownText           | otherMode
-    ${'Rich text'} | ${'richText'} | ${'Editing rich text'} | ${'Markdown'}
-    ${'Markdown'}  | ${'markdown'} | ${'Editing markdown'}  | ${'Rich text'}
-  `('$modeText', ({ modeText, value, dropdownText, otherMode }) => {
-    beforeEach(() => {
-      createComponent({ value });
-    });
-
-    it('shows correct dropdown label', () => {
-      expect(findDropdown().props('text')).toEqual(dropdownText);
-    });
-
-    it('checks correct checked dropdown item', () => {
-      expect(findDropdownItem(modeText).props().isChecked).toBe(true);
-      expect(findDropdownItem(otherMode).props().isChecked).toBe(false);
-    });
-
-    it('emits event on click', () => {
-      findDropdownItem(modeText).vm.$emit('click');
-
-      expect(wrapper.emitted().input).toEqual([[value]]);
-    });
-  });
-
-  it('passes size to dropdown', () => {
-    createComponent({ size: 'small', value: 'markdown' });
-
-    expect(findDropdown().props('size')).toEqual('small');
-  });
-});
diff --git a/spec/frontend/vue_shared/components/markdown/editor_mode_switcher_spec.js b/spec/frontend/vue_shared/components/markdown/editor_mode_switcher_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..693353ed604261050841e56add426cd7a6b6223d
--- /dev/null
+++ b/spec/frontend/vue_shared/components/markdown/editor_mode_switcher_spec.js
@@ -0,0 +1,37 @@
+import { GlButton } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import EditorModeSwitcher from '~/vue_shared/components/markdown/editor_mode_switcher.vue';
+
+describe('vue_shared/component/markdown/editor_mode_switcher', () => {
+  let wrapper;
+
+  const createComponent = ({ value } = {}) => {
+    wrapper = shallowMount(EditorModeSwitcher, {
+      propsData: {
+        value,
+      },
+    });
+  };
+
+  const findSwitcherButton = () => wrapper.findComponent(GlButton);
+
+  describe.each`
+    modeText       | value         | buttonText
+    ${'Rich text'} | ${'richText'} | ${'Switch to Markdown'}
+    ${'Markdown'}  | ${'markdown'} | ${'Switch to rich text'}
+  `('when $modeText', ({ modeText, value, buttonText }) => {
+    beforeEach(() => {
+      createComponent({ value });
+    });
+
+    it('shows correct button label', () => {
+      expect(findSwitcherButton().text()).toEqual(buttonText);
+    });
+
+    it('emits event on click', () => {
+      findSwitcherButton(modeText).vm.$emit('click');
+
+      expect(wrapper.emitted().input).toEqual([[]]);
+    });
+  });
+});
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
index 68ce07f86b98033f8957ce3b1c57d0fcdb3eb3e1..b29f0d58d777b2152247adcc9fca5288b9b9e488 100644
--- a/spec/frontend/vue_shared/components/markdown/field_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -18,12 +18,6 @@ const textareaValue = 'testing\n123';
 const uploadsPath = 'test/uploads';
 const restrictedToolBarItems = ['quote'];
 
-function assertMarkdownTabs(isWrite, writeLink, previewLink, wrapper) {
-  expect(writeLink.element.children[0].classList.contains('active')).toBe(isWrite);
-  expect(previewLink.element.children[0].classList.contains('active')).toBe(!isWrite);
-  expect(wrapper.find('.md-preview-holder').element.style.display).toBe(isWrite ? 'none' : '');
-}
-
 describe('Markdown field component', () => {
   let axiosMock;
   let subject;
@@ -92,8 +86,7 @@ describe('Markdown field component', () => {
     });
   }
 
-  const getPreviewLink = () => subject.findByTestId('preview-tab');
-  const getWriteLink = () => subject.findByTestId('write-tab');
+  const getPreviewToggle = () => subject.findByTestId('preview-toggle');
   const getMarkdownButton = () => subject.find('.js-md');
   const getListBulletedButton = () => subject.findAll('.js-md[title="Add a bullet list"]');
   const getVideo = () => subject.find('video');
@@ -109,8 +102,7 @@ describe('Markdown field component', () => {
     <p>markdown preview</p>
     <video src="${FIXTURES_PATH}/static/mock-video.mp4"></video>
   `;
-    let previewLink;
-    let writeLink;
+    let previewToggle;
     let dropzoneSpy;
 
     beforeEach(() => {
@@ -140,8 +132,8 @@ describe('Markdown field component', () => {
         .onPost(markdownPreviewPath)
         .reply(HTTP_STATUS_OK, { references: { users: [], commands: 'test command' } });
 
-      previewLink = getPreviewLink();
-      previewLink.vm.$emit('click', { target: {} });
+      previewToggle = getPreviewToggle();
+      previewToggle.vm.$emit('click', true);
 
       await axios.waitFor(markdownPreviewPath);
       const referencedCommands = subject.find('[data-testid="referenced-commands"]');
@@ -155,26 +147,29 @@ describe('Markdown field component', () => {
         axiosMock.onPost(markdownPreviewPath).reply(HTTP_STATUS_OK, { body: previewHTML });
       });
 
-      it('sets preview link as active', async () => {
-        previewLink = getPreviewLink();
-        previewLink.vm.$emit('click', { target: {} });
+      it('sets preview toggle as active', async () => {
+        previewToggle = getPreviewToggle();
+
+        expect(previewToggle.text()).toBe('Preview');
+
+        previewToggle.vm.$emit('click', true);
 
         await nextTick();
-        expect(previewLink.element.children[0].classList.contains('active')).toBe(true);
+        expect(previewToggle.text()).toBe('Continue editing');
       });
 
       it('shows preview loading text', async () => {
-        previewLink = getPreviewLink();
-        previewLink.vm.$emit('click', { target: {} });
+        previewToggle = getPreviewToggle();
+        previewToggle.vm.$emit('click', true);
 
         await nextTick();
         expect(subject.find('.md-preview-holder').element.textContent.trim()).toContain('Loading…');
       });
 
       it('renders markdown preview and GFM', async () => {
-        previewLink = getPreviewLink();
+        previewToggle = getPreviewToggle();
 
-        previewLink.vm.$emit('click', { target: {} });
+        previewToggle.vm.$emit('click', true);
 
         await axios.waitFor(markdownPreviewPath);
         expect(subject.find('.md-preview-holder').element.innerHTML).toContain(previewHTML);
@@ -182,8 +177,8 @@ describe('Markdown field component', () => {
       });
 
       it('calls video.pause() on comment input when isSubmitting is changed to true', async () => {
-        previewLink = getPreviewLink();
-        previewLink.vm.$emit('click', { target: {} });
+        previewToggle = getPreviewToggle();
+        previewToggle.vm.$emit('click', true);
 
         await axios.waitFor(markdownPreviewPath);
         const video = getVideo();
@@ -195,34 +190,27 @@ describe('Markdown field component', () => {
         expect(callPause).toHaveBeenCalled();
       });
 
-      it('clicking already active write or preview link does nothing', async () => {
-        writeLink = getWriteLink();
-        previewLink = getPreviewLink();
-
-        writeLink.vm.$emit('click', { target: {} });
-        await nextTick();
-
-        assertMarkdownTabs(true, writeLink, previewLink, subject);
-        writeLink.vm.$emit('click', { target: {} });
-        await nextTick();
+      it('switches between preview/write on toggle', async () => {
+        previewToggle = getPreviewToggle();
 
-        assertMarkdownTabs(true, writeLink, previewLink, subject);
-        previewLink.vm.$emit('click', { target: {} });
+        previewToggle.vm.$emit('click', true);
         await nextTick();
+        expect(subject.find('.md-preview-holder').element.style.display).toBe(''); // visible
 
-        assertMarkdownTabs(false, writeLink, previewLink, subject);
-        previewLink.vm.$emit('click', { target: {} });
+        previewToggle.vm.$emit('click', false);
         await nextTick();
-
-        assertMarkdownTabs(false, writeLink, previewLink, subject);
+        expect(subject.find('.md-preview-holder').element.style.display).toBe('none');
       });
 
-      it('passes correct props to MarkdownToolbar', () => {
+      it('passes correct props to MarkdownHeader and MarkdownToolbar', () => {
         expect(findMarkdownToolbar().props()).toEqual({
           canAttachFile: true,
           markdownDocsPath,
           quickActionsDocsPath: '',
           showCommentToolBar: true,
+        });
+
+        expect(findMarkdownHeader().props()).toMatchObject({
           showContentEditorSwitcher: false,
         });
       });
@@ -380,13 +368,13 @@ describe('Markdown field component', () => {
     it('defaults to false', () => {
       createSubject();
 
-      expect(findMarkdownToolbar().props('showContentEditorSwitcher')).toBe(false);
+      expect(findMarkdownHeader().props('showContentEditorSwitcher')).toBe(false);
     });
 
     it('passes showContentEditorSwitcher', () => {
       createSubject({ showContentEditorSwitcher: true });
 
-      expect(findMarkdownToolbar().props('showContentEditorSwitcher')).toBe(true);
+      expect(findMarkdownHeader().props('showContentEditorSwitcher')).toBe(true);
     });
   });
 });
diff --git a/spec/frontend/vue_shared/components/markdown/header_spec.js b/spec/frontend/vue_shared/components/markdown/header_spec.js
index 68f05e5119d0d0f6e7e89ca984aa9de94b116792..48fe5452e7485f3d52625a8a3fdffa09f9e03fbc 100644
--- a/spec/frontend/vue_shared/components/markdown/header_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/header_spec.js
@@ -1,10 +1,11 @@
 import $ from 'jquery';
 import { nextTick } from 'vue';
-import { GlTabs } from '@gitlab/ui';
+import { GlToggle } from '@gitlab/ui';
 import HeaderComponent from '~/vue_shared/components/markdown/header.vue';
 import ToolbarButton from '~/vue_shared/components/markdown/toolbar_button.vue';
 import DrawioToolbarButton from '~/vue_shared/components/markdown/drawio_toolbar_button.vue';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import EditorModeSwitcher from '~/vue_shared/components/markdown/editor_mode_switcher.vue';
 
 describe('Markdown field header component', () => {
   let wrapper;
@@ -15,12 +16,11 @@ describe('Markdown field header component', () => {
         previewMarkdown: false,
         ...props,
       },
-      stubs: { GlTabs },
+      stubs: { GlToggle },
     });
   };
 
-  const findWriteTab = () => wrapper.findByTestId('write-tab');
-  const findPreviewTab = () => wrapper.findByTestId('preview-tab');
+  const findPreviewToggle = () => wrapper.findByTestId('preview-toggle');
   const findToolbar = () => wrapper.findByTestId('md-header-toolbar');
   const findToolbarButtons = () => wrapper.findAllComponents(ToolbarButton);
   const findToolbarButtonByProp = (prop, value) =>
@@ -87,16 +87,14 @@ describe('Markdown field header component', () => {
     });
   });
 
-  it('activates `write` tab when previewMarkdown is false', () => {
-    expect(findWriteTab().attributes('active')).toBe('true');
-    expect(findPreviewTab().attributes('active')).toBeUndefined();
+  it('hides markdown preview when previewMarkdown is false', () => {
+    expect(findPreviewToggle().text()).toBe('Preview');
   });
 
-  it('activates `preview` tab when previewMarkdown is true', () => {
+  it('shows markdown preview when previewMarkdown is true', () => {
     createWrapper({ previewMarkdown: true });
 
-    expect(findWriteTab().attributes('active')).toBeUndefined();
-    expect(findPreviewTab().attributes('active')).toBe('true');
+    expect(findPreviewToggle().text()).toBe('Continue editing');
   });
 
   it('hides toolbar in preview mode', () => {
@@ -105,17 +103,16 @@ describe('Markdown field header component', () => {
     expect(findToolbar().classes().includes('gl-display-none!')).toBe(true);
   });
 
-  it('emits toggle markdown event when clicking preview tab', async () => {
-    const eventData = { target: {} };
-    findPreviewTab().vm.$emit('click', eventData);
+  it('emits toggle markdown event when clicking preview toggle', async () => {
+    findPreviewToggle().vm.$emit('click', true);
 
     await nextTick();
-    expect(wrapper.emitted('preview-markdown').length).toEqual(1);
+    expect(wrapper.emitted('showPreview').length).toEqual(1);
 
-    findWriteTab().vm.$emit('click', eventData);
+    findPreviewToggle().vm.$emit('click', false);
 
     await nextTick();
-    expect(wrapper.emitted('write-markdown').length).toEqual(1);
+    expect(wrapper.emitted('showPreview').length).toEqual(2);
   });
 
   it('does not emit toggle markdown event when triggered from another form', () => {
@@ -125,15 +122,8 @@ describe('Markdown field header component', () => {
       ),
     ]);
 
-    expect(wrapper.emitted('preview-markdown')).toBeUndefined();
-    expect(wrapper.emitted('write-markdown')).toBeUndefined();
-  });
-
-  it('blurs preview link after click', () => {
-    const target = { blur: jest.fn() };
-    findPreviewTab().vm.$emit('click', { target });
-
-    expect(target.blur).toHaveBeenCalled();
+    expect(wrapper.emitted('showPreview')).toBeUndefined();
+    expect(wrapper.emitted('hidePreview')).toBeUndefined();
   });
 
   it('renders markdown table template', () => {
@@ -166,12 +156,12 @@ describe('Markdown field header component', () => {
     expect(wrapper.find('.js-suggestion-btn').exists()).toBe(false);
   });
 
-  it('hides preview tab when previewMarkdown property is false', () => {
+  it('hides markdown preview when previewMarkdown property is false', () => {
     createWrapper({
       enablePreview: false,
     });
 
-    expect(wrapper.findByTestId('preview-tab').exists()).toBe(false);
+    expect(wrapper.findByTestId('preview-toggle').exists()).toBe(false);
   });
 
   describe('restricted tool bar items', () => {
@@ -215,4 +205,18 @@ describe('Markdown field header component', () => {
       });
     });
   });
+
+  describe('with content editor switcher', () => {
+    beforeEach(() => {
+      createWrapper({
+        showContentEditorSwitcher: true,
+      });
+    });
+
+    it('re-emits event from switcher', () => {
+      wrapper.findComponent(EditorModeSwitcher).vm.$emit('input', 'richText');
+
+      expect(wrapper.emitted('enableContentEditor')).toEqual([[]]);
+    });
+  });
 });
diff --git a/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js b/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js
index 63a689088c78c7ffa365febc4193b1518cf6cfab..dec2327db0f426b59eaaa0bf3cd9a54163b8f860 100644
--- a/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js
@@ -122,13 +122,13 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
   it('enables content editor switcher when contentEditorEnabled prop is true', () => {
     buildWrapper({ propsData: { enableContentEditor: true } });
 
-    expect(findMarkdownField().text()).toContain('Rich text');
+    expect(findMarkdownField().text()).toContain('Switch to rich text');
   });
 
   it('hides content editor switcher when contentEditorEnabled prop is false', () => {
     buildWrapper({ propsData: { enableContentEditor: false } });
 
-    expect(findMarkdownField().text()).not.toContain('Rich text');
+    expect(findMarkdownField().text()).not.toContain('Switch to rich text');
   });
 
   it('passes down any additional props to markdown field component', () => {
diff --git a/spec/frontend/vue_shared/components/markdown/toolbar_spec.js b/spec/frontend/vue_shared/components/markdown/toolbar_spec.js
index fea14f80496a907febdbf39a7ea8e439c2f4c274..2489421b697194d458c4f12f18e9f2cb22dbea68 100644
--- a/spec/frontend/vue_shared/components/markdown/toolbar_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/toolbar_spec.js
@@ -1,6 +1,5 @@
 import { mount } from '@vue/test-utils';
 import Toolbar from '~/vue_shared/components/markdown/toolbar.vue';
-import EditorModeDropdown from '~/vue_shared/components/markdown/editor_mode_dropdown.vue';
 
 describe('toolbar', () => {
   let wrapper;
@@ -44,18 +43,4 @@ describe('toolbar', () => {
       expect(wrapper.find('.comment-toolbar').exists()).toBe(true);
     });
   });
-
-  describe('with content editor switcher', () => {
-    beforeEach(() => {
-      createMountedWrapper({
-        showContentEditorSwitcher: true,
-      });
-    });
-
-    it('re-emits event from switcher', () => {
-      wrapper.findComponent(EditorModeDropdown).vm.$emit('input', 'richText');
-
-      expect(wrapper.emitted('enableContentEditor')).toEqual([[]]);
-    });
-  });
 });
diff --git a/spec/support/helpers/content_editor_helpers.rb b/spec/support/helpers/content_editor_helpers.rb
index 1bbc05cc05ac64213911150da205a3d053f54d9f..f19af0c9af8d459f38a67f51a9ef226098021c3c 100644
--- a/spec/support/helpers/content_editor_helpers.rb
+++ b/spec/support/helpers/content_editor_helpers.rb
@@ -2,8 +2,7 @@
 
 module ContentEditorHelpers
   def switch_to_content_editor
-    click_button _('Editing markdown')
-    click_button _('Rich text')
+    click_button("Switch to rich text")
   end
 
   def type_in_content_editor(keys)
diff --git a/spec/support/helpers/features/notes_helpers.rb b/spec/support/helpers/features/notes_helpers.rb
index 78774b515df9aeb6f46352917e6177e331f427fc..7973d541f9c7b60066db812d423845dff1e327f2 100644
--- a/spec/support/helpers/features/notes_helpers.rb
+++ b/spec/support/helpers/features/notes_helpers.rb
@@ -41,7 +41,7 @@ def preview_note(text)
         wait_for_requests
         filled_text.send_keys(:escape)
 
-        click_on('Preview')
+        click_button("Preview")
 
         yield if block_given?
       end
diff --git a/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb b/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb
index d2dfb468485893c566459166c67634962700cc54..2bcbd5e51905dd3386a91d2203a0b9a32c64a2b7 100644
--- a/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb
+++ b/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb
@@ -104,8 +104,8 @@
     fill_in 'merge_request_description', with: long_description
 
     height = get_textarea_height
-    find('.js-md-preview-button').click
-    find('.js-md-write-button').click
+    click_button("Preview")
+    click_button("Continue editing")
     new_height = get_textarea_height
 
     expect(height).to eq(new_height)
diff --git a/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb b/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb
index 7a3b94ad81df22987422a8e9e2e1315cd4f5bbd2..6451c531aecb0af1f4d708ddc792b73516db7627 100644
--- a/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb
@@ -62,7 +62,7 @@ def attach_with_dropzone(wait = false)
         attach_with_dropzone(true)
         wait_for_requests
 
-        find('.js-md-preview-button').click
+        click_button("Preview")
         file_path = page.find('input[name="files[]"]', visible: :hidden).value
         link = page.find('a.no-attachment-icon')['href']
         img_link = page.find('a.no-attachment-icon img')['src']
diff --git a/spec/support/shared_examples/features/wiki/user_previews_wiki_changes_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_previews_wiki_changes_shared_examples.rb
index 3e285bb8ad7920aae922b97462ee08d47bb72ba5..ca68df9a89ba475ea5d761dfec4f7671dbb51aef 100644
--- a/spec/support/shared_examples/features/wiki/user_previews_wiki_changes_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_previews_wiki_changes_shared_examples.rb
@@ -78,7 +78,7 @@ def relative_path(path)
 
     it_behaves_like 'relative links' do
       before do
-        click_on 'Preview'
+        click_button("Preview")
       end
 
       let(:element) { preview }
@@ -88,7 +88,7 @@ def relative_path(path)
       # using two `\n` ensures we're sublist to it's own line due
       # to list auto-continue
       fill_in :wiki_content, with: "1. one\n\n  - sublist\n"
-      click_on "Preview"
+      click_button("Preview")
 
       # the above generates two separate lists (not embedded) in CommonMark
       expect(preview).to have_content("sublist")
@@ -102,7 +102,7 @@ def relative_path(path)
         [[also_do_not_linkify]]
         ```
       HEREDOC
-      click_on "Preview"
+      click_button("Preview")
 
       expect(preview).to have_content("do_not_linkify")
       expect(preview).to have_content('[[do_not_linkify]]')