diff --git a/package.json b/package.json
index f84e4eb040..f0ca3fcd6e 100644
--- a/package.json
+++ b/package.json
@@ -186,6 +186,7 @@
 		"env:cli": "node ./tools/local-env/scripts/docker.js exec --user wp_php cli wp",
 		"env:logs": "node ./tools/local-env/scripts/docker.js logs",
 		"env:pull": "node ./tools/local-env/scripts/docker.js pull",
+		"env:composer": "node ./tools/local-env/scripts/docker.js run -T --rm php composer",
 		"test:performance": "wp-scripts test-playwright --config tests/performance/playwright.config.js",
 		"test:php": "node ./tools/local-env/scripts/docker.js run --rm php ./vendor/bin/phpunit",
 		"test:coverage": "npm run test:php -- --coverage-html ./coverage/html/ --coverage-php ./coverage/php/report.php --coverage-text=./coverage/text/report.txt",
diff --git a/src/js/_enqueues/admin/tags.js b/src/js/_enqueues/admin/tags.js
index 3b6cf2b489..ff7761adb8 100644
--- a/src/js/_enqueues/admin/tags.js
+++ b/src/js/_enqueues/admin/tags.js
@@ -31,6 +31,12 @@ jQuery( function($) {
 		if ( r ) {
 			data = t.attr('href').replace(/[^?]*\?/, '').replace(/action=delete/, 'action=delete-tag');
 
+			tr.children().css('backgroundColor', '#faafaa');
+
+			// Disable pointer events and all form controls/links in the row
+			tr.css('pointer-events', 'none');
+			tr.find(':input, a').prop('disabled', true).attr('tabindex', -1);
+
 			/**
 			 * Makes a request to the server to delete the term that corresponds to the
 			 * delete term button.
@@ -40,8 +46,20 @@ jQuery( function($) {
 			 * @return {void}
 			 */
 			$.post(ajaxurl, data, function(r){
+				var message;
 				if ( '1' == r ) {
 					$('#ajax-response').empty();
+					let nextFocus = tr.next( 'tr' ).find( 'a.row-title' );
+					let prevFocus = tr.prev( 'tr' ).find( 'a.row-title' );
+					// If there is neither a next row or a previous row, focus the tag input field.
+					if ( nextFocus.length < 1 && prevFocus.length < 1 ) {
+						nextFocus = $( '#tag-name' ).trigger( 'focus' );
+					} else {
+						if ( nextFocus.length < 1 ) {
+							nextFocus = prevFocus;
+						}
+					}
+
 					tr.fadeOut('normal', function(){ tr.remove(); });
 
 					/**
@@ -53,23 +71,38 @@ jQuery( function($) {
 					 */
 					$('select#parent option[value="' + data.match(/tag_ID=(\d+)/)[1] + '"]').remove();
 					$('a.tag-link-' + data.match(/tag_ID=(\d+)/)[1]).remove();
-
+					nextFocus.trigger( 'focus' );
+					message = wp.i18n.__( 'The selected tag has been deleted.' );
+			
 				} else if ( '-1' == r ) {
-					$('#ajax-response').empty().append('<div class="notice notice-error"><p>' + wp.i18n.__( 'Sorry, you are not allowed to do that.' ) + '</p></div>');
-					tr.children().css('backgroundColor', '');
+					message = wp.i18n.__( 'Sorry, you are not allowed to do that.' );
+					$('#ajax-response').empty().append('<div class="notice notice-error"><p>' + message + '</p></div>');
+					resetRowAfterFailure( tr );
 
 				} else {
-					$('#ajax-response').empty().append('<div class="notice notice-error"><p>' + wp.i18n.__( 'An error occurred while processing your request. Please try again later.' ) + '</p></div>');
-					tr.children().css('backgroundColor', '');
+					message = wp.i18n.__( 'An error occurred while processing your request. Please try again later.' );
+					$('#ajax-response').empty().append('<div class="notice notice-error"><p>' + message + '</p></div>');
+					resetRowAfterFailure( tr );
 				}
+				wp.a11y.speak( message, 'assertive' );
 			});
-
-			tr.children().css('backgroundColor', '#f33');
 		}
 
 		return false;
 	});
 
+	/**
+	 * Restores the original UI state of a table row after an AJAX failure.
+	 *
+	 * @param {jQuery} tr The table row to reset.
+	 * @return {void}
+	 */
+	function resetRowAfterFailure( tr ) {
+		tr.children().css( 'backgroundColor', '' );
+		tr.css( 'pointer-events', '' );
+		tr.find( ':input, a' ).prop( 'disabled', false ).removeAttr( 'tabindex' );
+	}
+
 	/**
 	 * Adds a deletion confirmation when removing a tag.
 	 *
