diff --git a/backport-changelog/6.6/6731.md b/backport-changelog/6.6/6731.md
new file mode 100644
index 00000000000000..b8671873251659
--- /dev/null
+++ b/backport-changelog/6.6/6731.md
@@ -0,0 +1,3 @@
+https://github.com/WordPress/wordpress-develop/pull/6731
+
+* https://github.com/WordPress/gutenberg/pull/62299
diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php
index 3f45b137d186d2..ad4a9f21872bec 100644
--- a/lib/class-wp-theme-json-gutenberg.php
+++ b/lib/class-wp-theme-json-gutenberg.php
@@ -3559,53 +3559,32 @@ public static function get_from_editor_settings( $settings ) {
 
 		// Deprecated theme supports.
 		if ( isset( $settings['disableCustomColors'] ) ) {
-			if ( ! isset( $theme_settings['settings']['color'] ) ) {
-				$theme_settings['settings']['color'] = array();
-			}
 			$theme_settings['settings']['color']['custom'] = ! $settings['disableCustomColors'];
 		}
 
 		if ( isset( $settings['disableCustomGradients'] ) ) {
-			if ( ! isset( $theme_settings['settings']['color'] ) ) {
-				$theme_settings['settings']['color'] = array();
-			}
 			$theme_settings['settings']['color']['customGradient'] = ! $settings['disableCustomGradients'];
 		}
 
 		if ( isset( $settings['disableCustomFontSizes'] ) ) {
-			if ( ! isset( $theme_settings['settings']['typography'] ) ) {
-				$theme_settings['settings']['typography'] = array();
-			}
 			$theme_settings['settings']['typography']['customFontSize'] = ! $settings['disableCustomFontSizes'];
 		}
 
 		if ( isset( $settings['enableCustomLineHeight'] ) ) {
-			if ( ! isset( $theme_settings['settings']['typography'] ) ) {
-				$theme_settings['settings']['typography'] = array();
-			}
 			$theme_settings['settings']['typography']['lineHeight'] = $settings['enableCustomLineHeight'];
 		}
 
 		if ( isset( $settings['enableCustomUnits'] ) ) {
-			if ( ! isset( $theme_settings['settings']['spacing'] ) ) {
-				$theme_settings['settings']['spacing'] = array();
-			}
 			$theme_settings['settings']['spacing']['units'] = ( true === $settings['enableCustomUnits'] ) ?
 				array( 'px', 'em', 'rem', 'vh', 'vw', '%' ) :
 				$settings['enableCustomUnits'];
 		}
 
 		if ( isset( $settings['colors'] ) ) {
-			if ( ! isset( $theme_settings['settings']['color'] ) ) {
-				$theme_settings['settings']['color'] = array();
-			}
 			$theme_settings['settings']['color']['palette'] = $settings['colors'];
 		}
 
 		if ( isset( $settings['gradients'] ) ) {
-			if ( ! isset( $theme_settings['settings']['color'] ) ) {
-				$theme_settings['settings']['color'] = array();
-			}
 			$theme_settings['settings']['color']['gradients'] = $settings['gradients'];
 		}
 
@@ -3617,23 +3596,14 @@ public static function get_from_editor_settings( $settings ) {
 					$font_sizes[ $key ]['size'] = $font_size['size'] . 'px';
 				}
 			}
-			if ( ! isset( $theme_settings['settings']['typography'] ) ) {
-				$theme_settings['settings']['typography'] = array();
-			}
 			$theme_settings['settings']['typography']['fontSizes'] = $font_sizes;
 		}
 
 		if ( isset( $settings['enableCustomSpacing'] ) ) {
-			if ( ! isset( $theme_settings['settings']['spacing'] ) ) {
-				$theme_settings['settings']['spacing'] = array();
-			}
 			$theme_settings['settings']['spacing']['padding'] = $settings['enableCustomSpacing'];
 		}
 
 		if ( isset( $settings['spacingSizes'] ) ) {
-			if ( ! isset( $theme_settings['settings']['spacing'] ) ) {
-				$theme_settings['settings']['spacing'] = array();
-			}
 			$theme_settings['settings']['spacing']['spacingSizes'] = $settings['spacingSizes'];
 		}
 
@@ -3801,12 +3771,10 @@ public function get_data() {
 	/**
 	 * Sets the spacingSizes array based on the spacingScale values from theme.json.
 	 *
-	 * No longer used since theme.json version 3 as the spacingSizes are now
-	 * automatically generated during construction and merge instead of manually
-	 * set in the resolver.
-	 *
 	 * @since 6.1.0
-	 * @deprecated 6.6.0
+	 * @deprecated 6.6.0 No longer used as the spacingSizes are automatically
+	 *                   generated in the constructor and merge methods instead
+	 *                   of manually after instantiation.
 	 *
 	 * @return null|void
 	 */
diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php
index 28121cf1b8c8a0..a02ae74a91fdac 100644
--- a/lib/class-wp-theme-json-resolver-gutenberg.php
+++ b/lib/class-wp-theme-json-resolver-gutenberg.php
@@ -294,59 +294,25 @@ public static function get_theme_data( $deprecated = array(), $options = array()
 		 */
 		$theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( gutenberg_get_classic_theme_supports_block_editor_settings() );
 		if ( ! wp_theme_has_theme_json() ) {
-			if ( ! isset( $theme_support_data['settings']['color'] ) ) {
-				$theme_support_data['settings']['color'] = array();
-			}
-
-			$default_palette = false;
-			if ( current_theme_supports( 'default-color-palette' ) ) {
-				$default_palette = true;
-			}
-			if ( ! isset( $theme_support_data['settings']['color']['palette'] ) ) {
-				// If the theme does not have any palette, we still want to show the core one.
-				$default_palette = true;
-			}
-			$theme_support_data['settings']['color']['defaultPalette'] = $default_palette;
-
-			$default_gradients = false;
-			if ( current_theme_supports( 'default-gradient-presets' ) ) {
-				$default_gradients = true;
-			}
-			if ( ! isset( $theme_support_data['settings']['color']['gradients'] ) ) {
-				// If the theme does not have any gradients, we still want to show the core ones.
-				$default_gradients = true;
-			}
-			$theme_support_data['settings']['color']['defaultGradients'] = $default_gradients;
-
-			if ( ! isset( $theme_support_data['settings']['typography'] ) ) {
-				$theme_support_data['settings']['typography'] = array();
-			}
-			$default_font_sizes = false;
-			if ( current_theme_supports( 'default-font-sizes' ) ) {
-				$default_font_sizes = true;
-			}
-			if ( ! isset( $theme_support_data['settings']['typography']['fontSizes'] ) ) {
-				// If the theme does not have any font sizes, we still want to show the core one.
-				$default_font_sizes = true;
-			}
-			$theme_support_data['settings']['typography']['defaultFontSizes'] = $default_font_sizes;
-
-			if ( ! isset( $theme_support_data['settings']['spacing'] ) ) {
-				$theme_support_data['settings']['spacing'] = array();
-			}
-			$default_spacing_sizes = false;
-			if ( current_theme_supports( 'default-spacing-sizes' ) ) {
-				$default_spacing_sizes = true;
-			}
-			if ( ! isset( $theme_support_data['settings']['spacing']['spacingSizes'] ) ) {
-				// If the theme does not have any spacing sizes, we still want to show the core one.
-				$default_spacing_sizes = true;
-			}
-			$theme_support_data['settings']['spacing']['defaultSpacingSizes'] = $default_spacing_sizes;
+			/*
+			 * Unlike block themes, classic themes without a theme.json disable
+			 * default presets when custom preset theme support is added. This
+			 * behavior can be overridden by using the corresponding default
+			 * preset theme support.
+			 */
+			$theme_support_data['settings']['color']['defaultPalette']        =
+				! isset( $theme_support_data['settings']['color']['palette'] ) ||
+				current_theme_supports( 'default-color-palette' );
+			$theme_support_data['settings']['color']['defaultGradients']      =
+				! isset( $theme_support_data['settings']['color']['gradients'] ) ||
+				current_theme_supports( 'default-gradient-presets' );
+			$theme_support_data['settings']['typography']['defaultFontSizes'] =
+				! isset( $theme_support_data['settings']['typography']['fontSizes'] ) ||
+				current_theme_supports( 'default-font-sizes' );
+			$theme_support_data['settings']['spacing']['defaultSpacingSizes'] =
+				! isset( $theme_support_data['settings']['spacing']['spacingSizes'] ) ||
+				current_theme_supports( 'default-spacing-sizes' );
 
-			if ( ! isset( $theme_support_data['settings']['shadow'] ) ) {
-				$theme_support_data['settings']['shadow'] = array();
-			}
 			/*
 			 * Shadow presets are explicitly disabled for classic themes until a
 			 * decision is made for whether the default presets should match the
diff --git a/lib/class-wp-theme-json-schema-gutenberg.php b/lib/class-wp-theme-json-schema-gutenberg.php
index 0def88f86a23a7..43b6ea6dcc7410 100644
--- a/lib/class-wp-theme-json-schema-gutenberg.php
+++ b/lib/class-wp-theme-json-schema-gutenberg.php
@@ -55,10 +55,9 @@ public static function migrate( $theme_json ) {
 		switch ( $theme_json['version'] ) {
 			case 1:
 				$theme_json = self::migrate_v1_to_v2( $theme_json );
-				// no break
+				// Deliberate fall through. Once migrated to v2, also migrate to v3.
 			case 2:
 				$theme_json = self::migrate_v2_to_v3( $theme_json );
-				// no break
 		}
 
 		return $theme_json;
@@ -97,7 +96,10 @@ private static function migrate_v1_to_v2( $old ) {
 	/**
 	 * Migrates from v2 to v3.
 	 *
-	 * - Sets settings.typography.defaultFontSizes to false.
+	 * - Sets settings.typography.defaultFontSizes to false if settings.typography.fontSizes are defined.
+	 * - Sets settings.spacing.defaultSpacingSizes to false if settings.spacing.spacingSizes are defined.
+	 * - Prevents settings.spacing.spacingSizes from merging with settings.spacing.spacingScale by
+	 *   unsetting spacingScale when spacingSizes are defined.
 	 *
 	 * @since 6.6.0
 	 *
@@ -132,12 +134,6 @@ private static function migrate_v2_to_v3( $old ) {
 		 * when the theme did not provide any.
 		 */
 		if ( isset( $old['settings']['typography']['fontSizes'] ) ) {
-			if ( ! isset( $new['settings'] ) ) {
-				$new['settings'] = array();
-			}
-			if ( ! isset( $new['settings']['typography'] ) ) {
-				$new['settings']['typography'] = array();
-			}
 			$new['settings']['typography']['defaultFontSizes'] = false;
 		}
 
@@ -151,12 +147,6 @@ private static function migrate_v2_to_v3( $old ) {
 			isset( $old['settings']['spacing']['spacingSizes'] ) ||
 			isset( $old['settings']['spacing']['spacingScale'] )
 		) {
-			if ( ! isset( $new['settings'] ) ) {
-				$new['settings'] = array();
-			}
-			if ( ! isset( $new['settings']['spacing'] ) ) {
-				$new['settings']['spacing'] = array();
-			}
 			$new['settings']['spacing']['defaultSpacingSizes'] = false;
 		}