diff --git a/.circleci/bazel.rc b/.circleci/bazel.rc
deleted file mode 100644
index b5866269712c..000000000000
--- a/.circleci/bazel.rc
+++ /dev/null
@@ -1,19 +0,0 @@
-# Bazel configuration that will be copied to /etc/bazel.bazelrc in CircleCI containers.
-# This allows us adding specific configuration flags for builds within CircleCI.
-# See more: https://docs.bazel.build/versions/master/user-manual.html#where-are-the-bazelrc-files
-
-# Print all enabled Bazel flags in CI mode. This makes it easier to debug and reproduce
-# Bazel issues that show up on CircleCI.
-common --announce_rc
-
-# Save downloaded repositories in a location that can be cached by CircleCI. This helps us
-# speeding up the analysis time significantly with Bazel managed node dependencies on the CI.
-build --repository_cache=/home/circleci/bazel_repository_cache
-
-# Workaround https://github.com/bazelbuild/bazel/issues/3645. Bazel doesn't calculate the
-# memory ceiling correctly when running under Docker. Limit Bazel to consuming resources that
-# fit in CircleCI "xlarge" class. https://circleci.com/docs/2.0/configuration-reference/#resource_class
-# Note that we use less than the available RAM as bazel only estimates memory for actions
-# and we don't want to accidentally run out of memory.
-build --local_ram_resources=14336
-build --local_cpu_resources=8
diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 9454be12fd03..000000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-# This config is remaining in place to prevent pull requests failing because of CircleCI config missing.
-
-version: 2.1
-
-jobs:
-  pass:
-    docker:
-      - image: cimg/base:2022.05
-    steps:
-      - run: echo "This too shall pass (always)"
-
-workflows:
-  version: 2
-  default_workflow:
-    jobs:
-      - pass
diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml
index 8dabe7245929..2fe989f3df08 100644
--- a/.github/workflows/assistant-to-the-branch-manager.yml
+++ b/.github/workflows/assistant-to-the-branch-manager.yml
@@ -16,6 +16,6 @@ jobs:
       - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
         with:
           persist-credentials: false
-      - uses: angular/dev-infra/github-actions/branch-manager@804107deac3621184db54fab3e7cfe7f735a0d74
+      - uses: angular/dev-infra/github-actions/branch-manager@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index bf3db89a1b31..d6f098068bdc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,7 +21,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Install node modules
@@ -54,13 +54,13 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Check API Goldens
@@ -75,13 +75,13 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run e2e tests
@@ -96,13 +96,13 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run integration tests
@@ -120,13 +120,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run linker AOT tests
@@ -141,13 +141,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run linker JIT tests
@@ -162,13 +162,13 @@ jobs:
     runs-on: ubuntu-latest-16core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run tests
@@ -183,13 +183,13 @@ jobs:
     runs-on: ubuntu-latest-16core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run tests
@@ -204,13 +204,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Build and Verify Release Output
@@ -235,13 +235,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Build and Verify Release Output
@@ -270,15 +270,15 @@ jobs:
       CI_RUNNER_NUMBER: ${{ github.run_id }}
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@40b2cbdbcc40f36f125d721c4e8decd3bb607ea4
         with:
           cache-node-modules: true
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@40b2cbdbcc40f36f125d721c4e8decd3bb607ea4
       - name: Setup Saucelabs Variables
-        uses: angular/dev-infra/github-actions/saucelabs@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/saucelabs@40b2cbdbcc40f36f125d721c4e8decd3bb607ea4
       - name: Run tests on Saucelabs
         run: ./scripts/circleci/run-saucelabs-tests.sh
 
@@ -290,14 +290,14 @@ jobs:
       CI_RUNNER_NUMBER: ${{ github.run_id }}
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
-      - name: Setup Saucelabs Variables
-        uses: angular/dev-infra/github-actions/browserstack@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
+      - name: Setup Browserstack Variables
+        uses: angular/dev-infra/github-actions/browserstack@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Run tests on Browserstack
         run: ./scripts/circleci/run-browserstack-tests.sh
diff --git a/.github/workflows/deploy-dev-app-main-push.yml b/.github/workflows/deploy-dev-app-main-push.yml
index a09b9508a173..66c08c9555df 100644
--- a/.github/workflows/deploy-dev-app-main-push.yml
+++ b/.github/workflows/deploy-dev-app-main-push.yml
@@ -17,13 +17,13 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
 
diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml
index 368b598f55e3..4aaba058fa0f 100644
--- a/.github/workflows/dev-infra.yml
+++ b/.github/workflows/dev-infra.yml
@@ -12,13 +12,13 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
-      - uses: angular/dev-infra/github-actions/commit-message-based-labels@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+      - uses: angular/dev-infra/github-actions/commit-message-based-labels@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
   post_approval_changes:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
-      - uses: angular/dev-infra/github-actions/post-approval-changes@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+      - uses: angular/dev-infra/github-actions/post-approval-changes@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
diff --git a/.github/workflows/google-internal-tests.yml b/.github/workflows/google-internal-tests.yml
index b06078948d9b..ba9ed6831056 100644
--- a/.github/workflows/google-internal-tests.yml
+++ b/.github/workflows/google-internal-tests.yml
@@ -13,7 +13,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0
-      - uses: angular/dev-infra/github-actions/google-internal-tests@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+      - uses: angular/dev-infra/github-actions/google-internal-tests@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           run-tests-guide-url: http://go/angular-material-presubmit
           github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index e648a3a3b29b..e8dc9d40afa0 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -19,7 +19,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Install node modules
@@ -53,13 +53,13 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Check API Goldens
@@ -69,13 +69,13 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run e2e tests
@@ -85,13 +85,13 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run integration tests
@@ -104,13 +104,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run linker AOT tests
@@ -120,13 +120,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run linker JIT tests
@@ -136,13 +136,13 @@ jobs:
     runs-on: ubuntu-latest-16core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run tests
@@ -152,13 +152,13 @@ jobs:
     runs-on: ubuntu-latest-16core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Run tests
@@ -168,13 +168,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Build and Verify Release Output
@@ -198,7 +198,7 @@ jobs:
       CI_RUNNER_NUMBER: ${{ github.run_id }}
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@40b2cbdbcc40f36f125d721c4e8decd3bb607ea4
         with:
           cache-node-modules: true
           # Checking out the pull request commit is intended here as we need to run the changed code tests.
@@ -206,9 +206,9 @@ jobs:
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@40b2cbdbcc40f36f125d721c4e8decd3bb607ea4
       - name: Setup Saucelabs Variables
-        uses: angular/dev-infra/github-actions/saucelabs@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/saucelabs@40b2cbdbcc40f36f125d721c4e8decd3bb607ea4
       - name: Run tests on Saucelabs
         run: ./scripts/circleci/run-saucelabs-tests.sh
 
@@ -220,7 +220,7 @@ jobs:
       CI_RUNNER_NUMBER: ${{ github.run_id }}
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
           # Checking out the pull request commit is intended here as we need to run the changed code tests.
@@ -228,8 +228,8 @@ jobs:
       - name: Install node modules
         run: yarn install --frozen-lockfile
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
-      - name: Setup Saucelabs Variables
-        uses: angular/dev-infra/github-actions/browserstack@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
+      - name: Setup Browserstack Variables
+        uses: angular/dev-infra/github-actions/browserstack@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Run tests on Browserstack
         run: ./scripts/circleci/run-browserstack-tests.sh
diff --git a/.github/workflows/preview-build-dev-app.yml b/.github/workflows/preview-build-dev-app.yml
index a253e82052ad..ad934b43f55b 100644
--- a/.github/workflows/preview-build-dev-app.yml
+++ b/.github/workflows/preview-build-dev-app.yml
@@ -23,18 +23,18 @@ jobs:
       (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'dev-app preview'))
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
 
       # Build the web package
       - run: bazel build //src/dev-app:web_package --symlink_prefix=dist/
 
-      - uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+      - uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           workflow-artifact-name: 'dev-app'
           pull-number: '${{github.event.pull_request.number}}'
diff --git a/.github/workflows/preview-deploy-dev-app.yml b/.github/workflows/preview-deploy-dev-app.yml
index 336a1c78a9d1..010adfb6b4e3 100644
--- a/.github/workflows/preview-deploy-dev-app.yml
+++ b/.github/workflows/preview-deploy-dev-app.yml
@@ -33,7 +33,7 @@ jobs:
           npx -y firebase-tools@latest target:clear --project ${{env.PREVIEW_PROJECT}} hosting dev-app
           npx -y firebase-tools@latest target:apply --project ${{env.PREVIEW_PROJECT}} hosting dev-app ${{env.PREVIEW_SITE}}
 
-      - uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+      - uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           github-token: '${{secrets.GITHUB_TOKEN}}'
           workflow-artifact-name: 'dev-app'
diff --git a/.github/workflows/scheduled-ci.yml b/.github/workflows/scheduled-ci.yml
index 73f49915f634..e51025c8c40c 100644
--- a/.github/workflows/scheduled-ci.yml
+++ b/.github/workflows/scheduled-ci.yml
@@ -19,13 +19,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setting up Angular snapshot builds
         # Angular snapshots must be set up first so that the yarn install properly
         # updates the yarn.lock as expected with the changes
@@ -44,13 +44,13 @@ jobs:
     runs-on: ubuntu-latest-4core
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Setup Bazel
-        uses: angular/dev-infra/github-actions/bazel/setup@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/setup@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setup Bazel RBE
-        uses: angular/dev-infra/github-actions/bazel/configure-remote@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/bazel/configure-remote@359350bbc10aab1bac85d0eec61a53377078ab82
       - name: Setting up Angular snapshot builds
         # Angular snapshots must be set up first so that the yarn install properly
         # updates the yarn.lock as expected with the changes
@@ -71,7 +71,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Initialize environment
-        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@89624a6442b75b5cda33c5e9b5c8c4f87ca4f13d
+        uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@359350bbc10aab1bac85d0eec61a53377078ab82
         with:
           cache-node-modules: true
       - name: Install node modules
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 476abf08ce73..72ed2b2745da 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,78 +1,210 @@
-<a name="18.2.10"></a>
-# 18.2.10 "plastic-monkey" (2024-10-23)
+<a name="19.0.5"></a>
+# 19.0.5 "silk-sky" (2025-01-08)
+### cdk
+| Commit | Type | Description |
+| -- | -- | -- |
+| [64d8df8bd](https://github.com/angular/components/commit/64d8df8bddaae4a046291bf86168d15d7cc7e885) | fix | **menu:** avoid re-opening the menu on enter ([#30263](https://github.com/angular/components/pull/30263)) |
+| [5b04e1733](https://github.com/angular/components/commit/5b04e1733712d51670595e288a7f5ca13745ecf5) | fix | **tree:** expandAll not expanding all nodes ([#30226](https://github.com/angular/components/pull/30226)) |
 ### material
 | Commit | Type | Description |
 | -- | -- | -- |
-| [501faa9a54](https://github.com/angular/components/commit/501faa9a547c043e8abef5cb75acca930f31fa2e) | fix | **chips:** emitting end event multiple times when holding down key ([#29894](https://github.com/angular/components/pull/29894)) |
-| [4a0397a1c7](https://github.com/angular/components/commit/4a0397a1c7527b1e56a1aedebe5dfc262327e134) | fix | **tabs:** remove IE animation workaround ([#29899](https://github.com/angular/components/pull/29899)) |
+| [85c6e54a5](https://github.com/angular/components/commit/85c6e54a559e2be0c778aa6b2a7f4c4aa36b569a) | fix | **datepicker:** simplify DI setup ([#30247](https://github.com/angular/components/pull/30247)) |
+| [1eb6cabcc](https://github.com/angular/components/commit/1eb6cabcc0735643f73180a49017f63b3335b6ad) | fix | **sidenav:** remove deprecated API usage ([#30268](https://github.com/angular/components/pull/30268)) |
+| [4618b5b7c](https://github.com/angular/components/commit/4618b5b7cc9700216a037a1fd33853b0eaa2736f) | fix | **sidenav:** switch away from animations module ([#30235](https://github.com/angular/components/pull/30235)) |
+| [10e752a52](https://github.com/angular/components/commit/10e752a52400c2bbdb1fc840522366f12973a09d) | fix | **sort:** show arrow on focus ([#30217](https://github.com/angular/components/pull/30217)) |
+| [e8a099179](https://github.com/angular/components/commit/e8a099179855ae873c3c2e49fbc102508e5d015b) | fix | **timepicker:** don't mark as touched when blurred while dropdown is open ([#30228](https://github.com/angular/components/pull/30228)) |
+| [f9f8df348](https://github.com/angular/components/commit/f9f8df348045094d1e26ae1abe0aad174f2db4ab) | perf | **tooltip:** Tiny but measurable optimization to MatTooltip construction. Defer hooking up to directionality changes until overlay is created. ([#30214](https://github.com/angular/components/pull/30214)) |
+### cdk-experimental
+| Commit | Type | Description |
+| -- | -- | -- |
+| [4a040cb9f](https://github.com/angular/components/commit/4a040cb9f87be9f41e1900ec6b2f912b2814e880) | perf | **column-resize:** Use ResizeObserver to avoid layout thrashing ([#30215](https://github.com/angular/components/pull/30215)) |
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="18.2.9"></a>
-# 18.2.9 "curite-castle" (2024-10-17)
+<a name="19.0.4"></a>
+# 19.0.4 "linen-lampshade" (2024-12-18)
+### cdk
+| Commit | Type | Description |
+| -- | -- | -- |
+| [622057a146](https://github.com/angular/components/commit/622057a146df8acc8d77192dc4c2a8102dea7b56) | fix | **drag-drop:** resolve projected handles |
+| [1456074baa](https://github.com/angular/components/commit/1456074baae6ba1f2ff82f3bf27b1fd9bb1b9017) | fix | **drag-drop:** stop dragging on touchcancel ([#30184](https://github.com/angular/components/pull/30184)) |
+| [c92def439b](https://github.com/angular/components/commit/c92def439bef7287918536e0f53cd9061bc86f44) | fix | **testing:** add code to keyboard events ([#30188](https://github.com/angular/components/pull/30188)) |
 ### material
 | Commit | Type | Description |
 | -- | -- | -- |
-| [80bfac26b](https://github.com/angular/components/commit/80bfac26b17a1e54779aaf806a2ed7a718104d8f) | fix | **badge:** content incorrectly truncated in M3 ([#29854](https://github.com/angular/components/pull/29854)) |
-| [2d7519178](https://github.com/angular/components/commit/2d7519178573c62022d2d65efa08a43b50a47e88) | fix | **card:** elevated card container color ([#29835](https://github.com/angular/components/pull/29835)) |
-| [6ce574731](https://github.com/angular/components/commit/6ce574731f14b5c675f5ddeadd2a93f4f105c825) | fix | **dialog:** updates dialog max-height in landscape ([#29853](https://github.com/angular/components/pull/29853)) |
-| [ddb55e2c2](https://github.com/angular/components/commit/ddb55e2c2bcb65048d57c692a830ddc1ded728fb) | fix | **form-field:** account in `cols` attribute on textarea ([#29836](https://github.com/angular/components/pull/29836)) |
-| [afc6b9db1](https://github.com/angular/components/commit/afc6b9db1aa784408e900f82ae7e04250a34f472) | fix | **radio:** use tokens for focused border color ([#29716](https://github.com/angular/components/pull/29716)) |
+| [050b59b883](https://github.com/angular/components/commit/050b59b88399ffb37fef65db3bd726e64d13f3e4) | fix | **list:** enable MacOS select all with command+a ([#30183](https://github.com/angular/components/pull/30183)) |
+| [c3f22f3c9a](https://github.com/angular/components/commit/c3f22f3c9a31eef7810795b548e82c056320b151) | fix | **menu:** remove dependency on animations module ([#30163](https://github.com/angular/components/pull/30163)) |
+| [a9c569e13d](https://github.com/angular/components/commit/a9c569e13d1d3351fcd6a364cc93392453ab7a47) | fix | **sort:** avoid center align for sort header ([#30198](https://github.com/angular/components/pull/30198)) |
+| [f0ec675aaa](https://github.com/angular/components/commit/f0ec675aaa3a280379bbc90aa201040c0f48da8d) | fix | **table:** improve filter predicate efficiency ([#30172](https://github.com/angular/components/pull/30172)) |
+| [b724b0698c](https://github.com/angular/components/commit/b724b0698cf89230bbff9613d37d0090fbbb77e4) | fix | **table:** set border none for header cells on last row ([#30193](https://github.com/angular/components/pull/30193)) |
+| [125d867161](https://github.com/angular/components/commit/125d8671618aa91015b8a1dbe03ab002f1042451) | fix | **theming:** fix not found error in the guide duplicate theming styles document ([#30108](https://github.com/angular/components/pull/30108)) |
+| [8d3279fcd4](https://github.com/angular/components/commit/8d3279fcd465c4722b495c6a01d0d0bf92cb9ff0) | fix | **tooltip:** body line height affecting gap ([#30164](https://github.com/angular/components/pull/30164)) |
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="19.0.0-next.9"></a>
-# 19.0.0-next.9 "howlite-headband" (2024-10-17)
+<a name="19.0.3"></a>
+# 19.0.3 "polonium-popsicle" (2024-12-11)
+### material
+| Commit | Type | Description |
+| -- | -- | -- |
+| [7b64c451e6](https://github.com/angular/components/commit/7b64c451e6fa72f1cd34dc661d7790047a9c0951) | fix | **expansion:** switch away from animations module ([#30119](https://github.com/angular/components/pull/30119)) |
+| [d18c3395d8](https://github.com/angular/components/commit/d18c3395d82791bbf12bec72f36303fb4115ac2c) | fix | **menu:** decouple menu lifecycle from animations ([#30148](https://github.com/angular/components/pull/30148)) |
+| [3ea8cf5c31](https://github.com/angular/components/commit/3ea8cf5c31f4b619504b7bffd69606534e919057) | fix | **paginator:** ignore clicks on disabled buttons ([#30138](https://github.com/angular/components/pull/30138)) |
+| [fbaf286f9c](https://github.com/angular/components/commit/fbaf286f9cde16fb5cecf5994eb28555b03ea32a) | fix | **select:** add opt-in input that allows selection of nullable options ([#30142](https://github.com/angular/components/pull/30142)) |
+| [600a8b04f9](https://github.com/angular/components/commit/600a8b04f9c5cc8dc06b6f5d5d4ddc5a13287692) | fix | **timepicker:** deserialize ControlValueAccessor values correctly ([#30149](https://github.com/angular/components/pull/30149)) |
+| [4b69162998](https://github.com/angular/components/commit/4b6916299826101c4c8a12c9c4aa77ae0e49db71) | fix | **timepicker:** disable toggle if timepicker is disabled ([#30137](https://github.com/angular/components/pull/30137)) |
+
+<!-- CHANGELOG SPLIT MARKER -->
+
+<a name="19.0.2"></a>
+# 19.0.2 "plastic-rhino" (2024-12-04)
+### cdk
+| Commit | Type | Description |
+| -- | -- | -- |
+| [460f971b27](https://github.com/angular/components/commit/460f971b27239d0102061a9b976e86af513065a7) | fix | **accordion:** improve accessibility in example code ([#30087](https://github.com/angular/components/pull/30087)) |
+| [6306a12c12](https://github.com/angular/components/commit/6306a12c12ee0c255e20dfb9be78076f880120bf) | fix | **menu:** disable flexible dimensions ([#30086](https://github.com/angular/components/pull/30086)) |
+### material
+| Commit | Type | Description |
+| -- | -- | -- |
+| [0ed9869529](https://github.com/angular/components/commit/0ed9869529b4c7a2d008f8125f252d49e913228c) | fix | **button-toggle:** unable to tab into ngModel-based group on first render ([#30103](https://github.com/angular/components/pull/30103)) |
+| [72ff6fcce3](https://github.com/angular/components/commit/72ff6fcce323c1f44b57b3fa2dec92a13a5dbcd3) | fix | **core:** optgroup label color not inferred correctly ([#30085](https://github.com/angular/components/pull/30085)) |
+| [c395585446](https://github.com/angular/components/commit/c3955854469db7bc07dbfc511391bbcd00ae7666) | fix | **schematics:** avoid parsing stylesheets that don't include Material |
+| [5b3350a60e](https://github.com/angular/components/commit/5b3350a60eb9c0dfcf483bacc3c782c1308f180e) | fix | **schematics:** error if stylesheet contains syntax errors |
+| [1235ad28bc](https://github.com/angular/components/commit/1235ad28bcf7f950510f6c0e548268e125298f62) | fix | **sort:** simplify animations ([#30057](https://github.com/angular/components/pull/30057)) |
+| [5b165067e8](https://github.com/angular/components/commit/5b165067e8f12587db4fa15f30069651164c3e4e) | fix | **tabs:** ink bar not showing when same tab is re-selected ([#30121](https://github.com/angular/components/pull/30121)) |
+### youtube-player
+| Commit | Type | Description |
+| -- | -- | -- |
+| [1d3905a208](https://github.com/angular/components/commit/1d3905a2086954cbeec2b17aa8b11378d48311f3) | fix | update to latest typings ([#30126](https://github.com/angular/components/pull/30126)) |
+
+<!-- CHANGELOG SPLIT MARKER -->
+
+<a name="19.0.1"></a>
+# 19.0.1 "mercury-mailbox" (2024-11-27)
+### material
+| Commit | Type | Description |
+| -- | -- | -- |
+| [2d7e078bb](https://github.com/angular/components/commit/2d7e078bb46d665f21a6ef3ff1b76fec336862bc) | fix | **button-toggle:** animate checkbox ([#30025](https://github.com/angular/components/pull/30025)) |
+| [edac40645](https://github.com/angular/components/commit/edac40645f5130a9b85eaefa2479792a93d62396) | fix | **chips:** emit state changes when chip grid is disabled ([#30033](https://github.com/angular/components/pull/30033)) |
+| [18f7f4bb9](https://github.com/angular/components/commit/18f7f4bb9e3b9cae8563f3134aadede818140e9d) | fix | **datepicker:** adds comparison ids and aria-describedby spans ([#30040](https://github.com/angular/components/pull/30040)) |
+| [375435497](https://github.com/angular/components/commit/375435497fa42446ea51d11f72c32853fb337933) | fix | **slider:** update documentation ([#30029](https://github.com/angular/components/pull/30029)) |
+| [a31201475](https://github.com/angular/components/commit/a3120147523da86bc0e8d9531344d3c531c4795b) | fix | **timepicker:** make disabled input public ([#30063](https://github.com/angular/components/pull/30063)) |
+### docs
+| Commit | Type | Description |
+| -- | -- | -- |
+| [f9d9d2c81](https://github.com/angular/components/commit/f9d9d2c8115da469c234768c220205feb2a58eb1) | fix | update errorState example to cover handle missing state ([#30059](https://github.com/angular/components/pull/30059)) |
+### multiple
+| Commit | Type | Description |
+| -- | -- | -- |
+| [59b7f436a](https://github.com/angular/components/commit/59b7f436acc5c4b2e732ec09ac44e031e8b422bf) | fix | use cross-compatible type for setTimeout ([#30073](https://github.com/angular/components/pull/30073)) |
+
+<!-- CHANGELOG SPLIT MARKER -->
+
+<a name="19.0.0"></a>
+# 19.0.0 "hafnium-hippo" (2024-11-19)
 ## Breaking Changes
+### cdk
+- * Since `cdk.high-contrast` targets a media query instead of a class, the specificity of the styles it emits is lower than before.
+- * The overlay stays are now loaded slightly later than before which can change their specificity. You may have to update any overlay style overrides.
+- * Virtual scrolling lists now have proper type checking which can reveal some previously-hidden compilation errors.
+  
+  * fix(cdk/scrolling): adds ngTemplateContextGuard
+  
+  implements ngTemplateContextGuard for CdkVirtualForOf directive
+### material
+- * The ripples styles are now loaded slightly later than before which can change their specificity. You may have to update any ripple style overrides.
+- * `mixinColor` and `CanColor` have been removed. Use a host binding instead.
+  * `mixinDisableRipple` and `CanDisableRipple` have been removed. Use input transforms instead.
+  * `mixinDisabled` and `CanDisable` have been removed. Use input transforms instead.
+  * `mixinInitialized` and `HasInitialized` have been removed. Use a `Subject` that emits in `ngOnInit` instead.
+  * `mixinTabIndex` and `HasTabIndex` have been removed. Use input transforms instead.
 ### google-maps
 - * The new @googlemaps/markerclusterer API should be imported instead of the old one. Read more at: https://github.com/googlemaps/js-markerclusterer
   * The `MapMarkerClusterer` class has been renamed to `DeprecatedMapMarkerClusterer`.
   * The `map-marker-clusterer` selector has been changed to `deprecated-map-marker-clusterer`.
+### multiple
+- * In order for Material to be compatible with [recent changes in Sass](https://sass-lang.com/documentation/breaking-changes/mixed-decls/) and upcoming changes in the CSS standard, tokens are now emitted in-place, rather the being hoisted to the top of the selector. As a result, some token overrides might not apply anymore. This is relevant primarily for the cases like `@include mat.button-theme($theme); --mat-button-color: red;`. It can be resolved by wrapping the overrides with `& {}`, for example `@include mat.button-theme($theme); & { --mat-button-color: red; }`.
+- * `MatButton.ripple` is no longer available.
+  * `MatCheckbox.ripple` is no longer available.
+  * `MatChip.ripple` is no longer available.
+### material-date-fns-adapter
+| Commit | Type | Description |
+| -- | -- | -- |
+| [234e5e0e8](https://github.com/angular/components/commit/234e5e0e8b7001671b459491bc048c379e29fc1d) | feat | add support for date-fns 4 ([#29744](https://github.com/angular/components/pull/29744)) |
+### youtube-player
+| Commit | Type | Description |
+| -- | -- | -- |
+| [09da06b42](https://github.com/angular/components/commit/09da06b42e2aad668bbdeb9adecdad401b0d8df6) | fix | ready event not emitting |
+| [288598750](https://github.com/angular/components/commit/2885987500f9005fbdf981c700b516096896868b) | fix | startSeconds not applied when using placeholder |
 ### google-maps
 | Commit | Type | Description |
 | -- | -- | -- |
+| [1bd976c6a](https://github.com/angular/components/commit/1bd976c6a7b4493e9dc741f6fe25fde455adfbcf) | feat | Add support for some mouse events [#29741](https://github.com/angular/components/pull/29741) ([#29747](https://github.com/angular/components/pull/29747)) |
 | [a05475e76](https://github.com/angular/components/commit/a05475e769d6a64e10cdcebca83f1906b322f9a9) | feat | deprecate marker cluster component |
 | [c70aae15b](https://github.com/angular/components/commit/c70aae15b095f5d7005b491270866f6647732a26) | feat | implement new marker clusterer |
 | [b9deeee85](https://github.com/angular/components/commit/b9deeee85b06fa24812f36d8290390b6f058d131) | fix | add schematic to switch to the new clusterer name |
+| [a6709497f](https://github.com/angular/components/commit/a6709497fc6e5eca110db5374f7d6ca4b2ca5a58) | fix | expose all clusterer types ([#29905](https://github.com/angular/components/pull/29905)) |
+| [74c2a081f](https://github.com/angular/components/commit/74c2a081f9c4c2221cab62efee3db81789bf6efa) | fix | resolve CLI errors in ng update schematic ([#29947](https://github.com/angular/components/pull/29947)) |
 ### material
 | Commit | Type | Description |
 | -- | -- | -- |
+| [9122335b2](https://github.com/angular/components/commit/9122335b25b28a5532159ab87c36aab3be9c3716) | feat | **checkbox:** add new aria properties to MatCheckbox ([#29457](https://github.com/angular/components/pull/29457)) |
+| [64ed7ca71](https://github.com/angular/components/commit/64ed7ca7157b519703d152bb86a84a233f310f71) | feat | **core:** add experimental theme demo ([#29636](https://github.com/angular/components/pull/29636)) |
 | [a58e6f671](https://github.com/angular/components/commit/a58e6f6711af48f7106ed675b4b996c41899a0be) | feat | **core:** add theme-overrides mixin ([#29858](https://github.com/angular/components/pull/29858)) |
+| [d206225c5](https://github.com/angular/components/commit/d206225c58d071e6cb6b680ef11d1c7bab7a73cc) | feat | **core:** create focus-indicator structural styles loader ([#29763](https://github.com/angular/components/pull/29763)) |
+| [b519b4785](https://github.com/angular/components/commit/b519b4785b1da26becdb88e3810d606b9bddedfc) | feat | **core:** default to color-scheme theme type ([#29907](https://github.com/angular/components/pull/29907)) |
+| [ea0d1ba7b](https://github.com/angular/components/commit/ea0d1ba7b776e021ecfa27b80c921a22b98e3c40) | feat | **core:** deprecate the core mixin ([#29906](https://github.com/angular/components/pull/29906)) |
 | [486990912](https://github.com/angular/components/commit/4869909123c37a4910f5fde3f70d59cda4b44816) | feat | **core:** rename theme mixin ([#29857](https://github.com/angular/components/pull/29857)) |
+| [4b49d7354](https://github.com/angular/components/commit/4b49d73542a4b10c8d5bd67a7258bfdd44a8e329) | feat | **core:** switch system prefix from sys to mat-sys ([#29908](https://github.com/angular/components/pull/29908)) |
+| [1abb484aa](https://github.com/angular/components/commit/1abb484aa72177a748eecdf9b850cc1c07d1a42b) | feat | **input:** add the ability to interact with disabled inputs ([#29574](https://github.com/angular/components/pull/29574)) |
+| [4adc3725d](https://github.com/angular/components/commit/4adc3725dd08ef3cf3868f9c752e16c8c1492466) | feat | **schematics:** create v19 core removal schematic ([#29768](https://github.com/angular/components/pull/29768)) |
 | [9c3af284f](https://github.com/angular/components/commit/9c3af284f89c9a10af66e0ded6f7805bab207a91) | feat | **schematics:** Switch custom theme schematic to use theme mixin instead of define-theme and add high contrast override mixins ([#29642](https://github.com/angular/components/pull/29642)) |
+| [3fc1f9a1b](https://github.com/angular/components/commit/3fc1f9a1b026b9cd0ec666bc623169d1ba5a9532) | feat | **schematics:** Update custom theme schematic to work with light-dark and use theme-overrides mixin ([#29911](https://github.com/angular/components/pull/29911)) |
+| [ff3d342fd](https://github.com/angular/components/commit/ff3d342fd4ab91d0dd24147bc747c5a0ba8f1aaf) | feat | **tabs:** add `alignTabs` in `MatTabsConfig` ([#29779](https://github.com/angular/components/pull/29779)) |
 | [371446a7c](https://github.com/angular/components/commit/371446a7cfb5176e02fe796b4d39941db82c22c2) | feat | **theming:** Disambiguate token names in theme overrides ([#29859](https://github.com/angular/components/pull/29859)) |
-| [cc0532bb2](https://github.com/angular/components/commit/cc0532bb26106691b5fcd5a159d66b4adfa8cf1b) | fix | **badge:** content incorrectly truncated in M3 ([#29854](https://github.com/angular/components/pull/29854)) |
-| [9262a018b](https://github.com/angular/components/commit/9262a018baa07a8328b3378239cc1b23b0e86372) | fix | **card:** elevated card container color ([#29835](https://github.com/angular/components/pull/29835)) |
-| [613cf5406](https://github.com/angular/components/commit/613cf54063138201a9398979cd363ee1ace7ea66) | fix | **core:** rename sys vars from mat-app to mat-sys ([#29879](https://github.com/angular/components/pull/29879)) |
-| [da9cb714e](https://github.com/angular/components/commit/da9cb714e92dc2fc997043bbca33004910763998) | fix | **dialog:** updates dialog max-height in landscape ([#29853](https://github.com/angular/components/pull/29853)) |
-| [48b2680f6](https://github.com/angular/components/commit/48b2680f6b41be5dc9bda7f261279cc4c9ad7d64) | fix | **form-field:** account in `cols` attribute on textarea ([#29836](https://github.com/angular/components/pull/29836)) |
-| [e975bb949](https://github.com/angular/components/commit/e975bb94996ad4031d0207e7d7af66c601e708b1) | fix | **radio:** use tokens for focused border color ([#29716](https://github.com/angular/components/pull/29716)) |
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [3b4ade5a0](https://github.com/angular/components/commit/3b4ade5a0b0df26cb72a9bb81742e1ea5d86a46a) | fix | **tree:** only handle keyboard events directly from the node ([#29861](https://github.com/angular/components/pull/29861)) |
-
-<!-- CHANGELOG SPLIT MARKER -->
-
-<a name="19.0.0-next.8"></a>
-# 19.0.0-next.8 "thulium-trumpet" (2024-10-09)
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [9eb1f867d](https://github.com/angular/components/commit/9eb1f867d8b45bbc9771062e6a6c40fdd2ca24d1) | fix | **stepper:** remove mock of forms type |
-| [02823c080](https://github.com/angular/components/commit/02823c080be730d3c8cb7900b2449b660a5b0e08) | fix | **stepper:** reset submitted state when resetting stepper |
-### material
-| Commit | Type | Description |
-| -- | -- | -- |
-| [b777c2df0](https://github.com/angular/components/commit/b777c2df0052232cc304e20c46b0d0572d1f9894) | feat | **core:** expose styling information to the docs site |
 | [9546fe77e](https://github.com/angular/components/commit/9546fe77ef7322276bddf25ed826b2ab73e5ee20) | feat | **timepicker:** add test harnesses |
 | [2646e0885](https://github.com/angular/components/commit/2646e088510f00ca2ae885d42acae9c7fcd8656e) | feat | **timepicker:** add timepicker component |
+| [de6c20686](https://github.com/angular/components/commit/de6c20686c441ff39b872b69c725c3c46b1f3a93) | fix | **bottom-sheet:** add `height` `minHeight` `maxHeight` to config ([#29794](https://github.com/angular/components/pull/29794)) |
+| [fcb76d3ed](https://github.com/angular/components/commit/fcb76d3ed1ed4f6d5634496f47473efeda3bd1aa) | fix | **core:** add missing system variables ([#29624](https://github.com/angular/components/pull/29624)) |
+| [5ad133d07](https://github.com/angular/components/commit/5ad133d07341fa8647e81277e7f1b9f54b15059a) | fix | **core:** allow optgroup overrides through core-overrides ([#29897](https://github.com/angular/components/pull/29897)) |
 | [0fb4247ce](https://github.com/angular/components/commit/0fb4247ce834c475556a17e116e20f1ec0fd5a5a) | fix | **core:** avoid browser inconsistencies when parsing time |
-| [984723e10](https://github.com/angular/components/commit/984723e10bf3cf412058f20c57a4c8117024b0c0) | fix | **schematics:** treat lower dependency builder as default builder ([#29833](https://github.com/angular/components/pull/29833)) |
+| [855ed4948](https://github.com/angular/components/commit/855ed49482b1e215f43e1e9b96f1b28eded94640) | fix | **core:** avoid having to manually load ripple styles |
+| [d0d59b784](https://github.com/angular/components/commit/d0d59b784abdde79bebaf9cff6d316c952228fa7) | fix | **core:** change ng-add to use mat.theme ([#29990](https://github.com/angular/components/pull/29990)) |
+| [a8e40ec34](https://github.com/angular/components/commit/a8e40ec341103a4f3fa84bd446067dd37cbf6d50) | fix | **core:** correctly identify color input ([#29909](https://github.com/angular/components/pull/29909)) |
+| [edce90652](https://github.com/angular/components/commit/edce90652ade6715b4404db284f684b1b511fae4) | fix | **core:** delete deprecated APIs ([#29651](https://github.com/angular/components/pull/29651)) |
+| [54875a325](https://github.com/angular/components/commit/54875a3258a89a5326d7e224b6550c96e5801cd5) | fix | **core:** drop sanity checks ([#29688](https://github.com/angular/components/pull/29688)) |
+| [ef14c2869](https://github.com/angular/components/commit/ef14c286986f9451addeada26ab7b51402aa143f) | fix | **core:** option showing double selected indicator in high contrast mode |
+| [5403b4b07](https://github.com/angular/components/commit/5403b4b074d0a694bdba5b145f43ce61b1145ad1) | fix | **core:** remove unused motion system vars ([#29920](https://github.com/angular/components/pull/29920)) |
+| [613cf5406](https://github.com/angular/components/commit/613cf54063138201a9398979cd363ee1ace7ea66) | fix | **core:** rename sys vars from mat-app to mat-sys ([#29879](https://github.com/angular/components/pull/29879)) |
+| [d0e178b75](https://github.com/angular/components/commit/d0e178b75eb8e8e4d158ebff146cfb2ecadef686) | fix | **core:** stop manually instantiating MatRipple directive ([#29630](https://github.com/angular/components/pull/29630)) |
+| [d55ec612c](https://github.com/angular/components/commit/d55ec612cc66b42971c9da2677bc6e54017dd271) | fix | **core:** update prebuilt themes to use mat.theme ([#29989](https://github.com/angular/components/pull/29989)) |
+| [7cf8c6c46](https://github.com/angular/components/commit/7cf8c6c464732af4283c5e3c3c724dd90acc4136) | fix | **datepicker:** calendar font tokens not being picked up ([#29610](https://github.com/angular/components/pull/29610)) |
+| [5ba97925b](https://github.com/angular/components/commit/5ba97925b64a23cdaabfea514dda964c79f4a5f1) | fix | **form-field:** avoid touching the DOM on each state change |
+| [a2cd04902](https://github.com/angular/components/commit/a2cd0490260e99ec0a9a23d0837177f99fc81425) | fix | **form-field:** incorrect form field border radius with system-level themes ([#29966](https://github.com/angular/components/pull/29966)) |
+| [5345a875f](https://github.com/angular/components/commit/5345a875f68526191493e8220d4ed91c72d0e5eb) | fix | **input:** preserve aria-describedby set externally |
+| [9dcb95a72](https://github.com/angular/components/commit/9dcb95a722adc2cf151fc559a3eaf76195aca3f2) | fix | **list:** remove unnecessary high contrast styles |
+| [dbcb921d5](https://github.com/angular/components/commit/dbcb921d54608adc95dc124635d2973312928687) | fix | **menu:** handle keyboard events through dispatcher ([#29997](https://github.com/angular/components/pull/29997)) |
+| [de5e57ad1](https://github.com/angular/components/commit/de5e57ad1d9a76922091ca3adbab35bb9843b5fd) | fix | **menu:** use static elevation ([#29968](https://github.com/angular/components/pull/29968)) |
+| [482009bac](https://github.com/angular/components/commit/482009bac173bd4453d20dfec283e3cab23d2af0) | fix | **schematics:** add explicit system variable prefix schematic ([#29980](https://github.com/angular/components/pull/29980)) |
+| [75631fb0b](https://github.com/angular/components/commit/75631fb0b305891ea22e422f8bd9d9d991c1d6ef) | fix | **sidenav:** prevent the content from jumping when hydrated ([#29991](https://github.com/angular/components/pull/29991)) |
 | [14e9ec7cc](https://github.com/angular/components/commit/14e9ec7ccb0956f54604ee9f19c6dbee6b496fcd) | fix | **timepicker:** always re-focus input |
 | [1eda48604](https://github.com/angular/components/commit/1eda4860400fbb08c76b7760bb0eba3234f0c707) | fix | **timepicker:** hide toggle icon from assistive technology |
 | [490bcfe38](https://github.com/angular/components/commit/490bcfe38c1f640beefdf537d2af46467f07a4c7) | fix | **timepicker:** more flexible interval parsing |
 | [fb6e20290](https://github.com/angular/components/commit/fb6e20290ba6842c5190217de55d13044169eebf) | fix | **timepicker:** text field in parse error not up to date |
+| [9b5ee9d55](https://github.com/angular/components/commit/9b5ee9d551f09f606cb0e92f6288cf3edd76a1da) | fix | **timepicker:** value considered as invalid by default |
+### cdk
+| Commit | Type | Description |
+| -- | -- | -- |
+| [f4a02adb7](https://github.com/angular/components/commit/f4a02adb779968ab1e696aa93dc69b62e7a18929) | feat | **a11y:** use native media query for high contrast detection ([#29678](https://github.com/angular/components/pull/29678)) |
+| [9b4085c6e](https://github.com/angular/components/commit/9b4085c6e3eee78556000c0f60ef2c51c0668ed9) | feat | **private:** create cdk-visually-hidden style loader ([#29757](https://github.com/angular/components/pull/29757)) |
+| [df21d2b09](https://github.com/angular/components/commit/df21d2b0915ee54fbf04b93ccba512a9161f5008) | fix | **overlay:** avoid having to manually load structural styles |
+| [560878a23](https://github.com/angular/components/commit/560878a231373dca51ecac07f913503ee3e860aa) | fix | **overlay:** load structural styles in a cascade layer ([#29725](https://github.com/angular/components/pull/29725)) |
+| [873eb01e0](https://github.com/angular/components/commit/873eb01e018018f19434a4187a6b2a871272d09a) | fix | **portal:** remove ComponentFactoryResolver usages ([#27427](https://github.com/angular/components/pull/27427)) |
+| [5439460d1](https://github.com/angular/components/commit/5439460d1fe166f8ec34ab7d48f05e0dd7f6a946) | fix | **scrolling:** adds ngTemplateContextGuard ([#27276](https://github.com/angular/components/pull/27276)) |
+| [ad18e6d74](https://github.com/angular/components/commit/ad18e6d74e57e4980a411f0ac9d0b502d5fc577f) | fix | **text-field:** avoid having to manually load text field styles |
+| [bd84c2a67](https://github.com/angular/components/commit/bd84c2a67476b688a0c775de8566a4ff4b3b2ce0) | fix | **tree:** fix issue where `isExpanded` wouldn't be set if placed before `isExpandable` ([#29565](https://github.com/angular/components/pull/29565)) |
+| [3b4ade5a0](https://github.com/angular/components/commit/3b4ade5a0b0df26cb72a9bb81742e1ea5d86a46a) | fix | **tree:** only handle keyboard events directly from the node ([#29861](https://github.com/angular/components/pull/29861)) |
+| [f6066c23f](https://github.com/angular/components/commit/f6066c23feee5a23d870104860f1e18bb9f3db83) | fix | **tree:** warn if mixed node types are used within the same tree |
 ### mat
 | Commit | Type | Description |
 | -- | -- | -- |
@@ -80,39 +212,51 @@
 ### multiple
 | Commit | Type | Description |
 | -- | -- | -- |
+| [01711b180](https://github.com/angular/components/commit/01711b180404ad029bef54e81bdc90fb158dc506) | fix | account for mixed declarations in latest Sass version ([#29596](https://github.com/angular/components/pull/29596)) |
+| [cb1450fc7](https://github.com/angular/components/commit/cb1450fc76998426111e150a983deb31ecbe42ce) | fix | change fallbacks to use m3 ([#29528](https://github.com/angular/components/pull/29528)) |
+| [a9da72ed1](https://github.com/angular/components/commit/a9da72ed1551601b22b1a509f2e50227ac23f432) | fix | consolidate strong focus indicators ([#29623](https://github.com/angular/components/pull/29623)) |
 | [be342289c](https://github.com/angular/components/commit/be342289c2cc720af31edf1ce98eee08e2bf9235) | fix | remove final references to ComponentFactoryResolver ([#29832](https://github.com/angular/components/pull/29832)) |
+| [d1d53f51a](https://github.com/angular/components/commit/d1d53f51ad9c565275c4916cf8e107dd994b7fc3) | fix | remove usages of Sass globals ([#29972](https://github.com/angular/components/pull/29972)) |
+| [b3a9062ed](https://github.com/angular/components/commit/b3a9062edf8863250ddd462e5abe009fbc46243b) | fix | ripples not showing up in some cases ([#29672](https://github.com/angular/components/pull/29672)) |
+| [485bd9923](https://github.com/angular/components/commit/485bd9923b732390fbc3533f94815da97bd34c13) | fix | stop exposing internal ripple implementation ([#29622](https://github.com/angular/components/pull/29622)) |
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="18.2.8"></a>
-# 18.2.8 "actinium-angle" (2024-10-09)
-### cdk
+<a name="18.2.10"></a>
+# 18.2.10 "plastic-monkey" (2024-10-23)
+### material
 | Commit | Type | Description |
 | -- | -- | -- |
-| [fa43a2456](https://github.com/angular/components/commit/fa43a245668201f7a54fa76c320825c5234a7c04) | fix | **stepper:** remove mock of forms type |
-| [5bed0943a](https://github.com/angular/components/commit/5bed0943a6f3a0913242b7b998e473da875303e6) | fix | **stepper:** reset submitted state when resetting stepper |
+| [501faa9a54](https://github.com/angular/components/commit/501faa9a547c043e8abef5cb75acca930f31fa2e) | fix | **chips:** emitting end event multiple times when holding down key ([#29894](https://github.com/angular/components/pull/29894)) |
+| [4a0397a1c7](https://github.com/angular/components/commit/4a0397a1c7527b1e56a1aedebe5dfc262327e134) | fix | **tabs:** remove IE animation workaround ([#29899](https://github.com/angular/components/pull/29899)) |
+
+<!-- CHANGELOG SPLIT MARKER -->
+
+<a name="18.2.9"></a>
+# 18.2.9 "curite-castle" (2024-10-17)
 ### material
 | Commit | Type | Description |
 | -- | -- | -- |
-| [104b5932c](https://github.com/angular/components/commit/104b5932c6aba2f06172f9156f68bc4390a11215) | feat | **core:** expose styling information to the docs site |
-| [7ebfbeb6c](https://github.com/angular/components/commit/7ebfbeb6c9ecf08f6fd3926113c43ed91be5da6d) | fix | **schematics:** treat lower dependency builder as default builder ([#29833](https://github.com/angular/components/pull/29833)) |
+| [80bfac26b](https://github.com/angular/components/commit/80bfac26b17a1e54779aaf806a2ed7a718104d8f) | fix | **badge:** content incorrectly truncated in M3 ([#29854](https://github.com/angular/components/pull/29854)) |
+| [2d7519178](https://github.com/angular/components/commit/2d7519178573c62022d2d65efa08a43b50a47e88) | fix | **card:** elevated card container color ([#29835](https://github.com/angular/components/pull/29835)) |
+| [6ce574731](https://github.com/angular/components/commit/6ce574731f14b5c675f5ddeadd2a93f4f105c825) | fix | **dialog:** updates dialog max-height in landscape ([#29853](https://github.com/angular/components/pull/29853)) |
+| [ddb55e2c2](https://github.com/angular/components/commit/ddb55e2c2bcb65048d57c692a830ddc1ded728fb) | fix | **form-field:** account in `cols` attribute on textarea ([#29836](https://github.com/angular/components/pull/29836)) |
+| [afc6b9db1](https://github.com/angular/components/commit/afc6b9db1aa784408e900f82ae7e04250a34f472) | fix | **radio:** use tokens for focused border color ([#29716](https://github.com/angular/components/pull/29716)) |
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="19.0.0-next.7"></a>
-# 19.0.0-next.7 "snow-supernova" (2024-10-03)
+<a name="18.2.8"></a>
+# 18.2.8 "actinium-angle" (2024-10-09)
 ### cdk
 | Commit | Type | Description |
 | -- | -- | -- |
-| [5be8905f65](https://github.com/angular/components/commit/5be8905f65cc907506fc0791223a7499a6235603) | fix | **drag-drop:** positioning thrown off with align-self ([#29813](https://github.com/angular/components/pull/29813)) |
+| [fa43a2456](https://github.com/angular/components/commit/fa43a245668201f7a54fa76c320825c5234a7c04) | fix | **stepper:** remove mock of forms type |
+| [5bed0943a](https://github.com/angular/components/commit/5bed0943a6f3a0913242b7b998e473da875303e6) | fix | **stepper:** reset submitted state when resetting stepper |
 ### material
 | Commit | Type | Description |
 | -- | -- | -- |
-| [ff3d342fd4](https://github.com/angular/components/commit/ff3d342fd4ab91d0dd24147bc747c5a0ba8f1aaf) | feat | **tabs:** add `alignTabs` in `MatTabsConfig` ([#29779](https://github.com/angular/components/pull/29779)) |
-| [2861a306ae](https://github.com/angular/components/commit/2861a306aebc54eafe4a72b4a53860d8612af5d4) | fix | **chips:** chip grid not re-focusing first item |
-| [86ebb9bfd5](https://github.com/angular/components/commit/86ebb9bfd55e637be1e6d0117a10e290c5247ebd) | fix | **chips:** chip set overwriting disabled state ([#29795](https://github.com/angular/components/pull/29795)) |
-| [8e1711216f](https://github.com/angular/components/commit/8e1711216f7d07324e311e0f6ada3d2426c7891e) | fix | **chips:** focus escape not working consistently |
-| [6a8c73d3da](https://github.com/angular/components/commit/6a8c73d3da8999bf2dcc711ba4610fa193bef9a4) | fix | **core:** infer first day of week in native date adapter ([#29802](https://github.com/angular/components/pull/29802)) |
+| [104b5932c](https://github.com/angular/components/commit/104b5932c6aba2f06172f9156f68bc4390a11215) | feat | **core:** expose styling information to the docs site |
+| [7ebfbeb6c](https://github.com/angular/components/commit/7ebfbeb6c9ecf08f6fd3926113c43ed91be5da6d) | fix | **schematics:** treat lower dependency builder as default builder ([#29833](https://github.com/angular/components/pull/29833)) |
 
 <!-- CHANGELOG SPLIT MARKER -->
 
@@ -132,21 +276,6 @@
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="19.0.0-next.6"></a>
-# 19.0.0-next.6 "topaz-tornado" (2024-09-25)
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [9b4085c6e3](https://github.com/angular/components/commit/9b4085c6e3eee78556000c0f60ef2c51c0668ed9) | feat | **private:** create cdk-visually-hidden style loader ([#29757](https://github.com/angular/components/pull/29757)) |
-### material
-| Commit | Type | Description |
-| -- | -- | -- |
-| [d206225c58](https://github.com/angular/components/commit/d206225c58d071e6cb6b680ef11d1c7bab7a73cc) | feat | **core:** create focus-indicator structural styles loader ([#29763](https://github.com/angular/components/pull/29763)) |
-| [4adc3725dd](https://github.com/angular/components/commit/4adc3725dd08ef3cf3868f9c752e16c8c1492466) | feat | **schematics:** create v19 core removal schematic ([#29768](https://github.com/angular/components/pull/29768)) |
-| [49af49bb01](https://github.com/angular/components/commit/49af49bb019b93e48a1f6386a1b0b9ab20989a23) | fix | **datepicker:** set explicit line height on calendar ([#29770](https://github.com/angular/components/pull/29770)) |
-
-<!-- CHANGELOG SPLIT MARKER -->
-
 <a name="18.2.6"></a>
 # 18.2.6 "emerald-egg" (2024-09-25)
 ### material
@@ -174,34 +303,6 @@
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="19.0.0-next.5"></a>
-# 19.0.0-next.5 "astatine-armor" (2024-09-20)
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [4cd2152d9](https://github.com/angular/components/commit/4cd2152d9813078f81fc2be671f123ffa8c09974) | fix | **drag-drop:** account for scale when setting free drag position ([#29739](https://github.com/angular/components/pull/29739)) |
-| [fd4085895](https://github.com/angular/components/commit/fd4085895e67a695a4fbb5d3da2db9271f35a4e6) | fix | **listbox:** scroll active option into view when using aria-activedescendant ([#29722](https://github.com/angular/components/pull/29722)) |
-| [560878a23](https://github.com/angular/components/commit/560878a231373dca51ecac07f913503ee3e860aa) | fix | **overlay:** load structural styles in a cascade layer ([#29725](https://github.com/angular/components/pull/29725)) |
-| [873eb01e0](https://github.com/angular/components/commit/873eb01e018018f19434a4187a6b2a871272d09a) | fix | **portal:** remove ComponentFactoryResolver usages ([#27427](https://github.com/angular/components/pull/27427)) |
-| [be004b89f](https://github.com/angular/components/commit/be004b89fc7938b5a020a743e3344268601d0e9f) | fix | **tree:** resolve maximum call stack error ([#29754](https://github.com/angular/components/pull/29754)) |
-### material
-| Commit | Type | Description |
-| -- | -- | -- |
-| [777d1d295](https://github.com/angular/components/commit/777d1d295aaa8bc6e47a7c76e8fe9246ed30db2e) | fix | **chips:** increase chip remove touch target size ([#29452](https://github.com/angular/components/pull/29452)) |
-| [602bef1cd](https://github.com/angular/components/commit/602bef1cd6a4e11c89105ec3cd2f1410eea9cb50) | fix | **datepicker:** replace labels not pointing to anything ([#29755](https://github.com/angular/components/pull/29755)) |
-| [60776637e](https://github.com/angular/components/commit/60776637ee78cd942a3527402e3e8f9f25d871c1) | fix | **select:** remove incompatible aria-autocomplete attribute ([#29645](https://github.com/angular/components/pull/29645)) |
-| [0ed5d7d4f](https://github.com/angular/components/commit/0ed5d7d4fe91a3442a6d5cb80b032b66fc7ac30a) | fix | **slider:** log proper error when slider isn't configured correctly ([#29745](https://github.com/angular/components/pull/29745)) |
-### google-maps
-| Commit | Type | Description |
-| -- | -- | -- |
-| [1bd976c6a](https://github.com/angular/components/commit/1bd976c6a7b4493e9dc741f6fe25fde455adfbcf) | feat | Add support for some mouse events [#29741](https://github.com/angular/components/pull/29741) ([#29747](https://github.com/angular/components/pull/29747)) |
-### material-date-fns-adapter
-| Commit | Type | Description |
-| -- | -- | -- |
-| [234e5e0e8](https://github.com/angular/components/commit/234e5e0e8b7001671b459491bc048c379e29fc1d) | feat | add support for date-fns 4 ([#29744](https://github.com/angular/components/pull/29744)) |
-
-<!-- CHANGELOG SPLIT MARKER -->
-
 <a name="18.2.4"></a>
 # 18.2.4 "aramid-angle" (2024-09-12)
 ### cdk
@@ -217,60 +318,6 @@
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="19.0.0-next.4"></a>
-# 19.0.0-next.4 "ion-ink" (2024-09-12)
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [3a62ab11f](https://github.com/angular/components/commit/3a62ab11fe6e97931ec4d758b03cb660ffdd4fc5) | fix | **overlay:** avoid leaking memory through afterNextRender ([#29709](https://github.com/angular/components/pull/29709)) |
-### material
-| Commit | Type | Description |
-| -- | -- | -- |
-| [9122335b2](https://github.com/angular/components/commit/9122335b25b28a5532159ab87c36aab3be9c3716) | feat | **checkbox:** add new aria properties to MatCheckbox ([#29457](https://github.com/angular/components/pull/29457)) |
-| [fead293e9](https://github.com/angular/components/commit/fead293e907f40a37e478779c6b0b3b50992262b) | fix | **badge:** change legacy container size default ([#29713](https://github.com/angular/components/pull/29713)) |
-| [54875a325](https://github.com/angular/components/commit/54875a3258a89a5326d7e224b6550c96e5801cd5) | fix | **core:** drop sanity checks ([#29688](https://github.com/angular/components/pull/29688)) |
-| [ef14c2869](https://github.com/angular/components/commit/ef14c286986f9451addeada26ab7b51402aa143f) | fix | **core:** option showing double selected indicator in high contrast mode |
-| [77051f871](https://github.com/angular/components/commit/77051f871a71b973ab6cbb642b1bdd6fe8a0da28) | fix | **form-field:** Don't allow label to grow larger than input ([#29673](https://github.com/angular/components/pull/29673)) |
-| [9dcb95a72](https://github.com/angular/components/commit/9dcb95a722adc2cf151fc559a3eaf76195aca3f2) | fix | **list:** remove unnecessary high contrast styles |
-| [4d0a3eff7](https://github.com/angular/components/commit/4d0a3eff7c5d5186516fe5c8f1af8c003d02882d) | fix | **select:** Update checkbox color to match the selected label text color ([#29684](https://github.com/angular/components/pull/29684)) |
-
-<!-- CHANGELOG SPLIT MARKER -->
-
-<a name="19.0.0-next.3"></a>
-# 19.0.0-next.3 "quicksilver-quintessence" (2024-09-04)
-## Breaking Changes
-### cdk
-- * Since `cdk.high-contrast` targets a media query instead of a class, the specificity of the styles it emits is lower than before.
-- * Virtual scrolling lists now have proper type checking which can reveal some previously-hidden compilation errors.
-  
-  * fix(cdk/scrolling): adds ngTemplateContextGuard
-  
-  implements ngTemplateContextGuard for CdkVirtualForOf directive
-### material
-- * `mixinColor` and `CanColor` have been removed. Use a host binding instead.
-  * `mixinDisableRipple` and `CanDisableRipple` have been removed. Use input transforms instead.
-  * `mixinDisabled` and `CanDisable` have been removed. Use input transforms instead.
-  * `mixinInitialized` and `HasInitialized` have been removed. Use a `Subject` that emits in `ngOnInit` instead.
-  * `mixinTabIndex` and `HasTabIndex` have been removed. Use input transforms instead.
-### material
-| Commit | Type | Description |
-| -- | -- | -- |
-| [90eea1bf70](https://github.com/angular/components/commit/90eea1bf7084ea7098676ca9988624802f27884c) | fix | **core:** Allow system variables to be formatted for opacity ([#29665](https://github.com/angular/components/pull/29665)) |
-| [edce90652a](https://github.com/angular/components/commit/edce90652ade6715b4404db284f684b1b511fae4) | fix | **core:** delete deprecated APIs ([#29651](https://github.com/angular/components/pull/29651)) |
-| [4771931c2f](https://github.com/angular/components/commit/4771931c2f334be1edc2b7764921d6539808317e) | fix | **core:** Fix incorrect color role mappings ([#29655](https://github.com/angular/components/pull/29655)) |
-| [9333de0537](https://github.com/angular/components/commit/9333de0537e7b905407999820bf283f4943c986b) | fix | **tooltip:** remove old IE workaround ([#29674](https://github.com/angular/components/pull/29674)) |
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [f4a02adb77](https://github.com/angular/components/commit/f4a02adb779968ab1e696aa93dc69b62e7a18929) | feat | **a11y:** use native media query for high contrast detection ([#29678](https://github.com/angular/components/pull/29678)) |
-| [5439460d1f](https://github.com/angular/components/commit/5439460d1fe166f8ec34ab7d48f05e0dd7f6a946) | fix | **scrolling:** adds ngTemplateContextGuard ([#27276](https://github.com/angular/components/pull/27276)) |
-### multiple
-| Commit | Type | Description |
-| -- | -- | -- |
-| [b3a9062edf](https://github.com/angular/components/commit/b3a9062edf8863250ddd462e5abe009fbc46243b) | fix | ripples not showing up in some cases ([#29672](https://github.com/angular/components/pull/29672)) |
-
-<!-- CHANGELOG SPLIT MARKER -->
-
 <a name="18.2.3"></a>
 # 18.2.3 "parchment-deluge" (2024-09-04)
 ### material
@@ -283,42 +330,6 @@
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="19.0.0-next.2"></a>
-# 19.0.0-next.2 "bronze-book" (2024-08-28)
-## Breaking Changes
-### cdk
-- * The overlay stays are now loaded slightly later than before which can change their specificity. You may have to update any overlay style overrides.
-### material
-- * The ripples styles are now loaded slightly later than before which can change their specificity. You may have to update any ripple style overrides.
-### multiple
-- * `MatButton.ripple` is no longer available.
-  * `MatCheckbox.ripple` is no longer available.
-  * `MatChip.ripple` is no longer available.
-### material
-| Commit | Type | Description |
-| -- | -- | -- |
-| [64ed7ca715](https://github.com/angular/components/commit/64ed7ca7157b519703d152bb86a84a233f310f71) | feat | **core:** add experimental theme demo ([#29636](https://github.com/angular/components/pull/29636)) |
-| [fcb76d3ed1](https://github.com/angular/components/commit/fcb76d3ed1ed4f6d5634496f47473efeda3bd1aa) | fix | **core:** add missing system variables ([#29624](https://github.com/angular/components/pull/29624)) |
-| [855ed49482](https://github.com/angular/components/commit/855ed49482b1e215f43e1e9b96f1b28eded94640) | fix | **core:** avoid having to manually load ripple styles |
-| [d0e178b75e](https://github.com/angular/components/commit/d0e178b75eb8e8e4d158ebff146cfb2ecadef686) | fix | **core:** stop manually instantiating MatRipple directive ([#29630](https://github.com/angular/components/pull/29630)) |
-| [3bf0e31f77](https://github.com/angular/components/commit/3bf0e31f771c0a6886aa0e88dec19f85e523d791) | fix | **schematics:** Add the missing neutral tones for the M3 color palettes ([#29644](https://github.com/angular/components/pull/29644)) |
-| [64cf19ccdb](https://github.com/angular/components/commit/64cf19ccdba5f584f3e508de97d58283654d9fb8) | perf | **tooltip:** Avoid unneeded calls to clearTimeout ([#29643](https://github.com/angular/components/pull/29643)) |
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [2f1fe03ae9](https://github.com/angular/components/commit/2f1fe03ae990266ff05c298a93c7fd74bc13e87b) | fix | **drag-drop:** error if ngDevMode is undefined ([#29634](https://github.com/angular/components/pull/29634)) |
-| [df21d2b091](https://github.com/angular/components/commit/df21d2b0915ee54fbf04b93ccba512a9161f5008) | fix | **overlay:** avoid having to manually load structural styles |
-| [ad18e6d74e](https://github.com/angular/components/commit/ad18e6d74e57e4980a411f0ac9d0b502d5fc577f) | fix | **text-field:** avoid having to manually load text field styles |
-| [a6835ef6a7](https://github.com/angular/components/commit/a6835ef6a700dcded10e1a83d936dc553774f021) | fix | **tree:** avoid breaking change in constructor ([#29648](https://github.com/angular/components/pull/29648)) |
-| [8b34fb7e8d](https://github.com/angular/components/commit/8b34fb7e8d6276de269a9c1dc2507458eaf7d594) | fix | **tree:** capturing focus on load ([#29641](https://github.com/angular/components/pull/29641)) |
-### multiple
-| Commit | Type | Description |
-| -- | -- | -- |
-| [a9da72ed15](https://github.com/angular/components/commit/a9da72ed1551601b22b1a509f2e50227ac23f432) | fix | consolidate strong focus indicators ([#29623](https://github.com/angular/components/pull/29623)) |
-| [485bd9923b](https://github.com/angular/components/commit/485bd9923b732390fbc3533f94815da97bd34c13) | fix | stop exposing internal ripple implementation ([#29622](https://github.com/angular/components/pull/29622)) |
-
-<!-- CHANGELOG SPLIT MARKER -->
-
 <a name="18.2.2"></a>
 # 18.2.2 "steel-sword" (2024-08-28)
 ### cdk
@@ -336,31 +347,6 @@
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="19.0.0-next.1"></a>
-# 19.0.0-next.1 "plastic-moose" (2024-08-22)
-## Breaking Changes
-### multiple
-- * In order for Material to be compatible with [recent changes in Sass](https://sass-lang.com/documentation/breaking-changes/mixed-decls/) and upcoming changes in the CSS standard, tokens are now emitted in-place, rather the being hoisted to the top of the selector. As a result, some token overrides might not apply anymore. This is relevant primarily for the cases like `@include mat.button-theme($theme); --mat-button-color: red;`. It can be resolved by wrapping the overrides with `& {}`, for example `@include mat.button-theme($theme); & { --mat-button-color: red; }`.
-### material
-| Commit | Type | Description |
-| -- | -- | -- |
-| [1abb484aa7](https://github.com/angular/components/commit/1abb484aa72177a748eecdf9b850cc1c07d1a42b) | feat | **input:** add the ability to interact with disabled inputs ([#29574](https://github.com/angular/components/pull/29574)) |
-| [7cf8c6c464](https://github.com/angular/components/commit/7cf8c6c464732af4283c5e3c3c724dd90acc4136) | fix | **datepicker:** calendar font tokens not being picked up ([#29610](https://github.com/angular/components/pull/29610)) |
-| [4f2bc4da78](https://github.com/angular/components/commit/4f2bc4da78ff85c6a9d5a2323908c82e6af85e11) | fix | **icon:** update error message for missing HttpClient ([#29589](https://github.com/angular/components/pull/29589)) |
-| [adf413670f](https://github.com/angular/components/commit/adf413670fe10bcfbfff1ec424fcfe2b76d66bdb) | fix | **menu:** inconsistent layout of submenu icon ([#29603](https://github.com/angular/components/pull/29603)) |
-| [357f6f27a5](https://github.com/angular/components/commit/357f6f27a5feb7f0b0aa6e626352a386e6725202) | fix | **tabs:** switch pagination to not use native buttons ([#29605](https://github.com/angular/components/pull/29605)) |
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [04ce4d2648](https://github.com/angular/components/commit/04ce4d2648004e970bc864962e6ec12e92f27698) | fix | **drag-drop:** preview positioned incorrectly when RTL is set on the body ([#29606](https://github.com/angular/components/pull/29606)) |
-### multiple
-| Commit | Type | Description |
-| -- | -- | -- |
-| [01711b1804](https://github.com/angular/components/commit/01711b180404ad029bef54e81bdc90fb158dc506) | fix | account for mixed declarations in latest Sass version ([#29596](https://github.com/angular/components/pull/29596)) |
-| [cb1450fc76](https://github.com/angular/components/commit/cb1450fc76998426111e150a983deb31ecbe42ce) | fix | change fallbacks to use m3 ([#29528](https://github.com/angular/components/pull/29528)) |
-
-<!-- CHANGELOG SPLIT MARKER -->
-
 <a name="18.2.1"></a>
 # 18.2.1 "plastic-panda" (2024-08-22)
 ### cdk
@@ -377,15 +363,6 @@
 
 <!-- CHANGELOG SPLIT MARKER -->
 
-<a name="19.0.0-next.0"></a>
-# 19.0.0-next.0 "yttrium-igloo" (2024-08-14)
-### cdk
-| Commit | Type | Description |
-| -- | -- | -- |
-| [bd84c2a67](https://github.com/angular/components/commit/bd84c2a67476b688a0c775de8566a4ff4b3b2ce0) | fix | **tree:** fix issue where `isExpanded` wouldn't be set if placed before `isExpandable` ([#29565](https://github.com/angular/components/pull/29565)) |
-
-<!-- CHANGELOG SPLIT MARKER -->
-
 <a name="18.2.0"></a>
 # 18.2.0 "technetium-tapas" (2024-08-14)
 ## Deprecations
diff --git a/CHANGELOG_ARCHIVE.md b/CHANGELOG_ARCHIVE.md
index 3335305fe079..9de1841eee84 100644
--- a/CHANGELOG_ARCHIVE.md
+++ b/CHANGELOG_ARCHIVE.md
@@ -7297,7 +7297,7 @@ contains all of the components. Build tools such as [`rollup.js`](http://rollupj
 tree-shaking to eliminate the code for components that you aren't using.
 
 The addition of theming as also changed the directory structure for bringing the core css into your
-application. See the new [theming guide](guides/theming.md) for more information.
+application. See the new [theming guide](guides/theming-with-config) for more information.
 
 
 ### Features
diff --git a/LICENSE b/LICENSE
index 7da427f850de..0f2b89697e5e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License
 
-Copyright (c) 2024 Google LLC.
+Copyright (c) 2025 Google LLC.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/goldens/size-test.yaml b/goldens/size-test.yaml
index 18645551fc0a..d3b577de0535 100644
--- a/goldens/size-test.yaml
+++ b/goldens/size-test.yaml
@@ -1,15 +1,15 @@
-cdk/drag-drop/all-directives: 170299
-cdk/drag-drop/basic: 166324
-material/autocomplete/without-optgroup: 223062
-material/button-toggle/standalone: 147380
-material/chips/basic: 208741
-material/datepicker/range-picker/without-form-field: 364729
-material/expansion/without-accordion: 154530
-material/form-field/advanced: 223916
-material/form-field/basic: 222205
-material/list/nav-list: 153825
-material/menu/without-lazy-content: 221068
-material/radio/without-group: 150402
-material/select/basic: 269413
-material/tabs/advanced: 217500
-material/tabs/basic: 217357
+cdk/drag-drop/all-directives: 179236
+cdk/drag-drop/basic: 175100
+material/autocomplete/without-optgroup: 240989
+material/button-toggle/standalone: 159023
+material/chips/basic: 220624
+material/datepicker/range-picker/without-form-field: 389083
+material/expansion/without-accordion: 157841
+material/form-field/advanced: 237040
+material/form-field/basic: 235120
+material/list/nav-list: 162378
+material/menu/without-lazy-content: 236952
+material/radio/without-group: 160056
+material/select/basic: 288687
+material/tabs/advanced: 230594
+material/tabs/basic: 230451
diff --git a/guides/creating-a-custom-form-field-control.md b/guides/creating-a-custom-form-field-control.md
index a4b66adf0ecb..3911d17073ab 100644
--- a/guides/creating-a-custom-form-field-control.md
+++ b/guides/creating-a-custom-form-field-control.md
@@ -357,14 +357,14 @@ ngDoCheck() {
 }
 
 private updateErrorState() {
-  const parent = this._parentFormGroup || this.parentForm;
+  const parentSubmitted = this._parentFormGroup?.submitted || this._parentForm?.submitted;
+  const touchedOrParentSubmitted = this.touched || parentSubmitted;
 
-  const oldState = this.errorState;
-  const newState = (this.ngControl?.invalid || this.parts.invalid) && (this.touched || parent.submitted);
+  const newState = (this.ngControl?.invalid || this.parts.invalid) && touchedOrParentSubmitted;
 
-  if (oldState !== newState) {
+  if (this.errorState !== newState) {
     this.errorState = newState;
-    this.stateChanges.next();
+    this.stateChanges.next(); // Notify listeners of state changes.
   }
 }
 ```
diff --git a/guides/customizing-component-styles.md b/guides/customizing-component-styles.md
deleted file mode 100644
index 2b3e02b5717c..000000000000
--- a/guides/customizing-component-styles.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# Customizing Angular Material component styles
-
-Angular Material supports customizing component styles via Sass API as described in the [theming
-guide][]. This document provides guidance on defining custom CSS rules that directly style
-Angular Material components.
-
-[theming guide]: https://material.angular.io/guide/theming
-
-## Targeting custom styles
-
-### Component host elements
-
-For any Angular Material component, you can safely define custom CSS for a component's host element
-that affect the positioning or layout of that component, such as `margin`, `position`, `top`,
-`left`, `transform`, and `z-index`. You should apply such styles by defining a custom CSS
-class and applying that class to the component's host element.
-
-Avoid defining custom styles that would affect the size or internal layout of the component, such as
-`padding`, `height`, `width`, or `overflow`. You can specify `display: none` to hide a component,
-but avoid specifying any other `display` value. Overriding these properties can break components
-in unexpected ways as the internal styles change between releases.
-
-### Internal component elements
-
-Avoid any custom styles or overrides on internal elements within a Angular Material components.
-The DOM structure and CSS classes applied for each component may change at any time, causing custom
-styles to break.
-
-## Applying styles to Angular Material components
-
-While Angular Material does not support defining custom styles or CSS overrides on components'
-internal elements, you might choose to do this anyway. There are three points to consider while
-customizing styles for Angular Material components: view encapsulation, CSS specificity, and
-rendering location.
-
-### View encapsulation
-
-By default, Angular scopes component styles to exclusively affect that component's view. This means
-that the styles you author affect only the elements directly within your component template.
-Encapsulated styles do *not* affect elements that are children of other components within your
-template. You can read more about view encapsulation in the
-[Angular documentation](https://angular.dev/guide/components/styling#style-scoping). You may
-also wish to review
-[_The State of CSS in Angular_](https://blog.angular.io/the-state-of-css-in-angular-4a52d4bd2700)
-on the Angular blog.
-
-#### Bypassing encapsulation
-
-Angular Material disables style encapsulation for all components in the library. However, the
-default style encapsulation in your own components still prevents custom styles from leaking into
-Angular Material components.
-
-If your component enables view encapsulation, your component styles will only
-affect the elements explicitly defined in your template. To affect descendants of components used
-in your template, you can use one of the following approaches:
-
-1. Define custom styles in a global stylesheet declared in the `styles` array of your `angular.json`
-configuration file.
-2. Disable view encapsulation for your component. This approach effectively turns your component
-styles into global CSS.
-3. Apply the deprecated `::ng-deep` pseudo-class to a CSS rule. Any CSS rule with `::ng-deep`
-becomes a global style. [See the Angular documentation for more on `::ng-deep`][ng-deep].
-
-All of these approaches involve creating global CSS that isn't affected by style encapsulation.
-Global CSS affects all elements in your application. Global CSS class names may collide with class
-names defined by components. Global CSS is often a source of hard-to-diagnose bugs and is generally
-difficult to maintain.
-
-[ng-deep]: https://angular.dev/guide/components/styling#ng-deep
-
-### CSS specificity
-
-Each CSS declaration has a level of *specificity* based on the type and number of selectors used.
-More specific styles take precedence over less specific styles. Angular Material generally attempts
-to use the least specific selectors possible. However, Angular Material may change component style
-specificity at any time, making custom overrides brittle and prone to breaking.
-
-You can read more about specificity and how it is calculated on the
-[MDN web docs](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity).
-
-### Rendering location
-
-Some Angular Material components render elements that are not direct DOM descendants of the
-component's host element. In particular, overlay-based components such as `MatDialog`, `MatMenu`,
-`MatTooltip`, etc. render into an overlay container element directly on the document body. Because
-these components render elements outside of your application's components, component-specific styles
-will not apply to these elements. You can define styles for these elements as global styles.
-
-#### Styling overlay components
-
-Overlay-based components have a `panelClass` property, or similar, that let you target the
-overlay pane. The following example shows how to add an `outline` style with `MatDialog`.
-
-```scss
-// Add this to your global stylesheet after including theme mixins.
-.my-outlined-dialog {
-  outline: 2px solid purple;
-}
-```
-
-```ts
-this.dialog.open(MyDialogComponent, {panelClass: 'my-outlined-dialog'})
-```
-
-You should always apply an application-specific prefix to global CSS classes to avoid naming
-collisions.
diff --git a/guides/duplicate-theming-styles.md b/guides/duplicate-theming-styles.md
deleted file mode 100644
index c85973453dd8..000000000000
--- a/guides/duplicate-theming-styles.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Avoiding duplicated theming styles
-
-As explained in the [theming guide](./theming.md), a theme in Angular Material consists of
-configurations for the `color`, `density` and `typography` systems. As some of these individual
-systems have default configurations, some usage patterns may cause duplication in the CSS output.
-
-Below are examples of patterns that generate duplicative theme styles:
-
-**Example #1**
-
-```scss
-@use '@angular/material' as mat;
-
-$light-theme: mat.define-light-theme((color: ...));
-$dark-theme: mat.define-dark-theme((color: ...));
-
-// Generates styles for all systems configured in the theme. In this case, color styles
-// and default density styles are generated. Density is in themes by default.
-@include mat.all-component-themes($light-theme);
-
-.dark-theme {
-  // Generates styles for all systems configured in the theme. In this case, color styles
-  // and the default density styles are generated. **Note** that this is a problem because it
-  // means that density styles are generated *again*, even though only the color should change.
-  @include mat.all-component-themes($dark-theme);
-}
-```
-
-To fix this, you can use the dedicated mixin for color styles for the `.dark-theme`
-selector. Replace the `all-component-themes` mixin and include the dark theme using the
-`all-component-colors` mixin. For example:
-
-```scss
-@use '@angular/material' as mat;
-
-...
-@include mat.all-component-themes($light-theme);
-
-.dark-theme {
-  // This mixin only generates the color styles now.
-  @include mat.all-component-colors($dark-theme);
-}
-```
-
-Typography can also be configured via Sass mixin; see `all-component-typographies`.
-
-**Example #2**
-
-Theme styles could also be duplicated if individual theme mixins are used. For example:
-
-```scss
-@use '@angular/material' as mat;
-
-@include mat.all-component-themes($my-theme);
-
-.my-custom-dark-button {
-  // This will also generate the default density styles again.
-  @include mat.button-theme($my-theme);
-}
-```
-
-To avoid this duplication of styles, use the dedicated mixin for the color system and
-extract the configuration for the color system from the theme.
-
-```scss
-@use '@angular/material' as mat;
-
-.my-custom-dark-button {
-  // This will only generate the color styles for `mat-button`.
-  @include mat.button-color($my-theme);
-}
-```
-
-## Disabling duplication warnings
-
-If your application intentionally duplicates styles, a global Sass variable can be
-set to disable duplication warnings from Angular Material. For example:
-
-```scss
-@use '@angular/material' as mat;
-
-mat.$theme-ignore-duplication-warnings: true;
-
-// Include themes as usual.
-@include mat.all-component-themes($light-theme);
-
-...
-```
diff --git a/guides/elevation.md b/guides/elevation.md
deleted file mode 100644
index 8725fda6746e..000000000000
--- a/guides/elevation.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# Applying Elevation
-
-[The Material Design specification][material-elevation] gives guidance on expressing elevation on
-UI elements by adding shadows. Angular Material provides CSS classes and Sass mixins for adding
-these shadows.
-
-[material-elevation]: https://material.io/design/environment/elevation.html
-
-## Elevation CSS classes
-
-The `core-theme` Sass mixin, described in the [theming guide][theming-guide], emits CSS classes for applying
-elevation. These classes follow the pattern `mat-elevation-z#`, where `#` is the elevation number
-you want, from 0 to 24. These predefined classes use the CSS `box-shadow` settings defined by the
-Material Design specification.
-
-You can dynamically change elevation on an element by swapping elevation CSS classes.
-
-```html
-<div [class.mat-elevation-z2]="!isActive" [class.mat-elevation-z8]="isActive"></div>
-```
-
-<!-- example(elevation-overview) -->
-
-[theming-guide]: https://material.angular.io/guide/theming#applying-a-theme-to-components
-
-## Elevation Sass mixins
-
-In addition to the predefined CSS classes, you can apply elevation styles using the `elevation`
-Sass mixin. This mixin accepts a `$zValue` and an optional `$color`. The `$zValue` is a number from
-0 to 24, representing the semantic elevation of the element, that controls the intensity of the
-box-shadow. You can use the `$color` parameter to further customize the shadow appearance.
-
-```scss
-@use '@angular/material' as mat;
-
-.my-class-with-default-shadow {
-  // Adds a shadow for elevation level 2 with default color and full opacity:
-  @include mat.elevation(2);
-}
-
-.my-class-with-custom-shadow {
-  // Adds a shadow for elevation level 2 with color #e91e63 and 80% of the default opacity:
-  @include mat.elevation(2, #e91e63, 0.8);
-}
-```
-
-### Overridable elevation
-
-When authoring a component, you may want to specify a default elevation that the component consumer
-can override. You can accomplish this by using the `overridable-elevation` Sass mixin. This behaves
-identically to the `elevation` mixin, except that the styles only apply when the element does not
-have a CSS class matching the pattern `mat-elevation-z#`, as described in
-[Elevation CSS classes](#elevation-css-classes) above.
-
-### Animating elevation
-
-You can use the `elevation-transition` mixin to add a transition when elevation changes.
-
-```scss
-@use '@angular/material' as mat;
-
-.my-class {
-  @include mat.elevation-transition();
-  @include mat.elevation(2);
-
-  &:active {
-    @include mat.elevation(8);
-  }
-}
-```
diff --git a/guides/material-2.md b/guides/material-2.md
index 5a5809d2bafb..5a908afd6c7c 100644
--- a/guides/material-2.md
+++ b/guides/material-2.md
@@ -1103,7 +1103,7 @@ the APIs for both are largely the same. However, there are a few differences to
   mixins should be wrapped in a selector. If your app includes such an `@include` at the root level,
   we recommend wrapping it in `html { ... }`
 - M3 has a different API for setting the color variant of a component (see
-  [using component color variants](https://material.angular.io/guide/theming#using-component-color-variants)
+  [using component color variants](#optional-add-backwards-compatibility-styles-for-color-variants)
   for more).
 - The `backgroundColor` property of `<mat-tab-group>` is not supported, and should not be used with
   M3 themes.
diff --git a/guides/schematics.md b/guides/schematics.md
index ec7787de4429..25d14101e6d9 100644
--- a/guides/schematics.md
+++ b/guides/schematics.md
@@ -26,7 +26,7 @@ The Angular Material `ng add` schematic helps you set up an Angular CLI project
 
 - Ensure [project dependencies](./getting-started#step-1-install-angular-material-angular-cdk-and-angular-animations) are placed in `package.json`
 - Enable the [BrowserAnimationsModule](./getting-started#step-2-configure-animations) in your app module
-- Add either a [prebuilt theme](./theming#pre-built-themes) or a [custom theme](./theming#defining-a-custom-theme)
+- Add either a prebuilt theme or a custom theme
 - Add Roboto fonts to your `index.html`
 - Add the [Material Icon font](./getting-started#step-6-optional-add-material-icons) to your `index.html`
 - Add global styles to
diff --git a/guides/theming-your-components.md b/guides/theming-your-components.md
deleted file mode 100644
index c8c304f85f14..000000000000
--- a/guides/theming-your-components.md
+++ /dev/null
@@ -1,247 +0,0 @@
-# Theme your own components with Angular Material's theming system
-
-You can use Angular Material's Sass-based theming system for your own custom components.
-
-**Note: The information on this page is specific to Material 3, for Material 2
-information on how to theme your components see the [Material 2 guide][material-2].**
-
-[material-2]: https://material.angular.io/guide/material-2-theming#theming-your-components
-
-## Reading values from a theme
-
-As described in the [theming guide][theme-map], a theme is a Sass map that contains style values to
-customize components. Angular Material provides APIs for reading values from this data structure.
-
-[theme-map]: https://material.angular.io/guide/theming#defining-a-theme
-
-### Reading tonal palette colors
-
-To read a
-[tonal palette color](https://m3.material.io/styles/color/system/how-the-system-works#3ce9da92-a118-4692-8b2c-c5c52a413fa6)
-from the theme, use the `get-theme-color` function with three arguments:
-
-| Argument   | Description                                                                                                                                                                                                                                                        |
-| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `$theme`   | The M3 theme to read from.                                                                                                                                                                                                                                         |
-| `$palette` | The name of the palette to read from. This can be any of the standard M3 palettes:<ul><li>`primary`</li><li>`secondary`</li><li>`tertiary`</li><li>`error`</li><li>`neutral`</li><li>`neutral-variant`</li></ul>                                                   |
-| `$hue`     | The hue number to read within the palette. This can be any of the standard hues:<ul><li>`0`</li><li>`10`</li><li>`20`</li><li>`30`</li><li>`40`</li><li>`50`</li><li>`60`</li><li>`70`</li><li>`80`</li><li>`90`</li><li>`95`</li><li>`99`</li><li>`100`</li></ul> |
-
-<!-- TODO(mmalerba): Illustrate palettes and hues with example. -->
-
-### Reading color roles
-
-To read a [color role](https://m3.material.io/styles/color/roles), use `get-theme-color` with two
-arguments:
-
-| Argument | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
-| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `$theme` | The M3 theme to read from.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
-| `$role`  | The name of the color role. This can be any of the M3 color roles:<ul><li>`primary`</li><li>`on-primary`</li><li>`primary-container`</li><li>`on-primary-container`</li><li>`primary-fixed`</li><li>`primary-fixed-dim`</li><li>`on-primary-fixed`</li><li>`on-primary-fixed-variant`</li><li>`secondary`</li><li>`on-secondary`</li><li>`secondary-container`</li><li>`on-secondary-container`</li><li>`secondary-fixed`</li><li>`secondary-fixed-dim`</li><li>`on-secondary-fixed`</li><li>`on-secondary-fixed-variant`</li><li>`tertiary`</li><li>`on-tertiary`</li><li>`tertiary-container`</li><li>`on-tertiary-container`</li><li>`tertiary-fixed`</li><li>`tertiary-fixed-dim`</li><li>`on-tertiary-fixed`</li><li>`on-tertiary-fixed-variant`</li><li>`error`</li><li>`on-error`</li><li>`error-container`</li><li>`on-error-container`</li><li>`surface-dim`</li><li>`surface`</li><li>`surface-bright`</li><li>`surface-container-lowest`</li><li>`surface-container-low`</li><li>`surface-container`</li><li>`surface-container-high`</li><li>`surface-container-highest`</li><li>`on-surface`</li><li>`on-surface-variant`</li><li>`outline`</li><li>`outline-variant`</li><li>`inverse-surface`</li><li>`inverse-on-surface`</li><li>`inverse-primary`</li><li>`scrim`</li><li>`shadow`</li></ul> |
-
-<!-- TODO(mmalerba): Illustrate color roles with example. -->
-
-### Reading the theme type
-
-To read the theme type (`light` or `dark`), call `get-theme-type` with a single argument:
-
-| Argument | Description                |
-| -------- | -------------------------- |
-| `$theme` | The M3 theme to read from. |
-
-
-### Reading typescale properties
-
-To read a [typescale](https://m3.material.io/styles/typography/type-scale-tokens) property from the
-theme, call `get-theme-typography` with three arguments:
-
-| Argument    | Description                                                                                                                                                                                                                                                                                                                                                                                                                          |
-| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `$theme`    | The M3 theme to read from.                                                                                                                                                                                                                                                                                                                                                                                                           |
-| `$level`    | The typescale level. This can be any of the M3 typescale levels:<ul><li>`display-large`</li><li>`display-medium`</li><li>`display-small`</li><li>`headline-large`</li><li>`headline-medium`</li><li>`headline-small`</li><li>`title-large`</li><li>`title-medium`</li><li>`title-small`</li><li>`body-large`</li><li>`body-medium`</li><li>`body-small`</li><li>`label-large`</li><li>`label-medium`</li><li>`label-small`</li></ul> |
-| `$property` | The CSS font property to get a value for. This can be one of the following CSS properties:<ul><li>`font` (The CSS font shorthand, includes all font properties except letter-spacing)</li><li>`font-family`</li><li>`font-size`</li><li>`font-weight`</li><li>`line-height`</li><li>`letter-spacing`</li></ul>                                                                                                                       |
-
-<!-- TODO(mmalerba): Illustrate typescales with example. -->
-
-### Reading the density scale
-
-To read the density scale (`0`, `-1`, `-2`, `-3`, `-4`, or `-5`) from the theme, call
-`get-theme-density` with a single argument:
-
-| Argument | Description                |
-| -------- | -------------------------- |
-| `$theme` | The M3 theme to read from. |
-
-### Checking what dimensions are configured for a theme
-
-Depending on how a theme was created, it may not have configuration data for all theming dimensions
-(base, color, typography, density). You can check if a theme has a configuration for a particular
-dimension by calling the `theme-has` Sass function, passing the theme and the dimension to check.
-
-See the below example of checking the configured dimensions for a theme:
-
-```scss
-$theme: mat.define-theme(...);
-
-$has-base: mat.theme-has($theme, base);
-$has-color: mat.theme-has($theme, color);
-$has-typography: mat.theme-has($theme, typography);
-$has-density: mat.theme-has($theme, density);
-```
-
-## Separating theme styles
-
-Angular Material components each have a Sass file that defines mixins for customizing
-that component's color and typography. For example, `MatButton` has mixins for `button-color` and
-`button-typography`. Each mixin emits all color and typography styles for that component,
-respectively.
-
-You can mirror this structure in your components by defining your own mixins. These mixins
-should accept an Angular Material theme, from which they can read color and typography values. You
-can then include these mixins in your application along with Angular Material's own mixins.
-
-## Step-by-step example
-
-To illustrate participation in Angular Material's theming system, we can look at an example of a
-custom carousel component. The carousel starts with a single file, `carousel.scss`, that contains
-structural, color, and typography styles. This file is included in the `styleUrls` of the component.
-
-```scss
-// carousel.scss
-
-.my-carousel {
-  display: flex;
-  font-family: serif;
-}
-
-.my-carousel-button {
-  border-radius: 50%;
-  color: blue;
-}
-```
-
-### Step 1: Extract theme-based styles to a separate file
-
-To change this file to participate in Angular Material's theming system, we split the styles into
-two files, with the color and typography styles moved into mixins. By convention, the new file
-name ends with `-theme`. Additionally, the file starts with an underscore (`_`), indicating that
-this is a Sass partial file. See the [Sass documentation][sass-partials] for more information about
-partial files.
-
-[sass-partials]: https://sass-lang.com/guide#topic-4
-
-```scss
-// carousel.scss
-
-.my-carousel {
-  display: flex;
-}
-
-.my-carousel-button {
-  border-radius: 50%;
-}
-```
-
-```scss
-// _carousel-theme.scss
-
-@mixin color($theme) {
-  .my-carousel-button {
-    color: blue;
-  }
-}
-
-@mixin typography($theme) {
-  .my-carousel {
-    font-family: serif;
-  }
-}
-```
-
-### Step 2: Use values from the theme
-
-Now that theme theme-based styles reside in mixins, we can extract the values we need from the
-theme passed into the mixins.
-
-```scss
-// _carousel-theme.scss
-
-@use 'sass:map';
-@use '@angular/material' as mat;
-
-@mixin color($theme) {
-  .my-carousel-button {
-    // Read the 50 hue from the primary color palette.
-    color: mat.get-theme-color($theme, primary, 50);
-  }
-}
-
-@mixin typography($theme) {
-  .my-carousel {
-    // Get the large headline font from the theme.
-    font: mat.get-theme-typography($theme, headline-large, font);
-  }
-}
-```
-
-### Step 3: Add a theme mixin
-
-For convenience, we can add a `theme` mixin that includes both color and typography.
-This theme mixin should only emit the styles for each color and typography, respectively, if they
-have a config specified.
-
-```scss
-// _carousel-theme.scss
-
-@use 'sass:map';
-@use '@angular/material' as mat;
-
-@mixin color($theme) {
-  .my-carousel-button {
-    // Read the 50 hue from the primary color palette.
-    color: mat.get-theme-color($theme, primary, 50);
-  }
-}
-
-@mixin typography($theme) {
-  .my-carousel {
-    // Get the large headline font from the theme.
-    font: mat.get-theme-typography($theme, headline-large, font);
-  }
-}
-
-@mixin theme($theme) {
-  @if mat.theme-has($theme, color) {
-    @include color($theme);
-  }
-
-  @if mat.theme-has($theme, typography) {
-    @include typography($theme);
-  }
-}
-```
-
-### Step 4: Include the theme mixin in your application
-
-Now that you've defined the carousel component's theme mixin, you can include this mixin along with
-the other theme mixins in your application.
-
-```scss
-@use '@angular/material' as mat;
-@use './path/to/carousel-theme' as carousel;
-
-$my-theme: mat.define-theme((
-  color: (
-    theme-type: light,
-    primary: mat.$red-palette,
-  ),
-  typography: (
-    brand-family: 'Comic Sans',
-    bold-weight: 900,
-  ),
-));
-
-html {
-  @include mat.all-component-themes($my-theme);
-  @include carousel.theme($my-theme);
-}
-```
diff --git a/guides/theming.md b/guides/theming.md
index c6d73ea35ebf..f30e54fab197 100644
--- a/guides/theming.md
+++ b/guides/theming.md
@@ -1,651 +1,469 @@
-# Theming Angular Material
+# Theming
 
-## What is theming?
+Angular Material lets you customize the appearance of your components by
+defining a custom theme. Angular Material’s theming system is inspired by
+Google’s [Material Design](https://m3.material.io/styles).
 
-Angular Material's theming system lets you customize base, color, typography, and density styles for components in your application. The theming system is based on Google's
-[Material Design 3][material-design-theming] specification which is the latest
-iteration of Google's open-source design system, Material Design.
+This guide describes how to set up theming for your application using
+Sass APIs introduced in Angular Material v19. 
 
-**For Material 2 specific documentation and how to update to Material 3, see the
-[Material 2 guide][material-2].**
+If your application depends on a version before v19, or if your application's
+theme is applied using a theme config created with `mat.define-theme`, 
+`mat.define-light-theme`, or `mat.define-dark-theme`,
+then you can refer to the theming guides at 
+[v18.material.angular.io/guides](https://v18.material.angular.io/guides).
 
-This document describes the concepts and APIs for customizing colors. For typography customization,
-see [Angular Material Typography][mat-typography]. For guidance on building components to be
-customizable with this system, see [Theming your own components][theme-your-own].
+## Getting Started
 
-[material-design-theming]: https://m3.material.io/
-[material-2]: https://material.angular.io/guide/material-2-theming
-[mat-typography]: https://material.angular.io/guide/typography
-[theme-your-own]: https://material.angular.io/guide/theming-your-components
+Your application needs to have a [Sass](https://sass-lang.com) **theme file**
+that includes Angular Material’s `mat.theme` mixin.
 
-### Sass
+The `mat.theme` mixin takes a map that defines color, typography, and density
+values and outputs a set of CSS variables that control the component appearance
+and layout. These variables are based on
+[Design Tokens](https://m3.material.io/foundations/design-tokens/overview).
 
-Angular Material's theming APIs are built with [Sass](https://sass-lang.com). This document assumes
-familiarity with CSS and Sass basics, including variables, functions, and mixins.
+The color variables are defined using the CSS color function
+[light-dark](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark)
+so that your theme can switch between light and dark mode using the CSS property
+[color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme).
 
-### Custom themes with Sass
+The following example theme file applies a violet color palette, Roboto font,
+and standard density to the application’s Angular Material components. It
+targets the `html` selector to ensure the CSS variables are applied across the
+entire application. The `color-scheme` is explicitly set to `light dark` so that
+the end user's system preferences are used to determine whether the application
+appears in light or dark mode.
 
-A **theme file** is a Sass file that calls Angular Material Sass mixins to output color,
-typography, and density CSS styles.
-
-#### Defining a theme
-
-Angular Material represents a theme as a Sass map that contains your color, typography, and density
-choices, as well as some base design system settings.
-
-The simplest usage of the API, `$theme: mat.define-theme()` defines a theme with default values.
-However, `define-theme` allows you to configure the appearance of your
-Angular Material app along three theming dimensions: color, typography, and density, by passing a
-theme configuration object. The configuration object may have the following properties.
-
-| Property     | Description                                                                                                     |
-| ------------ | --------------------------------------------------------------------------------------------------------------- |
-| `color`      | [Optional] A map of color options. See [customizing your colors](#customizing-your-colors) for details.         |
-| `typography` | [Optional] A map of typography options. See [customizing your typography](#customizing-your-typography) for details. |
-| `density`    | [Optional] A map of density options. See [customizing your density](#customizing-your-density) for details.     |
-
-<!-- TODO(mmalerba): Upgrade to embedded example -->
-
-```scss
-@use '@angular/material' as mat;
-
-$theme: mat.define-theme((
-  color: (
-    theme-type: dark,
-    primary: mat.$violet-palette,
-  ),
-  typography: (
-    brand-family: 'Comic Sans',
-    bold-weight: 900
-  ),
-  density: (
-    scale: -1
-  )
-));
-```
-
-#### Customizing your colors
-
-The following aspects of your app's colors can be customized via the `color` property of the theme
-configuration object (see the [M3 color spec](https://m3.material.io/styles/color/roles) to learn
-more about these terms):
-
-| Color Property | Description                                                                                                                                                                                                                                                              |
-| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `theme-type`   | [Optional] Specifies the type of theme, `light` or `dark`. The choice of a light versus a dark theme determines the background and foreground colors used throughout the components.                                                                                                                                                                                                               |
-| `primary`      | [Optional] Specifies the palette to use for the app's primary color palette. (Note: the secondary, neutral, and neutral-variant palettes described in the M3 spec will be automatically chosen based on your primary palette, to ensure a harmonious color combination). |
-| `tertiary`     | [Optional] Specifies the palette to use for the app's tertiary color palette.                                                                                                                                                                                            |
-
-##### Pre-built themes
-
-Angular Material includes several pre-built theme CSS files, each with different palettes selected.
-You can use one of these pre-built themes if you don't want to define a custom theme with Sass.
-
-| Theme                  | Light or dark? | Specification                    |
-|------------------------|----------------|----------------------------------|
-| `azure-blue.css`       | Light          | Material Design 3                |
-| `rose-red.css`         | Light          | Material Design 3                |
-| `cyan-orange.css`      | Dark           | Material Design 3                |
-| `magenta-violet.css`   | Dark           | Material Design 3                |
-| `deeppurple-amber.css` | Light          | Material Design 2                |
-| `indigo-pink.css`      | Light          | Material Design 2                |
-| `pink-bluegrey.css`    | Dark           | Material Design 2                |
-| `purple-green.css`     | Dark           | Material Design 2                |
-
-These files include the CSS for every component in the library. To include only the CSS for a subset
-of components, you must use the Sass API detailed in [Defining a theme](#defining-a-theme) above.
-You can [reference the source code for these pre-built themes](https://github.com/angular/components/blob/main/src/material/core/theming/prebuilt) to see examples of complete theme definitions.
-
-##### Pre-defined palettes
-
-The pre-built themes are based on a set of pre-defined palettes that can be used with the `primary`
-and `tertiary` options:
-
-- `$red-palette`
-- `$green-palette`
-- `$blue-palette`
-- `$yellow-palette`
-- `$cyan-palette`
-- `$magenta-palette`
-- `$orange-palette`
-- `$chartreuse-palette`
-- `$spring-green-palette`
-- `$azure-palette`
-- `$violet-palette`
-- `$rose-palette`
-
-##### Custom theme
-Alternatively, custom palettes can be generated with a custom color with the following schematic:
-
-```shell
-ng generate @angular/material:theme-color
 ```
-
-This schematic integrates with [Material Color Utilities](https://github.com/material-foundation/material-color-utilities) to build palettes based on a single color. Optionally you can provide
-additional custom colors for the secondary, tertiary, and neutral palettes.
-
-The output of the schematic is a new Sass file that exports the palettes that can be provided to
-a theme definition.
-
-```scss
 @use '@angular/material' as mat;
-@use './path/to/my-theme'; // location of generated file
 
 html {
-  @include mat.theme(
-    color: (
-      primary: my-theme.$primary-palette,
-      tertiary: my-theme.$tertiary-palette,
-    ),
+  color-scheme: light dark;
+  @include mat.theme((
+    color: mat.$violet-palette,
     typography: Roboto,
-    density: 0,
-  )
+    density: 0
+  ));
 }
 ```
 
-You can also optionally generate high contrast override mixins for your custom theme that allows for
-a better accessibility experience. Learn more about this schematic in its [documentation](https://github.com/angular/components/blob/main/src/material/schematics/ng-generate/theme-color/README.md).
+You can use the following styles to apply the theme’s surface background and
+on-surface text colors as a default across your application:
+
+```
+body {
+  background: var(--mat-sys-surface);
+  color: var(--mat-sys-on-surface);
+}
+```
 
-<!-- TODO(mmalerba): Illustrate palettes with example. -->
+The `mat.theme` mixin will only declare CSS variables for the categories
+included in the input. For example, if `typography` is not defined, then
+typography CSS variables will not be included in the output.
 
-#### Customizing your typography
+### **Color**
 
-The following aspects of your app's typography can be customized via the `typography` property of
-the theme configuration object.
+The `theme`‘s color determines the component color styles, such as the fill
+color of checkboxes or ripple color of buttons. It depends on color palettes of
+varying tones to build a color scheme. Check out the
+[Palettes](#prebuilt-color-palettes)
+section to learn about available prebuilt palettes, or how to create custom
+palettes.
 
-| Typography Property | Description                                                          |
-| ------------------- | -------------------------------------------------------------------- |
-| `plain-family`      | [Optional] The font family to use for plain text, such as body text. |
-| `brand-family`      | [Optional] The font family to use for brand text, such as headlines. |
-| `bold-weight`       | [Optional] The font weight to use for bold text.                     |
-| `medium-weight`     | [Optional] The font weight to use for medium text.                   |
-| `regular-weight`    | [Optional] The font weight to use for regular text.                  |
+You can set the color in one of two ways: as a single color palette, or as a
+color map.
 
-See the [typography guide](https://material.angular.io/guide/typography) for more
-information.
+#### *Single Color Palette*
 
-#### Customizing your density
+If you provide a single color palette, Angular Material uses its values for the
+theme’s primary, secondary, and tertiary colors. The CSS color values will be
+defined using `light-dark` CSS color function. Your application styles should
+define an explicit value declaration for the `color-scheme` CSS property.
 
-The following aspects of your app's density can be customized via the `density` property of the
-theme configuration object:
+#### *Color Map*
 
-| Density Property | Description                                                                                                      |
-| ---------------- | ---------------------------------------------------------------------------------------------------------------- |
-| `scale`          | [Optional] The level of compactness of the components in your app, from `0` (most space) to `-5` (most compact). |
+If you provide a color map, then the tertiary color palette can be configured
+separately from the primary palette. The tertiary palette can be used to add a
+distinct accent color to some components.
 
+You can also set the `theme-type` to determine the color values are defined:
 
-#### Applying a theme to components
+*   `color-scheme` \- include both light and dark colors using the `light-dark`
+    CSS color function
+*   `light` \- only define the light color values
+*   `dark` \- only define the dark color values
 
-The `core-theme` Sass mixin emits prerequisite styles for common features used by multiple
-components, such as ripples. This mixin must be included once per theme.
+The `light-dark` CSS color function is
+[widely available](https://caniuse.com/?search=light-dark) for all major
+browsers. However, if your application must support older browser versions or
+non-major browsers, you should explicitly set the `theme-type` to either `light`
+or `dark`.
 
-Each Angular Material component has a mixin for each [theming dimension](#theming-dimensions): base,
-color, typography, and density. For example, `MatButton` declares `button-base`, `button-color`,
-`button-typography`, and `button-density`. Each mixin emits only the styles corresponding to that
-dimension of customization.
+The following example theme file applies a violet primary color and orange
+tertiary color. The theme-type is set to `light` which means that only the light
+color values will be set for the application. The typography is set to Roboto
+with a standard density setting.
 
-Additionally, each component has a "theme" mixin that emits all styles that depend on the theme
-config. This theme mixin only emits color, typography, or density styles if you provided a
-corresponding configuration to `define-theme`, and it always emits the base styles.
+```
+@use '@angular/material' as mat;
 
-Once you've created your theme, you can apply it using the same `-theme`, `-color`, `-typography`, `-density`, and `-base` mixins.
+html {
+  @include mat.theme((
+    color: (
+      primary: mat.$violet-palette,
+      tertiary: mat.$orange-palette,
+      theme-type: light,
+    ),
+    typography: Roboto,
+    density: 0
+  ));
+}
+```
 
-For M3 themes, these mixins make some guarantees about the emitted styles.
+### **Typography**
 
-- The mixins emit properties under the exact selector you specify. They will _not_ add to the
-  selector or increase the specificity of the rule.
-- The mixins only emit
-  [CSS custom property declarations](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
-  (e.g. `--some-prop: xyz`). They do _not_ emit any standard CSS properties such as `color`,
-  `width`, etc.
+The `mat.theme` ‘s typography determines the text styles used in components,
+such as the font for dialog titles or menu list items.
 
-Apply the styles for each of the components used in your application by including each of their
-theme Sass mixins.
+You can set the typography in one of two ways: as a single font family value, or
+as a typography map.
 
-```scss
-@use '@angular/material' as mat;
+#### *Single Font Family Value*
 
-$my-theme: mat.define-theme((
- color: (
-    theme-type: light,
-    primary: mat.$violet-palette,
-  ),
-));
+If you provide a font family, Angular Material uses it for all the text in its
+components. The font weights used in components are set to 700 for bold text,
+500 for medium text, and 400 for regular text.
 
-html {
-  // Emit theme-dependent styles for common features used across multiple components.
-  @include mat.core-theme($my-theme);
+#### *Typography Map*
 
-  // Emit styles for MatButton based on `$my-theme`. Because the configuration
-  // passed to `define-theme` omits typography, `button-theme` will not
-  // emit any typography styles.
-  @include mat.button-theme($my-theme);
+If you provide a typography map, then distinct font families are set for plain
+and brand text. The plain font family is typically used for most of the
+application’s text, while the brand font family is typically used for headings
+and titles.
 
-  // Include the theme mixins for other components you use here.
-}
-```
+The typography map also sets specific weights for bold, medium, and regular
+text.
 
-As an alternative to listing every component that your application uses, Angular Material offers
-Sass mixins that includes styles for all components in the library: `all-component-bases`,
-`all-component-colors`, `all-component-typographies`, `all-component-densities`, and
-`all-component-themes`. These mixins behave the same as individual component mixins, except they
-emit styles for `core-theme` and _all_ 35+ components in Angular Material. Unless your application
-uses every single component, this will produce unnecessary CSS.
+The following example theme file applies the Roboto font family to plain text
+and the Open Sans font family to brand text. It specifies that bold weight is
+900, medium weight is 500, and regular weight is 300\. The color scheme uses the
+violet color palette with a standard density.
 
-```scss
+```
 @use '@angular/material' as mat;
 
-$my-theme: mat.define-theme((
- color: (
-    theme-type: light,
-    primary: mat.$violet-palette,
-  ),
-));
-
 html {
-  @include mat.all-component-themes($my-theme);
+  @include mat.theme((
+    color: mat.$violet-palette,
+    typography: (
+      plain-family: Roboto,
+      brand-family: Open Sans,
+      bold-weight: 900,
+      medium-weight: 500,
+      regular-weight: 300,
+    ),
+    density: 0,
+  ));
 }
 ```
 
-To include the emitted styles in your application, [add your theme file to the `styles` array of
-your project's `angular.json` file][adding-styles].
+### **Density**
 
-[adding-styles]: https://angular.dev/reference/configs/workspace-config#styles-and-scripts-configuration
+The `mat.theme` ‘s density value determines the spacing within components, such
+as how much padding is used around a button’s text or the height of form fields.
 
-#### Theming dimensions
+The density value accepts integers from 0 to \-5, where 0 is the default spacing
+and \-5 is the most dense and compact layout. Each whole number step down (-1,
+\-2, etc.) reduces the affected sizes by 4px, down to the minimum size necessary
+for a component to render itself coherently.
 
-Angular Material themes are divided along four dimensions: base, color, typography, and density.
+The following example theme file has a density setting of \-2 which causes most
+components to include less whitespace in their layout. The color scheme uses the
+violet color palette and applies Roboto as the font-family.
 
-##### Base
+```
+@use '@angular/material' as mat;
 
-Common base styles for the design system. These styles don't change based on your configured
-colors, typography, or density, so they only need to be included once per application. These
-mixins include structural styles such as border-radius, border-width, etc. All components have a base
-mixin that can be used to include its base styles. (For example,
-`@include mat.checkbox-base($theme)`)
+html {
+  @include mat.theme((
+    color: mat.$violet-palette,
+    typography: Roboto,
+    density: -2,
+  ));
+}
+```
 
-##### Color
+Setting the density below 0 can reduce accessibility and make navigation harder
+for users of assistive technology.
 
-Styles related to the colors in your application. These style should be included at least once in
-your application. Depending on your needs, you may need to include these styles multiple times
-with different configurations. (For example, if your app supports light and dark theme colors.)
-All components have a color mixin that can be used to include its color styles. (For example,
-`@include mat.checkbox-color($theme)`)
+Density customizations do not affect components that appear in task-based or
+pop-up contexts, such as the date picker. The Material Design density guidance
+explicitly discourages changes to density for such interactions because they
+don't compete for space in the application's layout.
 
-##### Typography
+## **Color Palettes**
 
-Styles related to the fonts used in your application, including the font family, size, weight,
-line-height, and letter-spacing. These style should be included at least once in your application.
-Depending on your needs, you may need to include these styles multiple times with different
-configurations. (For example, if your app supports reading content in either a serif or sans-serif
-font.) All components  have a typography mixin that can be used to include its typography
-styles. (For example, `@include mat.checkbox-typography($theme)`)
+A color palette is a set of similar colors with different hues ranging from
+light to dark. The Angular Material theme uses color palettes to create a color
+scheme to communicate an application’s hierarchy, state, and brand.
 
-##### Density
+### **Prebuilt Color Palettes**
 
-Styles related to the size and spacing of elements in your application. These style should be
-included at least once in your application. Depending on your needs, you may need to include these
-styles multiple times with different configurations. (For example, if your app supports both a
-normal and compact mode). All components have a density mixin that can be used to include its
-density styles. (For example, `@include mat.checkbox-density($theme)`)
+Angular Material provides twelve prebuilt color palettes that can be used for
+your application’s theme:
 
-##### Theme mixin
+*   `$red-palette`
+*   `$green-palette`
+*   `$blue-palette`
+*   `$yellow-palette`
+*   `$cyan-palette`
+*   `$magenta-palette`
+*   `$orange-palette`
+*   `$chartreuse-palette`
+*   `$spring-green-palette`
+*   `$azure-palette`
+*   `$violet-palette`
+*   `$rose-palette`
 
-All components also support a theme mixin that can be used to include the component's styles for all
-theme dimensions at once. (For example, `@include mat.checkbox-theme($theme)`).
+### **Custom Color Palettes**
 
-**The recommended approach is to rely on the `theme` mixins to lay down your base styles, and if
-needed use the single dimension mixins to override particular aspects for parts of your app (see the
-section on [Multiple themes in one file](#multiple-themes-in-one-file).)**
+The Angular Material
+[palette generation schematic](https://github.com/angular/components/blob/main/src/material/schematics/ng-generate/theme-color/README.md)
+builds custom color palettes based on a single color input for the primary
+color, and optionally color inputs to further customize secondary, tertiary, and
+neutral palettes:
 
-### Defining multiple themes
+```
+ng generate @angular/material:theme-color
+```
 
-Using the Sass API described in [Defining a theme](#defining-a-theme), you can also define
-_multiple_ themes by repeating the API calls multiple times. You can do this either in the same
-theme file or in separate theme files.
+## **Loading Fonts**
 
-#### Multiple themes in one file
+You can use Google Fonts as one option to load fonts in your application. For
+example, the following code in an application’s `<head>` loads the font family
+Roboto with the font weights 700, 500, and 400:
 
-Defining multiple themes in a single file allows you to support multiple themes without having to
-manage loading of multiple CSS assets. The downside, however, is that your CSS will include more
-styles than necessary.
+```
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
+```
 
-To control which theme applies when, `@include` the mixins only within a context specified via
-CSS rule declaration. See the [documentation for Sass mixins][sass-mixins] for further background.
+Learn more about using fonts with
+[Google Fonts](https://developers.google.com/fonts/docs/getting_started). By
+default, projects created with the Angular CLI are
+[configured](https://angular.dev/reference/configs/workspace-config#fonts-optimization-options)
+to inline assets from Google Fonts to reduce render-blocking requests.
 
-[sass-mixins]: https://sass-lang.com/documentation/at-rules/mixin
+## **Supporting Light and Dark Mode**
 
-```scss
-@use '@angular/material' as mat;
+By default, the `mat.theme` mixin defines colors using the CSS color function
+`light-dark` to make it easy for your application to switch between light and
+dark mode. The `light-dark` function depends on the value of `color-scheme`
+declared in your application’s global styles. If your application does not
+define a value for `color-scheme`, then the light colors will always be applied.
 
-// Define a dark theme
-$dark-theme: mat.define-theme((
-  color: (
-    theme-type: dark,
-    primary: mat.$violet-palette,
-  ),
-));
-
-// Define a light theme
-$light-theme: mat.define-theme((
-  color: (
-    theme-type: light,
-    primary: mat.$violet-palette,
-  ),
-));
+You can define `color-scheme: light` or `color-scheme: dark` to explicitly
+define your application’s mode. To set the mode depending on the user’s system
+preferences, use `color-scheme: light-dark` as shown in the following example:
+
+```
+@use '@angular/material' as mat;
 
 html {
-  // Apply the dark theme by default
-  @include mat.core-theme($dark-theme);
-  @include mat.button-theme($dark-theme);
-
-  // Apply the light theme only when the user prefers light themes.
-  @media (prefers-color-scheme: light) {
-    // Use the `-color` mixins to only apply color styles without reapplying the same
-    // typography and density styles.
-    @include mat.core-color($light-theme);
-    @include mat.button-color($light-theme);
-  }
+  color-scheme: light dark;
+  @include mat.theme((
+    color: mat.$violet-palette,
+    typography: Roboto,
+    density: 0
+  ));
 }
 ```
 
-#### Multiple themes across separate files
-
-You can define multiple themes in separate files by creating multiple theme files per
-[Defining a theme](#defining-a-theme), adding each of the files to the `styles` of your
-`angular.json`. However, you must additionally set the `inject` option for each of these files to
-`false` in order to prevent all the theme files from being loaded at the same time. When setting
-this property to `false`, your application becomes responsible for manually loading the desired
-file. The approach for this loading depends on your application.
-
-### Application background color
-
-By default, Angular Material does not apply any styles to your DOM outside
-its own components. If you want to set your application's background color
-to match the components' theme, you can either:
-1. Put your application's main content inside `mat-sidenav-container`, assuming you're using
-   `MatSidenav`, or
-2. Apply the `mat-app-background` CSS class to your main content root element (typically `body`).
-
-### Granular customizations with CSS custom properties
-
-The CSS custom properties emitted by the theme mixins are derived from
-[M3's design tokens](https://m3.material.io/foundations/design-tokens/overview). To further
-customize your UI beyond the `define-theme` API, you can manually set these custom properties in
-your styles.
-
-The guarantees made by the theme mixins mean that you do not need to target internal selectors of
-components or use excessive specificity to override any of these tokenized properties. Always apply
-your base theme to your application's root element (typically `html` or `body`) and apply any
-overrides on the highest-level selector where they apply.
-
-<!-- TODO(mmalerba): Upgrade to embedded example -->
-
-```html
-<mat-sidenav-container>
-  Some content...
-  <mat-sidenav>
-    Some sidenav content...
-    <mat-checkbox class="danger">Enable admin mode</mat-checkbox>
-  </mat-sidenav>
-</mat-sidenav-container>
-```
+You can also use the strategy of defining `color-scheme` under a CSS selector so
+that the mode depends on whether that class has been applied. In the following
+example, the application always displays the light mode theme unless the class
+“dark-mode” is added to the HTML body.
 
-```scss
+```
 @use '@angular/material' as mat;
 
-$light-theme: mat.define-theme();
-$dark-theme: mat.define-theme((
-  color: (
-    theme-type: dark
-  )
-));
-
 html {
-  // Apply the base theme at the root, so it will be inherited by the whole app.
-  @include mat.all-component-themes($light-theme);
-}
-
-mat-sidenav {
-  // Override the colors to create a dark sidenav.
-  @include mat.all-component-colors($dark-theme);
-}
-
-.danger {
-  // Override the checkbox hover state to indicate that this is a dangerous setting. No need to
-  // target the internal selectors for the elements that use these variables.
-  --mdc-checkbox-unselected-hover-state-layer-color: red;
-  --mdc-checkbox-unselected-hover-icon-color: red;
+  color-scheme: light;
+  @include mat.theme((
+    color: mat.$violet-palette,
+    typography: Roboto,
+    density: 0
+  ));
 }
-```
 
-## Customizing density
-
-Angular Material's density customization is based on the
-[Material Design density guidelines][material-density]. This system defines a scale where zero
-represents the default density. You can decrement the number for _more density_ and increment the
-number for _less density_.
-
-The density system is based on a *density scale*. The scale starts with the
-default density of `0`. Each whole number step down (`-1`, `-2`, etc.) reduces
-the affected sizes by `4dp`, down to the minimum size necessary for a component to render
-coherently.
-
-Components that appear in task-based or pop-up contexts, such as `MatDatepicker`, don't change their
-size via the density system. The [Material Design density guidance][material-density] explicitly
-discourages increasing density for such interactions because they don't compete for space in the
-application's layout.
-
-You can apply custom density setting to the entire library or to individual components using their
-density Sass mixins.
-
-```scss
-// You can set a density setting in your theme to apply to all components.
-$dark-theme: mat.define-theme((
-  color: ...,
-  typography: ...,
-  density: (
-    scale: -2
-  ),
-));
-
-// Or you can selectively apply the Sass mixin to affect only specific parts of your application.
-.the-dense-zone {
-  @include mat.button-density(-1);
+body.dark-mode {
+  color-scheme: dark;
 }
 ```
 
-[material-density]: https://m3.material.io/foundations/layout/understanding-layout/spacing
+Angular Material does not automatically apply different styles or themes based
+on user preference media queries, such as `color-scheme`, `prefers-color-scheme`
+or `prefers-contrast`. Instead, Angular Material gives you the flexibility to
+define your own queries to apply the styles that make sense for your users. This
+may mean relying on `color-scheme: light dark`, defining custom media queries,
+or reading a saved user preference to apply styles.
 
-## Strong focus indicators
+## **Multiple Themes**
 
-By default, most components indicate browser focus by changing their background color as described
-by the Material Design specification. This behavior, however, can fall short of accessibility
-requirements, such as [WCAG][], which require a stronger indication of browser focus.
+You can call the `mat.theme` mixin more than once to apply multiple different
+color schemes in your application.
 
-Angular Material supports rendering highly visible outlines on focused elements. Applications can
-enable these strong focus indicators via two Sass mixins:
-`strong-focus-indicators` and `strong-focus-indicators-theme`.
+### **Context-specific Themes**
 
-The `strong-focus-indicators` mixin emits structural indicator styles for all components. This mixin
-should be included exactly once in an application, similar to the `core` mixin described above.
+The following example theme file customizes the theme for components in
+different contexts. In this case, a cyan-based palette is applied to a container
+of information about deleting data, causing buttons and other components to have
+a unique and attention-grabbing style applied:
 
-The `strong-focus-indicators-theme` mixin emits only the indicator's color styles. This mixin should
-be included once per theme, similar to the theme mixins described above. Additionally, you can use
-this mixin to change the color of the focus indicators in situations in which the default color
-would not contrast sufficiently with the background color.
-
-The following example includes strong focus indicator styles in an application alongside the rest of
-the custom theme API.
-
-```scss
+```
 @use '@angular/material' as mat;
 
-@include mat.strong-focus-indicators();
-
-$my-theme: mat.define-theme((
-  color: (
-    theme-type: light,
-    primary: mat.$violet-palette,
-  ),
-));
-
 html {
-  @include mat.all-component-themes($my-theme);
-  @include mat.strong-focus-indicators-theme($my-theme);
+  @include mat.theme((
+    color: mat.$violet-palette,
+    typography: Roboto,
+    density: 0,
+  ));
 }
-```
-
-### Customizing strong focus indicators
 
-You can pass a configuration map to `strong-focus-indicators` to customize the appearance of the
-indicators. This configuration includes `border-style`, `border-width`, and `border-radius`.
+.example-bright-container {
+  @include mat.theme((
+    color: mat.$cyan-palette,
+  ));
+}
+```
 
-You also can customize the color of indicators with `strong-focus-indicators-theme`. This mixin
-accepts either a theme, as described earlier in this guide, or a CSS color value. When providing a
-theme, the indicators will use the default hue of the primary palette.
+## **Using Theme Styles**
 
-The following example includes strong focus indicator styles with custom settings alongside the rest
-of the custom theme API.
+An application’s custom components can use the CSS variables defined by
+`mat.theme` to apply the theme’s colors and typography.
 
-```scss
-@use '@angular/material' as mat;
+The color variables are useful for emphasizing important text and actions,
+providing stronger application branding, and ensuring strong contrast ratios
+between surface and on-surface elements.
 
-@include mat.strong-focus-indicators((
-  border-style: dotted,
-  border-width: 4px,
-  border-radius: 2px,
-));
+The typography variables are useful for creating clear information hierarchy and
+text consistency through the application.
 
-$my-theme: mat.define-theme((
-  color: (
-    theme-type: light,
-    primary: mat.$violet-palette,
-  ),
-));
+The following example styles demonstrate a component using the color and
+typography variables to create an application-wide banner presenting important
+information to the user:
 
-html {
-  @include mat.all-component-themes($my-theme);
-  @include mat.strong-focus-indicators-theme(purple);
+```
+:host {
+  background: var(--mat-sys-primary-container);
+  color: var(--mat-sys-on-primary-container);
+  border: 1px solid var(--mat-sys-outline-variant);
+  font: var(--mat-sys-body-large);
 }
 ```
 
-[WCAG]: https://www.w3.org/WAI/standards-guidelines/wcag/glance/
+See the [Theme Variables](https://material.angular.io/guide/system-variables) guide for a
+comprehensive list of these variables, examples of where they are used, and how
+components can depend on them.
 
-## Theming and style encapsulation
+## **Customizing Tokens**
 
-Angular Material assumes that, by default, all theme styles are loaded as global CSS. If you want
-to use [Shadow DOM][shadow-dom] in your application, you must load the theme styles within each
-shadow root that contains an Angular Material component. You can accomplish this by manually loading
-the CSS in each shadow root, or by using [Constructable Stylesheets][constructable-css].
+Angular Material components also allow for narrowly targeted customization of
+specific tokens through the `overrides` mixins. This enables fine-grained
+adjustments to specific system-level theme CSS variables as well as individual
+component tokens, such as a component’s border-color or title font size.
 
-[shadow-dom]: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM
-[constructable-css]: https://developers.google.com/web/updates/2019/02/constructable-stylesheets
+The `overrides` API validates that the customized tokens are correctly spelled
+and can be used to ensure backwards compatibility if tokens are added, moved, or
+renamed in future versions.
 
-## User preference media queries
+### **System Tokens**
 
-Angular Material does not apply styles based on user preference media queries, such as
-`prefers-color-scheme` or `prefers-contrast`. Instead, Angular Material's Sass mixins give you the
-flexibility to apply theme styles to based on the conditions that make the most sense for your
-users. This may mean using media queries directly or reading a saved user preference.
+System-level tokens can be changed to different values through the
+`mat.theme-overrides` mixin, which will redefine CSS variables that are used in
+the application.
 
-## Using component color variants
+The following example applies a violet color palette for the application, but
+alters the `primary-container` token to a specific shade of blue.
 
-A number of components have a `color` input property that allows developers to apply different color
-variants of the component. When using an M3 theme, this input still adds a CSS class to the
-component (e.g. `.mat-accent`). However, there are no built-in styles targeting these classes. You
-can instead apply color variants by passing the `$color-variant` option to a component's `-theme` or
-`-color` mixins.
+```
+@use '@angular/material' as mat;
 
-<!-- TODO(mmalerba): Upgrade to embedded example -->
+html {
+  color-scheme: light dark;
+  @include mat.theme((
+    color: mat.$violet-palette,
+    typography: Roboto,
+    density: 0
+  ));
 
-```html
-<mat-checkbox class="tertiary-checkbox" />
-<section class="tertiary-checkbox">
-  <mat-checkbox />
-</section>
+  .example-orange-primary-container {
+    @include mat.theme-overrides((
+      primary-container: #84ffff
+    ));
+  }
+}
 ```
 
-```scss
-@use '@angular/material' as mat;
+Alternatively, an optional override map can be provided in the `mat.theme` mixin
+to replace values applied by the mixin:
 
-$theme: mat.define-theme();
+```
+@use '@angular/material' as mat;
 
-.tertiary-checkbox {
-  @include mat.checkbox-color($theme, $color-variant: tertiary);
+html {
+  color-scheme: light dark;
+  @include mat.theme((
+    color: mat.$violet-palette,
+    typography: Roboto,
+    density: 0
+  ), $overrides: (
+    primary-container: orange,
+  );
 }
 ```
 
-This API is more flexible, and produces less CSS. For example, the `.tertiary-checkbox` class shown
-above can be applied to any checkbox _or_ any element that contains checkboxes, to change the color
-of all checkboxes within that element.
-
-While you should prefer applying the mixins with color variants explicitly, if migrating from M2 to
-M3 you can alternatively use [the provided backwards compatibility mixins](https://material.angular.io/guide/material-2-theming#how-to-migrate-an-app-from-material-2-to-material-3)
-that apply styles directly to the existing CSS classes (`mat-primary`, `mat-accent`, and
-`mat-warn`).
-
-The table below shows the supported `$color-variant` values for each component. (Unlisted components
-do not support any color variants.)
-
-| Component        | Supported `$color-variant` values                      | Default     |
-| ---------------- | ------------------------------------------------------ | ----------- |
-| Badge            | `primary`, `secondary`, `tertiary`, `error`            | `error`     |
-| Button           | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Button-toggle    | `primary`, `secondary`, `tertiary`, `error`            | `secondary` |
-| Checkbox         | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Chips            | `primary`, `secondary`, `tertiary`, `error`            | `secondary` |
-| Datepicker       | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Fab              | `primary`, `secondary`, `tertiary`                     | `primary`   |
-| Form-field       | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Icon             | `surface`, `primary`, `secondary`, `tertiary`, `error` | `surface`   |
-| Option           | `primary`, `secondary`, `tertiary`, `error`            | `secondary` |
-| Progress-bar     | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Progress-spinner | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Pseudo-checkbox  | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Radio            | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Select           | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Slide-toggle     | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Slider           | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Stepper          | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-| Tabs             | `primary`, `secondary`, `tertiary`, `error`            | `primary`   |
-
-## Style customization outside the theming system
-
-Angular Material supports customizing color, typography, and density as outlined in this document.
-Angular strongly discourages, and does not directly support, overriding component CSS outside the
-theming APIs described above. Component DOM structure and CSS classes are considered private
-implementation details that may change at any time.
-
-<!-- TODO(amysorto): Move this section into theming your components guide and
-move M2 specific details to the material 2 guide -->
-## Theme your own components using a Material 3 theme
-
-The same utility functions for reading properties of M2 themes (described in
-[our guide for theming your components](https://material.angular.io/guide/theming-your-components))
-can be used to read properties from M3 themes. However, the named palettes, typography
-levels, etc. available are different for M3 themes, in accordance with the spec.
-
-The structure of the theme object is considered an implementation detail. Code should not depend on
-directly reading properties off of it, e.g. using `map.get`. Always use the utility functions
-provided by Angular Material to access properties of the theme.
-
-<!-- TODO(mmalerba): Upgrade to embedded example -->
-
-```scss
-@use '@angular/material' as mat;
+### **Component Tokens**
 
-@mixin my-comp-theme($theme) {
-  .my-comp {
-    font: mat.get-theme-typography($theme, body-large, font);
-    letter-spacing: mat.get-theme-typography($theme, body-large, letter-spacing);
-    background: mat.get-theme-color($theme, surface);
-    @if mat.get-theme-type($theme) == dark {
-      color: mat.get-theme-color($theme, primary, 20);
-    } @else {
-      color: mat.get-theme-color($theme, primary, 80);
-    }
-    padding: 48px + (2px * mat.get-theme-density($theme));
-  }
+Each Angular Material component defines an `overrides` mixin that can be used to
+customize tokenized styles for their color, typography, and density.
+
+More information for each component’s override API, including their list of
+available customizable tokens, can be found on their respective documentation
+page under the Styling tab.
+
+The following example demonstrates the Card’s `overrides` API to change the
+background color to red, increase the corner border radius, and specify a larger
+title font size.
+
+```
+html {
+  @include mat.card-overrides((
+    elevated-container-color: red,
+    elevated-container-shape: 32px,
+    title-text-size: 2rem,
+  ));
 }
 ```
+
+### **Direct Style Overrides**
+
+Angular Material supports customizing color, typography, and density as outlined
+in this document. Angular strongly discourages, and does not directly support,
+overriding component CSS outside the theming APIs described above. Component DOM
+structure and CSS classes are considered private implementation details that may
+change at any time. CSS variables used by the Angular Material components should
+be defined through the `overrides` API instead of defined explicitly.
+
+## **Shadow DOM**
+
+Angular Material assumes that, by default, all theme styles are loaded as global
+CSS. If you want to use
+[Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM)
+in your application, you must load the theme styles within each shadow root that
+contains an Angular Material component. You can accomplish this by manually
+loading the CSS in each shadow root, or by using
+[Constructable Stylesheets](https://developers.google.com/web/updates/2019/02/constructable-stylesheets).
diff --git a/guides/typography.md b/guides/typography.md
deleted file mode 100644
index 9f39aeaa4f8d..000000000000
--- a/guides/typography.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Customizing Typography
-
-**Note: The information on this page is specific to Material 3, for Material 2
-information on typography go to the [Material 2 guide](https://material.angular.io/guide/material-2-theming#customizing-typography).**
-
-## What is typography?
-
-Typography is a way of arranging type to make text legible, readable, and appealing when displayed.
-Angular Material's [theming system][theming-system] supports customizing the typography settings
-for the library's components. Additionally, Angular Material provides APIs for applying typography
-styles to elements in your own application.
-
-Angular Material's theming APIs are built with [Sass](https://sass-lang.com). This document assumes
-familiarity with CSS and Sass basics, including variables, functions, and mixins.
-
-[theming-system]: https://material.angular.io/guide/theming
-
-## Including font assets
-
-Angular Material's typography APIs lets you specify any font-face. The default font-face value is
-configured to [Google's Roboto font][roboto] with the 300, 400, and 500 font-weight styles. To use
-Roboto, your application must load the font, which is not included with Angular Material. The
-easiest way to load Roboto, or any other custom font, is by using Google Fonts. The following
-snippet can be placed in your application's `<head>` to load Roboto from Google Fonts.
-
-```html
-<link rel="preconnect" href="https://fonts.gstatic.com">
-<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
-```
-
-See [Getting Started with the Google Fonts API][fonts-api] for more about using Google Fonts. Also
-note that, by default, [the Angular CLI inlines assets from Google Fonts to reduce render-blocking
-requests][font-inlining].
-
-[roboto]: https://fonts.google.com/share?selection.family=Roboto:wght@300;400;500
-[fonts-api]: https://developers.google.com/fonts/docs/getting_started
-[font-inlining]: https://angular.dev/reference/configs/workspace-config#fonts-optimization-options
-
-## Configuring Typography
-
-The following aspects of your app's typography can be customized via the `typography` property of
-the theme configuration object.
-
-| Typography Property | Description                                                          |
-| ------------------- | -------------------------------------------------------------------- |
-| `plain-family`      | [Optional] The font family to use for plain text, such as body text. |
-| `brand-family`      | [Optional] The font family to use for brand text, such as headlines. |
-| `bold-weight`       | [Optional] The font weight to use for bold text.                     |
-| `medium-weight`     | [Optional] The font weight to use for medium text.                   |
-| `regular-weight`    | [Optional] The font weight to use for regular text.                  |
-
-These are used to generate the styles for the different typescale levels.
-
-## Type scale levels
-
-A **type scale** is a selection of font styles that can be used across an app.
-They’re assigned based on use (such as display or headline), and grouped more
-broadly into categories based on scale (such as large or small). For more
-information, see the [M3 typography spec](https://m3.material.io/styles/typography/type-scale-tokens).
-
-There are `large`, `medium`, and `small` variations for the following type roles:
-- **Display**: Display styles are reserved for short, important text or numerals. They work best on large screens.
-- **Headline**: Headline styles are best-suited for short, high-emphasis text on smaller screens. These styles can be good for marking primary passages of text or important regions of content.
-- **Title**: Title styles are smaller than headline styles, and should be used for medium-emphasis text that remains relatively short. For example, consider using title styles to divide secondary passages of text or secondary regions of content.
-- **Body**: Body styles are used for longer passages of text in your app.
-- **Label**: Label styles are smaller, utilitarian styles, used for things like the text inside components or for very small text in the content body, such as captions.
-
-The table below lists the CSS classes emitted and the native elements styled.
-
-| CSS class                 | Typesale level      |
-|---------------------------|---------------------|
-| `.mat-display-large`      | `display-large`     |
-| `.mat-display-medium`     | `display-medium`    |
-| `.mat-display-small`      | `display-small`     |
-| `.mat-headline-large`     | `headline-large`    |
-| `.mat-headline-medium`    | `headline-medium`   |
-| `.mat-headline-small`     | `headline-small`    |
-| `.mat-title-large`        | `title-large`       |
-| `.mat-title-medium`       | `title-medium`      |
-| `.mat-title-small`        | `title-small`       |
-| `.mat-body-large`         | `body-large`        |
-| `.mat-body-medium`        | `body-medium`       |
-| `.mat-body-small`         | `body-small`        |
-| `.mat-label-large`        | `label-large`       |
-| `.mat-label-medium`       | `label-medium`      |
-| `.mat-label-small`        | `label-small`       |
-
-## Using typography styles in your application
-
-See the [theming guide](https://material.angular.io/guide/theming#defining-a-theme)
-for details on setting up a theme that has typography configured.
-
-### Reading typography values from a config
-
-It is possible to read typography properties from a theme for use in your own components. For more
-information about this see our guide on [Theming your own components][reading-typography].
-
-[reading-typography]: https://material.angular.io/guide/theming-your-components#reading-typography-values
-
-## Using typography styles in your application
-
-**Note: this section is applicable only if you are using the [M2 backwards compatability
-mixin](https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-typography-hierarchy).**
-
-In addition to styles shared between components, the `typography-hierarchy` mixin includes CSS
-classes for styling your application. These CSS classes correspond to the typography levels in your
-typography config. This mixin also emits styles for native header elements scoped within the
-`.mat-typography` CSS class.
-
-```scss
-@use '@angular/material' as mat;
-
-// Use the default configuration.
-$my-typography: mat.define-typography-config();
-@include mat.typography-hierarchy($my-typography);
-```
-
-In addition to the typographic styles, these style rules also include a `margin-bottom` for
-headers and paragraphs. For `body` styles, text is styled within the provided CSS selector.
-
-The `.mat-h5` and `.mat-h6` styles don't directly correspond to a specific Material Design
-typography level. The `.mat-h5` style uses the `body-2` level with the font-size scaled down by
-`0.83`. The `.mat-h6` style uses the `body-2` level with the font-size scaled down by `0.67`.
-
-The `button` typography level does not map to a CSS class.
-
-The following example demonstrates usage of the typography styles emitted by the
-`typography-hierarchy` mixin.
-
-```html
-<body>
-  <!-- This header will *not* be styled because it is outside `.mat-typography` -->
-  <h1>Top header</h1>
-
-  <!-- This paragraph will be styled as `body-1` via the `.mat-body` CSS class applied -->
-  <p class="mat-body">Introductory text</p>
-
-  <div class="mat-typography">
-    <!-- This header will be styled as `title` because it is inside `.mat-typography` -->
-    <h2>Inner header</h2>
-
-    <!-- This paragraph will be styled as `body-1` because it is inside `.mat-typography` -->
-    <p>Some inner text</p>
-  </div>
-</body>
-```
diff --git a/integration/size-test/cdk/drag-drop/all-directives.ts b/integration/size-test/cdk/drag-drop/all-directives.ts
index b2cc0fba0610..303e9633ae49 100644
--- a/integration/size-test/cdk/drag-drop/all-directives.ts
+++ b/integration/size-test/cdk/drag-drop/all-directives.ts
@@ -3,6 +3,7 @@ import {Component, NgModule} from '@angular/core';
 
 /** Component using all parts of the drag-drop module. All directives should be preserved. */
 @Component({
+  standalone: false,
   template: `
     <div cdkDropListGroup>
       <div cdkDropList>
diff --git a/integration/size-test/cdk/drag-drop/basic.ts b/integration/size-test/cdk/drag-drop/basic.ts
index c4e7a5fa7e2c..aa1f7757d32e 100644
--- a/integration/size-test/cdk/drag-drop/basic.ts
+++ b/integration/size-test/cdk/drag-drop/basic.ts
@@ -7,6 +7,7 @@ import {Component, NgModule} from '@angular/core';
  * `CdkDragHandle` are not used and should be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <div cdkDropList>
       <div cdkDrag></div>
diff --git a/integration/size-test/material/autocomplete/without-optgroup.ts b/integration/size-test/material/autocomplete/without-optgroup.ts
index f439047dc847..ef4881841d1c 100644
--- a/integration/size-test/material/autocomplete/without-optgroup.ts
+++ b/integration/size-test/material/autocomplete/without-optgroup.ts
@@ -6,6 +6,7 @@ import {MatAutocompleteModule} from '@angular/material/autocomplete';
  * autocomplete like `MatOptgroup` are not used and should be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <input [matAutocomplete]="myAutocomplete">
     <mat-autocomplete #myAutocomplete>
diff --git a/integration/size-test/material/button-toggle/standalone.ts b/integration/size-test/material/button-toggle/standalone.ts
index 7d1a2dc49d3d..c6c8bb47d00b 100644
--- a/integration/size-test/material/button-toggle/standalone.ts
+++ b/integration/size-test/material/button-toggle/standalone.ts
@@ -6,6 +6,7 @@ import {MatButtonToggleModule} from '@angular/material/button-toggle';
  * module such as `MatButtonToggleGroup` are not used and should be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-button-toggle>Center text</mat-button-toggle>
   `,
diff --git a/integration/size-test/material/chips/basic.ts b/integration/size-test/material/chips/basic.ts
index 45e1827302ad..d5607a708401 100644
--- a/integration/size-test/material/chips/basic.ts
+++ b/integration/size-test/material/chips/basic.ts
@@ -6,6 +6,7 @@ import {MatChipsModule} from '@angular/material/chips';
  * chip module such as `MatChipRemove` are not used and should be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-chip-listbox>
       <mat-chip-option>First</mat-chip-option>
diff --git a/integration/size-test/material/datepicker/range-picker/without-form-field.ts b/integration/size-test/material/datepicker/range-picker/without-form-field.ts
index 6756ced254bc..52a85d09c21f 100644
--- a/integration/size-test/material/datepicker/range-picker/without-form-field.ts
+++ b/integration/size-test/material/datepicker/range-picker/without-form-field.ts
@@ -8,6 +8,7 @@ import {MatDatepickerModule} from '@angular/material/datepicker';
  * should be omitted.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-date-range-input [rangePicker]="picker">
       <input matStartDate>
diff --git a/integration/size-test/material/expansion/without-accordion.ts b/integration/size-test/material/expansion/without-accordion.ts
index 13fe53ba0cc1..10be13872738 100644
--- a/integration/size-test/material/expansion/without-accordion.ts
+++ b/integration/size-test/material/expansion/without-accordion.ts
@@ -6,6 +6,7 @@ import {MatExpansionModule} from '@angular/material/expansion';
  * the module such as `MatAccordion` or `CdkAccordion` should be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-expansion-panel>
       <mat-expansion-panel-header>Title</mat-expansion-panel-header>
diff --git a/integration/size-test/material/form-field/advanced.ts b/integration/size-test/material/form-field/advanced.ts
index 5efcce71d668..d663269732cf 100644
--- a/integration/size-test/material/form-field/advanced.ts
+++ b/integration/size-test/material/form-field/advanced.ts
@@ -7,6 +7,7 @@ import {MatInputModule} from '@angular/material/input';
  * directives such as `MatError`, `MatHint`, `MatPrefix` or `MatSuffix`.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-form-field>
       <div matSuffix></div>
diff --git a/integration/size-test/material/form-field/basic.ts b/integration/size-test/material/form-field/basic.ts
index 2e5b64f7f8e9..fb518efb9898 100644
--- a/integration/size-test/material/form-field/basic.ts
+++ b/integration/size-test/material/form-field/basic.ts
@@ -8,6 +8,7 @@ import {MatInputModule} from '@angular/material/input';
  * and should be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-form-field>
       <input matInput>
diff --git a/integration/size-test/material/list/nav-list.ts b/integration/size-test/material/list/nav-list.ts
index 9c605aadcfef..576120f476e9 100644
--- a/integration/size-test/material/list/nav-list.ts
+++ b/integration/size-test/material/list/nav-list.ts
@@ -7,6 +7,7 @@ import {MatListModule} from '@angular/material/list';
  * and should be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-nav-list>
       <mat-list-item>
diff --git a/integration/size-test/material/menu/without-lazy-content.ts b/integration/size-test/material/menu/without-lazy-content.ts
index 26852f18ea32..602b9fb25cad 100644
--- a/integration/size-test/material/menu/without-lazy-content.ts
+++ b/integration/size-test/material/menu/without-lazy-content.ts
@@ -6,6 +6,7 @@ import {MatMenuModule} from '@angular/material/menu';
  * specified, so it should be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <button [matMenuTriggerFor]="menu">Open</button>
     <mat-menu #menu="matMenu"></mat-menu>
diff --git a/integration/size-test/material/radio/without-group.ts b/integration/size-test/material/radio/without-group.ts
index 79a9a25e4ecb..e976e49bf95c 100644
--- a/integration/size-test/material/radio/without-group.ts
+++ b/integration/size-test/material/radio/without-group.ts
@@ -6,6 +6,7 @@ import {MatRadioModule} from '@angular/material/radio';
  * should be tree-shaken away properly.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-radio-button value="hello"></mat-radio-button>
   `,
diff --git a/integration/size-test/material/select/basic.ts b/integration/size-test/material/select/basic.ts
index 405cb0486479..69b5947d38fa 100644
--- a/integration/size-test/material/select/basic.ts
+++ b/integration/size-test/material/select/basic.ts
@@ -7,6 +7,7 @@ import {MatSelectModule} from '@angular/material/select';
  * tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-select>
       <mat-option value="First">First</mat-option>
diff --git a/integration/size-test/material/tabs/advanced.ts b/integration/size-test/material/tabs/advanced.ts
index deedf72e1f10..9f953bd0078e 100644
--- a/integration/size-test/material/tabs/advanced.ts
+++ b/integration/size-test/material/tabs/advanced.ts
@@ -6,6 +6,7 @@ import {MatTabsModule} from '@angular/material/tabs';
  * lazy `MatTabContent` and `MatTabLabel`.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-tab-group>
       <mat-tab>
diff --git a/integration/size-test/material/tabs/basic.ts b/integration/size-test/material/tabs/basic.ts
index 32ab52724394..92ccd61b72e5 100644
--- a/integration/size-test/material/tabs/basic.ts
+++ b/integration/size-test/material/tabs/basic.ts
@@ -7,6 +7,7 @@ import {MatTabsModule} from '@angular/material/tabs';
  * be tree-shaken away.
  */
 @Component({
+  standalone: false,
   template: `
     <mat-tab-group>
       <mat-tab label="Hello">Content</mat-tab>
diff --git a/package.json b/package.json
index 7b73d9d44acd..83593aa3a974 100644
--- a/package.json
+++ b/package.json
@@ -54,35 +54,35 @@
     "ci-notify-slack-failure": "node --no-warnings=ExperimentalWarning --loader ts-node/esm/transpile-only scripts/circleci/notify-slack-job-failure.mts",
     "prepare": "husky"
   },
-  "version": "19.0.0-next.9",
+  "version": "19.0.5",
   "dependencies": {
-    "@angular/animations": "^19.0.0-next.10",
-    "@angular/common": "^19.0.0-next.10",
-    "@angular/compiler": "^19.0.0-next.10",
-    "@angular/core": "^19.0.0-next.10",
-    "@angular/forms": "^19.0.0-next.10",
-    "@angular/platform-browser": "^19.0.0-next.10",
+    "@angular/animations": "^19.0.0",
+    "@angular/common": "^19.0.0",
+    "@angular/compiler": "^19.0.0",
+    "@angular/core": "^19.0.0",
+    "@angular/forms": "^19.0.0",
+    "@angular/platform-browser": "^19.0.0",
     "@types/google.maps": "^3.54.10",
-    "@types/youtube": "^0.0.50",
+    "@types/youtube": "^0.1.0",
     "rxjs": "^6.6.7",
     "rxjs-tslint-rules": "^4.34.8",
     "tslib": "^2.3.1",
     "zone.js": "~0.15.0"
   },
   "devDependencies": {
-    "@angular-devkit/build-angular": "^19.0.0-next.10",
-    "@angular-devkit/core": "^19.0.0-next.10",
-    "@angular-devkit/schematics": "^19.0.0-next.10",
-    "@angular/bazel": "https://github.com/angular/bazel-builds.git#9e6140d1eef8ddf7113d00738f603e9cc3c310f1",
+    "@angular-devkit/build-angular": "^19.0.0",
+    "@angular-devkit/core": "^19.0.0",
+    "@angular-devkit/schematics": "^19.0.0",
+    "@angular/bazel": "https://github.com/angular/bazel-builds.git#d9a8ea4f9e62cb475eff89519426a38631b2704d",
     "@angular/build-tooling": "https://github.com/angular/dev-infra-private-build-tooling-builds.git#74e0e7b090c6e16056290836b2d936ca7820b86f",
-    "@angular/build": "^19.0.0-next.10",
-    "@angular/cli": "^19.0.0-next.10",
-    "@angular/compiler-cli": "^19.0.0-next.10",
-    "@angular/localize": "^19.0.0-next.10",
+    "@angular/build": "^19.0.0",
+    "@angular/cli": "^19.0.0",
+    "@angular/compiler-cli": "^19.0.0",
+    "@angular/localize": "^19.0.0",
     "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#36946be4df61f6549ae3829c026022e47674eae2",
-    "@angular/platform-browser-dynamic": "^19.0.0-next.10",
-    "@angular/platform-server": "^19.0.0-next.10",
-    "@angular/router": "^19.0.0-next.10",
+    "@angular/platform-browser-dynamic": "^19.0.0",
+    "@angular/platform-server": "^19.0.0",
+    "@angular/router": "^19.0.0",
     "@babel/core": "^7.16.12",
     "@babel/helper-explode-assignable-expression": "^7.18.6",
     "@babel/helper-string-parser": "^7.22.5",
@@ -102,7 +102,7 @@
     "@octokit/rest": "18.3.5",
     "@rollup/plugin-commonjs": "^21.0.0",
     "@rollup/plugin-node-resolve": "^13.1.3",
-    "@schematics/angular": "^19.0.0-next.10",
+    "@schematics/angular": "^19.0.0",
     "@types/babel__core": "^7.1.18",
     "@types/browser-sync": "^2.26.3",
     "@types/fs-extra": "^9.0.13",
@@ -160,7 +160,7 @@
     "requirejs": "^2.3.6",
     "rollup": "^2.66.1",
     "rollup-plugin-sourcemaps": "^0.6.3",
-    "sass": "^1.77.8",
+    "sass": "^1.80.6",
     "selenium-webdriver": "^3.6.0",
     "semver": "^7.3.5",
     "send": "^0.17.2",
diff --git a/renovate.json b/renovate.json
index e2d8389c4fe0..0dd970b703c8 100644
--- a/renovate.json
+++ b/renovate.json
@@ -20,24 +20,28 @@
   "ignorePaths": ["integration/**"],
   "packageRules": [
     {
-      "matchPackagePatterns": ["*"],
-      "enabled": false
+      "enabled": false,
+      "matchPackageNames": ["*"]
     },
     {
-      "matchPackageNames": ["@angular/ng-dev", "@angular/build-tooling", "angular/dev-infra"],
+      "matchPackageNames": [
+        "@angular/ng-dev",
+        "@angular/build-tooling",
+        "angular/dev-infra"
+      ],
       "groupName": "angular shared dev-infra code",
       "enabled": true
     },
     {
-      "matchPackagePatterns": ["^@bazel/.*", "^build_bazel.*"],
       "groupName": "bazel setup",
-      "enabled": true
+      "enabled": true,
+      "matchPackageNames": ["/^@bazel/.*/", "/^build_bazel.*/"]
     },
     {
-      "matchPaths": [".github/workflows/scorecard.yml"],
-      "matchPackagePatterns": ["*"],
+      "matchFileNames": [".github/workflows/scorecard.yml"],
       "groupName": "scorecard action dependencies",
-      "groupSlug": "scorecard-action"
+      "groupSlug": "scorecard-action",
+      "matchPackageNames": ["*"]
     }
   ]
 }
diff --git a/src/bazel-tsconfig-build.json b/src/bazel-tsconfig-build.json
index ea425fb5bc38..f8cae066f05a 100644
--- a/src/bazel-tsconfig-build.json
+++ b/src/bazel-tsconfig-build.json
@@ -21,8 +21,6 @@
     "importHelpers": true,
     "strictBindCallApply": true,
     "esModuleInterop": true,
-    // Keep the below in sync with https://github.com/angular/angular/blob/f9b821f07d8dba57a6a7e5fc127dc096247424aa/packages/bazel/src/ng_module/ng_module.bzl#L214
-    "useDefineForClassFields": false,
     "newLine": "lf",
     // Bazel either uses "umd" or "esnext". We replicate this here for IDE support.
     // https://github.com/bazelbuild/rules_typescript/blob/master/internal/common/tsconfig.bzl#L199
diff --git a/src/cdk-experimental/column-resize/column-resize.ts b/src/cdk-experimental/column-resize/column-resize.ts
index 4b084dcc17a0..0ec6b7a7c3fc 100644
--- a/src/cdk-experimental/column-resize/column-resize.ts
+++ b/src/cdk-experimental/column-resize/column-resize.ts
@@ -6,7 +6,8 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {AfterViewInit, Directive, ElementRef, NgZone, OnDestroy} from '@angular/core';
+import {AfterViewInit, Directive, ElementRef, inject, NgZone, OnDestroy} from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {fromEvent, merge, Subject} from 'rxjs';
 import {filter, map, mapTo, pairwise, startWith, take, takeUntil} from 'rxjs/operators';
 
@@ -19,14 +20,13 @@ import {HeaderRowEventDispatcher} from './event-dispatcher';
 const HOVER_OR_ACTIVE_CLASS = 'cdk-column-resize-hover-or-active';
 const WITH_RESIZED_COLUMN_CLASS = 'cdk-column-resize-with-resized-column';
 
-let nextId = 0;
-
 /**
  * Base class for ColumnResize directives which attach to mat-table elements to
  * provide common events and services for column resizing.
  */
 @Directive()
 export abstract class ColumnResize implements AfterViewInit, OnDestroy {
+  private _idGenerator = inject(_IdGenerator);
   protected readonly destroyed = new Subject<void>();
 
   /* Publicly accessible interface for triggering and being notified of resizes. */
@@ -40,7 +40,7 @@ export abstract class ColumnResize implements AfterViewInit, OnDestroy {
   protected abstract readonly notifier: ColumnResizeNotifierSource;
 
   /** Unique ID for this table instance. */
-  protected readonly selectorId = `${++nextId}`;
+  protected readonly selectorId = this._idGenerator.getId('cdk-column-resize-');
 
   /** The id attribute of the table, if specified. */
   id?: string;
@@ -60,7 +60,7 @@ export abstract class ColumnResize implements AfterViewInit, OnDestroy {
 
   /** Gets the unique CSS class name for this table instance. */
   getUniqueCssClass() {
-    return `cdk-column-resize-${this.selectorId}`;
+    return this.selectorId;
   }
 
   /** Called when a column in the table is resized. Applies a css class to the table element. */
diff --git a/src/cdk-experimental/column-resize/resizable.ts b/src/cdk-experimental/column-resize/resizable.ts
index a71a49e616f7..cfcfd0617694 100644
--- a/src/cdk-experimental/column-resize/resizable.ts
+++ b/src/cdk-experimental/column-resize/resizable.ts
@@ -13,6 +13,7 @@ import {
   Injector,
   NgZone,
   OnDestroy,
+  OnInit,
   Type,
   ViewContainerRef,
   ChangeDetectorRef,
@@ -42,7 +43,7 @@ const OVERLAY_ACTIVE_CLASS = 'cdk-resizable-overlay-thumb-active';
  */
 @Directive()
 export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
-  implements AfterViewInit, OnDestroy
+  implements AfterViewInit, OnDestroy, OnInit
 {
   protected minWidthPxInternal: number = 0;
   protected maxWidthPxInternal: number = Number.MAX_SAFE_INTEGER;
@@ -95,6 +96,10 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
     }
   }
 
+  ngOnInit() {
+    this.resizeStrategy.registerColumn(this.elementRef.nativeElement);
+  }
+
   ngAfterViewInit() {
     this._listenForRowHoverEvents();
     this._listenForResizeEvents();
@@ -282,14 +287,13 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
   }
 
   private _appendInlineHandle(): void {
-    this.styleScheduler.schedule(() => {
-      this.inlineHandle = this.document.createElement('div');
-      this.inlineHandle.tabIndex = 0;
-      this.inlineHandle.className = this.getInlineHandleCssClassName();
+    this.inlineHandle = this.document.createElement('div');
+    // TODO: re-apply tab index once this element has behavior.
+    // this.inlineHandle.tabIndex = 0;
+    this.inlineHandle.className = this.getInlineHandleCssClassName();
 
-      // TODO: Apply correct aria role (probably slider) after a11y spec questions resolved.
+    // TODO: Apply correct aria role (probably slider) after a11y spec questions resolved.
 
-      this.elementRef.nativeElement!.appendChild(this.inlineHandle);
-    });
+    this.elementRef.nativeElement!.appendChild(this.inlineHandle);
   }
 }
diff --git a/src/cdk-experimental/column-resize/resize-strategy.ts b/src/cdk-experimental/column-resize/resize-strategy.ts
index 51fe6ec0f1ff..a37ea5db0b43 100644
--- a/src/cdk-experimental/column-resize/resize-strategy.ts
+++ b/src/cdk-experimental/column-resize/resize-strategy.ts
@@ -18,12 +18,17 @@ import {ColumnResize} from './column-resize';
  * The details of how resizing works for tables for flex mat-tables are quite different.
  */
 @Injectable()
-export abstract class ResizeStrategy {
+export abstract class ResizeStrategy implements OnDestroy {
   protected abstract readonly columnResize: ColumnResize;
   protected abstract readonly styleScheduler: _CoalescedStyleScheduler;
   protected abstract readonly table: CdkTable<unknown>;
 
   private _pendingResizeDelta: number | null = null;
+  private _tableObserved = false;
+  private _elemSizeCache = new WeakMap<HTMLElement, {width: number; height: number}>();
+  private _resizeObserver = globalThis?.ResizeObserver
+    ? new globalThis.ResizeObserver(entries => this._updateCachedSizes(entries))
+    : null;
 
   /** Updates the width of the specified column. */
   abstract applyColumnSize(
@@ -51,7 +56,7 @@ export abstract class ResizeStrategy {
   protected updateTableWidthAndStickyColumns(delta: number): void {
     if (this._pendingResizeDelta === null) {
       const tableElement = this.columnResize.elementRef.nativeElement;
-      const tableWidth = getElementWidth(tableElement);
+      const tableWidth = this.getElementWidth(tableElement);
 
       this.styleScheduler.schedule(() => {
         tableElement.style.width = coerceCssPixelValue(tableWidth + this._pendingResizeDelta!);
@@ -66,6 +71,48 @@ export abstract class ResizeStrategy {
 
     this._pendingResizeDelta = (this._pendingResizeDelta ?? 0) + delta;
   }
+
+  /** Gets the style.width pixels on the specified element if present, otherwise its offsetWidth. */
+  protected getElementWidth(element: HTMLElement) {
+    // Optimization: Check style.width first as we probably set it already before reading
+    // offsetWidth which triggers layout.
+    return (
+      coercePixelsFromCssValue(element.style.width) ||
+      this._elemSizeCache.get(element)?.width ||
+      element.offsetWidth
+    );
+  }
+
+  /** Informs the ResizeStrategy instance of a column that may be resized in the future. */
+  registerColumn(column: HTMLElement) {
+    if (!this._tableObserved) {
+      this._tableObserved = true;
+      this._resizeObserver?.observe(this.columnResize.elementRef.nativeElement, {
+        box: 'border-box',
+      });
+    }
+    this._resizeObserver?.observe(column, {box: 'border-box'});
+  }
+
+  ngOnDestroy(): void {
+    this._resizeObserver?.disconnect();
+  }
+
+  private _updateCachedSizes(entries: ResizeObserverEntry[]) {
+    for (const entry of entries) {
+      const newEntry = entry.borderBoxSize?.length
+        ? {
+            width: entry.borderBoxSize[0].inlineSize,
+            height: entry.borderBoxSize[0].blockSize,
+          }
+        : {
+            width: entry.contentRect.width,
+            height: entry.contentRect.height,
+          };
+
+      this._elemSizeCache.set(entry.target as HTMLElement, newEntry);
+    }
+  }
 }
 
 /**
@@ -87,7 +134,7 @@ export class TableLayoutFixedResizeStrategy extends ResizeStrategy {
     sizeInPx: number,
     previousSizeInPx?: number,
   ): void {
-    const delta = sizeInPx - (previousSizeInPx ?? getElementWidth(columnHeader));
+    const delta = sizeInPx - (previousSizeInPx ?? this.getElementWidth(columnHeader));
 
     if (delta === 0) {
       return;
@@ -101,14 +148,14 @@ export class TableLayoutFixedResizeStrategy extends ResizeStrategy {
   }
 
   applyMinColumnSize(_: string, columnHeader: HTMLElement, sizeInPx: number): void {
-    const currentWidth = getElementWidth(columnHeader);
+    const currentWidth = this.getElementWidth(columnHeader);
     const newWidth = Math.max(currentWidth, sizeInPx);
 
     this.applyColumnSize(_, columnHeader, newWidth, currentWidth);
   }
 
   applyMaxColumnSize(_: string, columnHeader: HTMLElement, sizeInPx: number): void {
-    const currentWidth = getElementWidth(columnHeader);
+    const currentWidth = this.getElementWidth(columnHeader);
     const newWidth = Math.min(currentWidth, sizeInPx);
 
     this.applyColumnSize(_, columnHeader, newWidth, currentWidth);
@@ -189,7 +236,8 @@ export class CdkFlexTableResizeStrategy extends ResizeStrategy implements OnDest
     return `cdk-column-${cssFriendlyColumnName}`;
   }
 
-  ngOnDestroy(): void {
+  override ngOnDestroy(): void {
+    super.ngOnDestroy();
     this._styleElement?.remove();
     this._styleElement = undefined;
   }
@@ -277,13 +325,6 @@ function coercePixelsFromCssValue(cssValue: string): number {
   return Number(cssValue.match(/(\d+)px/)?.[1]);
 }
 
-/** Gets the style.width pixels on the specified element if present, otherwise its offsetWidth. */
-function getElementWidth(element: HTMLElement) {
-  // Optimization: Check style.width first as we probably set it already before reading
-  // offsetWidth which triggers layout.
-  return coercePixelsFromCssValue(element.style.width) || element.offsetWidth;
-}
-
 /**
  * Converts CSS flex values as set in CdkFlexTableResizeStrategy to numbers,
  * eg "0 0.01 123px" to 123.
diff --git a/src/cdk-experimental/combobox/combobox-popup.ts b/src/cdk-experimental/combobox/combobox-popup.ts
index c452e713d8ee..0f5912611c43 100644
--- a/src/cdk-experimental/combobox/combobox-popup.ts
+++ b/src/cdk-experimental/combobox/combobox-popup.ts
@@ -7,10 +7,9 @@
  */
 
 import {Directive, ElementRef, Input, OnInit, inject} from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {AriaHasPopupValue, CDK_COMBOBOX, CdkCombobox} from './combobox';
 
-let nextId = 0;
-
 @Directive({
   selector: '[cdkComboboxPopup]',
   exportAs: 'cdkComboboxPopup',
@@ -44,7 +43,7 @@ export class CdkComboboxPopup<T = unknown> implements OnInit {
   }
   private _firstFocusElement: HTMLElement;
 
-  @Input() id = `cdk-combobox-popup-${nextId++}`;
+  @Input() id: string = inject(_IdGenerator).getId('cdk-combobox-popup-');
 
   ngOnInit() {
     this.registerWithPanel();
diff --git a/src/cdk-experimental/combobox/combobox.spec.ts b/src/cdk-experimental/combobox/combobox.spec.ts
index 456f1a53aba7..88656cbb2bf8 100644
--- a/src/cdk-experimental/combobox/combobox.spec.ts
+++ b/src/cdk-experimental/combobox/combobox.spec.ts
@@ -385,7 +385,6 @@ describe('Combobox', () => {
       <button id="applyButton" (click)="toggleCombobox.updateAndClose(input.value)">Apply</button>
     </div>
   </ng-template>`,
-  standalone: true,
   imports: [CdkComboboxModule],
 })
 class ComboboxToggle {
diff --git a/src/cdk-experimental/popover-edit/popover-edit.spec.ts b/src/cdk-experimental/popover-edit/popover-edit.spec.ts
index 03ee73cd6fa0..6ad6476cdde2 100644
--- a/src/cdk-experimental/popover-edit/popover-edit.spec.ts
+++ b/src/cdk-experimental/popover-edit/popover-edit.spec.ts
@@ -403,6 +403,7 @@ describe('CDK Popover Edit', () => {
         });
         fixture = TestBed.createComponent<BaseTestComponent>(componentClass);
         component = fixture.componentInstance;
+        component.renderData();
         fixture.detectChanges();
         tick(10);
         fixture.detectChanges();
diff --git a/src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts b/src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts
index c233eabfc777..e0aa8068ac75 100644
--- a/src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts
+++ b/src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts
@@ -95,7 +95,6 @@ function finishInit(fixture: ComponentFixture<any>) {
     }
   `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule, ExperimentalScrollingModule],
 })
 class AutoSizeVirtualScroll {
diff --git a/src/cdk-experimental/selection/selection-module.ts b/src/cdk-experimental/selection/selection-module.ts
index 3a3a3a9ca286..40dcdece7ebb 100644
--- a/src/cdk-experimental/selection/selection-module.ts
+++ b/src/cdk-experimental/selection/selection-module.ts
@@ -7,7 +7,6 @@
  */
 
 import {CdkTableModule} from '@angular/cdk/table';
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 
 import {CdkRowSelection} from './row-selection';
@@ -18,7 +17,6 @@ import {CdkSelectionToggle} from './selection-toggle';
 
 @NgModule({
   imports: [
-    CommonModule,
     CdkTableModule,
     CdkSelection,
     CdkSelectionToggle,
diff --git a/src/cdk-experimental/selection/selection.spec.ts b/src/cdk-experimental/selection/selection.spec.ts
index 1661251b78be..179688d1615e 100644
--- a/src/cdk-experimental/selection/selection.spec.ts
+++ b/src/cdk-experimental/selection/selection.spec.ts
@@ -452,7 +452,6 @@ describe('cdkSelectionColumn with multiple = false', () => {
         </li>
       }
     </ul>`,
-  standalone: true,
   imports: [CdkSelectionModule, AsyncPipe],
 })
 class ListWithMultiSelection {
@@ -517,7 +516,6 @@ class ListWithMultiSelection {
         </li>
       }
     </ul>`,
-  standalone: true,
   imports: [CdkSelectionModule, AsyncPipe],
 })
 class ListWithSingleSelection {
@@ -559,7 +557,6 @@ class ListWithSingleSelection {
           cdkRowSelection [cdkRowSelectionValue]="row"></tr>
     </table>
     `,
-  standalone: true,
   imports: [CdkSelectionModule, CdkTableModule],
 })
 class MultiSelectTableWithSelectionColumn {
@@ -627,7 +624,6 @@ class MultiSelectTableWithSelectionColumn {
           cdkRowSelection [cdkRowSelectionValue]="row"></tr>
     </table>
     `,
-  standalone: true,
   imports: [CdkSelectionModule, CdkTableModule],
 })
 class SingleSelectTableWithSelectionColumn {
diff --git a/src/cdk-experimental/table-scroll-container/BUILD.bazel b/src/cdk-experimental/table-scroll-container/BUILD.bazel
index 9db3cec310c4..e624e99e819f 100644
--- a/src/cdk-experimental/table-scroll-container/BUILD.bazel
+++ b/src/cdk-experimental/table-scroll-container/BUILD.bazel
@@ -14,6 +14,7 @@ ng_module(
         exclude = ["**/*.spec.ts"],
     ),
     deps = [
+        "//src/cdk/a11y",
         "//src/cdk/bidi",
         "//src/cdk/platform",
         "//src/cdk/table",
diff --git a/src/cdk-experimental/table-scroll-container/table-scroll-container.spec.ts b/src/cdk-experimental/table-scroll-container/table-scroll-container.spec.ts
index 009e971b6b20..cf83cb16bd5e 100644
--- a/src/cdk-experimental/table-scroll-container/table-scroll-container.spec.ts
+++ b/src/cdk-experimental/table-scroll-container/table-scroll-container.spec.ts
@@ -293,7 +293,6 @@ class FakeDataSource extends DataSource<TestData> {
     </table>
     </div>
   `,
-  standalone: true,
   imports: [CdkTableModule, CdkTableScrollContainerModule],
   styles: `
     .cdk-header-cell, .cdk-cell, .cdk-footer-cell {
diff --git a/src/cdk-experimental/table-scroll-container/table-scroll-container.ts b/src/cdk-experimental/table-scroll-container/table-scroll-container.ts
index 0b88717878bc..2182bc795ebc 100644
--- a/src/cdk-experimental/table-scroll-container/table-scroll-container.ts
+++ b/src/cdk-experimental/table-scroll-container/table-scroll-container.ts
@@ -7,6 +7,7 @@
  */
 
 import {CSP_NONCE, Directive, ElementRef, OnDestroy, OnInit, inject} from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {DOCUMENT} from '@angular/common';
 import {Directionality} from '@angular/cdk/bidi';
 import {_getShadowRoot} from '@angular/cdk/platform';
@@ -17,8 +18,6 @@ import {
   StickyUpdate,
 } from '@angular/cdk/table';
 
-let nextId = 0;
-
 /**
  * Applies styles to the host element that make its scrollbars match up with
  * the non-sticky scrollable portions of the CdkTable contained within.
@@ -43,7 +42,7 @@ export class CdkTableScrollContainer implements StickyPositioningListener, OnDes
   private readonly _directionality = inject(Directionality, {optional: true});
   private readonly _nonce = inject(CSP_NONCE, {optional: true});
 
-  private readonly _uniqueClassName = `cdk-table-scroll-container-${++nextId}`;
+  private readonly _uniqueClassName = inject(_IdGenerator).getId('cdk-table-scroll-container-');
   private _styleRoot!: Node;
   private _styleElement?: HTMLStyleElement;
 
diff --git a/src/cdk/a11y/aria-describer/aria-describer.spec.ts b/src/cdk/a11y/aria-describer/aria-describer.spec.ts
index ebb74d1ff8dc..eea223a7f2a6 100644
--- a/src/cdk/a11y/aria-describer/aria-describer.spec.ts
+++ b/src/cdk/a11y/aria-describer/aria-describer.spec.ts
@@ -400,7 +400,6 @@ function expectMessage(el: Element, message: string) {
     <div id="description-with-existing-id">Hello</div>
     <div description-without-id>Hey</div>
   `,
-  standalone: true,
   imports: [A11yModule],
 })
 class TestApp {
diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts
index 3f9f04265f91..1bed0e280003 100644
--- a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts
+++ b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts
@@ -901,14 +901,12 @@ describe('FocusMonitor input label detection', () => {
 
 @Component({
   template: `<div class="parent"><button>focus me!</button></div>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class PlainButton {}
 
 @Component({
   template: `<button cdkMonitorElementFocus (cdkFocusChange)="focusChanged($event)"></button>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class ButtonWithFocusClasses {
@@ -917,28 +915,24 @@ class ButtonWithFocusClasses {
 
 @Component({
   template: `<div tabindex="0" cdkMonitorElementFocus><button></button></div>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class ComplexComponentWithMonitorElementFocus {}
 
 @Component({
   template: `<div tabindex="0" cdkMonitorSubtreeFocus><button></button></div>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class ComplexComponentWithMonitorSubtreeFocus {}
 
 @Component({
   template: `<div cdkMonitorSubtreeFocus><button cdkMonitorElementFocus></button></div>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class ComplexComponentWithMonitorSubtreeFocusAndMonitorElementFocus {}
 
 @Component({
   template: `<ng-container cdkMonitorElementFocus></ng-container>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class FocusMonitorOnCommentNode {}
@@ -948,14 +942,12 @@ class FocusMonitorOnCommentNode {}
     <label for="test-checkbox">Check me</label>
     <input id="test-checkbox" type="checkbox">
   `,
-  standalone: true,
   imports: [A11yModule],
 })
 class CheckboxWithLabel {}
 
 @Component({
   template: `<button cdkMonitorElementFocus #exportedDir="cdkMonitorFocus"></button>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class ExportedFocusMonitor {
diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.ts b/src/cdk/a11y/focus-monitor/focus-monitor.ts
index 51a21cf68d6b..ef34ed52694b 100644
--- a/src/cdk/a11y/focus-monitor/focus-monitor.ts
+++ b/src/cdk/a11y/focus-monitor/focus-monitor.ts
@@ -98,10 +98,10 @@ export class FocusMonitor implements OnDestroy {
   private _windowFocused = false;
 
   /** The timeout id of the window focus timeout. */
-  private _windowFocusTimeoutId: number;
+  private _windowFocusTimeoutId: ReturnType<typeof setTimeout>;
 
   /** The timeout id of the origin clearing timeout. */
-  private _originTimeoutId: number;
+  private _originTimeoutId: ReturnType<typeof setTimeout>;
 
   /**
    * Whether the origin was determined via a touch interaction. Necessary as properly attributing
@@ -137,7 +137,7 @@ export class FocusMonitor implements OnDestroy {
     // Make a note of when the window regains focus, so we can
     // restore the origin info for the focused element.
     this._windowFocused = true;
-    this._windowFocusTimeoutId = window.setTimeout(() => (this._windowFocused = false));
+    this._windowFocusTimeoutId = setTimeout(() => (this._windowFocused = false));
   };
 
   /** Used to reference correct document/window */
diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.zone.spec.ts b/src/cdk/a11y/focus-monitor/focus-monitor.zone.spec.ts
index b8297208c6b0..33c1e386b953 100644
--- a/src/cdk/a11y/focus-monitor/focus-monitor.zone.spec.ts
+++ b/src/cdk/a11y/focus-monitor/focus-monitor.zone.spec.ts
@@ -41,7 +41,6 @@ describe('FocusMonitor observable stream Zone.js integration', () => {
 
 @Component({
   template: `<div class="parent"><button>focus me!</button></div>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class PlainButton {}
diff --git a/src/cdk/a11y/focus-trap/configurable-focus-trap.spec.ts b/src/cdk/a11y/focus-trap/configurable-focus-trap.spec.ts
index dfecc2cc111e..b19ad2c90ad6 100644
--- a/src/cdk/a11y/focus-trap/configurable-focus-trap.spec.ts
+++ b/src/cdk/a11y/focus-trap/configurable-focus-trap.spec.ts
@@ -115,7 +115,6 @@ function createComponent<T>(
       <button>SAVE</button>
     </div>
   `,
-  standalone: true,
 })
 class SimpleFocusTrap implements AfterViewInit {
   private _focusTrapFactory = inject(ConfigurableFocusTrapFactory);
diff --git a/src/cdk/a11y/focus-trap/event-listener-inert-strategy.spec.ts b/src/cdk/a11y/focus-trap/event-listener-inert-strategy.spec.ts
index f31bb3a1995f..709877c1219c 100644
--- a/src/cdk/a11y/focus-trap/event-listener-inert-strategy.spec.ts
+++ b/src/cdk/a11y/focus-trap/event-listener-inert-strategy.spec.ts
@@ -85,7 +85,6 @@ function createComponent<T>(
       <button #secondFocusable>SAVE</button>
     </div>
   `,
-  standalone: true,
 })
 class SimpleFocusTrap implements AfterViewInit {
   private _focusTrapFactory = inject(ConfigurableFocusTrapFactory);
diff --git a/src/cdk/a11y/focus-trap/focus-trap.spec.ts b/src/cdk/a11y/focus-trap/focus-trap.spec.ts
index 4ae11ebd29ca..ec480249c73a 100644
--- a/src/cdk/a11y/focus-trap/focus-trap.spec.ts
+++ b/src/cdk/a11y/focus-trap/focus-trap.spec.ts
@@ -352,7 +352,6 @@ function getActiveElement() {
       <button>SAVE</button>
     </div>
     `,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class SimpleFocusTrap {
@@ -371,7 +370,6 @@ const AUTO_FOCUS_TEMPLATE = `
 
 @Component({
   template: AUTO_FOCUS_TEMPLATE,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class FocusTrapWithAutoCapture {
@@ -383,7 +381,6 @@ class FocusTrapWithAutoCapture {
 @Component({
   template: AUTO_FOCUS_TEMPLATE,
   encapsulation: ViewEncapsulation.ShadowDom,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class FocusTrapWithAutoCaptureInShadowDom extends FocusTrapWithAutoCapture {}
@@ -397,7 +394,6 @@ class FocusTrapWithAutoCaptureInShadowDom extends FocusTrapWithAutoCapture {}
       </div>
     }
   `,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class FocusTrapWithBindings {
@@ -418,7 +414,6 @@ class FocusTrapWithBindings {
       <input>
     </div>
     `,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class FocusTrapTargets {
@@ -431,7 +426,6 @@ class FocusTrapTargets {
       <div cdkFocusInitial></div>
     </div>
     `,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class FocusTrapUnfocusableTarget {
@@ -446,7 +440,6 @@ class FocusTrapUnfocusableTarget {
       </svg>
     </div>
     `,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class FocusTrapWithSvg {
@@ -459,7 +452,6 @@ class FocusTrapWithSvg {
       <p>Hello</p>
     </div>
     `,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class FocusTrapWithoutFocusableElements {
@@ -478,7 +470,6 @@ class FocusTrapWithoutFocusableElements {
     </div>
   </ng-template>
   `,
-  standalone: true,
   imports: [A11yModule, PortalModule],
 })
 class FocusTrapInsidePortal {
diff --git a/src/cdk/a11y/id-generator.ts b/src/cdk/a11y/id-generator.ts
new file mode 100644
index 000000000000..55bae7a0a551
--- /dev/null
+++ b/src/cdk/a11y/id-generator.ts
@@ -0,0 +1,40 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.dev/license
+ */
+
+import {APP_ID, inject, Injectable} from '@angular/core';
+
+/**
+ * Keeps track of the ID count per prefix. This helps us make the IDs a bit more deterministic
+ * like they were before the service was introduced. Note that ideally we wouldn't have to do
+ * this, but there are some internal tests that rely on the IDs.
+ */
+const counters: Record<string, number> = {};
+
+/** Service that generates unique IDs for DOM nodes. */
+@Injectable({providedIn: 'root'})
+export class _IdGenerator {
+  private _appId = inject(APP_ID);
+
+  /**
+   * Generates a unique ID with a specific prefix.
+   * @param prefix Prefix to add to the ID.
+   */
+  getId(prefix: string): string {
+    // Omit the app ID if it's the default `ng`. Since the vast majority of pages have one
+    // Angular app on them, we can reduce the amount of breakages by not adding it.
+    if (this._appId !== 'ng') {
+      prefix += this._appId;
+    }
+
+    if (!counters.hasOwnProperty(prefix)) {
+      counters[prefix] = 0;
+    }
+
+    return `${prefix}${counters[prefix]++}`;
+  }
+}
diff --git a/src/cdk/a11y/key-manager/list-key-manager.spec.ts b/src/cdk/a11y/key-manager/list-key-manager.spec.ts
index cb37338a1117..ab4ca61e7087 100644
--- a/src/cdk/a11y/key-manager/list-key-manager.spec.ts
+++ b/src/cdk/a11y/key-manager/list-key-manager.spec.ts
@@ -109,7 +109,7 @@ describe('Key managers', () => {
     it('should maintain the active item when the signal-based items change', () => {
       keyManager.destroy();
 
-      @Component({template: '', standalone: true})
+      @Component({template: ''})
       class App {}
 
       const fixture = TestBed.createComponent(App);
diff --git a/src/cdk/a11y/key-manager/list-key-manager.ts b/src/cdk/a11y/key-manager/list-key-manager.ts
index 63fbc268c0e9..ef40642b7f25 100644
--- a/src/cdk/a11y/key-manager/list-key-manager.ts
+++ b/src/cdk/a11y/key-manager/list-key-manager.ts
@@ -6,20 +6,20 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {EffectRef, Injector, QueryList, Signal, effect, isSignal} from '@angular/core';
-import {Subject, Subscription} from 'rxjs';
 import {
-  UP_ARROW,
   DOWN_ARROW,
+  END,
+  HOME,
   LEFT_ARROW,
+  PAGE_DOWN,
+  PAGE_UP,
   RIGHT_ARROW,
   TAB,
+  UP_ARROW,
   hasModifierKey,
-  HOME,
-  END,
-  PAGE_UP,
-  PAGE_DOWN,
 } from '@angular/cdk/keycodes';
+import {EffectRef, Injector, QueryList, Signal, effect, isSignal, signal} from '@angular/core';
+import {Subject, Subscription} from 'rxjs';
 import {Typeahead} from './typeahead';
 
 /** This interface is for items that can be passed to a ListKeyManager. */
@@ -40,7 +40,7 @@ export type ListKeyManagerModifierKey = 'altKey' | 'ctrlKey' | 'metaKey' | 'shif
  */
 export class ListKeyManager<T extends ListKeyManagerOption> {
   private _activeItemIndex = -1;
-  private _activeItem: T | null = null;
+  private _activeItem = signal<T | null>(null);
   private _wrap = false;
   private _typeaheadSubscription = Subscription.EMPTY;
   private _itemChangesSubscription?: Subscription;
@@ -204,11 +204,11 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
   setActiveItem(item: T): void;
 
   setActiveItem(item: any): void {
-    const previousActiveItem = this._activeItem;
+    const previousActiveItem = this._activeItem();
 
     this.updateActiveItem(item);
 
-    if (this._activeItem !== previousActiveItem) {
+    if (this._activeItem() !== previousActiveItem) {
       this.change.next(this._activeItemIndex);
     }
   }
@@ -317,7 +317,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
 
   /** The active item. */
   get activeItem(): T | null {
-    return this._activeItem;
+    return this._activeItem();
   }
 
   /** Gets whether the user is currently typing into the manager using the typeahead feature. */
@@ -365,7 +365,7 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
     const activeItem = itemArray[index];
 
     // Explicitly check for `null` and `undefined` because other falsy values are valid.
-    this._activeItem = activeItem == null ? null : activeItem;
+    this._activeItem.set(activeItem == null ? null : activeItem);
     this._activeItemIndex = index;
     this._typeahead?.setCurrentSelectedItemIndex(index);
   }
@@ -452,8 +452,9 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
   /** Callback for when the items have changed. */
   private _itemsChanged(newItems: T[] | readonly T[]) {
     this._typeahead?.setItems(newItems);
-    if (this._activeItem) {
-      const newIndex = newItems.indexOf(this._activeItem);
+    const activeItem = this._activeItem();
+    if (activeItem) {
+      const newIndex = newItems.indexOf(activeItem);
 
       if (newIndex > -1 && newIndex !== this._activeItemIndex) {
         this._activeItemIndex = newIndex;
diff --git a/src/cdk/a11y/live-announcer/live-announcer.spec.ts b/src/cdk/a11y/live-announcer/live-announcer.spec.ts
index 13ad187f006e..2dbf2000fa4f 100644
--- a/src/cdk/a11y/live-announcer/live-announcer.spec.ts
+++ b/src/cdk/a11y/live-announcer/live-announcer.spec.ts
@@ -392,7 +392,6 @@ function getLiveElement(): Element {
 
 @Component({
   template: `<button (click)="announceText('Test')">Announce</button>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class TestApp {
@@ -406,7 +405,6 @@ class TestApp {
 @Component({
   template: '',
   host: {'[attr.aria-owns]': 'ariaOwns', 'aria-modal': 'true'},
-  standalone: true,
   imports: [A11yModule],
 })
 class TestModal {
@@ -418,7 +416,6 @@ class TestModal {
     <div
       [cdkAriaLive]="politeness ? politeness : null"
       [cdkAriaLiveDuration]="duration">{{content}}</div>`,
-  standalone: true,
   imports: [A11yModule],
 })
 class DivWithCdkAriaLive {
diff --git a/src/cdk/a11y/live-announcer/live-announcer.ts b/src/cdk/a11y/live-announcer/live-announcer.ts
index ed16913ffd96..91cd457f6812 100644
--- a/src/cdk/a11y/live-announcer/live-announcer.ts
+++ b/src/cdk/a11y/live-announcer/live-announcer.ts
@@ -29,7 +29,7 @@ export class LiveAnnouncer implements OnDestroy {
 
   private _liveElement: HTMLElement;
   private _document = inject(DOCUMENT);
-  private _previousTimeout: number;
+  private _previousTimeout: ReturnType<typeof setTimeout>;
   private _currentPromise: Promise<void> | undefined;
   private _currentResolve: (() => void) | undefined;
 
diff --git a/src/cdk/a11y/public-api.ts b/src/cdk/a11y/public-api.ts
index ead2d81e9b63..df192ec2c339 100644
--- a/src/cdk/a11y/public-api.ts
+++ b/src/cdk/a11y/public-api.ts
@@ -36,3 +36,4 @@ export {
   HighContrastModeDetector,
   HighContrastMode,
 } from './high-contrast-mode/high-contrast-mode-detector';
+export {_IdGenerator} from './id-generator';
diff --git a/src/cdk/accordion/BUILD.bazel b/src/cdk/accordion/BUILD.bazel
index 919a0b06faab..7b1065d33951 100644
--- a/src/cdk/accordion/BUILD.bazel
+++ b/src/cdk/accordion/BUILD.bazel
@@ -15,6 +15,7 @@ ng_module(
         exclude = ["**/*.spec.ts"],
     ),
     deps = [
+        "//src/cdk/a11y",
         "//src/cdk/collections",
         "@npm//@angular/core",
         "@npm//rxjs",
diff --git a/src/cdk/accordion/accordion-item.spec.ts b/src/cdk/accordion/accordion-item.spec.ts
index 253311a687ad..cbf5c7bfbc4d 100644
--- a/src/cdk/accordion/accordion-item.spec.ts
+++ b/src/cdk/accordion/accordion-item.spec.ts
@@ -238,7 +238,6 @@ describe('CdkAccordionItem', () => {
 
 @Component({
   template: `<cdk-accordion-item #item1></cdk-accordion-item>`,
-  standalone: true,
   imports: [CdkAccordionModule],
 })
 class SingleItem {}
@@ -248,7 +247,6 @@ class SingleItem {}
     <cdk-accordion-item #item1></cdk-accordion-item>
     <cdk-accordion-item #item2></cdk-accordion-item>
   `,
-  standalone: true,
   imports: [CdkAccordionModule],
 })
 class ItemGroupWithoutAccordion {}
@@ -260,7 +258,6 @@ class ItemGroupWithoutAccordion {}
       <cdk-accordion-item #item2></cdk-accordion-item>
     </cdk-accordion>
   `,
-  standalone: true,
   imports: [CdkAccordionModule],
 })
 class ItemGroupWithAccordion {}
diff --git a/src/cdk/accordion/accordion-item.ts b/src/cdk/accordion/accordion-item.ts
index 1bf8f117601f..9c1a856b24c0 100644
--- a/src/cdk/accordion/accordion-item.ts
+++ b/src/cdk/accordion/accordion-item.ts
@@ -17,13 +17,11 @@ import {
   inject,
   OnInit,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
 import {CDK_ACCORDION, CdkAccordion} from './accordion';
 import {Subscription} from 'rxjs';
 
-/** Used to generate unique ID for each accordion item. */
-let nextId = 0;
-
 /**
  * A basic directive expected to be extended and decorated as a component.  Sets up all
  * events and attributes needed to be managed by a CdkAccordion parent.
@@ -59,7 +57,7 @@ export class CdkAccordionItem implements OnInit, OnDestroy {
   @Output() readonly expandedChange: EventEmitter<boolean> = new EventEmitter<boolean>();
 
   /** The unique AccordionItem id. */
-  readonly id: string = `cdk-accordion-child-${nextId++}`;
+  readonly id: string = inject(_IdGenerator).getId('cdk-accordion-child-');
 
   /** Whether the AccordionItem is expanded. */
   @Input({transform: booleanAttribute})
diff --git a/src/cdk/accordion/accordion.spec.ts b/src/cdk/accordion/accordion.spec.ts
index 3a263d9f47cb..f0e137a50b7f 100644
--- a/src/cdk/accordion/accordion.spec.ts
+++ b/src/cdk/accordion/accordion.spec.ts
@@ -115,7 +115,6 @@ describe('CdkAccordion', () => {
     <cdk-accordion-item></cdk-accordion-item>
     <cdk-accordion-item></cdk-accordion-item>
   </cdk-accordion>`,
-  standalone: true,
   imports: [CdkAccordionModule],
 })
 class SetOfItems {
@@ -131,7 +130,6 @@ class SetOfItems {
       <cdk-accordion-item #innerItem="cdkAccordionItem"></cdk-accordion-item>
     </cdk-accordion-item>
   </cdk-accordion>`,
-  standalone: true,
   imports: [CdkAccordionModule],
 })
 class NestedItems {
diff --git a/src/cdk/accordion/accordion.ts b/src/cdk/accordion/accordion.ts
index 890634dec198..b110380f67c8 100644
--- a/src/cdk/accordion/accordion.ts
+++ b/src/cdk/accordion/accordion.ts
@@ -14,12 +14,11 @@ import {
   OnDestroy,
   SimpleChanges,
   booleanAttribute,
+  inject,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {Subject} from 'rxjs';
 
-/** Used to generate unique ID for each accordion. */
-let nextId = 0;
-
 /**
  * Injection token that can be used to reference instances of `CdkAccordion`. It serves
  * as alternative token to the actual `CdkAccordion` class which could cause unnecessary
@@ -43,7 +42,7 @@ export class CdkAccordion implements OnDestroy, OnChanges {
   readonly _openCloseAllActions: Subject<boolean> = new Subject<boolean>();
 
   /** A readonly id value to use for unique selection coordination. */
-  readonly id: string = `cdk-accordion-${nextId++}`;
+  readonly id: string = inject(_IdGenerator).getId('cdk-accordion-');
 
   /** Whether the accordion should allow multiple expanded accordion items simultaneously. */
   @Input({transform: booleanAttribute}) multi: boolean = false;
diff --git a/src/cdk/bidi/directionality.spec.ts b/src/cdk/bidi/directionality.spec.ts
index 72166e369169..a4b3f03b6af5 100644
--- a/src/cdk/bidi/directionality.spec.ts
+++ b/src/cdk/bidi/directionality.spec.ts
@@ -162,7 +162,6 @@ describe('Directionality', () => {
 @Component({
   selector: 'injects-directionality',
   template: `<div></div>`,
-  standalone: true,
   imports: [BidiModule],
 })
 class InjectsDirectionality {
@@ -175,7 +174,6 @@ class InjectsDirectionality {
       <injects-directionality></injects-directionality>
     </div>
   `,
-  standalone: true,
   imports: [Dir, InjectsDirectionality],
 })
 class ElementWithDir {
@@ -186,7 +184,6 @@ class ElementWithDir {
 
 @Component({
   template: '<div dir="auto"></div>',
-  standalone: true,
   imports: [Dir],
 })
 class ElementWithPredefinedAutoDir {
@@ -195,7 +192,6 @@ class ElementWithPredefinedAutoDir {
 
 @Component({
   template: '<div dir="RTL"></div>',
-  standalone: true,
   imports: [Dir],
 })
 class ElementWithPredefinedUppercaseDir {
diff --git a/src/cdk/clipboard/copy-to-clipboard.spec.ts b/src/cdk/clipboard/copy-to-clipboard.spec.ts
index 073b4df1bded..215f832838e7 100644
--- a/src/cdk/clipboard/copy-to-clipboard.spec.ts
+++ b/src/cdk/clipboard/copy-to-clipboard.spec.ts
@@ -14,7 +14,6 @@ const COPY_CONTENT = 'copy content';
     [cdkCopyToClipboard]="content"
     [cdkCopyToClipboardAttempts]="attempts"
     (cdkCopyToClipboardCopied)="copied($event)"></button>`,
-  standalone: true,
   imports: [ClipboardModule],
 })
 class CopyToClipboardHost {
diff --git a/src/cdk/dialog/dialog-container.ts b/src/cdk/dialog/dialog-container.ts
index a75c4a8fc6f2..7f426063e700 100644
--- a/src/cdk/dialog/dialog-container.ts
+++ b/src/cdk/dialog/dialog-container.ts
@@ -33,6 +33,7 @@ import {
   Injector,
   NgZone,
   OnDestroy,
+  Renderer2,
   ViewChild,
   ViewEncapsulation,
   afterNextRender,
@@ -79,6 +80,7 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
   protected _ngZone = inject(NgZone);
   private _overlayRef = inject(OverlayRef);
   private _focusMonitor = inject(FocusMonitor);
+  private _renderer = inject(Renderer2);
 
   private _platform = inject(Platform);
   protected _document = inject(DOCUMENT, {optional: true})!;
@@ -223,13 +225,13 @@ export class CdkDialogContainer<C extends DialogConfig = DialogConfig>
       // The tabindex attribute should be removed to avoid navigating to that element again
       this._ngZone.runOutsideAngular(() => {
         const callback = () => {
-          element.removeEventListener('blur', callback);
-          element.removeEventListener('mousedown', callback);
+          deregisterBlur();
+          deregisterMousedown();
           element.removeAttribute('tabindex');
         };
 
-        element.addEventListener('blur', callback);
-        element.addEventListener('mousedown', callback);
+        const deregisterBlur = this._renderer.listen(element, 'blur', callback);
+        const deregisterMousedown = this._renderer.listen(element, 'mousedown', callback);
       });
     }
     element.focus(options);
diff --git a/src/cdk/dialog/dialog.spec.ts b/src/cdk/dialog/dialog.spec.ts
index 06a83753853b..f224117dea08 100644
--- a/src/cdk/dialog/dialog.spec.ts
+++ b/src/cdk/dialog/dialog.spec.ts
@@ -1205,7 +1205,6 @@ describe('Dialog with a parent Dialog', () => {
 
 @Directive({
   selector: 'dir-with-view-container',
-  standalone: true,
 })
 class DirectiveWithViewContainer {
   viewContainerRef = inject(ViewContainerRef);
@@ -1223,7 +1222,6 @@ class ComponentWithOnPushViewContainer {
 @Component({
   selector: 'arbitrary-component',
   template: `<dir-with-view-container></dir-with-view-container>`,
-  standalone: true,
   imports: [DirectiveWithViewContainer],
 })
 class ComponentWithChildViewContainer {
@@ -1238,7 +1236,6 @@ class ComponentWithChildViewContainer {
   selector: 'arbitrary-component-with-template-ref',
   template: `<ng-template let-data let-dialogRef="dialogRef">
       Cheese {{localValue}} {{data?.value}}{{setDialogRef(dialogRef)}}</ng-template>`,
-  standalone: true,
   imports: [DialogModule],
 })
 class ComponentWithTemplateRef {
@@ -1256,7 +1253,6 @@ class ComponentWithTemplateRef {
 /** Simple component for testing ComponentPortal. */
 @Component({
   template: '<p>Pizza</p> <input> <button>Close</button>',
-  standalone: true,
   imports: [DialogModule],
 })
 class PizzaMsg {
@@ -1269,7 +1265,6 @@ class PizzaMsg {
   template: `
     <h2>This is the title</h2>
   `,
-  standalone: true,
   imports: [DialogModule],
 })
 class ContentElementDialog {
@@ -1279,7 +1274,6 @@ class ContentElementDialog {
 @Component({
   template: '',
   providers: [Dialog],
-  standalone: true,
   imports: [DialogModule],
 })
 class ComponentThatProvidesMatDialog {
@@ -1289,7 +1283,6 @@ class ComponentThatProvidesMatDialog {
 /** Simple component for testing ComponentPortal. */
 @Component({
   template: '',
-  standalone: true,
   imports: [DialogModule],
 })
 class DialogWithInjectedData {
@@ -1298,7 +1291,6 @@ class DialogWithInjectedData {
 
 @Component({
   template: '<p>Pasta</p>',
-  standalone: true,
   imports: [DialogModule],
 })
 class DialogWithoutFocusableElements {}
@@ -1314,7 +1306,6 @@ const TEMPLATE_INJECTOR_TEST_TOKEN = new InjectionToken<string>('TEMPLATE_INJECT
 
 @Directive({
   selector: 'template-injector-inner',
-  standalone: true,
 })
 class TemplateInjectorInnerDirective {
   constructor() {
@@ -1331,7 +1322,6 @@ class TemplateInjectorInnerDirective {
       useValue: 'hello from parent component',
     },
   ],
-  standalone: true,
   imports: [TemplateInjectorInnerDirective],
 })
 class TemplateInjectorParentComponent {
diff --git a/src/cdk/dialog/dialog.ts b/src/cdk/dialog/dialog.ts
index 468e0f81a76f..0c9e9f06c8e2 100644
--- a/src/cdk/dialog/dialog.ts
+++ b/src/cdk/dialog/dialog.ts
@@ -21,6 +21,7 @@ import {of as observableOf, Observable, Subject, defer} from 'rxjs';
 import {DialogRef} from './dialog-ref';
 import {DialogConfig} from './dialog-config';
 import {Directionality} from '@angular/cdk/bidi';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {
   ComponentType,
   Overlay,
@@ -33,9 +34,6 @@ import {startWith} from 'rxjs/operators';
 import {DEFAULT_DIALOG_CONFIG, DIALOG_DATA, DIALOG_SCROLL_STRATEGY} from './dialog-injectors';
 import {CdkDialogContainer} from './dialog-container';
 
-/** Unique id for the created dialog. */
-let uniqueId = 0;
-
 @Injectable({providedIn: 'root'})
 export class Dialog implements OnDestroy {
   private _overlay = inject(Overlay);
@@ -43,6 +41,7 @@ export class Dialog implements OnDestroy {
   private _defaultOptions = inject<DialogConfig>(DEFAULT_DIALOG_CONFIG, {optional: true});
   private _parentDialog = inject(Dialog, {optional: true, skipSelf: true});
   private _overlayContainer = inject(OverlayContainer);
+  private _idGenerator = inject(_IdGenerator);
 
   private _openDialogsAtThisLevel: DialogRef<any, any>[] = [];
   private readonly _afterAllClosedAtThisLevel = new Subject<void>();
@@ -110,7 +109,7 @@ export class Dialog implements OnDestroy {
       DialogRef<R, C>
     >;
     config = {...defaults, ...config};
-    config.id = config.id || `cdk-dialog-${uniqueId++}`;
+    config.id = config.id || this._idGenerator.getId('cdk-dialog-');
 
     if (
       config.id &&
diff --git a/src/cdk/drag-drop/directives/drag-handle.ts b/src/cdk/drag-drop/directives/drag-handle.ts
index 9dd1bd514181..01d11aa430c8 100644
--- a/src/cdk/drag-drop/directives/drag-handle.ts
+++ b/src/cdk/drag-drop/directives/drag-handle.ts
@@ -7,6 +7,7 @@
  */
 
 import {
+  AfterViewInit,
   Directive,
   ElementRef,
   InjectionToken,
@@ -19,6 +20,7 @@ import {Subject} from 'rxjs';
 import type {CdkDrag} from './drag';
 import {CDK_DRAG_PARENT} from '../drag-parent';
 import {assertElementNode} from './assertions';
+import {DragDropRegistry} from '../drag-drop-registry';
 
 /**
  * Injection token that can be used to reference instances of `CdkDragHandle`. It serves as
@@ -35,10 +37,11 @@ export const CDK_DRAG_HANDLE = new InjectionToken<CdkDragHandle>('CdkDragHandle'
   },
   providers: [{provide: CDK_DRAG_HANDLE, useExisting: CdkDragHandle}],
 })
-export class CdkDragHandle implements OnDestroy {
+export class CdkDragHandle implements AfterViewInit, OnDestroy {
   element = inject<ElementRef<HTMLElement>>(ElementRef);
 
   private _parentDrag = inject<CdkDrag>(CDK_DRAG_PARENT, {optional: true, skipSelf: true});
+  private _dragDropRegistry = inject(DragDropRegistry);
 
   /** Emits when the state of the handle has changed. */
   readonly _stateChanges = new Subject<CdkDragHandle>();
@@ -64,6 +67,21 @@ export class CdkDragHandle implements OnDestroy {
     this._parentDrag?._addHandle(this);
   }
 
+  ngAfterViewInit() {
+    if (!this._parentDrag) {
+      let parent = this.element.nativeElement.parentElement;
+      while (parent) {
+        const ref = this._dragDropRegistry.getDragDirectiveForNode(parent);
+        if (ref) {
+          this._parentDrag = ref;
+          ref._addHandle(this);
+          break;
+        }
+        parent = parent.parentElement;
+      }
+    }
+  }
+
   ngOnDestroy() {
     this._parentDrag?._removeHandle(this);
     this._stateChanges.complete();
diff --git a/src/cdk/drag-drop/directives/drag.ts b/src/cdk/drag-drop/directives/drag.ts
index 11535b2bdf2a..8ec7fab27f5e 100644
--- a/src/cdk/drag-drop/directives/drag.ts
+++ b/src/cdk/drag-drop/directives/drag.ts
@@ -48,8 +48,7 @@ import type {CdkDropList} from './drop-list';
 import {DragDrop} from '../drag-drop';
 import {CDK_DRAG_CONFIG, DragDropConfig, DragStartDelay, DragAxis} from './config';
 import {assertElementNode} from './assertions';
-
-const DRAG_HOST_CLASS = 'cdk-drag';
+import {DragDropRegistry} from '../drag-drop-registry';
 
 /**
  * Injection token that can be used to reference instances of `CdkDropList`. It serves as
@@ -63,7 +62,7 @@ export const CDK_DROP_LIST = new InjectionToken<CdkDropList>('CdkDropList');
   selector: '[cdkDrag]',
   exportAs: 'cdkDrag',
   host: {
-    'class': DRAG_HOST_CLASS,
+    'class': 'cdk-drag',
     '[class.cdk-drag-disabled]': 'disabled',
     '[class.cdk-drag-dragging]': '_dragRef.isDragging()',
   },
@@ -78,9 +77,9 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
   private _changeDetectorRef = inject(ChangeDetectorRef);
   private _selfHandle = inject<CdkDragHandle>(CDK_DRAG_HANDLE, {optional: true, self: true});
   private _parentDrag = inject<CdkDrag>(CDK_DRAG_PARENT, {optional: true, skipSelf: true});
+  private _dragDropRegistry = inject(DragDropRegistry);
 
   private readonly _destroyed = new Subject<void>();
-  private static _dragInstances: CdkDrag[] = [];
   private _handles = new BehaviorSubject<CdkDragHandle[]>([]);
   private _previewTemplate: CdkDragPreview | null;
   private _placeholderTemplate: CdkDragPlaceholder | null;
@@ -240,11 +239,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
       zIndex: config?.zIndex,
     });
     this._dragRef.data = this;
-
-    // We have to keep track of the drag instances in order to be able to match an element to
-    // a drag instance. We can't go through the global registry of `DragRef`, because the root
-    // element could be different.
-    CdkDrag._dragInstances.push(this);
+    this._dragDropRegistry.registerDirectiveNode(this.element.nativeElement, this);
 
     if (config) {
       this._assignDefaults(config);
@@ -348,10 +343,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
       this.dropContainer.removeItem(this);
     }
 
-    const index = CdkDrag._dragInstances.indexOf(this);
-    if (index > -1) {
-      CdkDrag._dragInstances.splice(index, 1);
-    }
+    this._dragDropRegistry.removeDirectiveNode(this.element.nativeElement);
 
     // Unnecessary in most cases, but used to avoid extra change detections with `zone-paths-rxjs`.
     this._ngZone.runOutsideAngular(() => {
@@ -487,12 +479,9 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
       // the item was projected into another item by something like `ngTemplateOutlet`.
       let parent = this.element.nativeElement.parentElement;
       while (parent) {
-        if (parent.classList.contains(DRAG_HOST_CLASS)) {
-          ref.withParent(
-            CdkDrag._dragInstances.find(drag => {
-              return drag.element.nativeElement === parent;
-            })?._dragRef || null,
-          );
+        const parentDrag = this._dragDropRegistry.getDragDirectiveForNode(parent);
+        if (parentDrag) {
+          ref.withParent(parentDrag._dragRef);
           break;
         }
         parent = parent.parentElement;
diff --git a/src/cdk/drag-drop/directives/drop-list-shared.spec.ts b/src/cdk/drag-drop/directives/drop-list-shared.spec.ts
index 139ec0f00efb..e8b123c199a8 100644
--- a/src/cdk/drag-drop/directives/drop-list-shared.spec.ts
+++ b/src/cdk/drag-drop/directives/drop-list-shared.spec.ts
@@ -4886,7 +4886,6 @@ export function getHorizontalFixtures(listOrientation: Exclude<DropListOrientati
     encapsulation: ViewEncapsulation.None,
     styles: HORIZONTAL_FIXTURE_STYLES,
     template: HORIZONTAL_FIXTURE_TEMPLATE,
-    standalone: true,
     imports: [CdkDropList, CdkDrag],
   })
   class DraggableInHorizontalDropZone implements AfterViewInit {
@@ -4918,7 +4917,6 @@ export function getHorizontalFixtures(listOrientation: Exclude<DropListOrientati
   }
 
   @Component({
-    standalone: true,
     imports: [CdkDropList, CdkDrag],
     template: HORIZONTAL_FIXTURE_TEMPLATE,
 
@@ -4973,7 +4971,6 @@ export function getHorizontalFixtures(listOrientation: Exclude<DropListOrientati
         }
       </div>
     `,
-    standalone: true,
     imports: [CdkDropList, CdkDrag, CdkDragPreview],
   })
   class DraggableInHorizontalFlexDropZoneWithMatchSizePreview {
@@ -5019,7 +5016,6 @@ const DROP_ZONE_FIXTURE_TEMPLATE = `
 
 @Component({
   template: DROP_ZONE_FIXTURE_TEMPLATE,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, NgFor],
 })
 export class DraggableInDropZone implements AfterViewInit {
@@ -5059,7 +5055,6 @@ export class DraggableInDropZone implements AfterViewInit {
   selector: 'draggable-in-on-push-zone',
   template: DROP_ZONE_FIXTURE_TEMPLATE,
   changeDetection: ChangeDetectionStrategy.OnPush,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, NgFor],
 })
 class DraggableInOnPushDropZone extends DraggableInDropZone {}
@@ -5071,7 +5066,6 @@ class DraggableInOnPushDropZone extends DraggableInDropZone {}
       <draggable-in-on-push-zone></draggable-in-on-push-zone>
     </div>
   `,
-  standalone: true,
   imports: [CdkDropListGroup, DraggableInOnPushDropZone],
 })
 class ConnectedDropListsInOnPush {}
@@ -5088,7 +5082,6 @@ class ConnectedDropListsInOnPush {}
       margin: 10vw 0 0 10vw;
     }
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, NgFor],
 })
 export class DraggableInScrollableVerticalDropZone extends DraggableInDropZone {
@@ -5117,7 +5110,6 @@ export class DraggableInScrollableVerticalDropZone extends DraggableInDropZone {
       margin: 10vw 0 0 10vw;
     }
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, NgFor, CdkScrollable],
 })
 class DraggableInScrollableParentContainer extends DraggableInDropZone implements AfterViewInit {
@@ -5165,7 +5157,6 @@ class DraggableInScrollableParentContainer extends DraggableInDropZone implement
         }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class DraggableInDropZoneWithContainer extends DraggableInDropZone {}
@@ -5196,7 +5187,6 @@ class DraggableInDropZoneWithContainer extends DraggableInDropZone {}
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, CdkDragPreview, NgIf],
 })
 class DraggableInDropZoneWithCustomPreview {
@@ -5231,7 +5221,6 @@ class DraggableInDropZoneWithCustomPreview {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, CdkDragPreview],
 })
 class DraggableInDropZoneWithCustomTextOnlyPreview {
@@ -5254,7 +5243,6 @@ class DraggableInDropZoneWithCustomTextOnlyPreview {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, CdkDragPreview],
 })
 class DraggableInDropZoneWithCustomMultiNodePreview {
@@ -5287,7 +5275,6 @@ class DraggableInDropZoneWithCustomMultiNodePreview {
       height: ${ITEM_HEIGHT * 3}px;
     }
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, CdkDragPlaceholder, NgClass],
 })
 class DraggableInDropZoneWithCustomPlaceholder {
@@ -5309,7 +5296,6 @@ class DraggableInDropZoneWithCustomPlaceholder {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, CdkDragPlaceholder],
 })
 class DraggableInDropZoneWithCustomTextOnlyPlaceholder {
@@ -5331,7 +5317,6 @@ class DraggableInDropZoneWithCustomTextOnlyPlaceholder {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, CdkDragPlaceholder],
 })
 class DraggableInDropZoneWithCustomMultiNodePlaceholder {
@@ -5407,7 +5392,6 @@ const CONNECTED_DROP_ZONES_TEMPLATE = `
   encapsulation: ViewEncapsulation.None,
   styles: CONNECTED_DROP_ZONES_STYLES,
   template: CONNECTED_DROP_ZONES_TEMPLATE,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 export class ConnectedDropZones implements AfterViewInit {
@@ -5442,7 +5426,6 @@ export class ConnectedDropZones implements AfterViewInit {
   encapsulation: ViewEncapsulation.ShadowDom,
   styles: CONNECTED_DROP_ZONES_STYLES,
   template: `@if (true) {${CONNECTED_DROP_ZONES_TEMPLATE}}`,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class ConnectedDropZonesInsideShadowRootWithNgIf extends ConnectedDropZones {}
@@ -5484,7 +5467,6 @@ class ConnectedDropZonesInsideShadowRootWithNgIf extends ConnectedDropZones {}
       </div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag, CdkDropListGroup],
 })
 class ConnectedDropZonesViaGroupDirective extends ConnectedDropZones {
@@ -5524,7 +5506,6 @@ class ConnectedDropZonesViaGroupDirective extends ConnectedDropZones {
       <div cdkDrag>Two</div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class ConnectedDropZonesWithSingleItems {
@@ -5545,7 +5526,6 @@ class ConnectedDropZonesWithSingleItems {
       <div cdkDropList #listTwo="cdkDropList"></div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDropListGroup],
 })
 class NestedDropListGroups {
@@ -5558,14 +5538,12 @@ class NestedDropListGroups {
   template: `
     <ng-container cdkDropList></ng-container>
   `,
-  standalone: true,
   imports: [CdkDropList],
 })
 class DropListOnNgContainer {}
 
 @Component({
   changeDetection: ChangeDetectionStrategy.OnPush,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
   template: `
     <div cdkDropList style="width: 100px; background: pink;">
@@ -5599,7 +5577,6 @@ class DraggableInDropZoneWithoutEvents {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
   changeDetection: ChangeDetectionStrategy.OnPush,
 })
@@ -5629,7 +5606,6 @@ class WrappedDropContainerComponent {
       <wrapped-drop-container [items]="done"></wrapped-drop-container>
     </div>
   `,
-  standalone: true,
   imports: [CdkDropListGroup, WrappedDropContainerComponent],
 })
 class ConnectedWrappedDropZones {
@@ -5660,7 +5636,6 @@ class ConnectedWrappedDropZones {
         }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class DraggableWithCanvasInDropZone extends DraggableInDropZone implements AfterViewInit {
@@ -5702,7 +5677,6 @@ class DraggableWithCanvasInDropZone extends DraggableInDropZone implements After
         }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class DraggableWithInvalidCanvasInDropZone extends DraggableInDropZone {}
@@ -5742,7 +5716,6 @@ class DraggableWithInvalidCanvasInDropZone extends DraggableInDropZone {}
         (cdkDragReleased)="itemDragReleasedSpy($event)">
       </div>
     </div>`,
-  standalone: true,
   imports: [CdkDrag],
 })
 class NestedDragsComponent {
@@ -5797,7 +5770,6 @@ class NestedDragsComponent {
       </div>
     </ng-template>
   `,
-  standalone: true,
   imports: [CdkDrag, NgTemplateOutlet],
 })
 class NestedDragsThroughTemplate {
@@ -5823,7 +5795,6 @@ class NestedDragsThroughTemplate {
       </div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class NestedDropZones {
@@ -5835,7 +5806,6 @@ class NestedDropZones {
 
 @Component({
   template: `<div cdkDropList></div>`,
-  standalone: true,
   imports: [CdkDropList],
 })
 class PlainStandaloneDropList {
@@ -5878,7 +5848,6 @@ class PlainStandaloneDropList {
       </div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class ConnectedDropZonesWithIntermediateSibling extends ConnectedDropZones {}
@@ -5911,7 +5880,6 @@ class ConnectedDropZonesWithIntermediateSibling extends ConnectedDropZones {}
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class DraggableWithInputsInDropZone extends DraggableInDropZone {
@@ -5934,7 +5902,6 @@ class DraggableWithInputsInDropZone extends DraggableInDropZone {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class DraggableWithRadioInputsInDropZone {
@@ -5986,7 +5953,6 @@ class DraggableWithRadioInputsInDropZone {
       </div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class ConnectedDropZonesWithAlternateContainer extends ConnectedDropZones {
@@ -6009,7 +5975,6 @@ class ConnectedDropZonesWithAlternateContainer extends ConnectedDropZones {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class DraggableWithInvalidAlternateContainer {
@@ -6032,7 +5997,6 @@ class DraggableWithInvalidAlternateContainer {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class DraggableWithMissingAlternateContainer {
diff --git a/src/cdk/drag-drop/directives/drop-list.ts b/src/cdk/drag-drop/directives/drop-list.ts
index f4fce01c96f7..1e6e6ff315e2 100644
--- a/src/cdk/drag-drop/directives/drop-list.ts
+++ b/src/cdk/drag-drop/directives/drop-list.ts
@@ -19,6 +19,7 @@ import {
   inject,
 } from '@angular/core';
 import {Directionality} from '@angular/cdk/bidi';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {ScrollDispatcher} from '@angular/cdk/scrolling';
 import {CDK_DROP_LIST, CdkDrag} from './drag';
 import {CdkDragDrop, CdkDragEnter, CdkDragExit, CdkDragSortEvent} from '../drag-events';
@@ -31,9 +32,6 @@ import {merge, Subject} from 'rxjs';
 import {startWith, takeUntil} from 'rxjs/operators';
 import {assertElementNode} from './assertions';
 
-/** Counter used to generate unique ids for drop zones. */
-let _uniqueIdCounter = 0;
-
 /** Container that wraps a set of draggable items. */
 @Directive({
   selector: '[cdkDropList], cdk-drop-list',
@@ -91,7 +89,7 @@ export class CdkDropList<T = any> implements OnDestroy {
    * Unique ID for the drop zone. Can be used as a reference
    * in the `connectedTo` of another `CdkDropList`.
    */
-  @Input() id: string = `cdk-drop-list-${_uniqueIdCounter++}`;
+  @Input() id: string = inject(_IdGenerator).getId('cdk-drop-list-');
 
   /** Locks the position of the draggable elements inside the container along the specified axis. */
   @Input('cdkDropListLockAxis') lockAxis: DragAxis;
diff --git a/src/cdk/drag-drop/directives/mixed-drop-list.spec.ts b/src/cdk/drag-drop/directives/mixed-drop-list.spec.ts
index 8deaae351dd5..ae2f7b480a99 100644
--- a/src/cdk/drag-drop/directives/mixed-drop-list.spec.ts
+++ b/src/cdk/drag-drop/directives/mixed-drop-list.spec.ts
@@ -131,7 +131,6 @@ function getSortedSiblings(item: Element) {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDropList, CdkDrag],
 })
 class DraggableInHorizontalWrappingDropZone {
diff --git a/src/cdk/drag-drop/directives/standalone-drag.spec.ts b/src/cdk/drag-drop/directives/standalone-drag.spec.ts
index 775f9e69ef91..049637833356 100644
--- a/src/cdk/drag-drop/directives/standalone-drag.spec.ts
+++ b/src/cdk/drag-drop/directives/standalone-drag.spec.ts
@@ -9,6 +9,7 @@ import {
   ViewEncapsulation,
   signal,
 } from '@angular/core';
+import {NgTemplateOutlet} from '@angular/common';
 import {fakeAsync, flush, tick} from '@angular/core/testing';
 import {
   dispatchEvent,
@@ -363,6 +364,22 @@ describe('Standalone CdkDrag', () => {
 
       expect(dragElement.style.transform).toBeFalsy();
     }));
+
+    it('should stop dragging on touchcancel', fakeAsync(() => {
+      const fixture = createComponent(StandaloneDraggable);
+      fixture.detectChanges();
+      const dragElement = fixture.componentInstance.dragElement.nativeElement;
+      const x = 50;
+      const y = 100;
+
+      expect(dragElement.style.transform).toBeFalsy();
+      startDraggingViaTouch(fixture, dragElement);
+      continueDraggingViaTouch(fixture, x, y);
+      dispatchTouchEvent(document, 'touchcancel', x, y);
+      fixture.detectChanges();
+      expect(dragElement.style.transform).toBe('translate3d(50px, 100px, 0px)');
+      expect(fixture.componentInstance.endedSpy).toHaveBeenCalled();
+    }));
   });
 
   describe('mouse dragging when initial transform is none', () => {
@@ -1631,6 +1648,25 @@ describe('Standalone CdkDrag', () => {
         .toBe('translate3d(50px, 100px, 0px)');
     }));
 
+    it('should be able to drag with a handle that is defined in a separate embedded view', fakeAsync(() => {
+      const fixture = createComponent(StandaloneDraggableWithExternalTemplateHandle);
+      fixture.detectChanges();
+      const dragElement = fixture.componentInstance.dragElement.nativeElement;
+      const handle = fixture.nativeElement.querySelector('.handle');
+
+      expect(dragElement.style.transform).toBeFalsy();
+      dragElementViaMouse(fixture, dragElement, 50, 100);
+
+      expect(dragElement.style.transform)
+        .withContext('Expected not to be able to drag the element by itself.')
+        .toBeFalsy();
+
+      dragElementViaMouse(fixture, handle, 50, 100);
+      expect(dragElement.style.transform)
+        .withContext('Expected to drag the element by its handle.')
+        .toBe('translate3d(50px, 100px, 0px)');
+    }));
+
     it('should disable the tap highlight while dragging via the handle', fakeAsync(() => {
       // This test is irrelevant if the browser doesn't support styling the tap highlight color.
       if (!('webkitTapHighlightColor' in document.body.style)) {
@@ -1747,7 +1783,6 @@ describe('Standalone CdkDrag', () => {
         style="width: 100px; height: 100px; background: red;"></div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag],
 })
 class StandaloneDraggable {
@@ -1775,7 +1810,6 @@ class StandaloneDraggable {
   template: `
     <div cdkDrag #dragElement style="width: 100px; height: 100px; background: red;"></div>
   `,
-  standalone: true,
   imports: [CdkDrag],
 })
 class StandaloneDraggableWithOnPush {
@@ -1790,7 +1824,6 @@ class StandaloneDraggableWithOnPush {
       <div #handleElement cdkDragHandle style="width: 10px; height: 10px; background: green;"></div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag, CdkDragHandle],
 })
 class StandaloneDraggableWithHandle {
@@ -1812,7 +1845,6 @@ class StandaloneDraggableWithHandle {
         style="width: 10px; height: 10px; background: green;"></div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag, CdkDragHandle],
 })
 class StandaloneDraggableWithPreDisabledHandle {
@@ -1833,7 +1865,6 @@ class StandaloneDraggableWithPreDisabledHandle {
       }
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag, CdkDragHandle],
 })
 class StandaloneDraggableWithDelayedHandle {
@@ -1849,7 +1880,6 @@ class StandaloneDraggableWithDelayedHandle {
 @Component({
   selector: 'passthrough-component',
   template: '<ng-content></ng-content>',
-  standalone: true,
 })
 class PassthroughComponent {}
 
@@ -1866,7 +1896,6 @@ class PassthroughComponent {}
       </passthrough-component>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag, CdkDragHandle, PassthroughComponent],
 })
 class StandaloneDraggableWithIndirectHandle {
@@ -1878,7 +1907,6 @@ class StandaloneDraggableWithIndirectHandle {
   selector: 'shadow-wrapper',
   template: '<ng-content></ng-content>',
   encapsulation: ViewEncapsulation.ShadowDom,
-  standalone: true,
 })
 class ShadowWrapper {}
 
@@ -1892,7 +1920,6 @@ class ShadowWrapper {}
       </div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag, CdkDragHandle, ShadowWrapper],
 })
 class StandaloneDraggableWithShadowInsideHandle {
@@ -1918,7 +1945,6 @@ class StandaloneDraggableWithShadowInsideHandle {
       <div cdkDragHandle style="right: 0;"></div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag, CdkDragHandle],
 })
 class StandaloneDraggableWithMultipleHandles {
@@ -1936,7 +1962,6 @@ class StandaloneDraggableWithMultipleHandles {
         style="width: 100px; height: 100px; background: red;"></div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag],
 })
 class DraggableWithAlternateRoot {
@@ -1950,7 +1975,6 @@ class DraggableWithAlternateRoot {
   template: `
     <ng-container cdkDrag></ng-container>
   `,
-  standalone: true,
   imports: [CdkDrag],
 })
 class DraggableOnNgContainer {}
@@ -1961,7 +1985,6 @@ class DraggableOnNgContainer {}
       <ng-container cdkDragHandle></ng-container>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag, CdkDragHandle],
 })
 class DragHandleOnNgContainer {}
@@ -1977,7 +2000,6 @@ class DragHandleOnNgContainer {}
         style="width: 100px; height: 100px; background: red;"></div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag, CdkDragHandle],
 })
 class DraggableWithAlternateRootAndSelfHandle {
@@ -1994,7 +2016,6 @@ class DraggableWithAlternateRootAndSelfHandle {
       </ng-container>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag],
 })
 class DraggableNgContainerWithAlternateRoot {
@@ -2004,9 +2025,25 @@ class DraggableNgContainerWithAlternateRoot {
 
 @Component({
   template: `<div cdkDrag></div>`,
-  standalone: true,
   imports: [CdkDrag],
 })
 class PlainStandaloneDraggable {
   @ViewChild(CdkDrag) dragInstance: CdkDrag;
 }
+
+@Component({
+  template: `
+    <div #dragElement cdkDrag
+      style="width: 100px; height: 100px; background: red; position: relative">
+      <ng-container [ngTemplateOutlet]="template"/>
+    </div>
+
+    <ng-template #template>
+      <div cdkDragHandle class="handle" style="width: 10px; height: 10px; background: green;"></div>
+    </ng-template>
+  `,
+  imports: [CdkDrag, CdkDragHandle, NgTemplateOutlet],
+})
+class StandaloneDraggableWithExternalTemplateHandle {
+  @ViewChild('dragElement') dragElement: ElementRef<HTMLElement>;
+}
diff --git a/src/cdk/drag-drop/directives/standalone-drag.zone.spec.ts b/src/cdk/drag-drop/directives/standalone-drag.zone.spec.ts
index 50e9ba0eb46f..19fe5f7b2ce8 100644
--- a/src/cdk/drag-drop/directives/standalone-drag.zone.spec.ts
+++ b/src/cdk/drag-drop/directives/standalone-drag.zone.spec.ts
@@ -51,7 +51,6 @@ describe('Standalone CdkDrag Zone.js integration', () => {
         style="width: 100px; height: 100px; background: red;"></div>
     </div>
   `,
-  standalone: true,
   imports: [CdkDrag],
 })
 class StandaloneDraggable {
diff --git a/src/cdk/drag-drop/drag-drop-registry.spec.ts b/src/cdk/drag-drop/drag-drop-registry.spec.ts
index 935b94ba5908..956d3238a266 100644
--- a/src/cdk/drag-drop/drag-drop-registry.spec.ts
+++ b/src/cdk/drag-drop/drag-drop-registry.spec.ts
@@ -243,6 +243,19 @@ describe('DragDropRegistry', () => {
     subscription.unsubscribe();
   });
 
+  it('should dispatch `touchcancel` events if the drag was interrupted', () => {
+    const spy = jasmine.createSpy('pointerUp spy');
+    const subscription = registry.pointerUp.subscribe(spy);
+    const item = new DragItem() as unknown as DragRef;
+
+    registry.startDragging(item, createTouchEvent('touchstart') as TouchEvent);
+    const event = dispatchTouchEvent(document, 'touchcancel');
+
+    expect(spy).toHaveBeenCalledWith(event);
+
+    subscription.unsubscribe();
+  });
+
   class DragItem {
     isDragging() {
       return this.shouldBeDragging;
@@ -254,7 +267,6 @@ describe('DragDropRegistry', () => {
 
   @Component({
     template: ``,
-    standalone: true,
     imports: [DragDropModule],
   })
   class BlankComponent {}
diff --git a/src/cdk/drag-drop/drag-drop-registry.ts b/src/cdk/drag-drop/drag-drop-registry.ts
index 3c789a2f933b..5667c6f78a47 100644
--- a/src/cdk/drag-drop/drag-drop-registry.ts
+++ b/src/cdk/drag-drop/drag-drop-registry.ts
@@ -23,6 +23,7 @@ import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
 import {Observable, Observer, Subject, merge} from 'rxjs';
 import type {DropListRef} from './drop-list-ref';
 import type {DragRef} from './drag-ref';
+import type {CdkDrag} from './directives/drag';
 
 /** Event options that can be used to bind an active, capturing event. */
 const activeCapturingEventOptions = normalizePassiveListenerOptions({
@@ -79,6 +80,13 @@ export class DragDropRegistry<_ = unknown, __ = unknown> implements OnDestroy {
    */
   private _draggingPredicate = (item: DragRef) => item.isDragging();
 
+  /**
+   * Map tracking DOM nodes and their corresponding drag directives. Note that this is different
+   * from looking through the `_dragInstances` and getting their root node, because the root node
+   * isn't necessarily the node that the directive is set on.
+   */
+  private _domNodesToDirectives: WeakMap<Node, CdkDrag> | null = null;
+
   /**
    * Emits the `touchmove` or `mousemove` events that are dispatched
    * while the user is dragging a drag item instance.
@@ -162,16 +170,23 @@ export class DragDropRegistry<_ = unknown, __ = unknown> implements OnDestroy {
     this._activeDragInstances.update(instances => [...instances, drag]);
 
     if (this._activeDragInstances().length === 1) {
-      const isTouchEvent = event.type.startsWith('touch');
-
       // We explicitly bind __active__ listeners here, because newer browsers will default to
       // passive ones for `mousemove` and `touchmove`. The events need to be active, because we
       // use `preventDefault` to prevent the page from scrolling while the user is dragging.
+      const isTouchEvent = event.type.startsWith('touch');
+      const endEventHandler = {
+        handler: (e: Event) => this.pointerUp.next(e as TouchEvent | MouseEvent),
+        options: true,
+      };
+
+      if (isTouchEvent) {
+        this._globalListeners.set('touchend', endEventHandler);
+        this._globalListeners.set('touchcancel', endEventHandler);
+      } else {
+        this._globalListeners.set('mouseup', endEventHandler);
+      }
+
       this._globalListeners
-        .set(isTouchEvent ? 'touchend' : 'mouseup', {
-          handler: (e: Event) => this.pointerUp.next(e as TouchEvent | MouseEvent),
-          options: true,
-        })
         .set('scroll', {
           handler: (e: Event) => this.scroll.next(e),
           // Use capturing so that we pick up scroll changes in any scrollable nodes that aren't
@@ -262,9 +277,36 @@ export class DragDropRegistry<_ = unknown, __ = unknown> implements OnDestroy {
     return merge(...streams);
   }
 
+  /**
+   * Tracks the DOM node which has a draggable directive.
+   * @param node Node to track.
+   * @param dragRef Drag directive set on the node.
+   */
+  registerDirectiveNode(node: Node, dragRef: CdkDrag): void {
+    this._domNodesToDirectives ??= new WeakMap();
+    this._domNodesToDirectives.set(node, dragRef);
+  }
+
+  /**
+   * Stops tracking a draggable directive node.
+   * @param node Node to stop tracking.
+   */
+  removeDirectiveNode(node: Node): void {
+    this._domNodesToDirectives?.delete(node);
+  }
+
+  /**
+   * Gets the drag directive corresponding to a specific DOM node, if any.
+   * @param node Node for which to do the lookup.
+   */
+  getDragDirectiveForNode(node: Node): CdkDrag | null {
+    return this._domNodesToDirectives?.get(node) || null;
+  }
+
   ngOnDestroy() {
     this._dragInstances.forEach(instance => this.removeDragItem(instance));
     this._dropInstances.forEach(instance => this.removeDropContainer(instance));
+    this._domNodesToDirectives = null;
     this._clearGlobalListeners();
     this.pointerMove.complete();
     this.pointerUp.complete();
diff --git a/src/cdk/drag-drop/drag-drop.spec.ts b/src/cdk/drag-drop/drag-drop.spec.ts
index 7cd74cd9c435..89f67d796dc8 100644
--- a/src/cdk/drag-drop/drag-drop.spec.ts
+++ b/src/cdk/drag-drop/drag-drop.spec.ts
@@ -35,7 +35,6 @@ describe('DragDrop', () => {
 
 @Component({
   template: '<div></div>',
-  standalone: true,
 })
 class TestComponent {
   elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
diff --git a/src/cdk/drag-drop/drag-drop.ts b/src/cdk/drag-drop/drag-drop.ts
index 590f68731378..f3b43d3d5d3c 100644
--- a/src/cdk/drag-drop/drag-drop.ts
+++ b/src/cdk/drag-drop/drag-drop.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {Injectable, NgZone, ElementRef, inject} from '@angular/core';
+import {Injectable, NgZone, ElementRef, inject, RendererFactory2} from '@angular/core';
 import {DOCUMENT} from '@angular/common';
 import {ViewportRuler} from '@angular/cdk/scrolling';
 import {DragRef, DragRefConfig} from './drag-ref';
@@ -28,6 +28,7 @@ export class DragDrop {
   private _ngZone = inject(NgZone);
   private _viewportRuler = inject(ViewportRuler);
   private _dragDropRegistry = inject(DragDropRegistry);
+  private _renderer = inject(RendererFactory2).createRenderer(null, null);
 
   constructor(...args: unknown[]);
   constructor() {}
@@ -48,6 +49,7 @@ export class DragDrop {
       this._ngZone,
       this._viewportRuler,
       this._dragDropRegistry,
+      this._renderer,
     );
   }
 
diff --git a/src/cdk/drag-drop/drag-ref.ts b/src/cdk/drag-drop/drag-ref.ts
index ea70c698a4d0..0d20f2aa38e6 100644
--- a/src/cdk/drag-drop/drag-ref.ts
+++ b/src/cdk/drag-drop/drag-ref.ts
@@ -19,6 +19,7 @@ import {
   ElementRef,
   EmbeddedViewRef,
   NgZone,
+  Renderer2,
   TemplateRef,
   ViewContainerRef,
   signal,
@@ -378,6 +379,7 @@ export class DragRef<T = any> {
     private _ngZone: NgZone,
     private _viewportRuler: ViewportRuler,
     private _dragDropRegistry: DragDropRegistry,
+    private _renderer: Renderer2,
   ) {
     this.withRootElement(element).withParent(_config.parentDragRef || null);
     this._parentPositions = new ParentPositionTracker(_document);
@@ -853,6 +855,7 @@ export class DragRef<T = any> {
         this._pickupPositionOnPage,
         this._initialTransform,
         this._config.zIndex || 1000,
+        this._renderer,
       );
       this._preview.attach(this._getPreviewInsertionPoint(parent, shadowRoot));
 
@@ -1106,24 +1109,24 @@ export class DragRef<T = any> {
 
     return this._ngZone.runOutsideAngular(() => {
       return new Promise(resolve => {
-        const handler = ((event: TransitionEvent) => {
+        const handler = (event: TransitionEvent) => {
           if (
             !event ||
             (this._preview &&
               _getEventTarget(event) === this._preview.element &&
               event.propertyName === 'transform')
           ) {
-            this._preview?.removeEventListener('transitionend', handler);
+            cleanupListener();
             resolve();
             clearTimeout(timeout);
           }
-        }) as EventListenerOrEventListenerObject;
+        };
 
         // If a transition is short enough, the browser might not fire the `transitionend` event.
         // Since we know how long it's supposed to take, add a timeout with a 50% buffer that'll
         // fire if the transition hasn't completed when it was supposed to.
         const timeout = setTimeout(handler as Function, duration * 1.5);
-        this._preview!.addEventListener('transitionend', handler);
+        const cleanupListener = this._preview!.addEventListener('transitionend', handler);
       });
     });
   }
diff --git a/src/cdk/drag-drop/preview-ref.ts b/src/cdk/drag-drop/preview-ref.ts
index 497655515f55..d1ddbfbddf16 100644
--- a/src/cdk/drag-drop/preview-ref.ts
+++ b/src/cdk/drag-drop/preview-ref.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {EmbeddedViewRef, TemplateRef, ViewContainerRef} from '@angular/core';
+import {EmbeddedViewRef, Renderer2, TemplateRef, ViewContainerRef} from '@angular/core';
 import {Direction} from '@angular/cdk/bidi';
 import {
   extendStyles,
@@ -56,6 +56,7 @@ export class PreviewRef {
     },
     private _initialTransform: string | null,
     private _zIndex: number,
+    private _renderer: Renderer2,
   ) {}
 
   attach(parent: HTMLElement): void {
@@ -91,12 +92,8 @@ export class PreviewRef {
     return getTransformTransitionDurationInMs(this._preview);
   }
 
-  addEventListener(name: string, handler: EventListenerOrEventListenerObject) {
-    this._preview.addEventListener(name, handler);
-  }
-
-  removeEventListener(name: string, handler: EventListenerOrEventListenerObject) {
-    this._preview.removeEventListener(name, handler);
+  addEventListener(name: string, handler: (event: any) => void): () => void {
+    return this._renderer.listen(this._preview, name, handler);
   }
 
   private _createPreview(): HTMLElement {
diff --git a/src/cdk/listbox/listbox.spec.ts b/src/cdk/listbox/listbox.spec.ts
index 92a545461b3f..46e304fae7f6 100644
--- a/src/cdk/listbox/listbox.spec.ts
+++ b/src/cdk/listbox/listbox.spec.ts
@@ -45,10 +45,10 @@ describe('CdkOption and CdkListbox', () => {
       expect(optionIds.size).toBe(options.length);
       for (let i = 0; i < options.length; i++) {
         expect(options[i].id).toBe(optionEls[i].id);
-        expect(options[i].id).toMatch(/cdk-option-\d+/);
+        expect(options[i].id).toMatch(/cdk-option-\w+\d+/);
       }
       expect(listbox.id).toEqual(listboxEl.id);
-      expect(listbox.id).toMatch(/cdk-listbox-\d+/);
+      expect(listbox.id).toMatch(/cdk-listbox-\w+\d+/);
     });
 
     it('should not overwrite user given ids', () => {
diff --git a/src/cdk/listbox/listbox.ts b/src/cdk/listbox/listbox.ts
index c27bef5bcaee..6ab6a87595ec 100644
--- a/src/cdk/listbox/listbox.ts
+++ b/src/cdk/listbox/listbox.ts
@@ -6,7 +6,12 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {ActiveDescendantKeyManager, Highlightable, ListKeyManagerOption} from '@angular/cdk/a11y';
+import {
+  _IdGenerator,
+  ActiveDescendantKeyManager,
+  Highlightable,
+  ListKeyManagerOption,
+} from '@angular/cdk/a11y';
 import {Directionality} from '@angular/cdk/bidi';
 import {coerceArray} from '@angular/cdk/coercion';
 import {SelectionModel} from '@angular/cdk/collections';
@@ -37,14 +42,12 @@ import {
   OnDestroy,
   Output,
   QueryList,
+  signal,
 } from '@angular/core';
 import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
 import {defer, fromEvent, merge, Observable, Subject} from 'rxjs';
 import {filter, map, startWith, switchMap, takeUntil} from 'rxjs/operators';
 
-/** The next id to use for creating unique DOM IDs. */
-let nextId = 0;
-
 /**
  * An implementation of SelectionModel that internally always represents the selection as a
  * multi-selection. This is necessary so that we can recover the full selection if the user
@@ -104,7 +107,7 @@ export class CdkOption<T = unknown> implements ListKeyManagerOption, Highlightab
     this._id = value;
   }
   private _id: string;
-  private _generatedId = `cdk-option-${nextId++}`;
+  private _generatedId = inject(_IdGenerator).getId('cdk-option-');
 
   /** The value of this option. */
   @Input('cdkOption') value: T;
@@ -118,24 +121,24 @@ export class CdkOption<T = unknown> implements ListKeyManagerOption, Highlightab
   /** Whether this option is disabled. */
   @Input({alias: 'cdkOptionDisabled', transform: booleanAttribute})
   get disabled(): boolean {
-    return this.listbox.disabled || this._disabled;
+    return this.listbox.disabled || this._disabled();
   }
   set disabled(value: boolean) {
-    this._disabled = value;
+    this._disabled.set(value);
   }
-  private _disabled: boolean = false;
+  private _disabled = signal(false);
 
   /** The tabindex of the option when it is enabled. */
   @Input('tabindex')
   get enabledTabIndex() {
-    return this._enabledTabIndex === undefined
+    return this._enabledTabIndex() === undefined
       ? this.listbox.enabledTabIndex
-      : this._enabledTabIndex;
+      : this._enabledTabIndex();
   }
   set enabledTabIndex(value) {
-    this._enabledTabIndex = value;
+    this._enabledTabIndex.set(value);
   }
-  private _enabledTabIndex?: number | null;
+  private _enabledTabIndex = signal<number | null | undefined>(undefined);
 
   /** The option's host element */
   readonly element: HTMLElement = inject(ElementRef).nativeElement;
@@ -262,17 +265,17 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
     this._id = value;
   }
   private _id: string;
-  private _generatedId = `cdk-listbox-${nextId++}`;
+  private _generatedId = inject(_IdGenerator).getId('cdk-listbox-');
 
   /** The tabindex to use when the listbox is enabled. */
   @Input('tabindex')
   get enabledTabIndex() {
-    return this._enabledTabIndex === undefined ? 0 : this._enabledTabIndex;
+    return this._enabledTabIndex() === undefined ? 0 : this._enabledTabIndex();
   }
   set enabledTabIndex(value) {
-    this._enabledTabIndex = value;
+    this._enabledTabIndex.set(value);
   }
-  private _enabledTabIndex?: number | null;
+  private _enabledTabIndex = signal<number | null | undefined>(undefined);
 
   /** The value selected in the listbox, represented as an array of option values. */
   @Input('cdkListboxValue')
@@ -301,11 +304,23 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
 
   /** Whether the listbox is disabled. */
   @Input({alias: 'cdkListboxDisabled', transform: booleanAttribute})
-  disabled: boolean = false;
+  get disabled() {
+    return this._disabled();
+  }
+  set disabled(value: boolean) {
+    this._disabled.set(value);
+  }
+  private _disabled = signal(false);
 
   /** Whether the listbox will use active descendant or will move focus onto the options. */
   @Input({alias: 'cdkListboxUseActiveDescendant', transform: booleanAttribute})
-  useActiveDescendant: boolean = false;
+  get useActiveDescendant() {
+    return this._useActiveDescendant();
+  }
+  set useActiveDescendant(value: boolean) {
+    this._useActiveDescendant.set(value);
+  }
+  private _useActiveDescendant = signal(false);
 
   /** The orientation of the listbox. Only affects keyboard interaction, not visual layout. */
   @Input('cdkListboxOrientation')
diff --git a/src/cdk/menu/menu-bar.spec.ts b/src/cdk/menu/menu-bar.spec.ts
index 03d3b7f993bd..10f0d7c1b895 100644
--- a/src/cdk/menu/menu-bar.spec.ts
+++ b/src/cdk/menu/menu-bar.spec.ts
@@ -1116,7 +1116,6 @@ describe('MenuBar', () => {
       </li>
     </ul>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MenuBarRadioGroup {}
@@ -1152,7 +1151,6 @@ class MenuBarRadioGroup {}
       </ng-template>
     </div>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MultiMenuWithSubmenu {
@@ -1179,7 +1177,6 @@ class MultiMenuWithSubmenu {
       </ng-template>
     </div>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MenuWithCheckboxes {
@@ -1207,7 +1204,6 @@ class MenuWithCheckboxes {
       </ng-template>
     </div>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MenuWithRadioButtons {
@@ -1241,7 +1237,6 @@ class MenuWithRadioButtons {
       <button #inline_menu_item cdkMenuItem></button>
     </div>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MenuBarWithMenusAndInlineMenu {
diff --git a/src/cdk/menu/menu-base.ts b/src/cdk/menu/menu-base.ts
index ecd908a08466..93be3a9819e1 100644
--- a/src/cdk/menu/menu-base.ts
+++ b/src/cdk/menu/menu-base.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {FocusKeyManager, FocusOrigin} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusKeyManager, FocusOrigin} from '@angular/cdk/a11y';
 import {Directionality} from '@angular/cdk/bidi';
 import {
   AfterContentInit,
@@ -30,9 +30,6 @@ import {CdkMenuItem} from './menu-item';
 import {MENU_STACK, MenuStack, MenuStackItem} from './menu-stack';
 import {PointerFocusTracker} from './pointer-focus-tracker';
 
-/** Counter used to create unique IDs for menus. */
-let nextId = 0;
-
 /**
  * Abstract directive that implements shared logic common to all menus.
  * This class can be extended to create custom menu types.
@@ -70,7 +67,7 @@ export abstract class CdkMenuBase
   protected readonly dir = inject(Directionality, {optional: true});
 
   /** The id of the menu's host element. */
-  @Input() id = `cdk-menu-${nextId++}`;
+  @Input() id: string = inject(_IdGenerator).getId('cdk-menu-');
 
   /** All child MenuItem elements nested in this Menu. */
   @ContentChildren(CdkMenuItem, {descendants: true})
diff --git a/src/cdk/menu/menu-group.spec.ts b/src/cdk/menu/menu-group.spec.ts
index 6c01b4439e90..4b0659e00011 100644
--- a/src/cdk/menu/menu-group.spec.ts
+++ b/src/cdk/menu/menu-group.spec.ts
@@ -103,7 +103,6 @@ describe('MenuGroup', () => {
       </ul>
     </ng-template>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class CheckboxMenu {
@@ -148,7 +147,6 @@ class CheckboxMenu {
       </ul>
     </ng-template>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MenuWithMultipleRadioGroups {
diff --git a/src/cdk/menu/menu-item-checkbox.spec.ts b/src/cdk/menu/menu-item-checkbox.spec.ts
index 0dea58151748..cadbb23762b5 100644
--- a/src/cdk/menu/menu-item-checkbox.spec.ts
+++ b/src/cdk/menu/menu-item-checkbox.spec.ts
@@ -100,7 +100,6 @@ describe('MenuItemCheckbox', () => {
 
 @Component({
   template: `<button cdkMenuItemCheckbox>Click me!</button>`,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class SingleCheckboxButton {}
diff --git a/src/cdk/menu/menu-item-radio.spec.ts b/src/cdk/menu/menu-item-radio.spec.ts
index 9bfd95826c4c..5a7a77c59711 100644
--- a/src/cdk/menu/menu-item-radio.spec.ts
+++ b/src/cdk/menu/menu-item-radio.spec.ts
@@ -94,7 +94,6 @@ describe('MenuItemRadio', () => {
 
 @Component({
   template: `<button cdkMenuItemRadio>Click me!</button>`,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class SimpleRadioButton {}
diff --git a/src/cdk/menu/menu-item-radio.ts b/src/cdk/menu/menu-item-radio.ts
index ce6d8348f2f8..a5c55c6d804e 100644
--- a/src/cdk/menu/menu-item-radio.ts
+++ b/src/cdk/menu/menu-item-radio.ts
@@ -6,14 +6,12 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
 import {Directive, inject, OnDestroy} from '@angular/core';
+import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {CdkMenuItemSelectable} from './menu-item-selectable';
 import {CdkMenuItem} from './menu-item';
 
-/** Counter used to set a unique id and name for a selectable item */
-let nextId = 0;
-
 /**
  * A directive providing behavior for the "menuitemradio" ARIA role, which behaves similarly to
  * a conventional radio-button. Any sibling `CdkMenuItemRadio` instances within the same `CdkMenu`
@@ -36,7 +34,7 @@ export class CdkMenuItemRadio extends CdkMenuItemSelectable implements OnDestroy
   private readonly _selectionDispatcher = inject(UniqueSelectionDispatcher);
 
   /** An ID to identify this radio item to the `UniqueSelectionDispatcher`. */
-  private _id = `${nextId++}`;
+  private _id = inject(_IdGenerator).getId('cdk-menu-item-radio-');
 
   /** Function to unregister the selection dispatcher */
   private _removeDispatcherListener: () => void;
diff --git a/src/cdk/menu/menu-item.spec.ts b/src/cdk/menu/menu-item.spec.ts
index bc3ee5ac753a..0d20cdab6fb0 100644
--- a/src/cdk/menu/menu-item.spec.ts
+++ b/src/cdk/menu/menu-item.spec.ts
@@ -206,7 +206,6 @@ class MenuItemWithMultipleNestings {
 @Component({
   selector: 'mat-icon',
   template: '<ng-content></ng-content>',
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MatIcon {}
diff --git a/src/cdk/menu/menu-item.ts b/src/cdk/menu/menu-item.ts
index f227092f7d77..9892639ad8ea 100644
--- a/src/cdk/menu/menu-item.ts
+++ b/src/cdk/menu/menu-item.ts
@@ -190,6 +190,14 @@ export class CdkMenuItem implements FocusableOption, FocusableElement, Toggler,
       case ENTER:
         // Skip events that will trigger clicks so the handler doesn't get triggered twice.
         if (!hasModifierKey(event) && !eventDispatchesNativeClick(this._elementRef, event)) {
+          const nodeName = this._elementRef.nativeElement.nodeName;
+
+          // Avoid repeat events on non-native elements (see #30250). Note that we don't do this
+          // on the native elements so we don't interfere with their behavior (see #26296).
+          if (nodeName !== 'A' && nodeName !== 'BUTTON') {
+            event.preventDefault();
+          }
+
           this.trigger({keepOpen: event.keyCode === SPACE && !this.closeOnSpacebarTrigger});
         }
         break;
diff --git a/src/cdk/menu/menu-stack.spec.ts b/src/cdk/menu/menu-stack.spec.ts
index dca51dd9fc2f..e2e946869e3b 100644
--- a/src/cdk/menu/menu-stack.spec.ts
+++ b/src/cdk/menu/menu-stack.spec.ts
@@ -100,7 +100,6 @@ describe('MenuStack', () => {
       </ng-template>
     </div>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MultiMenuWithSubmenu {
diff --git a/src/cdk/menu/menu-stack.ts b/src/cdk/menu/menu-stack.ts
index 7d3b48e71e48..b9c397b5ff2f 100644
--- a/src/cdk/menu/menu-stack.ts
+++ b/src/cdk/menu/menu-stack.ts
@@ -6,7 +6,8 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {Inject, Injectable, InjectionToken, Optional, SkipSelf} from '@angular/core';
+import {inject, Inject, Injectable, InjectionToken, Optional, SkipSelf} from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {Observable, Subject} from 'rxjs';
 import {debounceTime, distinctUntilChanged, startWith} from 'rxjs/operators';
 
@@ -58,9 +59,6 @@ export interface MenuStackCloseEvent {
   focusParentTrigger?: boolean;
 }
 
-/** The next available menu stack ID. */
-let nextId = 0;
-
 /**
  * MenuStack allows subscribers to listen for close events (when a MenuStackItem is popped off
  * of the stack) in order to perform closing actions. Upon the MenuStack being empty it emits
@@ -70,7 +68,7 @@ let nextId = 0;
 @Injectable()
 export class MenuStack {
   /** The ID of this menu stack. */
-  readonly id = `${nextId++}`;
+  readonly id = inject(_IdGenerator).getId('cdk-menu-stack-');
 
   /** All MenuStackItems tracked by this MenuStack. */
   private readonly _elements: MenuStackItem[] = [];
diff --git a/src/cdk/menu/menu-trigger.spec.ts b/src/cdk/menu/menu-trigger.spec.ts
index cc447dd7f0e7..d9b138a12cc8 100644
--- a/src/cdk/menu/menu-trigger.spec.ts
+++ b/src/cdk/menu/menu-trigger.spec.ts
@@ -465,6 +465,22 @@ describe('MenuTrigger', () => {
       expect(secondEvent.defaultPrevented).toBe(false);
     });
 
+    it('should prevent the default action on enter presses on non-button/non-link triggers', () => {
+      fixture.componentInstance.useButtonTrigger = false;
+      fixture.changeDetectorRef.markForCheck();
+      detectChanges();
+
+      const firstEvent = dispatchKeyboardEvent(nativeTrigger, 'keydown', ENTER);
+      detectChanges();
+      expect(firstEvent.defaultPrevented).toBe(true);
+      expect(nativeMenus.length).toBe(2);
+
+      const secondEvent = dispatchKeyboardEvent(nativeTrigger, 'keydown', ENTER);
+      detectChanges();
+      expect(nativeMenus.length).toBe(1);
+      expect(secondEvent.defaultPrevented).toBe(true);
+    });
+
     it('should close the open menu on background click', () => {
       nativeTrigger.click();
       detectChanges();
@@ -674,7 +690,11 @@ class TriggerOpensItsMenu {
 
 @Component({
   template: `
-    <button cdkMenuItem [cdkMenuTriggerFor]="sub1">First</button>
+    @if (useButtonTrigger) {
+      <button cdkMenuItem [cdkMenuTriggerFor]="sub1">First</button>
+    } @else {
+      <div cdkMenuItem [cdkMenuTriggerFor]="sub1">First</div>
+    }
 
     <ng-template #sub1>
       <div cdkMenu>
@@ -693,6 +713,7 @@ class StandaloneTriggerWithInlineMenu {
   @ViewChild('submenu_item', {read: ElementRef}) submenuItem?: ElementRef<HTMLElement>;
   @ViewChild('inline_item', {read: ElementRef}) nativeInlineItem: ElementRef<HTMLElement>;
   @ViewChildren(CdkMenu, {read: ElementRef}) nativeMenus: QueryList<ElementRef>;
+  useButtonTrigger = true;
 }
 
 @Component({
diff --git a/src/cdk/menu/menu-trigger.ts b/src/cdk/menu/menu-trigger.ts
index 4122b94a8109..36025000baf4 100644
--- a/src/cdk/menu/menu-trigger.ts
+++ b/src/cdk/menu/menu-trigger.ts
@@ -259,7 +259,7 @@ export class CdkMenuTrigger extends CdkMenuTriggerBase implements OnDestroy {
       .position()
       .flexibleConnectedTo(this._elementRef)
       .withLockedPosition()
-      .withGrowAfterOpen()
+      .withFlexibleDimensions(false)
       .withPositions(this._getOverlayPositions());
   }
 
diff --git a/src/cdk/menu/menu.spec.ts b/src/cdk/menu/menu.spec.ts
index 08176e13521a..11e9b6bf5acd 100644
--- a/src/cdk/menu/menu.spec.ts
+++ b/src/cdk/menu/menu.spec.ts
@@ -520,7 +520,6 @@ describe('Menu', () => {
       </ul>
     </ng-template>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class MenuCheckboxGroup {
@@ -534,7 +533,6 @@ class MenuCheckboxGroup {
       <button cdkMenuItem>Starred</button>
     </div>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class InlineMenu {}
@@ -588,7 +586,6 @@ class InlineMenu {}
       </div>
     </ng-template>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class WithComplexNestedMenus {
@@ -649,7 +646,6 @@ class WithComplexNestedMenus {
       </div>
     </ng-template>
   `,
-  standalone: true,
   imports: [CdkMenuModule],
 })
 class WithComplexNestedMenusOnBottom {
diff --git a/src/cdk/menu/pointer-focus-tracker.spec.ts b/src/cdk/menu/pointer-focus-tracker.spec.ts
index 8aac6c578a18..12797c27cf76 100644
--- a/src/cdk/menu/pointer-focus-tracker.spec.ts
+++ b/src/cdk/menu/pointer-focus-tracker.spec.ts
@@ -99,7 +99,6 @@ describe('FocusMouseManger', () => {
 @Component({
   selector: 'wrapper',
   template: `<ng-content></ng-content>`,
-  standalone: true,
 })
 class MockWrapper implements FocusableElement {
   readonly _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
@@ -115,7 +114,6 @@ class MockWrapper implements FocusableElement {
       }
     </div>
   `,
-  standalone: true,
   imports: [MockWrapper],
 })
 class MultiElementWithConditionalComponent implements AfterViewInit {
diff --git a/src/cdk/observers/observe-content.spec.ts b/src/cdk/observers/observe-content.spec.ts
index 709cf4c5850b..93f5b60491dc 100644
--- a/src/cdk/observers/observe-content.spec.ts
+++ b/src/cdk/observers/observe-content.spec.ts
@@ -274,7 +274,6 @@ describe('ContentObserver injectable', () => {
       (cdkObserveContent)="doSomething()"
       [cdkObserveContentDisabled]="disabled">{{text}}</div>
   `,
-  standalone: true,
   imports: [ObserversModule],
 })
 class ComponentWithTextContent {
@@ -285,7 +284,6 @@ class ComponentWithTextContent {
 
 @Component({
   template: `<div (cdkObserveContent)="doSomething()"><div>{{text}}</div></div>`,
-  standalone: true,
   imports: [ObserversModule],
 })
 class ComponentWithChildTextContent {
@@ -295,7 +293,6 @@ class ComponentWithChildTextContent {
 
 @Component({
   template: `<div (cdkObserveContent)="spy($event)" [debounce]="debounce">{{text}}</div>`,
-  standalone: true,
   imports: [ObserversModule],
 })
 class ComponentWithDebouncedListener {
@@ -305,7 +302,6 @@ class ComponentWithDebouncedListener {
 
 @Component({
   template: `<div #contentEl>{{text}}</div>`,
-  standalone: true,
   imports: [ObserversModule],
 })
 class UnobservedComponentWithTextContent {
diff --git a/src/cdk/observers/private/shared-resize-observer.spec.ts b/src/cdk/observers/private/shared-resize-observer.spec.ts
index 7b6b3071eecb..73ef98a55ba8 100644
--- a/src/cdk/observers/private/shared-resize-observer.spec.ts
+++ b/src/cdk/observers/private/shared-resize-observer.spec.ts
@@ -138,7 +138,6 @@ describe('SharedResizeObserver', () => {
     <div #el1></div>
     <div #el2></div>
   `,
-  standalone: true,
 })
 export class TestComponent {
   @ViewChild('el1') el1: ElementRef<Element>;
diff --git a/src/cdk/observers/private/shared-resize-observer.ts b/src/cdk/observers/private/shared-resize-observer.ts
index a0cbd76c1cf6..6b3016ff4748 100644
--- a/src/cdk/observers/private/shared-resize-observer.ts
+++ b/src/cdk/observers/private/shared-resize-observer.ts
@@ -5,7 +5,7 @@
  * Use of this source code is governed by an MIT-style license that can be
  * found in the LICENSE file at https://angular.dev/license
  */
-import {inject, Injectable, NgZone, OnDestroy} from '@angular/core';
+import {inject, Injectable, NgZone, OnDestroy, RendererFactory2} from '@angular/core';
 import {Observable, Subject} from 'rxjs';
 import {filter, shareReplay, takeUntil} from 'rxjs/operators';
 
@@ -98,6 +98,8 @@ class SingleBoxSharedResizeObserver {
   providedIn: 'root',
 })
 export class SharedResizeObserver implements OnDestroy {
+  private _cleanupErrorListener: (() => void) | undefined;
+
   /** Map of box type to shared resize observer. */
   private _observers = new Map<ResizeObserverBoxOptions, SingleBoxSharedResizeObserver>();
 
@@ -107,7 +109,12 @@ export class SharedResizeObserver implements OnDestroy {
   constructor() {
     if (typeof ResizeObserver !== 'undefined' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
       this._ngZone.runOutsideAngular(() => {
-        window.addEventListener('error', loopLimitExceededErrorHandler);
+        const renderer = inject(RendererFactory2).createRenderer(null, null);
+        this._cleanupErrorListener = renderer.listen(
+          'window',
+          'error',
+          loopLimitExceededErrorHandler,
+        );
       });
     }
   }
@@ -117,9 +124,7 @@ export class SharedResizeObserver implements OnDestroy {
       observer.destroy();
     }
     this._observers.clear();
-    if (typeof ResizeObserver !== 'undefined' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
-      window.removeEventListener('error', loopLimitExceededErrorHandler);
-    }
+    this._cleanupErrorListener?.();
   }
 
   /**
diff --git a/src/cdk/overlay/BUILD.bazel b/src/cdk/overlay/BUILD.bazel
index 03eefa013649..d3a7e69da539 100644
--- a/src/cdk/overlay/BUILD.bazel
+++ b/src/cdk/overlay/BUILD.bazel
@@ -23,6 +23,7 @@ ng_module(
     ],
     deps = [
         "//src:dev_mode_types",
+        "//src/cdk/a11y",
         "//src/cdk/bidi",
         "//src/cdk/coercion",
         "//src/cdk/keycodes",
diff --git a/src/cdk/overlay/dispatchers/overlay-keyboard-dispatcher.spec.ts b/src/cdk/overlay/dispatchers/overlay-keyboard-dispatcher.spec.ts
index 7a103af0b6b6..afc1f93512b6 100644
--- a/src/cdk/overlay/dispatchers/overlay-keyboard-dispatcher.spec.ts
+++ b/src/cdk/overlay/dispatchers/overlay-keyboard-dispatcher.spec.ts
@@ -138,15 +138,17 @@ describe('OverlayKeyboardDispatcher', () => {
   it('should dispose of the global keyboard event handler correctly', () => {
     const overlayRef = overlay.create();
     const body = document.body;
-
     spyOn(body, 'addEventListener');
     spyOn(body, 'removeEventListener');
 
     keyboardDispatcher.add(overlayRef);
-    expect(body.addEventListener).toHaveBeenCalledWith('keydown', jasmine.any(Function));
+    expect(body.addEventListener).toHaveBeenCalledWith('keydown', jasmine.any(Function), false);
 
     overlayRef.dispose();
-    expect(body.removeEventListener).toHaveBeenCalledWith('keydown', jasmine.any(Function));
+    expect(document.body.removeEventListener).toHaveBeenCalledWith(
+      'keydown',
+      jasmine.any(Function),
+    );
   });
 
   it('should skip overlays that do not have keydown event subscriptions', () => {
@@ -197,7 +199,6 @@ describe('OverlayKeyboardDispatcher', () => {
 
 @Component({
   template: 'Hello',
-  standalone: true,
   imports: [OverlayModule],
 })
 class TestComponent {}
diff --git a/src/cdk/overlay/dispatchers/overlay-keyboard-dispatcher.ts b/src/cdk/overlay/dispatchers/overlay-keyboard-dispatcher.ts
index 4d7e5979fde2..82d8a9bb5604 100644
--- a/src/cdk/overlay/dispatchers/overlay-keyboard-dispatcher.ts
+++ b/src/cdk/overlay/dispatchers/overlay-keyboard-dispatcher.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {Injectable, NgZone, inject} from '@angular/core';
+import {Injectable, NgZone, RendererFactory2, inject} from '@angular/core';
 import {BaseOverlayDispatcher} from './base-overlay-dispatcher';
 import type {OverlayRef} from '../overlay-ref';
 
@@ -17,7 +17,9 @@ import type {OverlayRef} from '../overlay-ref';
  */
 @Injectable({providedIn: 'root'})
 export class OverlayKeyboardDispatcher extends BaseOverlayDispatcher {
-  private _ngZone = inject(NgZone, {optional: true});
+  private _ngZone = inject(NgZone);
+  private _renderer = inject(RendererFactory2).createRenderer(null, null);
+  private _cleanupKeydown: (() => void) | undefined;
 
   /** Add a new overlay to the list of attached overlay refs. */
   override add(overlayRef: OverlayRef): void {
@@ -25,14 +27,10 @@ export class OverlayKeyboardDispatcher extends BaseOverlayDispatcher {
 
     // Lazily start dispatcher once first overlay is added
     if (!this._isAttached) {
-      /** @breaking-change 14.0.0 _ngZone will be required. */
-      if (this._ngZone) {
-        this._ngZone.runOutsideAngular(() =>
-          this._document.body.addEventListener('keydown', this._keydownListener),
-        );
-      } else {
-        this._document.body.addEventListener('keydown', this._keydownListener);
-      }
+      this._ngZone.runOutsideAngular(() => {
+        this._cleanupKeydown = this._renderer.listen('body', 'keydown', this._keydownListener);
+      });
+
       this._isAttached = true;
     }
   }
@@ -40,7 +38,7 @@ export class OverlayKeyboardDispatcher extends BaseOverlayDispatcher {
   /** Detaches the global keyboard event listener. */
   protected detach() {
     if (this._isAttached) {
-      this._document.body.removeEventListener('keydown', this._keydownListener);
+      this._cleanupKeydown?.();
       this._isAttached = false;
     }
   }
@@ -57,13 +55,7 @@ export class OverlayKeyboardDispatcher extends BaseOverlayDispatcher {
       // because we don't want overlays that don't handle keyboard events to block the ones below
       // them that do.
       if (overlays[i]._keydownEvents.observers.length > 0) {
-        const keydownEvents = overlays[i]._keydownEvents;
-        /** @breaking-change 14.0.0 _ngZone will be required. */
-        if (this._ngZone) {
-          this._ngZone.run(() => keydownEvents.next(event));
-        } else {
-          keydownEvents.next(event);
-        }
+        this._ngZone.run(() => overlays[i]._keydownEvents.next(event));
         break;
       }
     }
diff --git a/src/cdk/overlay/dispatchers/overlay-outside-click-dispatcher.spec.ts b/src/cdk/overlay/dispatchers/overlay-outside-click-dispatcher.spec.ts
index b738ab16194e..e97458f96a17 100644
--- a/src/cdk/overlay/dispatchers/overlay-outside-click-dispatcher.spec.ts
+++ b/src/cdk/overlay/dispatchers/overlay-outside-click-dispatcher.spec.ts
@@ -420,7 +420,6 @@ describe('OverlayOutsideClickDispatcher', () => {
 
 @Component({
   template: 'Hello',
-  standalone: true,
   imports: [OverlayModule],
 })
 class TestComponent {}
diff --git a/src/cdk/overlay/fullscreen-overlay-container.spec.ts b/src/cdk/overlay/fullscreen-overlay-container.spec.ts
index 38680cefbe6f..0d18a687b77f 100644
--- a/src/cdk/overlay/fullscreen-overlay-container.spec.ts
+++ b/src/cdk/overlay/fullscreen-overlay-container.spec.ts
@@ -113,7 +113,6 @@ describe('FullscreenOverlayContainer', () => {
 @Component({
   template: `<ng-template cdk-portal>Cake</ng-template>`,
   providers: [Overlay],
-  standalone: true,
   imports: [TemplatePortalDirective],
 })
 class TestComponentWithTemplatePortals {
diff --git a/src/cdk/overlay/fullscreen-overlay-container.ts b/src/cdk/overlay/fullscreen-overlay-container.ts
index ed4dbf5fbf87..301e1a1eca29 100644
--- a/src/cdk/overlay/fullscreen-overlay-container.ts
+++ b/src/cdk/overlay/fullscreen-overlay-container.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {Injectable, OnDestroy} from '@angular/core';
+import {inject, Injectable, OnDestroy, RendererFactory2} from '@angular/core';
 import {OverlayContainer} from './overlay-container';
 
 /**
@@ -18,8 +18,9 @@ import {OverlayContainer} from './overlay-container';
  */
 @Injectable({providedIn: 'root'})
 export class FullscreenOverlayContainer extends OverlayContainer implements OnDestroy {
+  private _renderer = inject(RendererFactory2).createRenderer(null, null);
   private _fullScreenEventName: string | undefined;
-  private _fullScreenListener: () => void;
+  private _cleanupFullScreenListener: (() => void) | undefined;
 
   constructor(...args: unknown[]);
 
@@ -29,38 +30,27 @@ export class FullscreenOverlayContainer extends OverlayContainer implements OnDe
 
   override ngOnDestroy() {
     super.ngOnDestroy();
-
-    if (this._fullScreenEventName && this._fullScreenListener) {
-      this._document.removeEventListener(this._fullScreenEventName, this._fullScreenListener);
-    }
+    this._cleanupFullScreenListener?.();
   }
 
   protected override _createContainer(): void {
+    const eventName = this._getEventName();
     super._createContainer();
     this._adjustParentForFullscreenChange();
-    this._addFullscreenChangeListener(() => this._adjustParentForFullscreenChange());
-  }
 
-  private _adjustParentForFullscreenChange(): void {
-    if (!this._containerElement) {
-      return;
+    if (eventName) {
+      this._cleanupFullScreenListener?.();
+      this._cleanupFullScreenListener = this._renderer.listen('document', eventName, () => {
+        this._adjustParentForFullscreenChange();
+      });
     }
-
-    const fullscreenElement = this.getFullscreenElement();
-    const parent = fullscreenElement || this._document.body;
-    parent.appendChild(this._containerElement);
   }
 
-  private _addFullscreenChangeListener(fn: () => void) {
-    const eventName = this._getEventName();
-
-    if (eventName) {
-      if (this._fullScreenListener) {
-        this._document.removeEventListener(eventName, this._fullScreenListener);
-      }
-
-      this._document.addEventListener(eventName, fn);
-      this._fullScreenListener = fn;
+  private _adjustParentForFullscreenChange(): void {
+    if (this._containerElement) {
+      const fullscreenElement = this.getFullscreenElement();
+      const parent = fullscreenElement || this._document.body;
+      parent.appendChild(this._containerElement);
     }
   }
 
diff --git a/src/cdk/overlay/overlay-container.spec.ts b/src/cdk/overlay/overlay-container.spec.ts
index 47b586c6c2cd..5f41778c0f1a 100644
--- a/src/cdk/overlay/overlay-container.spec.ts
+++ b/src/cdk/overlay/overlay-container.spec.ts
@@ -89,7 +89,6 @@ describe('OverlayContainer', () => {
 @Component({
   template: `<ng-template cdkPortal>Cake</ng-template>`,
   providers: [Overlay],
-  standalone: true,
   imports: [CdkPortal],
 })
 class TestComponentWithTemplatePortals {
diff --git a/src/cdk/overlay/overlay-directives.spec.ts b/src/cdk/overlay/overlay-directives.spec.ts
index e562e01c3fdb..43f9272d1b61 100644
--- a/src/cdk/overlay/overlay-directives.spec.ts
+++ b/src/cdk/overlay/overlay-directives.spec.ts
@@ -783,7 +783,6 @@ describe('Overlay directives', () => {
             [cdkConnectedOverlayTransformOriginOn]="transformOriginSelector">
     <p>Menu content</p>
   </ng-template>`,
-  standalone: true,
   imports: [OverlayModule],
 })
 class ConnectedOverlayDirectiveTest {
@@ -825,7 +824,6 @@ class ConnectedOverlayDirectiveTest {
   template: `
   <button cdk-overlay-origin #trigger="cdkOverlayOrigin">Toggle menu</button>
   <ng-template cdk-connected-overlay>Menu content</ng-template>`,
-  standalone: true,
   imports: [OverlayModule],
 })
 class ConnectedOverlayPropertyInitOrder {
diff --git a/src/cdk/overlay/overlay-directives.zone.spec.ts b/src/cdk/overlay/overlay-directives.zone.spec.ts
index 3f3768f77b2d..3cec7fd804f0 100644
--- a/src/cdk/overlay/overlay-directives.zone.spec.ts
+++ b/src/cdk/overlay/overlay-directives.zone.spec.ts
@@ -75,7 +75,6 @@ describe('Overlay directives Zone.js integration', () => {
               [cdkConnectedOverlayTransformOriginOn]="transformOriginSelector">
       <p>Menu content</p>
     </ng-template>`,
-  standalone: true,
   imports: [OverlayModule],
 })
 class ConnectedOverlayDirectiveTest {
@@ -117,7 +116,6 @@ class ConnectedOverlayDirectiveTest {
   template: `
     <button cdk-overlay-origin #trigger="cdkOverlayOrigin">Toggle menu</button>
     <ng-template cdk-connected-overlay>Menu content</ng-template>`,
-  standalone: true,
   imports: [OverlayModule],
 })
 class ConnectedOverlayPropertyInitOrder {
diff --git a/src/cdk/overlay/overlay-ref.ts b/src/cdk/overlay/overlay-ref.ts
index d1b4e4f5cbf5..7eca1b8f182f 100644
--- a/src/cdk/overlay/overlay-ref.ts
+++ b/src/cdk/overlay/overlay-ref.ts
@@ -14,6 +14,7 @@ import {
   EmbeddedViewRef,
   EnvironmentInjector,
   NgZone,
+  Renderer2,
   afterNextRender,
   afterRender,
   untracked,
@@ -46,10 +47,8 @@ export class OverlayRef implements PortalOutlet {
   private _positionStrategy: PositionStrategy | undefined;
   private _scrollStrategy: ScrollStrategy | undefined;
   private _locationChanges: SubscriptionLike = Subscription.EMPTY;
-  private _backdropClickHandler = (event: MouseEvent) => this._backdropClick.next(event);
-  private _backdropTransitionendHandler = (event: TransitionEvent) => {
-    this._disposeBackdrop(event.target as HTMLElement | null);
-  };
+  private _cleanupBackdropClick: (() => void) | undefined;
+  private _cleanupBackdropTransitionEnd: (() => void) | undefined;
 
   /**
    * Reference to the parent of the `_host` at the time it was detached. Used to restore
@@ -82,6 +81,7 @@ export class OverlayRef implements PortalOutlet {
     private _outsideClickDispatcher: OverlayOutsideClickDispatcher,
     private _animationsDisabled = false,
     private _injector: EnvironmentInjector,
+    private _renderer: Renderer2,
   ) {
     if (_config.scrollStrategy) {
       this._scrollStrategy = _config.scrollStrategy;
@@ -449,7 +449,12 @@ export class OverlayRef implements PortalOutlet {
 
     // Forward backdrop clicks such that the consumer of the overlay can perform whatever
     // action desired when such a click occurs (usually closing the overlay).
-    this._backdropElement.addEventListener('click', this._backdropClickHandler);
+    this._cleanupBackdropClick?.();
+    this._cleanupBackdropClick = this._renderer.listen(
+      this._backdropElement,
+      'click',
+      (event: MouseEvent) => this._backdropClick.next(event),
+    );
 
     // Add class to fade-in the backdrop after one frame.
     if (!this._animationsDisabled && typeof requestAnimationFrame !== 'undefined') {
@@ -494,7 +499,14 @@ export class OverlayRef implements PortalOutlet {
     backdropToDetach.classList.remove('cdk-overlay-backdrop-showing');
 
     this._ngZone.runOutsideAngular(() => {
-      backdropToDetach!.addEventListener('transitionend', this._backdropTransitionendHandler);
+      this._cleanupBackdropTransitionEnd?.();
+      this._cleanupBackdropTransitionEnd = this._renderer.listen(
+        backdropToDetach,
+        'transitionend',
+        (event: TransitionEvent) => {
+          this._disposeBackdrop(event.target as HTMLElement | null);
+        },
+      );
     });
 
     // If the backdrop doesn't have a transition, the `transitionend` event won't fire.
@@ -565,9 +577,10 @@ export class OverlayRef implements PortalOutlet {
 
   /** Removes a backdrop element from the DOM. */
   private _disposeBackdrop(backdrop: HTMLElement | null) {
+    this._cleanupBackdropClick?.();
+    this._cleanupBackdropTransitionEnd?.();
+
     if (backdrop) {
-      backdrop.removeEventListener('click', this._backdropClickHandler);
-      backdrop.removeEventListener('transitionend', this._backdropTransitionendHandler);
       backdrop.remove();
 
       // It is possible that a new portal has been attached to this overlay since we started
diff --git a/src/cdk/overlay/overlay.spec.ts b/src/cdk/overlay/overlay.spec.ts
index 94ed51dea804..e4c32cba3907 100644
--- a/src/cdk/overlay/overlay.spec.ts
+++ b/src/cdk/overlay/overlay.spec.ts
@@ -1101,14 +1101,12 @@ describe('Overlay', () => {
 @Component({
   selector: 'pizza',
   template: '<p>Pizza</p>',
-  standalone: true,
 })
 class PizzaMsg {}
 
 /** Test-bed component that contains a TempatePortal and an ElementRef. */
 @Component({
   template: `<ng-template cdkPortal>Cake</ng-template>`,
-  standalone: true,
   imports: [CdkPortal],
 })
 class TestComponentWithTemplatePortals {
diff --git a/src/cdk/overlay/overlay.ts b/src/cdk/overlay/overlay.ts
index 35cf6c7b18fd..5598d296d0d2 100644
--- a/src/cdk/overlay/overlay.ts
+++ b/src/cdk/overlay/overlay.ts
@@ -17,7 +17,9 @@ import {
   ANIMATION_MODULE_TYPE,
   EnvironmentInjector,
   inject,
+  RendererFactory2,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
 import {OverlayKeyboardDispatcher} from './dispatchers/overlay-keyboard-dispatcher';
 import {OverlayOutsideClickDispatcher} from './dispatchers/overlay-outside-click-dispatcher';
@@ -27,9 +29,6 @@ import {OverlayRef} from './overlay-ref';
 import {OverlayPositionBuilder} from './position/overlay-position-builder';
 import {ScrollStrategyOptions} from './scroll/index';
 
-/** Next overlay unique ID. */
-let nextUniqueId = 0;
-
 /**
  * Service to create Overlays. Overlays are dynamically added pieces of floating UI, meant to be
  * used as a low-level building block for other components. Dialogs, tooltips, menus,
@@ -51,6 +50,8 @@ export class Overlay {
   private _location = inject(Location);
   private _outsideClickDispatcher = inject(OverlayOutsideClickDispatcher);
   private _animationsModuleType = inject(ANIMATION_MODULE_TYPE, {optional: true});
+  private _idGenerator = inject(_IdGenerator);
+  private _renderer = inject(RendererFactory2).createRenderer(null, null);
 
   private _appRef: ApplicationRef;
   private _styleLoader = inject(_CdkPrivateStyleLoader);
@@ -87,6 +88,7 @@ export class Overlay {
       this._outsideClickDispatcher,
       this._animationsModuleType === 'NoopAnimations',
       this._injector.get(EnvironmentInjector),
+      this._renderer,
     );
   }
 
@@ -106,7 +108,7 @@ export class Overlay {
   private _createPaneElement(host: HTMLElement): HTMLElement {
     const pane = this._document.createElement('div');
 
-    pane.id = `cdk-overlay-${nextUniqueId++}`;
+    pane.id = this._idGenerator.getId('cdk-overlay-');
     pane.classList.add('cdk-overlay-pane');
     host.appendChild(pane);
 
diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts
index 61bc0a212cad..d9f4bf0754ea 100644
--- a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts
+++ b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts
@@ -2959,7 +2959,6 @@ function createOverflowContainerElement() {
       class="transform-origin"
       style="width: ${DEFAULT_WIDTH}px; height: ${DEFAULT_HEIGHT}px;"></div>
   `,
-  standalone: true,
   imports: [ScrollingModule, OverlayModule, PortalModule],
 })
 class TestOverlay {}
diff --git a/src/cdk/overlay/position/global-position-strategy.spec.ts b/src/cdk/overlay/position/global-position-strategy.spec.ts
index 0e7b6d2ef7c0..fa70c2bb67f3 100644
--- a/src/cdk/overlay/position/global-position-strategy.spec.ts
+++ b/src/cdk/overlay/position/global-position-strategy.spec.ts
@@ -457,7 +457,6 @@ describe('GlobalPositonStrategy', () => {
 
 @Component({
   template: '',
-  standalone: true,
   imports: [OverlayModule, PortalModule],
 })
 class BlankPortal {}
diff --git a/src/cdk/overlay/scroll/block-scroll-strategy.spec.ts b/src/cdk/overlay/scroll/block-scroll-strategy.spec.ts
index bafe9541229e..af8bfe4e8501 100644
--- a/src/cdk/overlay/scroll/block-scroll-strategy.spec.ts
+++ b/src/cdk/overlay/scroll/block-scroll-strategy.spec.ts
@@ -215,7 +215,6 @@ describe('BlockScrollStrategy', () => {
 /** Simple component that we can attach to the overlay. */
 @Component({
   template: '<p>Focaccia</p>',
-  standalone: true,
   imports: [OverlayModule, PortalModule],
 })
 class FocacciaMsg {}
diff --git a/src/cdk/overlay/scroll/close-scroll-strategy.spec.ts b/src/cdk/overlay/scroll/close-scroll-strategy.spec.ts
index 8f5828c872bc..22b501164df9 100644
--- a/src/cdk/overlay/scroll/close-scroll-strategy.spec.ts
+++ b/src/cdk/overlay/scroll/close-scroll-strategy.spec.ts
@@ -135,7 +135,6 @@ describe('CloseScrollStrategy', () => {
 /** Simple component that we can attach to the overlay. */
 @Component({
   template: '<p>Mozarella</p>',
-  standalone: true,
   imports: [OverlayModule, PortalModule],
 })
 class MozarellaMsg {}
diff --git a/src/cdk/overlay/scroll/close-scroll-strategy.zone.spec.ts b/src/cdk/overlay/scroll/close-scroll-strategy.zone.spec.ts
index 163b9bea5672..396428f9f4a3 100644
--- a/src/cdk/overlay/scroll/close-scroll-strategy.zone.spec.ts
+++ b/src/cdk/overlay/scroll/close-scroll-strategy.zone.spec.ts
@@ -64,7 +64,6 @@ describe('CloseScrollStrategy Zone.js integration', () => {
 /** Simple component that we can attach to the overlay. */
 @Component({
   template: '<p>Mozarella</p>',
-  standalone: true,
   imports: [OverlayModule, PortalModule],
 })
 class MozarellaMsg {}
diff --git a/src/cdk/overlay/scroll/reposition-scroll-strategy.spec.ts b/src/cdk/overlay/scroll/reposition-scroll-strategy.spec.ts
index c5c27b13535c..261e4754f429 100644
--- a/src/cdk/overlay/scroll/reposition-scroll-strategy.spec.ts
+++ b/src/cdk/overlay/scroll/reposition-scroll-strategy.spec.ts
@@ -115,7 +115,6 @@ describe('RepositionScrollStrategy', () => {
 /** Simple component that we can attach to the overlay. */
 @Component({
   template: '<p>Pasta</p>',
-  standalone: true,
   imports: [OverlayModule, PortalModule],
 })
 class PastaMsg {}
diff --git a/src/cdk/portal/portal.spec.ts b/src/cdk/portal/portal.spec.ts
index 7d6d05810a6e..913801ff3d4b 100644
--- a/src/cdk/portal/portal.spec.ts
+++ b/src/cdk/portal/portal.spec.ts
@@ -725,7 +725,6 @@ class ChocolateInjector {
 @Component({
   selector: 'pizza-msg',
   template: '<p>Pizza</p><p>{{snack}}</p><ng-content></ng-content>',
-  standalone: true,
   imports: [PortalModule],
 })
 class PizzaMsg {
@@ -738,7 +737,6 @@ class PizzaMsg {
  */
 @Directive({
   selector: '[savesParentNodeOnInit]',
-  standalone: true,
 })
 class SaveParentNodeOnInit implements AfterViewInit {
   private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
@@ -760,7 +758,6 @@ class SaveParentNodeOnInit implements AfterViewInit {
       <div savesParentNodeOnInit></div>
     </ng-template>
   `,
-  standalone: true,
   imports: [SaveParentNodeOnInit],
 })
 class ArbitraryViewContainerRefComponent {
@@ -802,7 +799,6 @@ class ArbitraryViewContainerRefComponent {
     </div>
   </div>
   `,
-  standalone: true,
   imports: [CdkPortal, CdkPortalOutlet, PizzaMsg],
 })
 class PortalTestApp {
@@ -845,7 +841,6 @@ class PortalTestApp {
       <ng-template cdkPortalOutlet></ng-template>
     </div>
   `,
-  standalone: true,
   imports: [CdkPortalOutlet],
 })
 class UnboundPortalTestApp {
diff --git a/src/cdk/schematics/update-tool/index.ts b/src/cdk/schematics/update-tool/index.ts
index bd8498ecf4b8..a63302a2a408 100644
--- a/src/cdk/schematics/update-tool/index.ts
+++ b/src/cdk/schematics/update-tool/index.ts
@@ -194,7 +194,7 @@ export class UpdateProject<Context> {
   }
 
   /**
-   * Creates a program form the specified tsconfig and patches the host
+   * Creates a program from the specified tsconfig and patches the host
    * to read files and directories through the given file system.
    *
    * @throws {TsconfigParseError} If the tsconfig could not be parsed.
diff --git a/src/cdk/scrolling/scroll-dispatcher.spec.ts b/src/cdk/scrolling/scroll-dispatcher.spec.ts
index be4372e9188a..4c7b59d4259f 100644
--- a/src/cdk/scrolling/scroll-dispatcher.spec.ts
+++ b/src/cdk/scrolling/scroll-dispatcher.spec.ts
@@ -271,7 +271,6 @@ describe('ScrollDispatcher', () => {
 /** Simple component that contains a large div and can be scrolled. */
 @Component({
   template: `<div #scrollingElement cdkScrollable style="height: 9999px"></div>`,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class ScrollingComponent {
@@ -290,7 +289,6 @@ class ScrollingComponent {
     </div>
     <div id="scrollable-2" cdkScrollable></div>
   `,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class NestedScrollingComponent {
diff --git a/src/cdk/scrolling/scroll-dispatcher.zone.spec.ts b/src/cdk/scrolling/scroll-dispatcher.zone.spec.ts
index 99859c345b01..e7b2b8fc7690 100644
--- a/src/cdk/scrolling/scroll-dispatcher.zone.spec.ts
+++ b/src/cdk/scrolling/scroll-dispatcher.zone.spec.ts
@@ -41,7 +41,6 @@ describe('ScrollDispatcher Zone.js integration', () => {
 /** Simple component that contains a large div and can be scrolled. */
 @Component({
   template: `<div #scrollingElement cdkScrollable style="height: 9999px"></div>`,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class ScrollingComponent {
diff --git a/src/cdk/scrolling/scrollable.spec.ts b/src/cdk/scrolling/scrollable.spec.ts
index 539369f27f94..de0db2eabdc5 100644
--- a/src/cdk/scrolling/scrollable.spec.ts
+++ b/src/cdk/scrolling/scrollable.spec.ts
@@ -246,7 +246,6 @@ describe('CdkScrollable', () => {
       height: 100px;
     }
   `,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class ScrollableViewport {
diff --git a/src/cdk/scrolling/viewport-ruler.ts b/src/cdk/scrolling/viewport-ruler.ts
index c0070df1ee26..a053c8736f4f 100644
--- a/src/cdk/scrolling/viewport-ruler.ts
+++ b/src/cdk/scrolling/viewport-ruler.ts
@@ -7,7 +7,7 @@
  */
 
 import {Platform} from '@angular/cdk/platform';
-import {Injectable, NgZone, OnDestroy, inject} from '@angular/core';
+import {Injectable, NgZone, OnDestroy, RendererFactory2, inject} from '@angular/core';
 import {Observable, Subject} from 'rxjs';
 import {auditTime} from 'rxjs/operators';
 import {DOCUMENT} from '@angular/common';
@@ -28,6 +28,7 @@ export interface ViewportScrollPosition {
 @Injectable({providedIn: 'root'})
 export class ViewportRuler implements OnDestroy {
   private _platform = inject(Platform);
+  private _listeners: (() => void)[] | undefined;
 
   /** Cached viewport dimensions. */
   private _viewportSize: {width: number; height: number} | null;
@@ -35,11 +36,6 @@ export class ViewportRuler implements OnDestroy {
   /** Stream of viewport change events. */
   private readonly _change = new Subject<Event>();
 
-  /** Event listener that will be used to handle the viewport change events. */
-  private _changeListener = (event: Event) => {
-    this._change.next(event);
-  };
-
   /** Used to reference correct document/window */
   protected _document = inject(DOCUMENT, {optional: true})!;
 
@@ -47,15 +43,15 @@ export class ViewportRuler implements OnDestroy {
 
   constructor() {
     const ngZone = inject(NgZone);
+    const renderer = inject(RendererFactory2).createRenderer(null, null);
 
     ngZone.runOutsideAngular(() => {
       if (this._platform.isBrowser) {
-        const window = this._getWindow();
-
-        // Note that bind the events ourselves, rather than going through something like RxJS's
-        // `fromEvent` so that we can ensure that they're bound outside of the NgZone.
-        window.addEventListener('resize', this._changeListener);
-        window.addEventListener('orientationchange', this._changeListener);
+        const changeListener = (event: Event) => this._change.next(event);
+        this._listeners = [
+          renderer.listen('window', 'resize', changeListener),
+          renderer.listen('window', 'orientationchange', changeListener),
+        ];
       }
 
       // Clear the cached position so that the viewport is re-measured next time it is required.
@@ -65,12 +61,7 @@ export class ViewportRuler implements OnDestroy {
   }
 
   ngOnDestroy() {
-    if (this._platform.isBrowser) {
-      const window = this._getWindow();
-      window.removeEventListener('resize', this._changeListener);
-      window.removeEventListener('orientationchange', this._changeListener);
-    }
-
+    this._listeners?.forEach(cleanup => cleanup());
     this._change.complete();
   }
 
diff --git a/src/cdk/scrolling/virtual-scroll-viewport.spec.ts b/src/cdk/scrolling/virtual-scroll-viewport.spec.ts
index 54000570d720..796fbad2ffa5 100644
--- a/src/cdk/scrolling/virtual-scroll-viewport.spec.ts
+++ b/src/cdk/scrolling/virtual-scroll-viewport.spec.ts
@@ -1248,7 +1248,6 @@ function triggerScroll(viewport: CdkVirtualScrollViewport, offset?: number) {
     }
   `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class FixedSizeVirtualScroll {
@@ -1314,7 +1313,6 @@ class FixedSizeVirtualScroll {
     }
   `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class FixedSizeVirtualScrollWithRtlDirection {
@@ -1359,7 +1357,6 @@ class FixedSizeVirtualScrollWithRtlDirection {
       border: 1px dashed #ccc;
     }
   `,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class VirtualScrollWithNoStrategy {
@@ -1368,7 +1365,6 @@ class VirtualScrollWithNoStrategy {
 
 @Directive({
   selector: '[injects-view-container]',
-  standalone: true,
 })
 class InjectsViewContainer {
   viewContainerRef = inject(ViewContainerRef);
@@ -1400,7 +1396,6 @@ class InjectsViewContainer {
     }
   `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class VirtualScrollWithItemInjectingViewContainer {
@@ -1439,7 +1434,6 @@ class VirtualScrollWithItemInjectingViewContainer {
     }
   `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class DelayedInitializationVirtualScroll {
@@ -1478,7 +1472,6 @@ class DelayedInitializationVirtualScroll {
     }
   `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class VirtualScrollWithAppendOnly {
@@ -1521,7 +1514,6 @@ class VirtualScrollWithAppendOnly {
         }
     `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class VirtualScrollWithCustomScrollingElement {
@@ -1563,7 +1555,6 @@ class VirtualScrollWithCustomScrollingElement {
         }
     `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class VirtualScrollWithScrollableWindow {
@@ -1576,7 +1567,6 @@ class VirtualScrollWithScrollableWindow {
 
 @Component({
   template: '<cdk-virtual-scroll-viewport itemSize="50"></cdk-virtual-scroll-viewport>',
-  standalone: true,
   imports: [ScrollingModule],
 })
 class VirtualScrollableQuery {
diff --git a/src/cdk/scrolling/virtual-scroll-viewport.zone.spec.ts b/src/cdk/scrolling/virtual-scroll-viewport.zone.spec.ts
index b0547d767973..f4b893ed251c 100644
--- a/src/cdk/scrolling/virtual-scroll-viewport.zone.spec.ts
+++ b/src/cdk/scrolling/virtual-scroll-viewport.zone.spec.ts
@@ -112,7 +112,6 @@ describe('CdkVirtualScrollViewport Zone.js intergation', () => {
       }
     `,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [ScrollingModule],
 })
 class FixedSizeVirtualScroll {
diff --git a/src/cdk/stepper/stepper.ts b/src/cdk/stepper/stepper.ts
index 49393aafeefe..95f08f9942a3 100644
--- a/src/cdk/stepper/stepper.ts
+++ b/src/cdk/stepper/stepper.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {FocusableOption, FocusKeyManager} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusableOption, FocusKeyManager} from '@angular/cdk/a11y';
 import {Direction, Directionality} from '@angular/cdk/bidi';
 import {ENTER, hasModifierKey, SPACE} from '@angular/cdk/keycodes';
 import {
@@ -46,9 +46,6 @@ import {startWith, takeUntil} from 'rxjs/operators';
 import {CdkStepHeader} from './step-header';
 import {CdkStepLabel} from './step-label';
 
-/** Used to generate unique ID for each stepper component. */
-let nextId = 0;
-
 /**
  * Position state of the content of each step in stepper that is used for transitioning
  * the content into correct position upon step selection change.
@@ -324,7 +321,7 @@ export class CdkStepper implements AfterContentInit, AfterViewInit, OnDestroy {
   @Output() readonly selectedIndexChange: EventEmitter<number> = new EventEmitter<number>();
 
   /** Used to track unique ID for each stepper component. */
-  _groupId = nextId++;
+  private _groupId = inject(_IdGenerator).getId('cdk-stepper-');
 
   /** Orientation of the stepper. */
   @Input()
@@ -434,12 +431,12 @@ export class CdkStepper implements AfterContentInit, AfterViewInit, OnDestroy {
 
   /** Returns a unique id for each step label element. */
   _getStepLabelId(i: number): string {
-    return `cdk-step-label-${this._groupId}-${i}`;
+    return `${this._groupId}-label-${i}`;
   }
 
   /** Returns unique id for each step content element. */
   _getStepContentId(i: number): string {
-    return `cdk-step-content-${this._groupId}-${i}`;
+    return `${this._groupId}-content-${i}`;
   }
 
   /** Marks the component to be change detected. */
diff --git a/src/cdk/table/sticky-styler.ts b/src/cdk/table/sticky-styler.ts
index 144db5883cca..286cabacc6be 100644
--- a/src/cdk/table/sticky-styler.ts
+++ b/src/cdk/table/sticky-styler.ts
@@ -16,6 +16,12 @@ import {StickyPositioningListener} from './sticky-position-listener';
 
 export type StickyDirection = 'top' | 'bottom' | 'left' | 'right';
 
+interface UpdateStickyColumnsParams {
+  rows: HTMLElement[];
+  stickyStartStates: boolean[];
+  stickyEndStates: boolean[];
+}
+
 /**
  * List of all possible directions that can be used for sticky positioning.
  * @docs-private
@@ -27,6 +33,12 @@ export const STICKY_DIRECTIONS: StickyDirection[] = ['top', 'bottom', 'left', 'r
  * @docs-private
  */
 export class StickyStyler {
+  private _elemSizeCache = new WeakMap<HTMLElement, {width: number; height: number}>();
+  private _resizeObserver = globalThis?.ResizeObserver
+    ? new globalThis.ResizeObserver(entries => this._updateCachedSizes(entries))
+    : null;
+  private _updatedStickyColumnsParamsToReplay: UpdateStickyColumnsParams[] = [];
+  private _stickyColumnsReplayTimeout: number | null = null;
   private _cachedCellWidths: number[] = [];
   private readonly _borderCellCss: Readonly<{[d in StickyDirection]: string}>;
 
@@ -68,6 +80,10 @@ export class StickyStyler {
    * @param stickyDirections The directions that should no longer be set as sticky on the rows.
    */
   clearStickyPositioning(rows: HTMLElement[], stickyDirections: StickyDirection[]) {
+    if (stickyDirections.includes('left') || stickyDirections.includes('right')) {
+      this._removeFromStickyColumnReplayQueue(rows);
+    }
+
     const elementsToClear: HTMLElement[] = [];
     for (const row of rows) {
       // If the row isn't an element (e.g. if it's an `ng-container`),
@@ -100,13 +116,23 @@ export class StickyStyler {
    *     in this index position should be stuck to the end of the row.
    * @param recalculateCellWidths Whether the sticky styler should recalculate the width of each
    *     column cell. If `false` cached widths will be used instead.
+   * @param replay Whether to enqueue this call for replay after a ResizeObserver update.
    */
   updateStickyColumns(
     rows: HTMLElement[],
     stickyStartStates: boolean[],
     stickyEndStates: boolean[],
     recalculateCellWidths = true,
+    replay = true,
   ) {
+    if (replay) {
+      this._updateStickyColumnReplayQueue({
+        rows: [...rows],
+        stickyStartStates: [...stickyStartStates],
+        stickyEndStates: [...stickyEndStates],
+      });
+    }
+
     if (
       !rows.length ||
       !this._isBrowser ||
@@ -213,7 +239,7 @@ export class StickyStyler {
           ? (Array.from(row.children) as HTMLElement[])
           : [row];
 
-        const height = row.getBoundingClientRect().height;
+        const height = this._retrieveElementSize(row).height;
         stickyOffset += height;
         stickyCellHeights[rowIndex] = height;
       }
@@ -366,8 +392,8 @@ export class StickyStyler {
     const cellWidths: number[] = [];
     const firstRowCells = row.children;
     for (let i = 0; i < firstRowCells.length; i++) {
-      let cell: HTMLElement = firstRowCells[i] as HTMLElement;
-      cellWidths.push(cell.getBoundingClientRect().width);
+      const cell = firstRowCells[i] as HTMLElement;
+      cellWidths.push(this._retrieveElementSize(cell).width);
     }
 
     this._cachedCellWidths = cellWidths;
@@ -411,4 +437,103 @@ export class StickyStyler {
 
     return positions;
   }
+
+  /**
+   * Retreives the most recently observed size of the specified element from the cache, or
+   * meaures it directly if not yet cached.
+   */
+  private _retrieveElementSize(element: HTMLElement): {width: number; height: number} {
+    const cachedSize = this._elemSizeCache.get(element);
+    if (cachedSize) {
+      return cachedSize;
+    }
+
+    const clientRect = element.getBoundingClientRect();
+    const size = {width: clientRect.width, height: clientRect.height};
+
+    if (!this._resizeObserver) {
+      return size;
+    }
+
+    this._elemSizeCache.set(element, size);
+    this._resizeObserver.observe(element, {box: 'border-box'});
+    return size;
+  }
+
+  /**
+   * Conditionally enqueue the requested sticky update and clear previously queued updates
+   * for the same rows.
+   */
+  private _updateStickyColumnReplayQueue(params: UpdateStickyColumnsParams) {
+    this._removeFromStickyColumnReplayQueue(params.rows);
+
+    // No need to replay if a flush is pending.
+    if (this._stickyColumnsReplayTimeout) {
+      return;
+    }
+
+    this._updatedStickyColumnsParamsToReplay.push(params);
+  }
+
+  /** Remove updates for the specified rows from the queue. */
+  private _removeFromStickyColumnReplayQueue(rows: HTMLElement[]) {
+    const rowsSet = new Set(rows);
+    for (const update of this._updatedStickyColumnsParamsToReplay) {
+      update.rows = update.rows.filter(row => !rowsSet.has(row));
+    }
+    this._updatedStickyColumnsParamsToReplay = this._updatedStickyColumnsParamsToReplay.filter(
+      update => !!update.rows.length,
+    );
+  }
+
+  /** Update _elemSizeCache with the observed sizes. */
+  private _updateCachedSizes(entries: ResizeObserverEntry[]) {
+    let needsColumnUpdate = false;
+    for (const entry of entries) {
+      const newEntry = entry.borderBoxSize?.length
+        ? {
+            width: entry.borderBoxSize[0].inlineSize,
+            height: entry.borderBoxSize[0].blockSize,
+          }
+        : {
+            width: entry.contentRect.width,
+            height: entry.contentRect.height,
+          };
+
+      if (
+        newEntry.width !== this._elemSizeCache.get(entry.target as HTMLElement)?.width &&
+        isCell(entry.target)
+      ) {
+        needsColumnUpdate = true;
+      }
+
+      this._elemSizeCache.set(entry.target as HTMLElement, newEntry);
+    }
+
+    if (needsColumnUpdate && this._updatedStickyColumnsParamsToReplay.length) {
+      if (this._stickyColumnsReplayTimeout) {
+        clearTimeout(this._stickyColumnsReplayTimeout);
+      }
+
+      this._stickyColumnsReplayTimeout = setTimeout(() => {
+        for (const update of this._updatedStickyColumnsParamsToReplay) {
+          this.updateStickyColumns(
+            update.rows,
+            update.stickyStartStates,
+            update.stickyEndStates,
+            true,
+            false,
+          );
+        }
+        this._updatedStickyColumnsParamsToReplay = [];
+        this._stickyColumnsReplayTimeout = null;
+      }, 0);
+    }
+  }
+}
+
+function isCell(element: Element) {
+  return ['cdk-cell', 'cdk-header-cell', 'cdk-footer-cell'].some(klass =>
+    element.classList.contains(klass),
+  );
 }
diff --git a/src/cdk/table/table.spec.ts b/src/cdk/table/table.spec.ts
index 711f19849def..09cf5910300b 100644
--- a/src/cdk/table/table.spec.ts
+++ b/src/cdk/table/table.spec.ts
@@ -563,8 +563,7 @@ describe('CdkTable', () => {
     getRows(tableElement).forEach(row => {
       expect(row.getAttribute('role')).toBe('row');
       getCells(row).forEach(cell => {
-        // Native role of TD elements is row.
-        expect(cell.getAttribute('role')).toBe(null);
+        expect(cell.getAttribute('role')).toBe('cell');
       });
     });
   });
diff --git a/src/cdk/table/table.ts b/src/cdk/table/table.ts
index f287b9adb8b9..56c416ab560d 100644
--- a/src/cdk/table/table.ts
+++ b/src/cdk/table/table.ts
@@ -459,11 +459,12 @@ export class CdkTable<T>
 
   /** Aria role to apply to the table's cells based on the table's own role. */
   _getCellRole(): string | null {
+    // Perform this lazily in case the table's role was updated by a directive after construction.
     if (this._cellRoleInternal === undefined) {
-      // Perform this lazily in case the table's role was updated by a directive after construction.
-      const role = this._elementRef.nativeElement.getAttribute('role');
-      const cellRole = role === 'grid' || role === 'treegrid' ? 'gridcell' : 'cell';
-      this._cellRoleInternal = this._isNativeHtmlTable && cellRole === 'cell' ? null : cellRole;
+      // Note that we set `role="cell"` even on native `td` elements,
+      // because some browsers seem to require it. See #29784.
+      const tableRole = this._elementRef.nativeElement.getAttribute('role');
+      return tableRole === 'grid' || tableRole === 'treegrid' ? 'gridcell' : 'cell';
     }
 
     return this._cellRoleInternal;
@@ -1084,7 +1085,12 @@ export class CdkTable<T>
    * re-render that section.
    */
   private _renderUpdatedColumns(): boolean {
-    const columnsDiffReducer = (acc: boolean, def: BaseRowDef) => acc || !!def.getColumnsDiff();
+    const columnsDiffReducer = (acc: boolean, def: BaseRowDef) => {
+      // The differ should be run for every column, even if `acc` is already
+      // true (see #29922)
+      const diff = !!def.getColumnsDiff();
+      return acc || diff;
+    };
 
     // Force re-render data rows if the list of column definitions have changed.
     const dataColumnsChanged = this._rowDefs.reduce(columnsDiffReducer, false);
diff --git a/src/cdk/table/text-column.spec.ts b/src/cdk/table/text-column.spec.ts
index ffb4a54a3e85..aae3304a4a0f 100644
--- a/src/cdk/table/text-column.spec.ts
+++ b/src/cdk/table/text-column.spec.ts
@@ -167,7 +167,6 @@ interface TestData {
       <cdk-row *cdkRowDef="let row; columns: displayedColumns"></cdk-row>
     </cdk-table>
   `,
-  standalone: true,
   imports: [CdkTableModule],
 })
 class BasicTextColumnApp {
@@ -187,7 +186,6 @@ class BasicTextColumnApp {
   template: `
     <cdk-text-column name="column-a"></cdk-text-column>
   `,
-  standalone: true,
   imports: [CdkTableModule],
 })
 class MissingTableApp {}
@@ -201,7 +199,6 @@ class MissingTableApp {}
       <cdk-row *cdkRowDef="let row; columns: displayedColumns"></cdk-row>
     </cdk-table>
   `,
-  standalone: true,
   imports: [CdkTableModule],
 })
 class TextColumnWithoutNameApp extends BasicTextColumnApp {}
diff --git a/src/cdk/testing/protractor/protractor-element.ts b/src/cdk/testing/protractor/protractor-element.ts
index 1f3af90e7519..9caf06699ffe 100644
--- a/src/cdk/testing/protractor/protractor-element.ts
+++ b/src/cdk/testing/protractor/protractor-element.ts
@@ -207,7 +207,11 @@ export class ProtractorElement implements TestElement {
   async setContenteditableValue(value: string): Promise<void> {
     const contenteditableAttr = await this.getAttribute('contenteditable');
 
-    if (contenteditableAttr !== '' && contenteditableAttr !== 'true') {
+    if (
+      contenteditableAttr !== '' &&
+      contenteditableAttr !== 'true' &&
+      contenteditableAttr !== 'plaintext-only'
+    ) {
       throw new Error('setContenteditableValue can only be called on a `contenteditable` element.');
     }
 
diff --git a/src/cdk/testing/selenium-webdriver/selenium-web-driver-element.ts b/src/cdk/testing/selenium-webdriver/selenium-web-driver-element.ts
index 93698d5d3aa2..72b10d1e3db8 100644
--- a/src/cdk/testing/selenium-webdriver/selenium-web-driver-element.ts
+++ b/src/cdk/testing/selenium-webdriver/selenium-web-driver-element.ts
@@ -161,7 +161,11 @@ export class SeleniumWebDriverElement implements TestElement {
   async setContenteditableValue(value: string): Promise<void> {
     const contenteditableAttr = await this.getAttribute('contenteditable');
 
-    if (contenteditableAttr !== '' && contenteditableAttr !== 'true') {
+    if (
+      contenteditableAttr !== '' &&
+      contenteditableAttr !== 'true' &&
+      contenteditableAttr !== 'plaintext-only'
+    ) {
       throw new Error('setContenteditableValue can only be called on a `contenteditable` element.');
     }
 
diff --git a/src/cdk/testing/testbed/fake-events/dispatch-events.ts b/src/cdk/testing/testbed/fake-events/dispatch-events.ts
index 3f0ca70569a4..b2cd3e9ae0df 100644
--- a/src/cdk/testing/testbed/fake-events/dispatch-events.ts
+++ b/src/cdk/testing/testbed/fake-events/dispatch-events.ts
@@ -43,8 +43,9 @@ export function dispatchKeyboardEvent(
   keyCode?: number,
   key?: string,
   modifiers?: ModifierKeys,
+  code?: string,
 ): KeyboardEvent {
-  return dispatchEvent(node, createKeyboardEvent(type, keyCode, key, modifiers));
+  return dispatchEvent(node, createKeyboardEvent(type, keyCode, key, modifiers, code));
 }
 
 /**
diff --git a/src/cdk/testing/testbed/fake-events/event-objects.ts b/src/cdk/testing/testbed/fake-events/event-objects.ts
index 6826f762affa..4329926a3e57 100644
--- a/src/cdk/testing/testbed/fake-events/event-objects.ts
+++ b/src/cdk/testing/testbed/fake-events/event-objects.ts
@@ -133,18 +133,20 @@ export function createKeyboardEvent(
   keyCode: number = 0,
   key: string = '',
   modifiers: ModifierKeys = {},
+  code: string = '',
 ) {
   return new KeyboardEvent(type, {
     bubbles: true,
     cancelable: true,
     composed: true, // Required for shadow DOM events.
     view: window,
-    keyCode: keyCode,
-    key: key,
+    keyCode,
+    key,
     shiftKey: modifiers.shift,
     metaKey: modifiers.meta,
     altKey: modifiers.alt,
     ctrlKey: modifiers.control,
+    code,
   });
 }
 
diff --git a/src/cdk/testing/testbed/fake-events/type-in-element.ts b/src/cdk/testing/testbed/fake-events/type-in-element.ts
index 3efc932d48b0..480c269c4c63 100644
--- a/src/cdk/testing/testbed/fake-events/type-in-element.ts
+++ b/src/cdk/testing/testbed/fake-events/type-in-element.ts
@@ -22,6 +22,50 @@ const incrementalInputTypes = new Set([
   'url',
 ]);
 
+/**
+ * Manual mapping of some common characters to their `code` in a keyboard event. Non-exhaustive, see
+ * the tables on MDN for more info: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
+ */
+const charsToCodes: Record<string, string> = {
+  ' ': 'Space',
+  '.': 'Period',
+  ',': 'Comma',
+  '`': 'Backquote',
+  '-': 'Minus',
+  '=': 'Equal',
+  '[': 'BracketLeft',
+  ']': 'BracketRight',
+  '\\': 'Backslash',
+  '/': 'Slash',
+  "'": 'Quote',
+  '"': 'Quote',
+  ';': 'Semicolon',
+};
+
+/**
+ * Determines the `KeyboardEvent.key` from a character. See #27034 and
+ * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
+ */
+function getKeyboardEventCode(char: string): string {
+  if (char.length !== 1) {
+    return '';
+  }
+
+  const charCode = char.charCodeAt(0);
+
+  // Key is a letter between a and z, uppercase or lowercase.
+  if ((charCode >= 97 && charCode <= 122) || (charCode >= 65 && charCode <= 90)) {
+    return `Key${char.toUpperCase()}`;
+  }
+
+  // Digits from 0 to 9.
+  if (48 <= charCode && charCode <= 57) {
+    return `Digit${char}`;
+  }
+
+  return charsToCodes[char] ?? '';
+}
+
 /**
  * Checks whether the given Element is a text input element.
  * @docs-private
@@ -60,7 +104,7 @@ export function typeInElement(
 export function typeInElement(element: HTMLElement, ...modifiersAndKeys: any[]) {
   const first = modifiersAndKeys[0];
   let modifiers: ModifierKeys;
-  let rest: (string | {keyCode?: number; key?: string})[];
+  let rest: (string | {keyCode?: number; key?: string; code?: string})[];
   if (
     first !== undefined &&
     typeof first !== 'string' &&
@@ -75,10 +119,14 @@ export function typeInElement(element: HTMLElement, ...modifiersAndKeys: any[])
   }
   const isInput = isTextInput(element);
   const inputType = element.getAttribute('type') || 'text';
-  const keys: {keyCode?: number; key?: string}[] = rest
+  const keys: {keyCode?: number; key?: string; code?: string}[] = rest
     .map(k =>
       typeof k === 'string'
-        ? k.split('').map(c => ({keyCode: c.toUpperCase().charCodeAt(0), key: c}))
+        ? k.split('').map(c => ({
+            keyCode: c.toUpperCase().charCodeAt(0),
+            key: c,
+            code: getKeyboardEventCode(c),
+          }))
         : [k],
     )
     .reduce((arr, k) => arr.concat(k), []);
@@ -109,15 +157,15 @@ export function typeInElement(element: HTMLElement, ...modifiersAndKeys: any[])
   }
 
   for (const key of keys) {
-    dispatchKeyboardEvent(element, 'keydown', key.keyCode, key.key, modifiers);
-    dispatchKeyboardEvent(element, 'keypress', key.keyCode, key.key, modifiers);
+    dispatchKeyboardEvent(element, 'keydown', key.keyCode, key.key, modifiers, key.code);
+    dispatchKeyboardEvent(element, 'keypress', key.keyCode, key.key, modifiers, key.code);
     if (isInput && key.key && key.key.length === 1) {
       if (enterValueIncrementally) {
         (element as HTMLInputElement | HTMLTextAreaElement).value += key.key;
         dispatchFakeEvent(element, 'input');
       }
     }
-    dispatchKeyboardEvent(element, 'keyup', key.keyCode, key.key, modifiers);
+    dispatchKeyboardEvent(element, 'keyup', key.keyCode, key.key, modifiers, key.code);
   }
 
   // Since we weren't dispatching `input` events while sending the keys, we have to do it now.
diff --git a/src/cdk/testing/testbed/unit-test-element.ts b/src/cdk/testing/testbed/unit-test-element.ts
index 235ca43c5e07..0860a12e234c 100644
--- a/src/cdk/testing/testbed/unit-test-element.ts
+++ b/src/cdk/testing/testbed/unit-test-element.ts
@@ -31,37 +31,37 @@ import {
 
 /** Maps `TestKey` constants to the `keyCode` and `key` values used by native browser events. */
 const keyMap = {
-  [TestKey.BACKSPACE]: {keyCode: keyCodes.BACKSPACE, key: 'Backspace'},
-  [TestKey.TAB]: {keyCode: keyCodes.TAB, key: 'Tab'},
-  [TestKey.ENTER]: {keyCode: keyCodes.ENTER, key: 'Enter'},
-  [TestKey.SHIFT]: {keyCode: keyCodes.SHIFT, key: 'Shift'},
-  [TestKey.CONTROL]: {keyCode: keyCodes.CONTROL, key: 'Control'},
-  [TestKey.ALT]: {keyCode: keyCodes.ALT, key: 'Alt'},
-  [TestKey.ESCAPE]: {keyCode: keyCodes.ESCAPE, key: 'Escape'},
-  [TestKey.PAGE_UP]: {keyCode: keyCodes.PAGE_UP, key: 'PageUp'},
-  [TestKey.PAGE_DOWN]: {keyCode: keyCodes.PAGE_DOWN, key: 'PageDown'},
-  [TestKey.END]: {keyCode: keyCodes.END, key: 'End'},
-  [TestKey.HOME]: {keyCode: keyCodes.HOME, key: 'Home'},
-  [TestKey.LEFT_ARROW]: {keyCode: keyCodes.LEFT_ARROW, key: 'ArrowLeft'},
-  [TestKey.UP_ARROW]: {keyCode: keyCodes.UP_ARROW, key: 'ArrowUp'},
-  [TestKey.RIGHT_ARROW]: {keyCode: keyCodes.RIGHT_ARROW, key: 'ArrowRight'},
-  [TestKey.DOWN_ARROW]: {keyCode: keyCodes.DOWN_ARROW, key: 'ArrowDown'},
-  [TestKey.INSERT]: {keyCode: keyCodes.INSERT, key: 'Insert'},
-  [TestKey.DELETE]: {keyCode: keyCodes.DELETE, key: 'Delete'},
-  [TestKey.F1]: {keyCode: keyCodes.F1, key: 'F1'},
-  [TestKey.F2]: {keyCode: keyCodes.F2, key: 'F2'},
-  [TestKey.F3]: {keyCode: keyCodes.F3, key: 'F3'},
-  [TestKey.F4]: {keyCode: keyCodes.F4, key: 'F4'},
-  [TestKey.F5]: {keyCode: keyCodes.F5, key: 'F5'},
-  [TestKey.F6]: {keyCode: keyCodes.F6, key: 'F6'},
-  [TestKey.F7]: {keyCode: keyCodes.F7, key: 'F7'},
-  [TestKey.F8]: {keyCode: keyCodes.F8, key: 'F8'},
-  [TestKey.F9]: {keyCode: keyCodes.F9, key: 'F9'},
-  [TestKey.F10]: {keyCode: keyCodes.F10, key: 'F10'},
-  [TestKey.F11]: {keyCode: keyCodes.F11, key: 'F11'},
-  [TestKey.F12]: {keyCode: keyCodes.F12, key: 'F12'},
-  [TestKey.META]: {keyCode: keyCodes.META, key: 'Meta'},
-  [TestKey.COMMA]: {keyCode: keyCodes.COMMA, key: ','},
+  [TestKey.BACKSPACE]: {keyCode: keyCodes.BACKSPACE, key: 'Backspace', code: 'Backspace'},
+  [TestKey.TAB]: {keyCode: keyCodes.TAB, key: 'Tab', code: 'Tab'},
+  [TestKey.ENTER]: {keyCode: keyCodes.ENTER, key: 'Enter', code: 'Enter'},
+  [TestKey.SHIFT]: {keyCode: keyCodes.SHIFT, key: 'Shift', code: 'ShiftLeft'},
+  [TestKey.CONTROL]: {keyCode: keyCodes.CONTROL, key: 'Control', code: 'ControlLeft'},
+  [TestKey.ALT]: {keyCode: keyCodes.ALT, key: 'Alt', code: 'AltLeft'},
+  [TestKey.ESCAPE]: {keyCode: keyCodes.ESCAPE, key: 'Escape', code: 'Escape'},
+  [TestKey.PAGE_UP]: {keyCode: keyCodes.PAGE_UP, key: 'PageUp', code: 'PageUp'},
+  [TestKey.PAGE_DOWN]: {keyCode: keyCodes.PAGE_DOWN, key: 'PageDown', code: 'PageDown'},
+  [TestKey.END]: {keyCode: keyCodes.END, key: 'End', code: 'End'},
+  [TestKey.HOME]: {keyCode: keyCodes.HOME, key: 'Home', code: 'Home'},
+  [TestKey.LEFT_ARROW]: {keyCode: keyCodes.LEFT_ARROW, key: 'ArrowLeft', code: 'ArrowLeft'},
+  [TestKey.UP_ARROW]: {keyCode: keyCodes.UP_ARROW, key: 'ArrowUp', code: 'ArrowUp'},
+  [TestKey.RIGHT_ARROW]: {keyCode: keyCodes.RIGHT_ARROW, key: 'ArrowRight', code: 'ArrowRight'},
+  [TestKey.DOWN_ARROW]: {keyCode: keyCodes.DOWN_ARROW, key: 'ArrowDown', code: 'ArrowDown'},
+  [TestKey.INSERT]: {keyCode: keyCodes.INSERT, key: 'Insert', code: 'Insert'},
+  [TestKey.DELETE]: {keyCode: keyCodes.DELETE, key: 'Delete', code: 'Delete'},
+  [TestKey.F1]: {keyCode: keyCodes.F1, key: 'F1', code: 'F1'},
+  [TestKey.F2]: {keyCode: keyCodes.F2, key: 'F2', code: 'F2'},
+  [TestKey.F3]: {keyCode: keyCodes.F3, key: 'F3', code: 'F3'},
+  [TestKey.F4]: {keyCode: keyCodes.F4, key: 'F4', code: 'F4'},
+  [TestKey.F5]: {keyCode: keyCodes.F5, key: 'F5', code: 'F5'},
+  [TestKey.F6]: {keyCode: keyCodes.F6, key: 'F6', code: 'F6'},
+  [TestKey.F7]: {keyCode: keyCodes.F7, key: 'F7', code: 'F7'},
+  [TestKey.F8]: {keyCode: keyCodes.F8, key: 'F8', code: 'F8'},
+  [TestKey.F9]: {keyCode: keyCodes.F9, key: 'F9', code: 'F9'},
+  [TestKey.F10]: {keyCode: keyCodes.F10, key: 'F10', code: 'F10'},
+  [TestKey.F11]: {keyCode: keyCodes.F11, key: 'F11', code: 'F11'},
+  [TestKey.F12]: {keyCode: keyCodes.F12, key: 'F12', code: 'F12'},
+  [TestKey.META]: {keyCode: keyCodes.META, key: 'Meta', code: 'MetaLeft'},
+  [TestKey.COMMA]: {keyCode: keyCodes.COMMA, key: ',', code: 'Comma'},
 };
 
 /** A `TestElement` implementation for unit tests. */
@@ -196,7 +196,11 @@ export class UnitTestElement implements TestElement {
   async setContenteditableValue(value: string): Promise<void> {
     const contenteditableAttr = await this.getAttribute('contenteditable');
 
-    if (contenteditableAttr !== '' && contenteditableAttr !== 'true') {
+    if (
+      contenteditableAttr !== '' &&
+      contenteditableAttr !== 'true' &&
+      contenteditableAttr !== 'plaintext-only'
+    ) {
       throw new Error('setContenteditableValue can only be called on a `contenteditable` element.');
     }
 
diff --git a/src/cdk/testing/tests/cross-environment.spec.ts b/src/cdk/testing/tests/cross-environment.spec.ts
index 1dc29256ee4d..661732f065b0 100644
--- a/src/cdk/testing/tests/cross-environment.spec.ts
+++ b/src/cdk/testing/tests/cross-environment.spec.ts
@@ -204,15 +204,15 @@ export function crossEnvironmentSpecs(
     });
 
     it('should send enter key', async () => {
-      const specialKey = await harness.specaialKey();
+      const specialKey = await harness.specialKey();
       await harness.sendEnter();
-      expect(await specialKey.text()).toBe('enter');
+      expect(await specialKey.text()).toBe('Enter|Enter');
     });
 
     it('should send alt+j key', async () => {
-      const specialKey = await harness.specaialKey();
+      const specialKey = await harness.specialKey();
       await harness.sendAltJ();
-      expect(await specialKey.text()).toBe('alt-j');
+      expect(await specialKey.text()).toBe('alt-j|KeyJ');
     });
 
     it('should load required harness with ancestor selector restriction', async () => {
diff --git a/src/cdk/testing/tests/harnesses/main-component-harness.ts b/src/cdk/testing/tests/harnesses/main-component-harness.ts
index 3ec3a364c927..71d516ee5a28 100644
--- a/src/cdk/testing/tests/harnesses/main-component-harness.ts
+++ b/src/cdk/testing/tests/harnesses/main-component-harness.ts
@@ -68,7 +68,7 @@ export class MainComponentHarness extends ComponentHarness {
     SubComponentHarness.with({title: 'List of test tools', itemCount: 4}),
   );
   readonly lastList = this.locatorFor(SubComponentHarness.with({selector: ':last-child'}));
-  readonly specaialKey = this.locatorFor('.special-key');
+  readonly specialKey = this.locatorFor('.special-key');
 
   readonly requiredAncestorRestrictedSubcomponent = this.locatorFor(
     SubComponentHarness.with({ancestor: '.other'}),
diff --git a/src/cdk/testing/tests/test-main-component.ts b/src/cdk/testing/tests/test-main-component.ts
index 117e34a9c2a7..2881127c673b 100644
--- a/src/cdk/testing/tests/test-main-component.ts
+++ b/src/cdk/testing/tests/test-main-component.ts
@@ -93,10 +93,10 @@ export class TestMainComponent implements OnDestroy {
 
   onKeyDown(event: KeyboardEvent) {
     if (event.keyCode === ENTER && event.key === 'Enter') {
-      this.specialKey = 'enter';
+      this.specialKey = `Enter|${event.code}`;
     }
     if (event.key === 'j' && event.altKey) {
-      this.specialKey = 'alt-j';
+      this.specialKey = `alt-j|${event.code}`;
     }
   }
 
diff --git a/src/cdk/text-field/autofill.spec.ts b/src/cdk/text-field/autofill.spec.ts
index 85d21d707a32..cb9f2965e7e6 100644
--- a/src/cdk/text-field/autofill.spec.ts
+++ b/src/cdk/text-field/autofill.spec.ts
@@ -204,7 +204,6 @@ describe('cdkAutofill', () => {
     <input #input2>
     <input #input3>
   `,
-  standalone: true,
   imports: [TextFieldModule],
 })
 class Inputs {
@@ -216,7 +215,6 @@ class Inputs {
 
 @Component({
   template: `<input #input cdkAutofill>`,
-  standalone: true,
   imports: [TextFieldModule],
 })
 class InputWithCdkAutofilled {
diff --git a/src/cdk/text-field/autofill.zone.spec.ts b/src/cdk/text-field/autofill.zone.spec.ts
index 70882a2067b2..adec28c6ed1f 100644
--- a/src/cdk/text-field/autofill.zone.spec.ts
+++ b/src/cdk/text-field/autofill.zone.spec.ts
@@ -50,7 +50,6 @@ describe('AutofillMonitor Zone.js integration', () => {
       <input #input2>
       <input #input3>
     `,
-  standalone: true,
   imports: [TextFieldModule],
 })
 class Inputs {
diff --git a/src/cdk/text-field/autosize.spec.ts b/src/cdk/text-field/autosize.spec.ts
index df0efd201ba1..5e9ae7cb59ba 100644
--- a/src/cdk/text-field/autosize.spec.ts
+++ b/src/cdk/text-field/autosize.spec.ts
@@ -409,7 +409,6 @@ const textareaStyleReset = `
     <textarea cdkTextareaAutosize [cdkAutosizeMinRows]="minRows" [cdkAutosizeMaxRows]="maxRows"
         #autosize="cdkTextareaAutosize" [placeholder]="placeholder">{{content}}</textarea>`,
   styles: textareaStyleReset,
-  standalone: true,
   imports: [FormsModule, TextFieldModule],
 })
 class AutosizeTextAreaWithContent {
@@ -423,7 +422,6 @@ class AutosizeTextAreaWithContent {
 @Component({
   template: `<textarea cdkTextareaAutosize [value]="value"></textarea>`,
   styles: textareaStyleReset,
-  standalone: true,
   imports: [FormsModule, TextFieldModule],
 })
 class AutosizeTextAreaWithValue {
@@ -433,7 +431,6 @@ class AutosizeTextAreaWithValue {
 @Component({
   template: `<textarea cdkTextareaAutosize [(ngModel)]="model"></textarea>`,
   styles: textareaStyleReset,
-  standalone: true,
   imports: [FormsModule, TextFieldModule],
 })
 class AutosizeTextareaWithNgModel {
@@ -443,7 +440,6 @@ class AutosizeTextareaWithNgModel {
 @Component({
   template: `<textarea [cdkTextareaAutosize]="false">{{content}}</textarea>`,
   styles: textareaStyleReset,
-  standalone: true,
   imports: [FormsModule, TextFieldModule],
 })
 class AutosizeTextareaWithoutAutosize {
diff --git a/src/cdk/text-field/autosize.ts b/src/cdk/text-field/autosize.ts
index 98ee6616ee97..deb7d4ca057e 100644
--- a/src/cdk/text-field/autosize.ts
+++ b/src/cdk/text-field/autosize.ts
@@ -17,6 +17,7 @@ import {
   NgZone,
   booleanAttribute,
   inject,
+  Renderer2,
 } from '@angular/core';
 import {DOCUMENT} from '@angular/common';
 import {Platform} from '@angular/cdk/platform';
@@ -41,11 +42,13 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
   private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
   private _platform = inject(Platform);
   private _ngZone = inject(NgZone);
+  private _renderer = inject(Renderer2);
 
   /** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */
   private _previousValue?: string;
   private _initialHeight: string | undefined;
   private readonly _destroyed = new Subject<void>();
+  private _listenerCleanups: (() => void)[] | undefined;
 
   private _minRows: number;
   private _maxRows: number;
@@ -162,8 +165,10 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
           .pipe(auditTime(16), takeUntil(this._destroyed))
           .subscribe(() => this.resizeToFitContent(true));
 
-        this._textareaElement.addEventListener('focus', this._handleFocusEvent);
-        this._textareaElement.addEventListener('blur', this._handleFocusEvent);
+        this._listenerCleanups = [
+          this._renderer.listen(this._textareaElement, 'focus', this._handleFocusEvent),
+          this._renderer.listen(this._textareaElement, 'blur', this._handleFocusEvent),
+        ];
       });
 
       this._isViewInited = true;
@@ -172,8 +177,7 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
   }
 
   ngOnDestroy() {
-    this._textareaElement.removeEventListener('focus', this._handleFocusEvent);
-    this._textareaElement.removeEventListener('blur', this._handleFocusEvent);
+    this._listenerCleanups?.forEach(cleanup => cleanup());
     this._destroyed.next();
     this._destroyed.complete();
   }
diff --git a/src/cdk/tree/nested-node.ts b/src/cdk/tree/nested-node.ts
index 406c4d65e8bb..6d7a93b88264 100644
--- a/src/cdk/tree/nested-node.ts
+++ b/src/cdk/tree/nested-node.ts
@@ -12,7 +12,6 @@ import {
   IterableDiffer,
   IterableDiffers,
   OnDestroy,
-  OnInit,
   QueryList,
   inject,
 } from '@angular/core';
@@ -40,8 +39,9 @@ import {CdkTreeNode} from './tree';
 })
 export class CdkNestedTreeNode<T, K = T>
   extends CdkTreeNode<T, K>
-  implements AfterContentInit, OnDestroy, OnInit
+  implements AfterContentInit, OnDestroy
 {
+  protected override _type: 'flat' | 'nested' = 'nested';
   protected _differs = inject(IterableDiffers);
 
   /** Differ used to find the changes in the data provided by the data source. */
@@ -75,13 +75,6 @@ export class CdkNestedTreeNode<T, K = T>
       .subscribe(() => this.updateChildrenNodes());
   }
 
-  // This is a workaround for https://github.com/angular/angular/issues/23091
-  // In aot mode, the lifecycle hooks from parent class are not called.
-  override ngOnInit() {
-    this._tree._setNodeTypeIfUnset('nested');
-    super.ngOnInit();
-  }
-
   override ngOnDestroy() {
     this._clear();
     super.ngOnDestroy();
diff --git a/src/cdk/tree/tree.spec.ts b/src/cdk/tree/tree.spec.ts
index 96321621afb9..824ac56d5b61 100644
--- a/src/cdk/tree/tree.spec.ts
+++ b/src/cdk/tree/tree.spec.ts
@@ -1481,6 +1481,32 @@ describe('CdkTree', () => {
       .withContext(`expect an expanded node`)
       .toBe(1);
   });
+
+  it('should expand/collapse all nested nodes when calling expandAll/collapseAll', () => {
+    configureCdkTreeTestingModule([IsExpandableOrderingTest]);
+    const fixture = TestBed.createComponent(IsExpandableOrderingTest);
+    const component = fixture.componentInstance;
+    const data = fixture.componentInstance.dataSource;
+    treeElement = fixture.nativeElement.querySelector('cdk-tree');
+
+    data[0].children[0].children.push(new MinimalTestData('extra'));
+    data[0].children[0].children[0].children.push(new MinimalTestData('extra'));
+    fixture.detectChanges();
+
+    component.tree.expandAll();
+    fixture.detectChanges();
+    expect(getNodes(treeElement).map(n => n.getAttribute('aria-expanded'))).toEqual([
+      'true',
+      'true',
+      'true',
+      'true',
+    ]);
+
+    component.tree.collapseAll();
+    fixture.detectChanges();
+
+    expect(getNodes(treeElement).map(n => n.getAttribute('aria-expanded'))).toEqual(['false']);
+  });
 });
 
 export class TestData {
@@ -1698,10 +1724,6 @@ class SimpleCdkTreeApp {
 
   @ViewChild(CdkTree) tree: CdkTree<TestData>;
   @ViewChildren(CdkTreeNodePadding) paddingNodes: QueryList<CdkTreeNodePadding<TestData>>;
-
-  expandAll() {
-    this.tree.expandAll();
-  }
 }
 
 @Component({
diff --git a/src/cdk/tree/tree.ts b/src/cdk/tree/tree.ts
index 603f6b9dee3e..5a27c8bb479f 100644
--- a/src/cdk/tree/tree.ts
+++ b/src/cdk/tree/tree.ts
@@ -323,9 +323,17 @@ export class CdkTree<T, K = T>
    * This will be called by the first node that's rendered in order for the tree
    * to determine what data transformations are required.
    */
-  _setNodeTypeIfUnset(nodeType: 'flat' | 'nested') {
-    if (this._nodeType.value === null) {
-      this._nodeType.next(nodeType);
+  _setNodeTypeIfUnset(newType: 'flat' | 'nested') {
+    const currentType = this._nodeType.value;
+
+    if (currentType === null) {
+      this._nodeType.next(newType);
+    } else if ((typeof ngDevMode === 'undefined' || ngDevMode) && currentType !== newType) {
+      console.warn(
+        `Tree is using conflicting node types which can cause unexpected behavior. ` +
+          `Please use tree nodes of the same type (e.g. only flat or only nested). ` +
+          `Current node type: "${currentType}", new node type "${newType}".`,
+      );
     }
   }
 
@@ -708,10 +716,7 @@ export class CdkTree<T, K = T>
     if (this.treeControl) {
       this.treeControl.expandAll();
     } else if (this._expansionModel) {
-      const expansionModel = this._expansionModel;
-      expansionModel.select(
-        ...this._flattenedNodes.value.map(child => this._getExpansionKey(child)),
-      );
+      this._forEachExpansionKey(keys => this._expansionModel?.select(...keys));
     }
   }
 
@@ -720,10 +725,7 @@ export class CdkTree<T, K = T>
     if (this.treeControl) {
       this.treeControl.collapseAll();
     } else if (this._expansionModel) {
-      const expansionModel = this._expansionModel;
-      expansionModel.deselect(
-        ...this._flattenedNodes.value.map(child => this._getExpansionKey(child)),
-      );
+      this._forEachExpansionKey(keys => this._expansionModel?.deselect(...keys));
     }
   }
 
@@ -768,13 +770,7 @@ export class CdkTree<T, K = T>
           if (!expanded) {
             return [];
           }
-          return this._findChildrenByLevel(
-            levelAccessor,
-            flattenedNodes,
-
-            dataNode,
-            1,
-          );
+          return this._findChildrenByLevel(levelAccessor, flattenedNodes, dataNode, 1);
         }),
       );
     }
@@ -1145,6 +1141,28 @@ export class CdkTree<T, K = T>
       this._ariaSets.set(parentKey, group);
     }
   }
+
+  /** Invokes a callback with all node expansion keys. */
+  private _forEachExpansionKey(callback: (keys: K[]) => void) {
+    const toToggle: K[] = [];
+    const observables: Observable<T[]>[] = [];
+
+    this._nodes.value.forEach(node => {
+      toToggle.push(this._getExpansionKey(node.data));
+      observables.push(this._getDescendants(node.data));
+    });
+
+    if (observables.length > 0) {
+      combineLatest(observables)
+        .pipe(take(1), takeUntil(this._onDestroy))
+        .subscribe(results => {
+          results.forEach(inner => inner.forEach(r => toToggle.push(this._getExpansionKey(r))));
+          callback(toToggle);
+        });
+    } else {
+      callback(toToggle);
+    }
+  }
 }
 
 /**
@@ -1169,6 +1187,7 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
   _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
   protected _tree = inject<CdkTree<T, K>>(CdkTree);
   protected _tabindex: number | null = -1;
+  protected readonly _type: 'flat' | 'nested' = 'flat';
 
   /**
    * The role of the tree node.
@@ -1368,10 +1387,8 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
         map(() => this.isExpanded),
         distinctUntilChanged(),
       )
-      .subscribe(() => {
-        this._changeDetectorRef.markForCheck();
-      });
-    this._tree._setNodeTypeIfUnset('flat');
+      .subscribe(() => this._changeDetectorRef.markForCheck());
+    this._tree._setNodeTypeIfUnset(this._type);
     this._tree._registerNode(this);
   }
 
diff --git a/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.css b/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.css
index b6d1add83573..dc8419038f70 100644
--- a/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.css
+++ b/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.css
@@ -14,8 +14,14 @@
 
 .example-accordion-item-header {
   display: flex;
-  align-content: center;
+  align-items: center;
   justify-content: space-between;
+  width: 100%;
+  background: none;
+  border: none;
+  padding: 16px;
+  text-align: left;
+
 }
 
 .example-accordion-item-description {
@@ -23,7 +29,6 @@
   color: #999;
 }
 
-.example-accordion-item-header,
 .example-accordion-item-body {
   padding: 16px;
 }
diff --git a/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.html b/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.html
index 984d85a30d29..8a7759c6697d 100644
--- a/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.html
+++ b/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.html
@@ -1,31 +1,31 @@
 <cdk-accordion class="example-accordion">
   @for (item of items; track item; let index = $index) {
-    <cdk-accordion-item
-
-      #accordionItem="cdkAccordionItem"
-      class="example-accordion-item"
-      role="button"
+  <cdk-accordion-item #accordionItem="cdkAccordionItem" class="example-accordion-item">
+    <button
+      class="example-accordion-item-header"
+      (click)="accordionItem.toggle()"
       tabindex="0"
       [attr.id]="'accordion-header-' + index"
       [attr.aria-expanded]="accordionItem.expanded"
       [attr.aria-controls]="'accordion-body-' + index">
-      <div class="example-accordion-item-header" (click)="accordionItem.toggle()">
-        {{ item }}
-        <span class="example-accordion-item-description">
-          Click to {{ accordionItem.expanded ? 'close' : 'open' }}
-        </span>
-      </div>
-      <div
-        class="example-accordion-item-body"
-        role="region"
-        [style.display]="accordionItem.expanded ? '' : 'none'"
-        [attr.id]="'accordion-body-' + index"
-        [attr.aria-labelledby]="'accordion-header-' + index">
-        Lorem ipsum dolor, sit amet consectetur adipisicing elit. Perferendis
-        excepturi incidunt ipsum deleniti labore, tempore non nam doloribus blanditiis
-        veritatis illo autem iure aliquid ullam rem tenetur deserunt velit culpa?
-      </div>
-    </cdk-accordion-item>
+      {{ item }}
+      <span class="example-accordion-item-description">
+        Click to {{ accordionItem.expanded ? 'close' : 'open' }}
+      </span>
+    </button>
+    @if(accordionItem.expanded) {
+    <div
+      class="example-accordion-item-body"
+      role="region"
+      [style.display]="accordionItem.expanded ? '' : 'none'"
+      [attr.id]="'accordion-body-' + index"
+      [attr.aria-labelledby]="'accordion-header-' + index"
+    >
+      Lorem ipsum dolor, sit amet, consectetur adipisicing elit. Perferendis excepturi incidunt ipsum
+      deleniti labore, tempore non nam doloribus blanditiis veritatis illo autem iure aliquid ullam
+      rem tenetur deserunt velit culpa?
+    </div>
+    }
+  </cdk-accordion-item>
   }
 </cdk-accordion>
-
diff --git a/src/components-examples/cdk/overlay/cdk-overlay-basic/cdk-overlay-basic-example.html b/src/components-examples/cdk/overlay/cdk-overlay-basic/cdk-overlay-basic-example.html
index 5ece34c61897..37fc8d128e14 100644
--- a/src/components-examples/cdk/overlay/cdk-overlay-basic/cdk-overlay-basic-example.html
+++ b/src/components-examples/cdk/overlay/cdk-overlay-basic/cdk-overlay-basic-example.html
@@ -8,6 +8,7 @@
   cdkConnectedOverlay
   [cdkConnectedOverlayOrigin]="trigger"
   [cdkConnectedOverlayOpen]="isOpen"
+  (detach)="isOpen = false"
 >
   <ul class="example-list">
     <li>Item 1</li>
diff --git a/src/components-examples/material/button/button-overview/button-overview-example.css b/src/components-examples/material/button/button-overview/button-overview-example.css
index 9e41b98fe605..0706c1b66c1d 100644
--- a/src/components-examples/material/button/button-overview/button-overview-example.css
+++ b/src/components-examples/material/button/button-overview/button-overview-example.css
@@ -27,5 +27,5 @@ section {
 .example-button-container {
   display: flex;
   justify-content: center;
-  width: 120px;
+  width: 140px;
 }
diff --git a/src/components-examples/material/form-field/form-field-custom-control/form-field-custom-control-example.ts b/src/components-examples/material/form-field/form-field-custom-control/form-field-custom-control-example.ts
index c3121f9503cf..8d47a9f778d6 100644
--- a/src/components-examples/material/form-field/form-field-custom-control/form-field-custom-control-example.ts
+++ b/src/components-examples/material/form-field/form-field-custom-control/form-field-custom-control-example.ts
@@ -173,6 +173,7 @@ export class MyTelInput implements ControlValueAccessor, MatFormFieldControl<MyT
       this._placeholder();
       this._required();
       this._disabled();
+      this._focused();
       // Propagate state changes.
       untracked(() => this.stateChanges.next());
     });
diff --git a/src/components-examples/material/select/index.ts b/src/components-examples/material/select/index.ts
index 698b773b35a5..594bd086b375 100644
--- a/src/components-examples/material/select/index.ts
+++ b/src/components-examples/material/select/index.ts
@@ -12,4 +12,5 @@ export {SelectResetExample} from './select-reset/select-reset-example';
 export {SelectValueBindingExample} from './select-value-binding/select-value-binding-example';
 export {SelectReactiveFormExample} from './select-reactive-form/select-reactive-form-example';
 export {SelectInitialValueExample} from './select-initial-value/select-initial-value-example';
+export {SelectSelectableNullExample} from './select-selectable-null/select-selectable-null-example';
 export {SelectHarnessExample} from './select-harness/select-harness-example';
diff --git a/src/components-examples/material/select/select-selectable-null/select-selectable-null-example.html b/src/components-examples/material/select/select-selectable-null/select-selectable-null-example.html
new file mode 100644
index 000000000000..a1bc2340a5c8
--- /dev/null
+++ b/src/components-examples/material/select/select-selectable-null/select-selectable-null-example.html
@@ -0,0 +1,19 @@
+<h4>mat-select allowing selection of nullable options</h4>
+<mat-form-field>
+  <mat-label>State</mat-label>
+  <mat-select [(ngModel)]="value" canSelectNullableOptions>
+    @for (option of options; track option) {
+      <mat-option [value]="option.value">{{option.label}}</mat-option>
+    }
+  </mat-select>
+</mat-form-field>
+
+<h4>mat-select with default configuration</h4>
+<mat-form-field>
+  <mat-label>State</mat-label>
+  <mat-select [(ngModel)]="value">
+    @for (option of options; track option) {
+      <mat-option [value]="option.value">{{option.label}}</mat-option>
+    }
+  </mat-select>
+</mat-form-field>
diff --git a/src/components-examples/material/select/select-selectable-null/select-selectable-null-example.ts b/src/components-examples/material/select/select-selectable-null/select-selectable-null-example.ts
new file mode 100644
index 000000000000..a5b29834cae1
--- /dev/null
+++ b/src/components-examples/material/select/select-selectable-null/select-selectable-null-example.ts
@@ -0,0 +1,21 @@
+import {Component} from '@angular/core';
+import {FormsModule} from '@angular/forms';
+import {MatInputModule} from '@angular/material/input';
+import {MatSelectModule} from '@angular/material/select';
+import {MatFormFieldModule} from '@angular/material/form-field';
+
+/** @title Select with selectable null options */
+@Component({
+  selector: 'select-selectable-null-example',
+  templateUrl: 'select-selectable-null-example.html',
+  imports: [MatFormFieldModule, MatSelectModule, MatInputModule, FormsModule],
+})
+export class SelectSelectableNullExample {
+  value: number | null = null;
+  options = [
+    {label: 'None', value: null},
+    {label: 'One', value: 1},
+    {label: 'Two', value: 2},
+    {label: 'Three', value: 3},
+  ];
+}
diff --git a/src/components-examples/material/sidenav/BUILD.bazel b/src/components-examples/material/sidenav/BUILD.bazel
index d27e9dd3b325..f2846cc92196 100644
--- a/src/components-examples/material/sidenav/BUILD.bazel
+++ b/src/components-examples/material/sidenav/BUILD.bazel
@@ -27,6 +27,7 @@ ng_module(
         "//src/material/toolbar",
         "@npm//@angular/forms",
         "@npm//@angular/platform-browser",
+        "@npm//@angular/router",
         "@npm//@types/jasmine",
     ],
 )
diff --git a/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.html b/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.html
index 4fbab4fc2719..cf7c57f17924 100644
--- a/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.html
+++ b/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.html
@@ -1,14 +1,14 @@
 @if (shouldRun) {
-  <div class="example-container" [class.example-is-mobile]="mobileQuery.matches">
+  <div class="example-container" [class.example-is-mobile]="isMobile()">
     <mat-toolbar class="example-toolbar">
       <button mat-icon-button (click)="snav.toggle()"><mat-icon>menu</mat-icon></button>
       <h1 class="example-app-name">Responsive App</h1>
     </mat-toolbar>
 
     <mat-sidenav-container class="example-sidenav-container"
-                          [style.marginTop.px]="mobileQuery.matches ? 56 : 0">
-      <mat-sidenav #snav [mode]="mobileQuery.matches ? 'over' : 'side'"
-                  [fixedInViewport]="mobileQuery.matches" fixedTopGap="56">
+                          [style.marginTop.px]="isMobile() ? 56 : 0">
+      <mat-sidenav #snav [mode]="isMobile() ? 'over' : 'side'"
+                  [fixedInViewport]="isMobile()" fixedTopGap="56">
         <mat-nav-list>
           @for (nav of fillerNav; track nav) {
             <a mat-list-item routerLink=".">{{nav}}</a>
diff --git a/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.ts b/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.ts
index ae1c85a7a1bf..a10511604986 100644
--- a/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.ts
+++ b/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.ts
@@ -1,24 +1,30 @@
 import {MediaMatcher} from '@angular/cdk/layout';
-import {ChangeDetectorRef, Component, OnDestroy, inject} from '@angular/core';
+import {Component, OnDestroy, inject, signal} from '@angular/core';
 import {MatListModule} from '@angular/material/list';
 import {MatSidenavModule} from '@angular/material/sidenav';
 import {MatIconModule} from '@angular/material/icon';
 import {MatButtonModule} from '@angular/material/button';
 import {MatToolbarModule} from '@angular/material/toolbar';
+import {RouterLink} from '@angular/router';
 
 /** @title Responsive sidenav */
 @Component({
   selector: 'sidenav-responsive-example',
   templateUrl: 'sidenav-responsive-example.html',
   styleUrl: 'sidenav-responsive-example.css',
-  imports: [MatToolbarModule, MatButtonModule, MatIconModule, MatSidenavModule, MatListModule],
+  imports: [
+    MatToolbarModule,
+    MatButtonModule,
+    MatIconModule,
+    MatSidenavModule,
+    MatListModule,
+    RouterLink,
+  ],
 })
 export class SidenavResponsiveExample implements OnDestroy {
-  mobileQuery: MediaQueryList;
+  protected readonly fillerNav = Array.from({length: 50}, (_, i) => `Nav Item ${i + 1}`);
 
-  fillerNav = Array.from({length: 50}, (_, i) => `Nav Item ${i + 1}`);
-
-  fillerContent = Array.from(
+  protected readonly fillerContent = Array.from(
     {length: 50},
     () =>
       `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
@@ -28,20 +34,25 @@ export class SidenavResponsiveExample implements OnDestroy {
        cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`,
   );
 
-  private _mobileQueryListener: () => void;
+  protected readonly isMobile = signal(true);
+
+  private readonly _mobileQuery: MediaQueryList;
+  private readonly _mobileQueryListener: () => void;
 
   constructor() {
-    const changeDetectorRef = inject(ChangeDetectorRef);
     const media = inject(MediaMatcher);
 
-    this.mobileQuery = media.matchMedia('(max-width: 600px)');
-    this._mobileQueryListener = () => changeDetectorRef.detectChanges();
-    this.mobileQuery.addListener(this._mobileQueryListener);
+    this._mobileQuery = media.matchMedia('(max-width: 600px)');
+    this.isMobile.set(this._mobileQuery.matches);
+    this._mobileQueryListener = () => this.isMobile.set(this._mobileQuery.matches);
+    this._mobileQuery.addEventListener('change', this._mobileQueryListener);
   }
 
   ngOnDestroy(): void {
-    this.mobileQuery.removeListener(this._mobileQueryListener);
+    this._mobileQuery.removeEventListener('change', this._mobileQueryListener);
   }
 
-  shouldRun = /(^|.)(stackblitz|webcontainer).(io|com)$/.test(window.location.host);
+  protected readonly shouldRun = /(^|.)(stackblitz|webcontainer).(io|com)$/.test(
+    window.location.host,
+  );
 }
diff --git a/src/components-examples/material/tabs/index.ts b/src/components-examples/material/tabs/index.ts
index 5e64e11dc4e7..8adb7b40e8e5 100644
--- a/src/components-examples/material/tabs/index.ts
+++ b/src/components-examples/material/tabs/index.ts
@@ -4,13 +4,12 @@ export {TabGroupAsyncExample} from './tab-group-async/tab-group-async-example';
 export {TabGroupBasicExample} from './tab-group-basic/tab-group-basic-example';
 export {TabGroupCustomLabelExample} from './tab-group-custom-label/tab-group-custom-label-example';
 export {TabGroupDynamicHeightExample} from './tab-group-dynamic-height/tab-group-dynamic-height-example';
-export {TabGroupHarnessExample} from './tab-group-harness/tab-group-harness-example';
 export {TabGroupDynamicExample} from './tab-group-dynamic/tab-group-dynamic-example';
+export {TabGroupHarnessExample} from './tab-group-harness/tab-group-harness-example';
 export {TabGroupHeaderBelowExample} from './tab-group-header-below/tab-group-header-below-example';
+export {TabGroupInkBarExample} from './tab-group-ink-bar/tab-group-ink-bar-example';
 export {TabGroupLazyLoadedExample} from './tab-group-lazy-loaded/tab-group-lazy-loaded-example';
+export {TabGroupPaginatedExample} from './tab-group-paginated/tab-group-paginated-example';
 export {TabGroupPreserveContentExample} from './tab-group-preserve-content/tab-group-preserve-content-example';
 export {TabGroupStretchedExample} from './tab-group-stretched/tab-group-stretched-example';
 export {TabNavBarBasicExample} from './tab-nav-bar-basic/tab-nav-bar-basic-example';
-export {TabGroupPaginatedExample} from './tab-group-paginated/tab-group-paginated-example';
-export {TabGroupInvertedExample} from './tab-group-inverted/tab-group-inverted-example';
-export {TabGroupInkBarExample} from './tab-group-ink-bar/tab-group-ink-bar-example';
diff --git a/src/components-examples/material/tabs/tab-group-header-below/tab-group-header-below-example.ts b/src/components-examples/material/tabs/tab-group-header-below/tab-group-header-below-example.ts
index 86c32b41f047..359af3eb24f3 100644
--- a/src/components-examples/material/tabs/tab-group-header-below/tab-group-header-below-example.ts
+++ b/src/components-examples/material/tabs/tab-group-header-below/tab-group-header-below-example.ts
@@ -2,7 +2,7 @@ import {Component} from '@angular/core';
 import {MatTabsModule} from '@angular/material/tabs';
 
 /**
- * @title Tab group with the headers on the bottom
+ * @title Tab group with headers below the content
  */
 @Component({
   selector: 'tab-group-header-below-example',
diff --git a/src/components-examples/material/tabs/tab-group-inverted/tab-group-inverted-example.html b/src/components-examples/material/tabs/tab-group-inverted/tab-group-inverted-example.html
deleted file mode 100644
index ad6c1dcbf521..000000000000
--- a/src/components-examples/material/tabs/tab-group-inverted/tab-group-inverted-example.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<mat-tab-group headerPosition="below">
-  <mat-tab label="First">Content 1</mat-tab>
-  <mat-tab label="Second">Content 2</mat-tab>
-  <mat-tab label="Third">Content 3</mat-tab>
-</mat-tab-group>
\ No newline at end of file
diff --git a/src/components-examples/material/tabs/tab-group-inverted/tab-group-inverted-example.ts b/src/components-examples/material/tabs/tab-group-inverted/tab-group-inverted-example.ts
deleted file mode 100644
index 01983ea46bfe..000000000000
--- a/src/components-examples/material/tabs/tab-group-inverted/tab-group-inverted-example.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import {Component} from '@angular/core';
-import {MatTabsModule} from '@angular/material/tabs';
-
-/**
- * @title Tab group with inverted tabs
- */
-@Component({
-  selector: 'tab-group-inverted-example',
-  templateUrl: 'tab-group-inverted-example.html',
-  imports: [MatTabsModule],
-})
-export class TabGroupInvertedExample {}
diff --git a/src/components-examples/material/timepicker/BUILD.bazel b/src/components-examples/material/timepicker/BUILD.bazel
index 6743551b16cf..09a215458152 100644
--- a/src/components-examples/material/timepicker/BUILD.bazel
+++ b/src/components-examples/material/timepicker/BUILD.bazel
@@ -15,8 +15,15 @@ ng_module(
     deps = [
         "//src/cdk/testing",
         "//src/cdk/testing/testbed",
+        "//src/material/button",
+        "//src/material/datepicker",
+        "//src/material/form-field",
+        "//src/material/icon",
+        "//src/material/input",
         "//src/material/timepicker",
         "//src/material/timepicker/testing",
+        "@npm//@angular/common",
+        "@npm//@angular/forms",
         "@npm//@angular/platform-browser",
         "@npm//@types/jasmine",
     ],
diff --git a/src/components-examples/material/timepicker/index.ts b/src/components-examples/material/timepicker/index.ts
index f9d81a9e356d..196ce4b3ca88 100644
--- a/src/components-examples/material/timepicker/index.ts
+++ b/src/components-examples/material/timepicker/index.ts
@@ -1,2 +1,8 @@
 export {TimepickerOverviewExample} from './timepicker-overview/timepicker-overview-example';
+export {TimepickerFormsExample} from './timepicker-forms/timepicker-forms-example';
+export {TimepickerDatepickerIntegrationExample} from './timepicker-datepicker-integration/timepicker-datepicker-integration-example';
+export {TimepickerValidationExample} from './timepicker-validation/timepicker-validation-example';
+export {TimepickerOptionsExample} from './timepicker-options/timepicker-options-example';
+export {TimepickerCustomIconExample} from './timepicker-custom-icon/timepicker-custom-icon-example';
+export {TimepickerLocaleExample} from './timepicker-locale/timepicker-locale-example';
 export {TimepickerHarnessExample} from './timepicker-harness/timepicker-harness-example';
diff --git a/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.html b/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.html
new file mode 100644
index 000000000000..9b7906130981
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.html
@@ -0,0 +1,8 @@
+<mat-form-field>
+  <mat-label>Pick a time</mat-label>
+  <input matInput [matTimepicker]="picker">
+  <mat-timepicker-toggle matIconSuffix [for]="picker">
+    <mat-icon matTimepickerToggleIcon>keyboard_arrow_down</mat-icon>
+  </mat-timepicker-toggle>
+  <mat-timepicker #picker/>
+</mat-form-field>
diff --git a/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.ts b/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.ts
new file mode 100644
index 000000000000..4f356aade0c0
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.ts
@@ -0,0 +1,16 @@
+import {ChangeDetectionStrategy, Component} from '@angular/core';
+import {MatTimepickerModule} from '@angular/material/timepicker';
+import {MatIcon} from '@angular/material/icon';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {provideNativeDateAdapter} from '@angular/material/core';
+
+/** @title Timepicker with custom toggle icon */
+@Component({
+  selector: 'timepicker-custom-icon-example',
+  templateUrl: 'timepicker-custom-icon-example.html',
+  providers: [provideNativeDateAdapter()],
+  imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule, MatIcon],
+  changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class TimepickerCustomIconExample {}
diff --git a/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.css b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.css
new file mode 100644
index 000000000000..ea720f56d371
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.css
@@ -0,0 +1,3 @@
+mat-form-field {
+  margin-right: 16px;
+}
diff --git a/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.html b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.html
new file mode 100644
index 000000000000..b33725aa847a
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.html
@@ -0,0 +1,18 @@
+<mat-form-field>
+  <mat-label>Meeting date</mat-label>
+  <input matInput [matDatepicker]="datepicker" [(ngModel)]="value">
+  <mat-datepicker #datepicker/>
+  <mat-datepicker-toggle [for]="datepicker" matSuffix/>
+</mat-form-field>
+
+<mat-form-field>
+  <mat-label>Meeting time</mat-label>
+  <input matInput
+    [matTimepicker]="timepicker"
+    [(ngModel)]="value"
+    [ngModelOptions]="{updateOn: 'blur'}">
+  <mat-timepicker #timepicker/>
+  <mat-timepicker-toggle [for]="timepicker" matSuffix/>
+</mat-form-field>
+
+<p>Value: {{value}}</p>
diff --git a/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.ts b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.ts
new file mode 100644
index 000000000000..9583814a648c
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.ts
@@ -0,0 +1,26 @@
+import {ChangeDetectionStrategy, Component} from '@angular/core';
+import {FormsModule} from '@angular/forms';
+import {MatTimepickerModule} from '@angular/material/timepicker';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {provideNativeDateAdapter} from '@angular/material/core';
+import {MatDatepickerModule} from '@angular/material/datepicker';
+
+/** @title Timepicker integration with datepicker */
+@Component({
+  selector: 'timepicker-datepicker-integration-example',
+  templateUrl: 'timepicker-datepicker-integration-example.html',
+  styleUrl: './timepicker-datepicker-integration-example.css',
+  providers: [provideNativeDateAdapter()],
+  imports: [
+    MatFormFieldModule,
+    MatInputModule,
+    MatTimepickerModule,
+    MatDatepickerModule,
+    FormsModule,
+  ],
+  changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class TimepickerDatepickerIntegrationExample {
+  value: Date;
+}
diff --git a/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.html b/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.html
new file mode 100644
index 000000000000..cb110ede3ffd
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.html
@@ -0,0 +1,10 @@
+<mat-form-field>
+  <mat-label>Pick a time</mat-label>
+  <input matInput [formControl]="formControl" [matTimepicker]="picker">
+  <mat-timepicker-toggle matIconSuffix [for]="picker"/>
+  <mat-timepicker #picker/>
+</mat-form-field>
+
+<p>Value: {{formControl.value}}</p>
+<p>Touched: {{formControl.touched}}</p>
+<p>Dirty: {{formControl.dirty}}</p>
diff --git a/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.ts b/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.ts
new file mode 100644
index 000000000000..60ce8d3a6aec
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.ts
@@ -0,0 +1,24 @@
+import {ChangeDetectionStrategy, Component} from '@angular/core';
+import {FormControl, ReactiveFormsModule} from '@angular/forms';
+import {MatTimepickerModule} from '@angular/material/timepicker';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {provideNativeDateAdapter} from '@angular/material/core';
+
+/** @title Timepicker forms integration */
+@Component({
+  selector: 'timepicker-forms-example',
+  templateUrl: 'timepicker-forms-example.html',
+  providers: [provideNativeDateAdapter()],
+  imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule, ReactiveFormsModule],
+  changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class TimepickerFormsExample {
+  formControl: FormControl<Date | null>;
+
+  constructor() {
+    const initialValue = new Date();
+    initialValue.setHours(12, 30, 0);
+    this.formControl = new FormControl(initialValue);
+  }
+}
diff --git a/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.html b/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.html
new file mode 100644
index 000000000000..fae0e9b34de8
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.html
@@ -0,0 +1,8 @@
+<mat-form-field>
+  <mat-label>Pick a time</mat-label>
+  <input matInput [(ngModel)]="value" [matTimepicker]="picker">
+  <mat-timepicker-toggle matIconSuffix [for]="picker"/>
+  <mat-timepicker #picker/>
+</mat-form-field>
+
+<button mat-button (click)="switchLocale()">Dynamically switch to Bulgarian</button>
diff --git a/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.ts b/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.ts
new file mode 100644
index 000000000000..18217aebaada
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.ts
@@ -0,0 +1,24 @@
+import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
+import {FormsModule} from '@angular/forms';
+import {MatTimepickerModule} from '@angular/material/timepicker';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {DateAdapter, provideNativeDateAdapter} from '@angular/material/core';
+import {MatButtonModule} from '@angular/material/button';
+
+/** @title Timepicker with different locale */
+@Component({
+  selector: 'timepicker-locale-example',
+  templateUrl: 'timepicker-locale-example.html',
+  providers: [provideNativeDateAdapter()],
+  imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule, FormsModule, MatButtonModule],
+  changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class TimepickerLocaleExample {
+  private readonly _adapter = inject<DateAdapter<unknown, unknown>>(DateAdapter);
+  value = new Date(2024, 0, 1, 13, 45, 0);
+
+  protected switchLocale() {
+    this._adapter.setLocale('bg-BG');
+  }
+}
diff --git a/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.html b/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.html
new file mode 100644
index 000000000000..3641f89734e4
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.html
@@ -0,0 +1,30 @@
+<h3>Interval examples</h3>
+
+<div>
+  <mat-form-field>
+    <mat-label>Every 45 minutes</mat-label>
+    <input matInput [matTimepicker]="minutesPicker">
+    <mat-timepicker-toggle matIconSuffix [for]="minutesPicker"/>
+    <mat-timepicker interval="45min" #minutesPicker/>
+  </mat-form-field>
+</div>
+
+<div>
+  <mat-form-field>
+    <mat-label>Every 3.5 hours</mat-label>
+    <input matInput [matTimepicker]="hoursPicker">
+    <mat-timepicker-toggle matIconSuffix [for]="hoursPicker"/>
+    <mat-timepicker interval="3.5h" #hoursPicker/>
+  </mat-form-field>
+</div>
+
+<h3>Custom list of options</h3>
+
+<div>
+  <mat-form-field>
+    <mat-label>Pick a time of day</mat-label>
+    <input matInput [matTimepicker]="customPicker">
+    <mat-timepicker-toggle matIconSuffix [for]="customPicker"/>
+    <mat-timepicker [options]="customOptions" #customPicker/>
+  </mat-form-field>
+</div>
diff --git a/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.ts b/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.ts
new file mode 100644
index 000000000000..ae75213b1b55
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.ts
@@ -0,0 +1,21 @@
+import {ChangeDetectionStrategy, Component} from '@angular/core';
+import {MatTimepickerModule, MatTimepickerOption} from '@angular/material/timepicker';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {provideNativeDateAdapter} from '@angular/material/core';
+
+/** @title Timepicker options customization */
+@Component({
+  selector: 'timepicker-options-example',
+  templateUrl: 'timepicker-options-example.html',
+  providers: [provideNativeDateAdapter()],
+  imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule],
+  changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class TimepickerOptionsExample {
+  customOptions: MatTimepickerOption<Date>[] = [
+    {label: 'Morning', value: new Date(2024, 0, 1, 9, 0, 0)},
+    {label: 'Noon', value: new Date(2024, 0, 1, 12, 0, 0)},
+    {label: 'Evening', value: new Date(2024, 0, 1, 22, 0, 0)},
+  ];
+}
diff --git a/src/components-examples/material/timepicker/timepicker-overview/timepicker-overview-example.html b/src/components-examples/material/timepicker/timepicker-overview/timepicker-overview-example.html
index 9c7394525960..a8c3fb17bae9 100644
--- a/src/components-examples/material/timepicker/timepicker-overview/timepicker-overview-example.html
+++ b/src/components-examples/material/timepicker/timepicker-overview/timepicker-overview-example.html
@@ -1,6 +1,8 @@
 <mat-form-field>
   <mat-label>Pick a time</mat-label>
+<!-- #docregion minimum-setup -->
   <input matInput [matTimepicker]="picker">
   <mat-timepicker-toggle matIconSuffix [for]="picker"/>
   <mat-timepicker #picker/>
+<!-- #enddocregion minimum-setup -->
 </mat-form-field>
diff --git a/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.css b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.css
new file mode 100644
index 000000000000..55f74ff0a83f
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.css
@@ -0,0 +1,3 @@
+mat-form-field {
+  margin-bottom: 30px;
+}
diff --git a/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.html b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.html
new file mode 100644
index 000000000000..d1ed42c97a47
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.html
@@ -0,0 +1,26 @@
+<mat-form-field>
+  <mat-label>Pick a time</mat-label>
+  <input
+    matInput
+    [formControl]="formControl"
+    [matTimepicker]="picker"
+    matTimepickerMin="12:30"
+    matTimepickerMax="17:30">
+  <mat-timepicker-toggle matIconSuffix [for]="picker"/>
+  <mat-timepicker #picker/>
+
+  @if (formControl.errors?.['matTimepickerParse']) {
+    <mat-error>Value isn't a valid time</mat-error>
+  }
+
+  @if (formControl.errors?.['matTimepickerMin']) {
+    <mat-error>Value is too early</mat-error>
+  }
+
+  @if (formControl.errors?.['matTimepickerMax']) {
+    <mat-error>Value is too late</mat-error>
+  }
+</mat-form-field>
+
+<p>Enter a value before 12:30 PM or after 5:30 PM to see the errors</p>
+<p>Errors: {{formControl.errors | json}}</p>
diff --git a/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.ts b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.ts
new file mode 100644
index 000000000000..9702b1be034f
--- /dev/null
+++ b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.ts
@@ -0,0 +1,20 @@
+import {ChangeDetectionStrategy, Component} from '@angular/core';
+import {JsonPipe} from '@angular/common';
+import {FormControl, ReactiveFormsModule} from '@angular/forms';
+import {MatTimepickerModule} from '@angular/material/timepicker';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {provideNativeDateAdapter} from '@angular/material/core';
+
+/** @title Timepicker validation */
+@Component({
+  selector: 'timepicker-validation-example',
+  templateUrl: 'timepicker-validation-example.html',
+  styleUrl: './timepicker-validation-example.css',
+  providers: [provideNativeDateAdapter()],
+  imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule, ReactiveFormsModule, JsonPipe],
+  changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class TimepickerValidationExample {
+  formControl = new FormControl<Date | null>(null);
+}
diff --git a/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.css b/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.css
index 2d1a32aa5732..ff730a9522f0 100644
--- a/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.css
+++ b/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.css
@@ -21,6 +21,6 @@
  * Leaf nodes need to have padding so as to align with other non-leaf nodes
  * under the same parent.
  */
-.example-tree div[role=group] > .mat-tree-node {
+.example-tree div[role=group] > .mat-nested-tree-node {
   padding-left: 40px;
 }
diff --git a/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.html b/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.html
index c18934525142..2d68f780f514 100644
--- a/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.html
+++ b/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.html
@@ -2,9 +2,9 @@
   <!-- This is the tree node template for leaf nodes -->
   <!-- There is inline padding applied to this node using styles.
     This padding value depends on the mat-icon-button width. -->
-  <mat-tree-node *matTreeNodeDef="let node">
+  <mat-nested-tree-node *matTreeNodeDef="let node">
     {{node.name}}
-  </mat-tree-node>
+  </mat-nested-tree-node>
   <!-- This is the tree node template for expandable nodes -->
   <mat-nested-tree-node
       *matTreeNodeDef="let node; when: hasChild"
diff --git a/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.css b/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.css
index 2d1a32aa5732..ff730a9522f0 100644
--- a/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.css
+++ b/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.css
@@ -21,6 +21,6 @@
  * Leaf nodes need to have padding so as to align with other non-leaf nodes
  * under the same parent.
  */
-.example-tree div[role=group] > .mat-tree-node {
+.example-tree div[role=group] > .mat-nested-tree-node {
   padding-left: 40px;
 }
diff --git a/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.html b/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.html
index c827115b1680..93b8b82f2335 100644
--- a/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.html
+++ b/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.html
@@ -2,9 +2,9 @@
   <!-- This is the tree node template for leaf nodes -->
   <!-- There is inline padding applied to this node using styles.
     This padding value depends on the mat-icon-button width. -->
-  <mat-tree-node *matTreeNodeDef="let node">
+  <mat-nested-tree-node *matTreeNodeDef="let node">
     {{node.name}}
-  </mat-tree-node>
+  </mat-nested-tree-node>
   <!-- This is the tree node template for expandable nodes -->
   <mat-nested-tree-node
       *matTreeNodeDef="let node; when: hasChild"
diff --git a/src/dev-app/sidenav/sidenav-demo.ts b/src/dev-app/sidenav/sidenav-demo.ts
index d62f3fcc70be..e38e9d351602 100644
--- a/src/dev-app/sidenav/sidenav-demo.ts
+++ b/src/dev-app/sidenav/sidenav-demo.ts
@@ -22,7 +22,7 @@ import {MatToolbarModule} from '@angular/material/toolbar';
 })
 export class SidenavDemo {
   isLaunched = false;
-  fillerContent = Array(30);
+  fillerContent = Array.from({length: 30}, (_, index) => index);
   fixed = false;
   coverHeader = false;
   showHeader = false;
diff --git a/src/dev-app/tabs/tabs-demo.html b/src/dev-app/tabs/tabs-demo.html
index 20aed4baf36b..85fa2cae5b08 100644
--- a/src/dev-app/tabs/tabs-demo.html
+++ b/src/dev-app/tabs/tabs-demo.html
@@ -20,9 +20,7 @@ <h3>Tab navigation bar basic</h3>
 <tab-nav-bar-basic-example></tab-nav-bar-basic-example>
 <h3>Paginated Tabs</h3>
 <tab-group-paginated-example></tab-group-paginated-example>
-<h3>Inverted Tabs</h3>
-<tab-group-inverted-example></tab-group-inverted-example>
 <h3>Ink bar fit to content</h3>
 <tab-group-ink-bar-example></tab-group-ink-bar-example>
-<h3>Tab group with the headers on the bottom</h3>
+<h3>Tab group with headers below the content</h3>
 <tab-group-header-below-example></tab-group-header-below-example>
diff --git a/src/dev-app/tabs/tabs-demo.ts b/src/dev-app/tabs/tabs-demo.ts
index c0ee1e2ef83d..a9b3240010f3 100644
--- a/src/dev-app/tabs/tabs-demo.ts
+++ b/src/dev-app/tabs/tabs-demo.ts
@@ -16,7 +16,6 @@ import {
   TabGroupDynamicHeightExample,
   TabGroupHeaderBelowExample,
   TabGroupInkBarExample,
-  TabGroupInvertedExample,
   TabGroupLazyLoadedExample,
   TabGroupPaginatedExample,
   TabGroupStretchedExample,
@@ -30,7 +29,6 @@ import {MatTabsModule} from '@angular/material/tabs';
   templateUrl: 'tabs-demo.html',
   imports: [
     TabGroupInkBarExample,
-    TabGroupInvertedExample,
     TabGroupPaginatedExample,
     TabNavBarBasicExample,
     TabGroupStretchedExample,
diff --git a/src/dev-app/youtube-player/youtube-player-demo.html b/src/dev-app/youtube-player/youtube-player-demo.html
index 1f08254f95b6..4225e9f7bd9e 100644
--- a/src/dev-app/youtube-player/youtube-player-demo.html
+++ b/src/dev-app/youtube-player/youtube-player-demo.html
@@ -13,9 +13,11 @@ <h2>Basic Example</h2>
     <div class="demo-video-selection">
       <mat-checkbox [(ngModel)]="disableCookies">Disable cookies</mat-checkbox>
       <mat-checkbox [(ngModel)]="disablePlaceholder">Disable placeholder</mat-checkbox>
+      <mat-checkbox [(ngModel)]="startAt30s">Start at 30s</mat-checkbox>
     </div>
     <youtube-player [videoId]="selectedVideoId"
                     [playerVars]="playerVars"
+                    [startSeconds]="startAt30s ? 30 : 0"
                     [width]="videoWidth"
                     [height]="videoHeight"
                     [disableCookies]="disableCookies"
diff --git a/src/dev-app/youtube-player/youtube-player-demo.ts b/src/dev-app/youtube-player/youtube-player-demo.ts
index 0c1f52e404d6..a70864d23b37 100644
--- a/src/dev-app/youtube-player/youtube-player-demo.ts
+++ b/src/dev-app/youtube-player/youtube-player-demo.ts
@@ -94,6 +94,7 @@ export class YouTubePlayerDemo implements AfterViewInit, OnDestroy {
   videoHeight: number | undefined;
   disableCookies = false;
   disablePlaceholder = false;
+  startAt30s = false;
   placeholderQuality: PlaceholderImageQuality;
 
   constructor() {
diff --git a/src/google-maps/deprecated-map-marker-clusterer/deprecated-map-marker-clusterer.spec.ts b/src/google-maps/deprecated-map-marker-clusterer/deprecated-map-marker-clusterer.spec.ts
index 9b1d297b9536..2f4eb9f60821 100644
--- a/src/google-maps/deprecated-map-marker-clusterer/deprecated-map-marker-clusterer.spec.ts
+++ b/src/google-maps/deprecated-map-marker-clusterer/deprecated-map-marker-clusterer.spec.ts
@@ -342,7 +342,6 @@ describe('DeprecatedMapMarkerClusterer', () => {
       </deprecated-map-marker-clusterer>
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapMarker, DeprecatedMapMarkerClusterer],
 })
 class TestApp {
diff --git a/src/google-maps/google-map/google-map.spec.ts b/src/google-maps/google-map/google-map.spec.ts
index 5eef67bce344..d693c793286a 100644
--- a/src/google-maps/google-map/google-map.spec.ts
+++ b/src/google-maps/google-map/google-map.spec.ts
@@ -444,7 +444,6 @@ describe('GoogleMap', () => {
       (mapRightclick)="handleRightclick($event)"
       (mapInitialized)="mapInitializedSpy($event)" />
   `,
-  standalone: true,
   imports: [GoogleMap],
 })
 class TestApp {
diff --git a/src/google-maps/map-advanced-marker/README.md b/src/google-maps/map-advanced-marker/README.md
new file mode 100644
index 000000000000..4f2177219546
--- /dev/null
+++ b/src/google-maps/map-advanced-marker/README.md
@@ -0,0 +1,44 @@
+# MapAdvancedMarker
+
+The `MapAdvancedMarker` component wraps the [`google.maps.marker.AdvancedMarkerElement` class](https://developers.google.com/maps/documentation/javascript/reference/advanced-markers) from the Google Maps JavaScript API. The `MapAdvancedMarker` component displays a marker on the map when it is a content child of a `GoogleMap` component.
+
+**Note:** Use of `map-advanced-marker` requires a `google-map` with a valid `mapId`.
+
+## Example
+
+```typescript
+// google-map-demo.component.ts
+import {Component} from '@angular/core';
+import {GoogleMap, MapAdvancedMarker} from '@angular/google-maps';
+
+@Component({
+  selector: 'google-map-demo',
+  templateUrl: 'google-map-demo.html',
+  imports: [GoogleMap, MapAdvancedMarker],
+})
+export class GoogleMapDemo {
+  center: google.maps.LatLngLiteral = {lat: 24, lng: 12};
+  zoom = 4;
+  advancedMarkerOptions: google.maps.marker.AdvancedMarkerElementOptions = {gmpDraggable: false};
+  advancedMarkerPositions: google.maps.LatLngLiteral[] = [];
+
+  addAdvancedMarker(event: google.maps.MapMouseEvent) {
+    this.advancedMarkerPositions.push(event.latLng.toJSON());
+  }
+}
+```
+
+```html
+<!-- google-map-demo.component.html -->
+<google-map
+  mapId="yourMapId"
+  height="400px"
+  width="750px"
+  [center]="center"
+  [zoom]="zoom"
+  (mapClick)="addAdvancedMarker($event)">
+    @for (position of advancedMarkerPositions; track position) {
+      <map-advanced-marker [position]="position" [options]="advancedMarkerOptions" />
+    }
+</google-map>
+```
diff --git a/src/google-maps/map-advanced-marker/map-advanced-marker.spec.ts b/src/google-maps/map-advanced-marker/map-advanced-marker.spec.ts
index 47686bb860e7..2f6cf7acd71b 100644
--- a/src/google-maps/map-advanced-marker/map-advanced-marker.spec.ts
+++ b/src/google-maps/map-advanced-marker/map-advanced-marker.spec.ts
@@ -176,7 +176,6 @@ describe('MapAdvancedMarker', () => {
         [options]="options" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapAdvancedMarker],
 })
 class TestApp {
diff --git a/src/google-maps/map-bicycling-layer/map-bicycling-layer.spec.ts b/src/google-maps/map-bicycling-layer/map-bicycling-layer.spec.ts
index b090236e7cce..1832fdf8709d 100644
--- a/src/google-maps/map-bicycling-layer/map-bicycling-layer.spec.ts
+++ b/src/google-maps/map-bicycling-layer/map-bicycling-layer.spec.ts
@@ -42,7 +42,6 @@ describe('MapBicyclingLayer', () => {
       <map-bicycling-layer />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapBicyclingLayer],
 })
 class TestApp {}
diff --git a/src/google-maps/map-circle/map-circle.spec.ts b/src/google-maps/map-circle/map-circle.spec.ts
index d7cefaebf4c1..c92e9558049e 100644
--- a/src/google-maps/map-circle/map-circle.spec.ts
+++ b/src/google-maps/map-circle/map-circle.spec.ts
@@ -166,7 +166,6 @@ describe('MapCircle', () => {
         (circleClick)="handleClick()"
         (circleRightclick)="handleRightclick()" />
     </google-map>`,
-  standalone: true,
   imports: [GoogleMap, MapCircle],
 })
 class TestApp {
diff --git a/src/google-maps/map-directions-renderer/map-directions-renderer.spec.ts b/src/google-maps/map-directions-renderer/map-directions-renderer.spec.ts
index 83b9181db769..e0eeb5b9e589 100644
--- a/src/google-maps/map-directions-renderer/map-directions-renderer.spec.ts
+++ b/src/google-maps/map-directions-renderer/map-directions-renderer.spec.ts
@@ -136,7 +136,6 @@ describe('MapDirectionsRenderer', () => {
         (directionsChanged)="handleDirectionsChanged()" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapDirectionsRenderer],
 })
 class TestApp {
diff --git a/src/google-maps/map-ground-overlay/map-ground-overlay.spec.ts b/src/google-maps/map-ground-overlay/map-ground-overlay.spec.ts
index eb2e41c19055..373c8e6e1c55 100644
--- a/src/google-maps/map-ground-overlay/map-ground-overlay.spec.ts
+++ b/src/google-maps/map-ground-overlay/map-ground-overlay.spec.ts
@@ -168,7 +168,6 @@ describe('MapGroundOverlay', () => {
         (mapClick)="handleClick()" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapGroundOverlay],
 })
 class TestApp {
diff --git a/src/google-maps/map-heatmap-layer/map-heatmap-layer.spec.ts b/src/google-maps/map-heatmap-layer/map-heatmap-layer.spec.ts
index 21c57e35e8a6..17a13b021737 100644
--- a/src/google-maps/map-heatmap-layer/map-heatmap-layer.spec.ts
+++ b/src/google-maps/map-heatmap-layer/map-heatmap-layer.spec.ts
@@ -163,7 +163,6 @@ describe('MapHeatmapLayer', () => {
       <map-heatmap-layer [data]="data" [options]="options" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapHeatmapLayer],
 })
 class TestApp {
diff --git a/src/google-maps/map-info-window/map-info-window.spec.ts b/src/google-maps/map-info-window/map-info-window.spec.ts
index 82497407123c..9d5c4bad5412 100644
--- a/src/google-maps/map-info-window/map-info-window.spec.ts
+++ b/src/google-maps/map-info-window/map-info-window.spec.ts
@@ -258,7 +258,6 @@ describe('MapInfoWindow', () => {
       </map-info-window>
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapInfoWindow],
 })
 class TestApp {
diff --git a/src/google-maps/map-kml-layer/map-kml-layer.spec.ts b/src/google-maps/map-kml-layer/map-kml-layer.spec.ts
index 35491897b0e5..4f479b6dc1f2 100644
--- a/src/google-maps/map-kml-layer/map-kml-layer.spec.ts
+++ b/src/google-maps/map-kml-layer/map-kml-layer.spec.ts
@@ -154,7 +154,6 @@ describe('MapKmlLayer', () => {
         (statusChanged)="handleStatusChange()" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapKmlLayer],
 })
 class TestApp {
diff --git a/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts b/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts
index 01629f6ed952..0dfd6074a6a4 100644
--- a/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts
+++ b/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts
@@ -177,7 +177,6 @@ describe('MapMarkerClusterer', () => {
 
 @Component({
   selector: 'test-app',
-  standalone: true,
   imports: [GoogleMapsModule],
   template: `
     <google-map>
diff --git a/src/google-maps/map-marker/map-marker.spec.ts b/src/google-maps/map-marker/map-marker.spec.ts
index 3f0e102e10ea..de00b590e6d9 100644
--- a/src/google-maps/map-marker/map-marker.spec.ts
+++ b/src/google-maps/map-marker/map-marker.spec.ts
@@ -233,7 +233,6 @@ describe('MapMarker', () => {
         (positionChanged)="handlePositionChanged()" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapMarker],
 })
 class TestApp {
diff --git a/src/google-maps/map-polygon/map-polygon.spec.ts b/src/google-maps/map-polygon/map-polygon.spec.ts
index 09d4ec277f29..bf012834f116 100644
--- a/src/google-maps/map-polygon/map-polygon.spec.ts
+++ b/src/google-maps/map-polygon/map-polygon.spec.ts
@@ -157,7 +157,6 @@ describe('MapPolygon', () => {
       </map-polygon>
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapPolygon],
 })
 class TestApp {
diff --git a/src/google-maps/map-polyline/map-polyline.spec.ts b/src/google-maps/map-polyline/map-polyline.spec.ts
index 095be84dd9f1..a8a788e1a22e 100644
--- a/src/google-maps/map-polyline/map-polyline.spec.ts
+++ b/src/google-maps/map-polyline/map-polyline.spec.ts
@@ -157,7 +157,6 @@ describe('MapPolyline', () => {
         (polylineRightclick)="handleRightclick()" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapPolyline],
 })
 class TestApp {
diff --git a/src/google-maps/map-rectangle/map-rectangle.spec.ts b/src/google-maps/map-rectangle/map-rectangle.spec.ts
index 3ad2bf32a6fe..50cc24e83304 100644
--- a/src/google-maps/map-rectangle/map-rectangle.spec.ts
+++ b/src/google-maps/map-rectangle/map-rectangle.spec.ts
@@ -151,7 +151,6 @@ describe('MapRectangle', () => {
         (rectangleRightclick)="handleRightclick()" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapRectangle],
 })
 class TestApp {
diff --git a/src/google-maps/map-traffic-layer/map-traffic-layer.spec.ts b/src/google-maps/map-traffic-layer/map-traffic-layer.spec.ts
index a11bc123e3d6..9561b07ed911 100644
--- a/src/google-maps/map-traffic-layer/map-traffic-layer.spec.ts
+++ b/src/google-maps/map-traffic-layer/map-traffic-layer.spec.ts
@@ -44,7 +44,6 @@ describe('MapTrafficLayer', () => {
       <map-traffic-layer [autoRefresh]="autoRefresh" />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapTrafficLayer],
 })
 class TestApp {
diff --git a/src/google-maps/map-transit-layer/map-transit-layer.spec.ts b/src/google-maps/map-transit-layer/map-transit-layer.spec.ts
index 708821aa5b7d..19fcd60f67ba 100644
--- a/src/google-maps/map-transit-layer/map-transit-layer.spec.ts
+++ b/src/google-maps/map-transit-layer/map-transit-layer.spec.ts
@@ -43,7 +43,6 @@ describe('MapTransitLayer', () => {
       <map-transit-layer />
     </google-map>
   `,
-  standalone: true,
   imports: [GoogleMap, MapTransitLayer],
 })
 class TestApp {}
diff --git a/src/google-maps/schematics/ng-update/index.ts b/src/google-maps/schematics/ng-update/index.ts
index 9fcd69c841c0..d6834a4382dc 100644
--- a/src/google-maps/schematics/ng-update/index.ts
+++ b/src/google-maps/schematics/ng-update/index.ts
@@ -26,10 +26,14 @@ const DEPRECATED_CLASS_NAME = 'DeprecatedMapMarkerClusterer';
 export function updateToV19(): Rule {
   return tree => {
     tree.visit(path => {
+      if (path.includes('node_modules')) {
+        return;
+      }
+
       if (path.endsWith('.html')) {
-        const content = tree.readText(path);
+        const content = tree.read(path)?.toString();
 
-        if (content.includes('<' + TAG_NAME)) {
+        if (content && content.includes('<' + TAG_NAME)) {
           tree.overwrite(path, migrateHtml(content));
         }
       } else if (path.endsWith('.ts') && !path.endsWith('.d.ts')) {
@@ -48,13 +52,14 @@ function migrateHtml(content: string): string {
 
 /** Migrates a TypeScript file from the old tag and class names to the new ones. */
 function migrateTypeScript(path: Path, tree: Tree) {
-  const content = tree.readText(path);
+  const content = tree.read(path)?.toString();
 
   // Exit early if none of the symbols we're looking for are mentioned.
   if (
-    !content.includes('<' + TAG_NAME) &&
-    !content.includes(MODULE_NAME) &&
-    !content.includes(CLASS_NAME)
+    !content ||
+    (!content.includes('<' + TAG_NAME) &&
+      !content.includes(MODULE_NAME) &&
+      !content.includes(CLASS_NAME))
   ) {
     return;
   }
diff --git a/src/material-experimental/menubar/menubar-item.spec.ts b/src/material-experimental/menubar/menubar-item.spec.ts
index 40b610c24de7..cd76be6616e7 100644
--- a/src/material-experimental/menubar/menubar-item.spec.ts
+++ b/src/material-experimental/menubar/menubar-item.spec.ts
@@ -62,7 +62,6 @@ describe('MatMenuBarItem', () => {
       </div>
     </ng-template>
   `,
-  standalone: true,
   imports: [MatMenuBarModule, CdkMenuModule],
 })
 class SimpleMenuBarItem {
diff --git a/src/material-experimental/menubar/menubar.spec.ts b/src/material-experimental/menubar/menubar.spec.ts
index f690dd033e31..9adab6e6666a 100644
--- a/src/material-experimental/menubar/menubar.spec.ts
+++ b/src/material-experimental/menubar/menubar.spec.ts
@@ -55,7 +55,6 @@ describe('MatMenuBar', () => {
       <mat-menubar-item id="second"></mat-menubar-item>
     </mat-menubar>
   `,
-  standalone: true,
   imports: [MatMenuBarModule],
 })
 class SimpleMatMenuBar {
diff --git a/src/material-experimental/selection/selection-module.ts b/src/material-experimental/selection/selection-module.ts
index 866221834d45..af9c76e74ce8 100644
--- a/src/material-experimental/selection/selection-module.ts
+++ b/src/material-experimental/selection/selection-module.ts
@@ -8,7 +8,6 @@
 
 // TODO(yifange): Move the table-specific code to a separate module from the other selection
 // behaviors once we move it out of experimental.
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {MatTableModule} from '@angular/material/table';
 import {MatCheckboxModule} from '@angular/material/checkbox';
@@ -20,7 +19,6 @@ import {MatRowSelection} from './row-selection';
 
 @NgModule({
   imports: [
-    CommonModule,
     MatTableModule,
     MatCheckboxModule,
     MatSelectAll,
diff --git a/src/material-luxon-adapter/adapter/luxon-date-adapter.spec.ts b/src/material-luxon-adapter/adapter/luxon-date-adapter.spec.ts
index 12a4a95f81f3..5eed39517609 100644
--- a/src/material-luxon-adapter/adapter/luxon-date-adapter.spec.ts
+++ b/src/material-luxon-adapter/adapter/luxon-date-adapter.spec.ts
@@ -258,7 +258,8 @@ describe('LuxonDateAdapter', () => {
   });
 
   it('should get first day of week', () => {
-    expect(adapter.getFirstDayOfWeek()).toBe(0);
+    adapter.setLocale('bg-BG');
+    expect(adapter.getFirstDayOfWeek()).toBe(1);
   });
 
   it('should create Luxon date', () => {
diff --git a/src/material-luxon-adapter/adapter/luxon-date-adapter.ts b/src/material-luxon-adapter/adapter/luxon-date-adapter.ts
index 5e7ade456685..58296201a97d 100644
--- a/src/material-luxon-adapter/adapter/luxon-date-adapter.ts
+++ b/src/material-luxon-adapter/adapter/luxon-date-adapter.ts
@@ -27,7 +27,7 @@ export interface MatLuxonDateAdapterOptions {
    * Sets the first day of week.
    * Changing this will change how Angular Material components like DatePicker shows start of week.
    */
-  firstDayOfWeek: number;
+  firstDayOfWeek?: number;
 
   /**
    * Sets the output Calendar.
@@ -49,7 +49,6 @@ export const MAT_LUXON_DATE_ADAPTER_OPTIONS = new InjectionToken<MatLuxonDateAda
 export function MAT_LUXON_DATE_ADAPTER_OPTIONS_FACTORY(): MatLuxonDateAdapterOptions {
   return {
     useUtc: false,
-    firstDayOfWeek: 0,
     defaultOutputCalendar: 'gregory',
   };
 }
@@ -67,7 +66,7 @@ function range<T>(length: number, valueFunction: (index: number) => T): T[] {
 @Injectable()
 export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
   private _useUTC: boolean;
-  private _firstDayOfWeek: number;
+  private _firstDayOfWeek: number | undefined;
   private _defaultOutputCalendar: LuxonCalendarSystem;
 
   constructor(...args: unknown[]);
@@ -81,7 +80,7 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
     });
 
     this._useUTC = !!options?.useUtc;
-    this._firstDayOfWeek = options?.firstDayOfWeek || 0;
+    this._firstDayOfWeek = options?.firstDayOfWeek;
     this._defaultOutputCalendar = options?.defaultOutputCalendar || 'gregory';
     this.setLocale(dateLocale || LuxonDateTime.local().locale);
   }
@@ -134,7 +133,7 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
   }
 
   getFirstDayOfWeek(): number {
-    return this._firstDayOfWeek;
+    return this._firstDayOfWeek ?? LuxonInfo.getStartOfWeek({locale: this.locale});
   }
 
   getNumDaysInMonth(date: LuxonDateTime): number {
diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts
index 159c036ce973..03c43eed53c2 100644
--- a/src/material/autocomplete/autocomplete-trigger.ts
+++ b/src/material/autocomplete/autocomplete-trigger.ts
@@ -34,6 +34,7 @@ import {
   NgZone,
   OnChanges,
   OnDestroy,
+  Renderer2,
   SimpleChanges,
   ViewContainerRef,
   afterNextRender,
@@ -49,7 +50,7 @@ import {
   _getOptionScrollPosition,
 } from '@angular/material/core';
 import {MAT_FORM_FIELD, MatFormField} from '@angular/material/form-field';
-import {Observable, Subject, Subscription, defer, fromEvent, merge, of as observableOf} from 'rxjs';
+import {Observable, Subject, Subscription, defer, merge, of as observableOf} from 'rxjs';
 import {delay, filter, map, startWith, switchMap, take, tap} from 'rxjs/operators';
 import {
   MAT_AUTOCOMPLETE_DEFAULT_OPTIONS,
@@ -130,6 +131,7 @@ export const MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER = {
 export class MatAutocompleteTrigger
   implements ControlValueAccessor, AfterViewInit, OnChanges, OnDestroy
 {
+  private _injector = inject(Injector);
   private _element = inject<ElementRef<HTMLInputElement>>(ElementRef);
   private _overlay = inject(Overlay);
   private _viewContainerRef = inject(ViewContainerRef);
@@ -139,6 +141,8 @@ export class MatAutocompleteTrigger
   private _formField = inject<MatFormField | null>(MAT_FORM_FIELD, {optional: true, host: true});
   private _document = inject(DOCUMENT);
   private _viewportRuler = inject(ViewportRuler);
+  private _scrollStrategy = inject(MAT_AUTOCOMPLETE_SCROLL_STRATEGY);
+  private _renderer = inject(Renderer2);
   private _defaults = inject<MatAutocompleteDefaultOptions | null>(
     MAT_AUTOCOMPLETE_DEFAULT_OPTIONS,
     {optional: true},
@@ -147,9 +151,10 @@ export class MatAutocompleteTrigger
   private _overlayRef: OverlayRef | null;
   private _portal: TemplatePortal;
   private _componentDestroyed = false;
-  private _scrollStrategy = inject(MAT_AUTOCOMPLETE_SCROLL_STRATEGY);
+  private _initialized = new Subject();
   private _keydownSubscription: Subscription | null;
   private _outsideClickSubscription: Subscription | null;
+  private _cleanupWindowBlur: (() => void) | undefined;
 
   /** Old value of the native input. Used to work around issues with the `input` event on IE. */
   private _previousValue: string | number | null;
@@ -244,10 +249,6 @@ export class MatAutocompleteTrigger
   @Input({alias: 'matAutocompleteDisabled', transform: booleanAttribute})
   autocompleteDisabled: boolean;
 
-  private _initialized = new Subject();
-
-  private _injector = inject(Injector);
-
   constructor(...args: unknown[]);
   constructor() {}
 
@@ -257,12 +258,7 @@ export class MatAutocompleteTrigger
   ngAfterViewInit() {
     this._initialized.next();
     this._initialized.complete();
-
-    const window = this._getWindow();
-
-    if (typeof window !== 'undefined') {
-      this._zone.runOutsideAngular(() => window.addEventListener('blur', this._windowBlurHandler));
-    }
+    this._cleanupWindowBlur = this._renderer.listen('window', 'blur', this._windowBlurHandler);
   }
 
   ngOnChanges(changes: SimpleChanges) {
@@ -276,12 +272,7 @@ export class MatAutocompleteTrigger
   }
 
   ngOnDestroy() {
-    const window = this._getWindow();
-
-    if (typeof window !== 'undefined') {
-      window.removeEventListener('blur', this._windowBlurHandler);
-    }
-
+    this._cleanupWindowBlur?.();
     this._handsetLandscapeSubscription.unsubscribe();
     this._viewportSubscription.unsubscribe();
     this._componentDestroyed = true;
@@ -408,12 +399,8 @@ export class MatAutocompleteTrigger
 
   /** Stream of clicks outside of the autocomplete panel. */
   private _getOutsideClickStream(): Observable<any> {
-    return merge(
-      fromEvent(this._document, 'click') as Observable<MouseEvent>,
-      fromEvent(this._document, 'auxclick') as Observable<MouseEvent>,
-      fromEvent(this._document, 'touchend') as Observable<TouchEvent>,
-    ).pipe(
-      filter(event => {
+    return new Observable(observer => {
+      const listener = (event: MouseEvent | TouchEvent) => {
         // If we're in the Shadow DOM, the event target will be the shadow root, so we have to
         // fall back to check the first element in the path of the click event.
         const clickTarget = _getEventTarget<HTMLElement>(event)!;
@@ -422,7 +409,7 @@ export class MatAutocompleteTrigger
           : null;
         const customOrigin = this.connectedTo ? this.connectedTo.elementRef.nativeElement : null;
 
-        return (
+        if (
           this._overlayAttached &&
           clickTarget !== this._element.nativeElement &&
           // Normally focus moves inside `mousedown` so this condition will almost always be
@@ -434,9 +421,21 @@ export class MatAutocompleteTrigger
           (!customOrigin || !customOrigin.contains(clickTarget)) &&
           !!this._overlayRef &&
           !this._overlayRef.overlayElement.contains(clickTarget)
-        );
-      }),
-    );
+        ) {
+          observer.next(event);
+        }
+      };
+
+      const cleanups = [
+        this._renderer.listen('document', 'click', listener),
+        this._renderer.listen('document', 'auxclick', listener),
+        this._renderer.listen('document', 'touchend', listener),
+      ];
+
+      return () => {
+        cleanups.forEach(current => current());
+      };
+    });
   }
 
   // Implemented as part of ControlValueAccessor.
@@ -996,11 +995,6 @@ export class MatAutocompleteTrigger
     return !element.readOnly && !element.disabled && !this.autocompleteDisabled;
   }
 
-  /** Use defaultView of injected document if available or fallback to global window reference */
-  private _getWindow(): Window {
-    return this._document?.defaultView || window;
-  }
-
   /** Scrolls to a particular option in the list. */
   private _scrollToOption(index: number): void {
     // Given that we are not actually focusing active options, we must manually adjust scroll
diff --git a/src/material/autocomplete/autocomplete.ts b/src/material/autocomplete/autocomplete.ts
index 4565f4e18a4f..390183a1ffc2 100644
--- a/src/material/autocomplete/autocomplete.ts
+++ b/src/material/autocomplete/autocomplete.ts
@@ -33,17 +33,11 @@ import {
   MatOption,
   ThemePalette,
 } from '@angular/material/core';
-import {ActiveDescendantKeyManager} from '@angular/cdk/a11y';
+import {_IdGenerator, ActiveDescendantKeyManager} from '@angular/cdk/a11y';
 import {Platform} from '@angular/cdk/platform';
 import {panelAnimation} from './animations';
 import {Subscription} from 'rxjs';
 
-/**
- * Autocomplete IDs need to be unique across components, so this counter exists outside of
- * the component definition.
- */
-let _uniqueAutocompleteIdCounter = 0;
-
 /** Event object that is emitted when an autocomplete option is selected. */
 export class MatAutocompleteSelectedEvent {
   constructor(
@@ -80,7 +74,7 @@ export interface MatAutocompleteDefaultOptions {
   /** Class or list of classes to be applied to the autocomplete's overlay panel. */
   overlayPanelClass?: string | string[];
 
-  /** Wheter icon indicators should be hidden for single-selection. */
+  /** Whether icon indicators should be hidden for single-selection. */
   hideSingleSelectionIndicator?: boolean;
 }
 
@@ -247,7 +241,7 @@ export class MatAutocomplete implements AfterContentInit, OnDestroy {
   }
 
   /** Unique ID to be used by autocomplete trigger's "aria-owns" property. */
-  id: string = `mat-autocomplete-${_uniqueAutocompleteIdCounter++}`;
+  id: string = inject(_IdGenerator).getId('mat-autocomplete-');
 
   /**
    * Tells any descendant `mat-optgroup` to use the inert a11y pattern.
diff --git a/src/material/autocomplete/module.ts b/src/material/autocomplete/module.ts
index 860119daae9a..d1e9983fad63 100644
--- a/src/material/autocomplete/module.ts
+++ b/src/material/autocomplete/module.ts
@@ -8,7 +8,6 @@
 
 import {NgModule} from '@angular/core';
 import {MatCommonModule, MatOptionModule} from '@angular/material/core';
-import {CommonModule} from '@angular/common';
 import {CdkScrollableModule} from '@angular/cdk/scrolling';
 import {OverlayModule} from '@angular/cdk/overlay';
 import {MatAutocomplete} from './autocomplete';
@@ -23,7 +22,6 @@ import {MatAutocompleteOrigin} from './autocomplete-origin';
     OverlayModule,
     MatOptionModule,
     MatCommonModule,
-    CommonModule,
     MatAutocomplete,
     MatAutocompleteTrigger,
     MatAutocompleteOrigin,
diff --git a/src/material/autocomplete/testing/autocomplete-harness.spec.ts b/src/material/autocomplete/testing/autocomplete-harness.spec.ts
index 3fedab3f7c40..1f034a97716c 100644
--- a/src/material/autocomplete/testing/autocomplete-harness.spec.ts
+++ b/src/material/autocomplete/testing/autocomplete-harness.spec.ts
@@ -176,7 +176,6 @@ describe('MatAutocompleteHarness', () => {
     <input id="prefilled" [matAutocomplete]="autocomplete" value="Prefilled value">
     <input id="grouped" [matAutocomplete]="groupedAutocomplete">
   `,
-  standalone: true,
   imports: [MatAutocompleteModule],
 })
 class AutocompleteHarnessTest {
diff --git a/src/material/badge/badge.spec.ts b/src/material/badge/badge.spec.ts
index 7c5a6ca9da22..2e0e1a996b9e 100644
--- a/src/material/badge/badge.spec.ts
+++ b/src/material/badge/badge.spec.ts
@@ -291,7 +291,6 @@ describe('MatBadge', () => {
       home
     </button>
   `,
-  standalone: true,
   imports: [MatBadgeModule],
 })
 class BadgeOnInteractiveElement {
@@ -308,7 +307,6 @@ class BadgeOnInteractiveElement {
 
 @Component({
   template: '<span matBadge="7" [matBadgeDescription]="description()">Hello</span>',
-  standalone: true,
   imports: [MatBadgeModule],
 })
 class BadgeOnNonInteractiveElement {
@@ -322,7 +320,6 @@ class BadgeOnNonInteractiveElement {
       <div class="mat-badge-content">Pre-existing badge</div>
     </span>
   `,
-  standalone: true,
   imports: [MatBadgeModule],
 })
 class PreExistingBadge {}
@@ -334,7 +331,6 @@ class PreExistingBadge {}
       <span matBadge="Hi">Something</span>
     </span>
   `,
-  standalone: true,
   imports: [MatBadgeModule],
 })
 class NestedBadge {}
@@ -342,7 +338,6 @@ class NestedBadge {}
 @Component({
   template: `
     <ng-template matBadge="1">Notifications</ng-template>`,
-  standalone: true,
   imports: [MatBadgeModule],
 })
 class BadgeOnTemplate {}
diff --git a/src/material/badge/badge.ts b/src/material/badge/badge.ts
index f6d8b2b44eee..7c48d1e6033a 100644
--- a/src/material/badge/badge.ts
+++ b/src/material/badge/badge.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {AriaDescriber, InteractivityChecker} from '@angular/cdk/a11y';
+import {_IdGenerator, AriaDescriber, InteractivityChecker} from '@angular/cdk/a11y';
 import {DOCUMENT} from '@angular/common';
 import {
   booleanAttribute,
@@ -26,8 +26,6 @@ import {
 import {ThemePalette} from '@angular/material/core';
 import {_CdkPrivateStyleLoader, _VisuallyHiddenLoader} from '@angular/cdk/private';
 
-let nextId = 0;
-
 /** Allowed position options for matBadgePosition */
 export type MatBadgePosition =
   | 'above after'
@@ -79,13 +77,14 @@ export class MatBadge implements OnInit, OnDestroy {
   private _ariaDescriber = inject(AriaDescriber);
   private _renderer = inject(Renderer2);
   private _animationMode = inject(ANIMATION_MODULE_TYPE, {optional: true});
+  private _idGenerator = inject(_IdGenerator);
 
   /**
    * Theme color of the badge. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/badge/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input('matBadgeColor')
   get color(): ThemePalette {
@@ -135,9 +134,6 @@ export class MatBadge implements OnInit, OnDestroy {
   /** Whether the badge is hidden. */
   @Input({alias: 'matBadgeHidden', transform: booleanAttribute}) hidden: boolean;
 
-  /** Unique id for the badge */
-  _id: number = nextId++;
-
   /** Visible badge element. */
   private _badgeElement: HTMLElement | undefined;
 
@@ -236,7 +232,7 @@ export class MatBadge implements OnInit, OnDestroy {
     const badgeElement = this._renderer.createElement('span');
     const activeClass = 'mat-badge-active';
 
-    badgeElement.setAttribute('id', `mat-badge-content-${this._id}`);
+    badgeElement.setAttribute('id', this._idGenerator.getId('mat-badge-content-'));
 
     // The badge is aria-hidden because we don't want it to appear in the page's navigation
     // flow. Instead, we use the badge to describe the decorated element with aria-describedby.
diff --git a/src/material/badge/testing/badge-harness.spec.ts b/src/material/badge/testing/badge-harness.spec.ts
index 48838b343d94..71261c9c3acd 100644
--- a/src/material/badge/testing/badge-harness.spec.ts
+++ b/src/material/badge/testing/badge-harness.spec.ts
@@ -136,7 +136,6 @@ describe('MatBadgeHarness', () => {
       matBadge="Disabled badge"
       [matBadgeDisabled]="disabled">Disabled</button>
   `,
-  standalone: true,
   imports: [MatBadgeModule],
 })
 class BadgeHarnessTest {
diff --git a/src/material/bottom-sheet/bottom-sheet-config.ts b/src/material/bottom-sheet/bottom-sheet-config.ts
index e95e22cfee53..ded882266ce6 100644
--- a/src/material/bottom-sheet/bottom-sheet-config.ts
+++ b/src/material/bottom-sheet/bottom-sheet-config.ts
@@ -72,4 +72,13 @@ export class MatBottomSheetConfig<D = any> {
 
   /** Scroll strategy to be used for the bottom sheet. */
   scrollStrategy?: ScrollStrategy;
+
+  /** Height for the bottom sheet. */
+  height?: string = '';
+
+  /** Minimum height for the bottom sheet. If a number is provided, assumes pixel units. */
+  minHeight?: number | string;
+
+  /** Maximum height for the bottom sheet. If a number is provided, assumes pixel units. */
+  maxHeight?: number | string;
 }
diff --git a/src/material/bottom-sheet/bottom-sheet-ref.ts b/src/material/bottom-sheet/bottom-sheet-ref.ts
index 6e664c2ed282..093b4cd50dce 100644
--- a/src/material/bottom-sheet/bottom-sheet-ref.ts
+++ b/src/material/bottom-sheet/bottom-sheet-ref.ts
@@ -47,7 +47,7 @@ export class MatBottomSheetRef<T = any, R = any> {
   private _result: R | undefined;
 
   /** Handle to the timeout that's running as a fallback in case the exit animation doesn't fire. */
-  private _closeFallbackTimeout: number;
+  private _closeFallbackTimeout: ReturnType<typeof setTimeout>;
 
   constructor(
     private _ref: DialogRef<R, T>,
diff --git a/src/material/bottom-sheet/bottom-sheet.spec.ts b/src/material/bottom-sheet/bottom-sheet.spec.ts
index e21a634119a0..4f978f23767d 100644
--- a/src/material/bottom-sheet/bottom-sheet.spec.ts
+++ b/src/material/bottom-sheet/bottom-sheet.spec.ts
@@ -461,6 +461,24 @@ describe('MatBottomSheet', () => {
     expect(scrollStrategy.enable).toHaveBeenCalled();
   });
 
+  it('should contain the height style properties on overlay pane', () => {
+    bottomSheet.open(PizzaMsg, {
+      panelClass: 'height--pane',
+      height: '300px',
+      maxHeight: 400, // this is converted into pixels
+      minHeight: 200, // this is converted into pixels
+    });
+
+    viewContainerFixture.detectChanges();
+
+    const paneElement = overlayContainerElement.querySelector('.height--pane') as HTMLElement;
+
+    expect(paneElement).toBeTruthy();
+    expect(paneElement.style.height).toBe('300px');
+    expect(paneElement.style.maxHeight).toBe('400px');
+    expect(paneElement.style.minHeight).toBe('200px');
+  });
+
   describe('passing in data', () => {
     it('should be able to pass in data', () => {
       const config = {
@@ -991,7 +1009,6 @@ describe('MatBottomSheet with default options', () => {
 
 @Directive({
   selector: 'dir-with-view-container',
-  standalone: true,
 })
 class DirectiveWithViewContainer {
   viewContainerRef = inject(ViewContainerRef);
@@ -999,7 +1016,6 @@ class DirectiveWithViewContainer {
 
 @Component({
   template: `<dir-with-view-container></dir-with-view-container>`,
-  standalone: true,
   imports: [DirectiveWithViewContainer],
 })
 class ComponentWithChildViewContainer {
@@ -1014,7 +1030,6 @@ class ComponentWithChildViewContainer {
   selector: 'arbitrary-component-with-template-ref',
   template: `<ng-template let-data let-bottomSheetRef="bottomSheetRef">
       Cheese {{localValue}} {{data?.value}}{{setRef(bottomSheetRef)}}</ng-template>`,
-  standalone: true,
 })
 class ComponentWithTemplateRef {
   localValue: string;
@@ -1030,7 +1045,6 @@ class ComponentWithTemplateRef {
 
 @Component({
   template: '<p>Pizza</p> <input> <button>Close</button>',
-  standalone: true,
 })
 class PizzaMsg {
   bottomSheetRef = inject<MatBottomSheetRef<PizzaMsg>>(MatBottomSheetRef);
@@ -1040,7 +1054,6 @@ class PizzaMsg {
 
 @Component({
   template: '<p>Taco</p>',
-  standalone: true,
 })
 class TacoMsg {}
 
@@ -1049,14 +1062,12 @@ class TacoMsg {}
     <h1>This is the title</h1>
     <p>This is the paragraph</p>
   `,
-  standalone: true,
 })
 class ContentElementDialog {}
 
 @Component({
   template: '',
   providers: [MatBottomSheet],
-  standalone: true,
   imports: [MatBottomSheetModule],
 })
 class ComponentThatProvidesMatBottomSheet {
@@ -1065,7 +1076,6 @@ class ComponentThatProvidesMatBottomSheet {
 
 @Component({
   template: '',
-  standalone: true,
 })
 class BottomSheetWithInjectedData {
   data = inject(MAT_BOTTOM_SHEET_DATA);
@@ -1074,6 +1084,5 @@ class BottomSheetWithInjectedData {
 @Component({
   template: `<button>I'm a button</button>`,
   encapsulation: ViewEncapsulation.ShadowDom,
-  standalone: true,
 })
 class ShadowDomComponent {}
diff --git a/src/material/bottom-sheet/testing/bottom-sheet-harness.spec.ts b/src/material/bottom-sheet/testing/bottom-sheet-harness.spec.ts
index 39ec594a2bda..cf3fe77b1a5c 100644
--- a/src/material/bottom-sheet/testing/bottom-sheet-harness.spec.ts
+++ b/src/material/bottom-sheet/testing/bottom-sheet-harness.spec.ts
@@ -54,7 +54,6 @@ describe('MatBottomSheetHarness', () => {
       Hello from the bottom sheet!
     </ng-template>
   `,
-  standalone: true,
   imports: [MatBottomSheetModule],
 })
 class BottomSheetHarnessTest {
diff --git a/src/material/button-toggle/button-toggle.html b/src/material/button-toggle/button-toggle.html
index 9452213fa907..a6d1e83d0502 100644
--- a/src/material/button-toggle/button-toggle.html
+++ b/src/material/button-toggle/button-toggle.html
@@ -11,25 +11,20 @@
         [attr.aria-labelledby]="ariaLabelledby"
         [attr.aria-disabled]="disabled && disabledInteractive ? 'true' : null"
         (click)="_onButtonClick()">
-  <span class="mat-button-toggle-label-content">
-    <!-- Render checkmark at the beginning for single-selection. -->
-    @if (buttonToggleGroup && checked && !buttonToggleGroup.multiple && !buttonToggleGroup.hideSingleSelectionIndicator) {
-      <mat-pseudo-checkbox
-          class="mat-mdc-option-pseudo-checkbox"
-          [disabled]="disabled"
-          state="checked"
-          aria-hidden="true"
-          appearance="minimal"></mat-pseudo-checkbox>
-    }
-    <!-- Render checkmark at the beginning for multiple-selection. -->
-    @if (buttonToggleGroup && checked && buttonToggleGroup.multiple && !buttonToggleGroup.hideMultipleSelectionIndicator) {
+  @if (buttonToggleGroup && (
+    !buttonToggleGroup.multiple && !buttonToggleGroup.hideSingleSelectionIndicator ||
+    buttonToggleGroup.multiple && !buttonToggleGroup.hideMultipleSelectionIndicator)
+  ) {
+    <div class="mat-button-toggle-checkbox-wrapper">
       <mat-pseudo-checkbox
-          class="mat-mdc-option-pseudo-checkbox"
-          [disabled]="disabled"
-          state="checked"
-          aria-hidden="true"
-          appearance="minimal"></mat-pseudo-checkbox>
-    }
+        [disabled]="disabled"
+        state="checked"
+        aria-hidden="true"
+        appearance="minimal"/>
+    </div>
+  }
+
+  <span class="mat-button-toggle-label-content">
     <ng-content></ng-content>
   </span>
 </button>
diff --git a/src/material/button-toggle/button-toggle.scss b/src/material/button-toggle/button-toggle.scss
index 4df361e165f3..778df32843af 100644
--- a/src/material/button-toggle/button-toggle.scss
+++ b/src/material/button-toggle/button-toggle.scss
@@ -7,9 +7,11 @@
 @use '../core/tokens/m2/mat/legacy-button-toggle' as tokens-mat-legacy-button-toggle;
 @use '../core/tokens/m2/mat/standard-button-toggle' as tokens-mat-standard-button-toggle;
 
-$standard-padding: 0 12px !default;
-$legacy-padding: 0 16px !default;
-$checkmark-padding: 12px !default;
+$standard-padding: 12px !default;
+$legacy-padding: 16px !default;
+$_checkmark-size: 18px !default;
+$_checkmark-margin: 12px;
+$_checkmark-transition: 150ms 45ms cubic-bezier(0.4, 0, 0.2, 1);
 
 // TODO(crisbeto): these variables aren't used anymore and should be removed.
 $legacy-height: 36px !default;
@@ -104,13 +106,51 @@ $_standard-tokens: (
   .mat-icon svg {
     vertical-align: top;
   }
+}
 
-  .mat-pseudo-checkbox {
-    margin-right: $checkmark-padding;
-    [dir='rtl'] & {
-      margin-right: 0;
-      margin-left: $checkmark-padding;
-    }
+.mat-button-toggle-checkbox-wrapper {
+  display: inline-block;
+  justify-content: flex-start;
+  align-items: center;
+  width: 0;
+  height: $_checkmark-size;
+  line-height: $_checkmark-size;
+  overflow: hidden;
+  box-sizing: border-box;
+  position: absolute;
+  top: 50%;
+  left: $legacy-padding;
+
+  // Uses a 3d transform, because otherwise Safari has some some of rendering
+  // artifact that adds a small gap between the two parts of the checkmark.
+  transform: translate3d(0, -50%, 0);
+
+  [dir='rtl'] & {
+    left: auto;
+    right: $legacy-padding;
+  }
+
+  .mat-button-toggle-appearance-standard & {
+    left: $standard-padding;
+  }
+
+  [dir='rtl'] .mat-button-toggle-appearance-standard & {
+    left: auto;
+    right: $standard-padding;
+  }
+
+  .mat-button-toggle-checked & {
+    width: $_checkmark-size;
+  }
+
+  .mat-button-toggle-animations-enabled & {
+    transition: width $_checkmark-transition;
+  }
+
+  // Disable the transition in vertical mode since it looks weird.
+  // There should be a limited amount of usages anyway.
+  .mat-button-toggle-vertical & {
+    transition: none;
   }
 }
 
@@ -219,7 +259,7 @@ $_standard-tokens: (
 .mat-button-toggle-label-content {
   @include vendor-prefixes.user-select(none);
   display: inline-block;
-  padding: $legacy-padding;
+  padding: 0 $legacy-padding;
 
   @include token-utils.use-tokens($_legacy-tokens...) {
     @include token-utils.create-token-slot(line-height, height);
@@ -229,7 +269,7 @@ $_standard-tokens: (
   position: relative;
 
   .mat-button-toggle-appearance-standard & {
-    padding: $standard-padding;
+    padding: 0 $standard-padding;
 
     @include token-utils.use-tokens($_standard-tokens...) {
       @include token-utils.create-token-slot(line-height, height);
@@ -292,6 +332,7 @@ $_standard-tokens: (
 }
 
 .mat-button-toggle-button {
+  $checkmark-spacing: $_checkmark-size + $_checkmark-margin;
   border: 0;
   background: none;
   color: inherit;
@@ -302,6 +343,16 @@ $_standard-tokens: (
   width: 100%; // Stretch the button in case the consumer set a custom width.
   cursor: pointer;
 
+  .mat-button-toggle-animations-enabled & {
+    transition: padding $_checkmark-transition;
+  }
+
+  // Disable the transition in vertical mode since it looks weird.
+  // There should be a limited amount of usages anyway.
+  .mat-button-toggle-vertical & {
+    transition: none;
+  }
+
   .mat-button-toggle-disabled & {
     cursor: default;
   }
@@ -310,6 +361,22 @@ $_standard-tokens: (
   &::-moz-focus-inner {
     border: 0;
   }
+
+  // Note that we use padding and `position: absolute` to show/hide the checkmark, instead of
+  // just transitioning it between `width: 18px` and `width: 0`, because it was being shown/hidden
+  // with `@if` before the transition was added and leaving it in the DOM while hidden can break
+  // some pre-existing layouts.
+  &:has(.mat-button-toggle-checkbox-wrapper) {
+    .mat-button-toggle-checked & {
+      padding-left: $checkmark-spacing;
+    }
+
+    [dir='rtl'] .mat-button-toggle-checked & {
+      padding-left: 0;
+      padding-right: $checkmark-spacing;
+    }
+  }
+
 }
 
 // Change the border-radius of the focus indicator to match the
diff --git a/src/material/button-toggle/button-toggle.spec.ts b/src/material/button-toggle/button-toggle.spec.ts
index 2ef8a9b44924..cc66f085dd50 100644
--- a/src/material/button-toggle/button-toggle.spec.ts
+++ b/src/material/button-toggle/button-toggle.spec.ts
@@ -96,8 +96,6 @@ describe('MatButtonToggle with forms', () => {
       innerButtons = buttonToggleDebugElements.map(
         debugEl => debugEl.query(By.css('button'))!.nativeElement,
       );
-
-      fixture.detectChanges();
     });
 
     it('should update the model before firing change event', fakeAsync(() => {
@@ -312,6 +310,18 @@ describe('MatButtonToggle with forms', () => {
 
     expect(instance.toggles.map(t => t.checked)).toEqual([true, false, false]);
   });
+
+  it('should set the initial tabindex when using ngModel with a static list of options where none match the value', fakeAsync(() => {
+    const fixture = TestBed.createComponent(ButtonToggleGroupWithNgModelAndStaticOptions);
+    fixture.detectChanges();
+    tick();
+    const indexes = Array.from(
+      fixture.nativeElement.querySelectorAll('button'),
+      (button: HTMLElement) => button.getAttribute('tabindex'),
+    );
+
+    expect(indexes).toEqual(['0', '-1', '-1']);
+  }));
 });
 
 describe('MatButtonToggle without forms', () => {
@@ -341,7 +351,7 @@ describe('MatButtonToggle without forms', () => {
     let groupNativeElement: HTMLElement;
     let buttonToggleDebugElements: DebugElement[];
     let buttonToggleNativeElements: HTMLElement[];
-    let buttonToggleLabelElements: HTMLLabelElement[];
+    let innerButtons: HTMLLabelElement[];
     let groupInstance: MatButtonToggleGroup;
     let buttonToggleInstances: MatButtonToggle[];
     let testComponent: ButtonTogglesInsideButtonToggleGroup;
@@ -360,7 +370,7 @@ describe('MatButtonToggle without forms', () => {
 
       buttonToggleNativeElements = buttonToggleDebugElements.map(debugEl => debugEl.nativeElement);
 
-      buttonToggleLabelElements = fixture.debugElement
+      innerButtons = fixture.debugElement
         .queryAll(By.css('button'))
         .map(debugEl => debugEl.nativeElement);
 
@@ -368,26 +378,20 @@ describe('MatButtonToggle without forms', () => {
     });
 
     it('should initialize the tab index correctly', () => {
-      buttonToggleLabelElements.forEach((buttonToggle, index) => {
-        if (index === 0) {
-          expect(buttonToggle.getAttribute('tabindex')).toBe('0');
-        } else {
-          expect(buttonToggle.getAttribute('tabindex')).toBe('-1');
-        }
-      });
+      expect(innerButtons.map(b => b.getAttribute('tabindex'))).toEqual(['0', '-1', '-1']);
     });
 
     it('should update the tab index correctly', () => {
-      buttonToggleLabelElements[1].click();
+      innerButtons[1].click();
       fixture.detectChanges();
 
-      expect(buttonToggleLabelElements[0].getAttribute('tabindex')).toBe('-1');
-      expect(buttonToggleLabelElements[1].getAttribute('tabindex')).toBe('0');
+      expect(innerButtons[0].getAttribute('tabindex')).toBe('-1');
+      expect(innerButtons[1].getAttribute('tabindex')).toBe('0');
     });
 
     it('should set individual button toggle names based on the group name', () => {
       expect(groupInstance.name).toBeTruthy();
-      for (let buttonToggle of buttonToggleLabelElements) {
+      for (let buttonToggle of innerButtons) {
         expect(buttonToggle.getAttribute('name')).toBe(groupInstance.name);
       }
     });
@@ -407,7 +411,7 @@ describe('MatButtonToggle without forms', () => {
 
       expect(buttonToggleInstances[0].disabled).toBe(false);
 
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
 
       expect(buttonToggleInstances[0].checked).toBe(true);
@@ -456,7 +460,7 @@ describe('MatButtonToggle without forms', () => {
 
     it('should update the group value when one of the toggles changes', () => {
       expect(groupInstance.value).toBeFalsy();
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
 
       expect(groupInstance.value).toBe('test1');
@@ -465,7 +469,7 @@ describe('MatButtonToggle without forms', () => {
 
     it('should propagate the value change back up via a two-way binding', () => {
       expect(groupInstance.value).toBeFalsy();
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
 
       expect(groupInstance.value).toBe('test1');
@@ -474,7 +478,7 @@ describe('MatButtonToggle without forms', () => {
 
     it('should update the group and toggles when one of the button toggles is clicked', () => {
       expect(groupInstance.value).toBeFalsy();
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
 
       expect(groupInstance.value).toBe('test1');
@@ -482,7 +486,7 @@ describe('MatButtonToggle without forms', () => {
       expect(buttonToggleInstances[0].checked).toBe(true);
       expect(buttonToggleInstances[1].checked).toBe(false);
 
-      buttonToggleLabelElements[1].click();
+      innerButtons[1].click();
       fixture.detectChanges();
 
       expect(groupInstance.value).toBe('test2');
@@ -492,7 +496,7 @@ describe('MatButtonToggle without forms', () => {
     });
 
     it('should check a button toggle upon interaction with underlying native radio button', () => {
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
 
       expect(buttonToggleInstances[0].checked).toBe(true);
@@ -515,12 +519,12 @@ describe('MatButtonToggle without forms', () => {
       const changeSpy = jasmine.createSpy('button-toggle change listener');
       buttonToggleInstances[0].change.subscribe(changeSpy);
 
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
       tick();
       expect(changeSpy).toHaveBeenCalledTimes(1);
 
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
       tick();
 
@@ -534,12 +538,12 @@ describe('MatButtonToggle without forms', () => {
       const changeSpy = jasmine.createSpy('button-toggle-group change listener');
       groupInstance.change.subscribe(changeSpy);
 
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
       tick();
       expect(changeSpy).toHaveBeenCalled();
 
-      buttonToggleLabelElements[1].click();
+      innerButtons[1].click();
       fixture.detectChanges();
       tick();
       expect(changeSpy).toHaveBeenCalledTimes(2);
@@ -579,7 +583,7 @@ describe('MatButtonToggle without forms', () => {
 
     it('should update the model if a selected toggle is removed', fakeAsync(() => {
       expect(groupInstance.value).toBeFalsy();
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
 
       expect(groupInstance.value).toBe('test1');
@@ -595,10 +599,14 @@ describe('MatButtonToggle without forms', () => {
     }));
 
     it('should show checkmark indicator by default', () => {
-      buttonToggleLabelElements[0].click();
+      innerButtons[0].click();
       fixture.detectChanges();
 
-      expect(document.querySelectorAll('.mat-pseudo-checkbox').length).toBe(1);
+      expect(
+        fixture.nativeElement.querySelectorAll(
+          '.mat-button-toggle-checked .mat-button-toggle-checkbox-wrapper',
+        ).length,
+      ).toBe(1);
     });
   });
 
@@ -763,7 +771,11 @@ describe('MatButtonToggle without forms', () => {
       buttonToggleLabelElements[1].click();
       fixture.detectChanges();
 
-      expect(document.querySelectorAll('.mat-pseudo-checkbox').length).toBe(2);
+      expect(
+        fixture.nativeElement.querySelectorAll(
+          '.mat-button-toggle-checked .mat-button-toggle-checkbox-wrapper',
+        ).length,
+      ).toBe(2);
     });
   });
 
@@ -1084,7 +1096,6 @@ describe('MatButtonToggle without forms', () => {
     <mat-button-toggle value="test3">Test3</mat-button-toggle>
   </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonTogglesInsideButtonToggleGroup {
@@ -1109,7 +1120,6 @@ class ButtonTogglesInsideButtonToggleGroup {
     }
   </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule, FormsModule, ReactiveFormsModule],
 })
 class ButtonToggleGroupWithNgModel {
@@ -1132,7 +1142,6 @@ class ButtonToggleGroupWithNgModel {
     <mat-button-toggle value="sugar">Sugar</mat-button-toggle>
   </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonTogglesInsideButtonToggleGroupMultiple {
@@ -1149,7 +1158,6 @@ class ButtonTogglesInsideButtonToggleGroupMultiple {
     <mat-button-toggle>Sugar</mat-button-toggle>
   </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class FalsyButtonTogglesInsideButtonToggleGroupMultiple {
@@ -1161,7 +1169,6 @@ class FalsyButtonTogglesInsideButtonToggleGroupMultiple {
   template: `
   <mat-button-toggle>Yes</mat-button-toggle>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class StandaloneButtonToggle {}
@@ -1173,7 +1180,6 @@ class StandaloneButtonToggle {}
     <mat-button-toggle value="green">Value Green</mat-button-toggle>
   </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleGroupWithInitialValue {
@@ -1188,7 +1194,6 @@ class ButtonToggleGroupWithInitialValue {
     <mat-button-toggle value="blue">Value Blue</mat-button-toggle>
   </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule, FormsModule, ReactiveFormsModule],
 })
 class ButtonToggleGroupWithFormControl {
@@ -1206,7 +1211,6 @@ class ButtonToggleGroupWithFormControl {
       }
     </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule, FormsModule, ReactiveFormsModule],
 })
 class ButtonToggleGroupWithIndirectDescendantToggles {
@@ -1216,7 +1220,6 @@ class ButtonToggleGroupWithIndirectDescendantToggles {
 /** Simple test component with an aria-label set. */
 @Component({
   template: `<mat-button-toggle aria-label="Super effective"></mat-button-toggle>`,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleWithAriaLabel {}
@@ -1224,7 +1227,6 @@ class ButtonToggleWithAriaLabel {}
 /** Simple test component with an aria-label set. */
 @Component({
   template: `<mat-button-toggle aria-labelledby="some-id"></mat-button-toggle>`,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleWithAriaLabelledby {}
@@ -1237,7 +1239,6 @@ class ButtonToggleWithAriaLabelledby {}
       }
     </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class RepeatedButtonTogglesWithPreselectedValue {
@@ -1250,14 +1251,12 @@ class RepeatedButtonTogglesWithPreselectedValue {
 
 @Component({
   template: `<mat-button-toggle tabindex="3"></mat-button-toggle>`,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleWithTabindex {}
 
 @Component({
   template: `<mat-button-toggle name="custom-name"></mat-button-toggle>`,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleWithStaticName {}
@@ -1269,7 +1268,6 @@ class ButtonToggleWithStaticName {}
       <mat-button-toggle value="2" checked>Two</mat-button-toggle>
     </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleWithStaticChecked {
@@ -1281,7 +1279,6 @@ class ButtonToggleWithStaticChecked {
   template: `
     <mat-button-toggle aria-label="Toggle me" aria-labelledby="something"></mat-button-toggle>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleWithStaticAriaAttributes {}
@@ -1294,7 +1291,6 @@ class ButtonToggleWithStaticAriaAttributes {}
     }
   </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule, FormsModule, ReactiveFormsModule],
 })
 class ButtonToggleGroupWithFormControlAndDynamicButtons {
@@ -1302,3 +1298,17 @@ class ButtonToggleGroupWithFormControlAndDynamicButtons {
   control = new FormControl('');
   values = ['a', 'b', 'c'];
 }
+
+@Component({
+  template: `
+    <mat-button-toggle-group [(ngModel)]="value">
+      <mat-button-toggle value="1">One</mat-button-toggle>
+      <mat-button-toggle value="2">Two</mat-button-toggle>
+      <mat-button-toggle value="3">Three</mat-button-toggle>
+    </mat-button-toggle-group>
+  `,
+  imports: [MatButtonToggleModule, FormsModule],
+})
+class ButtonToggleGroupWithNgModelAndStaticOptions {
+  value = '';
+}
diff --git a/src/material/button-toggle/button-toggle.ts b/src/material/button-toggle/button-toggle.ts
index bd03ff5ec284..2838742faa19 100644
--- a/src/material/button-toggle/button-toggle.ts
+++ b/src/material/button-toggle/button-toggle.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {FocusMonitor} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusMonitor} from '@angular/cdk/a11y';
 import {SelectionModel} from '@angular/cdk/collections';
 import {DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, UP_ARROW, SPACE, ENTER} from '@angular/cdk/keycodes';
 import {
@@ -31,6 +31,7 @@ import {
   booleanAttribute,
   inject,
   HostAttributeToken,
+  ANIMATION_MODULE_TYPE,
 } from '@angular/core';
 import {Direction, Directionality} from '@angular/cdk/bidi';
 import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
@@ -56,7 +57,7 @@ export interface MatButtonToggleDefaultOptions {
    * setting an appearance on a button toggle or group.
    */
   appearance?: MatButtonToggleAppearance;
-  /** Whetehr icon indicators should be hidden for single-selection button toggle groups. */
+  /** Whether icon indicators should be hidden for single-selection button toggle groups. */
   hideSingleSelectionIndicator?: boolean;
   /** Whether icon indicators should be hidden for multiple-selection button toggle groups. */
   hideMultipleSelectionIndicator?: boolean;
@@ -104,9 +105,6 @@ export const MAT_BUTTON_TOGGLE_GROUP_VALUE_ACCESSOR: any = {
   multi: true,
 };
 
-// Counter used to generate unique IDs.
-let uniqueIdCounter = 0;
-
 /** Change event object emitted by button toggle. */
 export class MatButtonToggleChange {
   constructor(
@@ -181,7 +179,7 @@ export class MatButtonToggleGroup implements ControlValueAccessor, OnInit, After
     this._name = value;
     this._markButtonsForCheck();
   }
-  private _name = `mat-button-toggle-group-${uniqueIdCounter++}`;
+  private _name = inject(_IdGenerator).getId('mat-button-toggle-group-');
 
   /** Whether the toggle group is vertical. */
   @Input({transform: booleanAttribute}) vertical: boolean;
@@ -475,16 +473,28 @@ export class MatButtonToggleGroup implements ControlValueAccessor, OnInit, After
       return;
     }
 
+    const toggles = this._buttonToggles.toArray();
+
     if (this.multiple && value) {
       if (!Array.isArray(value) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
         throw Error('Value must be an array in multiple-selection mode.');
       }
 
       this._clearSelection();
-      value.forEach((currentValue: any) => this._selectValue(currentValue));
+      value.forEach((currentValue: any) => this._selectValue(currentValue, toggles));
     } else {
       this._clearSelection();
-      this._selectValue(value);
+      this._selectValue(value, toggles);
+    }
+
+    // In single selection mode we need at least one enabled toggle to always be focusable.
+    if (!this.multiple && toggles.every(toggle => toggle.tabIndex === -1)) {
+      for (const toggle of toggles) {
+        if (!toggle.disabled) {
+          toggle.tabIndex = 0;
+          break;
+        }
+      }
     }
   }
 
@@ -501,17 +511,16 @@ export class MatButtonToggleGroup implements ControlValueAccessor, OnInit, After
   }
 
   /** Selects a value if there's a toggle that corresponds to it. */
-  private _selectValue(value: any) {
-    const correspondingOption = this._buttonToggles.find(toggle => {
-      return toggle.value != null && toggle.value === value;
-    });
-
-    if (correspondingOption) {
-      correspondingOption.checked = true;
-      this._selectionModel.select(correspondingOption);
-      if (!this.multiple) {
-        // If the button toggle is in single select mode, reset the tabIndex.
-        correspondingOption.tabIndex = 0;
+  private _selectValue(value: any, toggles: MatButtonToggle[]) {
+    for (const toggle of toggles) {
+      if (toggle.value != null && toggle.value === value) {
+        toggle.checked = true;
+        this._selectionModel.select(toggle);
+        if (!this.multiple) {
+          // If the button toggle is in single select mode, reset the tabIndex.
+          toggle.tabIndex = 0;
+        }
+        break;
       }
     }
   }
@@ -562,7 +571,8 @@ export class MatButtonToggle implements OnInit, AfterViewInit, OnDestroy {
   private _changeDetectorRef = inject(ChangeDetectorRef);
   private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
   private _focusMonitor = inject(FocusMonitor);
-
+  private _idGenerator = inject(_IdGenerator);
+  private _animationMode = inject(ANIMATION_MODULE_TYPE, {optional: true});
   private _checked = false;
 
   /**
@@ -602,8 +612,10 @@ export class MatButtonToggle implements OnInit, AfterViewInit, OnDestroy {
     return this._tabIndex;
   }
   set tabIndex(value: number | null) {
-    this._tabIndex = value;
-    this._markForCheck();
+    if (value !== this._tabIndex) {
+      this._tabIndex = value;
+      this._markForCheck();
+    }
   }
   private _tabIndex: number | null;
 
@@ -669,14 +681,13 @@ export class MatButtonToggle implements OnInit, AfterViewInit, OnDestroy {
   constructor() {
     inject(_CdkPrivateStyleLoader).load(_StructuralStylesLoader);
     const toggleGroup = inject<MatButtonToggleGroup>(MAT_BUTTON_TOGGLE_GROUP, {optional: true})!;
-    const defaultTabIndex = inject(new HostAttributeToken('tabindex'), {optional: true});
+    const defaultTabIndex = inject(new HostAttributeToken('tabindex'), {optional: true}) || '';
     const defaultOptions = inject<MatButtonToggleDefaultOptions>(
       MAT_BUTTON_TOGGLE_DEFAULT_OPTIONS,
       {optional: true},
     );
 
-    const parsedTabIndex = Number(defaultTabIndex);
-    this.tabIndex = parsedTabIndex || parsedTabIndex === 0 ? parsedTabIndex : null;
+    this._tabIndex = parseInt(defaultTabIndex) || 0;
     this.buttonToggleGroup = toggleGroup;
     this.appearance =
       defaultOptions && defaultOptions.appearance ? defaultOptions.appearance : 'standard';
@@ -685,7 +696,7 @@ export class MatButtonToggle implements OnInit, AfterViewInit, OnDestroy {
 
   ngOnInit() {
     const group = this.buttonToggleGroup;
-    this.id = this.id || `mat-button-toggle-${uniqueIdCounter++}`;
+    this.id = this.id || this._idGenerator.getId('mat-button-toggle-');
 
     if (group) {
       if (group._isPrechecked(this)) {
@@ -701,6 +712,14 @@ export class MatButtonToggle implements OnInit, AfterViewInit, OnDestroy {
   }
 
   ngAfterViewInit() {
+    // This serves two purposes:
+    // 1. We don't want the animation to fire on the first render for pre-checked toggles so we
+    //    delay adding the class until the view is rendered.
+    // 2. We don't want animation if the `NoopAnimationsModule` is provided.
+    if (this._animationMode !== 'NoopAnimations') {
+      this._elementRef.nativeElement.classList.add('mat-button-toggle-animations-enabled');
+    }
+
     this._focusMonitor.monitor(this._elementRef, true);
   }
 
diff --git a/src/material/button-toggle/testing/button-toggle-group.spec.ts b/src/material/button-toggle/testing/button-toggle-group.spec.ts
index 70377498cac4..178451dd8964 100644
--- a/src/material/button-toggle/testing/button-toggle-group.spec.ts
+++ b/src/material/button-toggle/testing/button-toggle-group.spec.ts
@@ -85,7 +85,6 @@ describe('MatButtonToggleGroupHarness', () => {
       <mat-button-toggle value="2">Two</mat-button-toggle>
     </mat-button-toggle-group>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleGroupHarnessTest {
diff --git a/src/material/button-toggle/testing/button-toggle-harness.spec.ts b/src/material/button-toggle/testing/button-toggle-harness.spec.ts
index c7fc5f6cdd8f..a712846a45f0 100644
--- a/src/material/button-toggle/testing/button-toggle-harness.spec.ts
+++ b/src/material/button-toggle/testing/button-toggle-harness.spec.ts
@@ -154,7 +154,6 @@ describe('MatButtonToggleHarness', () => {
         appearance="legacy">Second</mat-button-toggle>
       <span id="second-label">Second toggle</span>
   `,
-  standalone: true,
   imports: [MatButtonToggleModule],
 })
 class ButtonToggleHarnessTest {
diff --git a/src/material/button/BUILD.bazel b/src/material/button/BUILD.bazel
index af7369501faa..2f71c888a923 100644
--- a/src/material/button/BUILD.bazel
+++ b/src/material/button/BUILD.bazel
@@ -26,7 +26,6 @@ ng_module(
         ":icon-button_scss",
     ] + glob(["**/*.html"]),
     deps = [
-        "//src/cdk/platform",
         "//src/material/core",
     ],
 )
diff --git a/src/material/button/button-base.ts b/src/material/button/button-base.ts
index 823a0cf7f2e4..6c66a2304273 100644
--- a/src/material/button/button-base.ts
+++ b/src/material/button/button-base.ts
@@ -7,7 +7,6 @@
  */
 
 import {FocusMonitor, FocusOrigin} from '@angular/cdk/a11y';
-import {Platform} from '@angular/cdk/platform';
 import {
   AfterViewInit,
   ANIMATION_MODULE_TYPE,
@@ -21,6 +20,7 @@ import {
   numberAttribute,
   OnDestroy,
   OnInit,
+  Renderer2,
 } from '@angular/core';
 import {_StructuralStylesLoader, MatRippleLoader, ThemePalette} from '@angular/material/core';
 import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
@@ -90,7 +90,6 @@ const HOST_SELECTOR_MDC_CLASS_PAIR: {attribute: string; mdcClasses: string[]}[]
 @Directive()
 export class MatButtonBase implements AfterViewInit, OnDestroy {
   _elementRef = inject(ElementRef);
-  _platform = inject(Platform);
   _ngZone = inject(NgZone);
   _animationMode = inject(ANIMATION_MODULE_TYPE, {optional: true});
 
@@ -107,10 +106,10 @@ export class MatButtonBase implements AfterViewInit, OnDestroy {
 
   /**
    * Theme color of the button. This API is supported in M2 themes only, it has
-   * no effect in M3 themes.
+   * no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/button/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color?: string | null;
 
@@ -215,6 +214,8 @@ export class MatButtonBase implements AfterViewInit, OnDestroy {
 
 /** Shared host configuration for buttons using the `<a>` tag. */
 export const MAT_ANCHOR_HOST = {
+  // Note that this is basically a noop on anchors,
+  // but it appears that some internal apps depend on it.
   '[attr.disabled]': '_getDisabledAttribute()',
   '[class.mat-mdc-button-disabled]': 'disabled',
   '[class.mat-mdc-button-disabled-interactive]': 'disabledInteractive',
@@ -224,7 +225,7 @@ export const MAT_ANCHOR_HOST = {
   // consistency with the `mat-button` applied on native buttons where even
   // though they have an index, they're not tabbable.
   '[attr.tabindex]': 'disabled && !disabledInteractive ? -1 : tabIndex',
-  '[attr.aria-disabled]': '_getDisabledAttribute()',
+  '[attr.aria-disabled]': '_getAriaDisabled()',
   // MDC automatically applies the primary theme color to the button, but we want to support
   // an unthemed version. If color is undefined, apply a CSS class that makes it easy to
   // select and style this "theme".
@@ -240,6 +241,9 @@ export const MAT_ANCHOR_HOST = {
  */
 @Directive()
 export class MatAnchorBase extends MatButtonBase implements OnInit, OnDestroy {
+  private _renderer = inject(Renderer2);
+  private _cleanupClick: () => void;
+
   @Input({
     transform: (value: unknown) => {
       return value == null ? undefined : numberAttribute(value);
@@ -249,13 +253,17 @@ export class MatAnchorBase extends MatButtonBase implements OnInit, OnDestroy {
 
   ngOnInit(): void {
     this._ngZone.runOutsideAngular(() => {
-      this._elementRef.nativeElement.addEventListener('click', this._haltDisabledEvents);
+      this._cleanupClick = this._renderer.listen(
+        this._elementRef.nativeElement,
+        'click',
+        this._haltDisabledEvents,
+      );
     });
   }
 
   override ngOnDestroy(): void {
     super.ngOnDestroy();
-    this._elementRef.nativeElement.removeEventListener('click', this._haltDisabledEvents);
+    this._cleanupClick?.();
   }
 
   _haltDisabledEvents = (event: Event): void => {
@@ -267,6 +275,9 @@ export class MatAnchorBase extends MatButtonBase implements OnInit, OnDestroy {
   };
 
   protected override _getAriaDisabled() {
-    return this.ariaDisabled == null ? this.disabled : this.ariaDisabled;
+    if (this.ariaDisabled != null) {
+      return this.ariaDisabled;
+    }
+    return this.disabled || null;
   }
 }
diff --git a/src/material/button/button.spec.ts b/src/material/button/button.spec.ts
index 4577eb16526e..74ec8821cc81 100644
--- a/src/material/button/button.spec.ts
+++ b/src/material/button/button.spec.ts
@@ -292,7 +292,6 @@ describe('MatButton', () => {
   it('should be able to configure the default color of buttons', () => {
     @Component({
       template: `<button mat-button>Click me</button>`,
-      standalone: true,
       imports: [MatButtonModule],
     })
     class ConfigTestApp {}
@@ -316,13 +315,15 @@ describe('MatButton', () => {
   describe('interactive disabled buttons', () => {
     let fixture: ComponentFixture<TestApp>;
     let button: HTMLButtonElement;
+    let anchor: HTMLAnchorElement;
 
     beforeEach(() => {
       fixture = TestBed.createComponent(TestApp);
       fixture.componentInstance.isDisabled = true;
       fixture.changeDetectorRef.markForCheck();
       fixture.detectChanges();
-      button = fixture.debugElement.query(By.css('button'))!.nativeElement;
+      button = fixture.nativeElement.querySelector('button');
+      anchor = fixture.nativeElement.querySelector('a');
     });
 
     it('should set a class when allowing disabled interactivity', () => {
@@ -354,6 +355,29 @@ describe('MatButton', () => {
 
       expect(button.hasAttribute('disabled')).toBe(false);
     });
+
+    it('should set aria-disabled on anchor when disabledInteractive is enabled', () => {
+      fixture.componentInstance.isDisabled = false;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+      expect(anchor.hasAttribute('aria-disabled')).toBe(false);
+      expect(anchor.hasAttribute('disabled')).toBe(false);
+      expect(anchor.classList).not.toContain('mat-mdc-button-disabled-interactive');
+
+      fixture.componentInstance.isDisabled = true;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+      expect(anchor.getAttribute('aria-disabled')).toBe('true');
+      expect(anchor.hasAttribute('disabled')).toBe(true);
+      expect(anchor.classList).not.toContain('mat-mdc-button-disabled-interactive');
+
+      fixture.componentInstance.disabledInteractive = true;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+      expect(anchor.getAttribute('aria-disabled')).toBe('true');
+      expect(anchor.hasAttribute('disabled')).toBe(false);
+      expect(anchor.classList).toContain('mat-mdc-button-disabled-interactive');
+    });
   });
 });
 
@@ -399,7 +423,6 @@ describe('MatFabDefaultOptions', () => {
     <button mat-fab [extended]="extended" class="extended-fab-test">Extended</button>
     <button mat-mini-fab>Mini Fab Button</button>
   `,
-  standalone: true,
   imports: [MatButtonModule],
 })
 class TestApp {
diff --git a/src/material/button/fab.ts b/src/material/button/fab.ts
index 5d9641f5da52..a9edbcd256af 100644
--- a/src/material/button/fab.ts
+++ b/src/material/button/fab.ts
@@ -24,10 +24,10 @@ import {ThemePalette} from '@angular/material/core';
 export interface MatFabDefaultOptions {
   /**
    * Default theme color of the button. This API is supported in M2 themes
-   * only, it has no effect in M3 themes.
+   * only, it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/button/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants.
    */
   color?: ThemePalette;
 }
diff --git a/src/material/button/testing/button-harness.spec.ts b/src/material/button/testing/button-harness.spec.ts
index e19db0e5ea21..ab4a01fa4c6e 100644
--- a/src/material/button/testing/button-harness.spec.ts
+++ b/src/material/button/testing/button-harness.spec.ts
@@ -174,7 +174,6 @@ describe('MatButtonHarness', () => {
     <a id="anchor-fab" mat-fab>Fab anchor</a>
     <a id="anchor-mini-fab" mat-mini-fab>Mini Fab anchor</a>
   `,
-  standalone: true,
   imports: [MatButtonModule, MatIconModule, PlatformModule],
 })
 class ButtonHarnessTest {
diff --git a/src/material/card/card.spec.ts b/src/material/card/card.spec.ts
index 0273ecfef51a..eadb812356ed 100644
--- a/src/material/card/card.spec.ts
+++ b/src/material/card/card.spec.ts
@@ -48,7 +48,6 @@ describe('MatCard', () => {
 
 @Component({
   template: '<mat-card [appearance]="appearance()"></mat-card>',
-  standalone: true,
   imports: [MatCard],
 })
 class BasicCard {
@@ -57,7 +56,6 @@ class BasicCard {
 
 @Component({
   template: '<mat-card></mat-card>',
-  standalone: true,
   imports: [MatCard],
 })
 class BasicCardNoAppearance {}
diff --git a/src/material/card/module.ts b/src/material/card/module.ts
index 5ca2edb27cc8..a72ce0bf1404 100644
--- a/src/material/card/module.ts
+++ b/src/material/card/module.ts
@@ -6,7 +6,6 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {MatCommonModule} from '@angular/material/core';
 import {
@@ -44,7 +43,7 @@ const CARD_DIRECTIVES = [
 ];
 
 @NgModule({
-  imports: [MatCommonModule, CommonModule, ...CARD_DIRECTIVES],
+  imports: [MatCommonModule, ...CARD_DIRECTIVES],
   exports: [CARD_DIRECTIVES, MatCommonModule],
 })
 export class MatCardModule {}
diff --git a/src/material/card/testing/card-harness.spec.ts b/src/material/card/testing/card-harness.spec.ts
index 7837c73794eb..06ebb6a3cd93 100644
--- a/src/material/card/testing/card-harness.spec.ts
+++ b/src/material/card/testing/card-harness.spec.ts
@@ -123,7 +123,6 @@ describe('MatCardHarness', () => {
         </mat-card-footer>
       </mat-card>
   `,
-  standalone: true,
   imports: [MatCardModule],
 })
 class CardHarnessTest {}
diff --git a/src/material/checkbox/checkbox-config.ts b/src/material/checkbox/checkbox-config.ts
index 17c8339f8d92..70ed060f00dd 100644
--- a/src/material/checkbox/checkbox-config.ts
+++ b/src/material/checkbox/checkbox-config.ts
@@ -12,10 +12,10 @@ import {ThemePalette} from '@angular/material/core';
 export interface MatCheckboxDefaultOptions {
   /**
    * Default theme color of the checkbox. This API is supported in M2 themes
-   * only, it has no effect in M3 themes.
+   * only, it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/checkbox/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   color?: ThemePalette;
 
diff --git a/src/material/checkbox/checkbox.scss b/src/material/checkbox/checkbox.scss
index 1bc17261034b..0ab15a3d7d7a 100644
--- a/src/material/checkbox/checkbox.scss
+++ b/src/material/checkbox/checkbox.scss
@@ -107,8 +107,9 @@
 }
 
 // Checkbox components have to set `border-radius: 50%` in order to support density scaling
-// which will clip a square focus indicator so we have to turn it into a circle.
-.mat-mdc-checkbox-ripple::before {
+// which will clip a square focus indicator so we have to turn it into a circle. Needs extra
+// specificity in case the ripple styles are loaded later which can override the shape.
+.mat-mdc-checkbox .mat-mdc-checkbox-ripple::before {
   border-radius: 50%;
 }
 
diff --git a/src/material/checkbox/checkbox.spec.ts b/src/material/checkbox/checkbox.spec.ts
index 35fb4441d91e..ac44a8beb73b 100644
--- a/src/material/checkbox/checkbox.spec.ts
+++ b/src/material/checkbox/checkbox.spec.ts
@@ -298,7 +298,7 @@ describe('MatCheckbox', () => {
       fixture.changeDetectorRef.markForCheck();
       fixture.detectChanges();
 
-      expect(checkboxInstance.inputId).toMatch(/mat-mdc-checkbox-\d+/);
+      expect(checkboxInstance.inputId).toMatch(/mat-mdc-checkbox-\w+\d+/);
       expect(inputElement.id).toBe(checkboxInstance.inputId);
     }));
 
@@ -965,8 +965,8 @@ describe('MatCheckbox', () => {
         .queryAll(By.directive(MatCheckbox))
         .map(debugElement => debugElement.nativeElement.querySelector('input').id);
 
-      expect(firstId).toMatch(/mat-mdc-checkbox-\d+-input/);
-      expect(secondId).toMatch(/mat-mdc-checkbox-\d+-input/);
+      expect(firstId).toMatch(/mat-mdc-checkbox-\w+\d+-input/);
+      expect(secondId).toMatch(/mat-mdc-checkbox-\w+\d+-input/);
       expect(firstId).not.toEqual(secondId);
     }));
   });
@@ -1233,7 +1233,6 @@ describe('MatCheckboxDefaultOptions', () => {
       Simple checkbox
     </mat-checkbox>
   </div>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class SingleCheckbox {
@@ -1258,7 +1257,6 @@ class SingleCheckbox {
 @Component({
   template: `<mat-checkbox [required]="isRequired" [(ngModel)]="isGood"
                            [disabled]="isDisabled">Be good</mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox, FormsModule],
 })
 class CheckboxWithNgModel {
@@ -1270,7 +1268,6 @@ class CheckboxWithNgModel {
 @Component({
   template: `<mat-checkbox [required]="isRequired" [(ngModel)]="isGood">Be good</mat-checkbox>`,
   changeDetection: ChangeDetectionStrategy.OnPush,
-  standalone: true,
   imports: [MatCheckbox, FormsModule],
 })
 class CheckboxWithNgModelAndOnPush extends CheckboxWithNgModel {}
@@ -1281,7 +1278,6 @@ class CheckboxWithNgModelAndOnPush extends CheckboxWithNgModel {}
     <mat-checkbox>Option 1</mat-checkbox>
     <mat-checkbox>Option 2</mat-checkbox>
   `,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class MultipleCheckboxes {}
@@ -1293,7 +1289,6 @@ class MultipleCheckboxes {}
         [tabIndex]="customTabIndex"
         [disabled]="isDisabled">
     </mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithTabIndex {
@@ -1304,7 +1299,6 @@ class CheckboxWithTabIndex {
 /** Simple test component with an aria-label set. */
 @Component({
   template: `<mat-checkbox aria-label="Super effective"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithAriaLabel {}
@@ -1312,7 +1306,6 @@ class CheckboxWithAriaLabel {}
 /** Simple test component with an aria-label set. */
 @Component({
   template: `<mat-checkbox aria-labelledby="some-id"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithAriaLabelledby {}
@@ -1320,7 +1313,6 @@ class CheckboxWithAriaLabelledby {}
 /** Simple test component with an aria-describedby set. */
 @Component({
   template: `<mat-checkbox aria-describedby="some-id"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithAriaDescribedby {}
@@ -1328,7 +1320,6 @@ class CheckboxWithAriaDescribedby {}
 /** Simple test component with an aria-expanded set with true. */
 @Component({
   template: `<mat-checkbox aria-expanded="true"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithPositiveAriaExpanded {}
@@ -1336,7 +1327,6 @@ class CheckboxWithPositiveAriaExpanded {}
 /** Simple test component with an aria-expanded set with false. */
 @Component({
   template: `<mat-checkbox aria-expanded="false"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithNegativeAriaExpanded {}
@@ -1344,7 +1334,6 @@ class CheckboxWithNegativeAriaExpanded {}
 /** Simple test component with an aria-controls set. */
 @Component({
   template: `<mat-checkbox aria-controls="some-id"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithAriaControls {}
@@ -1352,7 +1341,6 @@ class CheckboxWithAriaControls {}
 /** Simple test component with an aria-owns set. */
 @Component({
   template: `<mat-checkbox aria-owns="some-id"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithAriaOwns {}
@@ -1360,7 +1348,6 @@ class CheckboxWithAriaOwns {}
 /** Simple test component with name attribute */
 @Component({
   template: `<mat-checkbox name="test-name"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithNameAttribute {}
@@ -1368,7 +1355,6 @@ class CheckboxWithNameAttribute {}
 /** Simple test component with change event */
 @Component({
   template: `<mat-checkbox (change)="lastEvent = $event"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithChangeEvent {
@@ -1378,7 +1364,6 @@ class CheckboxWithChangeEvent {
 /** Test component with reactive forms */
 @Component({
   template: `<mat-checkbox [formControl]="formControl"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox, ReactiveFormsModule],
 })
 class CheckboxWithFormControl {
@@ -1388,7 +1373,6 @@ class CheckboxWithFormControl {
 /** Test component without label */
 @Component({
   template: `<mat-checkbox>{{ label }}</mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithoutLabel {
@@ -1398,14 +1382,12 @@ class CheckboxWithoutLabel {
 /** Test component with the native tabindex attribute. */
 @Component({
   template: `<mat-checkbox tabindex="5"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithTabindexAttr {}
 
 @Component({
   template: `<mat-checkbox aria-label="Checkbox" aria-labelledby="something"></mat-checkbox>`,
-  standalone: true,
   imports: [MatCheckbox],
 })
 class CheckboxWithStaticAriaAttributes {}
diff --git a/src/material/checkbox/checkbox.ts b/src/material/checkbox/checkbox.ts
index 4f029f8fe5e6..e3912918f156 100644
--- a/src/material/checkbox/checkbox.ts
+++ b/src/material/checkbox/checkbox.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {FocusableOption} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusableOption} from '@angular/cdk/a11y';
 import {
   ANIMATION_MODULE_TYPE,
   AfterViewInit,
@@ -77,9 +77,6 @@ export class MatCheckboxChange {
   checked: boolean;
 }
 
-// Increasing integer for generating unique ids for checkbox components.
-let nextUniqueId = 0;
-
 // Default checkbox configuration.
 const defaults = MAT_CHECKBOX_DEFAULT_OPTIONS_FACTORY();
 
@@ -225,10 +222,10 @@ export class MatCheckbox
   // the lack of type checking previously and assigning random strings.
   /**
    * Theme color of the checkbox. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/checkbox/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: string | undefined;
 
@@ -255,7 +252,7 @@ export class MatCheckbox
     this._options = this._options || defaults;
     this.color = this._options.color || defaults.color;
     this.tabIndex = tabIndex == null ? 0 : parseInt(tabIndex) || 0;
-    this.id = this._uniqueId = `mat-mdc-checkbox-${++nextUniqueId}`;
+    this.id = this._uniqueId = inject(_IdGenerator).getId('mat-mdc-checkbox-');
     this.disabledInteractive = this._options?.disabledInteractive ?? false;
   }
 
diff --git a/src/material/checkbox/testing/checkbox-harness.spec.ts b/src/material/checkbox/testing/checkbox-harness.spec.ts
index 5d5d9fc2fcbc..aabff5d91b00 100644
--- a/src/material/checkbox/testing/checkbox-harness.spec.ts
+++ b/src/material/checkbox/testing/checkbox-harness.spec.ts
@@ -199,7 +199,6 @@ describe('MatCheckboxHarness', () => {
     </mat-checkbox>
     <span id="second-label">Second checkbox</span>
   `,
-  standalone: true,
   imports: [MatCheckboxModule, ReactiveFormsModule],
 })
 class CheckboxHarnessTest {
diff --git a/src/material/chips/chip-edit-input.spec.ts b/src/material/chips/chip-edit-input.spec.ts
index e7207d94529f..5a056f48fc0e 100644
--- a/src/material/chips/chip-edit-input.spec.ts
+++ b/src/material/chips/chip-edit-input.spec.ts
@@ -42,7 +42,6 @@ describe('MatChipEditInput', () => {
 
 @Component({
   template: `<mat-chip><span matChipEditInput></span></mat-chip>`,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class ChipEditInputContainer {}
diff --git a/src/material/chips/chip-grid.ts b/src/material/chips/chip-grid.ts
index 772611f619c4..9e0132d0e5d2 100644
--- a/src/material/chips/chip-grid.ts
+++ b/src/material/chips/chip-grid.ts
@@ -129,6 +129,7 @@ export class MatChipGrid
   override set disabled(value: boolean) {
     this._disabled = value;
     this._syncChipsState();
+    this.stateChanges.next();
   }
 
   /**
diff --git a/src/material/chips/chip-input.ts b/src/material/chips/chip-input.ts
index ce79c55d40fe..6c6c68be4063 100644
--- a/src/material/chips/chip-input.ts
+++ b/src/material/chips/chip-input.ts
@@ -18,6 +18,7 @@ import {
   booleanAttribute,
   inject,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {MatFormField, MAT_FORM_FIELD} from '@angular/material/form-field';
 import {MatChipsDefaultOptions, MAT_CHIPS_DEFAULT_OPTIONS} from './tokens';
 import {MatChipGrid} from './chip-grid';
@@ -39,9 +40,6 @@ export interface MatChipInputEvent {
   chipInput: MatChipInput;
 }
 
-// Increasing integer for generating unique ids.
-let nextUniqueId = 0;
-
 /**
  * Directive that adds chip-specific behaviors to an input element inside `<mat-form-field>`.
  * May be placed inside or outside of a `<mat-chip-grid>`.
@@ -107,7 +105,7 @@ export class MatChipInput implements MatChipTextControl, OnChanges, OnDestroy {
   @Input() placeholder: string = '';
 
   /** Unique id for the input. */
-  @Input() id: string = `mat-mdc-chip-list-input-${nextUniqueId++}`;
+  @Input() id: string = inject(_IdGenerator).getId('mat-mdc-chip-list-input-');
 
   /** Whether the input is disabled. */
   @Input({transform: booleanAttribute})
diff --git a/src/material/chips/chip-remove.spec.ts b/src/material/chips/chip-remove.spec.ts
index 4c05cf46d9ec..3e7525af81f4 100644
--- a/src/material/chips/chip-remove.spec.ts
+++ b/src/material/chips/chip-remove.spec.ts
@@ -116,7 +116,6 @@ describe('Chip Remove', () => {
       </mat-chip>
     </mat-chip-set>
   `,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class TestChip {
diff --git a/src/material/chips/chip-row.spec.ts b/src/material/chips/chip-row.spec.ts
index 545e22d86171..57f55050a712 100644
--- a/src/material/chips/chip-row.spec.ts
+++ b/src/material/chips/chip-row.spec.ts
@@ -424,7 +424,6 @@ describe('Row Chips', () => {
         </div>
       }
     </mat-chip-grid>`,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class SingleChip {
diff --git a/src/material/chips/chip-set.spec.ts b/src/material/chips/chip-set.spec.ts
index 61192a4328a7..c64eef460db0 100644
--- a/src/material/chips/chip-set.spec.ts
+++ b/src/material/chips/chip-set.spec.ts
@@ -115,7 +115,6 @@ describe('MatChipSet', () => {
         }
       </mat-chip-set>
   `,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class BasicChipSet {
@@ -133,7 +132,6 @@ class BasicChipSet {
       }
     </mat-chip-set>
   `,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class IndirectDescendantsChipSet extends BasicChipSet {}
diff --git a/src/material/chips/chip.spec.ts b/src/material/chips/chip.spec.ts
index cd022b7ec7a3..35b54129637a 100644
--- a/src/material/chips/chip.spec.ts
+++ b/src/material/chips/chip.spec.ts
@@ -164,7 +164,6 @@ describe('MatChip', () => {
         </div>
       }
     </mat-chip-set>`,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class SingleChip {
@@ -183,21 +182,18 @@ class SingleChip {
 
 @Component({
   template: `<mat-basic-chip>Hello</mat-basic-chip>`,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class BasicChip {}
 
 @Component({
   template: `<mat-basic-chip role="button" tabindex="3">Hello</mat-basic-chip>`,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class BasicChipWithStaticTabindex {}
 
 @Component({
   template: `<mat-basic-chip role="button" [tabIndex]="tabindex">Hello</mat-basic-chip>`,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class BasicChipWithBoundTabindex {
diff --git a/src/material/chips/chip.ts b/src/material/chips/chip.ts
index 9f6434ac5d5d..e1eecfaef157 100644
--- a/src/material/chips/chip.ts
+++ b/src/material/chips/chip.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {FocusMonitor} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusMonitor} from '@angular/cdk/a11y';
 import {BACKSPACE, DELETE} from '@angular/cdk/keycodes';
 import {DOCUMENT} from '@angular/common';
 import {
@@ -46,8 +46,6 @@ import {MatChipAvatar, MatChipRemove, MatChipTrailingIcon} from './chip-icons';
 import {MAT_CHIP, MAT_CHIP_AVATAR, MAT_CHIP_REMOVE, MAT_CHIP_TRAILING_ICON} from './tokens';
 import {_CdkPrivateStyleLoader, _VisuallyHiddenLoader} from '@angular/cdk/private';
 
-let uid = 0;
-
 /** Represents an event fired on an individual `mat-chip`. */
 export interface MatChipEvent {
   /** The chip the event was fired on. */
@@ -142,7 +140,7 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
   }
 
   /** A unique id for the chip. If none is supplied, it will be auto-generated. */
-  @Input() id: string = `mat-mdc-chip-${uid++}`;
+  @Input() id: string = inject(_IdGenerator).getId('mat-mdc-chip-');
 
   // TODO(#26104): Consider deprecating and using `_computeAriaAccessibleName` instead.
   // `ariaLabel` may be unnecessary, and `_computeAriaAccessibleName` only supports
@@ -180,10 +178,10 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
   // TODO: should be typed as `ThemePalette` but internal apps pass in arbitrary strings.
   /**
    * Theme color of the chip. This API is supported in M2 themes only, it has no
-   * effect in M3 themes.
+   * effect in M3 themes. For color customization in M3, see https://material.angular.io/components/chips/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color?: string | null;
 
diff --git a/src/material/chips/testing/chip-grid-harness.spec.ts b/src/material/chips/testing/chip-grid-harness.spec.ts
index 0e022287be52..30fb679e7389 100644
--- a/src/material/chips/testing/chip-grid-harness.spec.ts
+++ b/src/material/chips/testing/chip-grid-harness.spec.ts
@@ -135,7 +135,6 @@ describe('MatChipGridHarness', () => {
       <input [matChipInputFor]="grid"/>
     </mat-chip-grid>
   `,
-  standalone: true,
   imports: [MatChipsModule, ReactiveFormsModule],
 })
 class ChipGridHarnessTest {
diff --git a/src/material/chips/testing/chip-harness.spec.ts b/src/material/chips/testing/chip-harness.spec.ts
index 64c2ec44e4c4..2509afa602e3 100644
--- a/src/material/chips/testing/chip-harness.spec.ts
+++ b/src/material/chips/testing/chip-harness.spec.ts
@@ -94,7 +94,6 @@ describe('MatChipHarness', () => {
     </mat-chip>
     <mat-chip-row (removed)="removeChip()">Chip Row</mat-chip-row>
   `,
-  standalone: true,
   imports: [MatChipsModule, MatIconModule],
 })
 class ChipHarnessTest {
diff --git a/src/material/chips/testing/chip-input-harness.spec.ts b/src/material/chips/testing/chip-input-harness.spec.ts
index 913087581098..2172c1b1aa18 100644
--- a/src/material/chips/testing/chip-input-harness.spec.ts
+++ b/src/material/chips/testing/chip-input-harness.spec.ts
@@ -94,7 +94,6 @@ describe('MatChipInputHarness', () => {
       <input [matChipInputFor]="grid2" disabled />
     </mat-chip-grid>
   `,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class ChipInputHarnessTest {
diff --git a/src/material/chips/testing/chip-listbox-harness.spec.ts b/src/material/chips/testing/chip-listbox-harness.spec.ts
index 237706b1e8eb..c3db9add005f 100644
--- a/src/material/chips/testing/chip-listbox-harness.spec.ts
+++ b/src/material/chips/testing/chip-listbox-harness.spec.ts
@@ -125,7 +125,6 @@ describe('MatChipListboxHarness', () => {
       }
     </mat-chip-listbox>
   `,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class ChipListboxHarnessTest {
diff --git a/src/material/chips/testing/chip-option-harness.spec.ts b/src/material/chips/testing/chip-option-harness.spec.ts
index 44a1a21eb721..5f5be693bcd8 100644
--- a/src/material/chips/testing/chip-option-harness.spec.ts
+++ b/src/material/chips/testing/chip-option-harness.spec.ts
@@ -88,7 +88,6 @@ describe('MatChipOptionHarness', () => {
       </mat-chip-option>
     </mat-chip-listbox>
   `,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class ChipOptionHarnessTest {}
diff --git a/src/material/chips/testing/chip-row-harness.spec.ts b/src/material/chips/testing/chip-row-harness.spec.ts
index 6f62fc3b0453..419e96d104eb 100644
--- a/src/material/chips/testing/chip-row-harness.spec.ts
+++ b/src/material/chips/testing/chip-row-harness.spec.ts
@@ -41,7 +41,6 @@ describe('MatChipRowHarness', () => {
       <input [matChipInputFor]="grid" />
     </mat-chip-grid>
   `,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class ChipRowHarnessTest {
diff --git a/src/material/chips/testing/chip-set-harness.spec.ts b/src/material/chips/testing/chip-set-harness.spec.ts
index 576784f358df..2d5bc7b3af14 100644
--- a/src/material/chips/testing/chip-set-harness.spec.ts
+++ b/src/material/chips/testing/chip-set-harness.spec.ts
@@ -39,7 +39,6 @@ describe('MatChipSetHarness', () => {
       <mat-chip> Chip C </mat-chip>
     </mat-chip-set>
   `,
-  standalone: true,
   imports: [MatChipsModule],
 })
 class ChipSetHarnessTest {}
diff --git a/src/material/chips/tokens.ts b/src/material/chips/tokens.ts
index 197c3fa4d502..9e70ec83fbf1 100644
--- a/src/material/chips/tokens.ts
+++ b/src/material/chips/tokens.ts
@@ -14,7 +14,7 @@ export interface MatChipsDefaultOptions {
   /** The list of key codes that will trigger a chipEnd event. */
   separatorKeyCodes: readonly number[] | ReadonlySet<number>;
 
-  /** Wheter icon indicators should be hidden for single-selection. */
+  /** Whether icon indicators should be hidden for single-selection. */
   hideSingleSelectionIndicator?: boolean;
 }
 
diff --git a/src/material/core/m2/_theming.scss b/src/material/core/m2/_theming.scss
index 10f5bf50876e..9bdf01f26828 100644
--- a/src/material/core/m2/_theming.scss
+++ b/src/material/core/m2/_theming.scss
@@ -1,6 +1,7 @@
 @use 'sass:list';
 @use 'sass:map';
 @use 'sass:meta';
+@use 'sass:color';
 @use '../theming/theming';
 @use './palette';
 
@@ -82,7 +83,7 @@
     @return $color;
   }
 
-  @return rgba($color, if($opacity == null, opacity($color), $opacity));
+  @return rgba($color, if($opacity == null, color.opacity($color), $opacity));
 }
 
 // Validates the specified theme by ensuring that the optional color config defines
diff --git a/src/material/core/option/optgroup.scss b/src/material/core/option/optgroup.scss
index c46707607b84..f46bf360f39d 100644
--- a/src/material/core/option/optgroup.scss
+++ b/src/material/core/option/optgroup.scss
@@ -42,5 +42,6 @@
     text-decoration: inherit;
     text-transform: inherit;
     white-space: normal;
+    color: inherit;
   }
 }
diff --git a/src/material/core/option/optgroup.ts b/src/material/core/option/optgroup.ts
index 9a55b679cdfa..4e7b7fe154e6 100644
--- a/src/material/core/option/optgroup.ts
+++ b/src/material/core/option/optgroup.ts
@@ -15,6 +15,7 @@ import {
   booleanAttribute,
   inject,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {MatOptionParentComponent, MAT_OPTION_PARENT_COMPONENT} from './option-parent';
 
 // Notes on the accessibility pattern used for `mat-optgroup`.
@@ -37,9 +38,6 @@ import {MatOptionParentComponent, MAT_OPTION_PARENT_COMPONENT} from './option-pa
 // 3. `<mat-option aria-labelledby="optionLabel groupLabel"` - This works on Chrome, but Safari
 //     doesn't read out the text at all. Furthermore, on
 
-// Counter for unique group ids.
-let _uniqueOptgroupIdCounter = 0;
-
 /**
  * Injection token that can be used to reference instances of `MatOptgroup`. It serves as
  * alternative token to the actual `MatOptgroup` class which could cause unnecessary
@@ -73,7 +71,7 @@ export class MatOptgroup {
   @Input({transform: booleanAttribute}) disabled: boolean = false;
 
   /** Unique id for the underlying label. */
-  _labelId: string = `mat-optgroup-label-${_uniqueOptgroupIdCounter++}`;
+  _labelId: string = inject(_IdGenerator).getId('mat-optgroup-label-');
 
   /** Whether the group is in inert a11y mode. */
   _inert: boolean;
diff --git a/src/material/core/option/option.spec.ts b/src/material/core/option/option.spec.ts
index cd0fd98aaf65..a358a65f93a5 100644
--- a/src/material/core/option/option.spec.ts
+++ b/src/material/core/option/option.spec.ts
@@ -243,7 +243,6 @@ describe('MatOption component', () => {
 
 @Component({
   template: `<mat-option [id]="id()" [disabled]="disabled()"></mat-option>`,
-  standalone: true,
   imports: [MatOptionModule],
 })
 class BasicOption {
@@ -257,7 +256,6 @@ class BasicOption {
       <mat-option>Option</mat-option>
     </mat-optgroup>
   `,
-  standalone: true,
   imports: [MatOptionModule],
 })
 class InsideGroup {}
diff --git a/src/material/core/option/option.ts b/src/material/core/option/option.ts
index 987bccfcbde6..3b5b211f206c 100644
--- a/src/material/core/option/option.ts
+++ b/src/material/core/option/option.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {FocusableOption, FocusOrigin} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusableOption, FocusOrigin} from '@angular/cdk/a11y';
 import {ENTER, hasModifierKey, SPACE} from '@angular/cdk/keycodes';
 import {
   Component,
@@ -34,12 +34,6 @@ import {MatPseudoCheckbox} from '../selection/pseudo-checkbox/pseudo-checkbox';
 import {_StructuralStylesLoader} from '../focus-indicators/structural-styles';
 import {_CdkPrivateStyleLoader, _VisuallyHiddenLoader} from '@angular/cdk/private';
 
-/**
- * Option IDs need to be unique across components, so this counter exists outside of
- * the component definition.
- */
-let _uniqueIdCounter = 0;
-
 /** Event object emitted by MatOption when selected or deselected. */
 export class MatOptionSelectionChange<T = any> {
   constructor(
@@ -110,7 +104,7 @@ export class MatOption<T = any> implements FocusableOption, AfterViewChecked, On
   @Input() value: T;
 
   /** The unique ID of the option. */
-  @Input() id: string = `mat-option-${_uniqueIdCounter++}`;
+  @Input() id: string = inject(_IdGenerator).getId('mat-option-');
 
   /** Whether the option is disabled. */
   @Input({transform: booleanAttribute})
diff --git a/src/material/core/ripple/ripple.spec.ts b/src/material/core/ripple/ripple.spec.ts
index 96019a45fcd8..5a42b6eb9920 100644
--- a/src/material/core/ripple/ripple.spec.ts
+++ b/src/material/core/ripple/ripple.spec.ts
@@ -836,7 +836,6 @@ describe('MatRipple', () => {
          style="position: relative; width:300px; height:200px;">
     </div>
   `,
-  standalone: true,
   imports: [MatRippleModule],
 })
 class BasicRippleContainer {
@@ -856,7 +855,6 @@ class BasicRippleContainer {
     </div>
     <div class="alternateTrigger"></div>
   `,
-  standalone: true,
   imports: [MatRippleModule],
 })
 class RippleContainerWithInputBindings {
@@ -871,14 +869,12 @@ class RippleContainerWithInputBindings {
 
 @Component({
   template: `<div id="container" #ripple="matRipple" matRipple></div>`,
-  standalone: true,
   imports: [MatRippleModule],
 })
 class RippleContainerWithoutBindings {}
 
 @Component({
   template: `@if (!isDestroyed) {<div id="container" matRipple></div>}`,
-  standalone: true,
   imports: [MatRippleModule],
 })
 class RippleContainerWithNgIf {
@@ -890,7 +886,6 @@ class RippleContainerWithNgIf {
   styles: `* { transition: none !important; }`,
   template: `<div id="container" matRipple></div>`,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [MatRippleModule],
 })
 class RippleCssTransitionNone {}
@@ -899,7 +894,6 @@ class RippleCssTransitionNone {}
   styles: `* { transition-duration: 0ms !important; }`,
   template: `<div id="container" matRipple></div>`,
   encapsulation: ViewEncapsulation.None,
-  standalone: true,
   imports: [MatRippleModule],
 })
 class RippleCssTransitionDurationZero {}
@@ -910,7 +904,6 @@ class RippleCssTransitionDurationZero {}
       <div (click)="show = false" matRipple>Click to remove this element.</div>
     }
   `,
-  standalone: true,
   imports: [MatRippleModule],
 })
 class RippleWithDomRemovalOnClick {
diff --git a/src/material/core/ripple/ripple.zone.spec.ts b/src/material/core/ripple/ripple.zone.spec.ts
index 3ec711a2536a..01dbc761c150 100644
--- a/src/material/core/ripple/ripple.zone.spec.ts
+++ b/src/material/core/ripple/ripple.zone.spec.ts
@@ -52,7 +52,6 @@ describe('MatRipple Zone.js integration', () => {
            style="position: relative; width:300px; height:200px;">
       </div>
     `,
-  standalone: true,
   imports: [MatRippleModule],
 })
 class BasicRippleContainer {
diff --git a/src/material/core/testing/optgroup-harness.spec.ts b/src/material/core/testing/optgroup-harness.spec.ts
index 465418099898..f2fc0492d5ae 100644
--- a/src/material/core/testing/optgroup-harness.spec.ts
+++ b/src/material/core/testing/optgroup-harness.spec.ts
@@ -72,7 +72,6 @@ describe('MatOptgroupHarness', () => {
       <mat-option>Disabled option 1</mat-option>
     </mat-optgroup>
   `,
-  standalone: true,
   imports: [MatOptionModule],
 })
 class OptgroupHarnessTest {}
diff --git a/src/material/core/testing/option-harness.spec.ts b/src/material/core/testing/option-harness.spec.ts
index 1d94e7cff299..c10cba3afc89 100644
--- a/src/material/core/testing/option-harness.spec.ts
+++ b/src/material/core/testing/option-harness.spec.ts
@@ -112,7 +112,6 @@ describe('MatOptionHarness', () => {
     <mat-option>Plain option</mat-option>
     <mat-option disabled>Disabled option</mat-option>
   `,
-  standalone: true,
   imports: [MatOptionModule],
 })
 class OptionHarnessTest implements MatOptionParentComponent {
diff --git a/src/material/core/theming/_inspection.scss b/src/material/core/theming/_inspection.scss
index 7747097aa126..0f0e11fcb4b4 100644
--- a/src/material/core/theming/_inspection.scss
+++ b/src/material/core/theming/_inspection.scss
@@ -62,10 +62,17 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac
   }
 }
 
-/// Gets a color from a theme object. This function can take 2 or 3 arguments. If 2 arguments are
-/// passed, the second argument is treated as the name of a color role. If 3 arguments are passed,
-/// the second argument is treated as the name of a color palette (primary, secondary, etc.) and the
-/// third is treated as the palette hue (10, 50, etc.)
+/// Gets a color from a theme object. This function take a different amount of arguments depending
+/// on if it's working with an M2 or M3 theme:
+/// - With an M3 theme it accepts either 2 or 3 arguments. If 2 arguments are passed, the second
+/// argument is treated as the name of a color role. If 3 arguments are passed, the second argument
+/// is treated as the name of a color palette (primary, secondary, etc.) and the third is treated
+/// as the palette hue (10, 50, etc.).
+/// - With an M2 theme theme it accepts between 2 and 4 arguments, or the equivalent of calling
+/// the `m2-get-theme-color` function. The first argument is the theme, the second one is the
+/// palette from which to extract the color, the third one is the hue within the palette and the
+/// fourth is the opacity of the returned color.
+/// the second one is the
 /// @param {Map} $theme The theme
 /// @param {String} $color-role-or-palette-name The name of the color role to get, or the name of a
 ///   color palette.
@@ -74,25 +81,29 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac
 /// @return {Color} The requested theme color.
 @function get-theme-color($theme, $args...) {
   $version: get-theme-version($theme);
-  $args-count: list.length($args);
-  @if $args-count != 1 and $args-count != 2 and $args-count != 3 {
-    @error #{'Expected between 2 and 4 arguments. Got:'} $args-count + 1;
-  }
+  $args-count: list.length($args) + 1;
 
+  // M2 theme
   @if $version == 0 {
+    @if $args-count < 2 or $args-count > 4 {
+      @error 'Expected between 2 and 4 arguments when working with an M2 theme. ' +
+             'Got: #{$args-count}';
+    }
     @return m2-inspection.get-theme-color($theme, $args...);
   }
-  @else if $version == 1 {
-    @if $args-count == 1 {
-      @return _get-theme-role-color($theme, $args...);
-    }
-    @else if $args-count == 2 {
-      @return _get-theme-palette-color($theme, $args...);
+
+  // M3 theme
+  @if $version == 1 {
+    @if $args-count < 2 or $args-count > 3 {
+      @error 'Expected either 2 or 3 arguments when working with an M3 theme. Got: #{$args-count}';
     }
+    @return if($args-count == 2,
+      _get-theme-role-color($theme, $args...),
+      _get-theme-palette-color($theme, $args...)
+    );
   }
-  @else {
-    @error #{'Unrecognized theme version:'} $version;
-  }
+
+  @error 'Unrecognized theme version: #{$version}';
 }
 
 /// Gets a role color from a theme object.
diff --git a/src/material/core/theming/_m2-inspection.scss b/src/material/core/theming/_m2-inspection.scss
index 6463b26d3ebd..f096009282ff 100644
--- a/src/material/core/theming/_m2-inspection.scss
+++ b/src/material/core/theming/_m2-inspection.scss
@@ -102,14 +102,14 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac
   @return if(map.get($colors, is-dark), dark, light);
 }
 
-/// Gets a color from a theme object. This function can take 2 or 3 arguments. If 2 arguments are
-/// passed, the second argument is treated as the name of a color role. If 3 arguments are passed,
-/// the second argument is treated as the name of a color palette (primary, secondary, etc.) and the
-/// third is treated as the palette hue (10, 50, etc.)
+/// Gets a color from a theme object. This function can take between 2 and 4 arguments. The first
+/// argument is the theme, the second one is the palette from which to extract the color, the third
+/// one is the hue within the palette and the fourth is the opacity of the returned color.
 /// @param {Map} $theme The theme
 /// @param {String} $palette-name The name of a color palette.
 /// @param {Number} $hue The palette hue to get (passing this argument means the second argument is
 ///   interpreted as a palette name).
+/// @param {Number} $opacity The alpha channel value for the color.
 /// @return {Color} The requested theme color.
 @function get-theme-color($theme, $palette-name, $args...) {
   $theme: _get-m2-config($theme);
diff --git a/src/material/core/theming/_theming.scss b/src/material/core/theming/_theming.scss
index 89d391b3334e..c10879a7bc19 100644
--- a/src/material/core/theming/_theming.scss
+++ b/src/material/core/theming/_theming.scss
@@ -2,6 +2,7 @@
 @use 'sass:map';
 @use 'sass:math';
 @use 'sass:meta';
+@use 'sass:color';
 
 // Whether to enable compatibility with legacy methods for accessing theme information.
 $theme-legacy-inspection-api-compatibility: true !default;
@@ -14,7 +15,7 @@ $_generate-default-density: true !default;
 
 // Warning that will be printed if duplicated styles are generated by a theme.
 $_duplicate-warning: 'Read more about how style duplication can be avoided in a dedicated ' +
-  'guide. https://github.com/angular/components/blob/main/guides/duplicate-theming-styles.md';
+  'guide. https://v18.material.angular.io/guide/duplicate-theming-styles';
 
 // Warning that will be printed if the legacy theming API is used.
 $private-legacy-theme-warning: 'Angular Material themes should be created from a map containing ' +
@@ -332,7 +333,7 @@ $private-internal-name: _mat-theming-internals-do-not-access;
   // We convert the rgba color into a solid one by taking the opacity from the rgba
   // value and using it to determine the percentage of the background to put
   // into foreground when mixing the colors together.
-  @return mix($background-color, rgba($color, 1), (1 - opacity($color)) * 100%);
+  @return color.mix($background-color, rgba($color, 1), (1 - color.opacity($color)) * 100%);
 }
 
 // Clamps the density scale to a number between the given min and max.
diff --git a/src/material/core/theming/prebuilt/azure-blue.scss b/src/material/core/theming/prebuilt/azure-blue.scss
index d9d6ee55eec3..78c29f247c34 100644
--- a/src/material/core/theming/prebuilt/azure-blue.scss
+++ b/src/material/core/theming/prebuilt/azure-blue.scss
@@ -1,27 +1,14 @@
-@use '../../theming/definition';
-@use '../../theming/color-api-backwards-compatibility';
 @use '../../theming/palettes';
-@use '../all-theme';
-@use '../../core';
-@use '../../typography/typography';
-
-@include core.app-background();
-@include core.elevation-classes();
-
-$theme: definition.define-theme((
-  color: (
-    theme-type: light,
-    primary: palettes.$azure-palette,
-    tertiary: palettes.$blue-palette,
-  ),
-  density: (
-    scale: 0,
-  )
-));
+@use '../../../core/tokens/m3-system';
 
 html {
-  @include all-theme.all-component-themes($theme);
+  @include m3-system.theme((
+    color: (
+      theme-type: light,
+      primary: palettes.$azure-palette,
+      tertiary: palettes.$blue-palette,
+    ),
+    typography: Roboto,
+    density: 0,
+  ));
 }
-
-@include color-api-backwards-compatibility.color-variants-backwards-compatibility($theme);
-@include typography.typography-hierarchy($theme);
diff --git a/src/material/core/theming/prebuilt/cyan-orange.scss b/src/material/core/theming/prebuilt/cyan-orange.scss
index 40eec288ef57..8146612e175f 100644
--- a/src/material/core/theming/prebuilt/cyan-orange.scss
+++ b/src/material/core/theming/prebuilt/cyan-orange.scss
@@ -1,27 +1,14 @@
-@use '../../theming/definition';
-@use '../../theming/color-api-backwards-compatibility';
 @use '../../theming/palettes';
-@use '../all-theme';
-@use '../../core';
-@use '../../typography/typography';
-
-@include core.app-background();
-@include core.elevation-classes();
-
-$theme: definition.define-theme((
-  color: (
-    theme-type: dark,
-    primary: palettes.$cyan-palette,
-    tertiary: palettes.$orange-palette,
-  ),
-  density: (
-    scale: 0,
-  )
-));
+@use '../../../core/tokens/m3-system';
 
 html {
-  @include all-theme.all-component-themes($theme);
+  @include m3-system.theme((
+    color: (
+      theme-type: dark,
+      primary: palettes.$cyan-palette,
+      tertiary: palettes.$orange-palette,
+    ),
+    typography: Roboto,
+    density: 0,
+  ));
 }
-
-@include color-api-backwards-compatibility.color-variants-backwards-compatibility($theme);
-@include typography.typography-hierarchy($theme);
diff --git a/src/material/core/theming/prebuilt/magenta-violet.scss b/src/material/core/theming/prebuilt/magenta-violet.scss
index fe9084c0e17b..ab3cde2da5e4 100644
--- a/src/material/core/theming/prebuilt/magenta-violet.scss
+++ b/src/material/core/theming/prebuilt/magenta-violet.scss
@@ -1,27 +1,14 @@
-@use '../../theming/definition';
-@use '../../theming/color-api-backwards-compatibility';
 @use '../../theming/palettes';
-@use '../all-theme';
-@use '../../core';
-@use '../../typography/typography';
-
-@include core.app-background();
-@include core.elevation-classes();
-
-$theme: definition.define-theme((
-  color: (
-    theme-type: dark,
-    primary: palettes.$magenta-palette,
-    tertiary: palettes.$violet-palette,
-  ),
-  density: (
-    scale: 0,
-  )
-));
+@use '../../../core/tokens/m3-system';
 
 html {
-  @include all-theme.all-component-themes($theme);
+  @include m3-system.theme((
+    color: (
+      theme-type: dark,
+      primary: palettes.$magenta-palette,
+      tertiary: palettes.$violet-palette,
+    ),
+    typography: Roboto,
+    density: 0,
+  ));
 }
-
-@include color-api-backwards-compatibility.color-variants-backwards-compatibility($theme);
-@include typography.typography-hierarchy($theme);
diff --git a/src/material/core/theming/prebuilt/rose-red.scss b/src/material/core/theming/prebuilt/rose-red.scss
index 8e82d0e14f1c..c3114e9586b1 100644
--- a/src/material/core/theming/prebuilt/rose-red.scss
+++ b/src/material/core/theming/prebuilt/rose-red.scss
@@ -1,27 +1,14 @@
-@use '../../theming/definition';
-@use '../../theming/color-api-backwards-compatibility';
 @use '../../theming/palettes';
-@use '../all-theme';
-@use '../../core';
-@use '../../typography/typography';
-
-@include core.app-background();
-@include core.elevation-classes();
-
-$theme: definition.define-theme((
-  color: (
-    theme-type: light,
-    primary: palettes.$rose-palette,
-    tertiary: palettes.$red-palette,
-  ),
-  density: (
-    scale: 0,
-  )
-));
+@use '../../../core/tokens/m3-system';
 
 html {
-  @include all-theme.all-component-themes($theme);
+  @include m3-system.theme((
+    color: (
+      theme-type: light,
+      primary: palettes.$rose-palette,
+      tertiary: palettes.$red-palette,
+    ),
+    typography: Roboto,
+    density: 0,
+  ));
 }
-
-@include color-api-backwards-compatibility.color-variants-backwards-compatibility($theme);
-@include typography.typography-hierarchy($theme);
diff --git a/src/material/core/theming/tests/theming-inspection-api.spec.ts b/src/material/core/theming/tests/theming-inspection-api.spec.ts
index 6d3f9b74f5aa..19c2372e3a9c 100644
--- a/src/material/core/theming/tests/theming-inspection-api.spec.ts
+++ b/src/material/core/theming/tests/theming-inspection-api.spec.ts
@@ -315,7 +315,7 @@ describe('theming inspection api', () => {
             color: mat.get-theme-color($theme);
           }
         `),
-      ).toThrowError(/Expected between 2 and 4 arguments\. Got: 1/);
+      ).toThrowError(/Expected either 2 or 3 arguments when working with an M3 theme\. Got: 1/);
     });
 
     it('should get typography properties from theme', () => {
diff --git a/src/material/core/tokens/_m3-system.scss b/src/material/core/tokens/_m3-system.scss
index fc39e84f3d63..2a836cf8e531 100644
--- a/src/material/core/tokens/_m3-system.scss
+++ b/src/material/core/tokens/_m3-system.scss
@@ -83,7 +83,6 @@
   }
 
   @include system-level-shape($overrides: $overrides, $prefix: definition.$system-fallback-prefix);
-  @include system-level-motion($overrides:$overrides, $prefix: definition.$system-fallback-prefix);
   @include system-level-state($overrides: $overrides, $prefix: definition.$system-fallback-prefix);
 }
 
@@ -221,14 +220,6 @@
   }
 }
 
-@mixin system-level-motion($theme: (), $overrides: (), $prefix: definition.$system-level-prefix) {
-  & {
-    @each $name, $value in definitions.md-sys-motion-values() {
-      --#{$prefix}-#{$name}: #{map.get($overrides, $name) or $value};
-    }
-  }
-}
-
 // Return a new map where the values are the same as the provided map's
 // keys, prefixed with "--mat-sys-". For example:
 // (key1: '', key2: '') --> (key1: --mat-sys-key1, key2: --mat-sys-key2)
diff --git a/src/material/core/tokens/_m3-tokens.scss b/src/material/core/tokens/_m3-tokens.scss
index a016fef15c16..0cde0b8f5763 100644
--- a/src/material/core/tokens/_m3-tokens.scss
+++ b/src/material/core/tokens/_m3-tokens.scss
@@ -130,7 +130,7 @@ $_cached-token-slots: null;
 @function create-map($keys, $prefix) {
   $result: ();
   @each $key in $keys {
-    $result: map-merge($result, ($key: var(--#{$prefix}-#{$key})));
+    $result: map.merge($result, ($key: var(--#{$prefix}-#{$key})));
   }
   @return $result;
 }
@@ -191,8 +191,8 @@ $_cached-token-slots: null;
             'tertiary-fixed',
             'tertiary-fixed-dim'
     );
-    @return map-merge(create-map($keys, $prefix), (
-            shadow: map.get($mdc-sys-color, shadow)
+    @return map.merge(create-map($keys, $prefix), (
+      shadow: map.get($mdc-sys-color, shadow)
     ));
   }
 
diff --git a/src/material/core/tokens/_token-definition.scss b/src/material/core/tokens/_token-definition.scss
index 1208b89d9af9..aa4803556ca6 100644
--- a/src/material/core/tokens/_token-definition.scss
+++ b/src/material/core/tokens/_token-definition.scss
@@ -124,11 +124,12 @@ $_system-fallbacks: null;
 /// Maps the values in a map to new values using the given mapping function
 /// @param {Map} $map The maps whose values will be mapped to new values.
 /// @param {Function} $fn The value mapping function.
-/// @param {Map} A new map with its values updated using the mapping function.
-@function map-values($map, $fn) {
+/// @param {ArgList} $args Additional arguments to pass to the mapping function.
+/// @return {Map} A new map with its values updated using the mapping function.
+@function map-values($map, $fn, $args...) {
   $result: ();
   @each $key, $value in $map {
-    $result: map.set($result, $key, meta.call($fn, $value));
+    $result: map.set($result, $key, meta.call($fn, $value, $args...));
   }
   @return $result;
 }
diff --git a/src/material/core/tokens/m2/mat/_badge.scss b/src/material/core/tokens/m2/mat/_badge.scss
index 8e93f5750345..8ad24b1701d7 100644
--- a/src/material/core/tokens/m2/mat/_badge.scss
+++ b/src/material/core/tokens/m2/mat/_badge.scss
@@ -56,7 +56,7 @@ $prefix: (mat, badge);
   // the value to determine the percentage of the background to put into foreground when
   // mixing the colors together.
   @if (meta.type-of($disabled-background) == color and meta.type-of($app-background) == color) {
-    $badge-opacity: opacity($disabled-background);
+    $badge-opacity: color.opacity($disabled-background);
     $disabled-background: color.mix($app-background,
       rgba($disabled-background, 1), (1 - $badge-opacity) * 100%);
   }
diff --git a/src/material/core/tokens/m2/mat/_datepicker.scss b/src/material/core/tokens/m2/mat/_datepicker.scss
index 18231a105e99..c586fb125fbe 100644
--- a/src/material/core/tokens/m2/mat/_datepicker.scss
+++ b/src/material/core/tokens/m2/mat/_datepicker.scss
@@ -60,7 +60,7 @@ $private-default-overlap-color: #a8dab5;
   // for a solid border, but because we're using a dashed border for the
   // preview range, we need to bump its opacity to ensure that it's visible.
   @if meta.type-of($preview-outline-color) == color {
-    $preview-outline-opacity: math.min(opacity($preview-outline-color) * 2, 1);
+    $preview-outline-opacity: math.min(color.opacity($preview-outline-color) * 2, 1);
     $preview-outline-color: rgba($preview-outline-color, $preview-outline-opacity);
   }
 
diff --git a/src/material/core/tokens/m2/mat/_menu.scss b/src/material/core/tokens/m2/mat/_menu.scss
index 73a9e8b138b0..bf3e68248b23 100644
--- a/src/material/core/tokens/m2/mat/_menu.scss
+++ b/src/material/core/tokens/m2/mat/_menu.scss
@@ -1,6 +1,7 @@
 @use '../../token-definition';
 @use '../../../theming/inspection';
 @use '../../../style/sass-utils';
+@use '../../../style/elevation';
 
 // The prefix used to generate the fully qualified name for tokens in this file.
 $prefix: (mat, menu);
@@ -18,9 +19,10 @@ $prefix: (mat, menu);
     item-trailing-spacing: 16px,
     item-with-icon-leading-spacing: 16px,
     item-with-icon-trailing-spacing: 16px,
-    // Note that this uses a value, rather than a computed box-shadow, because we use
-    // the value at runtime to determine which shadow to set based on the menu's depth.
-    base-elevation-level: 8,
+    container-elevation-shadow: elevation.get-box-shadow(8),
+
+    // Unused
+    base-elevation-level: null,
   );
 }
 
diff --git a/src/material/core/tokens/m2/mat/_sort.scss b/src/material/core/tokens/m2/mat/_sort.scss
index f819669b3e58..2c2e6f98ca4b 100644
--- a/src/material/core/tokens/m2/mat/_sort.scss
+++ b/src/material/core/tokens/m2/mat/_sort.scss
@@ -26,7 +26,7 @@ $prefix: (mat, sort);
   // when mixing the colors together. Otherwise, if it resolves to something different
   // (e.g. it resolves to a CSS variable), we use the color directly.
   @if (meta.type-of($table-background) == color and meta.type-of($text-color) == color) {
-    $text-opacity: opacity($text-color);
+    $text-opacity: color.opacity($text-color);
     $arrow-color: color.mix($table-background, rgba($text-color, 1), (1 - $text-opacity) * 100%);
   }
   @else {
diff --git a/src/material/core/tokens/m3/mat/_menu.scss b/src/material/core/tokens/m3/mat/_menu.scss
index 5df22d6dee4e..c341e9a40465 100644
--- a/src/material/core/tokens/m3/mat/_menu.scss
+++ b/src/material/core/tokens/m3/mat/_menu.scss
@@ -1,6 +1,7 @@
 @use 'sass:map';
 @use '../../../style/sass-utils';
 @use '../../token-definition';
+@use '../../../style/elevation';
 
 // The prefix used to generate the fully qualified name for tokens in this file.
 $prefix: (mat, menu);
@@ -35,9 +36,11 @@ $prefix: (mat, menu);
       item-with-icon-leading-spacing: token-definition.hardcode(12px, $exclude-hardcoded),
       item-with-icon-trailing-spacing: token-definition.hardcode(12px, $exclude-hardcoded),
       container-color: map.get($systems, md-sys-color, surface-container),
-      // Note that this uses a value, rather than a computed box-shadow, because we use
-      // the value at runtime to determine which shadow to set based on the menu's depth.
-      base-elevation-level: token-definition.hardcode(2, $exclude-hardcoded),
+      container-elevation-shadow: token-definition.hardcode(
+        elevation.get-box-shadow(2), $exclude-hardcoded),
+
+      // Unused
+      base-elevation-level: null,
     )
   );
 
diff --git a/src/material/core/tokens/m3/mdc/_filled-text-field.scss b/src/material/core/tokens/m3/mdc/_filled-text-field.scss
index f098158e3783..7311e947fddc 100644
--- a/src/material/core/tokens/m3/mdc/_filled-text-field.scss
+++ b/src/material/core/tokens/m3/mdc/_filled-text-field.scss
@@ -1,6 +1,5 @@
 @use 'sass:map';
 @use 'sass:meta';
-@use 'sass:list';
 @use '../../token-definition';
 
 // The prefix used to generate the fully qualified name for tokens in this file.
@@ -34,8 +33,8 @@ $prefix: (mdc, filled-text-field);
   );
 
   @return token-definition.namespace-tokens($prefix, (
-    _fix-tokens($mdc-tokens),
-    token-definition.map-values($variant-tokens, meta.get-function(_fix-tokens))
+    _fix-tokens($mdc-tokens, $systems),
+    token-definition.map-values($variant-tokens, meta.get-function(_fix-tokens), $systems)
   ), $token-slots);
 }
 
@@ -43,8 +42,9 @@ $prefix: (mdc, filled-text-field);
 /// Fixes inconsistent values in the filled text field tokens so that they can produce valid
 /// styles.
 /// @param {Map} $initial-tokens Map of filled text field tokens currently being generated.
+/// @param {Map} $systems The MDC system tokens
 /// @return {Map} The given tokens, with the invalid values replaced with valid ones.
-@function _fix-tokens($initial-tokens) {
+@function _fix-tokens($initial-tokens, $systems) {
   // Need to get the hardcoded values, because they include opacities that are used for the disabled
   // state.
   $hardcoded-tokens: token-definition.get-mdc-tokens('filled-text-field', (), false);
@@ -80,13 +80,11 @@ $prefix: (mdc, filled-text-field);
     )
   ));
 
-  $container-shape: map.get($tokens, container-shape);
-
-  // The M2 token slots define a single `container-shape` slot while the M3 tokens provide a list
-  // of shapes (e.g. top/bottom/left/right). Extract the first value so it matches the expected
-  // token slot in M2.
-  @if meta.type-of($container-shape) == 'list' {
-    $tokens: map.set($tokens, container-shape, list.nth($container-shape, 1));
+  // The system tokens have this set as `corner-extra-small-top` which assumes that the value will
+  // be set as a `border-radius`, however we set it as `border-top-left-radius` and
+  // `border-top-right-radius`. Changing it at this point will be breaking so instead we remap it.
+  @if (map.get($tokens, container-shape)) {
+    $tokens: map.set($tokens, container-shape, map.get($systems, md-sys-shape, corner-extra-small));
   }
 
   @return $tokens;
diff --git a/src/material/datepicker/calendar-body.html b/src/material/datepicker/calendar-body.html
index 98b63b03410a..4bd24d90fa83 100644
--- a/src/material/datepicker/calendar-body.html
+++ b/src/material/datepicker/calendar-body.html
@@ -90,3 +90,9 @@
 <span [id]="_endDateLabelId" class="mat-calendar-body-hidden-label">
   {{endDateAccessibleName}}
 </span>
+<span [id]="_comparisonStartDateLabelId" class="mat-calendar-body-hidden-label">
+  {{comparisonDateAccessibleName}} {{startDateAccessibleName}}
+</span>
+<span [id]="_comparisonEndDateLabelId" class="mat-calendar-body-hidden-label">
+  {{comparisonDateAccessibleName}} {{endDateAccessibleName}}
+</span>
diff --git a/src/material/datepicker/calendar-body.spec.ts b/src/material/datepicker/calendar-body.spec.ts
index 1e40e18d6ab1..99c3cf246955 100644
--- a/src/material/datepicker/calendar-body.spec.ts
+++ b/src/material/datepicker/calendar-body.spec.ts
@@ -726,7 +726,6 @@ describe('MatCalendarBody', () => {
           [activeCell]="10"
           (selectedValueChange)="onSelect($event)">
     </table>`,
-  standalone: true,
   imports: [MatCalendarBody],
 })
 class StandardCalendarBody {
@@ -759,7 +758,6 @@ class StandardCalendarBody {
           (dragEnded)="dragEnded($event)"
           >
     </table>`,
-  standalone: true,
   imports: [MatCalendarBody],
 })
 class RangeCalendarBody {
diff --git a/src/material/datepicker/calendar-body.ts b/src/material/datepicker/calendar-body.ts
index 2d23941cb471..7de7a8125adb 100644
--- a/src/material/datepicker/calendar-body.ts
+++ b/src/material/datepicker/calendar-body.ts
@@ -24,9 +24,11 @@ import {
   afterNextRender,
   Injector,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {NgClass} from '@angular/common';
 import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
 import {_StructuralStylesLoader} from '@angular/material/core';
+import {MatDatepickerIntl} from './datepicker-intl';
 
 /** Extra CSS classes that can be associated with a calendar cell. */
 export type MatCalendarCellCssClasses = string | string[] | Set<string> | {[key: string]: any};
@@ -63,8 +65,6 @@ export interface MatCalendarUserEvent<D> {
   event: Event;
 }
 
-let calendarBodyId = 1;
-
 /** Event options that can be used to bind an active, capturing event. */
 const activeCapturingEventOptions = normalizePassiveListenerOptions({
   passive: false,
@@ -100,6 +100,7 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
   private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
   private _ngZone = inject(NgZone);
   private _platform = inject(Platform);
+  private _intl = inject(MatDatepickerIntl);
 
   /**
    * Used to skip the next focus event when rendering the preview range.
@@ -195,10 +196,24 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
   /** Width of an individual cell. */
   _cellWidth: string;
 
+  /** ID for the start date label. */
+  _startDateLabelId: string;
+
+  /** ID for the end date label. */
+  _endDateLabelId: string;
+
+  /** ID for the comparison start date label. */
+  _comparisonStartDateLabelId: string;
+
+  /** ID for the comparison end date label. */
+  _comparisonEndDateLabelId: string;
+
   private _didDragSinceMouseDown = false;
 
   private _injector = inject(Injector);
 
+  comparisonDateAccessibleName = this._intl.comparisonDateLabel;
+
   /**
    * Tracking function for rows based on their identity. Ideally we would use some sort of
    * key on the row, but that would require a breaking change for the `rows` input. We don't
@@ -209,7 +224,14 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
   constructor(...args: unknown[]);
 
   constructor() {
+    const idGenerator = inject(_IdGenerator);
+    this._startDateLabelId = idGenerator.getId('mat-calendar-body-start-');
+    this._endDateLabelId = idGenerator.getId('mat-calendar-body-end-');
+    this._comparisonStartDateLabelId = idGenerator.getId('mat-calendar-body-comparison-start-');
+    this._comparisonEndDateLabelId = idGenerator.getId('mat-calendar-body-comparison-end-');
+
     inject(_CdkPrivateStyleLoader).load(_StructuralStylesLoader);
+
     this._ngZone.runOutsideAngular(() => {
       const element = this._elementRef.nativeElement;
 
@@ -457,6 +479,17 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
     } else if (this.endValue === value) {
       return this._endDateLabelId;
     }
+
+    if (this.comparisonStart !== null && this.comparisonEnd !== null) {
+      if (value === this.comparisonStart && value === this.comparisonEnd) {
+        return `${this._comparisonStartDateLabelId} ${this._comparisonEndDateLabelId}`;
+      } else if (value === this.comparisonStart) {
+        return this._comparisonStartDateLabelId;
+      } else if (value === this.comparisonEnd) {
+        return this._comparisonEndDateLabelId;
+      }
+    }
+
     return null;
   }
 
@@ -597,12 +630,6 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
 
     return null;
   }
-
-  private _id = `mat-calendar-body-${calendarBodyId++}`;
-
-  _startDateLabelId = `${this._id}-start-date`;
-
-  _endDateLabelId = `${this._id}-end-date`;
 }
 
 /** Checks whether a node is a table cell element. */
diff --git a/src/material/datepicker/calendar-header.html b/src/material/datepicker/calendar-header.html
index 02f826cbb227..2e539ed68c97 100644
--- a/src/material/datepicker/calendar-header.html
+++ b/src/material/datepicker/calendar-header.html
@@ -21,11 +21,17 @@
     <button mat-icon-button type="button" class="mat-calendar-previous-button"
             [disabled]="!previousEnabled()" (click)="previousClicked()"
             [attr.aria-label]="prevButtonLabel">
+      <svg viewBox="0 0 24 24" focusable="false" aria-hidden="true">
+        <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
+       </svg>
     </button>
 
     <button mat-icon-button type="button" class="mat-calendar-next-button"
             [disabled]="!nextEnabled()" (click)="nextClicked()"
             [attr.aria-label]="nextButtonLabel">
+      <svg viewBox="0 0 24 24" focusable="false" aria-hidden="true">
+        <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
+      </svg>
     </button>
   </div>
 </div>
diff --git a/src/material/datepicker/calendar-header.spec.ts b/src/material/datepicker/calendar-header.spec.ts
index a03bbcaf935f..d9ed1edf6415 100644
--- a/src/material/datepicker/calendar-header.spec.ts
+++ b/src/material/datepicker/calendar-header.spec.ts
@@ -199,7 +199,9 @@ describe('MatCalendarHeader', () => {
       expect(periodButton.hasAttribute('aria-label')).toBe(true);
       expect(periodButton.getAttribute('aria-label')).toMatch(/^[a-z0-9\s]+$/i);
       expect(periodButton.hasAttribute('aria-describedby')).toBe(true);
-      expect(periodButton.getAttribute('aria-describedby')).toMatch(/mat-calendar-header-[0-9]+/i);
+      expect(periodButton.getAttribute('aria-describedby')).toMatch(
+        /mat-calendar-period-label-\w+[0-9]+/i,
+      );
     });
   });
 
@@ -382,7 +384,6 @@ describe('MatCalendarHeader', () => {
         (yearSelected)="selectedYear=$event"
         (monthSelected)="selectedMonth=$event">
     </mat-calendar>`,
-  standalone: true,
   imports: [MatNativeDateModule, MatDatepickerModule],
 })
 class StandardCalendar {
@@ -400,7 +401,6 @@ class StandardCalendar {
       [maxDate]="maxDate">
     </mat-calendar>
   `,
-  standalone: true,
   imports: [MatNativeDateModule, MatDatepickerModule],
 })
 class CalendarWithMinMaxDate {
diff --git a/src/material/datepicker/calendar.scss b/src/material/datepicker/calendar.scss
index 91c0ee44827e..7471adae05ac 100644
--- a/src/material/datepicker/calendar.scss
+++ b/src/material/datepicker/calendar.scss
@@ -1,6 +1,5 @@
 @use '@angular/cdk';
 
-@use '../core/style/layout-common';
 @use '../core/focus-indicators/private';
 @use '../core/tokens/m2/mat/datepicker' as tokens-mat-datepicker;
 @use '../core/tokens/token-utils';
@@ -16,12 +15,6 @@ $calendar-controls-side-margin: calc(33% / 7 - 16px);
 $calendar-arrow-size: 5px !default;
 $calendar-arrow-disabled-opacity: 0.5 !default;
 
-// Values chosen to approximate https://material.io/icons/#ic_navigate_before and
-// https://material.io/icons/#ic_navigate_next as closely as possible.
-$calendar-prev-next-icon-border-width: 2px;
-$calendar-prev-next-icon-margin: 15.5px;
-$calendar-prev-icon-transform: translateX(2px) rotate(-45deg);
-$calendar-next-icon-transform: translateX(-2px) rotate(45deg);
 $_tokens: tokens-mat-datepicker.$prefix, tokens-mat-datepicker.get-token-slots();
 
 .mat-calendar {
@@ -94,8 +87,6 @@ $_tokens: tokens-mat-datepicker.$prefix, tokens-mat-datepicker.get-token-slots()
 
 .mat-calendar-previous-button,
 .mat-calendar-next-button {
-  position: relative;
-
   @include token-utils.use-tokens($_tokens...) {
     // Needs need a bit more specificity to avoid being overwritten by the .mat-icon-button.
     .mat-datepicker-content &:not(.mat-mdc-button-disabled) {
@@ -103,29 +94,11 @@ $_tokens: tokens-mat-datepicker.$prefix, tokens-mat-datepicker.get-token-slots()
     }
   }
 
-  &::after {
-    @include layout-common.fill;
-    content: '';
-    margin: $calendar-prev-next-icon-margin;
-    border: 0 solid currentColor;
-    border-top-width: $calendar-prev-next-icon-border-width;
-  }
-
   [dir='rtl'] & {
     transform: rotate(180deg);
   }
 }
 
-.mat-calendar-previous-button::after {
-  border-left-width: $calendar-prev-next-icon-border-width;
-  transform: $calendar-prev-icon-transform;
-}
-
-.mat-calendar-next-button::after {
-  border-right-width: $calendar-prev-next-icon-border-width;
-  transform: $calendar-next-icon-transform;
-}
-
 .mat-calendar-table {
   border-spacing: 0;
   border-collapse: collapse;
diff --git a/src/material/datepicker/calendar.ts b/src/material/datepicker/calendar.ts
index 7e4302d2e90a..18c97679e604 100644
--- a/src/material/datepicker/calendar.ts
+++ b/src/material/datepicker/calendar.ts
@@ -39,11 +39,9 @@ import {
 import {MatYearView} from './year-view';
 import {MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER, DateRange} from './date-selection-model';
 import {MatIconButton, MatButton} from '@angular/material/button';
-import {CdkMonitorFocus} from '@angular/cdk/a11y';
+import {_IdGenerator, CdkMonitorFocus} from '@angular/cdk/a11y';
 import {_CdkPrivateStyleLoader, _VisuallyHiddenLoader} from '@angular/cdk/private';
 
-let calendarHeaderId = 1;
-
 /**
  * Possible views for the calendar.
  * @docs-private
@@ -222,9 +220,7 @@ export class MatCalendarHeader<D> {
     return [minYearLabel, maxYearLabel];
   }
 
-  private _id = `mat-calendar-header-${calendarHeaderId++}`;
-
-  _periodButtonLabelId = `${this._id}-period-label`;
+  _periodButtonLabelId = inject(_IdGenerator).getId('mat-calendar-period-label-');
 }
 
 /** A calendar that is used as part of the datepicker. */
diff --git a/src/material/datepicker/date-range-input-parts.ts b/src/material/datepicker/date-range-input-parts.ts
index aff57bd3ca5d..dcffd998400a 100644
--- a/src/material/datepicker/date-range-input-parts.ts
+++ b/src/material/datepicker/date-range-input-parts.ts
@@ -9,14 +9,13 @@
 import {Directionality} from '@angular/cdk/bidi';
 import {BACKSPACE, LEFT_ARROW, RIGHT_ARROW} from '@angular/cdk/keycodes';
 import {
+  AfterContentInit,
   Directive,
   DoCheck,
   ElementRef,
-  InjectionToken,
   Injector,
   Input,
   OnInit,
-  Signal,
   inject,
 } from '@angular/core';
 import {
@@ -33,34 +32,8 @@ import {
 import {ErrorStateMatcher, _ErrorStateTracker} from '@angular/material/core';
 import {_computeAriaAccessibleName} from './aria-accessible-name';
 import {DateRange, DateSelectionModelChange} from './date-selection-model';
-import {DateFilterFn, MatDatepickerInputBase} from './datepicker-input-base';
-
-/** Parent component that should be wrapped around `MatStartDate` and `MatEndDate`. */
-export interface MatDateRangeInputParent<D> {
-  id: string;
-  min: D | null;
-  max: D | null;
-  dateFilter: DateFilterFn<D>;
-  rangePicker: {
-    opened: boolean;
-    id: string;
-  };
-  // @breaking-change 20.0.0 property to become required.
-  _ariaOwns?: Signal<string | null>;
-  _startInput: MatDateRangeInputPartBase<D>;
-  _endInput: MatDateRangeInputPartBase<D>;
-  _groupDisabled: boolean;
-  _handleChildValueChange(): void;
-  _openDatepicker(): void;
-}
-
-/**
- * Used to provide the date range input wrapper component
- * to the parts without circular dependencies.
- */
-export const MAT_DATE_RANGE_INPUT_PARENT = new InjectionToken<MatDateRangeInputParent<unknown>>(
-  'MAT_DATE_RANGE_INPUT_PARENT',
-);
+import {MatDatepickerInputBase} from './datepicker-input-base';
+import {MatDateRangeInput} from './date-range-input';
 
 /**
  * Base class for the individual inputs that can be projected inside a `mat-date-range-input`.
@@ -68,9 +41,9 @@ export const MAT_DATE_RANGE_INPUT_PARENT = new InjectionToken<MatDateRangeInputP
 @Directive()
 abstract class MatDateRangeInputPartBase<D>
   extends MatDatepickerInputBase<DateRange<D>>
-  implements OnInit, DoCheck
+  implements OnInit, AfterContentInit, DoCheck
 {
-  _rangeInput = inject<MatDateRangeInputParent<D>>(MAT_DATE_RANGE_INPUT_PARENT);
+  _rangeInput = inject<MatDateRangeInput<D>>(MatDateRangeInput);
   override _elementRef = inject<ElementRef<HTMLInputElement>>(ElementRef);
   _defaultErrorStateMatcher = inject(ErrorStateMatcher);
   private _injector = inject(Injector);
@@ -86,6 +59,7 @@ abstract class MatDateRangeInputPartBase<D>
   protected abstract override _validator: ValidatorFn | null;
   protected abstract override _assignValueToModel(value: D | null): void;
   protected abstract override _getValueFromModel(modelValue: DateRange<D>): D | null;
+  protected abstract _register(): void;
   protected readonly _dir = inject(Directionality, {optional: true});
   private _errorStateTracker: _ErrorStateTracker;
 
@@ -135,6 +109,10 @@ abstract class MatDateRangeInputPartBase<D>
     }
   }
 
+  ngAfterContentInit(): void {
+    this._register();
+  }
+
   ngDoCheck() {
     if (this.ngControl) {
       // We need to re-evaluate this on every change detection cycle, because there are some
@@ -208,7 +186,7 @@ abstract class MatDateRangeInputPartBase<D>
   protected override _assignValueProgrammatically(value: D | null) {
     super._assignValueProgrammatically(value);
     const opposite = (
-      this === this._rangeInput._startInput
+      this === (this._rangeInput._startInput as MatDateRangeInputPartBase<D>)
         ? this._rangeInput._endInput
         : this._rangeInput._startInput
     ) as MatDateRangeInputPartBase<D> | undefined;
@@ -261,6 +239,10 @@ export class MatStartDate<D> extends MatDateRangeInputPartBase<D> {
 
   protected _validator = Validators.compose([...super._getValidators(), this._startValidator]);
 
+  protected override _register(): void {
+    this._rangeInput._startInput = this;
+  }
+
   protected _getValueFromModel(modelValue: DateRange<D>) {
     return modelValue.start;
   }
@@ -349,6 +331,10 @@ export class MatEndDate<D> extends MatDateRangeInputPartBase<D> {
       : {'matEndDateInvalid': {'start': start, 'actual': end}};
   };
 
+  protected override _register(): void {
+    this._rangeInput._endInput = this;
+  }
+
   protected _validator = Validators.compose([...super._getValidators(), this._endValidator]);
 
   protected _getValueFromModel(modelValue: DateRange<D>) {
diff --git a/src/material/datepicker/date-range-input.spec.ts b/src/material/datepicker/date-range-input.spec.ts
index b56002e368cf..b5f594457af4 100644
--- a/src/material/datepicker/date-range-input.spec.ts
+++ b/src/material/datepicker/date-range-input.spec.ts
@@ -1176,7 +1176,6 @@ describe('MatDateRangeInput', () => {
         #rangePicker></mat-date-range-picker>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [
     MatDateRangeInput,
     MatStartDate,
@@ -1219,7 +1218,6 @@ class StandardRangePicker {
       <mat-date-range-picker #rangePicker></mat-date-range-picker>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [MatDateRangeInput, MatStartDate, MatEndDate, MatFormField, MatDateRangePicker],
 })
 class RangePickerNoStart {}
@@ -1234,7 +1232,6 @@ class RangePickerNoStart {}
       <mat-date-range-picker #rangePicker></mat-date-range-picker>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [MatDateRangeInput, MatStartDate, MatEndDate, MatFormField, MatDateRangePicker],
 })
 class RangePickerNoEnd {}
@@ -1250,7 +1247,6 @@ class RangePickerNoEnd {}
       <mat-date-range-picker #rangePicker></mat-date-range-picker>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [
     MatDateRangeInput,
     MatStartDate,
@@ -1297,7 +1293,6 @@ class RangePickerNgModel {
       <mat-date-range-picker #rangePicker></mat-date-range-picker>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [MatDateRangeInput, MatStartDate, MatEndDate, MatFormField, MatDateRangePicker],
 })
 class RangePickerNoLabel {
@@ -1314,7 +1309,6 @@ class RangePickerNoLabel {
       multi: true,
     },
   ],
-  standalone: true,
 })
 class CustomValidator implements Validator {
   validate = jasmine.createSpy('validate spy').and.returnValue(null);
@@ -1331,7 +1325,6 @@ class CustomValidator implements Validator {
       <mat-date-range-picker #rangePicker></mat-date-range-picker>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [
     MatDateRangeInput,
     MatStartDate,
@@ -1361,7 +1354,6 @@ class RangePickerWithCustomValidator {
       <mat-date-range-picker #rangePicker></mat-date-range-picker>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [MatDateRangeInput, MatStartDate, MatEndDate, MatFormField, MatDateRangePicker],
 })
 class RangePickerErrorStateMatcher {
diff --git a/src/material/datepicker/date-range-input.ts b/src/material/datepicker/date-range-input.ts
index d1bdb1416a87..695c08b43308 100644
--- a/src/material/datepicker/date-range-input.ts
+++ b/src/material/datepicker/date-range-input.ts
@@ -6,13 +6,12 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {CdkMonitorFocus, FocusOrigin} from '@angular/cdk/a11y';
+import {_IdGenerator, CdkMonitorFocus, FocusOrigin} from '@angular/cdk/a11y';
 import {
   AfterContentInit,
   ChangeDetectionStrategy,
   ChangeDetectorRef,
   Component,
-  ContentChild,
   ElementRef,
   Input,
   OnChanges,
@@ -27,20 +26,13 @@ import {ControlContainer, NgControl, Validators} from '@angular/forms';
 import {DateAdapter, ThemePalette} from '@angular/material/core';
 import {MAT_FORM_FIELD, MatFormFieldControl} from '@angular/material/form-field';
 import {Subject, Subscription, merge} from 'rxjs';
-import {
-  MAT_DATE_RANGE_INPUT_PARENT,
-  MatDateRangeInputParent,
-  MatEndDate,
-  MatStartDate,
-} from './date-range-input-parts';
+import type {MatEndDate, MatStartDate} from './date-range-input-parts';
 import {MatDateRangePickerInput} from './date-range-picker';
 import {DateRange, MatDateSelectionModel} from './date-selection-model';
 import {MatDatepickerControl, MatDatepickerPanel} from './datepicker-base';
 import {createMissingDateImplError} from './datepicker-errors';
 import {DateFilterFn, _MatFormFieldPartial, dateInputsHaveChanged} from './datepicker-input-base';
 
-let nextUniqueId = 0;
-
 @Component({
   selector: 'mat-date-range-input',
   templateUrl: 'date-range-input.html',
@@ -60,17 +52,13 @@ let nextUniqueId = 0;
   },
   changeDetection: ChangeDetectionStrategy.OnPush,
   encapsulation: ViewEncapsulation.None,
-  providers: [
-    {provide: MatFormFieldControl, useExisting: MatDateRangeInput},
-    {provide: MAT_DATE_RANGE_INPUT_PARENT, useExisting: MatDateRangeInput},
-  ],
+  providers: [{provide: MatFormFieldControl, useExisting: MatDateRangeInput}],
   imports: [CdkMonitorFocus],
 })
 export class MatDateRangeInput<D>
   implements
     MatFormFieldControl<DateRange<D>>,
     MatDatepickerControl<D>,
-    MatDateRangeInputParent<D>,
     MatDateRangePickerInput<D>,
     AfterContentInit,
     OnChanges,
@@ -84,13 +72,16 @@ export class MatDateRangeInput<D>
   private _closedSubscription = Subscription.EMPTY;
   private _openedSubscription = Subscription.EMPTY;
 
+  _startInput: MatStartDate<D>;
+  _endInput: MatEndDate<D>;
+
   /** Current value of the range input. */
   get value() {
     return this._model ? this._model.selection : null;
   }
 
   /** Unique ID for the group. */
-  id = `mat-date-range-input-${nextUniqueId++}`;
+  id: string = inject(_IdGenerator).getId('mat-date-range-input-');
 
   /** Whether the control is focused. */
   focused = false;
@@ -256,9 +247,6 @@ export class MatDateRangeInput<D>
   /** End of the comparison range that should be shown in the calendar. */
   @Input() comparisonEnd: D | null = null;
 
-  @ContentChild(MatStartDate) _startInput: MatStartDate<D>;
-  @ContentChild(MatEndDate) _endInput: MatEndDate<D>;
-
   /**
    * Implemented as a part of `MatFormFieldControl`.
    * TODO(crisbeto): change type to `AbstractControlDirective` after #18206 lands.
diff --git a/src/material/datepicker/datepicker-base.ts b/src/material/datepicker/datepicker-base.ts
index b63170cad814..6046c3eb8ace 100644
--- a/src/material/datepicker/datepicker-base.ts
+++ b/src/material/datepicker/datepicker-base.ts
@@ -7,7 +7,7 @@
  */
 
 import {AnimationEvent} from '@angular/animations';
-import {CdkTrapFocus} from '@angular/cdk/a11y';
+import {_IdGenerator, CdkTrapFocus} from '@angular/cdk/a11y';
 import {Directionality} from '@angular/cdk/bidi';
 import {coerceStringArray} from '@angular/cdk/coercion';
 import {
@@ -76,9 +76,6 @@ import {DateFilterFn} from './datepicker-input-base';
 import {MatDatepickerIntl} from './datepicker-intl';
 import {_CdkPrivateStyleLoader, _VisuallyHiddenLoader} from '@angular/cdk/private';
 
-/** Used to generate a unique ID for each datepicker instance. */
-let datepickerUid = 0;
-
 /** Injection token that determines the scroll handling while the calendar is open. */
 export const MAT_DATEPICKER_SCROLL_STRATEGY = new InjectionToken<() => ScrollStrategy>(
   'mat-datepicker-scroll-strategy',
@@ -153,10 +150,10 @@ export class MatDatepickerContent<S, D = ExtractDateTypeFromSelection<S>>
 
   /**
    * Theme color of the internal calendar. This API is supported in M2 themes
-   * only, it has no effect in M3 themes.
+   * only, it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/datepicker/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette;
 
@@ -327,10 +324,10 @@ export interface MatDatepickerPanel<
   closedStream: EventEmitter<void>;
   /**
    * Color palette to use on the datepicker's calendar. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/datepicker/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   color: ThemePalette;
   /** The input element the datepicker is associated with. */
@@ -390,10 +387,10 @@ export abstract class MatDatepickerBase<
 
   /**
    * Theme color of the datepicker's calendar. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/datepicker/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   get color(): ThemePalette {
@@ -497,7 +494,7 @@ export abstract class MatDatepickerBase<
   private _opened = false;
 
   /** The id for the datepicker calendar. */
-  id: string = `mat-datepicker-${datepickerUid++}`;
+  id: string = inject(_IdGenerator).getId('mat-datepicker-');
 
   /** The minimum selectable date. */
   _getMinDate(): D | null {
diff --git a/src/material/datepicker/datepicker-intl.ts b/src/material/datepicker/datepicker-intl.ts
index a6b95dc93048..3faeafff9838 100644
--- a/src/material/datepicker/datepicker-intl.ts
+++ b/src/material/datepicker/datepicker-intl.ts
@@ -65,6 +65,11 @@ export class MatDatepickerIntl {
    */
   endDateLabel = 'End date';
 
+  /**
+   * A label for the Comparison date of a range of dates (used by screen readers).
+   */
+  comparisonDateLabel = 'Comparison range';
+
   /** Formats a range of years (used for visuals). */
   formatYearRange(start: string, end: string): string {
     return `${start} \u2013 ${end}`;
diff --git a/src/material/datepicker/datepicker-module.ts b/src/material/datepicker/datepicker-module.ts
index e0e99e22fb6d..abe21e81f077 100644
--- a/src/material/datepicker/datepicker-module.ts
+++ b/src/material/datepicker/datepicker-module.ts
@@ -9,7 +9,6 @@
 import {A11yModule} from '@angular/cdk/a11y';
 import {OverlayModule} from '@angular/cdk/overlay';
 import {PortalModule} from '@angular/cdk/portal';
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {MatButtonModule} from '@angular/material/button';
 import {CdkScrollableModule} from '@angular/cdk/scrolling';
@@ -34,7 +33,6 @@ import {MatDatepickerActions, MatDatepickerApply, MatDatepickerCancel} from './d
 
 @NgModule({
   imports: [
-    CommonModule,
     MatButtonModule,
     OverlayModule,
     A11yModule,
diff --git a/src/material/datepicker/month-view.spec.ts b/src/material/datepicker/month-view.spec.ts
index aa3bdf732e84..45823af1fd8f 100644
--- a/src/material/datepicker/month-view.spec.ts
+++ b/src/material/datepicker/month-view.spec.ts
@@ -858,7 +858,6 @@ describe('MatMonthView', () => {
       (dragEnded)="dragEnded($event)"
       [activeDrag]="activeDrag"></mat-month-view>
       `,
-  standalone: true,
   imports: [MatMonthView],
 })
 class StandardMonthView {
@@ -890,7 +889,6 @@ class StandardMonthView {
       [dateFilter]="dateFilter"
       [minDate]="minDate"
       [maxDate]="maxDate"></mat-month-view>`,
-  standalone: true,
   imports: [MatMonthView],
 })
 class MonthViewWithDateFilter {
@@ -904,7 +902,6 @@ class MonthViewWithDateFilter {
 
 @Component({
   template: `<mat-month-view [activeDate]="activeDate" [dateClass]="dateClass"></mat-month-view>`,
-  standalone: true,
   imports: [MatMonthView],
 })
 class MonthViewWithDateClass {
diff --git a/src/material/datepicker/multi-year-view.spec.ts b/src/material/datepicker/multi-year-view.spec.ts
index bf1bcf5f0449..f305f4008daa 100644
--- a/src/material/datepicker/multi-year-view.spec.ts
+++ b/src/material/datepicker/multi-year-view.spec.ts
@@ -401,7 +401,6 @@ describe('MatMultiYearView', () => {
   template: `
     <mat-multi-year-view [(activeDate)]="date" [(selected)]="selected"
                          (yearSelected)="selectedYear=$event"></mat-multi-year-view>`,
-  standalone: true,
   imports: [MatMultiYearView],
 })
 class StandardMultiYearView {
@@ -420,7 +419,6 @@ class StandardMultiYearView {
       [minDate]="minDate"
       [maxDate]="maxDate"></mat-multi-year-view>
     `,
-  standalone: true,
   imports: [MatMultiYearView],
 })
 class MultiYearViewWithDateFilter {
@@ -437,7 +435,6 @@ class MultiYearViewWithDateFilter {
     <mat-multi-year-view [(activeDate)]="activeDate" [minDate]="minDate" [maxDate]="maxDate">
     </mat-multi-year-view>
     `,
-  standalone: true,
   imports: [MatMultiYearView],
 })
 class MultiYearViewWithMinMaxDate {
@@ -450,7 +447,6 @@ class MultiYearViewWithMinMaxDate {
   template: `
     <mat-multi-year-view [activeDate]="activeDate" [dateClass]="dateClass"></mat-multi-year-view>
   `,
-  standalone: true,
   imports: [MatMultiYearView],
 })
 class MultiYearViewWithDateClass {
diff --git a/src/material/datepicker/testing/calendar-harness.spec.ts b/src/material/datepicker/testing/calendar-harness.spec.ts
index e4963994d7ae..31bab381a5f9 100644
--- a/src/material/datepicker/testing/calendar-harness.spec.ts
+++ b/src/material/datepicker/testing/calendar-harness.spec.ts
@@ -329,7 +329,6 @@ describe('MatCalendarHarness', () => {
       [comparisonEnd]="comparisonEnd"
       (selectedChange)="rangeChanged($event)"></mat-calendar>
   `,
-  standalone: true,
   imports: [MatNativeDateModule, MatDatepickerModule],
 })
 class CalendarHarnessTest {
diff --git a/src/material/datepicker/testing/date-range-input-harness.spec.ts b/src/material/datepicker/testing/date-range-input-harness.spec.ts
index fab9074154e0..0877e381e76d 100644
--- a/src/material/datepicker/testing/date-range-input-harness.spec.ts
+++ b/src/material/datepicker/testing/date-range-input-harness.spec.ts
@@ -269,7 +269,6 @@ describe('matDateRangeInputHarness', () => {
       <input matEndDate>
     </mat-date-range-input>
   `,
-  standalone: true,
   imports: [
     MatNativeDateModule,
     MatDateRangeInput,
diff --git a/src/material/datepicker/testing/datepicker-input-harness.spec.ts b/src/material/datepicker/testing/datepicker-input-harness.spec.ts
index 178aeeb15ccc..25cca010c24c 100644
--- a/src/material/datepicker/testing/datepicker-input-harness.spec.ts
+++ b/src/material/datepicker/testing/datepicker-input-harness.spec.ts
@@ -208,7 +208,6 @@ describe('MatDatepickerInputHarness', () => {
     <mat-datepicker #picker [touchUi]="touchUi"></mat-datepicker>
     <input id="no-datepicker" matDatepicker>
   `,
-  standalone: true,
   imports: [MatNativeDateModule, MatDatepickerModule, FormsModule],
 })
 class DatepickerInputHarnessTest {
diff --git a/src/material/datepicker/testing/datepicker-toggle-harness.spec.ts b/src/material/datepicker/testing/datepicker-toggle-harness.spec.ts
index ab72b88fb2ee..238b643686d2 100644
--- a/src/material/datepicker/testing/datepicker-toggle-harness.spec.ts
+++ b/src/material/datepicker/testing/datepicker-toggle-harness.spec.ts
@@ -89,7 +89,6 @@ describe('MatDatepickerToggleHarness', () => {
 
     <mat-datepicker-toggle id="no-calendar"></mat-datepicker-toggle>
   `,
-  standalone: true,
   imports: [MatNativeDateModule, MatDatepickerModule],
 })
 class DatepickerToggleHarnessTest {
diff --git a/src/material/datepicker/year-view.spec.ts b/src/material/datepicker/year-view.spec.ts
index ce8b3aec18f6..e833fa5153f0 100644
--- a/src/material/datepicker/year-view.spec.ts
+++ b/src/material/datepicker/year-view.spec.ts
@@ -397,7 +397,6 @@ describe('MatYearView', () => {
   template: `
     <mat-year-view [(activeDate)]="date" [(selected)]="selected"
                    (monthSelected)="selectedMonth=$event"></mat-year-view>`,
-  standalone: true,
   imports: [MatYearView],
 })
 class StandardYearView {
@@ -415,7 +414,6 @@ class StandardYearView {
       [dateFilter]="dateFilter"
       [minDate]="minDate"
       [maxDate]="maxDate"></mat-year-view>`,
-  standalone: true,
   imports: [MatYearView],
 })
 class YearViewWithDateFilter {
@@ -435,7 +433,6 @@ class YearViewWithDateFilter {
 
 @Component({
   template: `<mat-year-view [activeDate]="activeDate" [dateClass]="dateClass"></mat-year-view>`,
-  standalone: true,
   imports: [MatYearView],
 })
 class YearViewWithDateClass {
diff --git a/src/material/dialog/dialog-content-directives.ts b/src/material/dialog/dialog-content-directives.ts
index 9ab4f87f7272..97aba9812f9b 100644
--- a/src/material/dialog/dialog-content-directives.ts
+++ b/src/material/dialog/dialog-content-directives.ts
@@ -16,14 +16,12 @@ import {
   SimpleChanges,
   inject,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {CdkScrollable} from '@angular/cdk/scrolling';
 
 import {MatDialog} from './dialog';
 import {_closeDialogVia, MatDialogRef} from './dialog-ref';
 
-/** Counter used to generate unique IDs for dialog elements. */
-let dialogElementUid = 0;
-
 /**
  * Button that will close the current dialog.
  */
@@ -137,7 +135,7 @@ export abstract class MatDialogLayoutSection implements OnInit, OnDestroy {
   },
 })
 export class MatDialogTitle extends MatDialogLayoutSection {
-  @Input() id: string = `mat-mdc-dialog-title-${dialogElementUid++}`;
+  @Input() id: string = inject(_IdGenerator).getId('mat-mdc-dialog-title-');
 
   protected _onAdd() {
     // Note: we null check the queue, because there are some internal
diff --git a/src/material/dialog/dialog-ref.ts b/src/material/dialog/dialog-ref.ts
index 2017f67560bf..b20a6936ac68 100644
--- a/src/material/dialog/dialog-ref.ts
+++ b/src/material/dialog/dialog-ref.ts
@@ -52,7 +52,7 @@ export class MatDialogRef<T, R = any> {
   private _result: R | undefined;
 
   /** Handle to the timeout that's running as a fallback in case the exit animation doesn't fire. */
-  private _closeFallbackTimeout: number;
+  private _closeFallbackTimeout: ReturnType<typeof setTimeout>;
 
   /** Current state of the dialog. */
   private _state = MatDialogState.OPEN;
diff --git a/src/material/dialog/dialog.spec.ts b/src/material/dialog/dialog.spec.ts
index 1523e8ba9892..1aa69b524ff6 100644
--- a/src/material/dialog/dialog.spec.ts
+++ b/src/material/dialog/dialog.spec.ts
@@ -1581,7 +1581,6 @@ describe('MatDialog', () => {
 
     it('should set the aria-labelledby attribute to the id of the title under OnPush host', fakeAsync(() => {
       @Component({
-        standalone: true,
         imports: [MatDialogTitle],
         template: `@if (showTitle()) { <h2 mat-dialog-title>This is the first title</h2> }`,
       })
@@ -1592,7 +1591,6 @@ describe('MatDialog', () => {
       @Component({
         template: '',
         selector: 'child',
-        standalone: true,
       })
       class Child {
         readonly viewContainerRef = inject(ViewContainerRef);
@@ -1606,7 +1604,6 @@ describe('MatDialog', () => {
       }
 
       @Component({
-        standalone: true,
         imports: [Child],
         template: `<child></child>`,
         changeDetection: ChangeDetectionStrategy.OnPush,
@@ -2113,7 +2110,6 @@ describe('MatDialog with explicit injector provided', () => {
 
 @Directive({
   selector: 'dir-with-view-container',
-  standalone: true,
 })
 class DirectiveWithViewContainer {
   viewContainerRef = inject(ViewContainerRef);
@@ -2131,7 +2127,6 @@ class ComponentWithOnPushViewContainer {
 @Component({
   selector: 'arbitrary-component',
   template: `@if (showChildView) {<dir-with-view-container></dir-with-view-container>}`,
-  standalone: true,
   imports: [DirectiveWithViewContainer],
 })
 class ComponentWithChildViewContainer {
@@ -2148,7 +2143,6 @@ class ComponentWithChildViewContainer {
   selector: 'arbitrary-component-with-template-ref',
   template: `<ng-template let-data let-dialogRef="dialogRef">
     Cheese {{localValue}} {{data?.value}}{{setDialogRef(dialogRef)}}</ng-template>`,
-  standalone: true,
 })
 class ComponentWithTemplateRef {
   localValue: string;
@@ -2165,7 +2159,6 @@ class ComponentWithTemplateRef {
 /** Simple component for testing ComponentPortal. */
 @Component({
   template: '<p>Pizza</p> <input> <button>Close</button>',
-  standalone: true,
 })
 class PizzaMsg {
   dialogRef = inject<MatDialogRef<PizzaMsg>>(MatDialogRef);
@@ -2196,7 +2189,6 @@ class PizzaMsg {
       <button class="with-submit" type="submit" mat-dialog-close>Should have submit</button>
     </mat-dialog-actions>
   `,
-  standalone: true,
   imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogClose],
 })
 class ContentElementDialog {
@@ -2232,7 +2224,6 @@ class ContentElementDialog {
       </mat-dialog-actions>
     </ng-template>
   `,
-  standalone: true,
   imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogClose],
 })
 class ComponentWithContentElementTemplateRef {
@@ -2248,7 +2239,6 @@ class ComponentWithContentElementTemplateRef {
 @Component({
   template: '',
   providers: [MatDialog],
-  standalone: true,
 })
 class ComponentThatProvidesMatDialog {
   dialog = inject(MatDialog);
@@ -2257,7 +2247,6 @@ class ComponentThatProvidesMatDialog {
 /** Simple component for testing ComponentPortal. */
 @Component({
   template: '',
-  standalone: true,
 })
 class DialogWithInjectedData {
   data = inject(MAT_DIALOG_DATA);
@@ -2265,7 +2254,6 @@ class DialogWithInjectedData {
 
 @Component({
   template: '<p>Pasta</p>',
-  standalone: true,
 })
 class DialogWithoutFocusableElements {}
 
@@ -2278,7 +2266,6 @@ class ShadowDomComponent {}
 
 @Component({
   template: '',
-  standalone: true,
 })
 class ModuleBoundDialogParentComponent {
   private _injector = inject(Injector);
@@ -2301,7 +2288,6 @@ class ModuleBoundDialogService {
 
 @Component({
   template: '<module-bound-dialog-child-component></module-bound-dialog-child-component>',
-  standalone: true,
   imports: [forwardRef(() => ModuleBoundDialogChildComponent)],
 })
 class ModuleBoundDialogComponent {}
@@ -2309,7 +2295,6 @@ class ModuleBoundDialogComponent {}
 @Component({
   selector: 'module-bound-dialog-child-component',
   template: '<p>{{service.name}}</p>',
-  standalone: true,
 })
 class ModuleBoundDialogChildComponent {
   service = inject(ModuleBoundDialogService);
diff --git a/src/material/dialog/dialog.ts b/src/material/dialog/dialog.ts
index 89dea3732c39..49840489d23a 100644
--- a/src/material/dialog/dialog.ts
+++ b/src/material/dialog/dialog.ts
@@ -22,6 +22,7 @@ import {MatDialogRef} from './dialog-ref';
 import {defer, Observable, Subject} from 'rxjs';
 import {Dialog, DialogConfig} from '@angular/cdk/dialog';
 import {startWith} from 'rxjs/operators';
+import {_IdGenerator} from '@angular/cdk/a11y';
 
 /** Injection token that can be used to access the data that was passed in to a dialog. */
 export const MAT_DIALOG_DATA = new InjectionToken<any>('MatMdcDialogData');
@@ -65,9 +66,6 @@ export const MAT_DIALOG_SCROLL_STRATEGY_PROVIDER = {
   useFactory: MAT_DIALOG_SCROLL_STRATEGY_PROVIDER_FACTORY,
 };
 
-// Counter for unique dialog ids.
-let uniqueId = 0;
-
 /**
  * Service to open Material Design modal dialogs.
  */
@@ -77,6 +75,7 @@ export class MatDialog implements OnDestroy {
   private _defaultOptions = inject<MatDialogConfig>(MAT_DIALOG_DEFAULT_OPTIONS, {optional: true});
   private _scrollStrategy = inject(MAT_DIALOG_SCROLL_STRATEGY);
   private _parentDialog = inject(MatDialog, {optional: true, skipSelf: true});
+  private _idGenerator = inject(_IdGenerator);
   protected _dialog = inject(Dialog);
 
   private readonly _openDialogsAtThisLevel: MatDialogRef<any>[] = [];
@@ -154,7 +153,7 @@ export class MatDialog implements OnDestroy {
   ): MatDialogRef<T, R> {
     let dialogRef: MatDialogRef<T, R>;
     config = {...(this._defaultOptions || new MatDialogConfig()), ...config};
-    config.id = config.id || `mat-mdc-dialog-${uniqueId++}`;
+    config.id = config.id || this._idGenerator.getId('mat-mdc-dialog-');
     config.scrollStrategy = config.scrollStrategy || this._scrollStrategy();
 
     const cdkRef = this._dialog.open<R, D, T>(componentOrTemplateRef, {
diff --git a/src/material/dialog/dialog.zone.spec.ts b/src/material/dialog/dialog.zone.spec.ts
index 4369949cfbe6..efbbb3496553 100644
--- a/src/material/dialog/dialog.zone.spec.ts
+++ b/src/material/dialog/dialog.zone.spec.ts
@@ -73,7 +73,6 @@ describe('MatDialog', () => {
 
 @Directive({
   selector: 'dir-with-view-container',
-  standalone: true,
 })
 class DirectiveWithViewContainer {
   viewContainerRef = inject(ViewContainerRef);
@@ -82,7 +81,6 @@ class DirectiveWithViewContainer {
 @Component({
   selector: 'arbitrary-component',
   template: `@if (showChildView) {<dir-with-view-container></dir-with-view-container>}`,
-  standalone: true,
   imports: [DirectiveWithViewContainer],
 })
 class ComponentWithChildViewContainer {
@@ -98,7 +96,6 @@ class ComponentWithChildViewContainer {
 /** Simple component for testing ComponentPortal. */
 @Component({
   template: '<p>Pizza</p> <input> <button>Close</button>',
-  standalone: true,
 })
 class PizzaMsg {
   dialogRef = inject<MatDialogRef<PizzaMsg>>(MatDialogRef);
diff --git a/src/material/dialog/testing/dialog-harness.spec.ts b/src/material/dialog/testing/dialog-harness.spec.ts
index a42b30376c44..174529ffc617 100644
--- a/src/material/dialog/testing/dialog-harness.spec.ts
+++ b/src/material/dialog/testing/dialog-harness.spec.ts
@@ -72,7 +72,7 @@ describe('MatDialogHarness', () => {
     fixture.componentInstance.open();
     fixture.componentInstance.open({ariaLabelledBy: 'dialog-label'});
     const dialogs = await loader.getAllHarnesses(MatDialogHarness);
-    expect(await dialogs[0].getAriaLabelledby()).toMatch(/-dialog-title-\d+/);
+    expect(await dialogs[0].getAriaLabelledby()).toMatch(/-dialog-title-\w+\d+/);
     expect(await dialogs[1].getAriaLabelledby()).toBe('dialog-label');
   });
 
@@ -122,7 +122,6 @@ describe('MatDialogHarness', () => {
     </div>
   </ng-template>
   `,
-  standalone: true,
   imports: [MatDialogTitle, MatDialogContent, MatDialogActions],
 })
 class DialogHarnessTest {
diff --git a/src/material/dialog/testing/dialog-opener.spec.ts b/src/material/dialog/testing/dialog-opener.spec.ts
index 81666539af4e..8d87ef7d0fed 100644
--- a/src/material/dialog/testing/dialog-opener.spec.ts
+++ b/src/material/dialog/testing/dialog-opener.spec.ts
@@ -61,7 +61,6 @@ interface ExampleDialogResult {
     Data: {{data}}
     <button id="close-btn" (click)="close()">Close</button>
   `,
-  standalone: true,
 })
 class ExampleComponent {
   dialogRef = inject<MatDialogRef<ExampleComponent, ExampleDialogResult>>(MatDialogRef);
diff --git a/src/material/divider/divider.spec.ts b/src/material/divider/divider.spec.ts
index 3bb8c08c8aee..1884b94bcb5f 100644
--- a/src/material/divider/divider.spec.ts
+++ b/src/material/divider/divider.spec.ts
@@ -63,7 +63,6 @@ describe('MatDivider', () => {
 
 @Component({
   template: `<mat-divider [vertical]="vertical" [inset]="inset"></mat-divider>`,
-  standalone: true,
   imports: [MatDividerModule],
 })
 class MatDividerTestComponent {
diff --git a/src/material/divider/testing/divider-harness.spec.ts b/src/material/divider/testing/divider-harness.spec.ts
index bb4e8a911bbb..c0b784c62488 100644
--- a/src/material/divider/testing/divider-harness.spec.ts
+++ b/src/material/divider/testing/divider-harness.spec.ts
@@ -42,7 +42,6 @@ describe('MatLegacyButtonHarness', () => {
     <mat-divider></mat-divider>
     <mat-divider inset vertical></mat-divider>
   `,
-  standalone: true,
   imports: [MatDividerModule],
 })
 class DividerHarnessTest {}
diff --git a/src/material/expansion/accordion.spec.ts b/src/material/expansion/accordion.spec.ts
index cfbfa993da27..64cb07a80b7d 100644
--- a/src/material/expansion/accordion.spec.ts
+++ b/src/material/expansion/accordion.spec.ts
@@ -320,7 +320,6 @@ describe('MatAccordion', () => {
       </mat-expansion-panel>
     }
   </mat-accordion>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class SetOfItems {
@@ -349,7 +348,6 @@ class SetOfItems {
       Content 1
     </mat-expansion-panel>
   </mat-accordion>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class NestedAccordions {
@@ -369,7 +367,6 @@ class NestedAccordions {
       </mat-expansion-panel>
     </mat-expansion-panel>
   </mat-accordion>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class NestedPanel {
@@ -385,7 +382,6 @@ class NestedPanel {
       <p>Content</p>
     </mat-expansion-panel>
   </mat-accordion>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class AccordionWithHideToggle {
@@ -400,7 +396,6 @@ class AccordionWithHideToggle {
       <p>Content</p>
     </mat-expansion-panel>
   </mat-accordion>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class AccordionWithTogglePosition {
diff --git a/src/material/expansion/expansion-animations.ts b/src/material/expansion/expansion-animations.ts
index 010dee09eefe..b17dc9d84daa 100644
--- a/src/material/expansion/expansion-animations.ts
+++ b/src/material/expansion/expansion-animations.ts
@@ -39,6 +39,8 @@ export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,
  * Angular Bug: https://github.com/angular/angular/issues/18847
  *
  * @docs-private
+ * @deprecated No longer being used, to be removed.
+ * @breaking-change 21.0.0
  */
 export const matExpansionAnimations: {
   readonly indicatorRotate: AnimationTriggerMetadata;
diff --git a/src/material/expansion/expansion-panel-header.html b/src/material/expansion/expansion-panel-header.html
index 84c077279b98..a631bfea4c29 100644
--- a/src/material/expansion/expansion-panel-header.html
+++ b/src/material/expansion/expansion-panel-header.html
@@ -5,7 +5,7 @@
 </span>
 
 @if (_showToggle()) {
-  <span [@indicatorRotate]="_getExpandedState()" class="mat-expansion-indicator">
+  <span class="mat-expansion-indicator">
     <svg
       xmlns="http://www.w3.org/2000/svg"
       viewBox="0 -960 960 960"
diff --git a/src/material/expansion/expansion-panel-header.scss b/src/material/expansion/expansion-panel-header.scss
index a9e088eff9f1..b7e13692092a 100644
--- a/src/material/expansion/expansion-panel-header.scss
+++ b/src/material/expansion/expansion-panel-header.scss
@@ -9,7 +9,10 @@
   align-items: center;
   padding: 0 24px;
   border-radius: inherit;
-  transition: height expansion-variables.$header-transition;
+
+  .mat-expansion-panel-animations-enabled & {
+    transition: height expansion-variables.$header-transition;
+  }
 
   @include token-utils.use-tokens(
     tokens-mat-expansion.$prefix, tokens-mat-expansion.get-token-slots()) {
@@ -141,6 +144,14 @@
 // Creates the expansion indicator arrow. Done using ::after
 // rather than having additional nodes in the template.
 .mat-expansion-indicator {
+  .mat-expansion-panel-animations-enabled & {
+    transition: transform 225ms cubic-bezier(0.4, 0, 0.2, 1);
+  }
+
+  .mat-expansion-panel-header.mat-expanded & {
+    transform: rotate(180deg);
+  }
+
   &::after {
     border-style: solid;
     border-width: 0 2px 2px 0;
diff --git a/src/material/expansion/expansion-panel-header.ts b/src/material/expansion/expansion-panel-header.ts
index 791ead5c28a4..88405bc289bd 100644
--- a/src/material/expansion/expansion-panel-header.ts
+++ b/src/material/expansion/expansion-panel-header.ts
@@ -19,14 +19,12 @@ import {
   numberAttribute,
   OnDestroy,
   ViewEncapsulation,
-  ANIMATION_MODULE_TYPE,
   inject,
   HostAttributeToken,
 } from '@angular/core';
 import {EMPTY, merge, Subscription} from 'rxjs';
 import {filter} from 'rxjs/operators';
 import {MatAccordionTogglePosition} from './accordion-base';
-import {matExpansionAnimations} from './expansion-animations';
 import {
   MatExpansionPanel,
   MatExpansionPanelDefaultOptions,
@@ -44,7 +42,6 @@ import {_StructuralStylesLoader} from '@angular/material/core';
   templateUrl: 'expansion-panel-header.html',
   encapsulation: ViewEncapsulation.None,
   changeDetection: ChangeDetectionStrategy.OnPush,
-  animations: [matExpansionAnimations.indicatorRotate],
   host: {
     'class': 'mat-expansion-panel-header mat-focus-indicator',
     'role': 'button',
@@ -56,7 +53,6 @@ import {_StructuralStylesLoader} from '@angular/material/core';
     '[class.mat-expanded]': '_isExpanded()',
     '[class.mat-expansion-toggle-indicator-after]': `_getTogglePosition() === 'after'`,
     '[class.mat-expansion-toggle-indicator-before]': `_getTogglePosition() === 'before'`,
-    '[class._mat-animation-noopable]': '_animationMode === "NoopAnimations"',
     '[style.height]': '_getHeaderHeight()',
     '(click)': '_toggle()',
     '(keydown)': '_keydown($event)',
@@ -67,7 +63,6 @@ export class MatExpansionPanelHeader implements AfterViewInit, OnDestroy, Focusa
   private _element = inject(ElementRef);
   private _focusMonitor = inject(FocusMonitor);
   private _changeDetectorRef = inject(ChangeDetectorRef);
-  _animationMode = inject(ANIMATION_MODULE_TYPE, {optional: true});
 
   private _parentChangeSubscription = Subscription.EMPTY;
 
diff --git a/src/material/expansion/expansion-panel.html b/src/material/expansion/expansion-panel.html
index cdf99435966a..c27378e51129 100644
--- a/src/material/expansion/expansion-panel.html
+++ b/src/material/expansion/expansion-panel.html
@@ -1,15 +1,14 @@
 <ng-content select="mat-expansion-panel-header"></ng-content>
-<div class="mat-expansion-panel-content"
-     role="region"
-     [@bodyExpansion]="_getExpandedState()"
-     (@bodyExpansion.start)="_animationStarted($event)"
-     (@bodyExpansion.done)="_animationDone($event)"
-     [attr.aria-labelledby]="_headerId"
-     [id]="id"
-     #body>
-  <div class="mat-expansion-panel-body">
-    <ng-content></ng-content>
-    <ng-template [cdkPortalOutlet]="_portal"></ng-template>
+<div class="mat-expansion-panel-content-wrapper" [attr.inert]="expanded ? null : ''" #bodyWrapper>
+  <div class="mat-expansion-panel-content"
+       role="region"
+       [attr.aria-labelledby]="_headerId"
+       [id]="id"
+       #body>
+    <div class="mat-expansion-panel-body">
+      <ng-content></ng-content>
+      <ng-template [cdkPortalOutlet]="_portal"></ng-template>
+    </div>
+    <ng-content select="mat-action-row"></ng-content>
   </div>
-  <ng-content select="mat-action-row"></ng-content>
 </div>
diff --git a/src/material/expansion/expansion-panel.scss b/src/material/expansion/expansion-panel.scss
index fc8f348802f0..c9be77e66bcc 100644
--- a/src/material/expansion/expansion-panel.scss
+++ b/src/material/expansion/expansion-panel.scss
@@ -10,8 +10,11 @@
   display: block;
   margin: 0;
   overflow: hidden;
-  transition: margin 225ms variables.$fast-out-slow-in-timing-function,
-      elevation.private-transition-property-value();
+
+  &.mat-expansion-panel-animations-enabled {
+    transition: margin 225ms variables.$fast-out-slow-in-timing-function,
+        elevation.private-transition-property-value();
+  }
 
   // Required so that the `box-shadow` works after the
   // focus indicator relatively positions the header.
@@ -48,18 +51,58 @@
   @include cdk.high-contrast {
     outline: solid 1px;
   }
+}
 
-  &.ng-animate-disabled,
-  .ng-animate-disabled &,
-  &._mat-animation-noopable {
-    transition: none;
+.mat-expansion-panel-content-wrapper {
+  // Note: we can't use `overflow: hidden` here, because it can clip content with
+  // ripples or box shadows. Instead we transition the `visibility` below.
+  // Based on https://css-tricks.com/css-grid-can-do-auto-height-transitions.
+  display: grid;
+  grid-template-rows: 0fr;
+  grid-template-columns: 100%;
+
+  .mat-expansion-panel-animations-enabled & {
+    transition: grid-template-rows 225ms cubic-bezier(0.4, 0, 0.2, 1);
   }
+
+  .mat-expansion-panel.mat-expanded > & {
+    grid-template-rows: 1fr;
+  }
+
+  // All the browsers we support have support for `grid` as well, but
+  // given that these styles are load-bearing for the expansion panel,
+  // we have a fallback to `height` which doesn't animate, just in case.
+  // stylelint-disable material/no-prefixes
+  @supports not (grid-template-rows: 0fr) {
+    height: 0;
+
+    .mat-expansion-panel.mat-expanded > & {
+      height: auto;
+    }
+  }
+  // stylelint-enable material/no-prefixes
 }
 
 .mat-expansion-panel-content {
   display: flex;
   flex-direction: column;
   overflow: visible;
+  min-height: 0;
+
+  // The visibility here serves two purposes:
+  // 1. Hiding content from assistive technology.
+  // 2. Hiding any content that might be overflowing.
+  visibility: hidden;
+
+  .mat-expansion-panel-animations-enabled & {
+    // The duration here is slightly lower so the content
+    // goes away quicker than the collapse transition.
+    transition: visibility 190ms linear;
+  }
+
+  .mat-expansion-panel.mat-expanded > .mat-expansion-panel-content-wrapper > & {
+    visibility: visible;
+  }
 
   @include token-utils.use-tokens(
     tokens-mat-expansion.$prefix, tokens-mat-expansion.get-token-slots()) {
@@ -69,16 +112,6 @@
     @include token-utils.create-token-slot(line-height, container-text-line-height);
     @include token-utils.create-token-slot(letter-spacing, container-text-tracking);
   }
-
-  // Usually the `visibility: hidden` added by the animation is enough to prevent focus from
-  // entering the collapsed content, but children with their own `visibility` can override it.
-  // In other components we set a `display: none` at the root to stop focus from reaching the
-  // elements, however we can't do that here, because the content can determine the width
-  // of an expansion panel. The most practical fallback is to use `!important` to override
-  // any custom visibility.
-  &[style*='visibility: hidden'] * {
-    visibility: hidden !important;
-  }
 }
 
 .mat-expansion-panel-body {
diff --git a/src/material/expansion/expansion-panel.ts b/src/material/expansion/expansion-panel.ts
index 83f792243841..04dfdf0e0b02 100644
--- a/src/material/expansion/expansion-panel.ts
+++ b/src/material/expansion/expansion-panel.ts
@@ -6,7 +6,6 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {AnimationEvent} from '@angular/animations';
 import {CdkAccordionItem} from '@angular/cdk/accordion';
 import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
 import {CdkPortalOutlet, TemplatePortal} from '@angular/cdk/portal';
@@ -31,20 +30,19 @@ import {
   booleanAttribute,
   ANIMATION_MODULE_TYPE,
   inject,
+  NgZone,
+  Renderer2,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {Subject} from 'rxjs';
 import {filter, startWith, take} from 'rxjs/operators';
 import {MatAccordionBase, MatAccordionTogglePosition, MAT_ACCORDION} from './accordion-base';
-import {matExpansionAnimations} from './expansion-animations';
 import {MAT_EXPANSION_PANEL} from './expansion-panel-base';
 import {MatExpansionPanelContent} from './expansion-panel-content';
 
 /** MatExpansionPanel's states. */
 export type MatExpansionPanelState = 'expanded' | 'collapsed';
 
-/** Counter for generating unique element ids. */
-let uniqueId = 0;
-
 /**
  * Object that can be used to override the default options
  * for all of the expansion panels in a module.
@@ -78,7 +76,6 @@ export const MAT_EXPANSION_PANEL_DEFAULT_OPTIONS =
   templateUrl: 'expansion-panel.html',
   encapsulation: ViewEncapsulation.None,
   changeDetection: ChangeDetectionStrategy.OnPush,
-  animations: [matExpansionAnimations.bodyExpansion],
   providers: [
     // Provide MatAccordion as undefined to prevent nested expansion panels from registering
     // to the same accordion.
@@ -88,7 +85,6 @@ export const MAT_EXPANSION_PANEL_DEFAULT_OPTIONS =
   host: {
     'class': 'mat-expansion-panel',
     '[class.mat-expanded]': 'expanded',
-    '[class._mat-animation-noopable]': '_animationsDisabled',
     '[class.mat-expansion-panel-spacing]': '_hasSpacing()',
   },
   imports: [CdkPortalOutlet],
@@ -98,10 +94,13 @@ export class MatExpansionPanel
   implements AfterContentInit, OnChanges, OnDestroy
 {
   private _viewContainerRef = inject(ViewContainerRef);
-  _animationMode = inject(ANIMATION_MODULE_TYPE, {optional: true});
-
-  protected _animationsDisabled: boolean;
+  private readonly _animationsDisabled =
+    inject(ANIMATION_MODULE_TYPE, {optional: true}) === 'NoopAnimations';
   private _document = inject(DOCUMENT);
+  private _ngZone = inject(NgZone);
+  private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
+  private _renderer = inject(Renderer2);
+  private _cleanupTransitionEnd: (() => void) | undefined;
 
   /** Whether the toggle indicator should be hidden. */
   @Input({transform: booleanAttribute})
@@ -141,11 +140,15 @@ export class MatExpansionPanel
   /** Element containing the panel's user-provided content. */
   @ViewChild('body') _body: ElementRef<HTMLElement>;
 
+  /** Element wrapping the panel body. */
+  @ViewChild('bodyWrapper')
+  protected _bodyWrapper: ElementRef<HTMLElement> | undefined;
+
   /** Portal holding the user's content. */
   _portal: TemplatePortal;
 
   /** ID for the associated header element. Used for a11y labelling. */
-  _headerId = `mat-expansion-panel-header-${uniqueId++}`;
+  _headerId: string = inject(_IdGenerator).getId('mat-expansion-panel-header-');
 
   constructor(...args: unknown[]);
 
@@ -158,7 +161,6 @@ export class MatExpansionPanel
     );
 
     this._expansionDispatcher = inject(UniqueSelectionDispatcher);
-    this._animationsDisabled = this._animationMode === 'NoopAnimations';
 
     if (defaultOptions) {
       this.hideToggle = defaultOptions.hideToggle;
@@ -206,6 +208,8 @@ export class MatExpansionPanel
           this._portal = new TemplatePortal(this._lazyContent._template, this._viewContainerRef);
         });
     }
+
+    this._setupAnimationEvents();
   }
 
   ngOnChanges(changes: SimpleChanges) {
@@ -214,6 +218,7 @@ export class MatExpansionPanel
 
   override ngOnDestroy() {
     super.ngOnDestroy();
+    this._cleanupTransitionEnd?.();
     this._inputChanges.complete();
   }
 
@@ -228,38 +233,40 @@ export class MatExpansionPanel
     return false;
   }
 
-  /** Called when the expansion animation has started. */
-  protected _animationStarted(event: AnimationEvent) {
-    if (!isInitialAnimation(event) && !this._animationsDisabled && this._body) {
-      // Prevent the user from tabbing into the content while it's animating.
-      // TODO(crisbeto): maybe use `inert` to prevent focus from entering while closed as well
-      // instead of `visibility`? Will allow us to clean up some code but needs more testing.
-      this._body?.nativeElement.setAttribute('inert', '');
+  private _transitionEndListener = ({target, propertyName}: TransitionEvent) => {
+    if (target === this._bodyWrapper?.nativeElement && propertyName === 'grid-template-rows') {
+      this._ngZone.run(() => {
+        if (this.expanded) {
+          this.afterExpand.emit();
+        } else {
+          this.afterCollapse.emit();
+        }
+      });
     }
-  }
-
-  /** Called when the expansion animation has finished. */
-  protected _animationDone(event: AnimationEvent) {
-    if (!isInitialAnimation(event)) {
-      if (event.toState === 'expanded') {
-        this.afterExpand.emit();
-      } else if (event.toState === 'collapsed') {
-        this.afterCollapse.emit();
+  };
+
+  protected _setupAnimationEvents() {
+    // This method is defined separately, because we need to
+    // disable this logic in some internal components.
+    this._ngZone.runOutsideAngular(() => {
+      if (this._animationsDisabled) {
+        this.opened.subscribe(() => this._ngZone.run(() => this.afterExpand.emit()));
+        this.closed.subscribe(() => this._ngZone.run(() => this.afterCollapse.emit()));
+      } else {
+        setTimeout(() => {
+          const element = this._elementRef.nativeElement;
+          this._cleanupTransitionEnd = this._renderer.listen(
+            element,
+            'transitionend',
+            this._transitionEndListener,
+          );
+          element.classList.add('mat-expansion-panel-animations-enabled');
+        }, 200);
       }
-
-      // Re-enable tabbing once the animation is finished.
-      if (!this._animationsDisabled && this._body) {
-        this._body.nativeElement.removeAttribute('inert');
-      }
-    }
+    });
   }
 }
 
-/** Checks whether an animation is the initial setup animation. */
-function isInitialAnimation(event: AnimationEvent): boolean {
-  return event.fromState === 'void';
-}
-
 /**
  * Actions of a `<mat-expansion-panel>`.
  */
diff --git a/src/material/expansion/expansion.spec.ts b/src/material/expansion/expansion.spec.ts
index 4196816877fe..2fedd3188d8a 100644
--- a/src/material/expansion/expansion.spec.ts
+++ b/src/material/expansion/expansion.spec.ts
@@ -225,36 +225,20 @@ describe('MatExpansionPanel', () => {
     });
   });
 
-  it('should not be able to focus content while closed', fakeAsync(() => {
+  it('should not be able to focus content while closed', () => {
     const fixture = TestBed.createComponent(PanelWithContent);
     fixture.componentInstance.expanded = true;
     fixture.changeDetectorRef.markForCheck();
     fixture.detectChanges();
-    tick(250);
-
-    const button = fixture.debugElement.query(By.css('button'))!.nativeElement;
-
-    button.focus();
-    expect(document.activeElement)
-      .withContext('Expected button to start off focusable.')
-      .toBe(button);
+    const wrapper = fixture.nativeElement.querySelector('.mat-expansion-panel-content-wrapper');
+    expect(wrapper.hasAttribute('inert')).toBe(false);
 
-    button.blur();
     fixture.componentInstance.expanded = false;
     fixture.changeDetectorRef.markForCheck();
     fixture.detectChanges();
-    tick(250);
-
-    // Enforce a style recalculation as otherwise browsers like Safari on iOS 14 require
-    // us to wait until the next tick using actual async/await. Not retrieving the computed
-    // styles would result in the `visibility: hidden` on the expansion content to not apply.
-    getComputedStyle(button).getPropertyValue('visibility');
 
-    button.focus();
-    expect(document.activeElement)
-      .not.withContext('Expected button to no longer be focusable.')
-      .toBe(button);
-  }));
+    expect(wrapper.hasAttribute('inert')).toBe(true);
+  });
 
   it('should restore focus to header if focused element is inside panel on close', fakeAsync(() => {
     const fixture = TestBed.createComponent(PanelWithContent);
@@ -347,26 +331,6 @@ describe('MatExpansionPanel', () => {
     expect(content.classList).toContain('mat-content-hide-toggle');
   });
 
-  it('should update the indicator rotation when the expanded state is toggled programmatically', fakeAsync(() => {
-    const fixture = TestBed.createComponent(PanelWithContent);
-
-    fixture.detectChanges();
-    tick(250);
-
-    const arrow = fixture.debugElement.query(By.css('.mat-expansion-indicator'))!.nativeElement;
-
-    expect(arrow.style.transform).withContext('Expected no rotation.').toBe('rotate(0deg)');
-
-    fixture.componentInstance.expanded = true;
-    fixture.changeDetectorRef.markForCheck();
-    fixture.detectChanges();
-    tick(250);
-
-    expect(arrow.style.transform)
-      .withContext('Expected 180 degree rotation.')
-      .toBe('rotate(180deg)');
-  }));
-
   it('should make sure accordion item runs ngOnDestroy when expansion panel is destroyed', () => {
     const fixture = TestBed.createComponent(PanelWithContentInNgIf);
     fixture.detectChanges();
@@ -597,7 +561,6 @@ describe('MatExpansionPanel', () => {
     <p>Some content</p>
     <button>I am a button</button>
   </mat-expansion-panel>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class PanelWithContent {
@@ -619,7 +582,6 @@ class PanelWithContent {
       </div>
     }
   `,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class PanelWithContentInNgIf {
@@ -636,7 +598,6 @@ class PanelWithContentInNgIf {
     Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolores officia, aliquam dicta
     corrupti maxime voluptate accusamus impedit atque incidunt pariatur.
   </mat-expansion-panel>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class PanelWithCustomMargin {
@@ -653,7 +614,6 @@ class PanelWithCustomMargin {
       <button>I am a button</button>
     </ng-template>
   </mat-expansion-panel>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class LazyPanelWithContent {
@@ -669,7 +629,6 @@ class LazyPanelWithContent {
       <p>Some content</p>
     </ng-template>
   </mat-expansion-panel>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class LazyPanelOpenOnLoad {}
@@ -679,7 +638,6 @@ class LazyPanelOpenOnLoad {}
   <mat-expansion-panel [(expanded)]="expanded">
     <mat-expansion-panel-header>Panel Title</mat-expansion-panel-header>
   </mat-expansion-panel>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class PanelWithTwoWayBinding {
@@ -691,7 +649,6 @@ class PanelWithTwoWayBinding {
   <mat-expansion-panel>
     <mat-expansion-panel-header tabindex="7">Panel Title</mat-expansion-panel-header>
   </mat-expansion-panel>`,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class PanelWithHeaderTabindex {}
@@ -706,7 +663,6 @@ class PanelWithHeaderTabindex {}
       </mat-expansion-panel>
     </mat-expansion-panel>
   `,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class NestedLazyPanelWithContent {
diff --git a/src/material/expansion/testing/expansion-harness.spec.ts b/src/material/expansion/testing/expansion-harness.spec.ts
index 807462e41b47..cc93787cf573 100644
--- a/src/material/expansion/testing/expansion-harness.spec.ts
+++ b/src/material/expansion/testing/expansion-harness.spec.ts
@@ -328,7 +328,6 @@ function getActiveElementTag() {
 
     <div class="test-content-harness">Outside of expansion panel</div>
   `,
-  standalone: true,
   imports: [MatExpansionModule],
 })
 class ExpansionHarnessTestComponent {
diff --git a/src/material/form-field/directives/error.ts b/src/material/form-field/directives/error.ts
index 05304db89400..a304e90a8171 100644
--- a/src/material/form-field/directives/error.ts
+++ b/src/material/form-field/directives/error.ts
@@ -14,8 +14,7 @@ import {
   HostAttributeToken,
   inject,
 } from '@angular/core';
-
-let nextUniqueId = 0;
+import {_IdGenerator} from '@angular/cdk/a11y';
 
 /**
  * Injection token that can be used to reference instances of `MatError`. It serves as
@@ -35,7 +34,7 @@ export const MAT_ERROR = new InjectionToken<MatError>('MatError');
   providers: [{provide: MAT_ERROR, useExisting: MatError}],
 })
 export class MatError {
-  @Input() id: string = `mat-mdc-error-${nextUniqueId++}`;
+  @Input() id: string = inject(_IdGenerator).getId('mat-mdc-error-');
 
   constructor(...args: unknown[]);
 
diff --git a/src/material/form-field/directives/hint.ts b/src/material/form-field/directives/hint.ts
index 159fc054ce4a..147bd77b86e1 100644
--- a/src/material/form-field/directives/hint.ts
+++ b/src/material/form-field/directives/hint.ts
@@ -6,9 +6,8 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {Directive, Input} from '@angular/core';
-
-let nextUniqueId = 0;
+import {Directive, inject, Input} from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 
 /** Hint text to be shown underneath the form field control. */
 @Directive({
@@ -26,5 +25,5 @@ export class MatHint {
   @Input() align: 'start' | 'end' = 'start';
 
   /** Unique ID for the hint. Used for the aria-describedby on the form field control. */
-  @Input() id: string = `mat-mdc-hint-${nextUniqueId++}`;
+  @Input() id: string = inject(_IdGenerator).getId('mat-mdc-hint-');
 }
diff --git a/src/material/form-field/directives/line-ripple.ts b/src/material/form-field/directives/line-ripple.ts
index 7f5737944123..3fc842c264d3 100644
--- a/src/material/form-field/directives/line-ripple.ts
+++ b/src/material/form-field/directives/line-ripple.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {Directive, ElementRef, NgZone, OnDestroy, inject} from '@angular/core';
+import {Directive, ElementRef, NgZone, OnDestroy, Renderer2, inject} from '@angular/core';
 
 /** Class added when the line ripple is active. */
 const ACTIVATE_CLASS = 'mdc-line-ripple--active';
@@ -30,14 +30,20 @@ const DEACTIVATING_CLASS = 'mdc-line-ripple--deactivating';
 })
 export class MatFormFieldLineRipple implements OnDestroy {
   private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
+  private _cleanupTransitionEnd: () => void;
 
   constructor(...args: unknown[]);
 
   constructor() {
     const ngZone = inject(NgZone);
+    const renderer = inject(Renderer2);
 
     ngZone.runOutsideAngular(() => {
-      this._elementRef.nativeElement.addEventListener('transitionend', this._handleTransitionEnd);
+      this._cleanupTransitionEnd = renderer.listen(
+        this._elementRef.nativeElement,
+        'transitionend',
+        this._handleTransitionEnd,
+      );
     });
   }
 
@@ -61,6 +67,6 @@ export class MatFormFieldLineRipple implements OnDestroy {
   };
 
   ngOnDestroy() {
-    this._elementRef.nativeElement.removeEventListener('transitionend', this._handleTransitionEnd);
+    this._cleanupTransitionEnd();
   }
 }
diff --git a/src/material/form-field/form-field.md b/src/material/form-field/form-field.md
index 83d0b2b2f45e..fb5e1335d1dd 100644
--- a/src/material/form-field/form-field.md
+++ b/src/material/form-field/form-field.md
@@ -11,7 +11,7 @@ The following Angular Material components are designed to work inside a `<mat-fo
 - [`<input matNativeControl>` &amp; `<textarea matNativeControl>`](https://material.angular.io/components/input/overview)
 - [`<select matNativeControl>`](https://material.angular.io/components/select/overview)
 - [`<mat-select>`](https://material.angular.io/components/select/overview)
-- [`<mat-chip-list>`](https://material.angular.io/components/chips/overview)
+- [`<mat-chip-set>`](https://material.angular.io/components/chips/overview)
 
 <!-- example(form-field-overview) -->
 
diff --git a/src/material/form-field/form-field.ts b/src/material/form-field/form-field.ts
index 0d827d164f2b..7e871d0bd2bb 100644
--- a/src/material/form-field/form-field.ts
+++ b/src/material/form-field/form-field.ts
@@ -34,8 +34,9 @@ import {
 } from '@angular/core';
 import {AbstractControlDirective} from '@angular/forms';
 import {ThemePalette} from '@angular/material/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {Subject, Subscription, merge} from 'rxjs';
-import {takeUntil} from 'rxjs/operators';
+import {map, pairwise, takeUntil, filter, startWith} from 'rxjs/operators';
 import {MAT_ERROR, MatError} from './directives/error';
 import {
   FLOATING_LABEL_PARENT,
@@ -73,10 +74,10 @@ export interface MatFormFieldDefaultOptions {
   appearance?: MatFormFieldAppearance;
   /**
    * Default theme color of the form field. This API is supported in M2 themes only, it has no
-   * effect in M3 themes.
+   * effect in M3 themes. For color customization in M3, see https://material.angular.io/components/form-field/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   color?: ThemePalette;
   /** Whether the required marker should be hidden by default. */
@@ -105,8 +106,6 @@ export const MAT_FORM_FIELD_DEFAULT_OPTIONS = new InjectionToken<MatFormFieldDef
   'MAT_FORM_FIELD_DEFAULT_OPTIONS',
 );
 
-let nextUniqueId = 0;
-
 /** Default appearance used by the form field. */
 const DEFAULT_APPEARANCE: MatFormFieldAppearance = 'fill';
 
@@ -191,6 +190,7 @@ export class MatFormField
   private _changeDetectorRef = inject(ChangeDetectorRef);
   private _dir = inject(Directionality);
   private _platform = inject(Platform);
+  private _idGenerator = inject(_IdGenerator);
   private _defaults = inject<MatFormFieldDefaultOptions>(MAT_FORM_FIELD_DEFAULT_OPTIONS, {
     optional: true,
   });
@@ -225,10 +225,10 @@ export class MatFormField
 
   /**
    * Theme color of the form field. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/form-field/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette = 'primary';
 
@@ -305,10 +305,10 @@ export class MatFormField
   _hasTextSuffix = false;
 
   // Unique id for the internal form field label.
-  readonly _labelId = `mat-mdc-form-field-label-${nextUniqueId++}`;
+  readonly _labelId = this._idGenerator.getId('mat-mdc-form-field-label-');
 
   // Unique id for the hint label.
-  readonly _hintLabelId = `mat-mdc-hint-${nextUniqueId++}`;
+  readonly _hintLabelId = this._idGenerator.getId('mat-mdc-hint-');
 
   /** State of the mat-hint and mat-error animations. */
   _subscriptAnimationState = '';
@@ -328,6 +328,7 @@ export class MatFormField
   private _previousControl: MatFormFieldControl<unknown> | null = null;
   private _stateChanges: Subscription | undefined;
   private _valueChanges: Subscription | undefined;
+  private _describedByChanges: Subscription | undefined;
 
   private _injector = inject(Injector);
 
@@ -377,6 +378,7 @@ export class MatFormField
   ngOnDestroy() {
     this._stateChanges?.unsubscribe();
     this._valueChanges?.unsubscribe();
+    this._describedByChanges?.unsubscribe();
     this._destroyed.next();
     this._destroyed.complete();
   }
@@ -426,10 +428,22 @@ export class MatFormField
     this._stateChanges?.unsubscribe();
     this._stateChanges = control.stateChanges.subscribe(() => {
       this._updateFocusState();
-      this._syncDescribedByIds();
       this._changeDetectorRef.markForCheck();
     });
 
+    // Updating the `aria-describedby` touches the DOM. Only do it if it actually needs to change.
+    this._describedByChanges?.unsubscribe();
+    this._describedByChanges = control.stateChanges
+      .pipe(
+        startWith([undefined, undefined] as const),
+        map(() => [control.errorState, control.userAriaDescribedBy] as const),
+        pairwise(),
+        filter(([[prevErrorState, prevDescribedBy], [currentErrorState, currentDescribedBy]]) => {
+          return prevErrorState !== currentErrorState || prevDescribedBy !== currentDescribedBy;
+        }),
+      )
+      .subscribe(() => this._syncDescribedByIds());
+
     this._valueChanges?.unsubscribe();
 
     // Run change detection if the value changes.
diff --git a/src/material/form-field/module.ts b/src/material/form-field/module.ts
index 92e042438fa2..4e09f29dff33 100644
--- a/src/material/form-field/module.ts
+++ b/src/material/form-field/module.ts
@@ -7,7 +7,6 @@
  */
 
 import {ObserversModule} from '@angular/cdk/observers';
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {MatCommonModule} from '@angular/material/core';
 import {MatError} from './directives/error';
@@ -20,7 +19,6 @@ import {MatFormField} from './form-field';
 @NgModule({
   imports: [
     MatCommonModule,
-    CommonModule,
     ObserversModule,
     MatFormField,
     MatLabel,
diff --git a/src/material/form-field/testing/form-field-harness.spec.ts b/src/material/form-field/testing/form-field-harness.spec.ts
index b5d7642b1041..dc6a8e34aad2 100644
--- a/src/material/form-field/testing/form-field-harness.spec.ts
+++ b/src/material/form-field/testing/form-field-harness.spec.ts
@@ -357,7 +357,6 @@ describe('MatFormFieldHarness', () => {
       <mat-date-range-picker #rangePicker></mat-date-range-picker>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [
     ReactiveFormsModule,
     MatNativeDateModule,
diff --git a/src/material/grid-list/testing/grid-list-harness.spec.ts b/src/material/grid-list/testing/grid-list-harness.spec.ts
index 621f39a86e69..f0ceb23f1918 100644
--- a/src/material/grid-list/testing/grid-list-harness.spec.ts
+++ b/src/material/grid-list/testing/grid-list-harness.spec.ts
@@ -182,7 +182,6 @@ describe('MatGridListHarness', () => {
       </mat-grid-tile>
     </mat-grid-list>
   `,
-  standalone: true,
   imports: [MatGridListModule],
 })
 class GridListHarnessTest {
diff --git a/src/material/icon/icon.spec.ts b/src/material/icon/icon.spec.ts
index 84f9971285b9..3649f4aa94ee 100644
--- a/src/material/icon/icon.spec.ts
+++ b/src/material/icon/icon.spec.ts
@@ -1464,7 +1464,6 @@ describe('MatIcon with default options', () => {
 
 @Component({
   template: `<mat-icon>{{iconName}}</mat-icon>`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class IconWithLigature {
@@ -1473,7 +1472,6 @@ class IconWithLigature {
 
 @Component({
   template: `<mat-icon [fontIcon]="iconName"></mat-icon>`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class IconWithLigatureByAttribute {
@@ -1482,7 +1480,6 @@ class IconWithLigatureByAttribute {
 
 @Component({
   template: `<mat-icon [color]="iconColor">{{iconName}}</mat-icon>`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class IconWithColor {
@@ -1492,7 +1489,6 @@ class IconWithColor {
 
 @Component({
   template: `<mat-icon [fontSet]="fontSet" [fontIcon]="fontIcon"></mat-icon>`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class IconWithCustomFontCss {
@@ -1502,7 +1498,6 @@ class IconWithCustomFontCss {
 
 @Component({
   template: `<mat-icon [svgIcon]="iconName"></mat-icon>`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class IconFromSvgName {
@@ -1511,14 +1506,12 @@ class IconFromSvgName {
 
 @Component({
   template: '<mat-icon aria-hidden="false">face</mat-icon>',
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class IconWithAriaHiddenFalse {}
 
 @Component({
   template: `@if (showIcon) {<mat-icon [svgIcon]="iconName">{{iconName}}</mat-icon>}`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class IconWithBindingAndNgIf {
@@ -1528,7 +1521,6 @@ class IconWithBindingAndNgIf {
 
 @Component({
   template: `<mat-icon [inline]="inline">{{iconName}}</mat-icon>`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class InlineIcon {
@@ -1537,7 +1529,6 @@ class InlineIcon {
 
 @Component({
   template: `<mat-icon [svgIcon]="iconName"><div>Hello</div></mat-icon>`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class SvgIconWithUserContent {
@@ -1546,7 +1537,6 @@ class SvgIconWithUserContent {
 
 @Component({
   template: '<mat-icon [svgIcon]="iconName">house</mat-icon>',
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class IconWithLigatureAndSvgBinding {
@@ -1555,7 +1545,6 @@ class IconWithLigatureAndSvgBinding {
 
 @Component({
   template: `<mat-icon></mat-icon>`,
-  standalone: true,
   imports: [HttpClientTestingModule, MatIconModule],
 })
 class BlankIcon {
diff --git a/src/material/icon/icon.ts b/src/material/icon/icon.ts
index 3e80cf730c97..24e8d0be78d6 100644
--- a/src/material/icon/icon.ts
+++ b/src/material/icon/icon.ts
@@ -32,10 +32,10 @@ import {MatIconRegistry} from './icon-registry';
 export interface MatIconDefaultOptions {
   /**
    * Theme color of the icon. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/icon/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   color?: ThemePalette;
   /** Font set that the icon is a part of. */
@@ -159,10 +159,10 @@ export class MatIcon implements OnInit, AfterViewChecked, OnDestroy {
 
   /**
    * Theme color of the icon. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/icon/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   get color() {
diff --git a/src/material/icon/testing/icon-harness.spec.ts b/src/material/icon/testing/icon-harness.spec.ts
index 892badea88fc..f966db30c634 100644
--- a/src/material/icon/testing/icon-harness.spec.ts
+++ b/src/material/icon/testing/icon-harness.spec.ts
@@ -114,7 +114,6 @@ describe('MatIconHarness', () => {
     <mat-icon>ligature_icon_with_additional_content <span class="fake-badge">Hello</span></mat-icon>
     <mat-icon><span>ligature_icon_with_indirect_name</span></mat-icon>
   `,
-  standalone: true,
   imports: [MatIconModule],
 })
 class IconHarnessTest {}
diff --git a/src/material/input/input.spec.ts b/src/material/input/input.spec.ts
index 1921d48a1e38..611cdc3320f2 100644
--- a/src/material/input/input.spec.ts
+++ b/src/material/input/input.spec.ts
@@ -607,7 +607,7 @@ describe('MatMdcInput without forms', () => {
     fixture.componentInstance.formControl.markAsTouched();
     fixture.componentInstance.formControl.setErrors({invalid: true});
     fixture.detectChanges();
-    expect(input.getAttribute('aria-describedby')).toMatch(/^custom-error mat-mdc-error-\d+$/);
+    expect(input.getAttribute('aria-describedby')).toMatch(/^custom-error mat-mdc-error-\w+\d+$/);
 
     fixture.componentInstance.label = '';
     fixture.componentInstance.userDescribedByValue = '';
@@ -643,6 +643,18 @@ describe('MatMdcInput without forms', () => {
     expect(input.getAttribute('aria-describedby')).toBe('start end');
   }));
 
+  it('should preserve aria-describedby set directly in the DOM', fakeAsync(() => {
+    const fixture = createComponent(MatInputHintLabel2TestController);
+    const input = fixture.nativeElement.querySelector('input');
+    input.setAttribute('aria-describedby', 'custom');
+    fixture.componentInstance.label = 'label';
+    fixture.changeDetectorRef.markForCheck();
+    fixture.detectChanges();
+    const hint = fixture.nativeElement.querySelector('.mat-mdc-form-field-hint');
+
+    expect(input.getAttribute('aria-describedby')).toBe(`${hint.getAttribute('id')} custom`);
+  }));
+
   it('should set a class on the hint element based on its alignment', fakeAsync(() => {
     const fixture = createComponent(MatInputMultipleHintTestController);
 
diff --git a/src/material/input/input.ts b/src/material/input/input.ts
index f1b4f340d7f3..e0a768ebaffc 100644
--- a/src/material/input/input.ts
+++ b/src/material/input/input.ts
@@ -23,8 +23,10 @@ import {
   NgZone,
   OnChanges,
   OnDestroy,
+  Renderer2,
   WritableSignal,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {FormGroupDirective, NgControl, NgForm, Validators} from '@angular/forms';
 import {ErrorStateMatcher, _ErrorStateTracker} from '@angular/material/core';
 import {MatFormFieldControl, MatFormField, MAT_FORM_FIELD} from '@angular/material/form-field';
@@ -45,8 +47,6 @@ const MAT_INPUT_INVALID_TYPES = [
   'submit',
 ];
 
-let nextUniqueId = 0;
-
 /** Object that can be used to configure the default options for the input. */
 export interface MatInputConfig {
   /** Whether disabled inputs should be interactive. */
@@ -102,15 +102,20 @@ export class MatInput
   private _autofillMonitor = inject(AutofillMonitor);
   private _ngZone = inject(NgZone);
   protected _formField? = inject<MatFormField>(MAT_FORM_FIELD, {optional: true});
+  private _renderer = inject(Renderer2);
 
-  protected _uid = `mat-input-${nextUniqueId++}`;
+  protected _uid = inject(_IdGenerator).getId('mat-input-');
   protected _previousNativeValue: any;
   private _inputValueAccessor: {value: any};
   private _signalBasedValueAccessor?: {value: WritableSignal<any>};
   private _previousPlaceholder: string | null;
   private _errorStateTracker: _ErrorStateTracker;
-  private _webkitBlinkWheelListenerAttached = false;
   private _config = inject(MAT_INPUT_CONFIG, {optional: true});
+  private _cleanupIosKeyup: (() => void) | undefined;
+  private _cleanupWebkitWheel: (() => void) | undefined;
+
+  /** `aria-describedby` IDs assigned by the form field. */
+  private _formFieldDescribedBy: string[] | undefined;
 
   /** Whether the component is being rendered on the server. */
   readonly _isServer: boolean;
@@ -212,6 +217,7 @@ export class MatInput
     return this._type;
   }
   set type(value: string) {
+    const prevType = this._type;
     this._type = value || 'text';
     this._validateType();
 
@@ -222,7 +228,9 @@ export class MatInput
       (this._elementRef.nativeElement as HTMLInputElement).type = this._type;
     }
 
-    this._ensureWheelDefaultBehavior();
+    if (this._type !== prevType) {
+      this._ensureWheelDefaultBehavior();
+    }
   }
   protected _type = 'text';
 
@@ -327,7 +335,7 @@ export class MatInput
     // exists on iOS, we only bother to install the listener on iOS.
     if (this._platform.IOS) {
       this._ngZone.runOutsideAngular(() => {
-        element.addEventListener('keyup', this._iOSKeyupListener);
+        this._cleanupIosKeyup = this._renderer.listen(element, 'keyup', this._iOSKeyupListener);
       });
     }
 
@@ -379,13 +387,8 @@ export class MatInput
       this._autofillMonitor.stopMonitoring(this._elementRef.nativeElement);
     }
 
-    if (this._platform.IOS) {
-      this._elementRef.nativeElement.removeEventListener('keyup', this._iOSKeyupListener);
-    }
-
-    if (this._webkitBlinkWheelListenerAttached) {
-      this._elementRef.nativeElement.removeEventListener('wheel', this._webkitBlinkWheelListener);
-    }
+    this._cleanupIosKeyup?.();
+    this._cleanupWebkitWheel?.();
   }
 
   ngDoCheck() {
@@ -552,10 +555,29 @@ export class MatInput
    * @docs-private
    */
   setDescribedByIds(ids: string[]) {
-    if (ids.length) {
-      this._elementRef.nativeElement.setAttribute('aria-describedby', ids.join(' '));
+    const element = this._elementRef.nativeElement;
+    const existingDescribedBy = element.getAttribute('aria-describedby');
+    let toAssign: string[];
+
+    // In some cases there might be some `aria-describedby` IDs that were assigned directly,
+    // like by the `AriaDescriber` (see #30011). Attempt to preserve them by taking the previous
+    // attribute value and filtering out the IDs that came from the previous `setDescribedByIds`
+    // call. Note the `|| ids` here allows us to avoid duplicating IDs on the first render.
+    if (existingDescribedBy) {
+      const exclude = this._formFieldDescribedBy || ids;
+      toAssign = ids.concat(
+        existingDescribedBy.split(' ').filter(id => id && !exclude.includes(id)),
+      );
     } else {
-      this._elementRef.nativeElement.removeAttribute('aria-describedby');
+      toAssign = ids;
+    }
+
+    this._formFieldDescribedBy = ids;
+
+    if (toAssign.length) {
+      element.setAttribute('aria-describedby', toAssign.join(' '));
+    } else {
+      element.removeAttribute('aria-describedby');
     }
   }
 
@@ -605,27 +627,22 @@ export class MatInput
 
   /**
    * In blink and webkit browsers a focused number input does not increment or decrement its value
-   * on mouse wheel interaction unless a wheel event listener is attached to it or one of its ancestors or a passive wheel listener is attached somewhere in the DOM.
-   * For example: Hitting a tooltip once enables the mouse wheel input for all number inputs as long as it exists.
-   * In order to get reliable and intuitive behavior we apply a wheel event on our own
-   * thus making sure increment and decrement by mouse wheel works every time.
+   * on mouse wheel interaction unless a wheel event listener is attached to it or one of its
+   * ancestors or a passive wheel listener is attached somewhere in the DOM. For example: Hitting
+   * a tooltip once enables the mouse wheel input for all number inputs as long as it exists. In
+   * order to get reliable and intuitive behavior we apply a wheel event on our own thus making
+   * sure increment and decrement by mouse wheel works every time.
    * @docs-private
    */
   private _ensureWheelDefaultBehavior(): void {
-    if (
-      !this._webkitBlinkWheelListenerAttached &&
-      this._type === 'number' &&
-      (this._platform.BLINK || this._platform.WEBKIT)
-    ) {
-      this._ngZone.runOutsideAngular(() => {
-        this._elementRef.nativeElement.addEventListener('wheel', this._webkitBlinkWheelListener);
-      });
-      this._webkitBlinkWheelListenerAttached = true;
-    }
+    this._cleanupWebkitWheel?.();
 
-    if (this._webkitBlinkWheelListenerAttached && this._type !== 'number') {
-      this._elementRef.nativeElement.removeEventListener('wheel', this._webkitBlinkWheelListener);
-      this._webkitBlinkWheelListenerAttached = true;
+    if (this._type === 'number' && (this._platform.BLINK || this._platform.WEBKIT)) {
+      this._cleanupWebkitWheel = this._renderer.listen(
+        this._elementRef.nativeElement,
+        'wheel',
+        this._webkitBlinkWheelListener,
+      );
     }
   }
 
diff --git a/src/material/input/testing/input-harness.spec.ts b/src/material/input/testing/input-harness.spec.ts
index 0224d6dc2500..e546a4561b1d 100644
--- a/src/material/input/testing/input-harness.spec.ts
+++ b/src/material/input/testing/input-harness.spec.ts
@@ -66,11 +66,11 @@ describe('MatInputHarness', () => {
   it('should be able to get id of input', async () => {
     const inputs = await loader.getAllHarnesses(MatInputHarness);
     expect(inputs.length).toBe(7);
-    expect(await inputs[0].getId()).toMatch(/mat-input-\d+/);
-    expect(await inputs[1].getId()).toMatch(/mat-input-\d+/);
+    expect(await inputs[0].getId()).toMatch(/mat-input-\w+\d+/);
+    expect(await inputs[1].getId()).toMatch(/mat-input-\w+\d+/);
     expect(await inputs[2].getId()).toBe('myTextarea');
     expect(await inputs[3].getId()).toBe('nativeControl');
-    expect(await inputs[4].getId()).toMatch(/mat-input-\d+/);
+    expect(await inputs[4].getId()).toMatch(/mat-input-\w+\d+/);
     expect(await inputs[5].getId()).toBe('has-ng-model');
   });
 
@@ -279,7 +279,6 @@ describe('MatInputHarness', () => {
       <input matNativeControl placeholder="Color control" id="colorControl" type="color">
     </mat-form-field>
   `,
-  standalone: true,
   imports: [MatInputModule, FormsModule],
 })
 class InputHarnessTest {
diff --git a/src/material/input/testing/native-select-harness.spec.ts b/src/material/input/testing/native-select-harness.spec.ts
index 5e2249fcf580..4bc7b6c0d5a4 100644
--- a/src/material/input/testing/native-select-harness.spec.ts
+++ b/src/material/input/testing/native-select-harness.spec.ts
@@ -219,7 +219,6 @@ describe('MatNativeSelectHarness', () => {
       </select>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [MatInputModule, FormsModule],
 })
 class SelectHarnessTest {
diff --git a/src/material/list/list-module.ts b/src/material/list/list-module.ts
index ebb83b31883e..75c4cec2676b 100644
--- a/src/material/list/list-module.ts
+++ b/src/material/list/list-module.ts
@@ -6,7 +6,6 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {MatPseudoCheckboxModule, MatRippleModule, MatCommonModule} from '@angular/material/core';
 import {MatDividerModule} from '@angular/material/divider';
@@ -28,7 +27,6 @@ import {ObserversModule} from '@angular/cdk/observers';
 @NgModule({
   imports: [
     ObserversModule,
-    CommonModule,
     MatCommonModule,
     MatRippleModule,
     MatPseudoCheckboxModule,
diff --git a/src/material/list/list-option.ts b/src/material/list/list-option.ts
index c0bb4f419eae..c144909d67b6 100644
--- a/src/material/list/list-option.ts
+++ b/src/material/list/list-option.ts
@@ -133,10 +133,11 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
 
   /**
    * Theme color of the list option. This sets the color of the checkbox/radio.
-   * This API is supported in M2 themes only, it has no effect in M3 themes.
+   * This API is supported in M2 themes only, it has no effect in M3 themes. For color customization
+   * in M3, see https://material.angular.io/components/list/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   get color(): ThemePalette {
diff --git a/src/material/list/list.spec.ts b/src/material/list/list.spec.ts
index 6ba78e3d5508..171467313070 100644
--- a/src/material/list/list.spec.ts
+++ b/src/material/list/list.spec.ts
@@ -434,7 +434,6 @@ class BaseTestList {
       Paprika
     </a>
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithOneAnchorItem extends BaseTestList {
@@ -450,7 +449,6 @@ class ListWithOneAnchorItem extends BaseTestList {
       Paprika
     </a>
   </mat-nav-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class NavListWithOneAnchorItem extends BaseTestList {
@@ -469,7 +467,6 @@ class NavListWithOneAnchorItem extends BaseTestList {
       </a>
     }
   </mat-nav-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class NavListWithActivatedItem extends BaseTestList {
@@ -488,7 +485,6 @@ class NavListWithActivatedItem extends BaseTestList {
       Paprika
     </button>
   </mat-action-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ActionListWithoutType extends BaseTestList {
@@ -504,7 +500,6 @@ class ActionListWithoutType extends BaseTestList {
       Paprika
     </button>
   </mat-action-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ActionListWithType extends BaseTestList {
@@ -518,7 +513,6 @@ class ActionListWithType extends BaseTestList {
       <button mat-list-item>{{item.name}}</button>
     }
   </mat-action-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ActionListWithDisabledList extends BaseTestList {
@@ -532,7 +526,6 @@ class ActionListWithDisabledList extends BaseTestList {
       Paprika
     </button>
   </mat-action-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ActionListWithDisabledItem extends BaseTestList {
@@ -547,7 +540,6 @@ class ActionListWithDisabledItem extends BaseTestList {
       Paprika
     </mat-list-item>
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithOneItem extends BaseTestList {}
@@ -563,7 +555,6 @@ class ListWithOneItem extends BaseTestList {}
       </mat-list-item>
     }
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithTwoLineItem extends BaseTestList {}
@@ -579,7 +570,6 @@ class ListWithTwoLineItem extends BaseTestList {}
       </mat-list-item>
     }
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithThreeLineItem extends BaseTestList {}
@@ -595,7 +585,6 @@ class ListWithThreeLineItem extends BaseTestList {}
       Pepper
     </mat-list-item>
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithAvatar extends BaseTestList {}
@@ -610,7 +599,6 @@ class ListWithAvatar extends BaseTestList {}
       </mat-list-item>
     }
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithItemWithCssClass extends BaseTestList {}
@@ -628,7 +616,6 @@ class ListWithItemWithCssClass extends BaseTestList {}
       </mat-list-item>
     }
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithDynamicNumberOfLines extends BaseTestList {}
@@ -640,7 +627,6 @@ class ListWithDynamicNumberOfLines extends BaseTestList {}
       <mat-list-item>{{item.name}}</mat-list-item>
     }
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithMultipleItems extends BaseTestList {}
@@ -652,7 +638,6 @@ class ListWithMultipleItems extends BaseTestList {}
     <mat-list-item>Two</mat-list-item>
     <mat-list-item>Three</mat-list-item>
   </mat-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListWithDisabledItems {
@@ -662,7 +647,6 @@ class ListWithDisabledItems {
 
 @Component({
   template: `<mat-list-item></mat-list-item>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class StandaloneListItem {}
diff --git a/src/material/list/selection-list.spec.ts b/src/material/list/selection-list.spec.ts
index ec13b1283864..09b6c7233961 100644
--- a/src/material/list/selection-list.spec.ts
+++ b/src/material/list/selection-list.spec.ts
@@ -363,7 +363,7 @@ describe('MatSelectionList without forms', () => {
       expect(event.defaultPrevented).toBe(true);
     });
 
-    it('should select all items using ctrl + a', () => {
+    it('should select and deselect all items using ctrl + a', () => {
       listOptions.forEach(option => (option.componentInstance.disabled = false));
       fixture.changeDetectorRef.markForCheck();
       fixture.detectChanges();
@@ -375,6 +375,29 @@ describe('MatSelectionList without forms', () => {
       fixture.detectChanges();
 
       expect(listOptions.every(option => option.componentInstance.selected)).toBe(true);
+
+      dispatchKeyboardEvent(listOptions[2].nativeElement, 'keydown', A, 'A', {control: true});
+      fixture.detectChanges();
+
+      expect(listOptions.every(option => option.componentInstance.selected)).toBe(false);
+    });
+
+    it('should select and deselect all items using meta + a', () => {
+      listOptions.forEach(option => (option.componentInstance.disabled = false));
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+
+      expect(listOptions.some(option => option.componentInstance.selected)).toBe(false);
+
+      listOptions[2].nativeElement.focus();
+      dispatchKeyboardEvent(listOptions[2].nativeElement, 'keydown', A, 'A', {meta: true});
+      fixture.detectChanges();
+
+      expect(listOptions.every(option => option.componentInstance.selected)).toBe(true);
+      dispatchKeyboardEvent(listOptions[2].nativeElement, 'keydown', A, 'A', {meta: true});
+      fixture.detectChanges();
+
+      expect(listOptions.every(option => option.componentInstance.selected)).toBe(false);
     });
 
     it('should not select disabled items when pressing ctrl + a', () => {
@@ -1762,7 +1785,6 @@ describe('MatSelectionList with forms', () => {
       </mat-list-option>
     }
   </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithListOptions {
@@ -1791,7 +1813,6 @@ class SelectionListWithListOptions {
       Drafts
     </mat-list-option>
   </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithCheckboxPositionAfter {}
@@ -1812,7 +1833,6 @@ class SelectionListWithCheckboxPositionAfter {}
       Drafts
     </mat-list-option>
   </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithListDisabled {
@@ -1825,7 +1845,6 @@ class SelectionListWithListDisabled {
     <mat-list-option [disabled]="disableItem">Item</mat-list-option>
   </mat-selection-list>
   `,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithDisabledOption {
@@ -1840,7 +1859,6 @@ class SelectionListWithDisabledOption {
     <mat-list-option [selected]="true">Pre-selected - Item #3</mat-list-option>
     <mat-list-option>Not selected - Item #4</mat-list-option>
   </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithSelectedOption {}
@@ -1851,7 +1869,6 @@ class SelectionListWithSelectedOption {}
     <mat-list-option>Not selected - Item #1</mat-list-option>
     <mat-list-option [selected]="true">Pre-selected - Item #2</mat-list-option>
   </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class SingleSelectionListWithSelectedOption {}
@@ -1861,7 +1878,6 @@ class SingleSelectionListWithSelectedOption {}
   <mat-selection-list>
     <mat-list-option [selected]="true" [value]="itemValue">Item</mat-list-option>
   </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithSelectedOptionAndValue {
@@ -1875,7 +1891,6 @@ class SelectionListWithSelectedOptionAndValue {
       Inbox
     </mat-list-option>
   </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithOnlyOneOption {}
@@ -1890,7 +1905,6 @@ class SelectionListWithOnlyOneOption {}
         <mat-list-option [value]="option">{{option}}</mat-list-option>
       }
     </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule, FormsModule, ReactiveFormsModule],
 })
 class SelectionListWithModel {
@@ -1913,7 +1927,6 @@ class SelectionListWithModel {
       </mat-selection-list>
     }
   `,
-  standalone: true,
   imports: [MatListModule, FormsModule, ReactiveFormsModule],
 })
 class SelectionListWithFormControl {
@@ -1928,7 +1941,6 @@ class SelectionListWithFormControl {
       <mat-list-option value="opt1">Option 1</mat-list-option>
       <mat-list-option value="opt2" selected>Option 2</mat-list-option>
     </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule, FormsModule, ReactiveFormsModule],
 })
 class SelectionListWithPreselectedOption {
@@ -1941,7 +1953,6 @@ class SelectionListWithPreselectedOption {
       <mat-list-option value="opt1">Option 1</mat-list-option>
       <mat-list-option value="opt2" selected>Option 2</mat-list-option>
     </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule, FormsModule, ReactiveFormsModule],
 })
 class SelectionListWithPreselectedOptionAndModel {
@@ -1957,7 +1968,6 @@ class SelectionListWithPreselectedOptionAndModel {
       }
     </mat-selection-list>
   `,
-  standalone: true,
   imports: [MatListModule, FormsModule, ReactiveFormsModule],
 })
 class SelectionListWithPreselectedFormControlOnPush {
@@ -1972,7 +1982,6 @@ class SelectionListWithPreselectedFormControlOnPush {
         <mat-list-option [value]="option">{{option.label}}</mat-list-option>
       }
     </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule, FormsModule, ReactiveFormsModule],
 })
 class SelectionListWithCustomComparator {
@@ -1995,7 +2004,6 @@ class SelectionListWithCustomComparator {
       </mat-list-option>
     </mat-selection-list>
   `,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithAvatar {
@@ -2011,7 +2019,6 @@ class SelectionListWithAvatar {
       </mat-list-option>
     </mat-selection-list>
   `,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithIcon {
@@ -2027,7 +2034,6 @@ class SelectionListWithIcon {
         <mat-list-option [value]="2">Two</mat-list-option>
       }
     </mat-selection-list>`,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListWithIndirectChildOptions {
@@ -2040,7 +2046,6 @@ class SelectionListWithIndirectChildOptions {
     <mat-list-option [(selected)]="selected">Item</mat-list-option>
   </mat-selection-list>
 `,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListOptionWithTwoWayBinding {
diff --git a/src/material/list/selection-list.ts b/src/material/list/selection-list.ts
index c75002c2e38c..2ba9ce71a1e9 100644
--- a/src/material/list/selection-list.ts
+++ b/src/material/list/selection-list.ts
@@ -25,6 +25,7 @@ import {
   OnDestroy,
   Output,
   QueryList,
+  Renderer2,
   SimpleChanges,
   ViewEncapsulation,
   forwardRef,
@@ -78,9 +79,11 @@ export class MatSelectionList
 {
   _element = inject<ElementRef<HTMLElement>>(ElementRef);
   private _ngZone = inject(NgZone);
+  private _renderer = inject(Renderer2);
 
   private _initialized = false;
   private _keyManager: FocusKeyManager<MatListOption>;
+  private _listenerCleanups: (() => void)[] | undefined;
 
   /** Emits when the list has been destroyed. */
   private _destroyed = new Subject<void>();
@@ -100,10 +103,10 @@ export class MatSelectionList
   /**
    * Theme color of the selection list. This sets the checkbox color for all
    * list options. This API is supported in M2 themes only, it has no effect in
-   * M3 themes.
+   * M3 themes. For color customization in M3, see https://material.angular.io/components/list/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette = 'accent';
 
@@ -173,8 +176,10 @@ export class MatSelectionList
     // These events are bound outside the zone, because they don't change
     // any change-detected properties and they can trigger timeouts.
     this._ngZone.runOutsideAngular(() => {
-      this._element.nativeElement.addEventListener('focusin', this._handleFocusin);
-      this._element.nativeElement.addEventListener('focusout', this._handleFocusout);
+      this._listenerCleanups = [
+        this._renderer.listen(this._element.nativeElement, 'focusin', this._handleFocusin),
+        this._renderer.listen(this._element.nativeElement, 'focusout', this._handleFocusout),
+      ];
     });
 
     if (this._value) {
@@ -200,8 +205,7 @@ export class MatSelectionList
 
   ngOnDestroy() {
     this._keyManager?.destroy();
-    this._element.nativeElement.removeEventListener('focusin', this._handleFocusin);
-    this._element.nativeElement.removeEventListener('focusout', this._handleFocusout);
+    this._listenerCleanups?.forEach(current => current());
     this._destroyed.next();
     this._destroyed.complete();
     this._isDestroyed = true;
@@ -375,7 +379,7 @@ export class MatSelectionList
       event.keyCode === A &&
       this.multiple &&
       !this._keyManager.isTyping() &&
-      hasModifierKey(event, 'ctrlKey')
+      hasModifierKey(event, 'ctrlKey', 'metaKey')
     ) {
       const shouldSelect = this.options.some(option => !option.disabled && !option.selected);
       event.preventDefault();
diff --git a/src/material/list/testing/list-harness.spec.ts b/src/material/list/testing/list-harness.spec.ts
index 16ee4d12e22c..d39f4d650588 100644
--- a/src/material/list/testing/list-harness.spec.ts
+++ b/src/material/list/testing/list-harness.spec.ts
@@ -541,7 +541,6 @@ describe('MatSelectionListHarness', () => {
 
       <mat-list class="test-empty"></mat-list>
   `,
-  standalone: true,
   imports: [MatListModule],
 })
 class ListHarnessTest {
@@ -582,7 +581,6 @@ class ListHarnessTest {
 
       <mat-action-list class="test-empty"></mat-action-list>
   `,
-  standalone: true,
   imports: [MatListModule],
 })
 class ActionListHarnessTest {
@@ -625,7 +623,6 @@ class ActionListHarnessTest {
 
       <mat-nav-list class="test-empty"></mat-nav-list>
   `,
-  standalone: true,
   imports: [MatListModule],
 })
 class NavListHarnessTest {
@@ -669,7 +666,6 @@ class NavListHarnessTest {
 
     <mat-selection-list class="test-empty" disabled></mat-selection-list>
   `,
-  standalone: true,
   imports: [MatListModule],
 })
 class SelectionListHarnessTest {
diff --git a/src/material/list/tokens.ts b/src/material/list/tokens.ts
index 9389fa311b71..d882ceed932a 100644
--- a/src/material/list/tokens.ts
+++ b/src/material/list/tokens.ts
@@ -10,7 +10,7 @@ import {InjectionToken} from '@angular/core';
 
 /** Object that can be used to configure the default options for the list module. */
 export interface MatListConfig {
-  /** Wheter icon indicators should be hidden for single-selection. */
+  /** Whether icon indicators should be hidden for single-selection. */
   hideSingleSelectionIndicator?: boolean;
 }
 
diff --git a/src/material/menu/menu-animations.ts b/src/material/menu/menu-animations.ts
index 1ddefea6395b..1e988537cc26 100644
--- a/src/material/menu/menu-animations.ts
+++ b/src/material/menu/menu-animations.ts
@@ -20,6 +20,8 @@ import {
  * Animation duration and timing values are based on:
  * https://material.io/guidelines/components/menus.html#menus-usage
  * @docs-private
+ * @deprecated No longer used, will be removed.
+ * @breaking-change 21.0.0
  */
 export const matMenuAnimations: {
   readonly transformMenu: AnimationTriggerMetadata;
diff --git a/src/material/menu/menu-content.ts b/src/material/menu/menu-content.ts
index fc4369907ddd..cabacfe4b5a8 100644
--- a/src/material/menu/menu-content.ts
+++ b/src/material/menu/menu-content.ts
@@ -41,8 +41,8 @@ export class MatMenuContent implements OnDestroy {
   private _document = inject(DOCUMENT);
   private _changeDetectorRef = inject(ChangeDetectorRef);
 
-  private _portal: TemplatePortal<any>;
-  private _outlet: DomPortalOutlet;
+  private _portal: TemplatePortal<any> | undefined;
+  private _outlet: DomPortalOutlet | undefined;
 
   /** Emits when the menu content has been attached. */
   readonly _attached = new Subject<void>();
@@ -93,14 +93,13 @@ export class MatMenuContent implements OnDestroy {
    * @docs-private
    */
   detach() {
-    if (this._portal.isAttached) {
+    if (this._portal?.isAttached) {
       this._portal.detach();
     }
   }
 
   ngOnDestroy() {
-    if (this._outlet) {
-      this._outlet.dispose();
-    }
+    this.detach();
+    this._outlet?.dispose();
   }
 }
diff --git a/src/material/menu/menu-panel.ts b/src/material/menu/menu-panel.ts
index 8bf5cb06e4d5..b6814cbc2828 100644
--- a/src/material/menu/menu-panel.ts
+++ b/src/material/menu/menu-panel.ts
@@ -33,6 +33,11 @@ export interface MatMenuPanel<T = any> {
   focusFirstItem: (origin?: FocusOrigin) => void;
   resetActiveItem: () => void;
   setPositionClasses?: (x: MenuPositionX, y: MenuPositionY) => void;
+
+  /**
+   * @deprecated No longer used and will be removed.
+   * @breaking-change 21.0.0
+   */
   setElevation?(depth: number): void;
   lazyContent?: MatMenuContent;
   backdropClass?: string;
diff --git a/src/material/menu/menu-trigger.ts b/src/material/menu/menu-trigger.ts
index 9a8f519779ef..338253c89667 100644
--- a/src/material/menu/menu-trigger.ts
+++ b/src/material/menu/menu-trigger.ts
@@ -39,8 +39,8 @@ import {
   ViewContainerRef,
 } from '@angular/core';
 import {normalizePassiveListenerOptions} from '@angular/cdk/platform';
-import {asapScheduler, merge, Observable, of as observableOf, Subscription} from 'rxjs';
-import {delay, filter, take, takeUntil} from 'rxjs/operators';
+import {merge, Observable, of as observableOf, Subscription} from 'rxjs';
+import {filter, take, takeUntil} from 'rxjs/operators';
 import {MatMenu, MenuCloseReason} from './menu';
 import {throwMatMenuRecursiveError} from './menu-errors';
 import {MatMenuItem} from './menu-item';
@@ -81,6 +81,9 @@ const passiveEventListenerOptions = normalizePassiveListenerOptions({passive: tr
  */
 export const MENU_PANEL_TOP_PADDING = 8;
 
+/** Mapping between menu panels and the last trigger that opened them. */
+const PANELS_TO_TRIGGERS = new WeakMap<MatMenuPanel, MatMenuTrigger>();
+
 /** Directive applied to an element that should trigger a `mat-menu`. */
 @Directive({
   selector: `[mat-menu-trigger-for], [matMenuTriggerFor]`,
@@ -112,6 +115,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
   private _closingActionsSubscription = Subscription.EMPTY;
   private _hoverSubscription = Subscription.EMPTY;
   private _menuCloseSubscription = Subscription.EMPTY;
+  private _pendingRemoval: Subscription | undefined;
 
   /**
    * We're specifically looking for a `MatMenu` here since the generic `MatMenuPanel`
@@ -234,9 +238,8 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
   }
 
   ngOnDestroy() {
-    if (this._overlayRef) {
-      this._overlayRef.dispose();
-      this._overlayRef = null;
+    if (this.menu && this._ownsMenu(this.menu)) {
+      PANELS_TO_TRIGGERS.delete(this.menu);
     }
 
     this._element.nativeElement.removeEventListener(
@@ -245,9 +248,15 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
       passiveEventListenerOptions,
     );
 
+    this._pendingRemoval?.unsubscribe();
     this._menuCloseSubscription.unsubscribe();
     this._closingActionsSubscription.unsubscribe();
     this._hoverSubscription.unsubscribe();
+
+    if (this._overlayRef) {
+      this._overlayRef.dispose();
+      this._overlayRef = null;
+    }
   }
 
   /** Whether the menu is open. */
@@ -278,6 +287,16 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
       return;
     }
 
+    this._pendingRemoval?.unsubscribe();
+    const previousTrigger = PANELS_TO_TRIGGERS.get(menu);
+    PANELS_TO_TRIGGERS.set(menu, this);
+
+    // If the same menu is currently attached to another trigger,
+    // we need to close it so it doesn't end up in a broken state.
+    if (previousTrigger && previousTrigger !== this) {
+      previousTrigger.closeMenu();
+    }
+
     const overlayRef = this._createOverlay(menu);
     const overlayConfig = overlayRef.getConfig();
     const positionStrategy = overlayConfig.positionStrategy as FlexibleConnectedPositionStrategy;
@@ -285,17 +304,22 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
     this._setPosition(menu, positionStrategy);
     overlayConfig.hasBackdrop =
       menu.hasBackdrop == null ? !this.triggersSubmenu() : menu.hasBackdrop;
-    overlayRef.attach(this._getPortal(menu));
 
-    if (menu.lazyContent) {
-      menu.lazyContent.attach(this.menuData);
+    // We need the `hasAttached` check for the case where the user kicked off a removal animation,
+    // but re-entered the menu. Re-attaching the same portal will trigger an error otherwise.
+    if (!overlayRef.hasAttached()) {
+      overlayRef.attach(this._getPortal(menu));
+      menu.lazyContent?.attach(this.menuData);
     }
 
     this._closingActionsSubscription = this._menuClosingActions().subscribe(() => this.closeMenu());
-    this._initMenu(menu);
+    menu.parentMenu = this.triggersSubmenu() ? this._parentMaterialMenu : undefined;
+    menu.direction = this.dir;
+    menu.focusFirstItem(this._openedBy || 'program');
+    this._setIsMenuOpen(true);
 
     if (menu instanceof MatMenu) {
-      menu._startAnimation();
+      menu._setIsOpen(true);
       menu._directDescendantItems.changes.pipe(takeUntil(menu.close)).subscribe(() => {
         // Re-adjust the position without locking when the amount of items
         // changes so that the overlay is allowed to pick a new optimal position.
@@ -331,13 +355,32 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
 
   /** Closes the menu and does the necessary cleanup. */
   private _destroyMenu(reason: MenuCloseReason) {
-    if (!this._overlayRef || !this.menuOpen) {
+    const overlayRef = this._overlayRef;
+    const menu = this._menu;
+
+    if (!overlayRef || !this.menuOpen) {
       return;
     }
 
-    const menu = this.menu;
     this._closingActionsSubscription.unsubscribe();
-    this._overlayRef.detach();
+    this._pendingRemoval?.unsubscribe();
+
+    // Note that we don't wait for the animation to finish if another trigger took
+    // over the menu, because the panel will end up empty which looks glitchy.
+    if (menu instanceof MatMenu && this._ownsMenu(menu)) {
+      this._pendingRemoval = menu._animationDone.pipe(take(1)).subscribe(() => {
+        overlayRef.detach();
+        menu.lazyContent?.detach();
+      });
+      menu._setIsOpen(false);
+    } else {
+      overlayRef.detach();
+      menu?.lazyContent?.detach();
+    }
+
+    if (menu && this._ownsMenu(menu)) {
+      PANELS_TO_TRIGGERS.delete(menu);
+    }
 
     // Always restore focus if the user is navigating using the keyboard or the menu was opened
     // programmatically. We don't restore for non-root triggers, because it can prevent focus
@@ -348,58 +391,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
     }
 
     this._openedBy = undefined;
-
-    if (menu instanceof MatMenu) {
-      menu._resetAnimation();
-
-      if (menu.lazyContent) {
-        // Wait for the exit animation to finish before detaching the content.
-        menu._animationDone
-          .pipe(
-            filter(event => event.toState === 'void'),
-            take(1),
-            // Interrupt if the content got re-attached.
-            takeUntil(menu.lazyContent._attached),
-          )
-          .subscribe({
-            next: () => menu.lazyContent!.detach(),
-            // No matter whether the content got re-attached, reset the menu.
-            complete: () => this._setIsMenuOpen(false),
-          });
-      } else {
-        this._setIsMenuOpen(false);
-      }
-    } else {
-      this._setIsMenuOpen(false);
-      menu?.lazyContent?.detach();
-    }
-  }
-
-  /**
-   * This method sets the menu state to open and focuses the first item if
-   * the menu was opened via the keyboard.
-   */
-  private _initMenu(menu: MatMenuPanel): void {
-    menu.parentMenu = this.triggersSubmenu() ? this._parentMaterialMenu : undefined;
-    menu.direction = this.dir;
-    this._setMenuElevation(menu);
-    menu.focusFirstItem(this._openedBy || 'program');
-    this._setIsMenuOpen(true);
-  }
-
-  /** Updates the menu elevation based on the amount of parent menus that it has. */
-  private _setMenuElevation(menu: MatMenuPanel): void {
-    if (menu.setElevation) {
-      let depth = 0;
-      let parentMenu = menu.parentMenu;
-
-      while (parentMenu) {
-        depth++;
-        parentMenu = parentMenu.parentMenu;
-      }
-
-      menu.setElevation(depth);
-    }
+    this._setIsMenuOpen(false);
   }
 
   // set state rather than toggle to support triggers sharing a menu
@@ -428,11 +420,11 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
         config.positionStrategy as FlexibleConnectedPositionStrategy,
       );
       this._overlayRef = this._overlay.create(config);
-
-      // Consume the `keydownEvents` in order to prevent them from going to another overlay.
-      // Ideally we'd also have our keyboard event logic in here, however doing so will
-      // break anybody that may have implemented the `MatMenuPanel` themselves.
-      this._overlayRef.keydownEvents().subscribe();
+      this._overlayRef.keydownEvents().subscribe(event => {
+        if (this.menu instanceof MatMenu) {
+          this.menu._handleKeydown(event);
+        }
+      });
     }
 
     return this._overlayRef;
@@ -536,10 +528,9 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
     const detachments = this._overlayRef!.detachments();
     const parentClose = this._parentMaterialMenu ? this._parentMaterialMenu.closed : observableOf();
     const hover = this._parentMaterialMenu
-      ? this._parentMaterialMenu._hovered().pipe(
-          filter(active => active !== this._menuItemInstance),
-          filter(() => this._menuOpen),
-        )
+      ? this._parentMaterialMenu
+          ._hovered()
+          .pipe(filter(active => this._menuOpen && active !== this._menuItemInstance))
       : observableOf();
 
     return merge(backdrop, parentClose as Observable<MenuCloseReason>, hover, detachments);
@@ -594,35 +585,14 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
   /** Handles the cases where the user hovers over the trigger. */
   private _handleHover() {
     // Subscribe to changes in the hovered item in order to toggle the panel.
-    if (!this.triggersSubmenu() || !this._parentMaterialMenu) {
-      return;
-    }
-
-    this._hoverSubscription = this._parentMaterialMenu
-      ._hovered()
-      // Since we might have multiple competing triggers for the same menu (e.g. a sub-menu
-      // with different data and triggers), we have to delay it by a tick to ensure that
-      // it won't be closed immediately after it is opened.
-      .pipe(
-        filter(active => active === this._menuItemInstance && !active.disabled),
-        delay(0, asapScheduler),
-      )
-      .subscribe(() => {
-        this._openedBy = 'mouse';
-
-        // If the same menu is used between multiple triggers, it might still be animating
-        // while the new trigger tries to re-open it. Wait for the animation to finish
-        // before doing so. Also interrupt if the user moves to another item.
-        if (this.menu instanceof MatMenu && this.menu._isAnimating) {
-          // We need the `delay(0)` here in order to avoid
-          // 'changed after checked' errors in some cases. See #12194.
-          this.menu._animationDone
-            .pipe(take(1), delay(0, asapScheduler), takeUntil(this._parentMaterialMenu!._hovered()))
-            .subscribe(() => this.openMenu());
-        } else {
+    if (this.triggersSubmenu() && this._parentMaterialMenu) {
+      this._hoverSubscription = this._parentMaterialMenu._hovered().subscribe(active => {
+        if (active === this._menuItemInstance && !active.disabled) {
+          this._openedBy = 'mouse';
           this.openMenu();
         }
       });
+    }
   }
 
   /** Gets the portal that should be attached to the overlay. */
@@ -636,4 +606,13 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
 
     return this._portal;
   }
+
+  /**
+   * Determines whether the trigger owns a specific menu panel, at the current point in time.
+   * This allows us to distinguish the case where the same panel is passed into multiple triggers
+   * and multiple are open at a time.
+   */
+  private _ownsMenu(menu: MatMenuPanel): boolean {
+    return PANELS_TO_TRIGGERS.get(menu) === this;
+  }
 }
diff --git a/src/material/menu/menu.html b/src/material/menu/menu.html
index ae46031d7f1a..d8988e08ef3f 100644
--- a/src/material/menu/menu.html
+++ b/src/material/menu/menu.html
@@ -1,15 +1,17 @@
 <ng-template>
   <div
-    class="mat-mdc-menu-panel mat-mdc-elevation-specific"
+    class="mat-mdc-menu-panel"
     [id]="panelId"
     [class]="_classList"
-    (keydown)="_handleKeydown($event)"
+    [class.mat-menu-panel-animations-disabled]="_animationsDisabled"
+    [class.mat-menu-panel-exit-animation]="_panelAnimationState === 'void'"
+    [class.mat-menu-panel-animating]="_isAnimating"
     (click)="closed.emit('click')"
-    [@transformMenu]="_panelAnimationState"
-    (@transformMenu.start)="_onAnimationStart($event)"
-    (@transformMenu.done)="_onAnimationDone($event)"
     tabindex="-1"
     role="menu"
+    (animationstart)="_onAnimationStart($event.animationName)"
+    (animationend)="_onAnimationDone($event.animationName)"
+    (animationcancel)="_onAnimationDone($event.animationName)"
     [attr.aria-label]="ariaLabel || null"
     [attr.aria-labelledby]="ariaLabelledby || null"
     [attr.aria-describedby]="ariaDescribedby || null">
diff --git a/src/material/menu/menu.scss b/src/material/menu/menu.scss
index bb3c77431ac4..b5544945ff9c 100644
--- a/src/material/menu/menu.scss
+++ b/src/material/menu/menu.scss
@@ -31,14 +31,38 @@ mat-menu {
   }
 }
 
+@keyframes _mat-menu-enter {
+  from {
+    opacity: 0;
+    transform: scale(0.8);
+  }
+
+  to {
+    opacity: 1;
+    transform: none;
+  }
+}
+
+@keyframes _mat-menu-exit {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+  }
+}
+
 .mat-mdc-menu-panel {
   @include menu-common.base;
   box-sizing: border-box;
   outline: 0;
+  animation: _mat-menu-enter 120ms cubic-bezier(0, 0, 0.2, 1);
 
   @include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
     @include token-utils.create-token-slot(border-radius, container-shape);
     @include token-utils.create-token-slot(background-color, container-color);
+    @include token-utils.create-token-slot(box-shadow, container-elevation-shadow);
   }
 
   // TODO(crisbeto): we don't need this for anything, but it was there when
@@ -47,6 +71,14 @@ mat-menu {
   // We should clean it up eventually and re-approve all the screenshots.
   will-change: transform, opacity;
 
+  &.mat-menu-panel-exit-animation {
+    animation: _mat-menu-exit 100ms 25ms linear forwards;
+  }
+
+  &.mat-menu-panel-animations-disabled {
+    animation: none;
+  }
+
   // Prevent users from interacting with the panel while it's animating. Note that
   // people won't be able to click through it, because the overlay pane will catch the click.
   // This fixes the following issues:
@@ -54,7 +86,7 @@ mat-menu {
   //  * Users accidentally tapping on content inside the sub-menu on touch devices, if the
   //    sub-menu overlaps the trigger. The issue is due to touch devices emulating the
   //    `mouseenter` event by dispatching it on tap.
-  &.ng-animating {
+  &.mat-menu-panel-animating {
     pointer-events: none;
 
     // If the same menu is assigned to multiple triggers and the user moves quickly between them
diff --git a/src/material/menu/menu.spec.ts b/src/material/menu/menu.spec.ts
index 99e83b6ca61c..a065f4404038 100644
--- a/src/material/menu/menu.spec.ts
+++ b/src/material/menu/menu.spec.ts
@@ -15,9 +15,11 @@ import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
 import {
   ChangeDetectionStrategy,
   Component,
+  Directive,
   ElementRef,
   EventEmitter,
   Input,
+  OnDestroy,
   Output,
   Provider,
   QueryList,
@@ -473,16 +475,13 @@ describe('MatMenu', () => {
     fixture.componentInstance.trigger.openMenu();
 
     const panel = overlayContainerElement.querySelector('.mat-mdc-menu-panel')!;
-    const event = createKeyboardEvent('keydown', ESCAPE);
-    spyOn(event, 'stopPropagation').and.callThrough();
+    const event = dispatchKeyboardEvent(panel, 'keydown', ESCAPE);
 
-    dispatchEvent(panel, event);
     fixture.detectChanges();
     tick(500);
 
     expect(overlayContainerElement.textContent).toBe('');
     expect(event.defaultPrevented).toBe(true);
-    expect(event.stopPropagation).toHaveBeenCalled();
   }));
 
   it('should not close the menu when pressing ESCAPE with a modifier', fakeAsync(() => {
@@ -594,32 +593,6 @@ describe('MatMenu', () => {
     expect(panel.classList).toContain('custom-two');
   }));
 
-  it('should not remove mat-elevation class from overlay when panelClass is changed', fakeAsync(() => {
-    const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
-
-    fixture.componentInstance.panelClass = 'custom-one';
-    fixture.detectChanges();
-    fixture.componentInstance.trigger.openMenu();
-    fixture.detectChanges();
-    tick(500);
-
-    const panel = overlayContainerElement.querySelector('.mat-mdc-menu-panel')!;
-
-    expect(panel.classList).toContain('custom-one');
-    expect(panel.classList).toContain('mat-elevation-z2');
-
-    fixture.componentInstance.panelClass = 'custom-two';
-    fixture.changeDetectorRef.markForCheck();
-    fixture.detectChanges();
-
-    expect(panel.classList).not.toContain('custom-one');
-    expect(panel.classList).toContain('custom-two');
-    expect(panel.classList).toContain('mat-mdc-elevation-specific');
-    expect(panel.classList)
-      .withContext('Expected mat-elevation-z2 not to be removed')
-      .toContain('mat-elevation-z2');
-  }));
-
   it('should set the "menu" role on the overlay panel', fakeAsync(() => {
     const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
     fixture.detectChanges();
@@ -1249,46 +1222,37 @@ describe('MatMenu', () => {
     }));
 
     it('should detach the lazy content when the menu is closed', fakeAsync(() => {
-      const fixture = createComponent(SimpleLazyMenu);
+      let destroyCount = 0;
+
+      // Note: for some reason doing `spyOn(item, 'ngOnDestroy')` doesn't work, even though a
+      // `console.log` shows that the `ngOnDestroy` gets called. We work around it with a custom
+      // directive that increments a counter.
+      @Directive({selector: '[mat-menu-item]', standalone: false})
+      class DestroyChecker implements OnDestroy {
+        ngOnDestroy(): void {
+          destroyCount++;
+        }
+      }
 
+      const fixture = createComponent(SimpleLazyMenu, undefined, [DestroyChecker]);
       fixture.detectChanges();
       fixture.componentInstance.trigger.openMenu();
       fixture.detectChanges();
       tick(500);
-
-      expect(fixture.componentInstance.items.length).toBeGreaterThan(0);
-
-      fixture.componentInstance.trigger.closeMenu();
-      fixture.detectChanges();
-      tick(500);
       fixture.detectChanges();
 
-      expect(fixture.componentInstance.items.length).toBe(0);
-    }));
+      expect(fixture.componentInstance.items.length).toBe(2);
+      expect(destroyCount).toBe(0);
 
-    it('should wait for the close animation to finish before considering the panel as closed', fakeAsync(() => {
-      const fixture = createComponent(SimpleLazyMenu);
-      fixture.detectChanges();
-      const trigger = fixture.componentInstance.trigger;
-
-      expect(trigger.menuOpen).withContext('Expected menu to start off closed').toBe(false);
-
-      trigger.openMenu();
-      fixture.detectChanges();
-      tick(500);
-
-      expect(trigger.menuOpen).withContext('Expected menu to be open').toBe(true);
-
-      trigger.closeMenu();
+      fixture.componentInstance.trigger.closeMenu();
       fixture.detectChanges();
-
-      expect(trigger.menuOpen)
-        .withContext('Expected menu to be considered open while the close animation is running')
-        .toBe(true);
       tick(500);
       fixture.detectChanges();
 
-      expect(trigger.menuOpen).withContext('Expected menu to be closed').toBe(false);
+      expect(fixture.componentInstance.items.length)
+        .withContext('Expected items to be removed from query list')
+        .toBe(0);
+      expect(destroyCount).withContext('Expected ngOnDestroy to have been called').toBe(2);
     }));
 
     it('should focus the first menu item when opening a lazy menu via keyboard', async () => {
@@ -1770,15 +1734,12 @@ describe('MatMenu', () => {
     }));
 
     it('should complete the callback when the menu is destroyed', fakeAsync(() => {
-      const emitCallback = jasmine.createSpy('emit callback');
       const completeCallback = jasmine.createSpy('complete callback');
 
-      fixture.componentInstance.menu.closed.subscribe(emitCallback, null, completeCallback);
+      fixture.componentInstance.menu.closed.subscribe(null, null, completeCallback);
       fixture.destroy();
       tick(500);
 
-      expect(emitCallback).toHaveBeenCalledWith(undefined);
-      expect(emitCallback).toHaveBeenCalledTimes(1);
       expect(completeCallback).toHaveBeenCalled();
     }));
   });
@@ -2350,79 +2311,6 @@ describe('MatMenu', () => {
       expect(menuItems[0].querySelector('.mat-mdc-menu-submenu-icon')).toBeFalsy();
     }));
 
-    it('should increase the sub-menu elevation based on its depth', fakeAsync(() => {
-      compileTestComponent();
-      instance.rootTrigger.openMenu();
-      fixture.detectChanges();
-      tick(500);
-
-      instance.levelOneTrigger.openMenu();
-      fixture.detectChanges();
-      tick(500);
-
-      instance.levelTwoTrigger.openMenu();
-      fixture.detectChanges();
-      tick(500);
-
-      const menus = overlay.querySelectorAll('.mat-mdc-menu-panel');
-
-      expect(menus[0].classList).toContain('mat-mdc-elevation-specific');
-      expect(menus[0].classList)
-        .withContext('Expected root menu to have base elevation.')
-        .toContain('mat-elevation-z2');
-
-      expect(menus[1].classList).toContain('mat-mdc-elevation-specific');
-      expect(menus[1].classList)
-        .withContext('Expected first sub-menu to have base elevation + 1.')
-        .toContain('mat-elevation-z3');
-
-      expect(menus[2].classList).toContain('mat-mdc-elevation-specific');
-      expect(menus[2].classList)
-        .withContext('Expected second sub-menu to have base elevation + 2.')
-        .toContain('mat-elevation-z4');
-    }));
-
-    it('should update the elevation when the same menu is opened at a different depth', fakeAsync(() => {
-      compileTestComponent();
-      instance.rootTrigger.openMenu();
-      fixture.detectChanges();
-
-      instance.levelOneTrigger.openMenu();
-      fixture.detectChanges();
-
-      instance.levelTwoTrigger.openMenu();
-      fixture.detectChanges();
-
-      let lastMenu = overlay.querySelectorAll('.mat-mdc-menu-panel')[2];
-
-      expect(lastMenu.classList).toContain('mat-mdc-elevation-specific');
-      expect(lastMenu.classList)
-        .withContext('Expected menu to have the base elevation plus two.')
-        .toContain('mat-elevation-z4');
-
-      (overlay.querySelector('.cdk-overlay-backdrop')! as HTMLElement).click();
-      fixture.detectChanges();
-      tick(500);
-
-      expect(overlay.querySelectorAll('.mat-mdc-menu-panel').length)
-        .withContext('Expected no open menus')
-        .toBe(0);
-
-      instance.alternateTrigger.openMenu();
-      fixture.detectChanges();
-      tick(500);
-
-      lastMenu = overlay.querySelector('.mat-mdc-menu-panel') as HTMLElement;
-
-      expect(lastMenu.classList).toContain('mat-mdc-elevation-specific');
-      expect(lastMenu.classList)
-        .not.withContext('Expected menu not to maintain old elevation.')
-        .toContain('mat-elevation-z4');
-      expect(lastMenu.classList)
-        .withContext('Expected menu to have the proper updated elevation.')
-        .toContain('mat-elevation-z2');
-    }));
-
     it('should not change focus origin if origin not specified for trigger', fakeAsync(() => {
       compileTestComponent();
 
@@ -2442,28 +2330,6 @@ describe('MatMenu', () => {
       expect(levelTwoTrigger.classList).toContain('cdk-mouse-focused');
     }));
 
-    it('should not increase the elevation if the user specified a custom one', fakeAsync(() => {
-      const elevationFixture = createComponent(NestedMenuCustomElevation);
-
-      elevationFixture.detectChanges();
-      elevationFixture.componentInstance.rootTrigger.openMenu();
-      elevationFixture.detectChanges();
-      tick(500);
-
-      elevationFixture.componentInstance.levelOneTrigger.openMenu();
-      elevationFixture.detectChanges();
-      tick(500);
-
-      const menuClasses =
-        overlayContainerElement.querySelectorAll('.mat-mdc-menu-panel')[1].classList;
-
-      expect(menuClasses).toContain('mat-mdc-elevation-specific');
-      expect(menuClasses)
-        .withContext('Expected user elevation to be maintained')
-        .toContain('mat-elevation-z24');
-      expect(menuClasses).not.toContain('mat-elevation-z2', 'Expected no stacked elevation.');
-    }));
-
     it('should close all of the menus when the root is closed programmatically', fakeAsync(() => {
       compileTestComponent();
       instance.rootTrigger.openMenu();
@@ -2934,27 +2800,6 @@ class NestedMenu {
   showLazy = false;
 }
 
-@Component({
-  template: `
-    <button [matMenuTriggerFor]="root" #rootTrigger="matMenuTrigger">Toggle menu</button>
-
-    <mat-menu #root="matMenu">
-      <button mat-menu-item
-        [matMenuTriggerFor]="levelOne"
-        #levelOneTrigger="matMenuTrigger">One</button>
-    </mat-menu>
-
-    <mat-menu #levelOne="matMenu" class="mat-elevation-z24">
-      <button mat-menu-item>Two</button>
-    </mat-menu>
-  `,
-  standalone: false,
-})
-class NestedMenuCustomElevation {
-  @ViewChild('rootTrigger') rootTrigger: MatMenuTrigger;
-  @ViewChild('levelOneTrigger') levelOneTrigger: MatMenuTrigger;
-}
-
 @Component({
   template: `
     <button [matMenuTriggerFor]="root" #rootTriggerEl>Toggle menu</button>
diff --git a/src/material/menu/menu.ts b/src/material/menu/menu.ts
index 4aa5999155af..0d3a13d836c7 100644
--- a/src/material/menu/menu.ts
+++ b/src/material/menu/menu.ts
@@ -29,9 +29,9 @@ import {
   AfterRenderRef,
   inject,
   Injector,
+  ANIMATION_MODULE_TYPE,
 } from '@angular/core';
-import {AnimationEvent} from '@angular/animations';
-import {FocusKeyManager, FocusOrigin} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusKeyManager, FocusOrigin} from '@angular/cdk/a11y';
 import {Direction} from '@angular/cdk/bidi';
 import {
   ESCAPE,
@@ -48,9 +48,6 @@ import {MatMenuPanel, MAT_MENU_PANEL} from './menu-panel';
 import {MenuPositionX, MenuPositionY} from './menu-positions';
 import {throwMatMenuInvalidPositionX, throwMatMenuInvalidPositionY} from './menu-errors';
 import {MatMenuContent, MAT_MENU_CONTENT} from './menu-content';
-import {matMenuAnimations} from './menu-animations';
-
-let menuPanelUid = 0;
 
 /** Reason why the menu was closed. */
 export type MenuCloseReason = void | 'click' | 'keydown' | 'tab';
@@ -95,6 +92,12 @@ export function MAT_MENU_DEFAULT_OPTIONS_FACTORY(): MatMenuDefaultOptions {
   };
 }
 
+/** Name of the enter animation `@keyframes`. */
+const ENTER_ANIMATION = '_mat-menu-enter';
+
+/** Name of the exit animation `@keyframes`. */
+const EXIT_ANIMATION = '_mat-menu-exit';
+
 @Component({
   selector: 'mat-menu',
   templateUrl: 'menu.html',
@@ -107,20 +110,21 @@ export function MAT_MENU_DEFAULT_OPTIONS_FACTORY(): MatMenuDefaultOptions {
     '[attr.aria-labelledby]': 'null',
     '[attr.aria-describedby]': 'null',
   },
-  animations: [matMenuAnimations.transformMenu, matMenuAnimations.fadeInItems],
   providers: [{provide: MAT_MENU_PANEL, useExisting: MatMenu}],
 })
 export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnInit, OnDestroy {
   private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
   private _changeDetectorRef = inject(ChangeDetectorRef);
+  private _injector = inject(Injector);
 
   private _keyManager: FocusKeyManager<MatMenuItem>;
   private _xPosition: MenuPositionX;
   private _yPosition: MenuPositionY;
   private _firstItemFocusRef?: AfterRenderRef;
-  private _previousElevation: string;
-  private _elevationPrefix = 'mat-elevation-z';
-  private _baseElevation: number | null = null;
+  private _exitFallbackTimeout: ReturnType<typeof setTimeout> | undefined;
+
+  /** Whether animations are currently disabled. */
+  protected _animationsDisabled: boolean;
 
   /** All items inside the menu. Includes items nested inside another menu. */
   @ContentChildren(MatMenuItem, {descendants: true}) _allItems: QueryList<MatMenuItem>;
@@ -135,10 +139,10 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
   _panelAnimationState: 'void' | 'enter' = 'void';
 
   /** Emits whenever an animation on the menu completes. */
-  readonly _animationDone = new Subject<AnimationEvent>();
+  readonly _animationDone = new Subject<'void' | 'enter'>();
 
   /** Whether the menu is animating. */
-  _isAnimating: boolean;
+  _isAnimating = false;
 
   /** Parent menu of the current menu panel. */
   parentMenu: MatMenuPanel | undefined;
@@ -270,9 +274,7 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
    */
   @Output() readonly close: EventEmitter<MenuCloseReason> = this.closed;
 
-  readonly panelId = `mat-menu-panel-${menuPanelUid++}`;
-
-  private _injector = inject(Injector);
+  readonly panelId: string = inject(_IdGenerator).getId('mat-menu-panel-');
 
   constructor(...args: unknown[]);
 
@@ -284,6 +286,7 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
     this.backdropClass = defaultOptions.backdropClass;
     this.overlapTrigger = defaultOptions.overlapTrigger;
     this.hasBackdrop = defaultOptions.hasBackdrop;
+    this._animationsDisabled = inject(ANIMATION_MODULE_TYPE, {optional: true}) === 'NoopAnimations';
   }
 
   ngOnInit() {
@@ -332,6 +335,7 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
     this._directDescendantItems.destroy();
     this.closed.complete();
     this._firstItemFocusRef?.destroy();
+    clearTimeout(this._exitFallbackTimeout);
   }
 
   /** Stream that emits whenever the hovered menu item changes. */
@@ -390,10 +394,6 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
         manager.onKeydown(event);
         return;
     }
-
-    // Don't allow the event to propagate if we've already handled it, or it may
-    // end up reaching other overlays that were opened earlier (see #22694).
-    event.stopPropagation();
   }
 
   /**
@@ -405,15 +405,7 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
     this._firstItemFocusRef?.destroy();
     this._firstItemFocusRef = afterNextRender(
       () => {
-        let menuPanel: HTMLElement | null = null;
-
-        if (this._directDescendantItems.length) {
-          // Because the `mat-menuPanel` is at the DOM insertion point, not inside the overlay, we don't
-          // have a nice way of getting a hold of the menuPanel panel. We can't use a `ViewChild` either
-          // because the panel is inside an `ng-template`. We work around it by starting from one of
-          // the items and walking up the DOM.
-          menuPanel = this._directDescendantItems.first!._getHostElement().closest('[role="menu"]');
-        }
+        const menuPanel = this._resolvePanel();
 
         // If an item in the menuPanel is already focused, avoid overriding the focus.
         if (!menuPanel || !menuPanel.contains(document.activeElement)) {
@@ -441,41 +433,10 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
   }
 
   /**
-   * Sets the menu panel elevation.
-   * @param depth Number of parent menus that come before the menu.
+   * @deprecated No longer used and will be removed.
+   * @breaking-change 21.0.0
    */
-  setElevation(depth: number): void {
-    // The base elevation depends on which version of the spec
-    // we're running so we have to resolve it at runtime.
-    if (this._baseElevation === null) {
-      const styles =
-        typeof getComputedStyle === 'function'
-          ? getComputedStyle(this._elementRef.nativeElement)
-          : null;
-      const value = styles?.getPropertyValue('--mat-menu-base-elevation-level') || '8';
-      this._baseElevation = parseInt(value);
-    }
-
-    // The elevation starts at the base and increases by one for each level.
-    // Capped at 24 because that's the maximum elevation defined in the Material design spec.
-    const elevation = Math.min(this._baseElevation + depth, 24);
-    const newElevation = `${this._elevationPrefix}${elevation}`;
-    const customElevation = Object.keys(this._classList).find(className => {
-      return className.startsWith(this._elevationPrefix);
-    });
-
-    if (!customElevation || customElevation === this._previousElevation) {
-      const newClassList = {...this._classList};
-
-      if (this._previousElevation) {
-        newClassList[this._previousElevation] = false;
-      }
-
-      newClassList[newElevation] = true;
-      this._previousElevation = newElevation;
-      this._classList = newClassList;
-    }
-  }
+  setElevation(_depth: number): void {}
 
   /**
    * Adds classes to the menu panel based on its position. Can be used by
@@ -496,36 +457,58 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
     this._changeDetectorRef.markForCheck();
   }
 
-  /** Starts the enter animation. */
-  _startAnimation() {
-    // @breaking-change 8.0.0 Combine with _resetAnimation.
-    this._panelAnimationState = 'enter';
-  }
+  /** Callback that is invoked when the panel animation completes. */
+  protected _onAnimationDone(state: string) {
+    const isExit = state === EXIT_ANIMATION;
 
-  /** Resets the panel animation to its initial state. */
-  _resetAnimation() {
-    // @breaking-change 8.0.0 Combine with _startAnimation.
-    this._panelAnimationState = 'void';
+    if (isExit || state === ENTER_ANIMATION) {
+      if (isExit) {
+        clearTimeout(this._exitFallbackTimeout);
+        this._exitFallbackTimeout = undefined;
+      }
+      this._animationDone.next(isExit ? 'void' : 'enter');
+      this._isAnimating = false;
+    }
   }
 
-  /** Callback that is invoked when the panel animation completes. */
-  _onAnimationDone(event: AnimationEvent) {
-    this._animationDone.next(event);
-    this._isAnimating = false;
+  protected _onAnimationStart(state: string) {
+    if (state === ENTER_ANIMATION || state === EXIT_ANIMATION) {
+      this._isAnimating = true;
+    }
   }
 
-  _onAnimationStart(event: AnimationEvent) {
-    this._isAnimating = true;
-
-    // Scroll the content element to the top as soon as the animation starts. This is necessary,
-    // because we move focus to the first item while it's still being animated, which can throw
-    // the browser off when it determines the scroll position. Alternatively we can move focus
-    // when the animation is done, however moving focus asynchronously will interrupt screen
-    // readers which are in the process of reading out the menu already. We take the `element`
-    // from the `event` since we can't use a `ViewChild` to access the pane.
-    if (event.toState === 'enter' && this._keyManager.activeItemIndex === 0) {
-      event.element.scrollTop = 0;
+  _setIsOpen(isOpen: boolean) {
+    this._panelAnimationState = isOpen ? 'enter' : 'void';
+
+    if (isOpen) {
+      if (this._keyManager.activeItemIndex === 0) {
+        // Scroll the content element to the top as soon as the animation starts. This is necessary,
+        // because we move focus to the first item while it's still being animated, which can throw
+        // the browser off when it determines the scroll position. Alternatively we can move focus
+        // when the animation is done, however moving focus asynchronously will interrupt screen
+        // readers which are in the process of reading out the menu already. We take the `element`
+        // from the `event` since we can't use a `ViewChild` to access the pane.
+        const menuPanel = this._resolvePanel();
+
+        if (menuPanel) {
+          menuPanel.scrollTop = 0;
+        }
+      }
+    } else if (!this._animationsDisabled) {
+      // Some apps do `* { animation: none !important; }` in tests which will prevent the
+      // `animationend` event from firing. Since the exit animation is loading-bearing for
+      // removing the content from the DOM, add a fallback timer.
+      this._exitFallbackTimeout = setTimeout(() => this._onAnimationDone(EXIT_ANIMATION), 200);
+    }
+
+    // Animation events won't fire when animations are disabled so we simulate them.
+    if (this._animationsDisabled) {
+      setTimeout(() => {
+        this._onAnimationDone(isOpen ? ENTER_ANIMATION : EXIT_ANIMATION);
+      });
     }
+
+    this._changeDetectorRef.markForCheck();
   }
 
   /**
@@ -542,4 +525,19 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
         this._directDescendantItems.notifyOnChanges();
       });
   }
+
+  /** Gets the menu panel DOM node. */
+  private _resolvePanel(): HTMLElement | null {
+    let menuPanel: HTMLElement | null = null;
+
+    if (this._directDescendantItems.length) {
+      // Because the `mat-menuPanel` is at the DOM insertion point, not inside the overlay, we don't
+      // have a nice way of getting a hold of the menuPanel panel. We can't use a `ViewChild` either
+      // because the panel is inside an `ng-template`. We work around it by starting from one of
+      // the items and walking up the DOM.
+      menuPanel = this._directDescendantItems.first!._getHostElement().closest('[role="menu"]');
+    }
+
+    return menuPanel;
+  }
 }
diff --git a/src/material/menu/module.ts b/src/material/menu/module.ts
index 667ac4376814..0888920c6a18 100644
--- a/src/material/menu/module.ts
+++ b/src/material/menu/module.ts
@@ -6,7 +6,6 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {MatCommonModule, MatRippleModule} from '@angular/material/core';
 import {OverlayModule} from '@angular/cdk/overlay';
@@ -18,7 +17,6 @@ import {MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER, MatMenuTrigger} from './menu-
 
 @NgModule({
   imports: [
-    CommonModule,
     MatRippleModule,
     MatCommonModule,
     OverlayModule,
diff --git a/src/material/menu/testing/menu-harness.spec.ts b/src/material/menu/testing/menu-harness.spec.ts
index 3178dec315cd..3238f0b85b3d 100644
--- a/src/material/menu/testing/menu-harness.spec.ts
+++ b/src/material/menu/testing/menu-harness.spec.ts
@@ -163,7 +163,6 @@ describe('MatMenuHarness', () => {
         <menu mat-menu-item>Account</menu>
       </mat-menu>
   `,
-  standalone: true,
   imports: [MatMenuModule],
 })
 class MenuHarnessTest {}
@@ -190,7 +189,6 @@ class MenuHarnessTest {}
         <button mat-menu-item (click)="lastClickedLeaf = 3">Leaf Item 3</button>
       </mat-menu>
   `,
-  standalone: true,
   imports: [MatMenuModule],
 })
 class NestedMenuHarnessTest {
diff --git a/src/material/menu/testing/menu-harness.ts b/src/material/menu/testing/menu-harness.ts
index 890ad26bcd0d..753aa8c676f9 100644
--- a/src/material/menu/testing/menu-harness.ts
+++ b/src/material/menu/testing/menu-harness.ts
@@ -12,7 +12,6 @@ import {
   HarnessLoader,
   HarnessPredicate,
   TestElement,
-  TestKey,
 } from '@angular/cdk/testing';
 import {coerceBooleanProperty} from '@angular/cdk/coercion';
 import {MenuHarnessFilters, MenuItemHarnessFilters} from './menu-harness-filters';
@@ -82,7 +81,7 @@ export class MatMenuHarness extends ContentContainerComponentHarness<string> {
   async close(): Promise<void> {
     const panel = await this._getMenuPanel();
     if (panel) {
-      return panel.sendKeys(TestKey.ESCAPE);
+      return panel.click();
     }
   }
 
diff --git a/src/material/paginator/paginator.html b/src/material/paginator/paginator.html
index 208966624e56..10ae36fabfb2 100644
--- a/src/material/paginator/paginator.html
+++ b/src/material/paginator/paginator.html
@@ -44,11 +44,11 @@
       @if (showFirstLastButtons) {
         <button mat-icon-button type="button"
                 class="mat-mdc-paginator-navigation-first"
-                (click)="firstPage()"
+                (click)="_buttonClicked(0, _previousButtonsDisabled())"
                 [attr.aria-label]="_intl.firstPageLabel"
                 [matTooltip]="_intl.firstPageLabel"
                 [matTooltipDisabled]="_previousButtonsDisabled()"
-                [matTooltipPosition]="'above'"
+                matTooltipPosition="above"
                 [disabled]="_previousButtonsDisabled()"
                 disabledInteractive>
           <svg class="mat-mdc-paginator-icon"
@@ -61,11 +61,11 @@
       }
       <button mat-icon-button type="button"
               class="mat-mdc-paginator-navigation-previous"
-              (click)="previousPage()"
+              (click)="_buttonClicked(pageIndex - 1, _previousButtonsDisabled())"
               [attr.aria-label]="_intl.previousPageLabel"
               [matTooltip]="_intl.previousPageLabel"
               [matTooltipDisabled]="_previousButtonsDisabled()"
-              [matTooltipPosition]="'above'"
+              matTooltipPosition="above"
               [disabled]="_previousButtonsDisabled()"
               disabledInteractive>
         <svg class="mat-mdc-paginator-icon"
@@ -77,11 +77,11 @@
       </button>
       <button mat-icon-button type="button"
               class="mat-mdc-paginator-navigation-next"
-              (click)="nextPage()"
+              (click)="_buttonClicked(pageIndex + 1, _nextButtonsDisabled())"
               [attr.aria-label]="_intl.nextPageLabel"
               [matTooltip]="_intl.nextPageLabel"
               [matTooltipDisabled]="_nextButtonsDisabled()"
-              [matTooltipPosition]="'above'"
+              matTooltipPosition="above"
               [disabled]="_nextButtonsDisabled()"
               disabledInteractive>
         <svg class="mat-mdc-paginator-icon"
@@ -94,11 +94,11 @@
       @if (showFirstLastButtons) {
         <button mat-icon-button type="button"
                 class="mat-mdc-paginator-navigation-last"
-                (click)="lastPage()"
+                (click)="_buttonClicked(getNumberOfPages() - 1, _nextButtonsDisabled())"
                 [attr.aria-label]="_intl.lastPageLabel"
                 [matTooltip]="_intl.lastPageLabel"
                 [matTooltipDisabled]="_nextButtonsDisabled()"
-                [matTooltipPosition]="'above'"
+                matTooltipPosition="above"
                 [disabled]="_nextButtonsDisabled()"
                 disabledInteractive>
           <svg class="mat-mdc-paginator-icon"
diff --git a/src/material/paginator/paginator.spec.ts b/src/material/paginator/paginator.spec.ts
index a1543ea5e97a..54180cd4bc07 100644
--- a/src/material/paginator/paginator.spec.ts
+++ b/src/material/paginator/paginator.spec.ts
@@ -1,4 +1,3 @@
-import {dispatchMouseEvent} from '@angular/cdk/testing/private';
 import {ChangeDetectorRef, Component, Provider, Type, ViewChild, inject} from '@angular/core';
 import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
 import {ThemePalette} from '@angular/material/core';
@@ -135,7 +134,7 @@ describe('MatPaginator', () => {
       const paginator = component.paginator;
       expect(paginator.pageIndex).toBe(0);
 
-      dispatchMouseEvent(getNextButton(fixture), 'click');
+      getNextButton(fixture).click();
 
       expect(paginator.pageIndex).toBe(1);
       expect(component.pageEvent).toHaveBeenCalledWith(
@@ -154,7 +153,7 @@ describe('MatPaginator', () => {
       fixture.detectChanges();
       expect(paginator.pageIndex).toBe(1);
 
-      dispatchMouseEvent(getPreviousButton(fixture), 'click');
+      getPreviousButton(fixture).click();
 
       expect(paginator.pageIndex).toBe(0);
       expect(component.pageEvent).toHaveBeenCalledWith(
@@ -164,12 +163,37 @@ describe('MatPaginator', () => {
         }),
       );
     });
+
+    it('should not navigate to the next page when the paginator is disabled', () => {
+      const fixture = createComponent(MatPaginatorApp);
+      expect(fixture.componentInstance.paginator.pageIndex).toBe(0);
+
+      fixture.componentInstance.disabled = true;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+      getNextButton(fixture).click();
+      expect(fixture.componentInstance.paginator.pageIndex).toBe(0);
+    });
+
+    it('should not navigate to the previous page when the paginator is disabled', () => {
+      const fixture = createComponent(MatPaginatorApp);
+      fixture.componentInstance.pageIndex = 1;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+
+      expect(fixture.componentInstance.paginator.pageIndex).toBe(1);
+
+      fixture.componentInstance.disabled = true;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+      getPreviousButton(fixture).click();
+      expect(fixture.componentInstance.paginator.pageIndex).toBe(1);
+    });
   });
 
   it('should be able to show the first/last buttons', () => {
     const fixture = createComponent(MatPaginatorApp);
     expect(getFirstButton(fixture)).withContext('Expected first button to not exist.').toBeNull();
-
     expect(getLastButton(fixture)).withContext('Expected last button to not exist.').toBeNull();
 
     fixture.componentInstance.showFirstLastButtons = true;
@@ -271,7 +295,7 @@ describe('MatPaginator', () => {
     it('should be able to go to the last page via the last page button', () => {
       expect(paginator.pageIndex).toBe(0);
 
-      dispatchMouseEvent(getLastButton(fixture), 'click');
+      getLastButton(fixture).click();
 
       expect(paginator.pageIndex).toBe(9);
       expect(component.pageEvent).toHaveBeenCalledWith(
@@ -287,7 +311,7 @@ describe('MatPaginator', () => {
       fixture.detectChanges();
       expect(paginator.pageIndex).toBe(3);
 
-      dispatchMouseEvent(getFirstButton(fixture), 'click');
+      getFirstButton(fixture).click();
 
       expect(paginator.pageIndex).toBe(0);
       expect(component.pageEvent).toHaveBeenCalledWith(
@@ -305,7 +329,7 @@ describe('MatPaginator', () => {
       expect(paginator.hasNextPage()).toBe(false);
 
       component.pageEvent.calls.reset();
-      dispatchMouseEvent(getNextButton(fixture), 'click');
+      getNextButton(fixture).click();
 
       expect(component.pageEvent).not.toHaveBeenCalled();
       expect(paginator.pageIndex).toBe(9);
@@ -316,11 +340,35 @@ describe('MatPaginator', () => {
       expect(paginator.hasPreviousPage()).toBe(false);
 
       component.pageEvent.calls.reset();
-      dispatchMouseEvent(getPreviousButton(fixture), 'click');
+      getPreviousButton(fixture).click();
 
       expect(component.pageEvent).not.toHaveBeenCalled();
       expect(paginator.pageIndex).toBe(0);
     });
+
+    it('should not navigate to the last page when the paginator is disabled', () => {
+      expect(fixture.componentInstance.paginator.pageIndex).toBe(0);
+
+      fixture.componentInstance.disabled = true;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+      getLastButton(fixture).click();
+      expect(fixture.componentInstance.paginator.pageIndex).toBe(0);
+    });
+
+    it('should not navigate to the first page when the paginator is disabled', () => {
+      fixture.componentInstance.pageIndex = 1;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+
+      expect(fixture.componentInstance.paginator.pageIndex).toBe(1);
+
+      fixture.componentInstance.disabled = true;
+      fixture.changeDetectorRef.markForCheck();
+      fixture.detectChanges();
+      getFirstButton(fixture).click();
+      expect(fixture.componentInstance.paginator.pageIndex).toBe(1);
+    });
   });
 
   it('should mark for check when inputs are changed directly', () => {
@@ -569,19 +617,19 @@ describe('MatPaginator', () => {
   });
 });
 
-function getPreviousButton(fixture: ComponentFixture<any>) {
+function getPreviousButton(fixture: ComponentFixture<any>): HTMLButtonElement {
   return fixture.nativeElement.querySelector('.mat-mdc-paginator-navigation-previous');
 }
 
-function getNextButton(fixture: ComponentFixture<any>) {
+function getNextButton(fixture: ComponentFixture<any>): HTMLButtonElement {
   return fixture.nativeElement.querySelector('.mat-mdc-paginator-navigation-next');
 }
 
-function getFirstButton(fixture: ComponentFixture<any>) {
+function getFirstButton(fixture: ComponentFixture<any>): HTMLButtonElement {
   return fixture.nativeElement.querySelector('.mat-mdc-paginator-navigation-first');
 }
 
-function getLastButton(fixture: ComponentFixture<any>) {
+function getLastButton(fixture: ComponentFixture<any>): HTMLButtonElement {
   return fixture.nativeElement.querySelector('.mat-mdc-paginator-navigation-last');
 }
 
diff --git a/src/material/paginator/paginator.ts b/src/material/paginator/paginator.ts
index 0becbb4d065a..7ea27e892cf3 100644
--- a/src/material/paginator/paginator.ts
+++ b/src/material/paginator/paginator.ts
@@ -11,17 +11,17 @@ import {
   ChangeDetectorRef,
   Component,
   EventEmitter,
-  Inject,
   InjectionToken,
   Input,
   OnDestroy,
   OnInit,
-  Optional,
   Output,
   ViewEncapsulation,
   booleanAttribute,
+  inject,
   numberAttribute,
 } from '@angular/core';
+import {_IdGenerator} from '@angular/cdk/a11y';
 import {MatOption, ThemePalette} from '@angular/material/core';
 import {MatSelect} from '@angular/material/select';
 import {MatIconButton} from '@angular/material/button';
@@ -90,8 +90,6 @@ export const MAT_PAGINATOR_DEFAULT_OPTIONS = new InjectionToken<MatPaginatorDefa
   'MAT_PAGINATOR_DEFAULT_OPTIONS',
 );
 
-let nextUniqueId = 0;
-
 /**
  * Component to provide navigation between paged information. Displays the size of the current
  * page, user-selectable options to change that size, what items are being shown, and
@@ -111,11 +109,14 @@ let nextUniqueId = 0;
   imports: [MatFormField, MatSelect, MatOption, MatIconButton, MatTooltip],
 })
 export class MatPaginator implements OnInit, OnDestroy {
+  _intl = inject(MatPaginatorIntl);
+  private _changeDetectorRef = inject(ChangeDetectorRef);
+
   /** If set, styles the "page size" form field with the designated style. */
   _formFieldAppearance?: MatFormFieldAppearance;
 
   /** ID for the DOM node containing the paginator's items per page label. */
-  readonly _pageSizeLabelId = `mat-paginator-page-size-label-${nextUniqueId++}`;
+  readonly _pageSizeLabelId = inject(_IdGenerator).getId('mat-paginator-page-size-label-');
 
   private _intlChanges: Subscription;
   private _isInitialized = false;
@@ -123,10 +124,10 @@ export class MatPaginator implements OnInit, OnDestroy {
 
   /**
    * Theme color of the underlying form controls. This API is supported in M2
-   * themes only,it has no effect in M3 themes.
+   * themes only,it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/paginator/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette;
 
@@ -198,11 +199,15 @@ export class MatPaginator implements OnInit, OnDestroy {
   /** Emits when the paginator is initialized. */
   initialized: Observable<void> = this._initializedStream;
 
-  constructor(
-    public _intl: MatPaginatorIntl,
-    private _changeDetectorRef: ChangeDetectorRef,
-    @Optional() @Inject(MAT_PAGINATOR_DEFAULT_OPTIONS) defaults?: MatPaginatorDefaultOptions,
-  ) {
+  /** Inserted by Angular inject() migration for backwards compatibility */
+  constructor(...args: unknown[]);
+
+  constructor() {
+    const _intl = this._intl;
+    const defaults = inject<MatPaginatorDefaultOptions>(MAT_PAGINATOR_DEFAULT_OPTIONS, {
+      optional: true,
+    });
+
     this._intlChanges = _intl.changes.subscribe(() => this._changeDetectorRef.markForCheck());
 
     if (defaults) {
@@ -241,48 +246,32 @@ export class MatPaginator implements OnInit, OnDestroy {
 
   /** Advances to the next page if it exists. */
   nextPage(): void {
-    if (!this.hasNextPage()) {
-      return;
+    if (this.hasNextPage()) {
+      this._navigate(this.pageIndex + 1);
     }
-
-    const previousPageIndex = this.pageIndex;
-    this.pageIndex = this.pageIndex + 1;
-    this._emitPageEvent(previousPageIndex);
   }
 
   /** Move back to the previous page if it exists. */
   previousPage(): void {
-    if (!this.hasPreviousPage()) {
-      return;
+    if (this.hasPreviousPage()) {
+      this._navigate(this.pageIndex - 1);
     }
-
-    const previousPageIndex = this.pageIndex;
-    this.pageIndex = this.pageIndex - 1;
-    this._emitPageEvent(previousPageIndex);
   }
 
   /** Move to the first page if not already there. */
   firstPage(): void {
     // hasPreviousPage being false implies at the start
-    if (!this.hasPreviousPage()) {
-      return;
+    if (this.hasPreviousPage()) {
+      this._navigate(0);
     }
-
-    const previousPageIndex = this.pageIndex;
-    this.pageIndex = 0;
-    this._emitPageEvent(previousPageIndex);
   }
 
   /** Move to the last page if not already there. */
   lastPage(): void {
     // hasNextPage being false implies at the end
-    if (!this.hasNextPage()) {
-      return;
+    if (this.hasNextPage()) {
+      this._navigate(this.getNumberOfPages() - 1);
     }
-
-    const previousPageIndex = this.pageIndex;
-    this.pageIndex = this.getNumberOfPages() - 1;
-    this._emitPageEvent(previousPageIndex);
   }
 
   /** Whether there is a previous page. */
@@ -369,4 +358,28 @@ export class MatPaginator implements OnInit, OnDestroy {
       length: this.length,
     });
   }
+
+  /** Navigates to a specific page index. */
+  private _navigate(index: number) {
+    const previousIndex = this.pageIndex;
+
+    if (index !== previousIndex) {
+      this.pageIndex = index;
+      this._emitPageEvent(previousIndex);
+    }
+  }
+
+  /**
+   * Callback invoked when one of the navigation buttons is called.
+   * @param targetIndex Index to which the paginator should navigate.
+   * @param isDisabled Whether the button is disabled.
+   */
+  protected _buttonClicked(targetIndex: number, isDisabled: boolean) {
+    // Note that normally disabled buttons won't dispatch the click event, but the paginator ones
+    // do, because we're using `disabledInteractive` to allow them to be focusable. We need to
+    // check here to avoid the navigation.
+    if (!isDisabled) {
+      this._navigate(targetIndex);
+    }
+  }
 }
diff --git a/src/material/paginator/testing/paginator-harness.spec.ts b/src/material/paginator/testing/paginator-harness.spec.ts
index 3f728f9ab474..1b77d893f510 100644
--- a/src/material/paginator/testing/paginator-harness.spec.ts
+++ b/src/material/paginator/testing/paginator-harness.spec.ts
@@ -137,7 +137,6 @@ describe('MatPaginatorHarness', () => {
       [pageIndex]="pageIndex()">
     </mat-paginator>
   `,
-  standalone: true,
   imports: [MatPaginatorModule],
 })
 class PaginatorHarnessTest {
diff --git a/src/material/progress-bar/progress-bar.spec.ts b/src/material/progress-bar/progress-bar.spec.ts
index 265b6811e64f..0ef8a0fd48ea 100644
--- a/src/material/progress-bar/progress-bar.spec.ts
+++ b/src/material/progress-bar/progress-bar.spec.ts
@@ -336,14 +336,12 @@ describe('MatProgressBar', () => {
 
 @Component({
   template: '<mat-progress-bar></mat-progress-bar>',
-  standalone: true,
   imports: [MatProgressBar],
 })
 class BasicProgressBar {}
 
 @Component({
   template: '<mat-progress-bar mode="buffer"></mat-progress-bar>',
-  standalone: true,
   imports: [MatProgressBar],
 })
 class BufferProgressBar {}
diff --git a/src/material/progress-bar/progress-bar.ts b/src/material/progress-bar/progress-bar.ts
index 498aeb537299..bcaa9e4af0c3 100644
--- a/src/material/progress-bar/progress-bar.ts
+++ b/src/material/progress-bar/progress-bar.ts
@@ -22,6 +22,7 @@ import {
   inject,
   numberAttribute,
   ANIMATION_MODULE_TYPE,
+  Renderer2,
 } from '@angular/core';
 import {DOCUMENT} from '@angular/common';
 import {ThemePalette} from '@angular/material/core';
@@ -35,10 +36,10 @@ export interface ProgressAnimationEnd {
 export interface MatProgressBarDefaultOptions {
   /**
    * Default theme color of the progress bar. This API is supported in M2 themes only,
-   * it has no effect in M3 themes.
+   * it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/progress-bar/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   color?: ThemePalette;
 
@@ -110,6 +111,8 @@ export class MatProgressBar implements AfterViewInit, OnDestroy {
   readonly _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
   private _ngZone = inject(NgZone);
   private _changeDetectorRef = inject(ChangeDetectorRef);
+  private _renderer = inject(Renderer2);
+  private _cleanupTransitionEnd: (() => void) | undefined;
   _animationMode? = inject(ANIMATION_MODULE_TYPE, {optional: true});
 
   constructor(...args: unknown[]);
@@ -136,10 +139,10 @@ export class MatProgressBar implements AfterViewInit, OnDestroy {
   // TODO: should be typed as `ThemePalette` but internal apps pass in arbitrary strings.
   /**
    * Theme color of the progress bar. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/progress-bar/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   get color() {
@@ -203,12 +206,16 @@ export class MatProgressBar implements AfterViewInit, OnDestroy {
     // Run outside angular so change detection didn't get triggered on every transition end
     // instead only on the animation that we care about (primary value bar's transitionend)
     this._ngZone.runOutsideAngular(() => {
-      this._elementRef.nativeElement.addEventListener('transitionend', this._transitionendHandler);
+      this._cleanupTransitionEnd = this._renderer.listen(
+        this._elementRef.nativeElement,
+        'transitionend',
+        this._transitionendHandler,
+      );
     });
   }
 
   ngOnDestroy() {
-    this._elementRef.nativeElement.removeEventListener('transitionend', this._transitionendHandler);
+    this._cleanupTransitionEnd?.();
   }
 
   /** Gets the transform style that should be applied to the primary bar. */
diff --git a/src/material/progress-bar/testing/progress-bar-harness.spec.ts b/src/material/progress-bar/testing/progress-bar-harness.spec.ts
index 2d20a2666ab9..3415805f14ac 100644
--- a/src/material/progress-bar/testing/progress-bar-harness.spec.ts
+++ b/src/material/progress-bar/testing/progress-bar-harness.spec.ts
@@ -44,7 +44,6 @@ describe('MatProgressBarHarness', () => {
     <mat-progress-bar mode="determinate" [value]="value()"></mat-progress-bar>
     <mat-progress-bar mode="indeterminate"></mat-progress-bar>
   `,
-  standalone: true,
   imports: [MatProgressBarModule],
 })
 class ProgressBarHarnessTest {
diff --git a/src/material/progress-spinner/module.ts b/src/material/progress-spinner/module.ts
index 5c6c9b658c5d..4ea6aa671114 100644
--- a/src/material/progress-spinner/module.ts
+++ b/src/material/progress-spinner/module.ts
@@ -9,10 +9,9 @@
 import {NgModule} from '@angular/core';
 import {MatCommonModule} from '@angular/material/core';
 import {MatProgressSpinner, MatSpinner} from './progress-spinner';
-import {CommonModule} from '@angular/common';
 
 @NgModule({
-  imports: [CommonModule, MatProgressSpinner, MatSpinner],
+  imports: [MatProgressSpinner, MatSpinner],
   exports: [MatProgressSpinner, MatSpinner, MatCommonModule],
 })
 export class MatProgressSpinnerModule {}
diff --git a/src/material/progress-spinner/progress-spinner.spec.ts b/src/material/progress-spinner/progress-spinner.spec.ts
index 60a337d3a248..0bd90174d129 100644
--- a/src/material/progress-spinner/progress-spinner.spec.ts
+++ b/src/material/progress-spinner/progress-spinner.spec.ts
@@ -395,14 +395,12 @@ describe('MatProgressSpinner', () => {
 
 @Component({
   template: '<mat-progress-spinner></mat-progress-spinner>',
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class BasicProgressSpinner {}
 
 @Component({
   template: '<mat-progress-spinner [strokeWidth]="strokeWidth"></mat-progress-spinner>',
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class ProgressSpinnerCustomStrokeWidth {
@@ -411,7 +409,6 @@ class ProgressSpinnerCustomStrokeWidth {
 
 @Component({
   template: '<mat-progress-spinner [diameter]="diameter"></mat-progress-spinner>',
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class ProgressSpinnerCustomDiameter {
@@ -420,14 +417,12 @@ class ProgressSpinnerCustomDiameter {
 
 @Component({
   template: '<mat-progress-spinner mode="indeterminate"></mat-progress-spinner>',
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class IndeterminateProgressSpinner {}
 
 @Component({
   template: '<mat-progress-spinner [value]="value()" [mode]="mode()"></mat-progress-spinner>',
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class ProgressSpinnerWithValueAndBoundMode {
@@ -438,7 +433,6 @@ class ProgressSpinnerWithValueAndBoundMode {
 @Component({
   template: `
     <mat-spinner [color]="color()"></mat-spinner>`,
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class SpinnerWithColor {
@@ -448,7 +442,6 @@ class SpinnerWithColor {
 @Component({
   template: `
     <mat-progress-spinner value="50" [color]="color()"></mat-progress-spinner>`,
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class ProgressSpinnerWithColor {
@@ -459,7 +452,6 @@ class ProgressSpinnerWithColor {
   template: `
     <mat-progress-spinner value="25" diameter="37" strokeWidth="11"></mat-progress-spinner>
   `,
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class ProgressSpinnerWithStringValues {}
@@ -469,7 +461,6 @@ class ProgressSpinnerWithStringValues {}
     <mat-progress-spinner mode="indeterminate" [diameter]="diameter"></mat-progress-spinner>
   `,
   encapsulation: ViewEncapsulation.ShadowDom,
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class IndeterminateSpinnerInShadowDom {
@@ -485,7 +476,6 @@ class IndeterminateSpinnerInShadowDom {
     }
   `,
   encapsulation: ViewEncapsulation.ShadowDom,
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class IndeterminateSpinnerInShadowDomWithNgIf {
@@ -497,7 +487,6 @@ class IndeterminateSpinnerInShadowDomWithNgIf {
 
 @Component({
   template: '<mat-spinner mode="determinate"></mat-spinner>',
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class SpinnerWithMode {}
diff --git a/src/material/progress-spinner/progress-spinner.ts b/src/material/progress-spinner/progress-spinner.ts
index a8b805e88224..89eec823123d 100644
--- a/src/material/progress-spinner/progress-spinner.ts
+++ b/src/material/progress-spinner/progress-spinner.ts
@@ -28,10 +28,10 @@ export type ProgressSpinnerMode = 'determinate' | 'indeterminate';
 export interface MatProgressSpinnerDefaultOptions {
   /**
    * Default theme color of the progress spinner. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/progress-spinner/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   color?: ThemePalette;
   /** Diameter of the spinner. */
@@ -103,10 +103,10 @@ export class MatProgressSpinner {
   // TODO: should be typed as `ThemePalette` but internal apps pass in arbitrary strings.
   /**
    * Theme color of the progress spinner. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/progress-spinner/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   get color() {
diff --git a/src/material/progress-spinner/testing/progress-spinner-harness.spec.ts b/src/material/progress-spinner/testing/progress-spinner-harness.spec.ts
index bac8d2eb0d60..5ddd5d1ce558 100644
--- a/src/material/progress-spinner/testing/progress-spinner-harness.spec.ts
+++ b/src/material/progress-spinner/testing/progress-spinner-harness.spec.ts
@@ -48,7 +48,6 @@ describe('MatProgressSpinnerHarness', () => {
     <mat-progress-spinner mode="indeterminate"></mat-progress-spinner>
     <mat-spinner></mat-spinner>
   `,
-  standalone: true,
   imports: [MatProgressSpinnerModule],
 })
 class ProgressSpinnerHarnessTest {
diff --git a/src/material/radio/module.ts b/src/material/radio/module.ts
index 54cedc152f38..ec9d5f40fc41 100644
--- a/src/material/radio/module.ts
+++ b/src/material/radio/module.ts
@@ -6,13 +6,12 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {MatCommonModule, MatRippleModule} from '@angular/material/core';
 import {MatRadioButton, MatRadioGroup} from './radio';
 
 @NgModule({
-  imports: [MatCommonModule, CommonModule, MatRippleModule, MatRadioGroup, MatRadioButton],
+  imports: [MatCommonModule, MatRippleModule, MatRadioGroup, MatRadioButton],
   exports: [MatCommonModule, MatRadioGroup, MatRadioButton],
 })
 export class MatRadioModule {}
diff --git a/src/material/radio/radio.spec.ts b/src/material/radio/radio.spec.ts
index a1c8f235dad9..0d2e0ccb5af4 100644
--- a/src/material/radio/radio.spec.ts
+++ b/src/material/radio/radio.spec.ts
@@ -1089,7 +1089,6 @@ describe('MatRadioDefaultOverrides', () => {
     </mat-radio-button>
   </mat-radio-group>
   `,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class RadiosInsideRadioGroup {
@@ -1112,7 +1111,6 @@ class RadiosInsideRadioGroup {
     <mat-radio-button value="leaf" checked>Bulbasaur</mat-radio-button>
   </mat-radio-group>
   `,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class RadiosInsidePreCheckedRadioGroup {}
@@ -1138,7 +1136,6 @@ class RadiosInsidePreCheckedRadioGroup {}
     <mat-radio-button name="fruit" value="raspberry">Raspberry</mat-radio-button>
     <mat-radio-button id="nameless" value="no-name">No name</mat-radio-button>
   `,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class StandaloneRadioButtons {
@@ -1155,7 +1152,6 @@ class StandaloneRadioButtons {
     }
   </mat-radio-group>
   `,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class RadioGroupWithNgModel {
@@ -1174,7 +1170,6 @@ class RadioGroupWithNgModel {
     <mat-radio-button
       [disabled]="disabled"
       [disabledInteractive]="disabledInteractive">One</mat-radio-button>`,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class DisableableRadioButton {
@@ -1191,7 +1186,6 @@ class DisableableRadioButton {
       <mat-radio-button value="2">Two</mat-radio-button>
     </mat-radio-group>
   `,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class RadioGroupWithFormControl {
@@ -1201,7 +1195,6 @@ class RadioGroupWithFormControl {
 
 @Component({
   template: `<mat-radio-button [disabled]="disabled" [tabIndex]="tabIndex"></mat-radio-button>`,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class FocusableRadioButton {
@@ -1214,7 +1207,6 @@ class FocusableRadioButton {
   template: `
     <div><ng-content></ng-content></div>
   `,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class TranscludingWrapper {}
@@ -1229,7 +1221,6 @@ class TranscludingWrapper {}
     }
   </mat-radio-group>
   `,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule, TranscludingWrapper],
 })
 class InterleavedRadioGroup {
@@ -1243,21 +1234,18 @@ class InterleavedRadioGroup {
 
 @Component({
   template: `<mat-radio-button tabindex="5"></mat-radio-button>`,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class RadioButtonWithPredefinedTabindex {}
 
 @Component({
   template: `<mat-radio-button></mat-radio-button>`,
-  standalone: true,
   imports: [MatRadioModule, FormsModule],
 })
 class DefaultRadioButton {}
 
 @Component({
   template: `<mat-radio-button color="warn"></mat-radio-button>`,
-  standalone: true,
   imports: [MatRadioModule, FormsModule],
 })
 class RadioButtonWithColorBinding {}
@@ -1268,7 +1256,6 @@ class RadioButtonWithColorBinding {}
       aria-label="Radio button"
       aria-describedby="something"
       aria-labelledby="something-else"></mat-radio-button>`,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class RadioButtonWithPredefinedAriaAttributes {}
@@ -1289,7 +1276,6 @@ class RadioButtonWithPredefinedAriaAttributes {}
         }
     </mat-radio-group>
   `,
-  standalone: true,
   imports: [MatRadioModule, FormsModule, ReactiveFormsModule],
 })
 class PreselectedRadioWithStaticValueAndNgIf {
diff --git a/src/material/radio/radio.ts b/src/material/radio/radio.ts
index d569a1e311da..99b54821b07d 100644
--- a/src/material/radio/radio.ts
+++ b/src/material/radio/radio.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 
-import {FocusMonitor, FocusOrigin} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusMonitor, FocusOrigin} from '@angular/cdk/a11y';
 import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
 import {
   ANIMATION_MODULE_TYPE,
@@ -36,6 +36,7 @@ import {
   inject,
   numberAttribute,
   HostAttributeToken,
+  Renderer2,
 } from '@angular/core';
 import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
 import {
@@ -47,9 +48,6 @@ import {
 import {Subscription} from 'rxjs';
 import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
 
-// Increasing integer for generating unique ids for radio components.
-let nextUniqueId = 0;
-
 /** Change event object emitted by radio button and radio group. */
 export class MatRadioChange {
   constructor(
@@ -81,10 +79,10 @@ export const MAT_RADIO_GROUP = new InjectionToken<MatRadioGroup>('MatRadioGroup'
 export interface MatRadioDefaultOptions {
   /**
    * Theme color of the radio button. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/radio/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   color: ThemePalette;
 
@@ -129,7 +127,7 @@ export class MatRadioGroup implements AfterContentInit, OnDestroy, ControlValueA
   private _value: any = null;
 
   /** The HTML name attribute applied to radio buttons in this group. */
-  private _name: string = `mat-radio-group-${nextUniqueId++}`;
+  private _name: string = inject(_IdGenerator).getId('mat-radio-group-');
 
   /** The currently selected radio button. Should match value. */
   private _selected: MatRadioButton | null = null;
@@ -171,10 +169,10 @@ export class MatRadioGroup implements AfterContentInit, OnDestroy, ControlValueA
 
   /**
    * Theme color of the radio buttons in the group. This API is supported in M2
-   * themes only, it has no effect in M3 themes.
+   * themes only, it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/radio/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette;
 
@@ -422,7 +420,9 @@ export class MatRadioButton implements OnInit, AfterViewInit, DoCheck, OnDestroy
   });
 
   private _ngZone = inject(NgZone);
-  private _uniqueId: string = `mat-radio-${++nextUniqueId}`;
+  private _renderer = inject(Renderer2);
+  private _uniqueId = inject(_IdGenerator).getId('mat-radio-');
+  private _cleanupClick: (() => void) | undefined;
 
   /** The unique ID for the radio button. */
   @Input() id: string = this._uniqueId;
@@ -523,10 +523,10 @@ export class MatRadioButton implements OnInit, AfterViewInit, DoCheck, OnDestroy
 
   /**
    * Theme color of the radio button. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/radio/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   get color(): ThemePalette {
@@ -676,13 +676,16 @@ export class MatRadioButton implements OnInit, AfterViewInit, DoCheck, OnDestroy
     // 1. Its logic is completely DOM-related so we can avoid some change detections.
     // 2. There appear to be some internal tests that break when this triggers a change detection.
     this._ngZone.runOutsideAngular(() => {
-      this._inputElement.nativeElement.addEventListener('click', this._onInputClick);
+      this._cleanupClick = this._renderer.listen(
+        this._inputElement.nativeElement,
+        'click',
+        this._onInputClick,
+      );
     });
   }
 
   ngOnDestroy() {
-    // We need to null check in case the button was destroyed before `ngAfterViewInit`.
-    this._inputElement?.nativeElement.removeEventListener('click', this._onInputClick);
+    this._cleanupClick?.();
     this._focusMonitor.stopMonitoring(this._elementRef);
     this._removeUniqueSelectionListener();
   }
diff --git a/src/material/radio/testing/radio-harness.spec.ts b/src/material/radio/testing/radio-harness.spec.ts
index 0a448b8a2ddc..929a1f5b8537 100644
--- a/src/material/radio/testing/radio-harness.spec.ts
+++ b/src/material/radio/testing/radio-harness.spec.ts
@@ -312,7 +312,6 @@ describe('radio harness', () => {
       <mat-radio-button [value]="false" [name]="thirdGroupButtonName"></mat-radio-button>
     </mat-radio-group>
   `,
-  standalone: true,
   imports: [MatRadioModule, ReactiveFormsModule],
 })
 class MultipleRadioButtonsHarnessTest {
diff --git a/src/material/schematics/ng-add/index.spec.ts b/src/material/schematics/ng-add/index.spec.ts
index 28d0a4ee8200..803a9d243604 100644
--- a/src/material/schematics/ng-add/index.spec.ts
+++ b/src/material/schematics/ng-add/index.spec.ts
@@ -124,7 +124,7 @@ describe('ng-add schematic', () => {
     const themeContent = buffer!.toString();
 
     expect(themeContent).toContain(`@use '@angular/material' as mat;`);
-    expect(themeContent).toContain(`$material-theme: mat.define-theme((`);
+    expect(themeContent).toContain(`@include mat.theme((`);
   });
 
   it('should create a custom theme file if no SCSS file could be found', async () => {
diff --git a/src/material/schematics/ng-add/theming/create-custom-theme.ts b/src/material/schematics/ng-add/theming/create-custom-theme.ts
index 0e8386421146..b75880360b06 100644
--- a/src/material/schematics/ng-add/theming/create-custom-theme.ts
+++ b/src/material/schematics/ng-add/theming/create-custom-theme.ts
@@ -12,32 +12,16 @@ export function createCustomTheme(name: string = 'app') {
 // Custom Theming for Angular Material
 // For more information: https://material.angular.io/guide/theming
 @use '@angular/material' as mat;
-// Plus imports for other components in your app.
 
-// Define the theme object.
-$${name}-theme: mat.define-theme((
-  color: (
-    theme-type: light,
-    primary: mat.$azure-palette,
-    tertiary: mat.$blue-palette,
-  ),
-  density: (
-    scale: 0,
-  )
-));
-
-// Include theme styles for core and each component used in your app.
-// Alternatively, you can import and @include the theme mixins for each component
-// that you are using.
-:root {
-  @include mat.all-component-themes($${name}-theme);
-}
-
-// Comment out the line below if you want to use the pre-defined typography utility classes.
-// For more information: https://material.angular.io/guide/typography#using-typography-styles-in-your-application.
-// @include mat.typography-hierarchy($${name}-theme);
-
-// Comment out the line below if you want to use the deprecated \`color\` inputs.
-// @include mat.color-variants-backwards-compatibility($${name}-theme);
-`;
+html {
+  @include mat.theme((
+    color: (
+      theme-type: light,
+      primary: mat.$azure-palette,
+      tertiary: mat.$blue-palette,
+    ),
+    typography: Roboto,
+    density: 0,
+  ));
+}`;
 }
diff --git a/src/material/schematics/ng-generate/theme-color/README.md b/src/material/schematics/ng-generate/theme-color/README.md
index e7e8faf7406f..6d2cc4bee441 100644
--- a/src/material/schematics/ng-generate/theme-color/README.md
+++ b/src/material/schematics/ng-generate/theme-color/README.md
@@ -23,14 +23,14 @@ palettes (`$primary-palette` and `$tertiary-palette`) can be provided to the `th
 @use './path/to/my-theme'; // location of generated file
 
 html {
-  @include mat.theme(
+  @include mat.theme((
     color: (
       primary: my-theme.$primary-palette,
       tertiary: my-theme.$tertiary-palette,
     ),
     typography: Roboto,
     density: 0,
-  )
+  ));
 }
 ```
 
diff --git a/src/material/schematics/ng-update/index.ts b/src/material/schematics/ng-update/index.ts
index d89f7212ea25..e9f51ee593a6 100644
--- a/src/material/schematics/ng-update/index.ts
+++ b/src/material/schematics/ng-update/index.ts
@@ -15,8 +15,12 @@ import {
 
 import {materialUpgradeData} from './upgrade-data';
 import {MatCoreMigration} from './migrations/mat-core-removal';
+import {ExplicitSystemVariablePrefixMigration} from './migrations/explicit-system-variable-prefix';
 
-const materialMigrations: NullableDevkitMigration[] = [MatCoreMigration];
+const materialMigrations: NullableDevkitMigration[] = [
+  MatCoreMigration,
+  ExplicitSystemVariablePrefixMigration,
+];
 
 /** Entry point for the migration schematics with target of Angular Material v19 */
 export function updateToV19(): Rule {
diff --git a/src/material/schematics/ng-update/migrations/explicit-system-variable-prefix.ts b/src/material/schematics/ng-update/migrations/explicit-system-variable-prefix.ts
new file mode 100644
index 000000000000..f49a8962bec1
--- /dev/null
+++ b/src/material/schematics/ng-update/migrations/explicit-system-variable-prefix.ts
@@ -0,0 +1,125 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.dev/license
+ */
+
+import {DevkitContext, Migration, ResolvedResource, UpgradeData} from '@angular/cdk/schematics';
+
+/**
+ * Migration that adds `system-variables-prefix` to apps that have `use-system-variables` enabled.
+ */
+export class ExplicitSystemVariablePrefixMigration extends Migration<UpgradeData, DevkitContext> {
+  override enabled = true;
+
+  override visitStylesheet(stylesheet: ResolvedResource): void {
+    if (!stylesheet.filePath.endsWith('.scss')) {
+      return;
+    }
+
+    const content = this.fileSystem.read(stylesheet.filePath);
+    if (!content || !content.includes('@angular/material')) {
+      return;
+    }
+
+    const changes = this._getChanges(content);
+
+    if (changes.length > 0) {
+      const update = this.fileSystem.edit(stylesheet.filePath);
+
+      for (let i = changes.length - 1; i > -1; i--) {
+        update.insertRight(changes[i].start, changes[i].text);
+      }
+
+      this.fileSystem.commitEdits();
+    }
+  }
+
+  /** Gets the changes that should be applied to a file. */
+  private _getChanges(content: string) {
+    const key = 'use-system-variables';
+    const prefixKey = 'system-variables-prefix';
+    const changes: {start: number; text: string}[] = [];
+    let index = content.indexOf(key);
+
+    // Note: this migration is a bit rudimentary, because Sass doesn't expose a proper AST.
+    while (index > -1) {
+      const colonIndex = content.indexOf(':', index);
+      const valueEnd = colonIndex === -1 ? -1 : this._getValueEnd(content, colonIndex);
+
+      if (valueEnd === -1) {
+        index = content.indexOf(key, index + key.length);
+        continue;
+      }
+
+      const value = content.slice(colonIndex + 1, valueEnd + 1).trim();
+      if (value.startsWith('true') && !this._hasSystemPrefix(content, index, prefixKey)) {
+        changes.push({
+          start: this._getInsertIndex(content, valueEnd),
+          text: `${value.endsWith(',') ? '' : ','}\n    ${prefixKey}: sys,`,
+        });
+      }
+
+      index = content.indexOf(key, valueEnd);
+    }
+
+    return changes;
+  }
+
+  /**
+   * Gets the end index of a Sass map key.
+   * @param content Content of the file.
+   * @param startIndex Index at which to start the search.
+   */
+  private _getValueEnd(content: string, startIndex: number): number {
+    for (let i = startIndex + 1; i < content.length; i++) {
+      const char = content[i];
+
+      if (char === ',' || char === '\n' || char === ')') {
+        return i;
+      }
+    }
+
+    return -1;
+  }
+
+  /**
+   * Gets the index at which to insert the migrated content.
+   * @param content Initial file content.
+   * @param valueEnd Index at which the value of the system variables opt-in ends.
+   */
+  private _getInsertIndex(content: string, valueEnd: number): number {
+    for (let i = valueEnd; i < content.length; i++) {
+      if (content[i] === '\n') {
+        return i;
+      } else if (content[i] === ')') {
+        return i;
+      }
+    }
+
+    return valueEnd;
+  }
+
+  /**
+   * Determines if a map that enables system variables is using system variables already.
+   * @param content Full file contents.
+   * @param keyIndex Index at which the systems variable key is defined.
+   * @param prefixKey Name of the key that defines the prefix.
+   */
+  private _hasSystemPrefix(content: string, keyIndex: number, prefixKey: string): boolean {
+    // Note: technically this can break if there are other inline maps, but it should be rare.
+    const mapEnd = content.indexOf(')', keyIndex);
+
+    if (mapEnd > -1) {
+      for (let i = keyIndex; i > -1; i--) {
+        if (content[i] === '(') {
+          return content.slice(i, mapEnd).includes(prefixKey);
+        }
+      }
+    }
+
+    return false;
+  }
+}
diff --git a/src/material/schematics/ng-update/migrations/mat-core-removal.ts b/src/material/schematics/ng-update/migrations/mat-core-removal.ts
index dac48916476c..64c0b84d2808 100644
--- a/src/material/schematics/ng-update/migrations/mat-core-removal.ts
+++ b/src/material/schematics/ng-update/migrations/mat-core-removal.ts
@@ -16,6 +16,8 @@ import {
   WorkspacePath,
 } from '@angular/cdk/schematics';
 
+const MATERIAL_IMPORT_PATH = '@angular/material';
+
 export class MatCoreMigration extends Migration<UpgradeData, DevkitContext> {
   override enabled = true;
   private _namespace: string | undefined;
@@ -25,16 +27,28 @@ export class MatCoreMigration extends Migration<UpgradeData, DevkitContext> {
   }
 
   override visitStylesheet(stylesheet: ResolvedResource): void {
-    const processor = new postcss.Processor([
-      {
-        postcssPlugin: 'mat-core-removal-v19-plugin',
-        AtRule: {
-          use: node => this._getNamespace(node),
-          include: node => this._handleAtInclude(node, stylesheet.filePath),
+    // Avoid parsing the template Material isn't used.
+    if (!stylesheet.content.includes(MATERIAL_IMPORT_PATH)) {
+      return;
+    }
+
+    try {
+      const processor = new postcss.Processor([
+        {
+          postcssPlugin: 'mat-core-removal-v19-plugin',
+          AtRule: {
+            use: node => this._getNamespace(node),
+            include: node => this._handleAtInclude(node, stylesheet.filePath),
+          },
         },
-      },
-    ]);
-    processor.process(stylesheet.content, {syntax: scss}).sync();
+      ]);
+      processor.process(stylesheet.content, {syntax: scss}).sync();
+    } catch (e) {
+      this.logger.warn(
+        `Failed to migrate usages of mat.core in ${stylesheet.filePath} due to error:`,
+      );
+      this.logger.warn(e + '');
+    }
   }
 
   /** Handles updating the at-include rules of uses of the core mixin. */
@@ -70,7 +84,7 @@ export class MatCoreMigration extends Migration<UpgradeData, DevkitContext> {
 
   /** Sets the namespace if the given at-rule if it is importing from @angular/material. */
   private _getNamespace(node: postcss.AtRule): void {
-    if (!this._namespace && node.params.startsWith('@angular/material', 1)) {
+    if (!this._namespace && node.params.startsWith(MATERIAL_IMPORT_PATH, 1)) {
       this._namespace = node.params.split(/\s+/)[2] || 'material';
     }
   }
diff --git a/src/material/schematics/ng-update/test-cases/v19-explicit-system-variable-prefix.spec.ts b/src/material/schematics/ng-update/test-cases/v19-explicit-system-variable-prefix.spec.ts
new file mode 100644
index 000000000000..5a7a86afc73f
--- /dev/null
+++ b/src/material/schematics/ng-update/test-cases/v19-explicit-system-variable-prefix.spec.ts
@@ -0,0 +1,215 @@
+import {UnitTestTree} from '@angular-devkit/schematics/testing';
+import {createTestCaseSetup} from '@angular/cdk/schematics/testing';
+import {MIGRATION_PATH} from '../../paths';
+
+const THEME_FILE_PATH = '/projects/cdk-testing/src/theme.scss';
+
+describe('v19 explicit system variable prefix migration', () => {
+  let tree: UnitTestTree;
+  let writeFile: (filename: string, content: string) => void;
+  let runMigration: () => Promise<unknown>;
+
+  function stripWhitespace(content: string): string {
+    return content.replace(/\s/g, '');
+  }
+
+  beforeEach(async () => {
+    const testSetup = await createTestCaseSetup('migration-v19', MIGRATION_PATH, []);
+    tree = testSetup.appTree;
+    writeFile = testSetup.writeFile;
+    runMigration = testSetup.runFixers;
+  });
+
+  it('should add an explicit system variables prefix', async () => {
+    writeFile(
+      THEME_FILE_PATH,
+      `
+        @use '@angular/material' as mat;
+
+        $theme: mat.define-theme((
+          color: (
+            theme-type: 'light',
+            primary: mat.$azure-palette,
+            tertiary: mat.$red-palette,
+            use-system-variables: true
+          ),
+          typography: (
+            use-system-variables: true
+          ),
+          density: (
+            scale: -1
+          ),
+        ));
+
+        @include mat.all-component-themes($theme);
+      `,
+    );
+
+    await runMigration();
+
+    expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe(
+      stripWhitespace(`
+        @use '@angular/material' as mat;
+
+        $theme: mat.define-theme((
+          color: (
+            theme-type: 'light',
+            primary: mat.$azure-palette,
+            tertiary: mat.$red-palette,
+            use-system-variables: true,
+            system-variables-prefix: sys,
+          ),
+          typography: (
+            use-system-variables: true,
+            system-variables-prefix: sys,
+          ),
+          density: (
+            scale: -1
+          ),
+        ));
+
+        @include mat.all-component-themes($theme);
+    `),
+    );
+  });
+
+  it('should add an explicit system variables prefix if the value is using trailing commas', async () => {
+    writeFile(
+      THEME_FILE_PATH,
+      `
+        @use '@angular/material' as mat;
+
+        $theme: mat.define-theme((
+          color: (
+            theme-type: 'light',
+            primary: mat.$azure-palette,
+            tertiary: mat.$red-palette,
+            use-system-variables: true,
+          ),
+          typography: (
+            use-system-variables: true,
+          ),
+          density: (
+            scale: -1
+          ),
+        ));
+
+        @include mat.all-component-themes($theme);
+      `,
+    );
+
+    await runMigration();
+
+    expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe(
+      stripWhitespace(`
+        @use '@angular/material' as mat;
+
+        $theme: mat.define-theme((
+          color: (
+            theme-type: 'light',
+            primary: mat.$azure-palette,
+            tertiary: mat.$red-palette,
+            use-system-variables: true,
+            system-variables-prefix: sys,
+          ),
+          typography: (
+            use-system-variables: true,
+            system-variables-prefix: sys,
+          ),
+          density: (
+            scale: -1
+          ),
+        ));
+
+        @include mat.all-component-themes($theme);
+    `),
+    );
+  });
+
+  it('should not add an explicit system variables prefix if the map has one already', async () => {
+    writeFile(
+      THEME_FILE_PATH,
+      `
+        @use '@angular/material' as mat;
+
+        $theme: mat.define-theme((
+          color: (
+            theme-type: 'light',
+            primary: mat.$azure-palette,
+            tertiary: mat.$red-palette,
+            use-system-variables: true
+          ),
+          typography: (
+            use-system-variables: true,
+            system-variables-prefix: foo
+          ),
+          density: (
+            scale: -1
+          ),
+        ));
+
+        @include mat.all-component-themes($theme);
+      `,
+    );
+
+    await runMigration();
+
+    expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe(
+      stripWhitespace(`
+        @use '@angular/material' as mat;
+
+        $theme: mat.define-theme((
+          color: (
+            theme-type: 'light',
+            primary: mat.$azure-palette,
+            tertiary: mat.$red-palette,
+            use-system-variables: true,
+            system-variables-prefix: sys,
+          ),
+          typography: (
+            use-system-variables: true,
+            system-variables-prefix: foo
+          ),
+          density: (
+            scale: -1
+          ),
+        ));
+
+        @include mat.all-component-themes($theme);
+    `),
+    );
+  });
+
+  it('should handle a single-line map', async () => {
+    writeFile(
+      THEME_FILE_PATH,
+      `
+        @use '@angular/material' as mat;
+
+        $theme: mat.define-theme((
+          color: (theme-type: 'light', primary: mat.$azure-palette, use-system-variables: true),
+          typography: (use-system-variables: true),
+          density: (scale: -1),
+        ));
+
+        @include mat.all-component-themes($theme);
+      `,
+    );
+
+    await runMigration();
+
+    expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe(
+      stripWhitespace(`
+        @use '@angular/material' as mat;
+
+        $theme: mat.define-theme((
+          color: (theme-type: 'light', primary: mat.$azure-palette, use-system-variables: true, system-variables-prefix: sys,),
+          typography: (use-system-variables: true, system-variables-prefix: sys,),
+          density: (scale: -1),
+        ));
+
+        @include mat.all-component-themes($theme);
+    `),
+    );
+  });
+});
diff --git a/src/material/schematics/ng-update/test-cases/v19-mat-core-removal.spec.ts b/src/material/schematics/ng-update/test-cases/v19-mat-core-removal.spec.ts
index e249f8983b54..2a05fac5c73d 100644
--- a/src/material/schematics/ng-update/test-cases/v19-mat-core-removal.spec.ts
+++ b/src/material/schematics/ng-update/test-cases/v19-mat-core-removal.spec.ts
@@ -6,7 +6,7 @@ import {MIGRATION_PATH} from '../../paths';
 const PROJECT_ROOT_DIR = '/projects/cdk-testing';
 const THEME_FILE_PATH = join(PROJECT_ROOT_DIR, 'src/theme.scss');
 
-describe('v15 legacy components migration', () => {
+describe('v19 mat.core migration', () => {
   let tree: UnitTestTree;
 
   /** Writes multiple lines to a file. */
@@ -73,5 +73,12 @@ describe('v15 legacy components migration', () => {
         ],
       });
     });
+
+    it('should not break if there is an invalid syntax', async () => {
+      await runSassMigrationTest('', {
+        old: [`@use '@angular/material' as mat;`, `.foo { content: '; }`],
+        new: [`@use '@angular/material' as mat;`, `.foo { content: '; }`],
+      });
+    });
   });
 });
diff --git a/src/material/select/module.ts b/src/material/select/module.ts
index 4a910ed034c0..2bc3d42ebabe 100644
--- a/src/material/select/module.ts
+++ b/src/material/select/module.ts
@@ -7,7 +7,6 @@
  */
 
 import {OverlayModule} from '@angular/cdk/overlay';
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {MatCommonModule, MatOptionModule} from '@angular/material/core';
 import {MatFormFieldModule} from '@angular/material/form-field';
@@ -15,14 +14,7 @@ import {CdkScrollableModule} from '@angular/cdk/scrolling';
 import {MatSelect, MatSelectTrigger, MAT_SELECT_SCROLL_STRATEGY_PROVIDER} from './select';
 
 @NgModule({
-  imports: [
-    CommonModule,
-    OverlayModule,
-    MatOptionModule,
-    MatCommonModule,
-    MatSelect,
-    MatSelectTrigger,
-  ],
+  imports: [OverlayModule, MatOptionModule, MatCommonModule, MatSelect, MatSelectTrigger],
   exports: [
     CdkScrollableModule,
     MatFormFieldModule,
diff --git a/src/material/select/select.md b/src/material/select/select.md
index c91a694cb18b..2a00d2849caf 100644
--- a/src/material/select/select.md
+++ b/src/material/select/select.md
@@ -66,6 +66,15 @@ If you want one of your options to reset the select's value, you can omit specif
 
 <!-- example(select-reset) -->
 
+### Allowing nullable options to be selected
+
+By default any options with a `null` or `undefined` value will reset the select's value. If instead
+you want the nullable options to be selectable, you can enable the `canSelectNullableOptions` input.
+The default value for the input can be controlled application-wide through the `MAT_SELECT_CONFIG`
+injection token.
+
+<!-- example(select-selectable-null) -->
+
 ### Creating groups of options
 
 The `<mat-optgroup>` element can be used to group common options under a subheading. The name of the
diff --git a/src/material/select/select.scss b/src/material/select/select.scss
index 9f8e740fd283..2586a9f7b4a0 100644
--- a/src/material/select/select.scss
+++ b/src/material/select/select.scss
@@ -41,6 +41,13 @@ $scale: 0.75 !default;
     tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
     @include token-utils.create-token-slot(color, disabled-trigger-text-color);
   }
+
+  .mat-mdc-select-placeholder {
+    @include token-utils.use-tokens(
+      tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
+      @include token-utils.create-token-slot(color, disabled-trigger-text-color);
+    }
+  }
 }
 
 .mat-mdc-select-trigger {
@@ -178,6 +185,7 @@ div.mat-mdc-select-panel {
     @include token-utils.create-token-slot(color, placeholder-text-color);
   }
 
+  .mat-form-field-no-animations &,
   ._mat-animation-noopable & {
     transition: none;
   }
diff --git a/src/material/select/select.spec.ts b/src/material/select/select.spec.ts
index 9fce7d326cba..bb7ca95eba22 100644
--- a/src/material/select/select.spec.ts
+++ b/src/material/select/select.spec.ts
@@ -220,7 +220,7 @@ describe('MatSelect', () => {
           fixture.detectChanges();
           const hint = fixture.debugElement.query(By.css('mat-hint')).nativeElement;
           expect(select.getAttribute('aria-describedby')).toBe(hint.getAttribute('id'));
-          expect(select.getAttribute('aria-describedby')).toMatch(/^mat-mdc-hint-\d+$/);
+          expect(select.getAttribute('aria-describedby')).toMatch(/^mat-mdc-hint-\w+\d+$/);
         });
 
         it('should support user binding to `aria-describedby`', () => {
@@ -3508,7 +3508,7 @@ describe('MatSelect', () => {
       expect(trigger.textContent).not.toContain('None');
     }));
 
-    it('should not mark the reset option as selected ', fakeAsync(() => {
+    it('should not mark the reset option as selected', fakeAsync(() => {
       options[5].click();
       fixture.detectChanges();
       flush();
@@ -3545,6 +3545,102 @@ describe('MatSelect', () => {
     });
   });
 
+  describe('allowing selection of nullable options', () => {
+    beforeEach(waitForAsync(() => configureMatSelectTestingModule([ResetValuesSelect])));
+
+    let fixture: ComponentFixture<ResetValuesSelect>;
+    let trigger: HTMLElement;
+    let formField: HTMLElement;
+    let options: NodeListOf<HTMLElement>;
+    let label: HTMLLabelElement;
+
+    beforeEach(fakeAsync(() => {
+      fixture = TestBed.createComponent(ResetValuesSelect);
+      fixture.componentInstance.canSelectNullableOptions = true;
+      fixture.detectChanges();
+      trigger = fixture.debugElement.query(By.css('.mat-mdc-select-trigger'))!.nativeElement;
+      formField = fixture.debugElement.query(By.css('.mat-mdc-form-field'))!.nativeElement;
+      label = formField.querySelector('label')!;
+
+      trigger.click();
+      fixture.detectChanges();
+      flush();
+
+      options = overlayContainerElement.querySelectorAll('mat-option') as NodeListOf<HTMLElement>;
+      options[0].click();
+      fixture.detectChanges();
+      flush();
+    }));
+
+    it('should select an option with an undefined value', fakeAsync(() => {
+      options[4].click();
+      fixture.detectChanges();
+      flush();
+
+      expect(fixture.componentInstance.control.value).toBe(undefined);
+      expect(fixture.componentInstance.select.selected).toBeTruthy();
+      expect(label.classList).toContain('mdc-floating-label--float-above');
+      expect(trigger.textContent).toContain('Undefined');
+    }));
+
+    it('should select an option with a null value', fakeAsync(() => {
+      options[5].click();
+      fixture.detectChanges();
+      flush();
+
+      expect(fixture.componentInstance.control.value).toBe(null);
+      expect(fixture.componentInstance.select.selected).toBeTruthy();
+      expect(label.classList).toContain('mdc-floating-label--float-above');
+      expect(trigger.textContent).toContain('Null');
+    }));
+
+    it('should select a blank option', fakeAsync(() => {
+      options[6].click();
+      fixture.detectChanges();
+      flush();
+
+      expect(fixture.componentInstance.control.value).toBe(undefined);
+      expect(fixture.componentInstance.select.selected).toBeTruthy();
+      expect(label.classList).toContain('mdc-floating-label--float-above');
+      expect(trigger.textContent).toContain('None');
+    }));
+
+    it('should mark a nullable option as selected', fakeAsync(() => {
+      options[5].click();
+      fixture.detectChanges();
+      flush();
+
+      fixture.componentInstance.select.open();
+      fixture.detectChanges();
+      flush();
+
+      expect(options[5].classList).toContain('mdc-list-item--selected');
+    }));
+
+    it('should not reset when any other falsy option is selected', fakeAsync(() => {
+      options[3].click();
+      fixture.detectChanges();
+      flush();
+
+      expect(fixture.componentInstance.control.value).toBe(false);
+      expect(fixture.componentInstance.select.selected).toBeTruthy();
+      expect(label.classList).toContain('mdc-floating-label--float-above');
+      expect(trigger.textContent).toContain('Falsy');
+    }));
+
+    it('should consider the nullable values as selected when resetting the form control', () => {
+      expect(label.classList).toContain('mdc-floating-label--float-above');
+
+      fixture.componentInstance.control.reset();
+      fixture.detectChanges();
+
+      expect(fixture.componentInstance.control.value).toBe(null);
+      expect(fixture.componentInstance.select.selected).toBeTruthy();
+      expect(label.classList).toContain('mdc-floating-label--float-above');
+      expect(trigger.textContent).toContain('Null');
+    });
+  });
+
   describe('with reset option and a form control', () => {
     let fixture: ComponentFixture<SelectWithResetOptionAndFormControl>;
     let options: HTMLElement[];
@@ -5057,7 +5153,7 @@ class BasicSelectWithTheming {
   template: `
     <mat-form-field>
       <mat-label>Select a food</mat-label>
-      <mat-select [formControl]="control">
+      <mat-select [formControl]="control" [canSelectNullableOptions]="canSelectNullableOptions">
         @for (food of foods; track food) {
           <mat-option [value]="food.value">{{ food.viewValue }}</mat-option>
         }
@@ -5076,7 +5172,8 @@ class ResetValuesSelect {
     {viewValue: 'Undefined'},
     {value: null, viewValue: 'Null'},
   ];
-  control = new FormControl('' as string | boolean | null);
+  control = new FormControl('' as string | boolean | null | undefined);
+  canSelectNullableOptions = false;
 
   @ViewChild(MatSelect) select: MatSelect;
 }
diff --git a/src/material/select/select.ts b/src/material/select/select.ts
index c0fb76b45e10..e99ce6b7d40b 100644
--- a/src/material/select/select.ts
+++ b/src/material/select/select.ts
@@ -7,6 +7,7 @@
  */
 
 import {
+  _IdGenerator,
   ActiveDescendantKeyManager,
   addAriaReferencedId,
   LiveAnnouncer,
@@ -96,8 +97,6 @@ import {
 } from './select-errors';
 import {NgClass} from '@angular/common';
 
-let nextUniqueId = 0;
-
 /** Injection token that determines the scroll handling while a select is open. */
 export const MAT_SELECT_SCROLL_STRATEGY = new InjectionToken<() => ScrollStrategy>(
   'mat-select-scroll-strategy',
@@ -128,7 +127,7 @@ export interface MatSelectConfig {
   /** Class or list of classes to be applied to the menu's overlay panel. */
   overlayPanelClass?: string | string[];
 
-  /** Wheter icon indicators should be hidden for single-selection. */
+  /** Whether icon indicators should be hidden for single-selection. */
   hideSingleSelectionIndicator?: boolean;
 
   /**
@@ -136,6 +135,12 @@ export interface MatSelectConfig {
    * If set to null or an empty string, the panel will grow to match the longest option's text.
    */
   panelWidth?: string | number | null;
+
+  /**
+   * Whether nullable options can be selected by default.
+   * See `MatSelect.canSelectNullableOptions` for more information.
+   */
+  canSelectNullableOptions?: boolean;
 }
 
 /** Injection token that can be used to provide the default options the select module. */
@@ -215,11 +220,12 @@ export class MatSelect
   protected _changeDetectorRef = inject(ChangeDetectorRef);
   readonly _elementRef = inject(ElementRef);
   private _dir = inject(Directionality, {optional: true});
+  private _idGenerator = inject(_IdGenerator);
   protected _parentFormField = inject<MatFormField>(MAT_FORM_FIELD, {optional: true});
   ngControl = inject(NgControl, {self: true, optional: true})!;
   private _liveAnnouncer = inject(LiveAnnouncer);
-
   protected _defaultOptions = inject(MAT_SELECT_CONFIG, {optional: true});
+  private _initialized = new Subject();
 
   /** All of the defined select options. */
   @ContentChildren(MatOption, {descendants: true}) options: QueryList<MatOption>;
@@ -312,7 +318,7 @@ export class MatSelect
   private _compareWith = (o1: any, o2: any) => o1 === o2;
 
   /** Unique id for this input. */
-  private _uid = `mat-select-${nextUniqueId++}`;
+  private _uid = this._idGenerator.getId('mat-select-');
 
   /** Current `aria-labelledby` value for the select trigger. */
   private _triggerAriaLabelledBy: string | null = null;
@@ -367,7 +373,7 @@ export class MatSelect
   _onTouched = () => {};
 
   /** ID for the DOM node containing the select's value. */
-  _valueId = `mat-select-value-${nextUniqueId++}`;
+  _valueId = this._idGenerator.getId('mat-select-value-');
 
   /** Emits when the panel element is finished transforming in. */
   readonly _panelDoneAnimatingStream = new Subject<string>();
@@ -552,7 +558,14 @@ export class MatSelect
       ? this._defaultOptions.panelWidth
       : 'auto';
 
-  private _initialized = new Subject();
+  /**
+   * By default selecting an option with a `null` or `undefined` value will reset the select's
+   * value. Enable this option if the reset behavior doesn't match your requirements and instead
+   * the nullable options should become selected. The value of this input can be controlled app-wide
+   * using the `MAT_SELECT_CONFIG` injection token.
+   */
+  @Input({transform: booleanAttribute})
+  canSelectNullableOptions: boolean = this._defaultOptions?.canSelectNullableOptions ?? false;
 
   /** Combined stream of all of the child options' change events. */
   readonly optionSelectionChanges: Observable<MatOptionSelectionChange> = defer(() => {
@@ -1098,7 +1111,10 @@ export class MatSelect
 
       try {
         // Treat null as a special reset value.
-        return option.value != null && this._compareWith(option.value, value);
+        return (
+          (option.value != null || this.canSelectNullableOptions) &&
+          this._compareWith(option.value, value)
+        );
       } catch (error) {
         if (typeof ngDevMode === 'undefined' || ngDevMode) {
           // Notify developers of errors in their comparator.
@@ -1243,7 +1259,7 @@ export class MatSelect
   private _onSelect(option: MatOption, isUserInput: boolean): void {
     const wasSelected = this._selectionModel.isSelected(option);
 
-    if (option.value == null && !this._multiple) {
+    if (!this.canSelectNullableOptions && option.value == null && !this._multiple) {
       option.deselect();
       this._selectionModel.clear();
 
diff --git a/src/material/select/testing/select-harness.spec.ts b/src/material/select/testing/select-harness.spec.ts
index b08b9a8d992e..01a48d30617d 100644
--- a/src/material/select/testing/select-harness.spec.ts
+++ b/src/material/select/testing/select-harness.spec.ts
@@ -306,7 +306,6 @@ describe('MatSelectHarness', () => {
       </mat-select>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [MatSelectModule, MatFormFieldModule, ReactiveFormsModule],
 })
 class SelectHarnessTest {
diff --git a/src/material/sidenav/drawer-animations.ts b/src/material/sidenav/drawer-animations.ts
index 10586a7840bb..c4c3b7570b25 100644
--- a/src/material/sidenav/drawer-animations.ts
+++ b/src/material/sidenav/drawer-animations.ts
@@ -17,6 +17,8 @@ import {
 /**
  * Animations used by the Material drawers.
  * @docs-private
+ * @deprecated No longer used, will be removed.
+ * @breaking-change 21.0.0
  */
 export const matDrawerAnimations: {
   readonly transformDrawer: AnimationTriggerMetadata;
diff --git a/src/material/sidenav/drawer.scss b/src/material/sidenav/drawer.scss
index f7e89895a873..2583dbb27603 100644
--- a/src/material/sidenav/drawer.scss
+++ b/src/material/sidenav/drawer.scss
@@ -109,6 +109,10 @@ $drawer-over-drawer-z-index: 4;
   height: 100%;
   overflow: auto;
 
+  &.mat-drawer-content-hidden {
+    opacity: 0;
+  }
+
   .mat-drawer-transition & {
     transition: {
       duration: variables.$swift-ease-out-duration;
@@ -195,15 +199,27 @@ $drawer-over-drawer-z-index: 4;
     }
   }
 
-  // Usually the `visibility: hidden` added by the animation is enough to prevent focus from
-  // entering the hidden drawer content, but children with their own `visibility` can override it.
-  // This is a fallback that completely hides the content when the element becomes hidden.
-  // Note that we can't do this in the animation definition, because the style gets recomputed too
-  // late, breaking the animation because Angular didn't have time to figure out the target
-  // transform. This can also be achieved with JS, but it has issues when starting an
-  // animation before the previous one has finished.
-  &[style*='visibility: hidden'] {
-    display: none;
+  .mat-drawer-transition & {
+    transition: transform 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
+  }
+
+  &:not(.mat-drawer-opened):not(.mat-drawer-animating) {
+    // Stops the sidenav from poking out (e.g. with the box shadow) while it's off-screen.
+    // We can't use `display` because it interrupts the transition and `transition-behavior`
+    // isn't available in all browsers.
+    visibility: hidden;
+    box-shadow: none;
+
+    // The `visibility` above should prevent focus from entering the sidenav, but if a child
+    // element has `visibility`, it'll override the inherited value. This guarantees that the
+    // content won't be focusable.
+    .mat-drawer-inner-container {
+      display: none;
+    }
+  }
+
+  &.mat-drawer-opened {
+    transform: none;
   }
 }
 
diff --git a/src/material/sidenav/drawer.spec.ts b/src/material/sidenav/drawer.spec.ts
index 71cbbc619868..144207131276 100644
--- a/src/material/sidenav/drawer.spec.ts
+++ b/src/material/sidenav/drawer.spec.ts
@@ -1207,7 +1207,6 @@ describe('MatDrawerContainer', () => {
 /** Test component that contains an MatDrawerContainer but no MatDrawer. */
 @Component({
   template: `<mat-drawer-container></mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerContainerNoDrawerTestApp {}
@@ -1219,7 +1218,6 @@ class DrawerContainerNoDrawerTestApp {}
       <mat-drawer position="start"></mat-drawer>
       <mat-drawer position="end"></mat-drawer>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerContainerTwoDrawerTestApp {
@@ -1248,7 +1246,6 @@ class DrawerContainerTwoDrawerTestApp {
         <circle cx="50" cy="50" r="50"/>
       </svg>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class BasicTestApp {
@@ -1294,7 +1291,6 @@ class BasicTestApp {
         Closed Drawer.
       </mat-drawer>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerSetToOpenedFalse {}
@@ -1306,7 +1302,6 @@ class DrawerSetToOpenedFalse {}
         Closed Drawer.
       </mat-drawer>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerSetToOpenedTrue {
@@ -1320,7 +1315,6 @@ class DrawerSetToOpenedTrue {
         Closed Drawer.
       </mat-drawer>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerOpenBinding {
@@ -1333,7 +1327,6 @@ class DrawerOpenBinding {
       <mat-drawer #drawer1 [position]="drawer1Position"></mat-drawer>
       <mat-drawer #drawer2 [position]="drawer2Position"></mat-drawer>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerDynamicPosition {
@@ -1351,7 +1344,6 @@ class DrawerDynamicPosition {
       </mat-drawer>
       <input type="text" class="input2"/>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerWithFocusableElements {
@@ -1366,7 +1358,6 @@ class DrawerWithFocusableElements {
         <button disabled>Not focusable</button>
       </mat-drawer>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerWithoutFocusableElements {}
@@ -1379,7 +1370,6 @@ class DrawerWithoutFocusableElements {}
       }
     </mat-drawer-container>
   `,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerDelayed {
@@ -1394,7 +1384,6 @@ class DrawerDelayed {
         <mat-drawer [mode]="mode" style="width:100px"></mat-drawer>
       }
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerContainerStateChangesTestApp {
@@ -1414,7 +1403,6 @@ class DrawerContainerStateChangesTestApp {
         <div [style.width.px]="fillerWidth" style="height: 200px; background: red;"></div>
       </mat-drawer>
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class AutosizeDrawer {
@@ -1430,7 +1418,6 @@ class AutosizeDrawer {
       <mat-drawer-content>Content</mat-drawer-content>
     </mat-drawer-container>
   `,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class DrawerContainerWithContent {
@@ -1446,7 +1433,6 @@ class DrawerContainerWithContent {
         <mat-drawer #drawer>Drawer</mat-drawer>
       }
     </mat-drawer-container>`,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class IndirectDescendantDrawer {
@@ -1465,7 +1451,6 @@ class IndirectDescendantDrawer {
       </mat-drawer-content>
     </mat-drawer-container>
   `,
-  standalone: true,
   imports: [MatSidenavModule, A11yModule],
 })
 class NestedDrawerContainers {
diff --git a/src/material/sidenav/drawer.ts b/src/material/sidenav/drawer.ts
index eb3c78baec7a..59b4f0aa3e73 100644
--- a/src/material/sidenav/drawer.ts
+++ b/src/material/sidenav/drawer.ts
@@ -5,7 +5,6 @@
  * Use of this source code is governed by an MIT-style license that can be
  * found in the LICENSE file at https://angular.dev/license
  */
-import {AnimationEvent} from '@angular/animations';
 import {
   FocusMonitor,
   FocusOrigin,
@@ -20,10 +19,8 @@ import {Platform} from '@angular/cdk/platform';
 import {CdkScrollable, ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
 import {DOCUMENT} from '@angular/common';
 import {
-  AfterContentChecked,
   AfterContentInit,
   afterNextRender,
-  AfterRenderPhase,
   AfterViewInit,
   ANIMATION_MODULE_TYPE,
   ChangeDetectionStrategy,
@@ -42,21 +39,12 @@ import {
   OnDestroy,
   Output,
   QueryList,
+  Renderer2,
   ViewChild,
   ViewEncapsulation,
 } from '@angular/core';
 import {fromEvent, merge, Observable, Subject} from 'rxjs';
-import {
-  debounceTime,
-  distinctUntilChanged,
-  filter,
-  map,
-  mapTo,
-  startWith,
-  take,
-  takeUntil,
-} from 'rxjs/operators';
-import {matDrawerAnimations} from './drawer-animations';
+import {debounceTime, filter, map, mapTo, startWith, take, takeUntil} from 'rxjs/operators';
 
 /**
  * Throws an exception when two MatDrawer are matching the same position.
@@ -102,6 +90,7 @@ export function MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY(): boolean {
     'class': 'mat-drawer-content',
     '[style.margin-left.px]': '_container._contentMargins.left',
     '[style.margin-right.px]': '_container._contentMargins.right',
+    '[class.mat-drawer-content-hidden]': '_shouldBeHidden()',
   },
   changeDetection: ChangeDetectionStrategy.OnPush,
   encapsulation: ViewEncapsulation.None,
@@ -113,6 +102,7 @@ export function MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY(): boolean {
   ],
 })
 export class MatDrawerContent extends CdkScrollable implements AfterContentInit {
+  private _platform = inject(Platform);
   private _changeDetectorRef = inject(ChangeDetectorRef);
   _container = inject(MatDrawerContainer);
 
@@ -131,6 +121,24 @@ export class MatDrawerContent extends CdkScrollable implements AfterContentInit
       this._changeDetectorRef.markForCheck();
     });
   }
+
+  /** Determines whether the content element should be hidden from the user. */
+  protected _shouldBeHidden(): boolean {
+    // In some modes the content is pushed based on the width of the opened sidenavs, however on
+    // the server we can't measure the sidenav so the margin is always zero. This can cause the
+    // content to jump around when it's rendered on the server and hydrated on the client. We
+    // avoid it by hiding the content on the initial render and then showing it once the sidenav
+    // has been measured on the client.
+    if (this._platform.isBrowser) {
+      return false;
+    }
+
+    const {start, end} = this._container;
+    return (
+      (start != null && start.mode !== 'over' && start.opened) ||
+      (end != null && end.mode !== 'over' && end.opened)
+    );
+  }
 }
 
 /**
@@ -140,7 +148,6 @@ export class MatDrawerContent extends CdkScrollable implements AfterContentInit
   selector: 'mat-drawer',
   exportAs: 'matDrawer',
   templateUrl: 'drawer.html',
-  animations: [matDrawerAnimations.transformDrawer],
   host: {
     'class': 'mat-drawer',
     // must prevent the browser from aligning text based on value
@@ -149,31 +156,30 @@ export class MatDrawerContent extends CdkScrollable implements AfterContentInit
     '[class.mat-drawer-over]': 'mode === "over"',
     '[class.mat-drawer-push]': 'mode === "push"',
     '[class.mat-drawer-side]': 'mode === "side"',
-    '[class.mat-drawer-opened]': 'opened',
+    // The styles that render the sidenav off-screen come from the drawer container. Prior to #30235
+    // this was also done by the animations module which some internal tests seem to depend on.
+    // Simulate it by toggling the `hidden` attribute instead.
+    '[style.visibility]': '(!_container && !opened) ? "hidden" : null',
     'tabIndex': '-1',
-    '[@transform]': '_animationState',
-    '(@transform.start)': '_animationStarted.next($event)',
-    '(@transform.done)': '_animationEnd.next($event)',
   },
   changeDetection: ChangeDetectionStrategy.OnPush,
   encapsulation: ViewEncapsulation.None,
   imports: [CdkScrollable],
 })
-export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy {
+export class MatDrawer implements AfterViewInit, OnDestroy {
   private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
   private _focusTrapFactory = inject(FocusTrapFactory);
   private _focusMonitor = inject(FocusMonitor);
   private _platform = inject(Platform);
   private _ngZone = inject(NgZone);
+  private _renderer = inject(Renderer2);
   private readonly _interactivityChecker = inject(InteractivityChecker);
   private _doc = inject(DOCUMENT, {optional: true})!;
   _container? = inject<MatDrawerContainer>(MAT_DRAWER_CONTAINER, {optional: true});
 
   private _focusTrap: FocusTrap | null = null;
   private _elementFocusedBeforeDrawerWasOpened: HTMLElement | null = null;
-
-  /** Whether the drawer is initialized. Used for disabling the initial animation. */
-  private _enableAnimations = false;
+  private _eventCleanups: (() => void)[];
 
   /** Whether the view of the component has been attached. */
   private _isAttached: boolean;
@@ -271,13 +277,10 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
   private _openedVia: FocusOrigin | null;
 
   /** Emits whenever the drawer has started animating. */
-  readonly _animationStarted = new Subject<AnimationEvent>();
+  readonly _animationStarted = new Subject();
 
   /** Emits whenever the drawer is done animating. */
-  readonly _animationEnd = new Subject<AnimationEvent>();
-
-  /** Current state of the sidenav animation. */
-  _animationState: 'open-instant' | 'open' | 'void' = 'void';
+  readonly _animationEnd = new Subject();
 
   /** Event emitted when the drawer open state is changed. */
   @Output() readonly openedChange: EventEmitter<boolean> =
@@ -294,7 +297,7 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
   /** Event emitted when the drawer has started opening. */
   @Output()
   readonly openedStart: Observable<void> = this._animationStarted.pipe(
-    filter(e => e.fromState !== e.toState && e.toState.indexOf('open') === 0),
+    filter(() => this.opened),
     mapTo(undefined),
   );
 
@@ -308,7 +311,7 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
   /** Event emitted when the drawer has started closing. */
   @Output()
   readonly closedStart: Observable<void> = this._animationStarted.pipe(
-    filter(e => e.fromState !== e.toState && e.toState === 'void'),
+    filter(() => !this.opened),
     mapTo(undefined),
   );
 
@@ -351,7 +354,8 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
      * and we don't have close disabled.
      */
     this._ngZone.runOutsideAngular(() => {
-      (fromEvent(this._elementRef.nativeElement, 'keydown') as Observable<KeyboardEvent>)
+      const element = this._elementRef.nativeElement;
+      (fromEvent(element, 'keydown') as Observable<KeyboardEvent>)
         .pipe(
           filter(event => {
             return event.keyCode === ESCAPE && !this.disableClose && !hasModifierKey(event);
@@ -365,26 +369,17 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
             event.preventDefault();
           }),
         );
+
+      this._eventCleanups = [
+        this._renderer.listen(element, 'transitionrun', this._handleTransitionEvent),
+        this._renderer.listen(element, 'transitionend', this._handleTransitionEvent),
+        this._renderer.listen(element, 'transitioncancel', this._handleTransitionEvent),
+      ];
     });
 
-    // We need a Subject with distinctUntilChanged, because the `done` event
-    // fires twice on some browsers. See https://github.com/angular/angular/issues/24084
-    this._animationEnd
-      .pipe(
-        distinctUntilChanged((x, y) => {
-          return x.fromState === y.fromState && x.toState === y.toState;
-        }),
-      )
-      .subscribe((event: AnimationEvent) => {
-        const {fromState, toState} = event;
-
-        if (
-          (toState.indexOf('open') === 0 && fromState === 'void') ||
-          (toState === 'void' && fromState.indexOf('open') === 0)
-        ) {
-          this.openedChange.emit(this._opened);
-        }
-      });
+    this._animationEnd.subscribe(() => {
+      this.openedChange.emit(this._opened);
+    });
   }
 
   /**
@@ -398,13 +393,13 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
       // The tabindex attribute should be removed to avoid navigating to that element again
       this._ngZone.runOutsideAngular(() => {
         const callback = () => {
-          element.removeEventListener('blur', callback);
-          element.removeEventListener('mousedown', callback);
+          cleanupBlur();
+          cleanupMousedown();
           element.removeAttribute('tabindex');
         };
 
-        element.addEventListener('blur', callback);
-        element.addEventListener('mousedown', callback);
+        const cleanupBlur = this._renderer.listen(element, 'blur', callback);
+        const cleanupMousedown = this._renderer.listen(element, 'mousedown', callback);
       });
     }
     element.focus(options);
@@ -503,17 +498,8 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
     }
   }
 
-  ngAfterContentChecked() {
-    // Enable the animations after the lifecycle hooks have run, in order to avoid animating
-    // drawers that are open by default. When we're on the server, we shouldn't enable the
-    // animations, because we don't want the drawer to animate the first time the user sees
-    // the page.
-    if (this._platform.isBrowser) {
-      this._enableAnimations = true;
-    }
-  }
-
   ngOnDestroy() {
+    this._eventCleanups.forEach(cleanup => cleanup());
     this._focusTrap?.destroy();
     this._anchor?.remove();
     this._anchor = null;
@@ -583,15 +569,28 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
     restoreFocus: boolean,
     focusOrigin: Exclude<FocusOrigin, null>,
   ): Promise<MatDrawerToggleResult> {
+    if (isOpen === this._opened) {
+      return Promise.resolve(isOpen ? 'open' : 'close');
+    }
+
     this._opened = isOpen;
 
-    if (isOpen) {
-      this._animationState = this._enableAnimations ? 'open' : 'open-instant';
+    if (this._container?._transitionsEnabled) {
+      // Note: it's importatnt to set this as early as possible,
+      // otherwise the animation can look glitchy in some cases.
+      this._setIsAnimating(true);
     } else {
-      this._animationState = 'void';
-      if (restoreFocus) {
-        this._restoreFocus(focusOrigin);
-      }
+      // Simulate the animation events if animations are disabled.
+      setTimeout(() => {
+        this._animationStarted.next();
+        this._animationEnd.next();
+      });
+    }
+
+    this._elementRef.nativeElement.classList.toggle('mat-drawer-opened', isOpen);
+
+    if (!isOpen && restoreFocus) {
+      this._restoreFocus(focusOrigin);
     }
 
     // Needed to ensure that the closing sequence fires off correctly.
@@ -603,8 +602,13 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
     });
   }
 
+  /** Toggles whether the drawer is currently animating. */
+  private _setIsAnimating(isAnimating: boolean) {
+    this._elementRef.nativeElement.classList.toggle('mat-drawer-animating', isAnimating);
+  }
+
   _getWidth(): number {
-    return this._elementRef.nativeElement ? this._elementRef.nativeElement.offsetWidth || 0 : 0;
+    return this._elementRef.nativeElement.offsetWidth || 0;
   }
 
   /** Updates the enabled state of the focus trap. */
@@ -642,6 +646,27 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
       this._anchor.parentNode!.insertBefore(element, this._anchor);
     }
   }
+
+  /** Event handler for animation events. */
+  private _handleTransitionEvent = (event: TransitionEvent) => {
+    const element = this._elementRef.nativeElement;
+
+    if (event.target === element) {
+      this._ngZone.run(() => {
+        if (event.type === 'transitionrun') {
+          this._animationStarted.next(event);
+        } else {
+          // Don't toggle the animating state on `transitioncancel` since another animation should
+          // start afterwards. This prevents the drawer from blinking if an animation is interrupted.
+          if (event.type === 'transitionend') {
+            this._setIsAnimating(false);
+          }
+
+          this._animationEnd.next(event);
+        }
+      });
+    }
+  };
 }
 
 /**
@@ -675,6 +700,7 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
   private _ngZone = inject(NgZone);
   private _changeDetectorRef = inject(ChangeDetectorRef);
   private _animationMode = inject(ANIMATION_MODULE_TYPE, {optional: true});
+  _transitionsEnabled = false;
 
   /** All drawers in the container. Includes drawers from inside nested containers. */
   @ContentChildren(MatDrawer, {
@@ -772,6 +798,7 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
   constructor(...args: unknown[]);
 
   constructor() {
+    const platform = inject(Platform);
     const viewportRuler = inject(ViewportRuler);
 
     // If a `Dir` directive exists up the tree, listen direction changes
@@ -787,6 +814,17 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
       .change()
       .pipe(takeUntil(this._destroyed))
       .subscribe(() => this.updateContentMargins());
+
+    if (this._animationMode !== 'NoopAnimations' && platform.isBrowser) {
+      this._ngZone.runOutsideAngular(() => {
+        // Enable the animations after a delay in order to skip
+        // the initial transition if a drawer is open by default.
+        setTimeout(() => {
+          this._element.nativeElement.classList.add('mat-drawer-transition');
+          this._transitionsEnabled = true;
+        }, 200);
+      });
+    }
   }
 
   ngAfterContentInit() {
@@ -910,21 +948,10 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
    * is properly hidden.
    */
   private _watchDrawerToggle(drawer: MatDrawer): void {
-    drawer._animationStarted
-      .pipe(
-        filter((event: AnimationEvent) => event.fromState !== event.toState),
-        takeUntil(this._drawers.changes),
-      )
-      .subscribe((event: AnimationEvent) => {
-        // Set the transition class on the container so that the animations occur. This should not
-        // be set initially because animations should only be triggered via a change in state.
-        if (event.toState !== 'open-instant' && this._animationMode !== 'NoopAnimations') {
-          this._element.nativeElement.classList.add('mat-drawer-transition');
-        }
-
-        this.updateContentMargins();
-        this._changeDetectorRef.markForCheck();
-      });
+    drawer._animationStarted.pipe(takeUntil(this._drawers.changes)).subscribe(() => {
+      this.updateContentMargins();
+      this._changeDetectorRef.markForCheck();
+    });
 
     if (drawer.mode !== 'side') {
       drawer.openedChange
@@ -938,31 +965,21 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
    * re-validate drawers when the position changes.
    */
   private _watchDrawerPosition(drawer: MatDrawer): void {
-    if (!drawer) {
-      return;
-    }
     // NOTE: We need to wait for the microtask queue to be empty before validating,
     // since both drawers may be swapping positions at the same time.
     drawer.onPositionChanged.pipe(takeUntil(this._drawers.changes)).subscribe(() => {
-      afterNextRender(
-        () => {
-          this._validateDrawers();
-        },
-        {injector: this._injector, phase: AfterRenderPhase.Read},
-      );
+      afterNextRender({read: () => this._validateDrawers()}, {injector: this._injector});
     });
   }
 
   /** Subscribes to changes in drawer mode so we can run change detection. */
   private _watchDrawerMode(drawer: MatDrawer): void {
-    if (drawer) {
-      drawer._modeChanged
-        .pipe(takeUntil(merge(this._drawers.changes, this._destroyed)))
-        .subscribe(() => {
-          this.updateContentMargins();
-          this._changeDetectorRef.markForCheck();
-        });
-    }
+    drawer._modeChanged
+      .pipe(takeUntil(merge(this._drawers.changes, this._destroyed)))
+      .subscribe(() => {
+        this.updateContentMargins();
+        this._changeDetectorRef.markForCheck();
+      });
   }
 
   /** Toggles the 'mat-drawer-opened' class on the main 'mat-drawer-container' element. */
diff --git a/src/material/sidenav/sidenav.spec.ts b/src/material/sidenav/sidenav.spec.ts
index 93cc5b9599ca..d325d20a51ad 100644
--- a/src/material/sidenav/sidenav.spec.ts
+++ b/src/material/sidenav/sidenav.spec.ts
@@ -101,7 +101,6 @@ describe('MatSidenav', () => {
         Some content.
       </mat-sidenav-content>
     </mat-sidenav-container>`,
-  standalone: true,
   imports: [MatSidenavModule],
 })
 class SidenavWithFixedPosition {
@@ -120,7 +119,6 @@ class SidenavWithFixedPosition {
       }
       <mat-sidenav-content>Some content.</mat-sidenav-content>
     </mat-sidenav-container>`,
-  standalone: true,
   imports: [MatSidenavModule],
 })
 class IndirectDescendantSidenav {
@@ -139,7 +137,6 @@ class IndirectDescendantSidenav {
       </mat-sidenav-content>
     </mat-sidenav-container>
   `,
-  standalone: true,
   imports: [MatSidenavModule],
 })
 class NestedSidenavContainers {
diff --git a/src/material/sidenav/sidenav.ts b/src/material/sidenav/sidenav.ts
index e7214532f921..0dbfe6b6ada4 100644
--- a/src/material/sidenav/sidenav.ts
+++ b/src/material/sidenav/sidenav.ts
@@ -16,7 +16,6 @@ import {
   QueryList,
 } from '@angular/core';
 import {MatDrawer, MatDrawerContainer, MatDrawerContent, MAT_DRAWER_CONTAINER} from './drawer';
-import {matDrawerAnimations} from './drawer-animations';
 import {
   BooleanInput,
   coerceBooleanProperty,
@@ -30,8 +29,6 @@ import {CdkScrollable} from '@angular/cdk/scrolling';
   template: '<ng-content></ng-content>',
   host: {
     'class': 'mat-drawer-content mat-sidenav-content',
-    '[style.margin-left.px]': '_container._contentMargins.left',
-    '[style.margin-right.px]': '_container._contentMargins.right',
   },
   changeDetection: ChangeDetectionStrategy.OnPush,
   encapsulation: ViewEncapsulation.None,
@@ -48,7 +45,6 @@ export class MatSidenavContent extends MatDrawerContent {}
   selector: 'mat-sidenav',
   exportAs: 'matSidenav',
   templateUrl: 'drawer.html',
-  animations: [matDrawerAnimations.transformDrawer],
   host: {
     'class': 'mat-drawer mat-sidenav',
     'tabIndex': '-1',
@@ -58,7 +54,6 @@ export class MatSidenavContent extends MatDrawerContent {}
     '[class.mat-drawer-over]': 'mode === "over"',
     '[class.mat-drawer-push]': 'mode === "push"',
     '[class.mat-drawer-side]': 'mode === "side"',
-    '[class.mat-drawer-opened]': 'opened',
     '[class.mat-sidenav-fixed]': 'fixedInViewport',
     '[style.top.px]': 'fixedInViewport ? fixedTopGap : null',
     '[style.bottom.px]': 'fixedInViewport ? fixedBottomGap : null',
diff --git a/src/material/sidenav/testing/sidenav-harness.spec.ts b/src/material/sidenav/testing/sidenav-harness.spec.ts
index 33d5db19b037..14d42b2761e5 100644
--- a/src/material/sidenav/testing/sidenav-harness.spec.ts
+++ b/src/material/sidenav/testing/sidenav-harness.spec.ts
@@ -176,7 +176,6 @@ describe('MatSidenavHarness', () => {
       <mat-drawer-content>Content</mat-drawer-content>
     </mat-drawer-container>
   `,
-  standalone: true,
   imports: [MatSidenavModule],
 })
 class DrawerHarnessTest {
@@ -196,7 +195,6 @@ class DrawerHarnessTest {
       <mat-sidenav-content>Content</mat-sidenav-content>
     </mat-sidenav-container>
   `,
-  standalone: true,
   imports: [MatSidenavModule],
 })
 class SidenavHarnessTest {}
diff --git a/src/material/slide-toggle/slide-toggle-config.ts b/src/material/slide-toggle/slide-toggle-config.ts
index 359cec3b6bc1..44e3007fcc51 100644
--- a/src/material/slide-toggle/slide-toggle-config.ts
+++ b/src/material/slide-toggle/slide-toggle-config.ts
@@ -15,10 +15,10 @@ export interface MatSlideToggleDefaultOptions {
 
   /**
    * Default theme color of the slide toggle. This API is supported in M2 themes only,
-   * it has no effect in M3 themes.
+   * it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/slide-toggle/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   color?: ThemePalette;
 
diff --git a/src/material/slide-toggle/slide-toggle.spec.ts b/src/material/slide-toggle/slide-toggle.spec.ts
index 1433026fadc4..facc0f15038d 100644
--- a/src/material/slide-toggle/slide-toggle.spec.ts
+++ b/src/material/slide-toggle/slide-toggle.spec.ts
@@ -173,7 +173,7 @@ describe('MatSlideToggle without forms', () => {
       fixture.detectChanges();
 
       // Once the id binding is set to null, the id property should auto-generate a unique id.
-      expect(buttonElement.id).toMatch(/mat-mdc-slide-toggle-\d+-button/);
+      expect(buttonElement.id).toMatch(/mat-mdc-slide-toggle-\w+\d+-button/);
     });
 
     it('should forward the tabIndex to the underlying element', () => {
@@ -235,7 +235,7 @@ describe('MatSlideToggle without forms', () => {
 
       // We fall back to pointing to the label if a value isn't provided.
       expect(buttonElement.getAttribute('aria-labelledby')).toMatch(
-        /mat-mdc-slide-toggle-\d+-label/,
+        /mat-mdc-slide-toggle-\w+\d+-label/,
       );
     });
 
@@ -883,7 +883,6 @@ describe('MatSlideToggle with forms', () => {
       (click)="onSlideClick($event)">
       <span>Test Slide Toggle</span>
     </mat-slide-toggle>`,
-  standalone: true,
   imports: [MatSlideToggleModule, BidiModule],
 })
 class SlideToggleBasic {
@@ -918,7 +917,6 @@ class SlideToggleBasic {
       <mat-slide-toggle name="slide" ngModel [required]="isRequired">Required</mat-slide-toggle>
       <button type="submit"></button>
     </form>`,
-  standalone: true,
   imports: [MatSlideToggleModule, FormsModule, ReactiveFormsModule],
 })
 class SlideToggleWithForm {
@@ -929,7 +927,6 @@ class SlideToggleWithForm {
 @Component({
   template: `<mat-slide-toggle [(ngModel)]="modelValue" [disabled]="isDisabled"
                                [checked]="isChecked"></mat-slide-toggle>`,
-  standalone: true,
   imports: [MatSlideToggleModule, FormsModule, ReactiveFormsModule],
 })
 class SlideToggleWithModel {
@@ -940,7 +937,6 @@ class SlideToggleWithModel {
 
 @Component({
   template: `<mat-slide-toggle checked disabled>Label</mat-slide-toggle>`,
-  standalone: true,
   imports: [MatSlideToggleModule, BidiModule],
 })
 class SlideToggleCheckedAndDisabledAttr {}
@@ -950,7 +946,6 @@ class SlideToggleCheckedAndDisabledAttr {}
     <mat-slide-toggle [formControl]="formControl">
       <span>Test Slide Toggle</span>
     </mat-slide-toggle>`,
-  standalone: true,
   imports: [MatSlideToggleModule, FormsModule, ReactiveFormsModule],
 })
 class SlideToggleWithFormControl {
@@ -959,7 +954,6 @@ class SlideToggleWithFormControl {
 
 @Component({
   template: `<mat-slide-toggle tabindex="5" [disabled]="disabled"></mat-slide-toggle>`,
-  standalone: true,
   imports: [MatSlideToggleModule, BidiModule],
 })
 class SlideToggleWithTabindexAttr {
@@ -968,7 +962,6 @@ class SlideToggleWithTabindexAttr {
 
 @Component({
   template: `<mat-slide-toggle>{{label}}</mat-slide-toggle>`,
-  standalone: true,
   imports: [MatSlideToggleModule, BidiModule],
 })
 class SlideToggleWithoutLabel {
@@ -977,7 +970,6 @@ class SlideToggleWithoutLabel {
 
 @Component({
   template: `<mat-slide-toggle [(ngModel)]="checked" (change)="onChange()"></mat-slide-toggle>`,
-  standalone: true,
   imports: [MatSlideToggleModule, FormsModule, ReactiveFormsModule],
 })
 class SlideToggleWithModelAndChangeEvent {
@@ -987,7 +979,6 @@ class SlideToggleWithModelAndChangeEvent {
 
 @Component({
   template: `<mat-slide-toggle><some-text></some-text></mat-slide-toggle>`,
-  standalone: true,
   imports: [MatSlideToggleModule, BidiModule],
 })
 class SlideToggleProjectedLabel {}
@@ -995,7 +986,6 @@ class SlideToggleProjectedLabel {}
 @Component({
   selector: 'some-text',
   template: `<span>{{text}}</span>`,
-  standalone: true,
   imports: [MatSlideToggleModule, BidiModule],
 })
 class TextBindingComponent {
@@ -1006,7 +996,6 @@ class TextBindingComponent {
   template: `
     <mat-slide-toggle aria-label="Slide toggle" aria-labelledby="something"></mat-slide-toggle>
   `,
-  standalone: true,
   imports: [MatSlideToggleModule, BidiModule],
 })
 class SlideToggleWithStaticAriaAttributes {}
diff --git a/src/material/slide-toggle/slide-toggle.ts b/src/material/slide-toggle/slide-toggle.ts
index b5969838eea4..7d8a09bf97cc 100644
--- a/src/material/slide-toggle/slide-toggle.ts
+++ b/src/material/slide-toggle/slide-toggle.ts
@@ -35,7 +35,7 @@ import {
   ValidationErrors,
   Validator,
 } from '@angular/forms';
-import {FocusMonitor} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusMonitor} from '@angular/cdk/a11y';
 import {
   MAT_SLIDE_TOGGLE_DEFAULT_OPTIONS,
   MatSlideToggleDefaultOptions,
@@ -63,9 +63,6 @@ export class MatSlideToggleChange {
   ) {}
 }
 
-// Increasing integer for generating unique ids for slide-toggle components.
-let nextUniqueId = 0;
-
 @Component({
   selector: 'mat-slide-toggle',
   templateUrl: 'slide-toggle.html',
@@ -161,10 +158,10 @@ export class MatSlideToggle
   // the lack of type checking previously and assigning random strings.
   /**
    * Theme color of the slide toggle. This API is supported in M2 themes only,
-   * it has no effect in M3 themes.
+   * it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/slide-toggle/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: string | undefined;
 
@@ -220,7 +217,7 @@ export class MatSlideToggle
     this.tabIndex = tabIndex == null ? 0 : parseInt(tabIndex) || 0;
     this.color = defaults.color || 'accent';
     this._noopAnimations = animationMode === 'NoopAnimations';
-    this.id = this._uniqueId = `mat-mdc-slide-toggle-${++nextUniqueId}`;
+    this.id = this._uniqueId = inject(_IdGenerator).getId('mat-mdc-slide-toggle-');
     this.hideIcon = defaults.hideIcon ?? false;
     this.disabledInteractive = defaults.disabledInteractive ?? false;
     this._labelId = this._uniqueId + '-label';
diff --git a/src/material/slide-toggle/testing/slide-toggle-harness.spec.ts b/src/material/slide-toggle/testing/slide-toggle-harness.spec.ts
index d1aabd8a8819..aa2e6e64220d 100644
--- a/src/material/slide-toggle/testing/slide-toggle-harness.spec.ts
+++ b/src/material/slide-toggle/testing/slide-toggle-harness.spec.ts
@@ -190,7 +190,6 @@ describe('MatSlideToggleHarness', () => {
       </mat-slide-toggle>
       <span id="second-label">Second slide-toggle</span>
   `,
-  standalone: true,
   imports: [MatSlideToggleModule, ReactiveFormsModule],
 })
 class SlideToggleHarnessTest {
diff --git a/src/material/slider/slider-input.ts b/src/material/slider/slider-input.ts
index 23e76e9ef058..bbf72df06bea 100644
--- a/src/material/slider/slider-input.ts
+++ b/src/material/slider/slider-input.ts
@@ -19,6 +19,7 @@ import {
   numberAttribute,
   OnDestroy,
   Output,
+  Renderer2,
   signal,
 } from '@angular/core';
 import {ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR} from '@angular/forms';
@@ -87,6 +88,8 @@ export class MatSliderThumb implements _MatSliderThumb, OnDestroy, ControlValueA
   readonly _elementRef = inject<ElementRef<HTMLInputElement>>(ElementRef);
   readonly _cdr = inject(ChangeDetectorRef);
   protected _slider = inject<_MatSlider>(MAT_SLIDER);
+  private _platform = inject(Platform);
+  private _listenerCleanups: (() => void)[];
 
   @Input({transform: numberAttribute})
   get value(): number {
@@ -275,22 +278,22 @@ export class MatSliderThumb implements _MatSliderThumb, OnDestroy, ControlValueA
    */
   protected _isControlInitialized = false;
 
-  private _platform = inject(Platform);
-
   constructor(...args: unknown[]);
 
   constructor() {
+    const renderer = inject(Renderer2);
+
     this._ngZone.runOutsideAngular(() => {
-      this._hostElement.addEventListener('pointerdown', this._onPointerDown.bind(this));
-      this._hostElement.addEventListener('pointermove', this._onPointerMove.bind(this));
-      this._hostElement.addEventListener('pointerup', this._onPointerUp.bind(this));
+      this._listenerCleanups = [
+        renderer.listen(this._hostElement, 'pointerdown', this._onPointerDown.bind(this)),
+        renderer.listen(this._hostElement, 'pointermove', this._onPointerMove.bind(this)),
+        renderer.listen(this._hostElement, 'pointerup', this._onPointerUp.bind(this)),
+      ];
     });
   }
 
   ngOnDestroy(): void {
-    this._hostElement.removeEventListener('pointerdown', this._onPointerDown);
-    this._hostElement.removeEventListener('pointermove', this._onPointerMove);
-    this._hostElement.removeEventListener('pointerup', this._onPointerUp);
+    this._listenerCleanups.forEach(cleanup => cleanup());
     this._destroyed.next();
     this._destroyed.complete();
     this.dragStart.complete();
diff --git a/src/material/slider/slider-thumb.ts b/src/material/slider/slider-thumb.ts
index f5999aed1e8d..6d54c0274d95 100644
--- a/src/material/slider/slider-thumb.ts
+++ b/src/material/slider/slider-thumb.ts
@@ -15,6 +15,7 @@ import {
   Input,
   NgZone,
   OnDestroy,
+  Renderer2,
   ViewChild,
   ViewEncapsulation,
   inject,
@@ -53,6 +54,8 @@ export class MatSliderVisualThumb implements _MatSliderVisualThumb, AfterViewIni
   readonly _cdr = inject(ChangeDetectorRef);
   private readonly _ngZone = inject(NgZone);
   private _slider = inject<_MatSlider>(MAT_SLIDER);
+  private _renderer = inject(Renderer2);
+  private _listenerCleanups: (() => void)[] | undefined;
 
   /** Whether the slider displays a numeric value label upon pressing the thumb. */
   @Input() discrete: boolean;
@@ -122,26 +125,20 @@ export class MatSliderVisualThumb implements _MatSliderVisualThumb, AfterViewIni
     // of the NgZone to prevent Angular from needlessly running change detection.
     this._ngZone.runOutsideAngular(() => {
       const input = this._sliderInputEl!;
-      input.addEventListener('pointermove', this._onPointerMove);
-      input.addEventListener('pointerdown', this._onDragStart);
-      input.addEventListener('pointerup', this._onDragEnd);
-      input.addEventListener('pointerleave', this._onMouseLeave);
-      input.addEventListener('focus', this._onFocus);
-      input.addEventListener('blur', this._onBlur);
+      const renderer = this._renderer;
+      this._listenerCleanups = [
+        renderer.listen(input, 'pointermove', this._onPointerMove),
+        renderer.listen(input, 'pointerdown', this._onDragStart),
+        renderer.listen(input, 'pointerup', this._onDragEnd),
+        renderer.listen(input, 'pointerleave', this._onMouseLeave),
+        renderer.listen(input, 'focus', this._onFocus),
+        renderer.listen(input, 'blur', this._onBlur),
+      ];
     });
   }
 
   ngOnDestroy() {
-    const input = this._sliderInputEl;
-
-    if (input) {
-      input.removeEventListener('pointermove', this._onPointerMove);
-      input.removeEventListener('pointerdown', this._onDragStart);
-      input.removeEventListener('pointerup', this._onDragEnd);
-      input.removeEventListener('pointerleave', this._onMouseLeave);
-      input.removeEventListener('focus', this._onFocus);
-      input.removeEventListener('blur', this._onBlur);
-    }
+    this._listenerCleanups?.forEach(cleanup => cleanup());
   }
 
   private _onPointerMove = (event: PointerEvent): void => {
diff --git a/src/material/slider/slider.md b/src/material/slider/slider.md
index 5d0919d3b6d2..c8e358b8e582 100644
--- a/src/material/slider/slider.md
+++ b/src/material/slider/slider.md
@@ -77,3 +77,8 @@ The slider has the following keyboard bindings:
 
 `MatSlider` uses an internal `<input type="range">` to provide an accessible experience. The input
 receives focus and it can be labelled using `aria-label` or `aria-labelledby`.
+
+Make sure the colors of the active and inactive track of the `MatSlider` meet 
+at least a 3:1 contrast ratio with the background. This can be achieved through 
+changing the active or inactive track colors or showing tick marks on the
+track that have at least a 3:1 color contrast ratio with the background.
\ No newline at end of file
diff --git a/src/material/slider/slider.spec.ts b/src/material/slider/slider.spec.ts
index 83ca57e1e00e..6917b2df471e 100644
--- a/src/material/slider/slider.spec.ts
+++ b/src/material/slider/slider.spec.ts
@@ -1119,9 +1119,11 @@ describe('MatSlider', () => {
   describe('slider with direction', () => {
     let slider: MatSlider;
     let input: MatSliderThumb;
+    let sliderEl: HTMLElement;
+    let fixture: ComponentFixture<StandardRangeSlider>;
 
     beforeEach(waitForAsync(() => {
-      const fixture = createComponent(StandardSlider, [
+      fixture = createComponent(StandardSlider, [
         {
           provide: Directionality,
           useValue: {value: 'rtl', change: of()},
@@ -1130,6 +1132,7 @@ describe('MatSlider', () => {
       fixture.detectChanges();
       const sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider));
       slider = sliderDebugElement.componentInstance;
+      sliderEl = sliderDebugElement.nativeElement;
       input = slider._getInput(_MatThumb.END) as MatSliderThumb;
     }));
 
@@ -1137,6 +1140,23 @@ describe('MatSlider', () => {
       setValueByClick(slider, input, 25, true);
       checkInput(input, {min: 0, max: 100, value: 75, translateX: 75});
     }));
+
+    it('should position the tick marks correctly with a misaligned step (rtl)', () => {
+      slider.showTickMarks = true;
+      slider.min = 0;
+      slider.max = 10;
+      slider.step = 9;
+
+      fixture.detectChanges();
+
+      const activeClass = '.mdc-slider__tick-mark--active';
+      const inactiveClass = '.mdc-slider__tick-mark--inactive';
+      const ticks = sliderEl.querySelectorAll(`${activeClass},${inactiveClass}`);
+
+      expect(ticks.length).toBe(2);
+      expect(ticks[0].getBoundingClientRect().x).toBe(312);
+      expect(ticks[1].getBoundingClientRect().x).toBeCloseTo(47.4, 2);
+    });
   });
 
   describe('range slider with direction', () => {
@@ -1544,6 +1564,148 @@ describe('MatSlider', () => {
       expect(endInput.value).toBe(80);
     }));
   });
+
+  describe('slider with tick marks', () => {
+    let fixture: ComponentFixture<SliderWithTickMarks>;
+    let slider: MatSlider;
+    let sliderEl: HTMLElement;
+    let input: MatSliderThumb;
+
+    function getTickMarkEls() {
+      const activeClass = '.mdc-slider__tick-mark--active';
+      const inactiveClass = '.mdc-slider__tick-mark--inactive';
+      const active = sliderEl.querySelectorAll(activeClass);
+      const inactive = sliderEl.querySelectorAll(inactiveClass);
+      const ticks = sliderEl.querySelectorAll(`${activeClass},${inactiveClass}`);
+      return {ticks, active, inactive};
+    }
+
+    beforeEach(waitForAsync(() => {
+      fixture = createComponent(SliderWithTickMarks);
+      fixture.detectChanges();
+      const sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider));
+      slider = sliderDebugElement.componentInstance;
+      sliderEl = sliderDebugElement.nativeElement;
+      input = slider._getInput(_MatThumb.END) as MatSliderThumb;
+    }));
+
+    it('should have tick marks', () => {
+      expect(slider._tickMarks.length).toBeTruthy();
+    });
+
+    it('should have the correct number of ticks', () => {
+      expect(slider._tickMarks.length).toBe(101);
+
+      slider.max = 10;
+      expect(slider._tickMarks.length).toBe(11);
+
+      slider.step = 2;
+      expect(slider._tickMarks.length).toBe(6);
+
+      slider.min = 8;
+      expect(slider._tickMarks.length).toBe(2);
+    });
+
+    it('should position the tick marks correctly', () => {
+      const {ticks} = getTickMarkEls();
+
+      // 2.94 because the slider is 300px, there is 3px padding
+      // on each side of the tick mark track, and there are 100
+      // spaces between the 101 ticks. So the math is:
+      // (300 - 6) / 100 = 2.94
+      const spacing = 2.94;
+      const delta = 0.1; // Floating point imprecision
+
+      let x = 18; // Where the first tick happens to start at.
+
+      for (let i = 0; i < ticks.length; i++) {
+        const tickX = ticks[i].getBoundingClientRect().x;
+        expect(tickX).toBeGreaterThan(x - delta);
+        expect(tickX).toBeLessThan(x + delta);
+        x = tickX + spacing;
+      }
+    });
+
+    it('should render the correct number of active & inactive ticks', () => {
+      let tickEls = getTickMarkEls();
+      expect(tickEls.active.length).toBe(1);
+      expect(tickEls.inactive.length).toBe(100);
+
+      input.value = 50;
+      tickEls = getTickMarkEls();
+      expect(tickEls.active.length).toBe(51);
+      expect(tickEls.inactive.length).toBe(50);
+
+      input.value = 100;
+      tickEls = getTickMarkEls();
+      expect(tickEls.active.length).toBe(101);
+      expect(tickEls.inactive.length).toBe(0);
+    });
+
+    it('should position the tick marks correctly with a misaligned step', () => {
+      slider.max = 10;
+      slider.step = 9;
+      fixture.detectChanges();
+
+      const {ticks} = getTickMarkEls();
+      expect(ticks.length).toBe(2);
+
+      expect(ticks[0].getBoundingClientRect().x).toBe(18);
+      expect(ticks[1].getBoundingClientRect().x).toBeCloseTo(282.6, 2);
+    });
+  });
+
+  describe('range slider with tick marks', () => {
+    let fixture: ComponentFixture<RangeSliderWithTickMarks>;
+    let slider: MatSlider;
+    let sliderEl: HTMLElement;
+    let endInput: MatSliderRangeThumb;
+    let startInput: MatSliderRangeThumb;
+
+    function getTickMarkEls() {
+      const activeClass = '.mdc-slider__tick-mark--active';
+      const inactiveClass = '.mdc-slider__tick-mark--inactive';
+      const active = sliderEl.querySelectorAll(activeClass);
+      const inactive = sliderEl.querySelectorAll(inactiveClass);
+      const ticks = sliderEl.querySelectorAll(`${activeClass},${inactiveClass}`);
+      return {ticks, active, inactive};
+    }
+
+    beforeEach(waitForAsync(() => {
+      fixture = createComponent(RangeSliderWithTickMarks);
+      fixture.detectChanges();
+      const sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider));
+      slider = sliderDebugElement.componentInstance;
+      sliderEl = sliderDebugElement.nativeElement;
+      endInput = slider._getInput(_MatThumb.END) as MatSliderRangeThumb;
+      startInput = slider._getInput(_MatThumb.START) as MatSliderRangeThumb;
+    }));
+
+    it('should render the correct number of active & inactive ticks', () => {
+      startInput.value = 0;
+      endInput.value = 100;
+
+      let tickEls = getTickMarkEls();
+      expect(tickEls.active.length).toBe(101);
+      expect(tickEls.inactive.length).toBe(0);
+
+      startInput.value = 25;
+      tickEls = getTickMarkEls();
+      expect(tickEls.active.length).toBe(76);
+      expect(tickEls.inactive.length).toBe(25);
+
+      endInput.value = 75;
+      tickEls = getTickMarkEls();
+      expect(tickEls.active.length).toBe(51);
+      expect(tickEls.inactive.length).toBe(50);
+
+      startInput.value = 50;
+      endInput.value = 50;
+      tickEls = getTickMarkEls();
+      expect(tickEls.active.length).toBe(1);
+      expect(tickEls.inactive.length).toBe(100);
+    });
+  });
 });
 
 const SLIDER_STYLES = ['.mat-mdc-slider { width: 300px; }'];
@@ -1835,6 +1997,33 @@ class RangeSliderWithTwoWayBinding {
   endValue = 100;
 }
 
+@Component({
+  template: `
+  <mat-slider [showTickMarks]="true">
+    <input matSliderThumb>
+  </mat-slider>
+  `,
+  styles: SLIDER_STYLES,
+  standalone: false,
+})
+class SliderWithTickMarks {
+  @ViewChild(MatSlider) slider: MatSlider;
+}
+
+@Component({
+  template: `
+  <mat-slider [showTickMarks]="true">
+    <input matSliderStartThumb>
+    <input matSliderEndThumb>
+  </mat-slider>
+  `,
+  styles: SLIDER_STYLES,
+  standalone: false,
+})
+class RangeSliderWithTickMarks {
+  @ViewChild(MatSlider) slider: MatSlider;
+}
+
 /** Clicks on the MatSlider at the coordinates corresponding to the given value. */
 function setValueByClick(
   slider: MatSlider,
diff --git a/src/material/slider/slider.ts b/src/material/slider/slider.ts
index 74808591eb4a..5b23f8112494 100644
--- a/src/material/slider/slider.ts
+++ b/src/material/slider/slider.ts
@@ -149,10 +149,10 @@ export class MatSlider implements AfterViewInit, OnDestroy, _MatSlider {
 
   /**
    * Theme color of the slider. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/slider/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   color: ThemePalette;
@@ -590,7 +590,8 @@ export class MatSlider implements AfterViewInit, OnDestroy, _MatSlider {
   /** Returns the translateX positioning for a tick mark based on it's index. */
   _calcTickMarkTransform(index: number): string {
     // TODO(wagnermaciel): See if we can avoid doing this and just using flex to position these.
-    const translateX = index * (this._tickMarkTrackWidth / (this._tickMarks.length - 1));
+    const offset = index * (this._tickMarkTrackWidth / (this._tickMarks.length - 1));
+    const translateX = this._isRtl ? this._cachedWidth - 6 - offset : offset;
     return `translateX(${translateX}px`;
   }
 
@@ -788,7 +789,7 @@ export class MatSlider implements AfterViewInit, OnDestroy, _MatSlider {
     const step = this._step && this._step > 0 ? this._step : 1;
     const maxValue = Math.floor(this.max / step) * step;
     const percentage = (maxValue - this.min) / (this.max - this.min);
-    this._tickMarkTrackWidth = this._cachedWidth * percentage - 6;
+    this._tickMarkTrackWidth = (this._cachedWidth - 6) * percentage;
   }
 
   // Track active update conditions
@@ -877,16 +878,12 @@ export class MatSlider implements AfterViewInit, OnDestroy, _MatSlider {
     }
     const step = this.step > 0 ? this.step : 1;
     this._isRange ? this._updateTickMarkUIRange(step) : this._updateTickMarkUINonRange(step);
-
-    if (this._isRtl) {
-      this._tickMarks.reverse();
-    }
   }
 
   private _updateTickMarkUINonRange(step: number): void {
     const value = this._getValue();
-    let numActive = Math.max(Math.round((value - this.min) / step), 0);
-    let numInactive = Math.max(Math.round((this.max - value) / step), 0);
+    let numActive = Math.max(Math.round((value - this.min) / step), 0) + 1;
+    let numInactive = Math.max(Math.round((this.max - value) / step), 0) - 1;
     this._isRtl ? numActive++ : numInactive++;
 
     this._tickMarks = Array(numActive)
diff --git a/src/material/slider/testing/slider-harness.spec.ts b/src/material/slider/testing/slider-harness.spec.ts
index 4237f95b8f43..6a264b827b2f 100644
--- a/src/material/slider/testing/slider-harness.spec.ts
+++ b/src/material/slider/testing/slider-harness.spec.ts
@@ -202,7 +202,6 @@ describe('MatSliderHarness', () => {
       <input [value]="rangeSliderEndValue" matSliderEndThumb>
     </mat-slider>
   `,
-  standalone: true,
   imports: [MatSliderModule],
 })
 class SliderHarnessTest {
diff --git a/src/material/snack-bar/snack-bar-container.scss b/src/material/snack-bar/snack-bar-container.scss
index 6e1f29084cd0..87aecb67f3f2 100644
--- a/src/material/snack-bar/snack-bar-container.scss
+++ b/src/material/snack-bar/snack-bar-container.scss
@@ -105,14 +105,16 @@ $_side-padding: 8px;
 // The `mat-mdc-button` and `:not(:disabled)` here are redundant, but we need them to increase
 // the specificity over the button styles that may bleed in from the rest of the app.
 .mat-mdc-snack-bar-container .mat-mdc-button.mat-mdc-snack-bar-action:not(:disabled) {
-  // MDC's `action-label-text-color` should be able to do this, but the button theme has a
-  // higher specificity so it ends up overriding it. Define our own variable that we can
-  // use to control the color instead.
-  @include token-utils.use-tokens(
-    tokens-mat-snack-bar.$prefix,
-    tokens-mat-snack-bar.get-token-slots()
-  ) {
-    @include token-utils.create-token-slot(color, button-color);
+  &.mat-unthemed {
+    // MDC's `action-label-text-color` should be able to do this, but the button theme has a
+    // higher specificity so it ends up overriding it. Define our own variable that we can
+    // use to control the color instead.
+    @include token-utils.use-tokens(
+      tokens-mat-snack-bar.$prefix,
+      tokens-mat-snack-bar.get-token-slots()
+    ) {
+      @include token-utils.create-token-slot(color, button-color);
+    }
   }
 
   // Darken the ripples in the button so they're visible against the dark background.
diff --git a/src/material/snack-bar/snack-bar-container.ts b/src/material/snack-bar/snack-bar-container.ts
index 2a0ca64ab2d3..9180b4aaefe9 100644
--- a/src/material/snack-bar/snack-bar-container.ts
+++ b/src/material/snack-bar/snack-bar-container.ts
@@ -29,13 +29,11 @@ import {
   TemplatePortal,
 } from '@angular/cdk/portal';
 import {Observable, Subject} from 'rxjs';
-import {AriaLivePoliteness} from '@angular/cdk/a11y';
+import {_IdGenerator, AriaLivePoliteness} from '@angular/cdk/a11y';
 import {Platform} from '@angular/cdk/platform';
 import {AnimationEvent} from '@angular/animations';
 import {MatSnackBarConfig} from './snack-bar-config';
 
-let uniqueId = 0;
-
 /**
  * Internal component that wraps user-provided snack bar content.
  * @docs-private
@@ -72,7 +70,7 @@ export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy
   private readonly _announceDelay: number = 150;
 
   /** The timeout for announcing the snack bar's content. */
-  private _announceTimeoutId: number;
+  private _announceTimeoutId: ReturnType<typeof setTimeout>;
 
   /** Whether the component has been destroyed. */
   private _destroyed = false;
@@ -109,7 +107,7 @@ export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy
   _role?: 'status' | 'alert';
 
   /** Unique ID of the aria-live element. */
-  readonly _liveElementId = `mat-snack-bar-container-live-${uniqueId++}`;
+  readonly _liveElementId = inject(_IdGenerator).getId('mat-snack-bar-container-live-');
 
   constructor(...args: unknown[]);
 
diff --git a/src/material/snack-bar/snack-bar-ref.ts b/src/material/snack-bar/snack-bar-ref.ts
index 40f9cefb1f35..b5eaad9ab629 100644
--- a/src/material/snack-bar/snack-bar-ref.ts
+++ b/src/material/snack-bar/snack-bar-ref.ts
@@ -45,7 +45,7 @@ export class MatSnackBarRef<T> {
    * Timeout ID for the duration setTimeout call. Used to clear the timeout if the snackbar is
    * dismissed before the duration passes.
    */
-  private _durationTimeoutId: number;
+  private _durationTimeoutId: ReturnType<typeof setTimeout>;
 
   /** Whether the snack bar was dismissed using the action button. */
   private _dismissedByAction = false;
diff --git a/src/material/snack-bar/snack-bar.spec.ts b/src/material/snack-bar/snack-bar.spec.ts
index 28a54c2fd5bb..17a6b72b5915 100644
--- a/src/material/snack-bar/snack-bar.spec.ts
+++ b/src/material/snack-bar/snack-bar.spec.ts
@@ -1057,7 +1057,6 @@ describe('MatSnackBar Positioning', () => {
 
 @Directive({
   selector: 'dir-with-view-container',
-  standalone: true,
 })
 class DirectiveWithViewContainer {
   viewContainerRef = inject(ViewContainerRef);
@@ -1066,7 +1065,6 @@ class DirectiveWithViewContainer {
 @Component({
   selector: 'arbitrary-component',
   template: `@if (childComponentExists()) {<dir-with-view-container></dir-with-view-container>}`,
-  standalone: true,
   imports: [DirectiveWithViewContainer],
   changeDetection: ChangeDetectionStrategy.OnPush,
 })
@@ -1087,7 +1085,6 @@ class ComponentWithChildViewContainer {
       Fries {{localValue}} {{data?.value}}
     </ng-template>
   `,
-  standalone: true,
 })
 class ComponentWithTemplateRef {
   @ViewChild(TemplateRef) templateRef: TemplateRef<any>;
@@ -1097,7 +1094,6 @@ class ComponentWithTemplateRef {
 /** Simple component for testing ComponentPortal. */
 @Component({
   template: '<p>Burritos are on the way.</p>',
-  standalone: true,
 })
 class BurritosNotification {
   snackBarRef = inject<MatSnackBarRef<BurritosNotification>>(MatSnackBarRef);
@@ -1107,7 +1103,6 @@ class BurritosNotification {
 @Component({
   template: '',
   providers: [MatSnackBar],
-  standalone: true,
 })
 class ComponentThatProvidesMatSnackBar {
   snackBar = inject(MatSnackBar);
diff --git a/src/material/snack-bar/snack-bar.zone.spec.ts b/src/material/snack-bar/snack-bar.zone.spec.ts
index 403cdf9be9e9..1db0ee44e135 100644
--- a/src/material/snack-bar/snack-bar.zone.spec.ts
+++ b/src/material/snack-bar/snack-bar.zone.spec.ts
@@ -64,7 +64,6 @@ describe('MatSnackBar Zone.js integration', () => {
 
 @Directive({
   selector: 'dir-with-view-container',
-  standalone: true,
 })
 class DirectiveWithViewContainer {
   viewContainerRef = inject(ViewContainerRef);
@@ -73,7 +72,6 @@ class DirectiveWithViewContainer {
 @Component({
   selector: 'arbitrary-component',
   template: `@if (childComponentExists()) {<dir-with-view-container></dir-with-view-container>}`,
-  standalone: true,
   imports: [DirectiveWithViewContainer],
   changeDetection: ChangeDetectionStrategy.OnPush,
 })
diff --git a/src/material/snack-bar/testing/snack-bar-harness.spec.ts b/src/material/snack-bar/testing/snack-bar-harness.spec.ts
index 869e0e8f719a..e876df34dcc6 100644
--- a/src/material/snack-bar/testing/snack-bar-harness.spec.ts
+++ b/src/material/snack-bar/testing/snack-bar-harness.spec.ts
@@ -171,7 +171,6 @@ describe('MatSnackBarHarness', () => {
       <div matSnackBarActions><button matSnackBarAction>Ok</button></div>
     </ng-template>
   `,
-  standalone: true,
   imports: [MatSnackBarLabel, MatSnackBarActions, MatSnackBarAction],
 })
 class SnackbarHarnessTest {
diff --git a/src/material/sort/sort-animations.ts b/src/material/sort/sort-animations.ts
index 2107cc36b3f0..155a46c7b35c 100644
--- a/src/material/sort/sort-animations.ts
+++ b/src/material/sort/sort-animations.ts
@@ -24,6 +24,8 @@ const SORT_ANIMATION_TRANSITION =
 /**
  * Animations used by MatSort.
  * @docs-private
+ * @deprecated No longer being used, to be removed.
+ * @breaking-change 21.0.0
  */
 export const matSortAnimations: {
   readonly indicator: AnimationTriggerMetadata;
diff --git a/src/material/sort/sort-header.html b/src/material/sort/sort-header.html
index 93cf5d902690..ecfae9ac0294 100644
--- a/src/material/sort/sort-header.html
+++ b/src/material/sort/sort-header.html
@@ -11,6 +11,11 @@
 <div class="mat-sort-header-container mat-focus-indicator"
      [class.mat-sort-header-sorted]="_isSorted()"
      [class.mat-sort-header-position-before]="arrowPosition === 'before'"
+     [class.mat-sort-header-descending]="this._sort.direction === 'desc'"
+     [class.mat-sort-header-ascending]="this._sort.direction === 'asc'"
+     [class.mat-sort-header-recently-cleared-ascending]="_recentlyCleared() === 'asc'"
+     [class.mat-sort-header-recently-cleared-descending]="_recentlyCleared() === 'desc'"
+     [class.mat-sort-header-animations-disabled]="_animationModule === 'NoopAnimations'"
      [attr.tabindex]="_isDisabled() ? null : 0"
      [attr.role]="_isDisabled() ? null : 'button'">
 
@@ -26,18 +31,10 @@
 
   <!-- Disable animations while a current animation is running -->
   @if (_renderArrow()) {
-    <div class="mat-sort-header-arrow"
-        [@arrowOpacity]="_getArrowViewState()"
-        [@arrowPosition]="_getArrowViewState()"
-        [@allowChildren]="_getArrowDirectionState()"
-        (@arrowPosition.start)="_disableViewStateAnimation = true"
-        (@arrowPosition.done)="_disableViewStateAnimation = false">
-      <div class="mat-sort-header-stem"></div>
-      <div class="mat-sort-header-indicator" [@indicator]="_getArrowDirectionState()">
-        <div class="mat-sort-header-pointer-left" [@leftPointer]="_getArrowDirectionState()"></div>
-        <div class="mat-sort-header-pointer-right" [@rightPointer]="_getArrowDirectionState()"></div>
-        <div class="mat-sort-header-pointer-middle"></div>
-      </div>
+    <div class="mat-sort-header-arrow">
+      <svg viewBox="0 -960 960 960" focusable="false" aria-hidden="true">
+        <path d="M440-240v-368L296-464l-56-56 240-240 240 240-56 56-144-144v368h-80Z"/>
+      </svg>
     </div>
   }
 </div>
diff --git a/src/material/sort/sort-header.scss b/src/material/sort/sort-header.scss
index 0e1818717f69..c836a7383091 100644
--- a/src/material/sort/sort-header.scss
+++ b/src/material/sort/sort-header.scss
@@ -1,16 +1,7 @@
-@use '@angular/cdk';
-
 @use '../core/tokens/m2/mat/sort' as tokens-mat-sort;
 @use '../core/tokens/token-utils';
 @use '../core/focus-indicators/private';
 
-$header-arrow-margin: 6px;
-$header-arrow-container-size: 12px;
-$header-arrow-stem-size: 10px;
-$header-arrow-pointer-length: 6px;
-$header-arrow-thickness: 2px;
-$header-arrow-hint-opacity: 0.38;
-
 .mat-sort-header-container {
   display: flex;
   cursor: pointer;
@@ -42,7 +33,6 @@ $header-arrow-hint-opacity: 0.38;
 }
 
 .mat-sort-header-content {
-  text-align: center;
   display: flex;
   align-items: center;
 }
@@ -51,93 +41,98 @@ $header-arrow-hint-opacity: 0.38;
   flex-direction: row-reverse;
 }
 
+@keyframes _mat-sort-header-recently-cleared-ascending {
+  from {
+    transform: translateY(0);
+    opacity: 1;
+  }
+
+  to {
+    transform: translateY(-25%);
+    opacity: 0;
+  }
+}
+
+@keyframes _mat-sort-header-recently-cleared-descending {
+  from {
+    transform: translateY(0) rotate(180deg);
+    opacity: 1;
+  }
+
+  to {
+    transform: translateY(25%) rotate(180deg);
+    opacity: 0;
+  }
+}
+
 .mat-sort-header-arrow {
-  height: $header-arrow-container-size;
-  width: $header-arrow-container-size;
-  min-width: $header-arrow-container-size;
+  $timing: 225ms cubic-bezier(0.4, 0, 0.2, 1);
+  height: 12px;
+  width: 12px;
   position: relative;
-  display: flex;
+  transition: transform $timing, opacity $timing;
+  opacity: 0;
+  overflow: visible;
 
   @include token-utils.use-tokens(tokens-mat-sort.$prefix, tokens-mat-sort.get-token-slots()) {
     @include token-utils.create-token-slot(color, arrow-color);
   }
 
-  // Start off at 0 since the arrow may become visible while parent are animating.
-  // This will be overwritten when the arrow animations kick in. See #11819.
-  opacity: 0;
-
-  &,
-  [dir='rtl'] .mat-sort-header-position-before & {
-    margin: 0 0 0 $header-arrow-margin;
+  .mat-sort-header.cdk-keyboard-focused &,
+  .mat-sort-header.cdk-program-focused &,
+  .mat-sort-header:hover & {
+    opacity: 0.54;
   }
 
-  .mat-sort-header-position-before &,
-  [dir='rtl'] & {
-    margin: 0 $header-arrow-margin 0 0;
+  .mat-sort-header .mat-sort-header-sorted & {
+    opacity: 1;
   }
-}
 
-.mat-sort-header-stem {
-  background: currentColor;
-  height: $header-arrow-stem-size;
-  width: $header-arrow-thickness;
-  margin: auto;
-  display: flex;
-  align-items: center;
-
-  @include cdk.high-contrast {
-    width: 0;
-    border-left: solid $header-arrow-thickness;
+  .mat-sort-header-descending & {
+    transform: rotate(180deg);
   }
-}
 
-.mat-sort-header-indicator {
-  width: 100%;
-  height: $header-arrow-thickness;
-  display: flex;
-  align-items: center;
-  position: absolute;
-  top: 0;
-  left: 0;
-}
+  .mat-sort-header-recently-cleared-ascending & {
+    transform: translateY(-25%);
+  }
 
-.mat-sort-header-pointer-middle {
-  margin: auto;
-  height: $header-arrow-thickness;
-  width: $header-arrow-thickness;
-  background: currentColor;
-  transform: rotate(45deg);
+  .mat-sort-header-recently-cleared-ascending & {
+    transition: none; // Without this the animation looks glitchy on Safari.
+    animation: _mat-sort-header-recently-cleared-ascending $timing forwards;
+  }
 
-  @include cdk.high-contrast {
-    width: 0;
-    height: 0;
-    border-top: solid $header-arrow-thickness;
-    border-left: solid $header-arrow-thickness;
+  .mat-sort-header-recently-cleared-descending & {
+    transition: none; // Without this the animation looks glitchy on Safari.
+    animation: _mat-sort-header-recently-cleared-descending $timing forwards;
   }
-}
 
-.mat-sort-header-pointer-left,
-.mat-sort-header-pointer-right {
-  background: currentColor;
-  width: $header-arrow-pointer-length;
-  height: $header-arrow-thickness;
-  position: absolute;
-  top: 0;
+  // Set the durations to 0, but keep the actual animation, since we still want it to play.
+  .mat-sort-header-animations-disabled & {
+    transition-duration: 0ms;
+    animation-duration: 0ms;
+  }
 
-  @include cdk.high-contrast {
-    width: 0;
-    height: 0;
-    border-left: solid $header-arrow-pointer-length;
-    border-top: solid $header-arrow-thickness;
+  svg {
+    // Even though this is 24x24, the actual `path` inside ends up being 12x12.
+    width: 24px;
+    height: 24px;
+    fill: currentColor;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    margin: -12px 0 0 -12px;
+
+    // Without this transform the element twitches at the end of the transition on Safari.
+    transform: translateZ(0);
   }
-}
 
-.mat-sort-header-pointer-left {
-  transform-origin: right;
-  left: 0;
-}
+  &,
+  [dir='rtl'] .mat-sort-header-position-before & {
+    margin: 0 0 0 6px;
+  }
 
-.mat-sort-header-pointer-right {
-  transform-origin: left;
-  right: 0;
+  .mat-sort-header-position-before &,
+  [dir='rtl'] & {
+    margin: 0 6px 0 0;
+  }
 }
diff --git a/src/material/sort/sort-header.ts b/src/material/sort/sort-header.ts
index 75fc440a882e..51d529b0fcbd 100644
--- a/src/material/sort/sort-header.ts
+++ b/src/material/sort/sort-header.ts
@@ -11,7 +11,6 @@ import {ENTER, SPACE} from '@angular/cdk/keycodes';
 import {
   AfterViewInit,
   ChangeDetectionStrategy,
-  ChangeDetectorRef,
   Component,
   ElementRef,
   Input,
@@ -20,6 +19,9 @@ import {
   ViewEncapsulation,
   booleanAttribute,
   inject,
+  signal,
+  ANIMATION_MODULE_TYPE,
+  ChangeDetectorRef,
 } from '@angular/core';
 import {merge, Subscription} from 'rxjs';
 import {
@@ -29,7 +31,6 @@ import {
   MatSortDefaultOptions,
   SortHeaderArrowPosition,
 } from './sort';
-import {matSortAnimations} from './sort-animations';
 import {SortDirection} from './sort-direction';
 import {getSortHeaderNotContainedWithinSortError} from './sort-errors';
 import {MatSortHeaderIntl} from './sort-header-intl';
@@ -43,6 +44,8 @@ import {_StructuralStylesLoader} from '@angular/material/core';
  * be fully opaque in the center.
  *
  * @docs-private
+ * @deprecated No longer being used, to be removed.
+ * @breaking-change 21.0.0
  */
 export type ArrowViewState = SortDirection | 'hint' | 'active';
 
@@ -50,6 +53,8 @@ export type ArrowViewState = SortDirection | 'hint' | 'active';
  * States describing the arrow's animated position (animating fromState to toState).
  * If the fromState is not defined, there will be no animated transition to the toState.
  * @docs-private
+ * @deprecated No longer being used, to be removed.
+ * @breaking-change 21.0.0
  */
 export interface ArrowViewStateTransition {
   fromState?: ArrowViewState;
@@ -77,36 +82,33 @@ interface MatSortHeaderColumnDef {
   styleUrl: 'sort-header.css',
   host: {
     'class': 'mat-sort-header',
-    '(click)': '_handleClick()',
+    '(click)': '_toggleOnInteraction()',
     '(keydown)': '_handleKeydown($event)',
-    '(mouseenter)': '_setIndicatorHintVisible(true)',
-    '(mouseleave)': '_setIndicatorHintVisible(false)',
+    '(mouseleave)': '_recentlyCleared.set(false)',
     '[attr.aria-sort]': '_getAriaSortAttribute()',
     '[class.mat-sort-header-disabled]': '_isDisabled()',
   },
   encapsulation: ViewEncapsulation.None,
   changeDetection: ChangeDetectionStrategy.OnPush,
-  animations: [
-    matSortAnimations.indicator,
-    matSortAnimations.leftPointer,
-    matSortAnimations.rightPointer,
-    matSortAnimations.arrowOpacity,
-    matSortAnimations.arrowPosition,
-    matSortAnimations.allowChildren,
-  ],
 })
 export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewInit {
   _intl = inject(MatSortHeaderIntl);
-  private _changeDetectorRef = inject(ChangeDetectorRef);
   _sort = inject(MatSort, {optional: true})!;
   _columnDef = inject<MatSortHeaderColumnDef>('MAT_SORT_HEADER_COLUMN_DEF' as any, {
     optional: true,
   });
+  private _changeDetectorRef = inject(ChangeDetectorRef);
   private _focusMonitor = inject(FocusMonitor);
   private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
   private _ariaDescriber = inject(AriaDescriber, {optional: true});
+  private _renderChanges: Subscription | undefined;
+  protected _animationModule = inject(ANIMATION_MODULE_TYPE, {optional: true});
 
-  private _rerenderSubscription: Subscription;
+  /**
+   * Indicates which state was just cleared from the sort header.
+   * Will be reset on the next interaction. Used for coordinating animations.
+   */
+  protected _recentlyCleared = signal<SortDirection | null>(null);
 
   /**
    * The element with role="button" inside this component's view. We need this
@@ -114,27 +116,6 @@ export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewI
    */
   private _sortButton: HTMLElement;
 
-  /**
-   * Flag set to true when the indicator should be displayed while the sort is not active. Used to
-   * provide an affordance that the header is sortable by showing on focus and hover.
-   */
-  _showIndicatorHint: boolean = false;
-
-  /**
-   * The view transition state of the arrow (translation/ opacity) - indicates its `from` and `to`
-   * position through the animation. If animations are currently disabled, the fromState is removed
-   * so that there is no animation displayed.
-   */
-  _viewState: ArrowViewStateTransition = {};
-
-  /** The direction the arrow should be facing according to the current state. */
-  _arrowDirection: SortDirection = '';
-
-  /**
-   * Whether the view state animation should show the transition between the `from` and `to` states.
-   */
-  _disableViewStateAnimation = false;
-
   /**
    * ID of this sort header. If used within the context of a CdkColumnDef, this will default to
    * the column's name.
@@ -190,8 +171,6 @@ export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewI
     if (defaultOptions?.arrowPosition) {
       this.arrowPosition = defaultOptions?.arrowPosition;
     }
-
-    this._handleStateChanges();
   }
 
   ngOnInit() {
@@ -199,14 +178,10 @@ export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewI
       this.id = this._columnDef.name;
     }
 
-    // Initialize the direction of the arrow and set the view state to be immediately that state.
-    this._updateArrowDirection();
-    this._setAnimationTransitionState({
-      toState: this._isSorted() ? 'active' : this._arrowDirection,
-    });
-
     this._sort.register(this);
-
+    this._renderChanges = merge(this._sort._stateChanges, this._sort.sortChange).subscribe(() =>
+      this._changeDetectorRef.markForCheck(),
+    );
     this._sortButton = this._elementRef.nativeElement.querySelector('.mat-sort-header-container')!;
     this._updateSortActionDescription(this._sortActionDescription);
   }
@@ -214,80 +189,33 @@ export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewI
   ngAfterViewInit() {
     // We use the focus monitor because we also want to style
     // things differently based on the focus origin.
-    this._focusMonitor.monitor(this._elementRef, true).subscribe(origin => {
-      const newState = !!origin;
-      if (newState !== this._showIndicatorHint) {
-        this._setIndicatorHintVisible(newState);
-        this._changeDetectorRef.markForCheck();
-      }
-    });
+    this._focusMonitor
+      .monitor(this._elementRef, true)
+      .subscribe(() => this._recentlyCleared.set(null));
   }
 
   ngOnDestroy() {
     this._focusMonitor.stopMonitoring(this._elementRef);
     this._sort.deregister(this);
-    this._rerenderSubscription.unsubscribe();
+    this._renderChanges?.unsubscribe();
 
     if (this._sortButton) {
       this._ariaDescriber?.removeDescription(this._sortButton, this._sortActionDescription);
     }
   }
 
-  /**
-   * Sets the "hint" state such that the arrow will be semi-transparently displayed as a hint to the
-   * user showing what the active sort will become. If set to false, the arrow will fade away.
-   */
-  _setIndicatorHintVisible(visible: boolean) {
-    // No-op if the sort header is disabled - should not make the hint visible.
-    if (this._isDisabled() && visible) {
-      return;
-    }
-
-    this._showIndicatorHint = visible;
-
-    if (!this._isSorted()) {
-      this._updateArrowDirection();
-      if (this._showIndicatorHint) {
-        this._setAnimationTransitionState({fromState: this._arrowDirection, toState: 'hint'});
-      } else {
-        this._setAnimationTransitionState({fromState: 'hint', toState: this._arrowDirection});
-      }
-    }
-  }
-
-  /**
-   * Sets the animation transition view state for the arrow's position and opacity. If the
-   * `disableViewStateAnimation` flag is set to true, the `fromState` will be ignored so that
-   * no animation appears.
-   */
-  _setAnimationTransitionState(viewState: ArrowViewStateTransition) {
-    this._viewState = viewState || {};
-
-    // If the animation for arrow position state (opacity/translation) should be disabled,
-    // remove the fromState so that it jumps right to the toState.
-    if (this._disableViewStateAnimation) {
-      this._viewState = {toState: viewState.toState};
-    }
-  }
-
   /** Triggers the sort on this sort header and removes the indicator hint. */
   _toggleOnInteraction() {
-    this._sort.sort(this);
-
-    // Do not show the animation if the header was already shown in the right position.
-    if (this._viewState.toState === 'hint' || this._viewState.toState === 'active') {
-      this._disableViewStateAnimation = true;
-    }
-  }
-
-  _handleClick() {
     if (!this._isDisabled()) {
+      const wasSorted = this._isSorted();
+      const prevDirection = this._sort.direction;
       this._sort.sort(this);
+      this._recentlyCleared.set(wasSorted && !this._isSorted() ? prevDirection : null);
     }
   }
 
   _handleKeydown(event: KeyboardEvent) {
-    if (!this._isDisabled() && (event.keyCode === SPACE || event.keyCode === ENTER)) {
+    if (event.keyCode === SPACE || event.keyCode === ENTER) {
       event.preventDefault();
       this._toggleOnInteraction();
     }
@@ -301,31 +229,6 @@ export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewI
     );
   }
 
-  /** Returns the animation state for the arrow direction (indicator and pointers). */
-  _getArrowDirectionState() {
-    return `${this._isSorted() ? 'active-' : ''}${this._arrowDirection}`;
-  }
-
-  /** Returns the arrow position state (opacity, translation). */
-  _getArrowViewState() {
-    const fromState = this._viewState.fromState;
-    return (fromState ? `${fromState}-to-` : '') + this._viewState.toState;
-  }
-
-  /**
-   * Updates the direction the arrow should be pointing. If it is not sorted, the arrow should be
-   * facing the start direction. Otherwise if it is sorted, the arrow should point in the currently
-   * active sorted direction. The reason this is updated through a function is because the direction
-   * should only be changed at specific times - when deactivated but the hint is displayed and when
-   * the sort is active and the direction changes. Otherwise the arrow's direction should linger
-   * in cases such as the sort becoming deactivated but we want to animate the arrow away while
-   * preserving its direction, even though the next sort direction is actually different and should
-   * only be changed once the arrow displays again (hint or activation).
-   */
-  _updateArrowDirection() {
-    this._arrowDirection = this._isSorted() ? this._sort.direction : this.start || this._sort.start;
-  }
-
   _isDisabled() {
     return this._sort.disabled || this.disabled;
   }
@@ -365,33 +268,4 @@ export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewI
 
     this._sortActionDescription = newDescription;
   }
-
-  /** Handles changes in the sorting state. */
-  private _handleStateChanges() {
-    this._rerenderSubscription = merge(
-      this._sort.sortChange,
-      this._sort._stateChanges,
-      this._intl.changes,
-    ).subscribe(() => {
-      if (this._isSorted()) {
-        this._updateArrowDirection();
-
-        // Do not show the animation if the header was already shown in the right position.
-        if (this._viewState.toState === 'hint' || this._viewState.toState === 'active') {
-          this._disableViewStateAnimation = true;
-        }
-
-        this._setAnimationTransitionState({fromState: this._arrowDirection, toState: 'active'});
-        this._showIndicatorHint = false;
-      }
-
-      // If this header was recently active and now no longer sorted, animate away the arrow.
-      if (!this._isSorted() && this._viewState && this._viewState.toState === 'active') {
-        this._disableViewStateAnimation = false;
-        this._setAnimationTransitionState({fromState: 'active', toState: this._arrowDirection});
-      }
-
-      this._changeDetectorRef.markForCheck();
-    });
-  }
 }
diff --git a/src/material/sort/sort.spec.ts b/src/material/sort/sort.spec.ts
index 08bf17a48219..55d21297694e 100644
--- a/src/material/sort/sort.spec.ts
+++ b/src/material/sort/sort.spec.ts
@@ -1,11 +1,6 @@
 import {CollectionViewer, DataSource} from '@angular/cdk/collections';
 import {CdkTableModule} from '@angular/cdk/table';
-import {
-  createFakeEvent,
-  createMouseEvent,
-  dispatchMouseEvent,
-  wrappedErrorMessage,
-} from '@angular/cdk/testing/private';
+import {dispatchMouseEvent, wrappedErrorMessage} from '@angular/cdk/testing/private';
 import {Component, ElementRef, ViewChild, inject} from '@angular/core';
 import {ComponentFixture, TestBed, fakeAsync, tick, waitForAsync} from '@angular/core/testing';
 import {MatTableModule} from '@angular/material/table';
@@ -103,116 +98,6 @@ describe('MatSort', () => {
       expect(sortables.has('column_c')).toBe(true);
     });
 
-    describe('checking correct arrow direction and view state for its various states', () => {
-      let expectedStates: Map<string, {viewState: string; arrowDirection: string}>;
-
-      beforeEach(() => {
-        // Starting state for the view and directions - note that overrideStart is reversed to be
-        // desc
-        expectedStates = new Map<string, {viewState: string; arrowDirection: string}>([
-          ['defaultA', {viewState: 'asc', arrowDirection: 'asc'}],
-          ['defaultB', {viewState: 'asc', arrowDirection: 'asc'}],
-          ['overrideStart', {viewState: 'desc', arrowDirection: 'desc'}],
-          ['overrideDisableClear', {viewState: 'asc', arrowDirection: 'asc'}],
-        ]);
-        component.expectViewAndDirectionStates(expectedStates);
-      });
-
-      it('should be correct when mousing over headers and leaving on mouseleave', () => {
-        // Mousing over the first sort should set the view state to hint (asc)
-        component.dispatchMouseEvent('defaultA', 'mouseenter');
-        expectedStates.set('defaultA', {viewState: 'asc-to-hint', arrowDirection: 'asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-
-        // Mousing away from the first sort should hide the arrow
-        component.dispatchMouseEvent('defaultA', 'mouseleave');
-        expectedStates.set('defaultA', {viewState: 'hint-to-asc', arrowDirection: 'asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-
-        // Mousing over another sort should set the view state to hint (desc)
-        component.dispatchMouseEvent('overrideStart', 'mouseenter');
-        expectedStates.set('overrideStart', {viewState: 'desc-to-hint', arrowDirection: 'desc'});
-        component.expectViewAndDirectionStates(expectedStates);
-      });
-
-      it('should be correct when mousing over header and then sorting', () => {
-        // Mousing over the first sort should set the view state to hint
-        component.dispatchMouseEvent('defaultA', 'mouseenter');
-        expectedStates.set('defaultA', {viewState: 'asc-to-hint', arrowDirection: 'asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-
-        // Clicking sort on the header should set it to be active immediately
-        // (since it was already hinted)
-        component.dispatchMouseEvent('defaultA', 'click');
-        expectedStates.set('defaultA', {viewState: 'active', arrowDirection: 'active-asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-      });
-
-      it('should be correct when cycling through a default sort header', () => {
-        // Sort the header to set it to the active start state
-        component.sort('defaultA');
-        expectedStates.set('defaultA', {viewState: 'asc-to-active', arrowDirection: 'active-asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-
-        // Sorting again will reverse its direction
-        component.dispatchMouseEvent('defaultA', 'click');
-        expectedStates.set('defaultA', {viewState: 'active', arrowDirection: 'active-desc'});
-        component.expectViewAndDirectionStates(expectedStates);
-
-        // Sorting again will remove the sort and animate away the view
-        component.dispatchMouseEvent('defaultA', 'click');
-        expectedStates.set('defaultA', {viewState: 'active-to-desc', arrowDirection: 'desc'});
-        component.expectViewAndDirectionStates(expectedStates);
-      });
-
-      it('should not enter sort with animations if an animations is disabled', () => {
-        // Sort the header to set it to the active start state
-        component.defaultA._disableViewStateAnimation = true;
-        component.sort('defaultA');
-        expectedStates.set('defaultA', {viewState: 'active', arrowDirection: 'active-asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-
-        // Sorting again will reverse its direction
-        component.defaultA._disableViewStateAnimation = true;
-        component.dispatchMouseEvent('defaultA', 'click');
-        expectedStates.set('defaultA', {viewState: 'active', arrowDirection: 'active-desc'});
-        component.expectViewAndDirectionStates(expectedStates);
-      });
-
-      it('should be correct when sort has changed while a header is active', () => {
-        // Sort the first header to set up
-        component.sort('defaultA');
-        expectedStates.set('defaultA', {viewState: 'asc-to-active', arrowDirection: 'active-asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-
-        // Sort the second header and verify that the first header animated away
-        component.dispatchMouseEvent('defaultB', 'click');
-        expectedStates.set('defaultA', {viewState: 'active-to-asc', arrowDirection: 'asc'});
-        expectedStates.set('defaultB', {viewState: 'asc-to-active', arrowDirection: 'active-asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-      });
-
-      it('should be correct when sort has been disabled', () => {
-        // Mousing over the first sort should set the view state to hint
-        component.disabledColumnSort = true;
-        fixture.changeDetectorRef.markForCheck();
-        fixture.detectChanges();
-
-        component.dispatchMouseEvent('defaultA', 'mouseenter');
-        component.expectViewAndDirectionStates(expectedStates);
-      });
-
-      it('should be correct when sorting programmatically', () => {
-        component.active = 'defaultB';
-        component.direction = 'asc';
-        fixture.changeDetectorRef.markForCheck();
-        fixture.detectChanges();
-
-        expectedStates.set('defaultB', {viewState: 'asc-to-active', arrowDirection: 'active-asc'});
-        component.expectViewAndDirectionStates(expectedStates);
-      });
-    });
-
     it('should be able to cycle from asc -> desc from either start point', () => {
       component.disableClear = true;
 
@@ -328,54 +213,6 @@ describe('MatSort', () => {
       testSingleColumnSortDirectionSequence(fixture, ['asc', 'desc'], 'overrideDisableClear');
     });
 
-    it('should toggle indicator hint on button focus/blur and hide on click', () => {
-      const header = fixture.componentInstance.defaultA;
-      const container = fixture.nativeElement.querySelector('#defaultA .mat-sort-header-container');
-      const focusEvent = createFakeEvent('focus');
-      const blurEvent = createFakeEvent('blur');
-
-      // Should start without a displayed hint
-      expect(header._showIndicatorHint).toBeFalsy();
-
-      // Focusing the button should show the hint, blurring should hide it
-      container.dispatchEvent(focusEvent);
-      expect(header._showIndicatorHint).toBeTruthy();
-
-      container.dispatchEvent(blurEvent);
-      expect(header._showIndicatorHint).toBeFalsy();
-
-      // Show the indicator hint. On click the hint should be hidden
-      container.dispatchEvent(focusEvent);
-      expect(header._showIndicatorHint).toBeTruthy();
-
-      header._handleClick();
-      expect(header._showIndicatorHint).toBeFalsy();
-    });
-
-    it('should toggle indicator hint on mouseenter/mouseleave and hide on click', () => {
-      const header = fixture.componentInstance.defaultA;
-      const headerElement = fixture.nativeElement.querySelector('#defaultA');
-      const mouseenterEvent = createMouseEvent('mouseenter');
-      const mouseleaveEvent = createMouseEvent('mouseleave');
-
-      // Should start without a displayed hint
-      expect(header._showIndicatorHint).toBeFalsy();
-
-      // Mouse enter should show the hint, blurring should hide it
-      headerElement.dispatchEvent(mouseenterEvent);
-      expect(header._showIndicatorHint).toBeTruthy();
-
-      headerElement.dispatchEvent(mouseleaveEvent);
-      expect(header._showIndicatorHint).toBeFalsy();
-
-      // Show the indicator hint. On click the hint should be hidden
-      headerElement.dispatchEvent(mouseenterEvent);
-      expect(header._showIndicatorHint).toBeTruthy();
-
-      header._handleClick();
-      expect(header._showIndicatorHint).toBeFalsy();
-    });
-
     it('should apply the aria-sort label to the header when sorted', () => {
       const sortHeaderElement = fixture.nativeElement.querySelector('#defaultA');
       expect(sortHeaderElement.getAttribute('aria-sort')).toBe('none');
@@ -673,7 +510,6 @@ type SimpleMatSortAppColumnIds = 'defaultA' | 'defaultB' | 'overrideStart' | 'ov
       </div>
     </div>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class SimpleMatSortApp {
@@ -701,27 +537,6 @@ class SimpleMatSortApp {
     const sortElement = this.elementRef.nativeElement.querySelector(`#${id}`)!;
     dispatchMouseEvent(sortElement, event);
   }
-
-  /**
-   * Checks expectations for each sort header's view state and arrow direction states. Receives a
-   * map that is keyed by each sort header's ID and contains the expectation for that header's
-   * states.
-   */
-  expectViewAndDirectionStates(
-    viewStates: Map<string, {viewState: string; arrowDirection: string}>,
-  ) {
-    const sortHeaders = new Map([
-      ['defaultA', this.defaultA],
-      ['defaultB', this.defaultB],
-      ['overrideStart', this.overrideStart],
-      ['overrideDisableClear', this.overrideDisableClear],
-    ]);
-
-    viewStates.forEach((viewState, id) => {
-      expect(sortHeaders.get(id)!._getArrowViewState()).toEqual(viewState.viewState);
-      expect(sortHeaders.get(id)!._getArrowDirectionState()).toEqual(viewState.arrowDirection);
-    });
-  }
 }
 
 class FakeDataSource extends DataSource<any> {
@@ -753,7 +568,6 @@ class FakeDataSource extends DataSource<any> {
       <cdk-row *cdkRowDef="let row; columns: columnsToRender"></cdk-row>
     </cdk-table>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class CdkTableMatSortApp {
@@ -785,7 +599,6 @@ class CdkTableMatSortApp {
       <mat-row *matRowDef="let row; columns: columnsToRender"></mat-row>
     </mat-table>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class MatTableMatSortApp {
@@ -797,7 +610,6 @@ class MatTableMatSortApp {
 
 @Component({
   template: `<div mat-sort-header="a"> A </div>`,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class MatSortHeaderMissingMatSortApp {}
@@ -809,7 +621,6 @@ class MatSortHeaderMissingMatSortApp {}
       <div mat-sort-header="duplicateId"> A </div>
     </div>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class MatSortDuplicateMatSortableIdsApp {}
@@ -820,7 +631,6 @@ class MatSortDuplicateMatSortableIdsApp {}
       <div mat-sort-header> A </div>
     </div>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class MatSortableMissingIdApp {}
@@ -831,7 +641,6 @@ class MatSortableMissingIdApp {}
       <div mat-sort-header="a"> A </div>
     </div>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class MatSortableInvalidDirection {}
@@ -847,7 +656,6 @@ class MatSortableInvalidDirection {}
       </div>
     </div>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class MatSortWithoutExplicitInputs {
@@ -880,7 +688,6 @@ class MatSortWithoutExplicitInputs {
       </div>
     </div>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class MatSortWithArrowPosition {
@@ -901,7 +708,6 @@ class MatSortWithArrowPosition {
       </div>
     </div>
   `,
-  standalone: true,
   imports: [MatSortModule, MatTableModule, CdkTableModule],
 })
 class MatSortWithoutInputs {
diff --git a/src/material/sort/testing/sort-harness.spec.ts b/src/material/sort/testing/sort-harness.spec.ts
index f14d405aa46d..b5afa713b56c 100644
--- a/src/material/sort/testing/sort-harness.spec.ts
+++ b/src/material/sort/testing/sort-harness.spec.ts
@@ -137,7 +137,6 @@ describe('MatSortHarness', () => {
       }
     </table>
   `,
-  standalone: true,
   imports: [MatSortModule],
 })
 class SortHarnessTest {
diff --git a/src/material/stepper/step-header.ts b/src/material/stepper/step-header.ts
index 8ea45ff83158..38240eb3ced8 100644
--- a/src/material/stepper/step-header.ts
+++ b/src/material/stepper/step-header.ts
@@ -76,10 +76,10 @@ export class MatStepHeader extends CdkStepHeader implements AfterViewInit, OnDes
 
   /**
    * Theme color of the step header. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/stepper/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette;
 
diff --git a/src/material/stepper/stepper-module.ts b/src/material/stepper/stepper-module.ts
index 838518646d46..8b6c63fbb46e 100644
--- a/src/material/stepper/stepper-module.ts
+++ b/src/material/stepper/stepper-module.ts
@@ -8,7 +8,6 @@
 
 import {PortalModule} from '@angular/cdk/portal';
 import {CdkStepperModule} from '@angular/cdk/stepper';
-import {CommonModule} from '@angular/common';
 import {NgModule} from '@angular/core';
 import {ErrorStateMatcher, MatCommonModule, MatRippleModule} from '@angular/material/core';
 import {MatIconModule} from '@angular/material/icon';
@@ -23,7 +22,6 @@ import {MatStepContent} from './step-content';
 @NgModule({
   imports: [
     MatCommonModule,
-    CommonModule,
     PortalModule,
     CdkStepperModule,
     MatIconModule,
diff --git a/src/material/stepper/stepper.spec.ts b/src/material/stepper/stepper.spec.ts
index a57c5bb326cd..ea1d4a38050e 100644
--- a/src/material/stepper/stepper.spec.ts
+++ b/src/material/stepper/stepper.spec.ts
@@ -1923,7 +1923,6 @@ class SimpleMatVerticalStepperApp {
 }
 
 @Component({
-  standalone: true,
   template: `
     <mat-stepper orientation="vertical" linear>
       <mat-step [stepControl]="oneGroup">
diff --git a/src/material/stepper/stepper.ts b/src/material/stepper/stepper.ts
index 1324db2c14a2..57f01ecbbe40 100644
--- a/src/material/stepper/stepper.ts
+++ b/src/material/stepper/stepper.ts
@@ -30,7 +30,7 @@ import {AbstractControl, FormGroupDirective, NgForm} from '@angular/forms';
 import {ErrorStateMatcher, ThemePalette} from '@angular/material/core';
 import {CdkPortalOutlet, TemplatePortal} from '@angular/cdk/portal';
 import {Subject, Subscription} from 'rxjs';
-import {takeUntil, distinctUntilChanged, map, startWith, switchMap} from 'rxjs/operators';
+import {takeUntil, map, startWith, switchMap} from 'rxjs/operators';
 
 import {MatStepHeader} from './step-header';
 import {MatStepLabel} from './step-label';
@@ -70,10 +70,10 @@ export class MatStep extends CdkStep implements ErrorStateMatcher, AfterContentI
 
   /**
    * Theme color for the particular step. This API is supported in M2 themes
-   * only, it has no effect in M3 themes.
+   * only, it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/stepper/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette;
 
@@ -167,10 +167,10 @@ export class MatStepper extends CdkStepper implements AfterContentInit {
 
   /**
    * Theme color for all of the steps in stepper. This API is supported in M2
-   * themes only, it has no effect in M3 themes.
+   * themes only, it has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/stepper/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette;
 
@@ -226,19 +226,11 @@ export class MatStepper extends CdkStepper implements AfterContentInit {
       this._stateChanged();
     });
 
-    this._animationDone
-      .pipe(
-        // This needs a `distinctUntilChanged` in order to avoid emitting the same event twice due
-        // to a bug in animations where the `.done` callback gets invoked twice on some browsers.
-        // See https://github.com/angular/angular/issues/24084
-        distinctUntilChanged((x, y) => x.fromState === y.fromState && x.toState === y.toState),
-        takeUntil(this._destroyed),
-      )
-      .subscribe(event => {
-        if ((event.toState as StepContentPositionState) === 'current') {
-          this.animationDone.emit();
-        }
-      });
+    this._animationDone.pipe(takeUntil(this._destroyed)).subscribe(event => {
+      if ((event.toState as StepContentPositionState) === 'current') {
+        this.animationDone.emit();
+      }
+    });
   }
 
   _stepIsNavigable(index: number, step: MatStep): boolean {
diff --git a/src/material/stepper/testing/stepper-harness.spec.ts b/src/material/stepper/testing/stepper-harness.spec.ts
index dbe03cf1159c..3755becf1e5e 100644
--- a/src/material/stepper/testing/stepper-harness.spec.ts
+++ b/src/material/stepper/testing/stepper-harness.spec.ts
@@ -301,7 +301,6 @@ describe('MatStepperHarness', () => {
       </mat-step>
     </mat-stepper>
   `,
-  standalone: true,
   imports: [MatStepperModule, ReactiveFormsModule],
 })
 class StepperHarnessTest {
diff --git a/src/material/table/table-data-source.ts b/src/material/table/table-data-source.ts
index 5b85e23435f9..a5bcb8fc81b6 100644
--- a/src/material/table/table-data-source.ts
+++ b/src/material/table/table-data-source.ts
@@ -229,23 +229,12 @@ export class MatTableDataSource<T, P extends MatPaginator = MatPaginator> extend
    * @returns Whether the filter matches against the data
    */
   filterPredicate: (data: T, filter: string) => boolean = (data: T, filter: string): boolean => {
-    // Transform the data into a lowercase string of all property values.
-    const dataStr = Object.keys(data as unknown as Record<string, any>)
-      .reduce((currentTerm: string, key: string) => {
-        // Use an obscure Unicode character to delimit the words in the concatenated string.
-        // This avoids matches where the values of two columns combined will match the user's query
-        // (e.g. `Flute` and `Stop` will match `Test`). The character is intended to be something
-        // that has a very low chance of being typed in by somebody in a text field. This one in
-        // particular is "White up-pointing triangle with dot" from
-        // https://en.wikipedia.org/wiki/List_of_Unicode_characters
-        return currentTerm + (data as unknown as Record<string, any>)[key] + '◬';
-      }, '')
-      .toLowerCase();
-
     // Transform the filter by converting it to lowercase and removing whitespace.
     const transformedFilter = filter.trim().toLowerCase();
-
-    return dataStr.indexOf(transformedFilter) != -1;
+    // Loops over the values in the array and returns true if any of them match the filter string
+    return Object.values(data as {[key: string]: any}).some(value =>
+      `${value}`.toLowerCase().includes(transformedFilter),
+    );
   };
 
   constructor(initialData: T[] = []) {
diff --git a/src/material/table/table.scss b/src/material/table/table.scss
index d4cfe5707701..1d36a2e3d830 100644
--- a/src/material/table/table.scss
+++ b/src/material/table/table.scss
@@ -102,6 +102,10 @@
     [dir='rtl'] & {
       text-align: right;
     }
+
+    .mdc-data-table__row:last-child > & {
+      border-bottom: none;
+    }
   }
 
   .mat-mdc-cell {
@@ -109,7 +113,7 @@
     @include token-utils.create-token-slot(letter-spacing, row-item-label-text-tracking);
     line-height: inherit;
 
-    .mdc-data-table__row:last-child & {
+    .mdc-data-table__row:last-child > & {
       border-bottom: none;
     }
   }
diff --git a/src/material/table/table.spec.ts b/src/material/table/table.spec.ts
index fee8085f6fa8..2dbc82426740 100644
--- a/src/material/table/table.spec.ts
+++ b/src/material/table/table.spec.ts
@@ -720,7 +720,6 @@ class FakeDataSource extends DataSource<TestData> {
       <tr mat-footer-row *matFooterRowDef="columnsToRender"></tr>
     </table>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class MatTableApp {
@@ -756,7 +755,6 @@ class MatTableApp {
       </tr>
     </table>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class NativeHtmlTableApp {
@@ -811,7 +809,6 @@ class NativeHtmlTableApp {
       <tr mat-row *matRowDef="let row; columns: columnsToRender"></tr>
     </table>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class NestedTableApp {
@@ -831,7 +828,6 @@ class NestedTableApp {
       <tr mat-row *matRowDef="let row; columns: columnsToRender"></tr>
     </table>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class StickyTableApp {
@@ -860,7 +856,6 @@ class StickyTableApp {
       <tr mat-footer-row *matFooterRowDef="['column_a']"></tr>
     </table>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class MatTableWithWhenRowApp {
@@ -899,7 +894,6 @@ class MatTableWithWhenRowApp {
 
     <mat-paginator [pageSize]="5"></mat-paginator>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class ArrayDataSourceMatTableApp implements AfterViewInit {
@@ -953,7 +947,6 @@ class ArrayDataSourceMatTableApp implements AfterViewInit {
       <tr mat-row *matRowDef="let row; columns: columnsToRender"></tr>
     </table>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class MatTableWithSortApp implements OnInit {
@@ -1006,7 +999,6 @@ class MatTableWithSortApp implements OnInit {
 
     <mat-paginator [pageSize]="5"></mat-paginator>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class MatTableWithPaginatorApp implements OnInit {
@@ -1049,7 +1041,6 @@ class MatTableWithPaginatorApp implements OnInit {
       </ng-container>
     </table>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class TableWithNgContainerRow {
@@ -1088,7 +1079,6 @@ class TableWithNgContainerRow {
       <mat-footer-row *matFooterRowDef="columnsToRender"></mat-footer-row>
     </mat-table>
   `,
-  standalone: true,
   imports: [MatTableModule, MatPaginatorModule, MatSortModule],
 })
 class MatFlexTableApp {
diff --git a/src/material/table/testing/table-harness.spec.ts b/src/material/table/testing/table-harness.spec.ts
index b2c4c41b650e..eb8426f88120 100644
--- a/src/material/table/testing/table-harness.spec.ts
+++ b/src/material/table/testing/table-harness.spec.ts
@@ -214,7 +214,6 @@ describe('MatTableHarness', () => {
       <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
     </table>
   `,
-  standalone: true,
   imports: [MatTableModule],
 })
 class TableHarnessTest {
diff --git a/src/material/tabs/ink-bar.ts b/src/material/tabs/ink-bar.ts
index 77da049c500d..d742222b98f9 100644
--- a/src/material/tabs/ink-bar.ts
+++ b/src/material/tabs/ink-bar.ts
@@ -48,6 +48,7 @@ export class MatInkBar {
   /** Hides the ink bar. */
   hide() {
     this._items.forEach(item => item.deactivateInkBar());
+    this._currentItem = undefined;
   }
 
   /** Aligns the ink bar to a DOM node. */
diff --git a/src/material/tabs/tab-body.spec.ts b/src/material/tabs/tab-body.spec.ts
index 3511c7939ed3..71ac2ffdb376 100644
--- a/src/material/tabs/tab-body.spec.ts
+++ b/src/material/tabs/tab-body.spec.ts
@@ -215,7 +215,6 @@ describe('MatTabBody', () => {
     <ng-template>Tab Body Content</ng-template>
     <mat-tab-body [content]="content()" [position]="position" [origin]="origin"></mat-tab-body>
   `,
-  standalone: true,
   imports: [PortalModule, MatRippleModule, MatTabBody],
 })
 class SimpleTabBodyApp implements AfterViewInit {
diff --git a/src/material/tabs/tab-group.spec.ts b/src/material/tabs/tab-group.spec.ts
index e70bad58464e..f60b3c232df2 100644
--- a/src/material/tabs/tab-group.spec.ts
+++ b/src/material/tabs/tab-group.spec.ts
@@ -1301,7 +1301,6 @@ describe('MatTabGroup labels aligned with a config', () => {
       </mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class SimpleTabsTestApp {
@@ -1339,7 +1338,6 @@ class SimpleTabsTestApp {
       }
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class SimpleDynamicTabsTestApp {
@@ -1368,7 +1366,6 @@ class SimpleDynamicTabsTestApp {
       }
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class BindedTabsTestApp {
@@ -1404,7 +1401,6 @@ class BindedTabsTestApp {
       </mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class DisabledTabsTestApp {
@@ -1423,7 +1419,6 @@ class DisabledTabsTestApp {
       }
    </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule, AsyncPipe],
 })
 class AsyncTabsTestApp implements OnInit {
@@ -1451,7 +1446,6 @@ class AsyncTabsTestApp implements OnInit {
     <mat-tab label="Legumes"> <p #legumes>Peanuts</p> </mat-tab>
   </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabGroupWithSimpleApi {
@@ -1474,7 +1468,6 @@ class TabGroupWithSimpleApi {
       </mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class NestedTabs {
@@ -1494,7 +1487,6 @@ class NestedTabs {
       </mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TemplateTabs {}
@@ -1505,7 +1497,6 @@ class TemplateTabs {}
     <mat-tab [aria-label]="ariaLabel" [aria-labelledby]="ariaLabelledby"></mat-tab>
   </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabGroupWithAriaInputs {
@@ -1524,7 +1515,6 @@ class TabGroupWithAriaInputs {
       <div>pizza is active</div>
     }
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabGroupWithIsActiveBinding {}
@@ -1536,7 +1526,6 @@ class TabGroupWithIsActiveBinding {}
       <mat-tab label="Two">Tab two content</mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabsWithCustomAnimationDuration {}
@@ -1550,7 +1539,6 @@ class TabsWithCustomAnimationDuration {}
       }
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabGroupWithIndirectDescendantTabs {
@@ -1564,7 +1552,6 @@ class TabGroupWithIndirectDescendantTabs {
       <mat-tab label="Two">Tab two content</mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabGroupWithInkBarFitToContent {
@@ -1587,7 +1574,6 @@ class TabGroupWithInkBarFitToContent {
       </ng-container>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabGroupWithSpaceAbove {
@@ -1611,7 +1597,6 @@ class TabGroupWithSpaceAbove {
       <mat-tab label="Parent 3">Parent 3</mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class NestedTabGroupWithLabel {}
@@ -1628,7 +1613,6 @@ class NestedTabGroupWithLabel {}
       </mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabsWithClassesTestApp {
@@ -1647,7 +1631,6 @@ class TabsWithClassesTestApp {
       </mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabsWithAlignConfig {}
@@ -1663,7 +1646,6 @@ class TabsWithAlignConfig {}
       </mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabsWithAlignCenter {}
diff --git a/src/material/tabs/tab-group.ts b/src/material/tabs/tab-group.ts
index 023550b73109..d585ea3d9cf2 100644
--- a/src/material/tabs/tab-group.ts
+++ b/src/material/tabs/tab-group.ts
@@ -32,15 +32,12 @@ import {ThemePalette, MatRipple} from '@angular/material/core';
 import {merge, Subscription} from 'rxjs';
 import {MAT_TABS_CONFIG, MatTabsConfig} from './tab-config';
 import {startWith} from 'rxjs/operators';
-import {CdkMonitorFocus, FocusOrigin} from '@angular/cdk/a11y';
+import {_IdGenerator, CdkMonitorFocus, FocusOrigin} from '@angular/cdk/a11y';
 import {MatTabBody} from './tab-body';
 import {CdkPortalOutlet} from '@angular/cdk/portal';
 import {MatTabLabelWrapper} from './tab-label-wrapper';
 import {Platform} from '@angular/cdk/platform';
 
-/** Used to generate unique ID's for each tab component */
-let nextId = 0;
-
 /** @docs-private */
 export interface MatTabGroupBaseHeader {
   _alignInkBarToSelectedTab(): void;
@@ -124,10 +121,10 @@ export class MatTabGroup implements AfterContentInit, AfterContentChecked, OnDes
 
   /**
    * Theme color of the tab group. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/tabs/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   color: ThemePalette;
@@ -217,10 +214,10 @@ export class MatTabGroup implements AfterContentInit, AfterContentChecked, OnDes
 
   /**
    * Theme color of the background of the tab group. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/tabs/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    *
    * @deprecated The background color should be customized through Sass theming APIs.
    * @breaking-change 20.0.0 Remove this input
@@ -268,7 +265,7 @@ export class MatTabGroup implements AfterContentInit, AfterContentChecked, OnDes
   @Output() readonly selectedTabChange: EventEmitter<MatTabChangeEvent> =
     new EventEmitter<MatTabChangeEvent>(true);
 
-  private _groupId: number;
+  private _groupId: string;
 
   /** Whether the tab group is rendered on the server. */
   protected _isServer: boolean = !inject(Platform).isBrowser;
@@ -278,7 +275,7 @@ export class MatTabGroup implements AfterContentInit, AfterContentChecked, OnDes
   constructor() {
     const defaultConfig = inject<MatTabsConfig>(MAT_TABS_CONFIG, {optional: true});
 
-    this._groupId = nextId++;
+    this._groupId = inject(_IdGenerator).getId('mat-tab-group-');
     this.animationDuration =
       defaultConfig && defaultConfig.animationDuration ? defaultConfig.animationDuration : '500ms';
     this.disablePagination =
@@ -492,12 +489,12 @@ export class MatTabGroup implements AfterContentInit, AfterContentChecked, OnDes
 
   /** Returns a unique id for each tab label element */
   _getTabLabelId(i: number): string {
-    return `mat-tab-label-${this._groupId}-${i}`;
+    return `${this._groupId}-label-${i}`;
   }
 
   /** Returns a unique id for each tab content element */
   _getTabContentId(i: number): string {
-    return `mat-tab-content-${this._groupId}-${i}`;
+    return `${this._groupId}-content-${i}`;
   }
 
   /**
diff --git a/src/material/tabs/tab-header.spec.ts b/src/material/tabs/tab-header.spec.ts
index 2b2e41dc4797..2e56a2f211f6 100644
--- a/src/material/tabs/tab-header.spec.ts
+++ b/src/material/tabs/tab-header.spec.ts
@@ -754,7 +754,6 @@ interface Tab {
       width: 130px;
     }
   `,
-  standalone: true,
   imports: [Dir, MatTabHeader, MatTabLabelWrapper],
 })
 class SimpleTabHeaderApp {
diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts b/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts
index 8addcbd7302c..f3cb50704c18 100644
--- a/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts
+++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts
@@ -357,6 +357,28 @@ describe('MatTabNavBar', () => {
     expect(tabLinks[1].classList.contains('mdc-tab--active')).toBe(true);
   });
 
+  it('should re-show the ink bar if the same tab is cleared and re-activated', fakeAsync(() => {
+    const getInkBars = () =>
+      fixture.nativeElement.querySelectorAll('.mdc-tab-indicator--active').length;
+    const fixture = TestBed.createComponent(SimpleTabNavBarTestApp);
+    fixture.componentInstance.activeIndex = 0;
+    fixture.detectChanges();
+    tick(20);
+    expect(getInkBars()).toBe(1);
+
+    fixture.componentInstance.activeIndex = -1;
+    fixture.changeDetectorRef.markForCheck();
+    fixture.detectChanges();
+    tick(20);
+    expect(getInkBars()).toBe(0);
+
+    fixture.componentInstance.activeIndex = 0;
+    fixture.changeDetectorRef.markForCheck();
+    fixture.detectChanges();
+    tick(20);
+    expect(getInkBars()).toBe(1);
+  }));
+
   describe('ripples', () => {
     let fixture: ComponentFixture<SimpleTabNavBarTestApp>;
 
@@ -551,7 +573,6 @@ describe('MatTabNavBar with enabled animations', () => {
     </nav>
     <mat-tab-nav-panel #tabPanel id="tab-panel">Tab panel</mat-tab-nav-panel>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class SimpleTabNavBarTestApp {
@@ -577,7 +598,6 @@ class SimpleTabNavBarTestApp {
     </nav>
     <mat-tab-nav-panel #tabPanel>Tab panel</mat-tab-nav-panel>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabLinkWithNgIf {
@@ -593,7 +613,6 @@ class TabLinkWithNgIf {
     </nav>
     <mat-tab-nav-panel #tabPanel>Tab panel</mat-tab-nav-panel>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabBarWithInactiveTabsOnInit {
@@ -609,7 +628,6 @@ class TabBarWithInactiveTabsOnInit {
   </nav>
   <mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>,
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabsWithCustomAnimationDuration {
diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts
index f8f456ba4a29..3428d3721737 100644
--- a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts
+++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts
@@ -6,7 +6,6 @@
  * found in the LICENSE file at https://angular.dev/license
  */
 import {
-  AfterContentChecked,
   AfterContentInit,
   AfterViewInit,
   booleanAttribute,
@@ -36,7 +35,7 @@ import {
   ThemePalette,
   _StructuralStylesLoader,
 } from '@angular/material/core';
-import {FocusableOption, FocusMonitor} from '@angular/cdk/a11y';
+import {_IdGenerator, FocusableOption, FocusMonitor} from '@angular/cdk/a11y';
 import {Directionality} from '@angular/cdk/bidi';
 import {ViewportRuler} from '@angular/cdk/scrolling';
 import {Platform} from '@angular/cdk/platform';
@@ -49,9 +48,6 @@ import {MatPaginatedTabHeader} from '../paginated-tab-header';
 import {CdkObserveContent} from '@angular/cdk/observers';
 import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
 
-// Increasing integer for generating unique ids for tab nav components.
-let nextUniqueId = 0;
-
 /**
  * Navigation component matching the styles of the tab group header.
  * Provides anchored navigation with animated ink bar.
@@ -78,10 +74,7 @@ let nextUniqueId = 0;
   changeDetection: ChangeDetectionStrategy.Default,
   imports: [MatRipple, CdkObserveContent],
 })
-export class MatTabNav
-  extends MatPaginatedTabHeader
-  implements AfterContentChecked, AfterContentInit, OnDestroy, AfterViewInit
-{
+export class MatTabNav extends MatPaginatedTabHeader implements AfterContentInit, AfterViewInit {
   /** Whether the ink bar should fit its width to the size of the tab label content. */
   @Input({transform: booleanAttribute})
   get fitInkBarToContent(): boolean {
@@ -114,10 +107,10 @@ export class MatTabNav
 
   /**
    * Theme color of the background of the tab nav. This API is supported in M2 themes only, it
-   * has no effect in M3 themes.
+   * has no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/tabs/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input()
   get backgroundColor(): ThemePalette {
@@ -143,10 +136,10 @@ export class MatTabNav
 
   /**
    * Theme color of the nav bar. This API is supported in M2 themes only, it has
-   * no effect in M3 themes.
+   * no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/tabs/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color: ThemePalette = 'primary';
 
@@ -197,9 +190,9 @@ export class MatTabNav
     this._inkBar = new MatInkBar(this._items);
     // We need this to run before the `changes` subscription in parent to ensure that the
     // selectedIndex is up-to-date by the time the super class starts looking for it.
-    this._items.changes.pipe(startWith(null), takeUntil(this._destroyed)).subscribe(() => {
-      this.updateActiveLink();
-    });
+    this._items.changes
+      .pipe(startWith(null), takeUntil(this._destroyed))
+      .subscribe(() => this.updateActiveLink());
 
     super.ngAfterContentInit();
   }
@@ -232,9 +225,7 @@ export class MatTabNav
       }
     }
 
-    // The ink bar should hide itself if no items are active.
     this.selectedIndex = -1;
-    this._inkBar.hide();
   }
 
   _getRole(): string | null {
@@ -329,7 +320,7 @@ export class MatTabLink
   }
 
   /** Unique id for the tab. */
-  @Input() id = `mat-tab-link-${nextUniqueId++}`;
+  @Input() id: string = inject(_IdGenerator).getId('mat-tab-link-');
 
   constructor(...args: unknown[]);
 
@@ -444,7 +435,7 @@ export class MatTabLink
 })
 export class MatTabNavPanel {
   /** Unique id for the tab panel. */
-  @Input() id = `mat-tab-nav-panel-${nextUniqueId++}`;
+  @Input() id: string = inject(_IdGenerator).getId('mat-tab-nav-panel-');
 
   /** Id of the active tab in the nav bar. */
   _activeTabId?: string;
diff --git a/src/material/tabs/testing/tab-group-harness.spec.ts b/src/material/tabs/testing/tab-group-harness.spec.ts
index eaf0d73490ef..1bb0abfc32f1 100644
--- a/src/material/tabs/testing/tab-group-harness.spec.ts
+++ b/src/material/tabs/testing/tab-group-harness.spec.ts
@@ -174,7 +174,6 @@ describe('MatTabGroupHarness', () => {
       </mat-tab>
     </mat-tab-group>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabGroupHarnessTest {
diff --git a/src/material/tabs/testing/tab-nav-bar-harness.spec.ts b/src/material/tabs/testing/tab-nav-bar-harness.spec.ts
index 259add2a8fe6..510abdb65c4d 100644
--- a/src/material/tabs/testing/tab-nav-bar-harness.spec.ts
+++ b/src/material/tabs/testing/tab-nav-bar-harness.spec.ts
@@ -111,7 +111,6 @@ describe('MatTabNavBarHarness', () => {
       Tab content
     </mat-tab-nav-panel>
   `,
-  standalone: true,
   imports: [MatTabsModule],
 })
 class TabNavBarHarnessTest {
diff --git a/src/material/timepicker/testing/timepicker-harness.spec.ts b/src/material/timepicker/testing/timepicker-harness.spec.ts
index bc670144dc6c..838dba190b21 100644
--- a/src/material/timepicker/testing/timepicker-harness.spec.ts
+++ b/src/material/timepicker/testing/timepicker-harness.spec.ts
@@ -74,7 +74,6 @@ describe('MatTimepickerHarness', () => {
     <input id="two" [matTimepicker]="twoPicker">
     <mat-timepicker #twoPicker [interval]="interval()"/>
   `,
-  standalone: true,
   imports: [MatTimepickerInput, MatTimepicker],
 })
 class TimepickerHarnessTest {
diff --git a/src/material/timepicker/testing/timepicker-input-harness.spec.ts b/src/material/timepicker/testing/timepicker-input-harness.spec.ts
index 5ee6a178a985..90c14aaeaabc 100644
--- a/src/material/timepicker/testing/timepicker-input-harness.spec.ts
+++ b/src/material/timepicker/testing/timepicker-input-harness.spec.ts
@@ -170,7 +170,6 @@ describe('MatTimepickerInputHarness', () => {
     <input [matTimepicker]="basicPicker" id="basic" placeholder="Select a time">
     <mat-timepicker #basicPicker/>
   `,
-  standalone: true,
   imports: [MatTimepickerInput, MatTimepicker],
 })
 class TimepickerInputHarnessTest {
diff --git a/src/material/timepicker/testing/timepicker-toggle-harness.spec.ts b/src/material/timepicker/testing/timepicker-toggle-harness.spec.ts
index d6d87b8ca072..c1e48bbb0898 100644
--- a/src/material/timepicker/testing/timepicker-toggle-harness.spec.ts
+++ b/src/material/timepicker/testing/timepicker-toggle-harness.spec.ts
@@ -56,7 +56,6 @@ describe('MatTimepickerToggleHarness', () => {
     <mat-timepicker #twoPicker/>
     <mat-timepicker-toggle id="two" [for]="twoPicker" [disabled]="disabled()"/>
   `,
-  standalone: true,
   imports: [MatTimepickerInput, MatTimepicker, MatTimepickerToggle],
 })
 class TimepickerHarnessTest {
diff --git a/src/material/timepicker/timepicker-input.ts b/src/material/timepicker/timepicker-input.ts
index 05433d3512ba..2319299120c9 100644
--- a/src/material/timepicker/timepicker-input.ts
+++ b/src/material/timepicker/timepicker-input.ts
@@ -20,6 +20,7 @@ import {
   ModelSignal,
   OnDestroy,
   OutputRefSubscription,
+  Renderer2,
   Signal,
   signal,
 } from '@angular/core';
@@ -89,11 +90,12 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
   private _onChange: ((value: any) => void) | undefined;
   private _onTouched: (() => void) | undefined;
   private _validatorOnChange: (() => void) | undefined;
+  private _cleanupClick: () => void;
   private _accessorDisabled = signal(false);
   private _localeSubscription: Subscription;
   private _timepickerSubscription: OutputRefSubscription | undefined;
   private _validator: ValidatorFn;
-  private _lastValueValid = false;
+  private _lastValueValid = true;
   private _lastValidDate: D | null = null;
 
   /** Value of the `aria-activedescendant` attribute. */
@@ -144,8 +146,11 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
     () => this.disabledInput() || this._accessorDisabled(),
   );
 
-  /** Whether the input should be disabled through the template. */
-  protected readonly disabledInput: InputSignalWithTransform<boolean, unknown> = input(false, {
+  /**
+   * Whether the input should be disabled through the template.
+   * @docs-private
+   */
+  readonly disabledInput: InputSignalWithTransform<boolean, unknown> = input(false, {
     transform: booleanAttribute,
     alias: 'disabled',
   });
@@ -155,6 +160,7 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
       validateAdapter(this._dateAdapter, this._dateFormats);
     }
 
+    const renderer = inject(Renderer2);
     this._validator = this._getValidator();
     this._respondToValueChanges();
     this._respondToMinMaxChanges();
@@ -167,7 +173,11 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
 
     // Bind the click listener manually to the overlay origin, because we want the entire
     // form field to be clickable, if the timepicker is used in `mat-form-field`.
-    this.getOverlayOrigin().nativeElement.addEventListener('click', this._handleClick);
+    this._cleanupClick = renderer.listen(
+      this.getOverlayOrigin().nativeElement,
+      'click',
+      this._handleClick,
+    );
   }
 
   /**
@@ -175,7 +185,11 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
    * @docs-private
    */
   writeValue(value: any): void {
-    this.value.set(this._dateAdapter.getValidDateOrNull(value));
+    // Note that we need to deserialize here, rather than depend on the value change effect,
+    // because `getValidDateOrNull` will clobber the value if it's parseable, but not created by
+    // the current adapter (see #30140).
+    const deserialized = this._dateAdapter.deserialize(value);
+    this.value.set(this._dateAdapter.getValidDateOrNull(deserialized));
   }
 
   /**
@@ -229,7 +243,7 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
   }
 
   ngOnDestroy(): void {
-    this.getOverlayOrigin().nativeElement.removeEventListener('click', this._handleClick);
+    this._cleanupClick();
     this._timepickerSubscription?.unsubscribe();
     this._localeSubscription.unsubscribe();
   }
@@ -241,7 +255,9 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
 
   /** Handles clicks on the input or the containing form field. */
   private _handleClick = (): void => {
-    this.timepicker().open();
+    if (!this.disabled()) {
+      this.timepicker().open();
+    }
   };
 
   /** Handles the `input` event. */
@@ -269,13 +285,15 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
       this._formatValue(value);
     }
 
-    this._onTouched?.();
+    if (!this.timepicker().isOpen()) {
+      this._onTouched?.();
+    }
   }
 
   /** Handles the `keydown` event. */
   protected _handleKeydown(event: KeyboardEvent) {
     // All keyboard events while open are handled through the timepicker.
-    if (this.timepicker().isOpen()) {
+    if (this.timepicker().isOpen() || this.disabled()) {
       return;
     }
 
@@ -283,7 +301,7 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
       event.preventDefault();
       this.value.set(null);
       this._formatValue(null);
-    } else if ((event.keyCode === DOWN_ARROW || event.keyCode === UP_ARROW) && !this.disabled()) {
+    } else if (event.keyCode === DOWN_ARROW || event.keyCode === UP_ARROW) {
       event.preventDefault();
       this.timepicker().open();
     }
diff --git a/src/material/timepicker/timepicker-toggle.html b/src/material/timepicker/timepicker-toggle.html
index dab7a3d38c84..ef15001b8e5a 100644
--- a/src/material/timepicker/timepicker-toggle.html
+++ b/src/material/timepicker/timepicker-toggle.html
@@ -4,8 +4,8 @@
   aria-haspopup="listbox"
   [attr.aria-label]="ariaLabel()"
   [attr.aria-expanded]="timepicker().isOpen()"
-  [attr.tabindex]="disabled() ? -1 : tabIndex()"
-  [disabled]="disabled()"
+  [attr.tabindex]="_isDisabled() ? -1 : tabIndex()"
+  [disabled]="_isDisabled()"
   [disableRipple]="disableRipple()">
 
   <ng-content select="[matTimepickerToggleIcon]">
diff --git a/src/material/timepicker/timepicker-toggle.ts b/src/material/timepicker/timepicker-toggle.ts
index 7e88a18f405a..9bf902390a16 100644
--- a/src/material/timepicker/timepicker-toggle.ts
+++ b/src/material/timepicker/timepicker-toggle.ts
@@ -10,6 +10,7 @@ import {
   booleanAttribute,
   ChangeDetectionStrategy,
   Component,
+  computed,
   HostAttributeToken,
   inject,
   input,
@@ -46,6 +47,11 @@ export class MatTimepickerToggle<D> {
     return isNaN(parsed) ? null : parsed;
   })();
 
+  protected _isDisabled = computed(() => {
+    const timepicker = this.timepicker();
+    return this.disabled() || timepicker.disabled();
+  });
+
   /** Timepicker instance that the button will toggle. */
   readonly timepicker: InputSignal<MatTimepicker<D>> = input.required<MatTimepicker<D>>({
     alias: 'for',
@@ -73,7 +79,7 @@ export class MatTimepickerToggle<D> {
 
   /** Opens the connected timepicker. */
   protected _open(event: Event): void {
-    if (this.timepicker() && !this.disabled()) {
+    if (this.timepicker() && !this._isDisabled()) {
       this.timepicker().open();
       event.stopPropagation();
     }
diff --git a/src/material/timepicker/timepicker.md b/src/material/timepicker/timepicker.md
index 1333ed77b7e1..820e5aff6722 100644
--- a/src/material/timepicker/timepicker.md
+++ b/src/material/timepicker/timepicker.md
@@ -1 +1,313 @@
-TODO
+The Angular Material Timepicker allows users to set the time portion of a date object either by
+typing it in or by selecting it from a list of pre-defined options.
+
+<!-- example(timepicker-overview) -->
+
+### Connecting a timepicker to an input
+
+A timepicker is composed of a text input and a dropdown menu, connected through the `matTimepicker`
+binding on the input.
+
+There is also an optional timepicker toggle button that gives the user an easy way to open the dropdown.
+
+<!-- example({"example":"timepicker-overview",
+              "file":"timepicker-overview-example.html",
+              "region":"minimum-setup"}) -->
+
+The timepicker input and toggle can be used either on their own or as a part of a `mat-form-field`:
+
+<!-- example({"example":"timepicker-overview",
+              "file":"timepicker-overview-example.html"}) -->
+
+### Timepicker forms integration
+
+The timepicker input integrates with the `@angular/forms` module by providing itself as a
+`ControlValueAccessor` and a `Validator` (see [Input validation](#input-validation) below for more
+information). When the user types in a new time or selects one from the dropdown, the
+time will be set on the date object which is the current value of the form control. If the form
+control doesn't have a value, the timepicker will create one with today's date and the selected
+time.
+
+<!-- example(timepicker-forms) -->
+
+
+### Integration with `MatDatepicker`
+
+Material's datepicker and timepicker components can operate over the same value, allowing for a
+combined datetime picker to be implemented. When binding the two components to the same value, the
+datepicker will set the entire date object while the timepicker will only modify the time portion
+of it.
+
+<!-- example(timepicker-datepicker-integration) -->
+
+### Input validation
+
+The timepicker input checks that the value typed in by the user is a valid time string and
+whether it fits into the specified bounds.
+
+If the user types in an invalid time string (for example `abc` or `24:67`), the timepicker input
+will report the `matTimepickerParse` error. The string is parsed using the `parseTime` method of
+the [the current date implementation](#choosing-a-date-implementation-and-format-settings).
+
+The timepicker input also checks that the value typed in by the user fits within the minimum and
+maximum bounds set through the `matTimepickerMin` and `matTimepickerMax` inputs. They accept either
+a date object with a specific time or a time string. The inputs also control which times will be
+shown inside of the dropdown menu. For example, setting `matTimepickerMin="12:30"` and
+`matTimepickerMax="21:25"` will allow the user to only select a time between 12:30 in the afternoon
+and 9:25 in the evening. If the value is outside of those bounds, either a `maxTimepickerMin` or
+`matTimepickerMax` error will be reported to the value accessor.
+
+<!-- example(timepicker-validation) -->
+
+
+### Customizing the dropdown options
+
+By default the `mat-timepicker` dropdown shows options at 30 minute intervals. You can customize the
+list of options either by setting an interval or providing a custom set of options.
+
+The easiest way is to change the options is to pass the `interval` input to `mat-timepicker` with
+an interval string which will be used when generating the options. For example,
+`<mat-timepicker interval="90m"/>` will show the options at 90 minute intervals, starting from the
+minimum time and ending at the maximum. Valid interval strings include:
+* A number which will be interpreted as minutes, e.g. `interval="50"` represents 50 minutes.
+* A number with short units, for example `30m` represents 30 minutes while `5h` is 5 hours.
+Supported short units include `h` or `H` for hours, `m` or `M` for minutes and `s` or `S` for seconds.
+* A number with long units, for example `75 min` represents 75 minutes while `1.5 hours` is an hour
+and a half. Supported long units include `min` or `minute` or `minutes` for minutes, `hour` or `hours` for
+hours and `second` or `seconds` for seconds.
+
+Furthermore, the default interval can be controlled for the entire application using the
+`MAT_TIMEPICKER_CONFIG` injection token. For example, adding the following to your `providers` will
+default all timepickers to a 90 minute interval:
+
+```ts
+import {MAT_TIMEPICKER_CONFIG} from '@angular/material/timepicker';
+
+{
+  provide: MAT_TIMEPICKER_CONFIG,
+  useValue: {interval: '90 minutes'},
+}
+```
+
+If your app requires more fine-grained control over the options, you can pass in an array of
+options into `mat-timepicker` instead. Note that the options need to match the `MatTimepickerOption`
+interface.
+
+<!-- example(timepicker-options) -->
+
+
+### Customizing the toggle icon
+
+`mat-timepicker-toggle` renders a clock icon by default. You can customize it by projecting in an
+element with the `matTimepickerToggleIcon` attribute into the toggle:
+
+<!-- example(timepicker-custom-icon) -->
+
+### Internationalization
+
+Internationalization of the timepicker uses the same date adapter as `mat-datepicker`. It is
+configured via three aspects:
+
+1.  The date locale.
+2.  The date implementation that the timepicker accepts.
+3.  The display and parse formats used by the timepicker.
+
+#### Setting the locale code
+
+By default, the `MAT_DATE_LOCALE` injection token will use the existing `LOCALE_ID` locale code
+from `@angular/core`. If you want to override it, you can provide a new value for the
+`MAT_DATE_LOCALE` token:
+
+```ts
+bootstapApplication(MyApp, {
+  providers: [{provide: MAT_DATE_LOCALE, useValue: 'en-GB'}],
+});
+```
+
+It's also possible to set the locale at runtime using the `setLocale` method of the `DateAdapter`.
+
+**Note:** if you're using the `provideDateFnsAdapter`, you have to provide the data object for your
+locale to `MAT_DATE_LOCALE` instead of the locale code, in addition to providing a configuration
+compatible with `date-fns` to `MAT_DATE_FORMATS`. Locale data for `date-fns` can be imported
+from `date-fns/locale`.
+
+<!-- example(timepicker-locale) -->
+
+#### Choosing a date implementation and format settings
+
+The timepicker is built to be implementation-agnostic and to be interoperable with
+`mat-datepicker`. This means that it can be made to work with a variety of different date
+implementations. However it also means that developers need to make sure to provide the
+appropriate pieces for the timepicker to work with their chosen implementation.
+
+The easiest way to ensure this is to import one of the provided date adapters:
+
+`provideNativeDateAdapter` or `MatNativeDateModule`
+
+<table>
+  <tbody>
+    <tr>
+      <th align="left" scope="row">Date type</th>
+      <td><code>Date</code></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Supported locales</th>
+      <td>Locales using either AM/PM or 24-hour formatting</td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Dependencies</th>
+      <td>None</td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Import from</th>
+      <td><code>@angular/material/core</code></td>
+    </tr>
+  </tbody>
+</table>
+
+`provideDateFnsAdapter` or `MatDateFnsModule` (installed via `ng add @angular/material-date-fns-adapter`)
+
+<table>
+  <tbody>
+    <tr>
+      <th align="left" scope="row">Date type</th>
+      <td><code>Date</code></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Supported locales</th>
+      <td><a href="https://github.com/date-fns/date-fns/tree/master/src/locale/">See project for details</a></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Dependencies</th>
+      <td><a href="https://date-fns.org/">date-fns</a></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Import from</th>
+      <td><code>@angular/material-date-fns-adapter</code></td>
+    </tr>
+  </tbody>
+</table>
+
+`provideLuxonDateAdapter` or `MatLuxonDateModule` (installed via `ng add @angular/material-luxon-adapter`)
+
+<table>
+  <tbody>
+    <tr>
+      <th align="left" scope="row">Date type</th>
+      <td><code>DateTime</code></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Supported locales</th>
+      <td><a href="https://moment.github.io/luxon/">See project for details</a></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Dependencies</th>
+      <td><a href="https://moment.github.io/luxon/">Luxon</a></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Import from</th>
+      <td><code>@angular/material-luxon-adapter</code></td>
+    </tr>
+  </tbody>
+</table>
+
+`provideMomentDateAdapter` or `MatMomentDateModule` (installed via `ng add @angular/material-moment-adapter`)
+
+<table>
+  <tbody>
+    <tr>
+      <th align="left" scope="row">Date type</th>
+      <td><code>Moment</code></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Supported locales</th>
+      <td><a href="https://github.com/moment/moment/tree/develop/src/locale">See project for details</a></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Dependencies</th>
+      <td><a href="https://momentjs.com/">Moment.js</a></td>
+    </tr>
+    <tr>
+      <th align="left" scope="row">Import from</th>
+      <td><code>@angular/material-moment-adapter</code></td>
+    </tr>
+  </tbody>
+</table>
+
+**Note**: `provideNativeDateAdapter` implements time parsing using a regex which means that it
+only supports AM/PM time (e.g. `1:45 PM`) or 24-hour time (e.g. `22:45` or `22.45`). As such
+it won't work on locales with different formatting. We recommend using one of the provided date
+adapters mentioned above or creating your own adapter by extending the `DateAdapter` class from
+`@angular/material/core`. For example, if you want to use the `date-fns` adapter, you can update
+your `bootstrapApplication` format to the following:
+
+```ts
+import {provideDateFnsAdapter} from '@angular/material-date-fns-adapter';
+
+bootstrapApplication(MyApp, {
+  providers: [provideDateFnsAdapter()]
+});
+```
+
+#### Customizing the parse and display formats
+
+The `MAT_DATE_FORMATS` object is a collection of formats that the timepicker uses when parsing
+and displaying date objects. These formats are passed through to the `DateAdapter` so you will want
+to make sure that the format objects you're providing are compatible with the `DateAdapter` used in
+your app.
+
+`MAT_DATE_FORMATS` is the same object used by `mat-datepicker` so it's likely already
+configured if your app is using the datepicker, but for the timepicker you need to ensure that the
+`display.timeInput`, `display.timeOptionLabel` and `parse.timeInput` properties are set as well.
+
+If you want use one of the `DateAdapters` that ships with Angular Material, but use your own
+`MAT_DATE_FORMATS`, you can either pass the formats into the providers function, or provide the
+`MAT_DATE_FORMATS` token yourself. For example:
+
+```ts
+bootstrapApplication(MyApp, {
+  providers: [provideNativeDateAdapter(MY_NATIVE_DATE_FORMATS)],
+});
+```
+
+### Accessibility
+
+The timepicker implements the [ARIA combobox interaction pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/).
+The timepicker input specifies `role="combobox"` while the content of the dropdown applies
+`role="listbox"` and the options within the dropdown apply `role="option"`. By default the listbox
+is labelled from the `mat-form-field` it is placed in, but if you aren't using a form field or if
+you want to customize the label, you can do so through the `ariaLabel` or `ariaLabelledby` inputs
+on `mat-timepicker`.
+
+### Troubleshooting
+
+#### Error: MatTimepicker: No provider found for DateAdapter/MAT_DATE_FORMATS
+
+This error is thrown if you haven't provided all of the injectables the timepicker needs in order to
+work correctly. The easiest way to resolve this is to add `provideNativeDateAdapter` or
+`provideMomentDateAdapter` to your app config. See
+[_Choosing a date implementation_](#choosing-a-date-implementation-and-format-settings) for
+more information.
+
+#### Error: MatTimepicker: Incomplete `MAT_DATE_FORMATS` has been provided
+
+The timepicker needs the `display.timeInput`, `display.timeOptionLabel` and `parse.timeInput` fields
+in `MAT_DATE_FORMATS` in order to work correctly. You should update your date formats object to
+include include these fields. See [_Customizing the parse and display formats_](#customizing-the-parse-and-display-formats)
+for more information.
+
+#### Error: Cannot specify both the `options` and `interval` inputs at the same time
+
+A `mat-timepicker` cannot specifify both the `options` and `interval` inputs at the same time.
+The template should be updated to remove one of them.
+
+#### Error: Value of `options` input cannot be an empty array
+
+The array passed into the `options` input of `mat-timepicker` cannot be empty, because the user
+won't have any options to choose from.
+
+#### Error: A MatTimepicker can only be associated with a single input
+
+This error is thrown if more than one `<input>` tries to claim ownership over the same
+`<mat-timepicker>` (via the `matTimepicker` attribute on the input). A timepicker can only be
+associated with a single input.
diff --git a/src/material/timepicker/timepicker.scss b/src/material/timepicker/timepicker.scss
index ae8cfc84fff8..4cea2ec88ebc 100644
--- a/src/material/timepicker/timepicker.scss
+++ b/src/material/timepicker/timepicker.scss
@@ -38,11 +38,9 @@ mat-timepicker {
   }
 }
 
-// stylelint-disable material/no-prefixes
-.mat-timepicker-input:read-only {
+.mat-timepicker-input[readonly] {
   cursor: pointer;
 }
-// stylelint-enable material/no-prefixes
 
 @include cdk.high-contrast {
   .mat-timepicker-toggle-default-icon {
diff --git a/src/material/timepicker/timepicker.spec.ts b/src/material/timepicker/timepicker.spec.ts
index 7cff9457ffa1..da1bd81e5365 100644
--- a/src/material/timepicker/timepicker.spec.ts
+++ b/src/material/timepicker/timepicker.spec.ts
@@ -73,7 +73,7 @@ describe('MatTimepicker', () => {
 
       expect(getPanel()).toBeFalsy();
       expect(input.value).toBe('12:30 AM');
-      expect(fixture.componentInstance.input.value()).toEqual(createTime(0, 30));
+      expectSameTime(fixture.componentInstance.input.value(), createTime(0, 30));
       expect(fixture.componentInstance.selectedSpy).toHaveBeenCalledTimes(1);
       expect(fixture.componentInstance.selectedSpy).toHaveBeenCalledWith(
         jasmine.objectContaining({
@@ -91,7 +91,7 @@ describe('MatTimepicker', () => {
 
       // Initial value
       expect(fixture.componentInstance.value).toBeTruthy();
-      expect(inputInstance.value()).toEqual(fixture.componentInstance.value());
+      expectSameTime(inputInstance.value(), fixture.componentInstance.value());
 
       // Propagation from input back to host
       clearElement(input);
@@ -100,7 +100,7 @@ describe('MatTimepicker', () => {
       let value = inputInstance.value()!;
       expect(adapter.getHours(value)).toBe(11);
       expect(adapter.getMinutes(value)).toBe(15);
-      expect(fixture.componentInstance.value()).toEqual(value);
+      expectSameTime(fixture.componentInstance.value(), value);
 
       // Propagation from host down to input
       fixture.componentInstance.value.set(createTime(13, 37));
@@ -109,7 +109,7 @@ describe('MatTimepicker', () => {
       value = inputInstance.value()!;
       expect(adapter.getHours(value)).toBe(13);
       expect(adapter.getMinutes(value)).toBe(37);
-      expect(value).toEqual(fixture.componentInstance.value());
+      expectSameTime(fixture.componentInstance.value(), value);
     }));
 
     it('should emit the `selected` event if the option being clicked was selected already', fakeAsync(() => {
@@ -169,7 +169,7 @@ describe('MatTimepicker', () => {
 
       // The user's value shouldn't be overwritten.
       expect(input.value).toBe('13:37');
-      expect(fixture.componentInstance.input.value()).toEqual(createTime(13, 37));
+      expectSameTime(fixture.componentInstance.input.value(), createTime(13, 37));
     });
 
     it('should parse invalid time string', () => {
@@ -251,14 +251,14 @@ describe('MatTimepicker', () => {
       typeInElement(input, '2:10 PM');
       fixture.detectChanges();
       expect(input.value).toBe('2:10 PM');
-      expect(inputInstance.value()).toEqual(new Date(...dateParts, 14, 10, 0));
+      expectSameTime(inputInstance.value(), new Date(...dateParts, 14, 10, 0));
     });
 
     it('should not accept an invalid `min` value', () => {
       const fixture = TestBed.createComponent(StandaloneTimepicker);
       fixture.componentInstance.min.set(createTime(13, 45));
       fixture.detectChanges();
-      expect(fixture.componentInstance.input.min()).toEqual(createTime(13, 45));
+      expectSameTime(fixture.componentInstance.input.min(), createTime(13, 45));
 
       fixture.componentInstance.min.set(adapter.invalid());
       fixture.detectChanges();
@@ -269,7 +269,7 @@ describe('MatTimepicker', () => {
       const fixture = TestBed.createComponent(StandaloneTimepicker);
       fixture.componentInstance.max.set(createTime(13, 45));
       fixture.detectChanges();
-      expect(fixture.componentInstance.input.max()).toEqual(createTime(13, 45));
+      expectSameTime(fixture.componentInstance.input.max(), createTime(13, 45));
 
       fixture.componentInstance.max.set(adapter.invalid());
       fixture.detectChanges();
@@ -280,14 +280,14 @@ describe('MatTimepicker', () => {
       const fixture = TestBed.createComponent(StandaloneTimepicker);
       fixture.componentInstance.min.set('1:45 PM');
       fixture.detectChanges();
-      expect(fixture.componentInstance.input.min()).toEqual(createTime(13, 45));
+      expectSameTime(fixture.componentInstance.input.min(), createTime(13, 45));
     });
 
     it('should accept a valid time string as the `max`', () => {
       const fixture = TestBed.createComponent(StandaloneTimepicker);
       fixture.componentInstance.max.set('1:45 PM');
       fixture.detectChanges();
-      expect(fixture.componentInstance.input.max()).toEqual(createTime(13, 45));
+      expectSameTime(fixture.componentInstance.input.max(), createTime(13, 45));
     });
 
     it('should throw if multiple inputs are associated with a timepicker', () => {
@@ -788,7 +788,7 @@ describe('MatTimepicker', () => {
       flush();
 
       expect(input.value).toBe('1:30 AM');
-      expect(fixture.componentInstance.input.value()).toEqual(createTime(1, 30));
+      expectSameTime(fixture.componentInstance.input.value(), createTime(1, 30));
       expect(getPanel()).toBeFalsy();
       expect(event.defaultPrevented).toBeTrue();
       expect(fixture.componentInstance.selectedSpy).toHaveBeenCalledTimes(1);
@@ -868,7 +868,7 @@ describe('MatTimepicker', () => {
 
       typeInElement(input, '1:37 PM');
       fixture.detectChanges();
-      expect(control.value).toEqual(createTime(13, 37));
+      expectSameTime(control.value, createTime(13, 37));
       expect(control.dirty).toBe(true);
       expect(control.touched).toBe(false);
 
@@ -890,7 +890,7 @@ describe('MatTimepicker', () => {
       getOptions()[5].click();
       fixture.detectChanges();
 
-      expect(control.value).toEqual(createTime(2, 30));
+      expectSameTime(control.value, createTime(2, 30));
       expect(control.dirty).toBe(true);
     });
 
@@ -930,7 +930,7 @@ describe('MatTimepicker', () => {
       getOptions()[5].click();
       fixture.detectChanges();
 
-      expect(control.value).toEqual(createTime(2, 30));
+      expectSameTime(control.value, createTime(2, 30));
       expect(control.dirty).toBe(false);
       expect(spy).not.toHaveBeenCalled();
       subscription.unsubscribe();
@@ -946,7 +946,7 @@ describe('MatTimepicker', () => {
       fixture.componentInstance.input.value.set(createTime(12, 0));
       fixture.detectChanges();
 
-      expect(control.value).toEqual(createTime(13, 37));
+      expectSameTime(control.value, createTime(13, 37));
       expect(control.dirty).toBe(false);
     });
 
@@ -955,6 +955,18 @@ describe('MatTimepicker', () => {
       fixture.detectChanges();
       expect(fixture.componentInstance.control.touched).toBe(false);
 
+      getInput(fixture).click();
+      fixture.detectChanges();
+      dispatchFakeEvent(getInput(fixture), 'blur');
+      fixture.detectChanges();
+      expect(fixture.componentInstance.control.touched).toBe(false);
+    });
+
+    it('should mark the control as touched on blur while dropdown is open', () => {
+      const fixture = TestBed.createComponent(TimepickerWithForms);
+      fixture.detectChanges();
+      expect(fixture.componentInstance.control.touched).toBe(false);
+
       dispatchFakeEvent(getInput(fixture), 'blur');
       fixture.detectChanges();
       expect(fixture.componentInstance.control.touched).toBe(true);
@@ -1002,7 +1014,7 @@ describe('MatTimepicker', () => {
       typeInElement(input, '10:10 AM');
       fixture.detectChanges();
       expect(control.errors?.['matTimepickerParse']).toBeFalsy();
-      expect(control.value).toEqual(createTime(10, 10));
+      expectSameTime(control.value, createTime(10, 10));
 
       clearElement(input);
       typeInElement(input, 'not a valid date');
@@ -1034,7 +1046,7 @@ describe('MatTimepicker', () => {
       typeInElement(input, '12:10 PM');
       fixture.detectChanges();
       expect(control.errors?.['matTimepickerParse']).toBeFalsy();
-      expect(control.value).toEqual(createTime(12, 10));
+      expectSameTime(control.value, createTime(12, 10));
     }));
 
     it('should set an error if the user enters a time earlier than the minimum', fakeAsync(() => {
@@ -1052,7 +1064,7 @@ describe('MatTimepicker', () => {
       typeInElement(input, '11:59 AM');
       fixture.detectChanges();
       expect(control.errors?.['matTimepickerMin']).toBeTruthy();
-      expect(control.value).toEqual(createTime(11, 59));
+      expectSameTime(control.value, createTime(11, 59));
 
       // Change the minimum so the value becomes valid.
       fixture.componentInstance.min.set(createTime(11, 0));
@@ -1075,7 +1087,7 @@ describe('MatTimepicker', () => {
       typeInElement(input, '12:01 PM');
       fixture.detectChanges();
       expect(control.errors?.['matTimepickerMax']).toBeTruthy();
-      expect(control.value).toEqual(createTime(12, 1));
+      expectSameTime(control.value, createTime(12, 1));
 
       // Change the maximum so the value becomes valid.
       fixture.componentInstance.max.set(createTime(13, 0));
@@ -1121,11 +1133,11 @@ describe('MatTimepicker', () => {
       expect(toggle.getAttribute('aria-expanded')).toBe('true');
     });
 
-    it('should be able to set aria-label on the button', () => {
+    it('should be able to set custom aria-label on the button', () => {
       const fixture = TestBed.createComponent(StandaloneTimepicker);
       const toggle = getToggle(fixture);
       fixture.detectChanges();
-      expect(toggle.hasAttribute('aria-label')).toBe(false);
+      expect(toggle.hasAttribute('aria-label')).toBe(true);
 
       fixture.componentInstance.toggleAriaLabel.set('Toggle the timepicker');
       fixture.detectChanges();
@@ -1164,6 +1176,19 @@ describe('MatTimepicker', () => {
       fixture.detectChanges();
       expect(getPanel()).toBeFalsy();
     });
+
+    it('should disable the toggle when the timepicker is disabled', () => {
+      const fixture = TestBed.createComponent(StandaloneTimepicker);
+      const toggle = getToggle(fixture);
+      fixture.detectChanges();
+      expect(toggle.disabled).toBe(false);
+      expect(toggle.getAttribute('tabindex')).toBe('0');
+
+      fixture.componentInstance.disabled.set(true);
+      fixture.detectChanges();
+      expect(toggle.disabled).toBe(true);
+      expect(toggle.getAttribute('tabindex')).toBe('-1');
+    });
   });
 
   describe('global defaults', () => {
@@ -1197,6 +1222,12 @@ describe('MatTimepicker', () => {
     });
   });
 
+  function expectSameTime(one: Date | null, two: Date | null): void {
+    expect(adapter.sameTime(one, two))
+      .withContext(`Expected ${one} to be same time as ${two}`)
+      .toBe(true);
+  }
+
   function configureTestingModule(additionalProviders: Provider[] = []): void {
     TestBed.configureTestingModule({
       imports: [NoopAnimationsModule],
@@ -1255,7 +1286,6 @@ describe('MatTimepicker', () => {
       [disabled]="toggleDisabled()"
       [tabIndex]="toggleTabIndex()"/>
   `,
-  standalone: true,
   imports: [MatTimepicker, MatTimepickerInput, MatTimepickerToggle],
 })
 class StandaloneTimepicker {
@@ -1286,7 +1316,6 @@ class StandaloneTimepicker {
       <mat-timepicker-toggle [for]="picker" matSuffix/>
     </mat-form-field>
   `,
-  standalone: true,
   imports: [
     MatTimepicker,
     MatTimepickerInput,
@@ -1307,7 +1336,6 @@ class TimepickerInFormField {
     <input [matTimepicker]="picker" [(value)]="value"/>
     <mat-timepicker #picker/>
   `,
-  standalone: true,
   imports: [MatTimepicker, MatTimepickerInput],
 })
 class TimepickerTwoWayBinding {
@@ -1324,7 +1352,6 @@ class TimepickerTwoWayBinding {
       [matTimepickerMax]="max()"/>
     <mat-timepicker #picker/>
   `,
-  standalone: true,
   imports: [MatTimepicker, MatTimepickerInput, ReactiveFormsModule],
 })
 class TimepickerWithForms {
@@ -1340,14 +1367,12 @@ class TimepickerWithForms {
     <input [matTimepicker]="picker"/>
     <mat-timepicker #picker/>
   `,
-  standalone: true,
   imports: [MatTimepicker, MatTimepickerInput],
 })
 class TimepickerWithMultipleInputs {}
 
 @Component({
   template: '<mat-timepicker/>',
-  standalone: true,
   imports: [MatTimepicker],
 })
 class TimepickerWithoutInput {
diff --git a/src/material/timepicker/timepicker.ts b/src/material/timepicker/timepicker.ts
index 23efc3e45565..2a32ca0837b9 100644
--- a/src/material/timepicker/timepicker.ts
+++ b/src/material/timepicker/timepicker.ts
@@ -12,6 +12,7 @@ import {
   booleanAttribute,
   ChangeDetectionStrategy,
   Component,
+  computed,
   effect,
   ElementRef,
   inject,
@@ -44,7 +45,7 @@ import {Overlay, OverlayRef} from '@angular/cdk/overlay';
 import {TemplatePortal} from '@angular/cdk/portal';
 import {_getEventTarget} from '@angular/cdk/platform';
 import {ENTER, ESCAPE, hasModifierKey, TAB} from '@angular/cdk/keycodes';
-import {ActiveDescendantKeyManager} from '@angular/cdk/a11y';
+import {_IdGenerator, ActiveDescendantKeyManager} from '@angular/cdk/a11y';
 import type {MatTimepickerInput} from './timepicker-input';
 import {
   generateOptions,
@@ -55,9 +56,6 @@ import {
 } from './util';
 import {Subscription} from 'rxjs';
 
-/** Counter used to generate unique IDs. */
-let uniqueId = 0;
-
 /** Event emitted when a value is selected in the timepicker. */
 export interface MatTimepickerSelected<D> {
   value: D;
@@ -107,7 +105,7 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
   private _isOpen = signal(false);
   private _activeDescendant = signal<string | null>(null);
 
-  private _input: MatTimepickerInput<D>;
+  private _input = signal<MatTimepickerInput<D> | null>(null);
   private _overlayRef: OverlayRef | null = null;
   private _portal: TemplatePortal<unknown> | null = null;
   private _optionsCacheKey: string | null = null;
@@ -157,7 +155,7 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
   readonly activeDescendant: Signal<string | null> = this._activeDescendant.asReadonly();
 
   /** Unique ID of the timepicker's panel */
-  readonly panelId = `mat-timepicker-panel-${uniqueId++}`;
+  readonly panelId: string = inject(_IdGenerator).getId('mat-timepicker-panel-');
 
   /** Whether ripples within the timepicker should be disabled. */
   readonly disableRipple: InputSignalWithTransform<boolean, unknown> = input(
@@ -177,6 +175,9 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
     alias: 'aria-labelledby',
   });
 
+  /** Whether the timepicker is currently disabled. */
+  readonly disabled: Signal<boolean> = computed(() => !!this._input()?.disabled());
+
   constructor() {
     if (typeof ngDevMode === 'undefined' || ngDevMode) {
       validateAdapter(this._dateAdapter, this._dateFormats);
@@ -207,14 +208,16 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
 
   /** Opens the timepicker. */
   open(): void {
-    if (!this._input) {
+    const input = this._input();
+
+    if (!input) {
       return;
     }
 
     // Focus should already be on the input, but this call is in case the timepicker is opened
     // programmatically. We need to call this even if the timepicker is already open, because
     // the user might be clicking the toggle.
-    this._input.focus();
+    input.focus();
 
     if (this._isOpen()) {
       return;
@@ -223,14 +226,14 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
     this._isOpen.set(true);
     this._generateOptions();
     const overlayRef = this._getOverlayRef();
-    overlayRef.updateSize({width: this._input.getOverlayOrigin().nativeElement.offsetWidth});
+    overlayRef.updateSize({width: input.getOverlayOrigin().nativeElement.offsetWidth});
     this._portal ??= new TemplatePortal(this._panelTemplate(), this._viewContainerRef);
     overlayRef.attach(this._portal);
     this._onOpenRender?.destroy();
     this._onOpenRender = afterNextRender(
       () => {
         const options = this._options();
-        this._syncSelectedState(this._input.value(), options, options[0]);
+        this._syncSelectedState(input.value(), options, options[0]);
         this._onOpenRender = null;
       },
       {injector: this._injector},
@@ -250,11 +253,13 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
 
   /** Registers an input with the timepicker. */
   registerInput(input: MatTimepickerInput<D>): void {
-    if (this._input && input !== this._input && (typeof ngDevMode === 'undefined' || ngDevMode)) {
+    const currentInput = this._input();
+
+    if (currentInput && input !== currentInput && (typeof ngDevMode === 'undefined' || ngDevMode)) {
       throw new Error('MatTimepicker can only be registered with one input at a time');
     }
 
-    this._input = input;
+    this._input.set(input);
   }
 
   ngOnDestroy(): void {
@@ -268,7 +273,7 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
   protected _selectValue(value: D) {
     this.close();
     this.selected.emit({value, source: this});
-    this._input.focus();
+    this._input()?.focus();
   }
 
   /** Gets the value of the `aria-labelledby` attribute. */
@@ -276,7 +281,7 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
     if (this.ariaLabel()) {
       return null;
     }
-    return this.ariaLabelledby() || this._input?._getLabelId() || null;
+    return this.ariaLabelledby() || this._input()?._getLabelId() || null;
   }
 
   /** Creates an overlay reference for the timepicker panel. */
@@ -287,7 +292,7 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
 
     const positionStrategy = this._overlay
       .position()
-      .flexibleConnectedTo(this._input.getOverlayOrigin())
+      .flexibleConnectedTo(this._input()!.getOverlayOrigin())
       .withFlexibleDimensions(false)
       .withPush(false)
       .withTransformOriginOn('.mat-timepicker-panel')
@@ -320,9 +325,9 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
 
     this._overlayRef.outsidePointerEvents().subscribe(event => {
       const target = _getEventTarget(event) as HTMLElement;
-      const origin = this._input.getOverlayOrigin().nativeElement;
+      const origin = this._input()?.getOverlayOrigin().nativeElement;
 
-      if (target && target !== origin && !origin.contains(target)) {
+      if (target && origin && target !== origin && !origin.contains(target)) {
         this.close();
       }
     });
@@ -339,10 +344,11 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
     if (options !== null) {
       this._timeOptions = options;
     } else {
+      const input = this._input();
       const adapter = this._dateAdapter;
       const timeFormat = this._dateFormats.display.timeInput;
-      const min = this._input.min() || adapter.setTime(adapter.today(), 0, 0, 0);
-      const max = this._input.max() || adapter.setTime(adapter.today(), 23, 59, 0);
+      const min = input?.min() || adapter.setTime(adapter.today(), 0, 0, 0);
+      const max = input?.max() || adapter.setTime(adapter.today(), 23, 59, 0);
       const cacheKey =
         interval + '/' + adapter.format(min, timeFormat) + '/' + adapter.format(max, timeFormat);
 
@@ -435,11 +441,11 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
    */
   private _handleInputStateChanges(): void {
     effect(() => {
-      const value = this._input?.value();
+      const input = this._input();
       const options = this._options();
 
-      if (this._isOpen()) {
-        this._syncSelectedState(value, options, null);
+      if (this._isOpen() && input) {
+        this._syncSelectedState(input.value(), options, null);
       }
     });
   }
diff --git a/src/material/toolbar/testing/toolbar-harness.spec.ts b/src/material/toolbar/testing/toolbar-harness.spec.ts
index 2344bb9bec7b..81315d1984db 100644
--- a/src/material/toolbar/testing/toolbar-harness.spec.ts
+++ b/src/material/toolbar/testing/toolbar-harness.spec.ts
@@ -74,7 +74,6 @@ describe('MatToolbarHarness', () => {
       </mat-toolbar-row>
     </mat-toolbar>
   `,
-  standalone: true,
   imports: [MatToolbarModule],
 })
 class ToolbarHarnessTest {}
diff --git a/src/material/toolbar/toolbar.spec.ts b/src/material/toolbar/toolbar.spec.ts
index ce1d0df979c2..42f2e5a053a9 100644
--- a/src/material/toolbar/toolbar.spec.ts
+++ b/src/material/toolbar/toolbar.spec.ts
@@ -104,7 +104,6 @@ describe('MatToolbar', () => {
       <span>First Row</span>
     </mat-toolbar>
   `,
-  standalone: true,
   imports: [MatToolbarModule],
 })
 class ToolbarSingleRow {
@@ -118,7 +117,6 @@ class ToolbarSingleRow {
       <mat-toolbar-row>Second Row</mat-toolbar-row>
     </mat-toolbar>
   `,
-  standalone: true,
   imports: [MatToolbarModule],
 })
 class ToolbarMultipleRows {}
@@ -132,7 +130,6 @@ class ToolbarMultipleRows {}
       }
     </mat-toolbar>
   `,
-  standalone: true,
   imports: [MatToolbarModule],
 })
 class ToolbarMixedRowModes {
@@ -149,7 +146,6 @@ class ToolbarMixedRowModes {
       }
     </mat-toolbar>
   `,
-  standalone: true,
   imports: [MatToolbarModule],
 })
 class ToolbarMultipleIndirectRows {}
diff --git a/src/material/toolbar/toolbar.ts b/src/material/toolbar/toolbar.ts
index afebe7306507..63e0c554a4f3 100644
--- a/src/material/toolbar/toolbar.ts
+++ b/src/material/toolbar/toolbar.ts
@@ -50,10 +50,10 @@ export class MatToolbar implements AfterViewInit {
   // TODO: should be typed as `ThemePalette` but internal apps pass in arbitrary strings.
   /**
    * Theme color of the toolbar. This API is supported in M2 themes only, it has
-   * no effect in M3 themes.
+   * no effect in M3 themes. For color customization in M3, see https://material.angular.io/components/toolbar/styling.
    *
    * For information on applying color variants in M3, see
-   * https://material.angular.io/guide/theming#using-component-color-variants.
+   * https://material.angular.io/guide/material-2-theming#optional-add-backwards-compatibility-styles-for-color-variants
    */
   @Input() color?: string | null;
 
diff --git a/src/material/tooltip/module.ts b/src/material/tooltip/module.ts
index 9e6575c8065b..97e26a05f7f8 100644
--- a/src/material/tooltip/module.ts
+++ b/src/material/tooltip/module.ts
@@ -7,7 +7,6 @@
  */
 
 import {NgModule} from '@angular/core';
-import {CommonModule} from '@angular/common';
 import {A11yModule} from '@angular/cdk/a11y';
 import {OverlayModule} from '@angular/cdk/overlay';
 import {CdkScrollableModule} from '@angular/cdk/scrolling';
@@ -19,7 +18,7 @@ import {
 } from './tooltip';
 
 @NgModule({
-  imports: [A11yModule, CommonModule, OverlayModule, MatCommonModule, MatTooltip, TooltipComponent],
+  imports: [A11yModule, OverlayModule, MatCommonModule, MatTooltip, TooltipComponent],
   exports: [MatTooltip, TooltipComponent, MatCommonModule, CdkScrollableModule],
   providers: [MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER],
 })
diff --git a/src/material/tooltip/testing/tooltip-harness.spec.ts b/src/material/tooltip/testing/tooltip-harness.spec.ts
index 246417390db9..538433b8090a 100644
--- a/src/material/tooltip/testing/tooltip-harness.spec.ts
+++ b/src/material/tooltip/testing/tooltip-harness.spec.ts
@@ -72,7 +72,6 @@ describe('MatTooltipHarness', () => {
     <button matTooltip='Static message' id='two'>Trigger 2</button>
     <button matTooltip='Disabled Tooltip' [matTooltipDisabled]='true' id='three'>Trigger 3</button>
   `,
-  standalone: true,
   imports: [MatTooltipModule],
 })
 class TooltipHarnessTest {
diff --git a/src/material/tooltip/tooltip-animations.ts b/src/material/tooltip/tooltip-animations.ts
index e4eb1419da63..652e7f4806f1 100644
--- a/src/material/tooltip/tooltip-animations.ts
+++ b/src/material/tooltip/tooltip-animations.ts
@@ -17,6 +17,8 @@ import {
 /**
  * Animations used by MatTooltip.
  * @docs-private
+ * @deprecated No longer being used, to be removed.
+ * @breaking-change 21.0.0
  */
 export const matTooltipAnimations: {
   readonly tooltipState: AnimationTriggerMetadata;
diff --git a/src/material/tooltip/tooltip.scss b/src/material/tooltip/tooltip.scss
index 2371550ad14c..ab314afdf322 100644
--- a/src/material/tooltip/tooltip.scss
+++ b/src/material/tooltip/tooltip.scss
@@ -98,9 +98,14 @@
   }
 }
 
-// We need the additional specificity here, because it can be overridden by `.cdk-overlay-panel`.
-.mat-mdc-tooltip-panel.mat-mdc-tooltip-panel-non-interactive {
-  pointer-events: none;
+.mat-mdc-tooltip-panel {
+  // The line height inherited from the body can throw off the tooltip gap (see #30132).
+  line-height: normal;
+
+  // We need the additional specificity here, because it can be overridden by `.cdk-overlay-panel`.
+  &.mat-mdc-tooltip-panel-non-interactive {
+    pointer-events: none;
+  }
 }
 
 @keyframes mat-mdc-tooltip-show {
diff --git a/src/material/tooltip/tooltip.spec.ts b/src/material/tooltip/tooltip.spec.ts
index 3aff10c8f728..fccac2350c6b 100644
--- a/src/material/tooltip/tooltip.spec.ts
+++ b/src/material/tooltip/tooltip.spec.ts
@@ -1604,7 +1604,6 @@ describe('MatTooltip', () => {
         [matTooltipTouchGestures]="touchGestures"
         [matTooltipDisabled]="tooltipDisabled">Button</button>
     }`,
-  standalone: true,
   imports: [MatTooltipModule, OverlayModule],
 })
 class BasicTooltipDemo {
@@ -1629,7 +1628,6 @@ class BasicTooltipDemo {
               [matTooltipPosition]="position">Button</button>
       }
     </div>`,
-  standalone: true,
   imports: [MatTooltipModule, OverlayModule],
 })
 class ScrollableTooltipDemo {
@@ -1658,7 +1656,6 @@ class ScrollableTooltipDemo {
       Button
     </button>`,
   changeDetection: ChangeDetectionStrategy.OnPush,
-  standalone: true,
   imports: [MatTooltipModule, OverlayModule],
 })
 class OnPushTooltipDemo {
@@ -1673,7 +1670,6 @@ class OnPushTooltipDemo {
       <button [matTooltip]="tooltip">Button {{tooltip}}</button>
     }
   `,
-  standalone: true,
   imports: [MatTooltipModule, OverlayModule],
 })
 class DynamicTooltipsDemo {
@@ -1682,7 +1678,6 @@ class DynamicTooltipsDemo {
 
 @Component({
   template: `<button [matTooltip]="message" [attr.aria-label]="message">Click me</button>`,
-  standalone: true,
   imports: [MatTooltipModule, OverlayModule],
 })
 class DataBoundAriaLabelTooltip {
@@ -1701,7 +1696,6 @@ class DataBoundAriaLabelTooltip {
       matTooltip="Another thing"
       [matTooltipTouchGestures]="touchGestures"></textarea>
   `,
-  standalone: true,
   imports: [MatTooltipModule, OverlayModule],
 })
 class TooltipOnTextFields {
@@ -1718,7 +1712,6 @@ class TooltipOnTextFields {
       matTooltip="Drag me"
       [matTooltipTouchGestures]="touchGestures"></button>
   `,
-  standalone: true,
   imports: [MatTooltipModule, OverlayModule],
 })
 class TooltipOnDraggableElement {
diff --git a/src/material/tooltip/tooltip.ts b/src/material/tooltip/tooltip.ts
index 8d8053b16cb0..a4d0ee761f59 100644
--- a/src/material/tooltip/tooltip.ts
+++ b/src/material/tooltip/tooltip.ts
@@ -217,6 +217,7 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
   private _currentPosition: TooltipPosition;
   private readonly _cssClassPrefix: string = 'mat-mdc';
   private _ariaDescriptionPending: boolean;
+  private _dirSubscribed = false;
 
   /** Allows the user to define the position of the tooltip relative to the parent element */
   @Input('matTooltipPosition')
@@ -396,12 +397,6 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
       }
     }
 
-    this._dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
-      if (this._overlayRef) {
-        this._updatePosition(this._overlayRef);
-      }
-    });
-
     this._viewportMargin = MIN_VIEWPORT_TOOLTIP_THRESHOLD;
   }
 
@@ -571,6 +566,15 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
       this._overlayRef.addPanelClass(`${this._cssClassPrefix}-tooltip-panel-non-interactive`);
     }
 
+    if (!this._dirSubscribed) {
+      this._dirSubscribed = true;
+      this._dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
+        if (this._overlayRef) {
+          this._updatePosition(this._overlayRef);
+        }
+      });
+    }
+
     return this._overlayRef;
   }
 
diff --git a/src/material/tooltip/tooltip.zone.spec.ts b/src/material/tooltip/tooltip.zone.spec.ts
index e519ca5af276..4d8c8cf1de4d 100644
--- a/src/material/tooltip/tooltip.zone.spec.ts
+++ b/src/material/tooltip/tooltip.zone.spec.ts
@@ -74,7 +74,6 @@ describe('MatTooltip Zone.js integration', () => {
                 [matTooltipPosition]="position">Button</button>
         }
       </div>`,
-  standalone: true,
   imports: [MatTooltipModule, OverlayModule],
 })
 class ScrollableTooltipDemo {
diff --git a/src/material/tree/testing/tree-harness.spec.ts b/src/material/tree/testing/tree-harness.spec.ts
index a5dd4e17fd44..222ab037abaa 100644
--- a/src/material/tree/testing/tree-harness.spec.ts
+++ b/src/material/tree/testing/tree-harness.spec.ts
@@ -235,9 +235,9 @@ interface ExampleFlatNode {
     </mat-tree>
     <mat-tree [dataSource]="nestedTreeDataSource" [treeControl]="nestedTreeControl">
       <!-- This is the tree node template for leaf nodes -->
-      <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
+      <mat-nested-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
         {{node.name}}
-      </mat-tree-node>
+      </mat-nested-tree-node>
       <!-- This is the tree node template for expandable nodes -->
       <mat-nested-tree-node *matTreeNodeDef="let node; when: nestedTreeHasChild" isExpandable>
         <button matTreeNodeToggle>
@@ -250,7 +250,6 @@ interface ExampleFlatNode {
       </mat-nested-tree-node>
     </mat-tree>
   `,
-  standalone: true,
   imports: [MatTreeModule],
 })
 class TreeHarnessTest {
diff --git a/src/youtube-player/package.json b/src/youtube-player/package.json
index 0d9614e61c4c..bac679e02343 100644
--- a/src/youtube-player/package.json
+++ b/src/youtube-player/package.json
@@ -17,7 +17,7 @@
   },
   "homepage": "https://github.com/angular/components/tree/main/src/youtube-player#readme",
   "dependencies": {
-    "@types/youtube": "^0.0.50",
+    "@types/youtube": "^0.1.0",
     "tslib": "0.0.0-TSLIB"
   },
   "peerDependencies": {
diff --git a/src/youtube-player/youtube-player.spec.ts b/src/youtube-player/youtube-player.spec.ts
index 19a4792e8d94..757baf8bf435 100644
--- a/src/youtube-player/youtube-player.spec.ts
+++ b/src/youtube-player/youtube-player.spec.ts
@@ -725,17 +725,12 @@ describe('YoutubePlayer', () => {
 
     const player = noEventsApp.componentInstance.player;
     const subscriptions: Subscription[] = [];
-    const readySpy = jasmine.createSpy('ready spy');
     const stateChangeSpy = jasmine.createSpy('stateChange spy');
     const playbackQualityChangeSpy = jasmine.createSpy('playbackQualityChange spy');
     const playbackRateChangeSpy = jasmine.createSpy('playbackRateChange spy');
     const errorSpy = jasmine.createSpy('error spy');
     const apiChangeSpy = jasmine.createSpy('apiChange spy');
 
-    subscriptions.push(player.ready.subscribe(readySpy));
-    events.onReady({target: playerSpy});
-    expect(readySpy).toHaveBeenCalledWith({target: playerSpy});
-
     subscriptions.push(player.stateChange.subscribe(stateChangeSpy));
     events.onStateChange({target: playerSpy, data: 5});
     expect(stateChangeSpy).toHaveBeenCalledWith({target: playerSpy, data: 5});
@@ -763,7 +758,6 @@ describe('YoutubePlayer', () => {
 /** Test component that contains a YouTubePlayer. */
 @Component({
   selector: 'test-app',
-  standalone: true,
   imports: [YouTubePlayer],
   template: `
     @if (visible) {
@@ -811,7 +805,6 @@ class TestApp {
 }
 
 @Component({
-  standalone: true,
   imports: [YouTubePlayer],
   template: `
     <youtube-player [videoId]="videoId" [startSeconds]="42" [endSeconds]="1337"/>
@@ -822,7 +815,6 @@ class StaticStartEndSecondsApp {
 }
 
 @Component({
-  standalone: true,
   imports: [YouTubePlayer],
   template: `<youtube-player [videoId]="videoId"/>`,
 })
diff --git a/src/youtube-player/youtube-player.ts b/src/youtube-player/youtube-player.ts
index 0dd2e9525637..665ae54b90f3 100644
--- a/src/youtube-player/youtube-player.ts
+++ b/src/youtube-player/youtube-player.ts
@@ -29,6 +29,7 @@ import {
   CSP_NONCE,
   ChangeDetectorRef,
   AfterViewInit,
+  EventEmitter,
 } from '@angular/core';
 import {isPlatformBrowser} from '@angular/common';
 import {Observable, of as observableOf, Subject, BehaviorSubject, fromEventPattern} from 'rxjs';
@@ -218,22 +219,29 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
    */
   @Input() placeholderImageQuality: PlaceholderImageQuality;
 
-  /** Outputs are direct proxies from the player itself. */
-  @Output() readonly ready: Observable<YT.PlayerEvent> =
-    this._getLazyEmitter<YT.PlayerEvent>('onReady');
+  // Note: ready event can't go through the lazy emitter, because it
+  // happens before the `_playerChanges` stream emits the new player.
 
+  /** Emits when the player is initialized. */
+  @Output() readonly ready: Observable<YT.PlayerEvent> = new EventEmitter<YT.PlayerEvent>();
+
+  /** Emits when the state of the player has changed. */
   @Output() readonly stateChange: Observable<YT.OnStateChangeEvent> =
     this._getLazyEmitter<YT.OnStateChangeEvent>('onStateChange');
 
+  /** Emits when there's an error while initializing the player. */
   @Output() readonly error: Observable<YT.OnErrorEvent> =
     this._getLazyEmitter<YT.OnErrorEvent>('onError');
 
+  /** Emits when the underlying API of the player has changed. */
   @Output() readonly apiChange: Observable<YT.PlayerEvent> =
     this._getLazyEmitter<YT.PlayerEvent>('onApiChange');
 
+  /** Emits when the playback quality has changed. */
   @Output() readonly playbackQualityChange: Observable<YT.OnPlaybackQualityChangeEvent> =
     this._getLazyEmitter<YT.OnPlaybackQualityChangeEvent>('onPlaybackQualityChange');
 
+  /** Emits when the playback rate has changed. */
   @Output() readonly playbackRateChange: Observable<YT.OnPlaybackRateChangeEvent> =
     this._getLazyEmitter<YT.OnPlaybackRateChangeEvent>('onPlaybackRateChange');
 
@@ -575,7 +583,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
         }),
     );
 
-    const whenReady = () => {
+    const whenReady = (event: YT.PlayerEvent) => {
       // Only assign the player once it's ready, otherwise YouTube doesn't expose some APIs.
       this._ngZone.run(() => {
         this._isLoading = false;
@@ -584,6 +592,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
         this._pendingPlayer = undefined;
         player.removeEventListener('onReady', whenReady);
         this._playerChanges.next(player);
+        (this.ready as EventEmitter<YT.PlayerEvent>).emit(event);
         this._setSize();
         this._setQuality();
 
@@ -597,6 +606,12 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
         const state = player.getPlayerState();
         if (state === PlayerState.UNSTARTED || state === PlayerState.CUED || state == null) {
           this._cuePlayer();
+        } else if (playVideo && this.startSeconds && this.startSeconds > 0) {
+          // We have to use `seekTo` when `startSeconds` are specified to simulate it playing from
+          // a specific time. The "proper" way to do it would be to either go through `cueVideoById`
+          // or `playerVars.start`, but at the time of writing both end up resetting the video
+          // to the state as if the user hasn't interacted with it.
+          player.seekTo(this.startSeconds, true);
         }
 
         this._changeDetectorRef.markForCheck();
@@ -674,10 +689,10 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
       switchMap(player => {
         return player
           ? fromEventPattern<T>(
-              (listener: (event: T) => void) => {
+              listener => {
                 player.addEventListener(name, listener);
               },
-              (listener: (event: T) => void) => {
+              listener => {
                 // The API seems to throw when we try to unbind from a destroyed player and it doesn't
                 // expose whether the player has been destroyed so we have to wrap it in a try/catch to
                 // prevent the entire stream from erroring out.
diff --git a/tools/extract-tokens/BUILD.bazel b/tools/extract-tokens/BUILD.bazel
index ab58b0f7c342..1877ba74e2b3 100644
--- a/tools/extract-tokens/BUILD.bazel
+++ b/tools/extract-tokens/BUILD.bazel
@@ -10,6 +10,7 @@ ts_library(
     devmode_module = "commonjs",
     tsconfig = ":tsconfig.json",
     deps = [
+        "//tools/highlight-files:sources",
         "@npm//@types/node",
         "@npm//sass",
     ],
@@ -19,6 +20,7 @@ nodejs_binary(
     name = "extract-tokens",
     data = [
         ":extract_tokens_lib",
+        "@npm//highlight.js",
         "@npm//sass",
     ],
     entry_point = ":extract-tokens.ts",
diff --git a/tools/extract-tokens/extract-tokens.ts b/tools/extract-tokens/extract-tokens.ts
index 11acd6b831dc..7611a0851e55 100644
--- a/tools/extract-tokens/extract-tokens.ts
+++ b/tools/extract-tokens/extract-tokens.ts
@@ -2,6 +2,7 @@ import {readFileSync, writeFileSync} from 'fs';
 import {pathToFileURL} from 'url';
 import {relative, join, dirname} from 'path';
 import {compileString} from 'sass';
+import {highlightCodeBlock} from '../highlight-files/highlight-code-block';
 
 /** Information extracted for a single token from the theme. */
 interface ExtractedToken {
@@ -31,6 +32,16 @@ interface Token {
   derivedFrom?: string;
 }
 
+/** Information extracted from a theme file. */
+interface ThemeData {
+  /** Name of the theme file. */
+  name: string;
+  /** Name of the `overrides` mixin within the file. */
+  overridesMixin: string;
+  /** Tokens that can be used in the `overrides` mixin. */
+  tokens: Token[];
+}
+
 // Script that extracts the tokens from a specific Bazel target.
 if (require.main === module) {
   const [packagePath, outputPath, ...inputFiles] = process.argv.slice(2);
@@ -52,20 +63,19 @@ if (require.main === module) {
     throw new Error(`Could not find theme files in ${packagePath}`);
   }
 
-  const themes: {name: string; overridesMixin: string; tokens: Token[]}[] = [];
+  const themes: ThemeData[] = [];
 
   themeFiles.forEach(theme => {
-    const tokens = extractTokens(theme.filePath);
     themes.push({
       name: theme.mixinPrefix,
       // This can be derived from the `name` already, but we want the source
       // of truth to be in this repo, instead of whatever page consumes the data.
       overridesMixin: `${theme.mixinPrefix}-overrides`,
-      tokens,
+      tokens: extractTokens(theme.filePath),
     });
   });
 
-  writeFileSync(outputPath, JSON.stringify(themes));
+  writeFileSync(outputPath, JSON.stringify({example: getUsageExample(themes), themes}));
 }
 
 /**
@@ -137,6 +147,41 @@ function extractTokens(themePath: string): Token[] {
   });
 }
 
+/**
+ * Generates a highlighted code snippet that illustrates how an overrides mixin can be used.
+ * @param themes Themes that were extracted from a specific entrypoint. One of these themes will
+ *   be used as an example.
+ */
+function getUsageExample(themes: ThemeData[]): string | null {
+  const mixin = themes.find(theme => theme.tokens.length > 0);
+
+  if (!mixin) {
+    return null;
+  }
+
+  // Pick out a couple of color tokens to show as examples.
+  const firstToken = mixin.tokens.find(token => token.type === 'color');
+  const secondToken = mixin.tokens.find(token => token.type === 'color' && token !== firstToken);
+
+  if (!firstToken) {
+    return null;
+  }
+
+  const lines = [
+    `@use '@angular/material' as mat;`,
+    ``,
+    `// Customize the entire app. Change :root to your selector if you want to scope the styles.`,
+    `:root {`,
+    `  @include mat.${mixin.overridesMixin}((`,
+    `    ${firstToken.overridesName}: orange,`,
+    ...(secondToken ? [`    ${secondToken.overridesName}: red,`] : []),
+    `  ));`,
+    `}`,
+  ];
+
+  return highlightCodeBlock(lines.join('\n'), 'scss');
+}
+
 /**
  * Generates the code that can be added around a theme file in order to extract its tokens.
  * @param srcPath Absolute path to the source root.
@@ -159,6 +204,8 @@ function getTokenExtractionCode(
   const stringJoin = '__privateStringJoin';
   const m3Tokens = '___privateM3Tokens';
   const palettes = '___privatePalettes';
+  const sassUtils = '__privateSassUtils';
+  const inferTokenType = '__privateInferFromValue';
   const defineOverrides = '_define-overrides';
   const corePath = relative(dirname(absoluteThemePath), join(srcPath, 'material/core')) || '.';
 
@@ -170,12 +217,12 @@ function getTokenExtractionCode(
     @use 'sass:string' as ${str};
     @use '${join(corePath, 'tokens/m3-tokens')}' as ${m3Tokens};
     @use '${join(corePath, 'theming/palettes')}' as ${palettes};
-    @use '${join(corePath, 'style/sass-utils')}' as __privateSassUtils;
+    @use '${join(corePath, 'style/sass-utils')}' as ${sassUtils};
 
     // The 'generate-*' functions don't have the ability to enable
     // system tokens so we have to do it by setting a variable.
-    __privateSassUtils.$use-system-color-variables: true;
-    __privateSassUtils.$use-system-typography-variables: true;
+    ${sassUtils}.$use-system-color-variables: true;
+    ${sassUtils}.$use-system-typography-variables: true;
   `;
 
   const append = `
@@ -184,8 +231,8 @@ function getTokenExtractionCode(
     }
 
     $__all-color: ${m3Tokens}.generate-color-tokens(light, ${palettes}.$azure-palette,
-      ${palettes}.$azure-palette, ${palettes}.$azure-palette, 'sys');
-    $__all-typography: ${m3Tokens}.generate-typography-tokens(font, 100, 100, 100, 100, 'sys');
+      ${palettes}.$azure-palette, ${palettes}.$azure-palette, 'mat-sys');
+    $__all-typography: ${m3Tokens}.generate-typography-tokens(font, 100, 100, 100, 100, 'mat-sys');
     $__all-density: ${m3Tokens}.generate-density-tokens(0);
     $__all-base: ${m3Tokens}.generate-base-tokens();
     $__results: ();
@@ -196,6 +243,7 @@ function getTokenExtractionCode(
       @error 'Expected override to be a list but got ' + $__override-type;
     }
 
+    // Joins all the strings in a list with a separator.
     @function ${stringJoin}($value, $separator) {
       $result: '';
       @each $part in $value {
@@ -204,6 +252,37 @@ function getTokenExtractionCode(
       @return $result;
     }
 
+    // Uses some simple heuristics to determine the type of a token based on its name or value.
+    @function ${inferTokenType}($name, $value) {
+      @if ($value == null) {
+        @return null;
+      }
+
+      $type: ${meta}.type-of($value);
+      $inferred-type: null;
+
+      // Note: Sass' string.index returns a 1-based index or null (if the value can't be found)
+      // so it's safe to just null check it in the conditions below.
+      @if ($type == 'color' or ${str}.index($name, 'shadow') or ${str}.index($name, 'opacity')) {
+        $inferred-type: color;
+      } @else if (
+        ${str}.index($name, 'font') or
+        ${str}.index($name, 'line-height') or
+        ${str}.index($name, 'tracking') or
+        ${str}.index($name, 'weight') or
+        (${str}.index($name, 'text') and ${str}.index($name, 'size')) or
+        (${str}.index($name, 'text') and ${str}.index($name, 'transform'))
+      ) {
+        $inferred-type: typography;
+      } @else if (${str}.index($name, 'width') or ${str}.index($name, 'height')) {
+        $inferred-type: density;
+      } @else if ($type == 'string' or ${str}.index($name, 'shape')) {
+        $inferred-type: base;
+      }
+
+      @return $inferred-type;
+    }
+
     @each $map in $__override-tokens {
       $namespace: ${map}.get($map, namespace);
       $tokens: ${map}.get($map, tokens);
@@ -213,7 +292,7 @@ function getTokenExtractionCode(
       $typography: ${map}.get($__all-typography, $namespace) or ();
       $density: ${map}.get($__all-density, $namespace) or ();
 
-      @each $name, $_ in $tokens {
+      @each $name, $resolved-value in $tokens {
         $color-value: ${map}.get($color, $name);
         $base-value: ${map}.get($base, $name);
         $typography-value: ${map}.get($typography, $name);
@@ -236,6 +315,19 @@ function getTokenExtractionCode(
           $value: $color-value;
         }
 
+        // If the token has a value, but could not be found in the token maps, try to infer its type
+        // from the name and value. This is fairly rare, but can happen for some hardcoded tokens.
+        @if ($value == null and $resolved-value) {
+          $fallback-type: ${inferTokenType}($name, $resolved-value);
+
+          @if ($fallback-type == null) {
+            @error 'Cannot determine type of token "#{$name}". Token extraction script needs to be updated.';
+          }
+
+          $type: $fallback-type;
+          $value: $resolved-value;
+        }
+
         @if ($value) {
           $__results: ${list}.append($__results, (
             name: ${str}.unquote($name),
diff --git a/tools/postinstall/patches/@angular+bazel+16.0.0-next.6.patch b/tools/postinstall/patches/@angular+bazel+16.0.0-next.6.patch
index 75d5af2208d6..c253e05ab2dd 100644
--- a/tools/postinstall/patches/@angular+bazel+16.0.0-next.6.patch
+++ b/tools/postinstall/patches/@angular+bazel+16.0.0-next.6.patch
@@ -1,5 +1,5 @@
 diff --git a/node_modules/@angular/bazel/src/ng_module/ng_module.bzl b/node_modules/@angular/bazel/src/ng_module/ng_module.bzl
-index 99d7f6d..3ea60ea 100755
+index 5e82bcb..3c239f8 100755
 --- a/node_modules/@angular/bazel/src/ng_module/ng_module.bzl
 +++ b/node_modules/@angular/bazel/src/ng_module/ng_module.bzl
 @@ -18,6 +18,7 @@ load(
@@ -22,7 +22,7 @@ index 99d7f6d..3ea60ea 100755
 
      if not ctx.attr.type_check and ctx.attr.strict_templates:
          fail("Cannot set type_check = False and strict_templates = True for ng_module()")
-@@ -359,11 +360,11 @@ def _compile_action(
+@@ -355,11 +356,11 @@ def _compile_action(
 
  def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
      outs = _expected_outs(ctx)
@@ -36,7 +36,7 @@ index 99d7f6d..3ea60ea 100755
      _compile_action(ctx, inputs, compile_action_outputs, tsconfig_file, node_opts, "devmode")
 
  # Note: We need to define `label` and `srcs_files` as `tsc_wrapped` passes
-@@ -417,9 +418,13 @@ def _ng_module_impl(ctx):
+@@ -413,9 +414,13 @@ def _ng_module_impl(ctx):
      # and issue https://github.com/bazelbuild/rules_nodejs/issues/57 for more details.
      ts_providers["providers"].extend([
          js_module_info(
@@ -51,7 +51,7 @@ index 99d7f6d..3ea60ea 100755
          js_ecma_script_module_info(
              sources = ts_providers["typescript"]["es6_sources"],
              deps = ctx.attr.deps,
-@@ -435,7 +440,7 @@ def _ng_module_impl(ctx):
+@@ -431,7 +436,7 @@ def _ng_module_impl(ctx):
              package_name = ctx.attr.package_name,
              package_path = ctx.attr.package_path,
              path = path,
@@ -61,7 +61,7 @@ index 99d7f6d..3ea60ea 100755
 
      return ts_providers_dict_to_struct(ts_providers)
 diff --git a/node_modules/@angular/bazel/src/ng_package/packager.mjs b/node_modules/@angular/bazel/src/ng_package/packager.mjs
-index 12d5f0c..8868e27 100755
+index 7184fd9..ef3e508 100755
 --- a/node_modules/@angular/bazel/src/ng_package/packager.mjs
 +++ b/node_modules/@angular/bazel/src/ng_package/packager.mjs
 @@ -7,7 +7,7 @@
@@ -74,7 +74,7 @@ index 12d5f0c..8868e27 100755
   * List of known `package.json` fields which provide information about
   * supported package formats and their associated entry paths.
 diff --git a/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs b/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs
-index 09deff8..00d24be 100755
+index def2972..3de33ba 100755
 --- a/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs
 +++ b/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs
 @@ -12,7 +12,7 @@ import tscw from '@bazel/concatjs/internal/tsc_wrapped/index.js';
@@ -86,7 +86,7 @@ index 09deff8..00d24be 100755
  // FIXME: we should be able to add the assets to the tsconfig so FileLoader
  // knows about them
  const NGC_ASSETS = /\.(css|html)$/;
-@@ -348,6 +348,12 @@ function gatherDiagnosticsForInputsOnly(options, bazelOpts, ngProgram) {
+@@ -349,6 +349,12 @@ function gatherDiagnosticsForInputsOnly(options, bazelOpts, ngProgram) {
      }
      return diagnostics;
  }
@@ -100,12 +100,12 @@ index 09deff8..00d24be 100755
   * @deprecated
   * Kept here just for compatibility with 1P tools. To be removed soon after 1P update.
 diff --git a/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs b/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs
-index ccf82d2..daaa783 100755
+index 8efba56..d420348 100755
 --- a/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs
 +++ b/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs
 @@ -5,7 +5,7 @@
   * Use of this source code is governed by an MIT-style license that can be
-  * found in the LICENSE file at https://angular.io/license
+  * found in the LICENSE file at https://angular.dev/license
   */
 -import { main } from './index';
 +import { main } from './index.mjs';
diff --git a/tools/public_api_guard/cdk/a11y.md b/tools/public_api_guard/cdk/a11y.md
index 22d42d45c361..d447dca237d1 100644
--- a/tools/public_api_guard/cdk/a11y.md
+++ b/tools/public_api_guard/cdk/a11y.md
@@ -291,6 +291,15 @@ export interface Highlightable extends ListKeyManagerOption {
     setInactiveStyles(): void;
 }
 
+// @public
+export class _IdGenerator {
+    getId(prefix: string): string;
+    // (undocumented)
+    static ɵfac: i0.ɵɵFactoryDeclaration<_IdGenerator, never>;
+    // (undocumented)
+    static ɵprov: i0.ɵɵInjectableDeclaration<_IdGenerator>;
+}
+
 // @public
 export const INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS: InputModalityDetectorOptions;
 
diff --git a/tools/public_api_guard/cdk/drag-drop.md b/tools/public_api_guard/cdk/drag-drop.md
index bb39566f6fdc..28e2c19ceba0 100644
--- a/tools/public_api_guard/cdk/drag-drop.md
+++ b/tools/public_api_guard/cdk/drag-drop.md
@@ -16,6 +16,7 @@ import { NumberInput } from '@angular/cdk/coercion';
 import { Observable } from 'rxjs';
 import { OnChanges } from '@angular/core';
 import { OnDestroy } from '@angular/core';
+import { Renderer2 } from '@angular/core';
 import { SimpleChanges } from '@angular/core';
 import { Subject } from 'rxjs';
 import { TemplateRef } from '@angular/core';
@@ -150,7 +151,7 @@ export interface CdkDragExit<T = any, I = T> {
 }
 
 // @public
-export class CdkDragHandle implements OnDestroy {
+export class CdkDragHandle implements AfterViewInit, OnDestroy {
     constructor(...args: unknown[]);
     get disabled(): boolean;
     set disabled(value: boolean);
@@ -159,6 +160,8 @@ export class CdkDragHandle implements OnDestroy {
     // (undocumented)
     static ngAcceptInputType_disabled: unknown;
     // (undocumented)
+    ngAfterViewInit(): void;
+    // (undocumented)
     ngOnDestroy(): void;
     readonly _stateChanges: Subject<CdkDragHandle>;
     // (undocumented)
@@ -351,13 +354,16 @@ export class DragDropModule {
 // @public
 export class DragDropRegistry<_ = unknown, __ = unknown> implements OnDestroy {
     constructor(...args: unknown[]);
+    getDragDirectiveForNode(node: Node): CdkDrag | null;
     isDragging(drag: DragRef): boolean;
     // (undocumented)
     ngOnDestroy(): void;
     readonly pointerMove: Subject<TouchEvent | MouseEvent>;
     readonly pointerUp: Subject<TouchEvent | MouseEvent>;
+    registerDirectiveNode(node: Node, dragRef: CdkDrag): void;
     registerDragItem(drag: DragRef): void;
     registerDropContainer(drop: DropListRef): void;
+    removeDirectiveNode(node: Node): void;
     removeDragItem(drag: DragRef): void;
     removeDropContainer(drop: DropListRef): void;
     // @deprecated
@@ -373,7 +379,7 @@ export class DragDropRegistry<_ = unknown, __ = unknown> implements OnDestroy {
 
 // @public
 export class DragRef<T = any> {
-    constructor(element: ElementRef<HTMLElement> | HTMLElement, _config: DragRefConfig, _document: Document, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry);
+    constructor(element: ElementRef<HTMLElement> | HTMLElement, _config: DragRefConfig, _document: Document, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry, _renderer: Renderer2);
     readonly beforeStarted: Subject<void>;
     constrainPosition?: (userPointerPosition: Point, dragRef: DragRef, dimensions: DOMRect, pickupPositionInElement: Point) => Point;
     data: T;
diff --git a/tools/public_api_guard/cdk/listbox.md b/tools/public_api_guard/cdk/listbox.md
index 8855be392fb9..e3d0e1b391fd 100644
--- a/tools/public_api_guard/cdk/listbox.md
+++ b/tools/public_api_guard/cdk/listbox.md
@@ -26,13 +26,14 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
     deselect(option: CdkOption<T>): void;
     deselectValue(value: T): void;
     protected readonly destroyed: Subject<void>;
-    disabled: boolean;
+    get disabled(): boolean;
+    set disabled(value: boolean);
     protected readonly element: HTMLElement;
-    get enabledTabIndex(): number | null;
-    set enabledTabIndex(value: number | null);
+    get enabledTabIndex(): number | null | undefined;
+    set enabledTabIndex(value: number | null | undefined);
     focus(): void;
     protected _getAriaActiveDescendant(): string | null | undefined;
-    protected _getTabIndex(): number | null;
+    protected _getTabIndex(): number | null | undefined;
     protected _handleFocus(): void;
     protected _handleFocusIn(): void;
     protected _handleFocusOut(event: FocusEvent): void;
@@ -79,7 +80,8 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
     toggleValue(value: T): void;
     protected triggerOption(option: CdkOption<T> | null): void;
     protected triggerRange(trigger: CdkOption<T> | null, from: number, to: number, on: boolean): void;
-    useActiveDescendant: boolean;
+    get useActiveDescendant(): boolean;
+    set useActiveDescendant(value: boolean);
     get value(): readonly T[];
     set value(value: readonly T[]);
     readonly valueChange: Subject<ListboxValueChangeEvent<T>>;
@@ -108,11 +110,11 @@ export class CdkOption<T = unknown> implements ListKeyManagerOption, Highlightab
     get disabled(): boolean;
     set disabled(value: boolean);
     readonly element: HTMLElement;
-    get enabledTabIndex(): number | null;
-    set enabledTabIndex(value: number | null);
+    get enabledTabIndex(): number | null | undefined;
+    set enabledTabIndex(value: number | null | undefined);
     focus(): void;
     getLabel(): string;
-    protected _getTabIndex(): number | null;
+    protected _getTabIndex(): number | null | undefined;
     protected _handleFocus(): void;
     get id(): string;
     set id(value: string);
diff --git a/tools/public_api_guard/cdk/overlay.md b/tools/public_api_guard/cdk/overlay.md
index 4170e1a05877..0b21afc55cdd 100644
--- a/tools/public_api_guard/cdk/overlay.md
+++ b/tools/public_api_guard/cdk/overlay.md
@@ -27,6 +27,7 @@ import { OnChanges } from '@angular/core';
 import { OnDestroy } from '@angular/core';
 import { Platform } from '@angular/cdk/platform';
 import { PortalOutlet } from '@angular/cdk/portal';
+import { Renderer2 } from '@angular/core';
 import { ScrollDispatcher } from '@angular/cdk/scrolling';
 import { SimpleChanges } from '@angular/core';
 import { Subject } from 'rxjs';
@@ -356,7 +357,7 @@ export class OverlayPositionBuilder {
 
 // @public
 export class OverlayRef implements PortalOutlet {
-    constructor(_portalOutlet: PortalOutlet, _host: HTMLElement, _pane: HTMLElement, _config: ImmutableObject<OverlayConfig>, _ngZone: NgZone, _keyboardDispatcher: OverlayKeyboardDispatcher, _document: Document, _location: Location_2, _outsideClickDispatcher: OverlayOutsideClickDispatcher, _animationsDisabled: boolean | undefined, _injector: EnvironmentInjector);
+    constructor(_portalOutlet: PortalOutlet, _host: HTMLElement, _pane: HTMLElement, _config: ImmutableObject<OverlayConfig>, _ngZone: NgZone, _keyboardDispatcher: OverlayKeyboardDispatcher, _document: Document, _location: Location_2, _outsideClickDispatcher: OverlayOutsideClickDispatcher, _animationsDisabled: boolean | undefined, _injector: EnvironmentInjector, _renderer: Renderer2);
     addPanelClass(classes: string | string[]): void;
     // (undocumented)
     attach<T>(portal: ComponentPortal<T>): ComponentRef<T>;
diff --git a/tools/public_api_guard/cdk/stepper.md b/tools/public_api_guard/cdk/stepper.md
index 6c82b9b106b9..5279141041e4 100644
--- a/tools/public_api_guard/cdk/stepper.md
+++ b/tools/public_api_guard/cdk/stepper.md
@@ -100,7 +100,6 @@ export class CdkStepper implements AfterContentInit, AfterViewInit, OnDestroy {
     _getIndicatorType(index: number, state?: StepState): StepState;
     _getStepContentId(i: number): string;
     _getStepLabelId(i: number): string;
-    _groupId: number;
     linear: boolean;
     next(): void;
     // (undocumented)
diff --git a/tools/public_api_guard/cdk/table.md b/tools/public_api_guard/cdk/table.md
index 6b32402b128a..21da470d629a 100644
--- a/tools/public_api_guard/cdk/table.md
+++ b/tools/public_api_guard/cdk/table.md
@@ -565,7 +565,7 @@ export class StickyStyler {
     _getStickyStartColumnPositions(widths: number[], stickyStates: boolean[]): number[];
     _removeStickyStyle(element: HTMLElement, stickyDirections: StickyDirection[]): void;
     stickRows(rowsToStick: HTMLElement[], stickyStates: boolean[], position: 'top' | 'bottom'): void;
-    updateStickyColumns(rows: HTMLElement[], stickyStartStates: boolean[], stickyEndStates: boolean[], recalculateCellWidths?: boolean): void;
+    updateStickyColumns(rows: HTMLElement[], stickyStartStates: boolean[], stickyEndStates: boolean[], recalculateCellWidths?: boolean, replay?: boolean): void;
     updateStickyFooterContainer(tableElement: Element, stickyStates: boolean[]): void;
 }
 
diff --git a/tools/public_api_guard/cdk/tree.md b/tools/public_api_guard/cdk/tree.md
index 655f0f2c5456..dda4541d9306 100644
--- a/tools/public_api_guard/cdk/tree.md
+++ b/tools/public_api_guard/cdk/tree.md
@@ -54,7 +54,7 @@ export abstract class BaseTreeControl<T, K = T> implements TreeControl<T, K> {
 export const CDK_TREE_NODE_OUTLET_NODE: InjectionToken<{}>;
 
 // @public
-export class CdkNestedTreeNode<T, K = T> extends CdkTreeNode<T, K> implements AfterContentInit, OnDestroy, OnInit {
+export class CdkNestedTreeNode<T, K = T> extends CdkTreeNode<T, K> implements AfterContentInit, OnDestroy {
     constructor(...args: unknown[]);
     protected _children: T[];
     protected _clear(): void;
@@ -64,9 +64,9 @@ export class CdkNestedTreeNode<T, K = T> extends CdkTreeNode<T, K> implements Af
     ngAfterContentInit(): void;
     // (undocumented)
     ngOnDestroy(): void;
-    // (undocumented)
-    ngOnInit(): void;
     nodeOutlet: QueryList<CdkTreeNodeOutlet>;
+    // (undocumented)
+    protected _type: 'flat' | 'nested';
     protected updateChildrenNodes(children?: T[]): void;
     // (undocumented)
     static ɵdir: i0.ɵɵDirectiveDeclaration<CdkNestedTreeNode<any, any>, "cdk-nested-tree-node", ["cdkNestedTreeNode"], {}, {}, ["nodeOutlet"], never, true, never>;
@@ -118,7 +118,7 @@ export class CdkTree<T, K = T> implements AfterContentChecked, AfterContentInit,
     _registerNode(node: CdkTreeNode<T, K>): void;
     renderNodeChanges(data: readonly T[], dataDiffer?: IterableDiffer<T>, viewContainer?: ViewContainerRef, parentData?: T): void;
     protected _sendKeydownToKeyManager(event: KeyboardEvent): void;
-    _setNodeTypeIfUnset(nodeType: 'flat' | 'nested'): void;
+    _setNodeTypeIfUnset(newType: 'flat' | 'nested'): void;
     toggle(dataNode: T): void;
     toggleDescendants(dataNode: T): void;
     trackBy: TrackByFunction<T>;
@@ -205,6 +205,8 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
     protected _tabindex: number | null;
     // (undocumented)
     protected _tree: CdkTree<T, K>;
+    // (undocumented)
+    protected readonly _type: 'flat' | 'nested';
     typeaheadLabel: string | null;
     unfocus(): void;
     // (undocumented)
diff --git a/tools/public_api_guard/material/autocomplete.md b/tools/public_api_guard/material/autocomplete.md
index 4949ce629f4c..cbe39d11f711 100644
--- a/tools/public_api_guard/material/autocomplete.md
+++ b/tools/public_api_guard/material/autocomplete.md
@@ -14,8 +14,7 @@ import { EventEmitter } from '@angular/core';
 import * as i0 from '@angular/core';
 import * as i1 from '@angular/cdk/overlay';
 import * as i2 from '@angular/material/core';
-import * as i3 from '@angular/common';
-import * as i7 from '@angular/cdk/scrolling';
+import * as i6 from '@angular/cdk/scrolling';
 import { InjectionToken } from '@angular/core';
 import { MatOptgroup } from '@angular/material/core';
 import { MatOption } from '@angular/material/core';
@@ -142,7 +141,7 @@ export class MatAutocompleteModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatAutocompleteModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatAutocompleteModule, never, [typeof i1.OverlayModule, typeof i2.MatOptionModule, typeof i2.MatCommonModule, typeof i3.CommonModule, typeof i4.MatAutocomplete, typeof i5.MatAutocompleteTrigger, typeof i6.MatAutocompleteOrigin], [typeof i7.CdkScrollableModule, typeof i4.MatAutocomplete, typeof i2.MatOptionModule, typeof i2.MatCommonModule, typeof i5.MatAutocompleteTrigger, typeof i6.MatAutocompleteOrigin]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatAutocompleteModule, never, [typeof i1.OverlayModule, typeof i2.MatOptionModule, typeof i2.MatCommonModule, typeof i3.MatAutocomplete, typeof i4.MatAutocompleteTrigger, typeof i5.MatAutocompleteOrigin], [typeof i6.CdkScrollableModule, typeof i3.MatAutocomplete, typeof i2.MatOptionModule, typeof i2.MatCommonModule, typeof i4.MatAutocompleteTrigger, typeof i5.MatAutocompleteOrigin]>;
 }
 
 // @public
diff --git a/tools/public_api_guard/material/badge.md b/tools/public_api_guard/material/badge.md
index 85c9f45e0869..e42871f140e8 100644
--- a/tools/public_api_guard/material/badge.md
+++ b/tools/public_api_guard/material/badge.md
@@ -23,7 +23,6 @@ export class MatBadge implements OnInit, OnDestroy {
     disabled: boolean;
     getBadgeElement(): HTMLElement | undefined;
     hidden: boolean;
-    _id: number;
     isAbove(): boolean;
     isAfter(): boolean;
     // (undocumented)
diff --git a/tools/public_api_guard/material/bottom-sheet.md b/tools/public_api_guard/material/bottom-sheet.md
index 586bbde9a9c7..da17b68955fd 100644
--- a/tools/public_api_guard/material/bottom-sheet.md
+++ b/tools/public_api_guard/material/bottom-sheet.md
@@ -64,6 +64,9 @@ export class MatBottomSheetConfig<D = any> {
     direction?: Direction;
     disableClose?: boolean;
     hasBackdrop?: boolean;
+    height?: string;
+    maxHeight?: number | string;
+    minHeight?: number | string;
     panelClass?: string | string[];
     restoreFocus?: boolean;
     scrollStrategy?: ScrollStrategy;
diff --git a/tools/public_api_guard/material/button.md b/tools/public_api_guard/material/button.md
index 3c9326f8311c..1bd43539fc33 100644
--- a/tools/public_api_guard/material/button.md
+++ b/tools/public_api_guard/material/button.md
@@ -14,7 +14,6 @@ import { MatRippleLoader } from '@angular/material/core';
 import { NgZone } from '@angular/core';
 import { OnDestroy } from '@angular/core';
 import { OnInit } from '@angular/core';
-import { Platform } from '@angular/cdk/platform';
 import { ThemePalette } from '@angular/material/core';
 
 // @public
diff --git a/tools/public_api_guard/material/card.md b/tools/public_api_guard/material/card.md
index 576c88722df2..628fe507ac5b 100644
--- a/tools/public_api_guard/material/card.md
+++ b/tools/public_api_guard/material/card.md
@@ -6,7 +6,6 @@
 
 import * as i0 from '@angular/core';
 import * as i1 from '@angular/material/core';
-import * as i2 from '@angular/common';
 import { InjectionToken } from '@angular/core';
 
 // @public
@@ -103,7 +102,7 @@ export class MatCardModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatCardModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatCardModule, never, [typeof i1.MatCommonModule, typeof i2.CommonModule, typeof i3.MatCard, typeof i3.MatCardActions, typeof i3.MatCardAvatar, typeof i3.MatCardContent, typeof i3.MatCardFooter, typeof i3.MatCardHeader, typeof i3.MatCardImage, typeof i3.MatCardLgImage, typeof i3.MatCardMdImage, typeof i3.MatCardSmImage, typeof i3.MatCardSubtitle, typeof i3.MatCardTitle, typeof i3.MatCardTitleGroup, typeof i3.MatCardXlImage], [typeof i3.MatCard, typeof i3.MatCardActions, typeof i3.MatCardAvatar, typeof i3.MatCardContent, typeof i3.MatCardFooter, typeof i3.MatCardHeader, typeof i3.MatCardImage, typeof i3.MatCardLgImage, typeof i3.MatCardMdImage, typeof i3.MatCardSmImage, typeof i3.MatCardSubtitle, typeof i3.MatCardTitle, typeof i3.MatCardTitleGroup, typeof i3.MatCardXlImage, typeof i1.MatCommonModule]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatCardModule, never, [typeof i1.MatCommonModule, typeof i2.MatCard, typeof i2.MatCardActions, typeof i2.MatCardAvatar, typeof i2.MatCardContent, typeof i2.MatCardFooter, typeof i2.MatCardHeader, typeof i2.MatCardImage, typeof i2.MatCardLgImage, typeof i2.MatCardMdImage, typeof i2.MatCardSmImage, typeof i2.MatCardSubtitle, typeof i2.MatCardTitle, typeof i2.MatCardTitleGroup, typeof i2.MatCardXlImage], [typeof i2.MatCard, typeof i2.MatCardActions, typeof i2.MatCardAvatar, typeof i2.MatCardContent, typeof i2.MatCardFooter, typeof i2.MatCardHeader, typeof i2.MatCardImage, typeof i2.MatCardLgImage, typeof i2.MatCardMdImage, typeof i2.MatCardSmImage, typeof i2.MatCardSubtitle, typeof i2.MatCardTitle, typeof i2.MatCardTitleGroup, typeof i2.MatCardXlImage, typeof i1.MatCommonModule]>;
 }
 
 // @public
diff --git a/tools/public_api_guard/material/datepicker.md b/tools/public_api_guard/material/datepicker.md
index ee65f1dbf42c..e36f6f9de145 100644
--- a/tools/public_api_guard/material/datepicker.md
+++ b/tools/public_api_guard/material/datepicker.md
@@ -23,13 +23,12 @@ import { FactoryProvider } from '@angular/core';
 import { FocusOrigin } from '@angular/cdk/a11y';
 import { FormGroupDirective } from '@angular/forms';
 import * as i0 from '@angular/core';
-import * as i1 from '@angular/common';
-import * as i2 from '@angular/material/button';
-import * as i20 from '@angular/cdk/scrolling';
-import * as i3 from '@angular/cdk/overlay';
-import * as i4 from '@angular/cdk/a11y';
-import * as i5 from '@angular/cdk/portal';
-import * as i6 from '@angular/material/core';
+import * as i1 from '@angular/material/button';
+import * as i19 from '@angular/cdk/scrolling';
+import * as i2 from '@angular/cdk/overlay';
+import * as i3 from '@angular/cdk/a11y';
+import * as i4 from '@angular/cdk/portal';
+import * as i5 from '@angular/material/core';
 import { InjectionToken } from '@angular/core';
 import { MatButton } from '@angular/material/button';
 import { MatFormFieldControl } from '@angular/material/form-field';
@@ -42,7 +41,6 @@ import { OnInit } from '@angular/core';
 import { Overlay } from '@angular/cdk/overlay';
 import { Portal } from '@angular/cdk/portal';
 import { ScrollStrategy } from '@angular/cdk/overlay';
-import { Signal } from '@angular/core';
 import { SimpleChanges } from '@angular/core';
 import { Subject } from 'rxjs';
 import { TemplatePortal } from '@angular/cdk/portal';
@@ -197,14 +195,17 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
     _cellClicked(cell: MatCalendarCell, event: MouseEvent): void;
     _cellPadding: string;
     _cellWidth: string;
+    // (undocumented)
+    comparisonDateAccessibleName: string;
     comparisonEnd: number | null;
+    _comparisonEndDateLabelId: string;
     comparisonStart: number | null;
+    _comparisonStartDateLabelId: string;
     readonly dragEnded: EventEmitter<MatCalendarUserEvent<D | null>>;
     readonly dragStarted: EventEmitter<MatCalendarUserEvent<D>>;
     // (undocumented)
     _emitActiveDateChange(cell: MatCalendarCell, event: FocusEvent): void;
     endDateAccessibleName: string | null;
-    // (undocumented)
     _endDateLabelId: string;
     endValue: number;
     _firstRowOffset: number;
@@ -241,7 +242,6 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
     _scheduleFocusActiveCellAfterViewChecked(): void;
     readonly selectedValueChange: EventEmitter<MatCalendarUserEvent<number>>;
     startDateAccessibleName: string | null;
-    // (undocumented)
     _startDateLabelId: string;
     startValue: number;
     todayValue: number;
@@ -483,6 +483,7 @@ export class MatDatepickerIntl {
     calendarLabel: string;
     readonly changes: Subject<void>;
     closeCalendarLabel: string;
+    comparisonDateLabel: string;
     // @deprecated
     endDateLabel: string;
     formatYearRange(start: string, end: string): string;
@@ -511,7 +512,7 @@ export class MatDatepickerModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatDatepickerModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatDatepickerModule, never, [typeof i1.CommonModule, typeof i2.MatButtonModule, typeof i3.OverlayModule, typeof i4.A11yModule, typeof i5.PortalModule, typeof i6.MatCommonModule, typeof i7.MatCalendar, typeof i8.MatCalendarBody, typeof i9.MatDatepicker, typeof i10.MatDatepickerContent, typeof i11.MatDatepickerInput, typeof i12.MatDatepickerToggle, typeof i12.MatDatepickerToggleIcon, typeof i13.MatMonthView, typeof i14.MatYearView, typeof i15.MatMultiYearView, typeof i7.MatCalendarHeader, typeof i16.MatDateRangeInput, typeof i17.MatStartDate, typeof i17.MatEndDate, typeof i18.MatDateRangePicker, typeof i19.MatDatepickerActions, typeof i19.MatDatepickerCancel, typeof i19.MatDatepickerApply], [typeof i20.CdkScrollableModule, typeof i7.MatCalendar, typeof i8.MatCalendarBody, typeof i9.MatDatepicker, typeof i10.MatDatepickerContent, typeof i11.MatDatepickerInput, typeof i12.MatDatepickerToggle, typeof i12.MatDatepickerToggleIcon, typeof i13.MatMonthView, typeof i14.MatYearView, typeof i15.MatMultiYearView, typeof i7.MatCalendarHeader, typeof i16.MatDateRangeInput, typeof i17.MatStartDate, typeof i17.MatEndDate, typeof i18.MatDateRangePicker, typeof i19.MatDatepickerActions, typeof i19.MatDatepickerCancel, typeof i19.MatDatepickerApply]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatDatepickerModule, never, [typeof i1.MatButtonModule, typeof i2.OverlayModule, typeof i3.A11yModule, typeof i4.PortalModule, typeof i5.MatCommonModule, typeof i6.MatCalendar, typeof i7.MatCalendarBody, typeof i8.MatDatepicker, typeof i9.MatDatepickerContent, typeof i10.MatDatepickerInput, typeof i11.MatDatepickerToggle, typeof i11.MatDatepickerToggleIcon, typeof i12.MatMonthView, typeof i13.MatYearView, typeof i14.MatMultiYearView, typeof i6.MatCalendarHeader, typeof i15.MatDateRangeInput, typeof i16.MatStartDate, typeof i16.MatEndDate, typeof i17.MatDateRangePicker, typeof i18.MatDatepickerActions, typeof i18.MatDatepickerCancel, typeof i18.MatDatepickerApply], [typeof i19.CdkScrollableModule, typeof i6.MatCalendar, typeof i7.MatCalendarBody, typeof i8.MatDatepicker, typeof i9.MatDatepickerContent, typeof i10.MatDatepickerInput, typeof i11.MatDatepickerToggle, typeof i11.MatDatepickerToggleIcon, typeof i12.MatMonthView, typeof i13.MatYearView, typeof i14.MatMultiYearView, typeof i6.MatCalendarHeader, typeof i15.MatDateRangeInput, typeof i16.MatStartDate, typeof i16.MatEndDate, typeof i17.MatDateRangePicker, typeof i18.MatDatepickerActions, typeof i18.MatDatepickerCancel, typeof i18.MatDatepickerApply]>;
 }
 
 // @public
@@ -566,7 +567,7 @@ export class MatDatepickerToggleIcon {
 }
 
 // @public (undocumented)
-export class MatDateRangeInput<D> implements MatFormFieldControl<DateRange<D>>, MatDatepickerControl<D>, MatDateRangeInputParent<D>, MatDateRangePickerInput<D>, AfterContentInit, OnChanges, OnDestroy {
+export class MatDateRangeInput<D> implements MatFormFieldControl<DateRange<D>>, MatDatepickerControl<D>, MatDateRangePickerInput<D>, AfterContentInit, OnChanges, OnDestroy {
     constructor(...args: unknown[]);
     _ariaDescribedBy: string | null;
     _ariaOwns: WritableSignal<string | null>;
@@ -630,7 +631,7 @@ export class MatDateRangeInput<D> implements MatFormFieldControl<DateRange<D>>,
     _updateFocus(origin: FocusOrigin): void;
     get value(): DateRange<D> | null;
     // (undocumented)
-    static ɵcmp: i0.ɵɵComponentDeclaration<MatDateRangeInput<any>, "mat-date-range-input", ["matDateRangeInput"], { "rangePicker": { "alias": "rangePicker"; "required": false; }; "required": { "alias": "required"; "required": false; }; "dateFilter": { "alias": "dateFilter"; "required": false; }; "min": { "alias": "min"; "required": false; }; "max": { "alias": "max"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "separator": { "alias": "separator"; "required": false; }; "comparisonStart": { "alias": "comparisonStart"; "required": false; }; "comparisonEnd": { "alias": "comparisonEnd"; "required": false; }; }, {}, ["_startInput", "_endInput"], ["input[matStartDate]", "input[matEndDate]"], true, never>;
+    static ɵcmp: i0.ɵɵComponentDeclaration<MatDateRangeInput<any>, "mat-date-range-input", ["matDateRangeInput"], { "rangePicker": { "alias": "rangePicker"; "required": false; }; "required": { "alias": "required"; "required": false; }; "dateFilter": { "alias": "dateFilter"; "required": false; }; "min": { "alias": "min"; "required": false; }; "max": { "alias": "max"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "separator": { "alias": "separator"; "required": false; }; "comparisonStart": { "alias": "comparisonStart"; "required": false; }; "comparisonEnd": { "alias": "comparisonEnd"; "required": false; }; }, {}, never, ["input[matStartDate]", "input[matEndDate]"], true, never>;
     // (undocumented)
     static ɵfac: i0.ɵɵFactoryDeclaration<MatDateRangeInput<any>, never>;
 }
@@ -684,6 +685,8 @@ export class MatEndDate<D> extends MatDateRangeInputPartBase<D> {
     // (undocumented)
     _onKeydown(event: KeyboardEvent): void;
     // (undocumented)
+    protected _register(): void;
+    // (undocumented)
     protected _shouldHandleChangeEvent(change: DateSelectionModelChange<DateRange<D>>): boolean;
     // (undocumented)
     protected _validator: ValidatorFn | null;
@@ -836,6 +839,8 @@ export class MatStartDate<D> extends MatDateRangeInputPartBase<D> {
     // (undocumented)
     _onKeydown(event: KeyboardEvent): void;
     // (undocumented)
+    protected _register(): void;
+    // (undocumented)
     protected _shouldHandleChangeEvent(change: DateSelectionModelChange<DateRange<D>>): boolean;
     // (undocumented)
     protected _validator: ValidatorFn | null;
diff --git a/tools/public_api_guard/material/expansion.md b/tools/public_api_guard/material/expansion.md
index e4c2339ae2c2..fd9c46d1a7d1 100644
--- a/tools/public_api_guard/material/expansion.md
+++ b/tools/public_api_guard/material/expansion.md
@@ -6,7 +6,6 @@
 
 import { AfterContentInit } from '@angular/core';
 import { AfterViewInit } from '@angular/core';
-import { AnimationEvent as AnimationEvent_2 } from '@angular/animations';
 import { AnimationTriggerMetadata } from '@angular/animations';
 import { CdkAccordion } from '@angular/cdk/accordion';
 import { CdkAccordionItem } from '@angular/cdk/accordion';
@@ -75,7 +74,7 @@ export type MatAccordionDisplayMode = 'default' | 'flat';
 // @public
 export type MatAccordionTogglePosition = 'before' | 'after';
 
-// @public
+// @public @deprecated
 export const matExpansionAnimations: {
     readonly indicatorRotate: AnimationTriggerMetadata;
     readonly bodyExpansion: AnimationTriggerMetadata;
@@ -97,13 +96,8 @@ export class MatExpansionPanel extends CdkAccordionItem implements AfterContentI
     accordion: MatAccordionBase;
     readonly afterCollapse: EventEmitter<void>;
     readonly afterExpand: EventEmitter<void>;
-    protected _animationDone(event: AnimationEvent_2): void;
-    // (undocumented)
-    _animationMode: "NoopAnimations" | "BrowserAnimations" | null;
-    // (undocumented)
-    protected _animationsDisabled: boolean;
-    protected _animationStarted(event: AnimationEvent_2): void;
     _body: ElementRef<HTMLElement>;
+    protected _bodyWrapper: ElementRef<HTMLElement> | undefined;
     close(): void;
     _containsFocus(): boolean;
     _getExpandedState(): MatExpansionPanelState;
@@ -123,6 +117,8 @@ export class MatExpansionPanel extends CdkAccordionItem implements AfterContentI
     ngOnDestroy(): void;
     open(): void;
     _portal: TemplatePortal;
+    // (undocumented)
+    protected _setupAnimationEvents(): void;
     toggle(): void;
     get togglePosition(): MatAccordionTogglePosition;
     set togglePosition(value: MatAccordionTogglePosition);
@@ -171,8 +167,6 @@ export class MatExpansionPanelDescription {
 // @public
 export class MatExpansionPanelHeader implements AfterViewInit, OnDestroy, FocusableOption {
     constructor(...args: unknown[]);
-    // (undocumented)
-    _animationMode: "NoopAnimations" | "BrowserAnimations" | null;
     collapsedHeight: string;
     get disabled(): boolean;
     expandedHeight: string;
diff --git a/tools/public_api_guard/material/form-field.md b/tools/public_api_guard/material/form-field.md
index db2b4bf94c92..f7efb046f473 100644
--- a/tools/public_api_guard/material/form-field.md
+++ b/tools/public_api_guard/material/form-field.md
@@ -13,8 +13,7 @@ import { BooleanInput } from '@angular/cdk/coercion';
 import { ElementRef } from '@angular/core';
 import * as i0 from '@angular/core';
 import * as i1 from '@angular/material/core';
-import * as i2 from '@angular/common';
-import * as i3 from '@angular/cdk/observers';
+import * as i2 from '@angular/cdk/observers';
 import { InjectionToken } from '@angular/core';
 import { NgControl } from '@angular/forms';
 import { Observable } from 'rxjs';
@@ -198,7 +197,7 @@ export class MatFormFieldModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatFormFieldModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatFormFieldModule, never, [typeof i1.MatCommonModule, typeof i2.CommonModule, typeof i3.ObserversModule, typeof i4.MatFormField, typeof i5.MatLabel, typeof i6.MatError, typeof i7.MatHint, typeof i8.MatPrefix, typeof i9.MatSuffix], [typeof i4.MatFormField, typeof i5.MatLabel, typeof i7.MatHint, typeof i6.MatError, typeof i8.MatPrefix, typeof i9.MatSuffix, typeof i1.MatCommonModule]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatFormFieldModule, never, [typeof i1.MatCommonModule, typeof i2.ObserversModule, typeof i3.MatFormField, typeof i4.MatLabel, typeof i5.MatError, typeof i6.MatHint, typeof i7.MatPrefix, typeof i8.MatSuffix], [typeof i3.MatFormField, typeof i4.MatLabel, typeof i6.MatHint, typeof i5.MatError, typeof i7.MatPrefix, typeof i8.MatSuffix, typeof i1.MatCommonModule]>;
 }
 
 // @public
diff --git a/tools/public_api_guard/material/list.md b/tools/public_api_guard/material/list.md
index a9a2eafe9a27..07dd4c82049c 100644
--- a/tools/public_api_guard/material/list.md
+++ b/tools/public_api_guard/material/list.md
@@ -11,9 +11,8 @@ import { ElementRef } from '@angular/core';
 import { EventEmitter } from '@angular/core';
 import * as i0 from '@angular/core';
 import * as i1 from '@angular/cdk/observers';
-import * as i11 from '@angular/material/divider';
-import * as i2 from '@angular/common';
-import * as i3 from '@angular/material/core';
+import * as i10 from '@angular/material/divider';
+import * as i2 from '@angular/material/core';
 import { InjectionToken } from '@angular/core';
 import { NgZone } from '@angular/core';
 import { OnChanges } from '@angular/core';
@@ -153,7 +152,7 @@ export class MatListModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatListModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatListModule, never, [typeof i1.ObserversModule, typeof i2.CommonModule, typeof i3.MatCommonModule, typeof i3.MatRippleModule, typeof i3.MatPseudoCheckboxModule, typeof i4.MatList, typeof i5.MatActionList, typeof i6.MatNavList, typeof i7.MatSelectionList, typeof i4.MatListItem, typeof i8.MatListOption, typeof i9.MatListSubheaderCssMatStyler, typeof i10.MatListItemAvatar, typeof i10.MatListItemIcon, typeof i10.MatListItemLine, typeof i10.MatListItemTitle, typeof i10.MatListItemMeta], [typeof i4.MatList, typeof i5.MatActionList, typeof i6.MatNavList, typeof i7.MatSelectionList, typeof i4.MatListItem, typeof i8.MatListOption, typeof i10.MatListItemAvatar, typeof i10.MatListItemIcon, typeof i9.MatListSubheaderCssMatStyler, typeof i11.MatDividerModule, typeof i10.MatListItemLine, typeof i10.MatListItemTitle, typeof i10.MatListItemMeta]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatListModule, never, [typeof i1.ObserversModule, typeof i2.MatCommonModule, typeof i2.MatRippleModule, typeof i2.MatPseudoCheckboxModule, typeof i3.MatList, typeof i4.MatActionList, typeof i5.MatNavList, typeof i6.MatSelectionList, typeof i3.MatListItem, typeof i7.MatListOption, typeof i8.MatListSubheaderCssMatStyler, typeof i9.MatListItemAvatar, typeof i9.MatListItemIcon, typeof i9.MatListItemLine, typeof i9.MatListItemTitle, typeof i9.MatListItemMeta], [typeof i3.MatList, typeof i4.MatActionList, typeof i5.MatNavList, typeof i6.MatSelectionList, typeof i3.MatListItem, typeof i7.MatListOption, typeof i9.MatListItemAvatar, typeof i9.MatListItemIcon, typeof i8.MatListSubheaderCssMatStyler, typeof i10.MatDividerModule, typeof i9.MatListItemLine, typeof i9.MatListItemTitle, typeof i9.MatListItemMeta]>;
 }
 
 // @public (undocumented)
diff --git a/tools/public_api_guard/material/menu.md b/tools/public_api_guard/material/menu.md
index d52575110cd7..9bc9954d6531 100644
--- a/tools/public_api_guard/material/menu.md
+++ b/tools/public_api_guard/material/menu.md
@@ -6,17 +6,15 @@
 
 import { AfterContentInit } from '@angular/core';
 import { AfterViewInit } from '@angular/core';
-import { AnimationEvent as AnimationEvent_2 } from '@angular/animations';
 import { AnimationTriggerMetadata } from '@angular/animations';
 import { Direction } from '@angular/cdk/bidi';
 import { EventEmitter } from '@angular/core';
 import { FocusableOption } from '@angular/cdk/a11y';
 import { FocusOrigin } from '@angular/cdk/a11y';
 import * as i0 from '@angular/core';
-import * as i1 from '@angular/common';
-import * as i2 from '@angular/material/core';
-import * as i3 from '@angular/cdk/overlay';
-import * as i8 from '@angular/cdk/scrolling';
+import * as i1 from '@angular/material/core';
+import * as i2 from '@angular/cdk/overlay';
+import * as i7 from '@angular/cdk/scrolling';
 import { InjectionToken } from '@angular/core';
 import { Observable } from 'rxjs';
 import { OnDestroy } from '@angular/core';
@@ -55,7 +53,8 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
     // (undocumented)
     addItem(_item: MatMenuItem): void;
     _allItems: QueryList<MatMenuItem>;
-    readonly _animationDone: Subject<AnimationEvent_2>;
+    readonly _animationDone: Subject<"void" | "enter">;
+    protected _animationsDisabled: boolean;
     ariaDescribedby: string;
     ariaLabel: string;
     ariaLabelledby: string;
@@ -89,9 +88,9 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
     ngOnDestroy(): void;
     // (undocumented)
     ngOnInit(): void;
-    _onAnimationDone(event: AnimationEvent_2): void;
+    protected _onAnimationDone(state: string): void;
     // (undocumented)
-    _onAnimationStart(event: AnimationEvent_2): void;
+    protected _onAnimationStart(state: string): void;
     overlapTrigger: boolean;
     overlayPanelClass: string | string[];
     _panelAnimationState: 'void' | 'enter';
@@ -102,10 +101,11 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
     // @deprecated
     removeItem(_item: MatMenuItem): void;
     resetActiveItem(): void;
-    _resetAnimation(): void;
-    setElevation(depth: number): void;
+    // @deprecated (undocumented)
+    setElevation(_depth: number): void;
+    // (undocumented)
+    _setIsOpen(isOpen: boolean): void;
     setPositionClasses(posX?: MenuPositionX, posY?: MenuPositionY): void;
-    _startAnimation(): void;
     templateRef: TemplateRef<any>;
     get xPosition(): MenuPositionX;
     set xPosition(value: MenuPositionX);
@@ -117,7 +117,7 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
     static ɵfac: i0.ɵɵFactoryDeclaration<MatMenu, never>;
 }
 
-// @public
+// @public @deprecated
 export const matMenuAnimations: {
     readonly transformMenu: AnimationTriggerMetadata;
     readonly fadeInItems: AnimationTriggerMetadata;
@@ -192,7 +192,7 @@ export class MatMenuModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatMenuModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatMenuModule, never, [typeof i1.CommonModule, typeof i2.MatRippleModule, typeof i2.MatCommonModule, typeof i3.OverlayModule, typeof i4.MatMenu, typeof i5.MatMenuItem, typeof i6.MatMenuContent, typeof i7.MatMenuTrigger], [typeof i8.CdkScrollableModule, typeof i4.MatMenu, typeof i2.MatCommonModule, typeof i5.MatMenuItem, typeof i6.MatMenuContent, typeof i7.MatMenuTrigger]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatMenuModule, never, [typeof i1.MatRippleModule, typeof i1.MatCommonModule, typeof i2.OverlayModule, typeof i3.MatMenu, typeof i4.MatMenuItem, typeof i5.MatMenuContent, typeof i6.MatMenuTrigger], [typeof i7.CdkScrollableModule, typeof i3.MatMenu, typeof i1.MatCommonModule, typeof i4.MatMenuItem, typeof i5.MatMenuContent, typeof i6.MatMenuTrigger]>;
 }
 
 // @public
@@ -223,7 +223,7 @@ export interface MatMenuPanel<T = any> {
     removeItem?: (item: T) => void;
     // (undocumented)
     resetActiveItem: () => void;
-    // (undocumented)
+    // @deprecated (undocumented)
     setElevation?(depth: number): void;
     // (undocumented)
     setPositionClasses?: (x: MenuPositionX, y: MenuPositionY) => void;
diff --git a/tools/public_api_guard/material/paginator.md b/tools/public_api_guard/material/paginator.md
index 7fb1f2751433..078b87634a49 100644
--- a/tools/public_api_guard/material/paginator.md
+++ b/tools/public_api_guard/material/paginator.md
@@ -4,7 +4,6 @@
 
 ```ts
 
-import { ChangeDetectorRef } from '@angular/core';
 import { EventEmitter } from '@angular/core';
 import * as i0 from '@angular/core';
 import * as i1 from '@angular/material/button';
@@ -34,7 +33,8 @@ export function MAT_PAGINATOR_INTL_PROVIDER_FACTORY(parentIntl: MatPaginatorIntl
 
 // @public
 export class MatPaginator implements OnInit, OnDestroy {
-    constructor(_intl: MatPaginatorIntl, _changeDetectorRef: ChangeDetectorRef, defaults?: MatPaginatorDefaultOptions);
+    constructor(...args: unknown[]);
+    protected _buttonClicked(targetIndex: number, isDisabled: boolean): void;
     _changePageSize(pageSize: number): void;
     color: ThemePalette;
     disabled: boolean;
@@ -84,7 +84,7 @@ export class MatPaginator implements OnInit, OnDestroy {
     // (undocumented)
     static ɵcmp: i0.ɵɵComponentDeclaration<MatPaginator, "mat-paginator", ["matPaginator"], { "color": { "alias": "color"; "required": false; }; "pageIndex": { "alias": "pageIndex"; "required": false; }; "length": { "alias": "length"; "required": false; }; "pageSize": { "alias": "pageSize"; "required": false; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; }; "hidePageSize": { "alias": "hidePageSize"; "required": false; }; "showFirstLastButtons": { "alias": "showFirstLastButtons"; "required": false; }; "selectConfig": { "alias": "selectConfig"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "page": "page"; }, never, never, true, never>;
     // (undocumented)
-    static ɵfac: i0.ɵɵFactoryDeclaration<MatPaginator, [null, null, { optional: true; }]>;
+    static ɵfac: i0.ɵɵFactoryDeclaration<MatPaginator, never>;
 }
 
 // @public
diff --git a/tools/public_api_guard/material/progress-spinner.md b/tools/public_api_guard/material/progress-spinner.md
index bae5cac27552..f401ed839ddb 100644
--- a/tools/public_api_guard/material/progress-spinner.md
+++ b/tools/public_api_guard/material/progress-spinner.md
@@ -6,8 +6,7 @@
 
 import { ElementRef } from '@angular/core';
 import * as i0 from '@angular/core';
-import * as i1 from '@angular/common';
-import * as i3 from '@angular/material/core';
+import * as i2 from '@angular/material/core';
 import { InjectionToken } from '@angular/core';
 import { ThemePalette } from '@angular/material/core';
 
@@ -65,7 +64,7 @@ export class MatProgressSpinnerModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatProgressSpinnerModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatProgressSpinnerModule, never, [typeof i1.CommonModule, typeof i2.MatProgressSpinner, typeof i2.MatProgressSpinner], [typeof i2.MatProgressSpinner, typeof i2.MatProgressSpinner, typeof i3.MatCommonModule]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatProgressSpinnerModule, never, [typeof i1.MatProgressSpinner, typeof i1.MatProgressSpinner], [typeof i1.MatProgressSpinner, typeof i1.MatProgressSpinner, typeof i2.MatCommonModule]>;
 }
 
 // @public @deprecated (undocumented)
diff --git a/tools/public_api_guard/material/radio.md b/tools/public_api_guard/material/radio.md
index 5ef2f429d2b0..000afc2ad4f4 100644
--- a/tools/public_api_guard/material/radio.md
+++ b/tools/public_api_guard/material/radio.md
@@ -13,7 +13,6 @@ import { EventEmitter } from '@angular/core';
 import { FocusOrigin } from '@angular/cdk/a11y';
 import * as i0 from '@angular/core';
 import * as i1 from '@angular/material/core';
-import * as i2 from '@angular/common';
 import { InjectionToken } from '@angular/core';
 import { OnDestroy } from '@angular/core';
 import { OnInit } from '@angular/core';
@@ -166,7 +165,7 @@ export class MatRadioModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatRadioModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatRadioModule, never, [typeof i1.MatCommonModule, typeof i2.CommonModule, typeof i1.MatRippleModule, typeof i3.MatRadioGroup, typeof i3.MatRadioButton], [typeof i1.MatCommonModule, typeof i3.MatRadioGroup, typeof i3.MatRadioButton]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatRadioModule, never, [typeof i1.MatCommonModule, typeof i1.MatRippleModule, typeof i2.MatRadioGroup, typeof i2.MatRadioButton], [typeof i1.MatCommonModule, typeof i2.MatRadioGroup, typeof i2.MatRadioButton]>;
 }
 
 // (No @packageDocumentation comment for this package)
diff --git a/tools/public_api_guard/material/select.md b/tools/public_api_guard/material/select.md
index b51b0132d334..a39d47dbd3d6 100644
--- a/tools/public_api_guard/material/select.md
+++ b/tools/public_api_guard/material/select.md
@@ -17,11 +17,10 @@ import { ElementRef } from '@angular/core';
 import { ErrorStateMatcher } from '@angular/material/core';
 import { EventEmitter } from '@angular/core';
 import * as i0 from '@angular/core';
-import * as i1 from '@angular/common';
-import * as i2 from '@angular/cdk/overlay';
-import * as i3 from '@angular/material/core';
-import * as i5 from '@angular/cdk/scrolling';
-import * as i6 from '@angular/material/form-field';
+import * as i1 from '@angular/cdk/overlay';
+import * as i2 from '@angular/material/core';
+import * as i4 from '@angular/cdk/scrolling';
+import * as i5 from '@angular/material/form-field';
 import { InjectionToken } from '@angular/core';
 import { MatError } from '@angular/material/form-field';
 import { MatFormField } from '@angular/material/form-field';
@@ -85,6 +84,7 @@ export class MatSelect implements AfterContentInit, OnChanges, OnDestroy, OnInit
     ariaLabel: string;
     ariaLabelledby: string;
     protected _canOpen(): boolean;
+    canSelectNullableOptions: boolean;
     // (undocumented)
     protected _changeDetectorRef: ChangeDetectorRef;
     close(): void;
@@ -122,6 +122,8 @@ export class MatSelect implements AfterContentInit, OnChanges, OnDestroy, OnInit
     get multiple(): boolean;
     set multiple(value: boolean);
     // (undocumented)
+    static ngAcceptInputType_canSelectNullableOptions: unknown;
+    // (undocumented)
     static ngAcceptInputType_disabled: unknown;
     // (undocumented)
     static ngAcceptInputType_disableOptionCentering: unknown;
@@ -210,7 +212,7 @@ export class MatSelect implements AfterContentInit, OnChanges, OnDestroy, OnInit
     protected _viewportRuler: ViewportRuler;
     writeValue(value: any): void;
     // (undocumented)
-    static ɵcmp: i0.ɵɵComponentDeclaration<MatSelect, "mat-select", ["matSelect"], { "userAriaDescribedBy": { "alias": "aria-describedby"; "required": false; }; "panelClass": { "alias": "panelClass"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "disableRipple": { "alias": "disableRipple"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "hideSingleSelectionIndicator": { "alias": "hideSingleSelectionIndicator"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "disableOptionCentering": { "alias": "disableOptionCentering"; "required": false; }; "compareWith": { "alias": "compareWith"; "required": false; }; "value": { "alias": "value"; "required": false; }; "ariaLabel": { "alias": "aria-label"; "required": false; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; }; "typeaheadDebounceInterval": { "alias": "typeaheadDebounceInterval"; "required": false; }; "sortComparator": { "alias": "sortComparator"; "required": false; }; "id": { "alias": "id"; "required": false; }; "panelWidth": { "alias": "panelWidth"; "required": false; }; }, { "openedChange": "openedChange"; "_openedStream": "opened"; "_closedStream": "closed"; "selectionChange": "selectionChange"; "valueChange": "valueChange"; }, ["customTrigger", "options", "optionGroups"], ["mat-select-trigger", "*"], true, never>;
+    static ɵcmp: i0.ɵɵComponentDeclaration<MatSelect, "mat-select", ["matSelect"], { "userAriaDescribedBy": { "alias": "aria-describedby"; "required": false; }; "panelClass": { "alias": "panelClass"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "disableRipple": { "alias": "disableRipple"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "hideSingleSelectionIndicator": { "alias": "hideSingleSelectionIndicator"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "disableOptionCentering": { "alias": "disableOptionCentering"; "required": false; }; "compareWith": { "alias": "compareWith"; "required": false; }; "value": { "alias": "value"; "required": false; }; "ariaLabel": { "alias": "aria-label"; "required": false; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; }; "typeaheadDebounceInterval": { "alias": "typeaheadDebounceInterval"; "required": false; }; "sortComparator": { "alias": "sortComparator"; "required": false; }; "id": { "alias": "id"; "required": false; }; "panelWidth": { "alias": "panelWidth"; "required": false; }; "canSelectNullableOptions": { "alias": "canSelectNullableOptions"; "required": false; }; }, { "openedChange": "openedChange"; "_openedStream": "opened"; "_closedStream": "closed"; "selectionChange": "selectionChange"; "valueChange": "valueChange"; }, ["customTrigger", "options", "optionGroups"], ["mat-select-trigger", "*"], true, never>;
     // (undocumented)
     static ɵfac: i0.ɵɵFactoryDeclaration<MatSelect, never>;
 }
@@ -232,6 +234,7 @@ export class MatSelectChange {
 
 // @public
 export interface MatSelectConfig {
+    canSelectNullableOptions?: boolean;
     disableOptionCentering?: boolean;
     hideSingleSelectionIndicator?: boolean;
     overlayPanelClass?: string | string[];
@@ -246,7 +249,7 @@ export class MatSelectModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatSelectModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatSelectModule, never, [typeof i1.CommonModule, typeof i2.OverlayModule, typeof i3.MatOptionModule, typeof i3.MatCommonModule, typeof i4.MatSelect, typeof i4.MatSelectTrigger], [typeof i5.CdkScrollableModule, typeof i6.MatFormFieldModule, typeof i4.MatSelect, typeof i4.MatSelectTrigger, typeof i3.MatOptionModule, typeof i3.MatCommonModule]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatSelectModule, never, [typeof i1.OverlayModule, typeof i2.MatOptionModule, typeof i2.MatCommonModule, typeof i3.MatSelect, typeof i3.MatSelectTrigger], [typeof i4.CdkScrollableModule, typeof i5.MatFormFieldModule, typeof i3.MatSelect, typeof i3.MatSelectTrigger, typeof i2.MatOptionModule, typeof i2.MatCommonModule]>;
 }
 
 // @public
diff --git a/tools/public_api_guard/material/sidenav.md b/tools/public_api_guard/material/sidenav.md
index 062c2ddddf52..65cae7f04938 100644
--- a/tools/public_api_guard/material/sidenav.md
+++ b/tools/public_api_guard/material/sidenav.md
@@ -4,10 +4,8 @@
 
 ```ts
 
-import { AfterContentChecked } from '@angular/core';
 import { AfterContentInit } from '@angular/core';
 import { AfterViewInit } from '@angular/core';
-import { AnimationEvent as AnimationEvent_2 } from '@angular/animations';
 import { AnimationTriggerMetadata } from '@angular/animations';
 import { BooleanInput } from '@angular/cdk/coercion';
 import { CdkScrollable } from '@angular/cdk/scrolling';
@@ -32,11 +30,10 @@ export const MAT_DRAWER_DEFAULT_AUTOSIZE: InjectionToken<boolean>;
 export function MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY(): boolean;
 
 // @public
-export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy {
+export class MatDrawer implements AfterViewInit, OnDestroy {
     constructor(...args: unknown[]);
-    readonly _animationEnd: Subject<AnimationEvent_2>;
-    readonly _animationStarted: Subject<AnimationEvent_2>;
-    _animationState: 'open-instant' | 'open' | 'void';
+    readonly _animationEnd: Subject<unknown>;
+    readonly _animationStarted: Subject<unknown>;
     get autoFocus(): AutoFocusTarget | string | boolean;
     set autoFocus(value: AutoFocusTarget | string | BooleanInput);
     close(): Promise<MatDrawerToggleResult>;
@@ -54,8 +51,6 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
     set mode(value: MatDrawerMode);
     readonly _modeChanged: Subject<void>;
     // (undocumented)
-    ngAfterContentChecked(): void;
-    // (undocumented)
     ngAfterViewInit(): void;
     // (undocumented)
     ngOnDestroy(): void;
@@ -75,7 +70,7 @@ export class MatDrawer implements AfterViewInit, AfterContentChecked, OnDestroy
     static ɵfac: i0.ɵɵFactoryDeclaration<MatDrawer, never>;
 }
 
-// @public
+// @public @deprecated
 export const matDrawerAnimations: {
     readonly transformDrawer: AnimationTriggerMetadata;
 };
@@ -120,6 +115,8 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
     open(): void;
     get scrollable(): CdkScrollable;
     get start(): MatDrawer | null;
+    // (undocumented)
+    _transitionsEnabled: boolean;
     updateContentMargins(): void;
     // (undocumented)
     _userContent: MatDrawerContent;
@@ -136,6 +133,7 @@ export class MatDrawerContent extends CdkScrollable implements AfterContentInit
     _container: MatDrawerContainer;
     // (undocumented)
     ngAfterContentInit(): void;
+    protected _shouldBeHidden(): boolean;
     // (undocumented)
     static ɵcmp: i0.ɵɵComponentDeclaration<MatDrawerContent, "mat-drawer-content", never, {}, {}, never, ["*"], true, never>;
     // (undocumented)
diff --git a/tools/public_api_guard/material/sort.md b/tools/public_api_guard/material/sort.md
index d1a5a95a515e..78eeabc38186 100644
--- a/tools/public_api_guard/material/sort.md
+++ b/tools/public_api_guard/material/sort.md
@@ -16,11 +16,12 @@ import { OnDestroy } from '@angular/core';
 import { OnInit } from '@angular/core';
 import { Optional } from '@angular/core';
 import { Subject } from 'rxjs';
+import { WritableSignal } from '@angular/core';
 
-// @public
+// @public @deprecated
 export type ArrowViewState = SortDirection | 'hint' | 'active';
 
-// @public
+// @public @deprecated
 export interface ArrowViewStateTransition {
     // (undocumented)
     fromState?: ArrowViewState;
@@ -81,7 +82,7 @@ export interface MatSortable {
     start: SortDirection;
 }
 
-// @public
+// @public @deprecated
 export const matSortAnimations: {
     readonly indicator: AnimationTriggerMetadata;
     readonly leftPointer: AnimationTriggerMetadata;
@@ -100,18 +101,14 @@ export interface MatSortDefaultOptions {
 // @public
 export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewInit {
     constructor(...args: unknown[]);
-    _arrowDirection: SortDirection;
+    // (undocumented)
+    protected _animationModule: "NoopAnimations" | "BrowserAnimations" | null;
     arrowPosition: SortHeaderArrowPosition;
     // (undocumented)
     _columnDef: MatSortHeaderColumnDef | null;
     disableClear: boolean;
     disabled: boolean;
-    _disableViewStateAnimation: boolean;
     _getAriaSortAttribute(): "none" | "ascending" | "descending";
-    _getArrowDirectionState(): string;
-    _getArrowViewState(): string;
-    // (undocumented)
-    _handleClick(): void;
     // (undocumented)
     _handleKeydown(event: KeyboardEvent): void;
     id: string;
@@ -130,18 +127,14 @@ export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewI
     ngOnDestroy(): void;
     // (undocumented)
     ngOnInit(): void;
+    protected _recentlyCleared: WritableSignal<SortDirection | null>;
     _renderArrow(): boolean;
-    _setAnimationTransitionState(viewState: ArrowViewStateTransition): void;
-    _setIndicatorHintVisible(visible: boolean): void;
-    _showIndicatorHint: boolean;
     // (undocumented)
     _sort: MatSort;
     get sortActionDescription(): string;
     set sortActionDescription(value: string);
     start: SortDirection;
     _toggleOnInteraction(): void;
-    _updateArrowDirection(): void;
-    _viewState: ArrowViewStateTransition;
     // (undocumented)
     static ɵcmp: i0.ɵɵComponentDeclaration<MatSortHeader, "[mat-sort-header]", ["matSortHeader"], { "id": { "alias": "mat-sort-header"; "required": false; }; "arrowPosition": { "alias": "arrowPosition"; "required": false; }; "start": { "alias": "start"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "sortActionDescription": { "alias": "sortActionDescription"; "required": false; }; "disableClear": { "alias": "disableClear"; "required": false; }; }, {}, never, ["*"], true, never>;
     // (undocumented)
diff --git a/tools/public_api_guard/material/stepper.md b/tools/public_api_guard/material/stepper.md
index a989ec6117cf..00c63518d5ed 100644
--- a/tools/public_api_guard/material/stepper.md
+++ b/tools/public_api_guard/material/stepper.md
@@ -21,10 +21,9 @@ import { FocusOrigin } from '@angular/cdk/a11y';
 import { FormGroupDirective } from '@angular/forms';
 import * as i0 from '@angular/core';
 import * as i1 from '@angular/material/core';
-import * as i2 from '@angular/common';
-import * as i3 from '@angular/cdk/portal';
-import * as i4 from '@angular/cdk/stepper';
-import * as i5 from '@angular/material/icon';
+import * as i2 from '@angular/cdk/portal';
+import * as i3 from '@angular/cdk/stepper';
+import * as i4 from '@angular/material/icon';
 import { NgForm } from '@angular/forms';
 import { OnDestroy } from '@angular/core';
 import { Optional } from '@angular/core';
@@ -189,7 +188,7 @@ export class MatStepperModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatStepperModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatStepperModule, never, [typeof i1.MatCommonModule, typeof i2.CommonModule, typeof i3.PortalModule, typeof i4.CdkStepperModule, typeof i5.MatIconModule, typeof i1.MatRippleModule, typeof i6.MatStep, typeof i7.MatStepLabel, typeof i6.MatStepper, typeof i8.MatStepperNext, typeof i8.MatStepperPrevious, typeof i9.MatStepHeader, typeof i10.MatStepperIcon, typeof i11.MatStepContent], [typeof i1.MatCommonModule, typeof i6.MatStep, typeof i7.MatStepLabel, typeof i6.MatStepper, typeof i8.MatStepperNext, typeof i8.MatStepperPrevious, typeof i9.MatStepHeader, typeof i10.MatStepperIcon, typeof i11.MatStepContent]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatStepperModule, never, [typeof i1.MatCommonModule, typeof i2.PortalModule, typeof i3.CdkStepperModule, typeof i4.MatIconModule, typeof i1.MatRippleModule, typeof i5.MatStep, typeof i6.MatStepLabel, typeof i5.MatStepper, typeof i7.MatStepperNext, typeof i7.MatStepperPrevious, typeof i8.MatStepHeader, typeof i9.MatStepperIcon, typeof i10.MatStepContent], [typeof i1.MatCommonModule, typeof i5.MatStep, typeof i6.MatStepLabel, typeof i5.MatStepper, typeof i7.MatStepperNext, typeof i7.MatStepperPrevious, typeof i8.MatStepHeader, typeof i9.MatStepperIcon, typeof i10.MatStepContent]>;
 }
 
 // @public
diff --git a/tools/public_api_guard/material/tabs.md b/tools/public_api_guard/material/tabs.md
index 258c23ead76f..65e4cab22af7 100644
--- a/tools/public_api_guard/material/tabs.md
+++ b/tools/public_api_guard/material/tabs.md
@@ -442,7 +442,7 @@ export class MatTabLink extends InkBarItem implements AfterViewInit, OnDestroy,
 }
 
 // @public
-export class MatTabNav extends MatPaginatedTabHeader implements AfterContentChecked, AfterContentInit, OnDestroy, AfterViewInit {
+export class MatTabNav extends MatPaginatedTabHeader implements AfterContentInit, AfterViewInit {
     constructor(...args: unknown[]);
     // (undocumented)
     get animationDuration(): string;
diff --git a/tools/public_api_guard/material/timepicker.md b/tools/public_api_guard/material/timepicker.md
index c30900da874a..528d217bd53f 100644
--- a/tools/public_api_guard/material/timepicker.md
+++ b/tools/public_api_guard/material/timepicker.md
@@ -33,6 +33,7 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
     readonly ariaLabelledby: InputSignal<string | null>;
     close(): void;
     readonly closed: OutputEmitterRef<void>;
+    readonly disabled: Signal<boolean>;
     readonly disableRipple: InputSignalWithTransform<boolean, unknown>;
     protected _getAriaLabelledby(): string | null;
     readonly interval: InputSignalWithTransform<number | null, number | string | null>;
@@ -71,7 +72,7 @@ export class MatTimepickerInput<D> implements ControlValueAccessor, Validator, O
     protected readonly _ariaControls: Signal<string | null>;
     protected readonly _ariaExpanded: Signal<string>;
     readonly disabled: Signal<boolean>;
-    protected readonly disabledInput: InputSignalWithTransform<boolean, unknown>;
+    readonly disabledInput: InputSignalWithTransform<boolean, unknown>;
     focus(): void;
     _getLabelId(): string | null;
     getOverlayOrigin(): ElementRef<HTMLElement>;
@@ -125,6 +126,8 @@ export class MatTimepickerToggle<D> {
     readonly ariaLabel: InputSignal<string | undefined>;
     readonly disabled: InputSignalWithTransform<boolean, unknown>;
     readonly disableRipple: InputSignalWithTransform<boolean, unknown>;
+    // (undocumented)
+    protected _isDisabled: Signal<boolean>;
     protected _open(event: Event): void;
     readonly tabIndex: InputSignal<number | null>;
     readonly timepicker: InputSignal<MatTimepicker<D>>;
diff --git a/tools/public_api_guard/material/tooltip.md b/tools/public_api_guard/material/tooltip.md
index 1c83fa4db149..5ab73d9cf192 100644
--- a/tools/public_api_guard/material/tooltip.md
+++ b/tools/public_api_guard/material/tooltip.md
@@ -12,10 +12,9 @@ import { Directionality } from '@angular/cdk/bidi';
 import { ElementRef } from '@angular/core';
 import * as i0 from '@angular/core';
 import * as i1 from '@angular/cdk/a11y';
-import * as i2 from '@angular/common';
-import * as i3 from '@angular/cdk/overlay';
-import * as i4 from '@angular/material/core';
-import * as i6 from '@angular/cdk/scrolling';
+import * as i2 from '@angular/cdk/overlay';
+import * as i3 from '@angular/material/core';
+import * as i5 from '@angular/cdk/scrolling';
 import { InjectionToken } from '@angular/core';
 import { NumberInput } from '@angular/cdk/coercion';
 import { Observable } from 'rxjs';
@@ -104,7 +103,7 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
     static ɵfac: i0.ɵɵFactoryDeclaration<MatTooltip, never>;
 }
 
-// @public
+// @public @deprecated
 export const matTooltipAnimations: {
     readonly tooltipState: AnimationTriggerMetadata;
 };
@@ -129,7 +128,7 @@ export class MatTooltipModule {
     // (undocumented)
     static ɵinj: i0.ɵɵInjectorDeclaration<MatTooltipModule>;
     // (undocumented)
-    static ɵmod: i0.ɵɵNgModuleDeclaration<MatTooltipModule, never, [typeof i1.A11yModule, typeof i2.CommonModule, typeof i3.OverlayModule, typeof i4.MatCommonModule, typeof i5.MatTooltip, typeof i5.TooltipComponent], [typeof i5.MatTooltip, typeof i5.TooltipComponent, typeof i4.MatCommonModule, typeof i6.CdkScrollableModule]>;
+    static ɵmod: i0.ɵɵNgModuleDeclaration<MatTooltipModule, never, [typeof i1.A11yModule, typeof i2.OverlayModule, typeof i3.MatCommonModule, typeof i4.MatTooltip, typeof i4.TooltipComponent], [typeof i4.MatTooltip, typeof i4.TooltipComponent, typeof i3.MatCommonModule, typeof i5.CdkScrollableModule]>;
 }
 
 // @public
diff --git a/tools/public_api_guard/youtube-player/youtube-player.md b/tools/public_api_guard/youtube-player/youtube-player.md
index fb8690f358f4..236abe369746 100644
--- a/tools/public_api_guard/youtube-player/youtube-player.md
+++ b/tools/public_api_guard/youtube-player/youtube-player.md
@@ -24,12 +24,10 @@ export const YOUTUBE_PLAYER_CONFIG: InjectionToken<YouTubePlayerConfig>;
 // @public
 export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
     constructor(...args: unknown[]);
-    // (undocumented)
     readonly apiChange: Observable<YT.PlayerEvent>;
     disableCookies: boolean;
     disablePlaceholder: boolean;
     endSeconds: number | undefined;
-    // (undocumented)
     readonly error: Observable<YT.OnErrorEvent>;
     getAvailablePlaybackRates(): number[];
     getAvailableQualityLevels(): YT.SuggestedVideoQuality[];
@@ -77,9 +75,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
     pauseVideo(): void;
     placeholderButtonLabel: string;
     placeholderImageQuality: PlaceholderImageQuality;
-    // (undocumented)
     readonly playbackQualityChange: Observable<YT.OnPlaybackQualityChangeEvent>;
-    // (undocumented)
     readonly playbackRateChange: Observable<YT.OnPlaybackRateChangeEvent>;
     playerVars: YT.PlayerVars | undefined;
     playVideo(): void;
@@ -90,7 +86,6 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
     protected _shouldShowPlaceholder(): boolean;
     showBeforeIframeApiLoads: boolean;
     startSeconds: number | undefined;
-    // (undocumented)
     readonly stateChange: Observable<YT.OnStateChangeEvent>;
     stopVideo(): void;
     suggestedQuality: YT.SuggestedVideoQuality | undefined;
diff --git a/yarn.lock b/yarn.lock
index 5c34449c83f4..4e36a09852bb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -18,35 +18,35 @@
     "@angular-devkit/core" "18.1.0-next.0"
     rxjs "7.8.1"
 
-"@angular-devkit/architect@0.1900.0-next.11":
-  version "0.1900.0-next.11"
-  resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1900.0-next.11.tgz#83fb66ef9f2170a4a29f298727ee17e5e34815b0"
-  integrity sha512-ZlE2dmn2JHlfMDmxKPoTllYbHerCXYPWqr0UcxejWcIf+D+zFuTVvT2bfPEk2/J6ce8vKauzehWqIeS3aGxYIA==
+"@angular-devkit/architect@0.1900.0":
+  version "0.1900.0"
+  resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1900.0.tgz#50598a36951a95d1a146424f6d0584831d187dca"
+  integrity sha512-oC2CyKf9olKvthEwp2wmkKw+H9NhpnK9cWYHvajWeCRJ8A4DLaKwfMuZ9lioi92QPourrJzoikgp7C6m2AuuZQ==
   dependencies:
-    "@angular-devkit/core" "19.0.0-next.11"
+    "@angular-devkit/core" "19.0.0"
     rxjs "7.8.1"
 
-"@angular-devkit/build-angular@^19.0.0-next.10":
-  version "19.0.0-next.11"
-  resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-19.0.0-next.11.tgz#b61af638071e80e835bcdd121a60abdc1153fa35"
-  integrity sha512-NWW25/ZX7PJ0jb5bqo0QHJcWPwv/nUoOalgJuSb+0jic87fXRdaWSox6InpOsJvJarQw/XuElwMxgJKTHcPn4Q==
+"@angular-devkit/build-angular@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-19.0.0.tgz#ba7815ce1fbd134d9140fb6fb5dca6b33c73bf79"
+  integrity sha512-Q4owTwm4bLK5qYHvPehx1/55O0vWRShDGsoHOYgm8mMLc++hr7xWpF8HptVG7AP9O8Qq95Cpz9+N4iMqyWlyUw==
   dependencies:
     "@ampproject/remapping" "2.3.0"
-    "@angular-devkit/architect" "0.1900.0-next.11"
-    "@angular-devkit/build-webpack" "0.1900.0-next.11"
-    "@angular-devkit/core" "19.0.0-next.11"
-    "@angular/build" "19.0.0-next.11"
-    "@babel/core" "7.25.8"
-    "@babel/generator" "7.25.7"
-    "@babel/helper-annotate-as-pure" "7.25.7"
+    "@angular-devkit/architect" "0.1900.0"
+    "@angular-devkit/build-webpack" "0.1900.0"
+    "@angular-devkit/core" "19.0.0"
+    "@angular/build" "19.0.0"
+    "@babel/core" "7.26.0"
+    "@babel/generator" "7.26.2"
+    "@babel/helper-annotate-as-pure" "7.25.9"
     "@babel/helper-split-export-declaration" "7.24.7"
-    "@babel/plugin-transform-async-generator-functions" "7.25.8"
-    "@babel/plugin-transform-async-to-generator" "7.25.7"
-    "@babel/plugin-transform-runtime" "7.25.7"
-    "@babel/preset-env" "7.25.8"
-    "@babel/runtime" "7.25.7"
-    "@discoveryjs/json-ext" "0.6.1"
-    "@ngtools/webpack" "19.0.0-next.11"
+    "@babel/plugin-transform-async-generator-functions" "7.25.9"
+    "@babel/plugin-transform-async-to-generator" "7.25.9"
+    "@babel/plugin-transform-runtime" "7.25.9"
+    "@babel/preset-env" "7.26.0"
+    "@babel/runtime" "7.26.0"
+    "@discoveryjs/json-ext" "0.6.3"
+    "@ngtools/webpack" "19.0.0"
     "@vitejs/plugin-basic-ssl" "1.1.0"
     ansi-colors "4.1.3"
     autoprefixer "10.4.20"
@@ -64,24 +64,24 @@
     less-loader "12.2.0"
     license-webpack-plugin "4.0.2"
     loader-utils "3.3.1"
-    mini-css-extract-plugin "2.9.1"
+    mini-css-extract-plugin "2.9.2"
     open "10.1.0"
     ora "5.4.1"
     picomatch "4.0.2"
     piscina "4.7.0"
-    postcss "8.4.47"
+    postcss "8.4.49"
     postcss-loader "8.1.1"
     resolve-url-loader "5.0.0"
     rxjs "7.8.1"
-    sass "1.79.5"
-    sass-loader "16.0.2"
+    sass "1.80.7"
+    sass-loader "16.0.3"
     semver "7.6.3"
     source-map-loader "5.0.0"
     source-map-support "0.5.21"
-    terser "5.34.1"
+    terser "5.36.0"
     tree-kill "1.2.2"
-    tslib "2.7.0"
-    webpack "5.95.0"
+    tslib "2.8.1"
+    webpack "5.96.1"
     webpack-dev-middleware "7.4.2"
     webpack-dev-server "5.1.0"
     webpack-merge "6.0.1"
@@ -89,12 +89,12 @@
   optionalDependencies:
     esbuild "0.24.0"
 
-"@angular-devkit/build-webpack@0.1900.0-next.11":
-  version "0.1900.0-next.11"
-  resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1900.0-next.11.tgz#6b0336c22a1304a9b6a733edf97dcb543137fdcd"
-  integrity sha512-gxSxxqgwvHV5EWmuktJ7f/etV69bal0P4Q74tNZerB3e6leHxestZCXB6P6EouNPLp0def+EtAHZFAsfmHQe6g==
+"@angular-devkit/build-webpack@0.1900.0":
+  version "0.1900.0"
+  resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1900.0.tgz#716350ad892c21bce5e5430bb4296738947c33f2"
+  integrity sha512-mpsjpkp+SBd/16zmRTNDUiTXvcuMObGpcssOGqjf9MhaeSECYpU2J1MyXO+uXqnQ5ECAc/UK954Lv6bWwbusEw==
   dependencies:
-    "@angular-devkit/architect" "0.1900.0-next.11"
+    "@angular-devkit/architect" "0.1900.0"
     rxjs "7.8.1"
 
 "@angular-devkit/core@18.1.0-next.0":
@@ -109,10 +109,10 @@
     rxjs "7.8.1"
     source-map "0.7.4"
 
-"@angular-devkit/core@19.0.0-next.11", "@angular-devkit/core@^19.0.0-next.10":
-  version "19.0.0-next.11"
-  resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-19.0.0-next.11.tgz#dbcb8e0fe1e3606207c2dfd481e472a921779bc9"
-  integrity sha512-/u8b3d+rwKRZiXR00b9UKSI8OEHH23hy0PHm4/Myl1+2JLIZYGJhIHvcAZ2vE7xvTbpNP2IlpwVae26OUJ4W6Q==
+"@angular-devkit/core@19.0.0", "@angular-devkit/core@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-19.0.0.tgz#15943480916618aec415ec1c056806dff2e473ef"
+  integrity sha512-/EJQOKVFb9vsFbPR+57C7fJHFVr7le9Ru6aormIKw24xyZZHtt5X4rwdeN7l6Zkv8F0cJ2EoTSiQoY17090DLQ==
   dependencies:
     ajv "8.17.1"
     ajv-formats "3.0.1"
@@ -121,27 +121,27 @@
     rxjs "7.8.1"
     source-map "0.7.4"
 
-"@angular-devkit/schematics@19.0.0-next.11", "@angular-devkit/schematics@^19.0.0-next.10":
-  version "19.0.0-next.11"
-  resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-19.0.0-next.11.tgz#cf64089096164665023e229770706c06442bff98"
-  integrity sha512-YPixxsxwlI06f8Yt/AIYdIW0Pkaz/SRHGv48r6xIkU+tPABtT9qxw/xkyVgf50+TGKMcu+sBPtfcNLpi1zv4tw==
+"@angular-devkit/schematics@19.0.0", "@angular-devkit/schematics@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-19.0.0.tgz#e1d3e216ef027394a9e4d3eeb8a63cc67d24bd85"
+  integrity sha512-90pGZtpZgjDk1UgRBatfeqYP6qUZL9fLh+8zIpavOr2ey5bW2lADO7mS2Qrc7U1SmGqnxQXQQ7uIS+50gYm0tQ==
   dependencies:
-    "@angular-devkit/core" "19.0.0-next.11"
+    "@angular-devkit/core" "19.0.0"
     jsonc-parser "3.3.1"
     magic-string "0.30.12"
     ora "5.4.1"
     rxjs "7.8.1"
 
-"@angular/animations@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-19.0.0-next.10.tgz#19fd4b232d3f7bb14987fb04abe883b986609d31"
-  integrity sha512-wAJttvZxty7mgigBdlXwijrWu6aD8j9BPZiXv0qgUY1mA/SMU/yPGk7hv3aIyynbNWN9uBSowGxbqMGcExBTzQ==
+"@angular/animations@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-19.0.0.tgz#7cd4f5e6bf15ec834738f3807e77900ac8ac7d42"
+  integrity sha512-+uZTvEXjYh8PZKB4ijk8uuH1K+Tz/A67mUlltFv9pYKtnmbZAeS/PI66g/7pigRYDvEgid1fvlAANeBShAiPZQ==
   dependencies:
     tslib "^2.3.0"
 
-"@angular/bazel@https://github.com/angular/bazel-builds.git#9e6140d1eef8ddf7113d00738f603e9cc3c310f1":
-  version "19.0.0-next.1"
-  resolved "https://github.com/angular/bazel-builds.git#9e6140d1eef8ddf7113d00738f603e9cc3c310f1"
+"@angular/bazel@https://github.com/angular/bazel-builds.git#d9a8ea4f9e62cb475eff89519426a38631b2704d":
+  version "19.1.0-next.0"
+  resolved "https://github.com/angular/bazel-builds.git#d9a8ea4f9e62cb475eff89519426a38631b2704d"
   dependencies:
     "@microsoft/api-extractor" "^7.24.2"
     magic-string "^0.30.0"
@@ -231,21 +231,21 @@
     vite "5.2.12"
     watchpack "2.4.1"
 
-"@angular/build@19.0.0-next.11", "@angular/build@^19.0.0-next.10":
-  version "19.0.0-next.11"
-  resolved "https://registry.yarnpkg.com/@angular/build/-/build-19.0.0-next.11.tgz#6f37edeea02c329455dff948d4dd0dafda2a5885"
-  integrity sha512-bfHptkpx8mrg+iZptT68cl1BI98YXGlr9tQIndEL0VPhG1Xg8dM7/wc+B3zKxlCNoCYCxq4MFrTk4d+yPiIKhg==
+"@angular/build@19.0.0", "@angular/build@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/build/-/build-19.0.0.tgz#d3ce049930646748659e9c2b8a2dbe3808d01590"
+  integrity sha512-OLyUwAVCSqW589l19g19aP2O1NpBMRPsqKmYLaTYvYSIcZkNRJPxOcsCIDGB3FUQUEjpouYtzPA3RtBuJWsCwQ==
   dependencies:
     "@ampproject/remapping" "2.3.0"
-    "@angular-devkit/architect" "0.1900.0-next.11"
-    "@babel/core" "7.25.8"
-    "@babel/helper-annotate-as-pure" "7.25.7"
+    "@angular-devkit/architect" "0.1900.0"
+    "@babel/core" "7.26.0"
+    "@babel/helper-annotate-as-pure" "7.25.9"
     "@babel/helper-split-export-declaration" "7.24.7"
-    "@babel/plugin-syntax-import-attributes" "7.25.7"
-    "@inquirer/confirm" "5.0.0"
+    "@babel/plugin-syntax-import-attributes" "7.26.0"
+    "@inquirer/confirm" "5.0.2"
     "@vitejs/plugin-basic-ssl" "1.1.0"
+    beasties "0.1.0"
     browserslist "^4.23.0"
-    critters "0.0.25"
     esbuild "0.24.0"
     fast-glob "3.3.2"
     https-proxy-agent "7.0.5"
@@ -256,50 +256,50 @@
     parse5-html-rewriting-stream "7.0.0"
     picomatch "4.0.2"
     piscina "4.7.0"
-    rollup "4.24.0"
-    sass "1.79.5"
+    rollup "4.26.0"
+    sass "1.80.7"
     semver "7.6.3"
-    vite "5.4.9"
+    vite "5.4.11"
     watchpack "2.4.2"
   optionalDependencies:
-    lmdb "3.1.3"
-
-"@angular/cli@^19.0.0-next.10":
-  version "19.0.0-next.11"
-  resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-19.0.0-next.11.tgz#22e20b9e394d156a777075ef8fe6f454e0081a87"
-  integrity sha512-oZRNKj0JDu2mGykWKcZWvomrsAQS201s1FdfGBxyelmGIeexNsXgG3MaF/9lybAEfdLjovmtClzF6KqLxOWNyQ==
-  dependencies:
-    "@angular-devkit/architect" "0.1900.0-next.11"
-    "@angular-devkit/core" "19.0.0-next.11"
-    "@angular-devkit/schematics" "19.0.0-next.11"
-    "@inquirer/prompts" "7.0.0"
-    "@listr2/prompt-adapter-inquirer" "2.0.17"
-    "@schematics/angular" "19.0.0-next.11"
+    lmdb "3.1.5"
+
+"@angular/cli@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-19.0.0.tgz#68941696e9eb8e0eb80147ad0a3d2b6c0ff4798b"
+  integrity sha512-7FTNkMtTuaXp4CCWZlRIwFZtnkDJg+YjqAuloDNGhIXDjDsb9gWihepWpWXSMBTg4XI1OdsT+oYt38Z0YMck0A==
+  dependencies:
+    "@angular-devkit/architect" "0.1900.0"
+    "@angular-devkit/core" "19.0.0"
+    "@angular-devkit/schematics" "19.0.0"
+    "@inquirer/prompts" "7.1.0"
+    "@listr2/prompt-adapter-inquirer" "2.0.18"
+    "@schematics/angular" "19.0.0"
     "@yarnpkg/lockfile" "1.1.0"
     ini "5.0.0"
     jsonc-parser "3.3.1"
     listr2 "8.2.5"
     npm-package-arg "12.0.0"
     npm-pick-manifest "10.0.0"
-    pacote "19.0.1"
+    pacote "20.0.0"
     resolve "1.22.8"
     semver "7.6.3"
     symbol-observable "4.0.0"
     yargs "17.7.2"
 
-"@angular/common@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/common/-/common-19.0.0-next.10.tgz#12906af61de91e5efe802bba8a5136af61ee1666"
-  integrity sha512-/S1xEasophqxBS+Lb99ZLAfW0bm/NaT6of6WwJF4aTTZnvRQJSv1cmMobqEUzVzs3kXesA0yuDuh0hB9omJFtg==
+"@angular/common@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/common/-/common-19.0.0.tgz#d1ef6cb9ef91fb52d88e640696610d62f63f4698"
+  integrity sha512-kb2iS26GZS0vyR3emAQbIiQifnK5M5vnbclEHni+pApDEU5V9FufbdRP3vCxs28UHZvAZKB0LrxkTrnT6T+z5g==
   dependencies:
     tslib "^2.3.0"
 
-"@angular/compiler-cli@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-19.0.0-next.10.tgz#e123c204a62e9231e3faceb0fbde8c2cd8e92f42"
-  integrity sha512-bRezB/iIT/KUI1Foj0n93p/d9/JDWzIfJZls9YSKBkp8IYgNEEf8ofaeUDp0ksHh577AQJBNe6pCCxluGkgWCg==
+"@angular/compiler-cli@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-19.0.0.tgz#b06bae640841cf8150e55b9ad0a5d83af2b317bb"
+  integrity sha512-2PxpsIeppoDLAx7A6i0GE10WjC+Fkz8tTQioa7r4y/+eYnniEjJFIQM/8lbkOnRVcuYoeXoNyYWr3fEQAyO4LA==
   dependencies:
-    "@babel/core" "7.25.2"
+    "@babel/core" "7.26.0"
     "@jridgewell/sourcemap-codec" "^1.4.14"
     chokidar "^4.0.0"
     convert-source-map "^1.5.1"
@@ -308,10 +308,10 @@
     tslib "^2.3.0"
     yargs "^17.2.1"
 
-"@angular/compiler@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-19.0.0-next.10.tgz#522c9dc00013beea5c54732b6724e08eaf5f7158"
-  integrity sha512-p6lZMnrQCSQopViCzGFEWQpPeCgtxsLVwyiYzg/bUSlL9YkNWUES2inaK3CnmqegsnUCw+UP2sSvIKddMqapww==
+"@angular/compiler@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-19.0.0.tgz#6a9d03b639d9c2e89b31581e7976e99bae1cad27"
+  integrity sha512-Uw2Yy25pdqfzKsS9WofnIq1zvknlVYyy03LYO7NMKHlFWiy8q8SIXN7WKPFhiHlOfyACXipp4eZb9m3+IbOfSA==
   dependencies:
     tslib "^2.3.0"
 
@@ -322,26 +322,26 @@
   dependencies:
     tslib "^2.3.0"
 
-"@angular/core@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/core/-/core-19.0.0-next.10.tgz#e61e28d12741bd81fb75ccd1efd1b3840f38b341"
-  integrity sha512-//emUO2j82yEXszfn4ml6w8zaDQkd5vHbejmyPAiL5maTDkRNlsUP4Q5DEloxLBzMksnhJkBLz1Q1f4pxXWnIA==
+"@angular/core@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/core/-/core-19.0.0.tgz#ba977b5b436b89acb31d204b26622c533334139c"
+  integrity sha512-aNG2kd30BOM/zf0jC+aEVG8OA27IwqCki9EkmyRNYnaP2O5Mj1n7JpCyZGI+0LrWTJ2UUCfRNZiZdZwmNThr1Q==
   dependencies:
     tslib "^2.3.0"
 
-"@angular/forms@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-19.0.0-next.10.tgz#026c09f4c0616df126a043caf1d8c01bc928966c"
-  integrity sha512-4s/L2ywdXnbzQFDRlUgJoRJ6jyBZ/J4G/y+sBINCZfmpKNhg96mzh0HIPtHPKyK9np0qPISvEVPJsuz8CaaDIw==
+"@angular/forms@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-19.0.0.tgz#ac3539eda20d9138b1241ea108edde760196dfa5"
+  integrity sha512-gM4bUdlIJ0uRYNwoVMbXiZt4+bZzPXzyQ7ByNIOVKEAI0PN9Jz1dR1pSeQgIoUvKQbhwsVKVUoa7Tn1hoqwvTg==
   dependencies:
     tslib "^2.3.0"
 
-"@angular/localize@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-19.0.0-next.10.tgz#c1b16d58edfbc04b577563bb29761993628f4b7b"
-  integrity sha512-YB0oFz9W3m0hcZucNCW3NFfXwF7Ey/o771EyXVHuS/n2rxPPhIzubP0FLnp0HF6oKuB8/5eLydhesaMqHiWCrw==
+"@angular/localize@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-19.0.0.tgz#c9347f9819ec9a27e56ee4fc0ae246cae42a9d46"
+  integrity sha512-n1mDFjVKjJEXycpWPyXQ5sUy83KzJTbpohsvM6Fhgk+gTUSxmj9kP6wjnKtsGCSV3tjtI62jTczKYJJotoDc9w==
   dependencies:
-    "@babel/core" "7.25.2"
+    "@babel/core" "7.26.0"
     "@types/babel__core" "7.20.5"
     fast-glob "3.3.2"
     yargs "^17.2.1"
@@ -353,32 +353,32 @@
     "@yarnpkg/lockfile" "^1.1.0"
     typescript "~4.9.0"
 
-"@angular/platform-browser-dynamic@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.0.0-next.10.tgz#a5b514128e0f65ccf6af6a213e7f3028f3128532"
-  integrity sha512-gtBXkrX3Uwb/N4rkyuKlGBYnzaZjJqoLp0w4QxoNtmlgnHGO42p/pN59E6CpUAVCMzXxsnWRQb1px92aavonBQ==
+"@angular/platform-browser-dynamic@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.0.0.tgz#37f33da14f179ac4a9dcd8b411e498614f35e59e"
+  integrity sha512-ljvycDe0etmTBDzbCFakpsItywddpKEyCZGMKRvz5TdND1N1qqXydxAF1kLzP5H7F/QOMdP4/T/T1HS+6AUpkw==
   dependencies:
     tslib "^2.3.0"
 
-"@angular/platform-browser@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-19.0.0-next.10.tgz#8ea7f2be0376f48dee99052aa2e0e99fb668ece7"
-  integrity sha512-D12EbY7Z0KHPgqsiR/AXKEpLjEiH6r5Db0RHIbEx6zm83F7b6NiRu8X412wJfz2t/43rQCpuadMDHaErby8daQ==
+"@angular/platform-browser@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-19.0.0.tgz#217935da8119438e5de51c0bd5a1d6c66f3ebe8c"
+  integrity sha512-g9Qkv+KgEmXLVeg+dw1edmWsRBspUGeJMOBf2UX1kUCw6txeco+pzCMimouB5LQYHfs6cD6oC+FwINm0HNwrhg==
   dependencies:
     tslib "^2.3.0"
 
-"@angular/platform-server@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-19.0.0-next.10.tgz#9c9cfeff4fbe92d8530c8d424afa57b178ab4b03"
-  integrity sha512-uU+mHnBiT+lM5IM4Bawu84JPn/bTsp7wMvikdaBGD3ffzsA2XtqooOTVVNbdfekZ98w9io2Ck6JCSV/TKGZYIg==
+"@angular/platform-server@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-19.0.0.tgz#03e0d83c5bf6f048308169de8fcfc9195ffa2ea7"
+  integrity sha512-eQ+mT2DvIp+tQO268WJQ5CO9nB+jcXNYqUzEfAqAhUNnpxCn3j6d8GNjx16GOVkHVBrVJvW32WPBCG4fzoi0sQ==
   dependencies:
     tslib "^2.3.0"
     xhr2 "^0.2.0"
 
-"@angular/router@^19.0.0-next.10":
-  version "19.0.0-next.10"
-  resolved "https://registry.yarnpkg.com/@angular/router/-/router-19.0.0-next.10.tgz#84eced980bd4f85052928391035d72010e55b5a8"
-  integrity sha512-L0zu+tsMqvXN52FzXHxtpV+li3zlDjYsvceDO1LHuM2e15LBYSRbGrSmXz4G7Dv4QxMxV/ISLn1oXQmlHv6nKQ==
+"@angular/router@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@angular/router/-/router-19.0.0.tgz#49eed476d74eab0ed2b7111311bd707b72bde3bd"
+  integrity sha512-uFyT8DWVLGY8k0AZjpK7iyMO/WwT4/+b09Ax0uUEbdcRxTXSOg8/U/AVzQWtxzxI80/vJE2WZMmhIJFUTYwhKA==
   dependencies:
     tslib "^2.3.0"
 
@@ -400,12 +400,13 @@
     "@babel/highlight" "^7.24.7"
     picocolors "^1.0.0"
 
-"@babel/code-frame@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7"
-  integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==
+"@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0":
+  version "7.26.2"
+  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
+  integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
   dependencies:
-    "@babel/highlight" "^7.25.7"
+    "@babel/helper-validator-identifier" "^7.25.9"
+    js-tokens "^4.0.0"
     picocolors "^1.0.0"
 
 "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.7":
@@ -413,15 +414,10 @@
   resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.7.tgz#d23bbea508c3883ba8251fb4164982c36ea577ed"
   integrity sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==
 
-"@babel/compat-data@^7.25.2":
-  version "7.25.2"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.2.tgz#e41928bd33475305c586f6acbbb7e3ade7a6f7f5"
-  integrity sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==
-
-"@babel/compat-data@^7.25.7", "@babel/compat-data@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.8.tgz#0376e83df5ab0eb0da18885c0140041f0747a402"
-  integrity sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==
+"@babel/compat-data@^7.25.9", "@babel/compat-data@^7.26.0":
+  version "7.26.2"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e"
+  integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==
 
 "@babel/core@7.24.6":
   version "7.24.6"
@@ -444,42 +440,21 @@
     json5 "^2.2.3"
     semver "^6.3.1"
 
-"@babel/core@7.25.2":
-  version "7.25.2"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.2.tgz#ed8eec275118d7613e77a352894cd12ded8eba77"
-  integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==
-  dependencies:
-    "@ampproject/remapping" "^2.2.0"
-    "@babel/code-frame" "^7.24.7"
-    "@babel/generator" "^7.25.0"
-    "@babel/helper-compilation-targets" "^7.25.2"
-    "@babel/helper-module-transforms" "^7.25.2"
-    "@babel/helpers" "^7.25.0"
-    "@babel/parser" "^7.25.0"
-    "@babel/template" "^7.25.0"
-    "@babel/traverse" "^7.25.2"
-    "@babel/types" "^7.25.2"
-    convert-source-map "^2.0.0"
-    debug "^4.1.0"
-    gensync "^1.0.0-beta.2"
-    json5 "^2.2.3"
-    semver "^6.3.1"
-
-"@babel/core@7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.8.tgz#a57137d2a51bbcffcfaeba43cb4dd33ae3e0e1c6"
-  integrity sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==
+"@babel/core@7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40"
+  integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==
   dependencies:
     "@ampproject/remapping" "^2.2.0"
-    "@babel/code-frame" "^7.25.7"
-    "@babel/generator" "^7.25.7"
-    "@babel/helper-compilation-targets" "^7.25.7"
-    "@babel/helper-module-transforms" "^7.25.7"
-    "@babel/helpers" "^7.25.7"
-    "@babel/parser" "^7.25.8"
-    "@babel/template" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
-    "@babel/types" "^7.25.8"
+    "@babel/code-frame" "^7.26.0"
+    "@babel/generator" "^7.26.0"
+    "@babel/helper-compilation-targets" "^7.25.9"
+    "@babel/helper-module-transforms" "^7.26.0"
+    "@babel/helpers" "^7.26.0"
+    "@babel/parser" "^7.26.0"
+    "@babel/template" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
+    "@babel/types" "^7.26.0"
     convert-source-map "^2.0.0"
     debug "^4.1.0"
     gensync "^1.0.0-beta.2"
@@ -507,12 +482,13 @@
     json5 "^2.2.3"
     semver "^6.3.1"
 
-"@babel/generator@7.25.7", "@babel/generator@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56"
-  integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==
+"@babel/generator@7.26.2", "@babel/generator@^7.25.9", "@babel/generator@^7.26.0":
+  version "7.26.2"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f"
+  integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==
   dependencies:
-    "@babel/types" "^7.25.7"
+    "@babel/parser" "^7.26.2"
+    "@babel/types" "^7.26.0"
     "@jridgewell/gen-mapping" "^0.3.5"
     "@jridgewell/trace-mapping" "^0.3.25"
     jsesc "^3.0.2"
@@ -527,16 +503,6 @@
     "@jridgewell/trace-mapping" "^0.3.25"
     jsesc "^2.5.1"
 
-"@babel/generator@^7.25.0":
-  version "7.25.0"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.0.tgz#f858ddfa984350bc3d3b7f125073c9af6988f18e"
-  integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==
-  dependencies:
-    "@babel/types" "^7.25.0"
-    "@jridgewell/gen-mapping" "^0.3.5"
-    "@jridgewell/trace-mapping" "^0.3.25"
-    jsesc "^2.5.1"
-
 "@babel/helper-annotate-as-pure@7.24.6":
   version "7.24.6"
   resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz#517af93abc77924f9b2514c407bbef527fb8938d"
@@ -544,12 +510,12 @@
   dependencies:
     "@babel/types" "^7.24.6"
 
-"@babel/helper-annotate-as-pure@7.25.7", "@babel/helper-annotate-as-pure@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz#63f02dbfa1f7cb75a9bdb832f300582f30bb8972"
-  integrity sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==
+"@babel/helper-annotate-as-pure@7.25.9", "@babel/helper-annotate-as-pure@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4"
+  integrity sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==
   dependencies:
-    "@babel/types" "^7.25.7"
+    "@babel/types" "^7.25.9"
 
 "@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.24.7":
   version "7.24.7"
@@ -558,13 +524,13 @@
   dependencies:
     "@babel/types" "^7.24.7"
 
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.7.tgz#d721650c1f595371e0a23ee816f1c3c488c0d622"
-  integrity sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg==
+"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz#f41752fe772a578e67286e6779a68a5a92de1ee9"
+  integrity sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==
   dependencies:
-    "@babel/traverse" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/traverse" "^7.25.9"
+    "@babel/types" "^7.25.9"
 
 "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.6", "@babel/helper-compilation-targets@^7.24.7":
   version "7.24.7"
@@ -577,39 +543,28 @@
     lru-cache "^5.1.1"
     semver "^6.3.1"
 
-"@babel/helper-compilation-targets@^7.25.2":
-  version "7.25.2"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c"
-  integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==
-  dependencies:
-    "@babel/compat-data" "^7.25.2"
-    "@babel/helper-validator-option" "^7.24.8"
-    browserslist "^4.23.1"
-    lru-cache "^5.1.1"
-    semver "^6.3.1"
-
-"@babel/helper-compilation-targets@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz#11260ac3322dda0ef53edfae6e97b961449f5fa4"
-  integrity sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==
+"@babel/helper-compilation-targets@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875"
+  integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==
   dependencies:
-    "@babel/compat-data" "^7.25.7"
-    "@babel/helper-validator-option" "^7.25.7"
+    "@babel/compat-data" "^7.25.9"
+    "@babel/helper-validator-option" "^7.25.9"
     browserslist "^4.24.0"
     lru-cache "^5.1.1"
     semver "^6.3.1"
 
-"@babel/helper-create-class-features-plugin@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.7.tgz#5d65074c76cae75607421c00d6bd517fe1892d6b"
-  integrity sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw==
-  dependencies:
-    "@babel/helper-annotate-as-pure" "^7.25.7"
-    "@babel/helper-member-expression-to-functions" "^7.25.7"
-    "@babel/helper-optimise-call-expression" "^7.25.7"
-    "@babel/helper-replace-supers" "^7.25.7"
-    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+"@babel/helper-create-class-features-plugin@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz#7644147706bb90ff613297d49ed5266bde729f83"
+  integrity sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.25.9"
+    "@babel/helper-member-expression-to-functions" "^7.25.9"
+    "@babel/helper-optimise-call-expression" "^7.25.9"
+    "@babel/helper-replace-supers" "^7.25.9"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
     semver "^6.3.1"
 
 "@babel/helper-create-regexp-features-plugin@^7.18.6":
@@ -621,12 +576,12 @@
     regexpu-core "^5.3.1"
     semver "^6.3.1"
 
-"@babel/helper-create-regexp-features-plugin@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.7.tgz#dcb464f0e2cdfe0c25cc2a0a59c37ab940ce894e"
-  integrity sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ==
+"@babel/helper-create-regexp-features-plugin@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz#3e8999db94728ad2b2458d7a470e7770b7764e26"
+  integrity sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==
   dependencies:
-    "@babel/helper-annotate-as-pure" "^7.25.7"
+    "@babel/helper-annotate-as-pure" "^7.25.9"
     regexpu-core "^6.1.1"
     semver "^6.3.1"
 
@@ -670,13 +625,13 @@
   dependencies:
     "@babel/types" "^7.24.7"
 
-"@babel/helper-member-expression-to-functions@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.7.tgz#541a33b071f0355a63a0fa4bdf9ac360116b8574"
-  integrity sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA==
+"@babel/helper-member-expression-to-functions@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz#9dfffe46f727005a5ea29051ac835fb735e4c1a3"
+  integrity sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==
   dependencies:
-    "@babel/traverse" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/traverse" "^7.25.9"
+    "@babel/types" "^7.25.9"
 
 "@babel/helper-module-imports@^7.24.7":
   version "7.24.7"
@@ -686,13 +641,13 @@
     "@babel/traverse" "^7.24.7"
     "@babel/types" "^7.24.7"
 
-"@babel/helper-module-imports@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472"
-  integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==
+"@babel/helper-module-imports@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715"
+  integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==
   dependencies:
-    "@babel/traverse" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/traverse" "^7.25.9"
+    "@babel/types" "^7.25.9"
 
 "@babel/helper-module-transforms@^7.24.6", "@babel/helper-module-transforms@^7.24.7":
   version "7.24.7"
@@ -705,42 +660,31 @@
     "@babel/helper-split-export-declaration" "^7.24.7"
     "@babel/helper-validator-identifier" "^7.24.7"
 
-"@babel/helper-module-transforms@^7.25.2":
-  version "7.25.2"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6"
-  integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==
+"@babel/helper-module-transforms@^7.25.9", "@babel/helper-module-transforms@^7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae"
+  integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==
   dependencies:
-    "@babel/helper-module-imports" "^7.24.7"
-    "@babel/helper-simple-access" "^7.24.7"
-    "@babel/helper-validator-identifier" "^7.24.7"
-    "@babel/traverse" "^7.25.2"
+    "@babel/helper-module-imports" "^7.25.9"
+    "@babel/helper-validator-identifier" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
 
-"@babel/helper-module-transforms@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz#2ac9372c5e001b19bc62f1fe7d96a18cb0901d1a"
-  integrity sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==
+"@babel/helper-optimise-call-expression@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz#3324ae50bae7e2ab3c33f60c9a877b6a0146b54e"
+  integrity sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==
   dependencies:
-    "@babel/helper-module-imports" "^7.25.7"
-    "@babel/helper-simple-access" "^7.25.7"
-    "@babel/helper-validator-identifier" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
-
-"@babel/helper-optimise-call-expression@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.7.tgz#1de1b99688e987af723eed44fa7fc0ee7b97d77a"
-  integrity sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng==
-  dependencies:
-    "@babel/types" "^7.25.7"
+    "@babel/types" "^7.25.9"
 
 "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0":
   version "7.24.7"
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz#98c84fe6fe3d0d3ae7bfc3a5e166a46844feb2a0"
   integrity sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==
 
-"@babel/helper-plugin-utils@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c"
-  integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==
+"@babel/helper-plugin-utils@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46"
+  integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==
 
 "@babel/helper-remap-async-to-generator@^7.18.9":
   version "7.24.7"
@@ -751,23 +695,23 @@
     "@babel/helper-environment-visitor" "^7.24.7"
     "@babel/helper-wrap-function" "^7.24.7"
 
-"@babel/helper-remap-async-to-generator@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.7.tgz#9efdc39df5f489bcd15533c912b6c723a0a65021"
-  integrity sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw==
+"@babel/helper-remap-async-to-generator@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz#e53956ab3d5b9fb88be04b3e2f31b523afd34b92"
+  integrity sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==
   dependencies:
-    "@babel/helper-annotate-as-pure" "^7.25.7"
-    "@babel/helper-wrap-function" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+    "@babel/helper-annotate-as-pure" "^7.25.9"
+    "@babel/helper-wrap-function" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
 
-"@babel/helper-replace-supers@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.7.tgz#38cfda3b6e990879c71d08d0fef9236b62bd75f5"
-  integrity sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw==
+"@babel/helper-replace-supers@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz#ba447224798c3da3f8713fc272b145e33da6a5c5"
+  integrity sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==
   dependencies:
-    "@babel/helper-member-expression-to-functions" "^7.25.7"
-    "@babel/helper-optimise-call-expression" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+    "@babel/helper-member-expression-to-functions" "^7.25.9"
+    "@babel/helper-optimise-call-expression" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
 
 "@babel/helper-simple-access@^7.24.7":
   version "7.24.7"
@@ -777,21 +721,21 @@
     "@babel/traverse" "^7.24.7"
     "@babel/types" "^7.24.7"
 
-"@babel/helper-simple-access@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz#5eb9f6a60c5d6b2e0f76057004f8dacbddfae1c0"
-  integrity sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==
+"@babel/helper-simple-access@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz#6d51783299884a2c74618d6ef0f86820ec2e7739"
+  integrity sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==
   dependencies:
-    "@babel/traverse" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/traverse" "^7.25.9"
+    "@babel/types" "^7.25.9"
 
-"@babel/helper-skip-transparent-expression-wrappers@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.7.tgz#382831c91038b1a6d32643f5f49505b8442cb87c"
-  integrity sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA==
+"@babel/helper-skip-transparent-expression-wrappers@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz#0b2e1b62d560d6b1954893fd2b705dc17c91f0c9"
+  integrity sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==
   dependencies:
-    "@babel/traverse" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/traverse" "^7.25.9"
+    "@babel/types" "^7.25.9"
 
 "@babel/helper-split-export-declaration@7.24.6":
   version "7.24.6"
@@ -812,40 +756,30 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz#4d2d0f14820ede3b9807ea5fc36dfc8cd7da07f2"
   integrity sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==
 
-"@babel/helper-string-parser@^7.24.8":
-  version "7.24.8"
-  resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d"
-  integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==
-
-"@babel/helper-string-parser@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54"
-  integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==
+"@babel/helper-string-parser@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
+  integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
 
 "@babel/helper-validator-identifier@^7.24.7":
   version "7.24.7"
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db"
   integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==
 
-"@babel/helper-validator-identifier@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5"
-  integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==
+"@babel/helper-validator-identifier@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
+  integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
 
 "@babel/helper-validator-option@^7.24.7":
   version "7.24.7"
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz#24c3bb77c7a425d1742eec8fb433b5a1b38e62f6"
   integrity sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==
 
-"@babel/helper-validator-option@^7.24.8":
-  version "7.24.8"
-  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d"
-  integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==
-
-"@babel/helper-validator-option@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz#97d1d684448228b30b506d90cace495d6f492729"
-  integrity sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==
+"@babel/helper-validator-option@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72"
+  integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==
 
 "@babel/helper-wrap-function@^7.24.7":
   version "7.24.7"
@@ -857,14 +791,14 @@
     "@babel/traverse" "^7.24.7"
     "@babel/types" "^7.24.7"
 
-"@babel/helper-wrap-function@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.7.tgz#9f6021dd1c4fdf4ad515c809967fc4bac9a70fe7"
-  integrity sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg==
+"@babel/helper-wrap-function@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz#d99dfd595312e6c894bd7d237470025c85eea9d0"
+  integrity sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==
   dependencies:
-    "@babel/template" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/template" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
+    "@babel/types" "^7.25.9"
 
 "@babel/helpers@^7.24.6", "@babel/helpers@^7.24.7":
   version "7.24.7"
@@ -874,21 +808,13 @@
     "@babel/template" "^7.24.7"
     "@babel/types" "^7.24.7"
 
-"@babel/helpers@^7.25.0":
-  version "7.25.0"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.0.tgz#e69beb7841cb93a6505531ede34f34e6a073650a"
-  integrity sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==
+"@babel/helpers@^7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4"
+  integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==
   dependencies:
-    "@babel/template" "^7.25.0"
-    "@babel/types" "^7.25.0"
-
-"@babel/helpers@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.7.tgz#091b52cb697a171fe0136ab62e54e407211f09c2"
-  integrity sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==
-  dependencies:
-    "@babel/template" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/template" "^7.25.9"
+    "@babel/types" "^7.26.0"
 
 "@babel/highlight@^7.24.7":
   version "7.24.7"
@@ -900,71 +826,56 @@
     js-tokens "^4.0.0"
     picocolors "^1.0.0"
 
-"@babel/highlight@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.7.tgz#20383b5f442aa606e7b5e3043b0b1aafe9f37de5"
-  integrity sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==
-  dependencies:
-    "@babel/helper-validator-identifier" "^7.25.7"
-    chalk "^2.4.2"
-    js-tokens "^4.0.0"
-    picocolors "^1.0.0"
-
 "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.10.3", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.6", "@babel/parser@^7.24.7":
   version "7.24.7"
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85"
   integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==
 
-"@babel/parser@^7.25.0":
-  version "7.25.0"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.0.tgz#9fdc9237504d797b6e7b8f66e78ea7f570d256ad"
-  integrity sha512-CzdIU9jdP0dg7HdyB+bHvDJGagUv+qtzZt5rYCWwW6tITNqV9odjp6Qu41gkG0ca5UfdDUWrKkiAnHHdGRnOrA==
-
-"@babel/parser@^7.25.7", "@babel/parser@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2"
-  integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==
+"@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.2":
+  version "7.26.2"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11"
+  integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==
   dependencies:
-    "@babel/types" "^7.25.8"
+    "@babel/types" "^7.26.0"
 
-"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.7.tgz#93969ac50ef4d68b2504b01b758af714e4cbdd64"
-  integrity sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ==
+"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz#cc2e53ebf0a0340777fff5ed521943e253b4d8fe"
+  integrity sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
 
-"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.7.tgz#a338d611adb9dcd599b8b1efa200c88ebeffe046"
-  integrity sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ==
+"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz#af9e4fb63ccb8abcb92375b2fcfe36b60c774d30"
+  integrity sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.7.tgz#c5f755e911dfac7ef6957300c0f9c4a8c18c06f4"
-  integrity sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA==
+"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz#e8dc26fcd616e6c5bf2bd0d5a2c151d4f92a9137"
+  integrity sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.7.tgz#3b7ea04492ded990978b6deaa1dfca120ad4455a"
-  integrity sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng==
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz#807a667f9158acac6f6164b4beb85ad9ebc9e1d1"
+  integrity sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7"
-    "@babel/plugin-transform-optional-chaining" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
+    "@babel/plugin-transform-optional-chaining" "^7.25.9"
 
-"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.7.tgz#9622b1d597a703aa3a921e6f58c9c2d9a028d2c5"
-  integrity sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw==
+"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz#de7093f1e7deaf68eadd7cc6b07f2ab82543269e"
+  integrity sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
 
 "@babel/plugin-proposal-async-generator-functions@^7.20.1":
   version "7.20.7"
@@ -988,19 +899,19 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.0"
 
-"@babel/plugin-syntax-import-assertions@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz#8ce248f9f4ed4b7ed4cb2e0eb4ed9efd9f52921f"
-  integrity sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ==
+"@babel/plugin-syntax-import-assertions@^7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz#620412405058efa56e4a564903b79355020f445f"
+  integrity sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-syntax-import-attributes@7.25.7", "@babel/plugin-syntax-import-attributes@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz#d78dd0499d30df19a598e63ab895e21b909bc43f"
-  integrity sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==
+"@babel/plugin-syntax-import-attributes@7.26.0", "@babel/plugin-syntax-import-attributes@^7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz#3b1412847699eea739b4f2602c74ce36f6b0b0f7"
+  integrity sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
 "@babel/plugin-syntax-unicode-sets-regex@^7.18.6":
   version "7.18.6"
@@ -1010,466 +921,475 @@
     "@babel/helper-create-regexp-features-plugin" "^7.18.6"
     "@babel/helper-plugin-utils" "^7.18.6"
 
-"@babel/plugin-transform-arrow-functions@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.7.tgz#1b9ed22e6890a0e9ff470371c73b8c749bcec386"
-  integrity sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg==
+"@babel/plugin-transform-arrow-functions@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz#7821d4410bee5daaadbb4cdd9a6649704e176845"
+  integrity sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-async-generator-functions@7.25.8", "@babel/plugin-transform-async-generator-functions@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.8.tgz#3331de02f52cc1f2c75b396bec52188c85b0b1ec"
-  integrity sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA==
+"@babel/plugin-transform-async-generator-functions@7.25.9", "@babel/plugin-transform-async-generator-functions@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz#1b18530b077d18a407c494eb3d1d72da505283a2"
+  integrity sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-remap-async-to-generator" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-remap-async-to-generator" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
 
-"@babel/plugin-transform-async-to-generator@7.25.7", "@babel/plugin-transform-async-to-generator@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.7.tgz#a44c7323f8d4285a6c568dd43c5c361d6367ec52"
-  integrity sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg==
+"@babel/plugin-transform-async-to-generator@7.25.9", "@babel/plugin-transform-async-to-generator@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz#c80008dacae51482793e5a9c08b39a5be7e12d71"
+  integrity sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==
   dependencies:
-    "@babel/helper-module-imports" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-remap-async-to-generator" "^7.25.7"
+    "@babel/helper-module-imports" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-remap-async-to-generator" "^7.25.9"
 
-"@babel/plugin-transform-block-scoped-functions@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.7.tgz#e0b8843d5571719a2f1bf7e284117a3379fcc17c"
-  integrity sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ==
+"@babel/plugin-transform-block-scoped-functions@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz#5700691dbd7abb93de300ca7be94203764fce458"
+  integrity sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-block-scoping@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.7.tgz#6dab95e98adf780ceef1b1c3ab0e55cd20dd410a"
-  integrity sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow==
+"@babel/plugin-transform-block-scoping@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz#c33665e46b06759c93687ca0f84395b80c0473a1"
+  integrity sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-class-properties@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.7.tgz#a389cfca7a10ac80e3ff4c75fca08bd097ad1523"
-  integrity sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g==
+"@babel/plugin-transform-class-properties@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz#a8ce84fedb9ad512549984101fa84080a9f5f51f"
+  integrity sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-class-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-class-static-block@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz#a8af22028920fe404668031eceb4c3aadccb5262"
-  integrity sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ==
+"@babel/plugin-transform-class-static-block@^7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz#6c8da219f4eb15cae9834ec4348ff8e9e09664a0"
+  integrity sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-class-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-classes@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.7.tgz#5103206cf80d02283bbbd044509ea3b65d0906bb"
-  integrity sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg==
+"@babel/plugin-transform-classes@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz#7152457f7880b593a63ade8a861e6e26a4469f52"
+  integrity sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==
   dependencies:
-    "@babel/helper-annotate-as-pure" "^7.25.7"
-    "@babel/helper-compilation-targets" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-replace-supers" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+    "@babel/helper-annotate-as-pure" "^7.25.9"
+    "@babel/helper-compilation-targets" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-replace-supers" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
     globals "^11.1.0"
 
-"@babel/plugin-transform-computed-properties@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.7.tgz#7f621f0aa1354b5348a935ab12e3903842466f65"
-  integrity sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA==
+"@babel/plugin-transform-computed-properties@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz#db36492c78460e534b8852b1d5befe3c923ef10b"
+  integrity sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/template" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/template" "^7.25.9"
 
-"@babel/plugin-transform-destructuring@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.7.tgz#f6f26a9feefb5aa41fd45b6f5838901b5333d560"
-  integrity sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA==
+"@babel/plugin-transform-destructuring@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz#966ea2595c498224340883602d3cfd7a0c79cea1"
+  integrity sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-dotall-regex@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.7.tgz#9d775c4a3ff1aea64045300fcd4309b4a610ef02"
-  integrity sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ==
+"@babel/plugin-transform-dotall-regex@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz#bad7945dd07734ca52fe3ad4e872b40ed09bb09a"
+  integrity sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-regexp-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-duplicate-keys@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.7.tgz#fbba7d1155eab76bd4f2a038cbd5d65883bd7a93"
-  integrity sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg==
+"@babel/plugin-transform-duplicate-keys@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz#8850ddf57dce2aebb4394bb434a7598031059e6d"
+  integrity sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.7.tgz#102b31608dcc22c08fbca1894e104686029dc141"
-  integrity sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA==
+"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz#6f7259b4de127721a08f1e5165b852fcaa696d31"
+  integrity sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-regexp-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-dynamic-import@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz#f1edbe75b248cf44c70c8ca8ed3818a668753aaa"
-  integrity sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A==
+"@babel/plugin-transform-dynamic-import@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz#23e917de63ed23c6600c5dd06d94669dce79f7b8"
+  integrity sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-exponentiation-operator@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.7.tgz#5961a3a23a398faccd6cddb34a2182807d75fb5f"
-  integrity sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg==
+"@babel/plugin-transform-exponentiation-operator@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz#ece47b70d236c1d99c263a1e22b62dc20a4c8b0f"
+  integrity sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==
   dependencies:
-    "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-export-namespace-from@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz#d1988c3019a380b417e0516418b02804d3858145"
-  integrity sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw==
+"@babel/plugin-transform-export-namespace-from@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz#90745fe55053394f554e40584cda81f2c8a402a2"
+  integrity sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-for-of@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.7.tgz#0acfea0f27aa290818b5b48a5a44b3f03fc13669"
-  integrity sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw==
+"@babel/plugin-transform-for-of@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz#4bdc7d42a213397905d89f02350c5267866d5755"
+  integrity sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
 
-"@babel/plugin-transform-function-name@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.7.tgz#7e394ccea3693902a8b50ded8b6ae1fa7b8519fd"
-  integrity sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ==
+"@babel/plugin-transform-function-name@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz#939d956e68a606661005bfd550c4fc2ef95f7b97"
+  integrity sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==
   dependencies:
-    "@babel/helper-compilation-targets" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+    "@babel/helper-compilation-targets" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
 
-"@babel/plugin-transform-json-strings@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz#6fb3ec383a2ea92652289fdba653e3f9de722694"
-  integrity sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA==
+"@babel/plugin-transform-json-strings@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz#c86db407cb827cded902a90c707d2781aaa89660"
+  integrity sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-literals@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.7.tgz#70cbdc742f2cfdb1a63ea2cbd018d12a60b213c3"
-  integrity sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w==
+"@babel/plugin-transform-literals@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz#1a1c6b4d4aa59bc4cad5b6b3a223a0abd685c9de"
+  integrity sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-logical-assignment-operators@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz#01868ff92daa9e525b4c7902aa51979082a05710"
-  integrity sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g==
+"@babel/plugin-transform-logical-assignment-operators@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz#b19441a8c39a2fda0902900b306ea05ae1055db7"
+  integrity sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-member-expression-literals@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.7.tgz#0a36c3fbd450cc9e6485c507f005fa3d1bc8fca5"
-  integrity sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw==
+"@babel/plugin-transform-member-expression-literals@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz#63dff19763ea64a31f5e6c20957e6a25e41ed5de"
+  integrity sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-modules-amd@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.7.tgz#bb4e543b5611f6c8c685a2fd485408713a3adf3d"
-  integrity sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA==
+"@babel/plugin-transform-modules-amd@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz#49ba478f2295101544abd794486cd3088dddb6c5"
+  integrity sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==
   dependencies:
-    "@babel/helper-module-transforms" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-module-transforms" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-modules-commonjs@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.7.tgz#173f0c791bb7407c092ce6d77ee90eb3f2d1d2fd"
-  integrity sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg==
+"@babel/plugin-transform-modules-commonjs@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz#d165c8c569a080baf5467bda88df6425fc060686"
+  integrity sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==
   dependencies:
-    "@babel/helper-module-transforms" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-simple-access" "^7.25.7"
+    "@babel/helper-module-transforms" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-simple-access" "^7.25.9"
 
-"@babel/plugin-transform-modules-systemjs@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.7.tgz#8b14d319a177cc9c85ef8b0512afd429d9e2e60b"
-  integrity sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g==
+"@babel/plugin-transform-modules-systemjs@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz#8bd1b43836269e3d33307151a114bcf3ba6793f8"
+  integrity sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==
   dependencies:
-    "@babel/helper-module-transforms" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-validator-identifier" "^7.25.7"
-    "@babel/traverse" "^7.25.7"
+    "@babel/helper-module-transforms" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-validator-identifier" "^7.25.9"
+    "@babel/traverse" "^7.25.9"
 
-"@babel/plugin-transform-modules-umd@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.7.tgz#00ee7a7e124289549381bfb0e24d87fd7f848367"
-  integrity sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw==
+"@babel/plugin-transform-modules-umd@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz#6710079cdd7c694db36529a1e8411e49fcbf14c9"
+  integrity sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==
   dependencies:
-    "@babel/helper-module-transforms" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-module-transforms" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-named-capturing-groups-regex@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.7.tgz#a2f3f6d7f38693b462542951748f0a72a34d196d"
-  integrity sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow==
+"@babel/plugin-transform-named-capturing-groups-regex@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz#454990ae6cc22fd2a0fa60b3a2c6f63a38064e6a"
+  integrity sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-regexp-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-new-target@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.7.tgz#52b2bde523b76c548749f38dc3054f1f45e82bc9"
-  integrity sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA==
+"@babel/plugin-transform-new-target@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz#42e61711294b105c248336dcb04b77054ea8becd"
+  integrity sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-nullish-coalescing-operator@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz#befb4900c130bd52fccf2b926314557987f1b552"
-  integrity sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==
+"@babel/plugin-transform-nullish-coalescing-operator@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz#bcb1b0d9e948168102d5f7104375ca21c3266949"
+  integrity sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-numeric-separator@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz#91e370486371637bd42161052f2602c701386891"
-  integrity sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q==
+"@babel/plugin-transform-numeric-separator@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz#bfed75866261a8b643468b0ccfd275f2033214a1"
+  integrity sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-object-rest-spread@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz#0904ac16bcce41df4db12d915d6780f85c7fb04b"
-  integrity sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g==
+"@babel/plugin-transform-object-rest-spread@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz#0203725025074164808bcf1a2cfa90c652c99f18"
+  integrity sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==
   dependencies:
-    "@babel/helper-compilation-targets" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/plugin-transform-parameters" "^7.25.7"
+    "@babel/helper-compilation-targets" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/plugin-transform-parameters" "^7.25.9"
 
-"@babel/plugin-transform-object-super@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.7.tgz#582a9cea8cf0a1e02732be5b5a703a38dedf5661"
-  integrity sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA==
+"@babel/plugin-transform-object-super@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz#385d5de135162933beb4a3d227a2b7e52bb4cf03"
+  integrity sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-replace-supers" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-replace-supers" "^7.25.9"
 
-"@babel/plugin-transform-optional-catch-binding@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz#2649b86a3bb202c6894ec81a6ddf41b94d8f3103"
-  integrity sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg==
+"@babel/plugin-transform-optional-catch-binding@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz#10e70d96d52bb1f10c5caaac59ac545ea2ba7ff3"
+  integrity sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-optional-chaining@^7.25.7", "@babel/plugin-transform-optional-chaining@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz#f46283b78adcc5b6ab988a952f989e7dce70653f"
-  integrity sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg==
+"@babel/plugin-transform-optional-chaining@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz#e142eb899d26ef715435f201ab6e139541eee7dd"
+  integrity sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
 
-"@babel/plugin-transform-parameters@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.7.tgz#80c38b03ef580f6d6bffe1c5254bb35986859ac7"
-  integrity sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ==
+"@babel/plugin-transform-parameters@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz#b856842205b3e77e18b7a7a1b94958069c7ba257"
+  integrity sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-private-methods@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.7.tgz#c790a04f837b4bd61d6b0317b43aa11ff67dce80"
-  integrity sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA==
+"@babel/plugin-transform-private-methods@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz#847f4139263577526455d7d3223cd8bda51e3b57"
+  integrity sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-class-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-private-property-in-object@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz#1234f856ce85e061f9688764194e51ea7577c434"
-  integrity sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow==
+"@babel/plugin-transform-private-property-in-object@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz#9c8b73e64e6cc3cbb2743633885a7dd2c385fe33"
+  integrity sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==
   dependencies:
-    "@babel/helper-annotate-as-pure" "^7.25.7"
-    "@babel/helper-create-class-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-annotate-as-pure" "^7.25.9"
+    "@babel/helper-create-class-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-property-literals@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.7.tgz#a8612b4ea4e10430f00012ecf0155662c7d6550d"
-  integrity sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw==
+"@babel/plugin-transform-property-literals@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz#d72d588bd88b0dec8b62e36f6fda91cedfe28e3f"
+  integrity sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-regenerator@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.7.tgz#6eb006e6d26f627bc2f7844a9f19770721ad6f3e"
-  integrity sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ==
+"@babel/plugin-transform-regenerator@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz#03a8a4670d6cebae95305ac6defac81ece77740b"
+  integrity sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
     regenerator-transform "^0.15.2"
 
-"@babel/plugin-transform-reserved-words@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.7.tgz#dc56b25e02afaabef3ce0c5b06b0916e8523e995"
-  integrity sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng==
+"@babel/plugin-transform-regexp-modifiers@^7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz#2f5837a5b5cd3842a919d8147e9903cc7455b850"
+  integrity sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-regexp-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-runtime@7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.7.tgz#435a4fab67273f00047dc806e05069c9c6344e12"
-  integrity sha512-Y9p487tyTzB0yDYQOtWnC+9HGOuogtP3/wNpun1xJXEEvI6vip59BSBTsHnekZLqxmPcgsrAKt46HAAb//xGhg==
+"@babel/plugin-transform-reserved-words@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz#0398aed2f1f10ba3f78a93db219b27ef417fb9ce"
+  integrity sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==
   dependencies:
-    "@babel/helper-module-imports" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+
+"@babel/plugin-transform-runtime@7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz#62723ea3f5b31ffbe676da9d6dae17138ae580ea"
+  integrity sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==
+  dependencies:
+    "@babel/helper-module-imports" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
     babel-plugin-polyfill-corejs2 "^0.4.10"
     babel-plugin-polyfill-corejs3 "^0.10.6"
     babel-plugin-polyfill-regenerator "^0.6.1"
     semver "^6.3.1"
 
-"@babel/plugin-transform-shorthand-properties@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.7.tgz#92690a9c671915602d91533c278cc8f6bf12275f"
-  integrity sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA==
+"@babel/plugin-transform-shorthand-properties@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz#bb785e6091f99f826a95f9894fc16fde61c163f2"
+  integrity sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-spread@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.7.tgz#df83e899a9fc66284ee601a7b738568435b92998"
-  integrity sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw==
+"@babel/plugin-transform-spread@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz#24a35153931b4ba3d13cec4a7748c21ab5514ef9"
+  integrity sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
 
-"@babel/plugin-transform-sticky-regex@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.7.tgz#341c7002bef7f29037be7fb9684e374442dd0d17"
-  integrity sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw==
+"@babel/plugin-transform-sticky-regex@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz#c7f02b944e986a417817b20ba2c504dfc1453d32"
+  integrity sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-template-literals@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.7.tgz#e566c581bb16d8541dd8701093bb3457adfce16b"
-  integrity sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA==
+"@babel/plugin-transform-template-literals@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz#6dbd4a24e8fad024df76d1fac6a03cf413f60fe1"
+  integrity sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-typeof-symbol@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.7.tgz#debb1287182efd20488f126be343328c679b66eb"
-  integrity sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA==
+"@babel/plugin-transform-typeof-symbol@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz#224ba48a92869ddbf81f9b4a5f1204bbf5a2bc4b"
+  integrity sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-unicode-escapes@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.7.tgz#973592b6d13a914794e1de8cf1383e50e0f87f81"
-  integrity sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ==
+"@babel/plugin-transform-unicode-escapes@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz#a75ef3947ce15363fccaa38e2dd9bc70b2788b82"
+  integrity sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-unicode-property-regex@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.7.tgz#25349197cce964b1343f74fa7cfdf791a1b1919e"
-  integrity sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w==
+"@babel/plugin-transform-unicode-property-regex@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz#a901e96f2c1d071b0d1bb5dc0d3c880ce8f53dd3"
+  integrity sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-regexp-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-unicode-regex@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.7.tgz#f93a93441baf61f713b6d5552aaa856bfab34809"
-  integrity sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g==
+"@babel/plugin-transform-unicode-regex@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz#5eae747fe39eacf13a8bd006a4fb0b5d1fa5e9b1"
+  integrity sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-regexp-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-unicode-sets-regex@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.7.tgz#d1b3295d29e0f8f4df76abc909ad1ebee919560c"
-  integrity sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw==
+"@babel/plugin-transform-unicode-sets-regex@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz#65114c17b4ffc20fa5b163c63c70c0d25621fabe"
+  integrity sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
+    "@babel/helper-create-regexp-features-plugin" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/preset-env@7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.8.tgz#dc6b719627fb29cd9cccbbbe041802fd575b524c"
-  integrity sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg==
+"@babel/preset-env@7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.26.0.tgz#30e5c6bc1bcc54865bff0c5a30f6d4ccdc7fa8b1"
+  integrity sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==
   dependencies:
-    "@babel/compat-data" "^7.25.8"
-    "@babel/helper-compilation-targets" "^7.25.7"
-    "@babel/helper-plugin-utils" "^7.25.7"
-    "@babel/helper-validator-option" "^7.25.7"
-    "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.7"
-    "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.7"
-    "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.7"
-    "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.7"
-    "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.7"
+    "@babel/compat-data" "^7.26.0"
+    "@babel/helper-compilation-targets" "^7.25.9"
+    "@babel/helper-plugin-utils" "^7.25.9"
+    "@babel/helper-validator-option" "^7.25.9"
+    "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.9"
+    "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.9"
+    "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.9"
+    "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.9"
+    "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.9"
     "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2"
-    "@babel/plugin-syntax-import-assertions" "^7.25.7"
-    "@babel/plugin-syntax-import-attributes" "^7.25.7"
+    "@babel/plugin-syntax-import-assertions" "^7.26.0"
+    "@babel/plugin-syntax-import-attributes" "^7.26.0"
     "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6"
-    "@babel/plugin-transform-arrow-functions" "^7.25.7"
-    "@babel/plugin-transform-async-generator-functions" "^7.25.8"
-    "@babel/plugin-transform-async-to-generator" "^7.25.7"
-    "@babel/plugin-transform-block-scoped-functions" "^7.25.7"
-    "@babel/plugin-transform-block-scoping" "^7.25.7"
-    "@babel/plugin-transform-class-properties" "^7.25.7"
-    "@babel/plugin-transform-class-static-block" "^7.25.8"
-    "@babel/plugin-transform-classes" "^7.25.7"
-    "@babel/plugin-transform-computed-properties" "^7.25.7"
-    "@babel/plugin-transform-destructuring" "^7.25.7"
-    "@babel/plugin-transform-dotall-regex" "^7.25.7"
-    "@babel/plugin-transform-duplicate-keys" "^7.25.7"
-    "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.7"
-    "@babel/plugin-transform-dynamic-import" "^7.25.8"
-    "@babel/plugin-transform-exponentiation-operator" "^7.25.7"
-    "@babel/plugin-transform-export-namespace-from" "^7.25.8"
-    "@babel/plugin-transform-for-of" "^7.25.7"
-    "@babel/plugin-transform-function-name" "^7.25.7"
-    "@babel/plugin-transform-json-strings" "^7.25.8"
-    "@babel/plugin-transform-literals" "^7.25.7"
-    "@babel/plugin-transform-logical-assignment-operators" "^7.25.8"
-    "@babel/plugin-transform-member-expression-literals" "^7.25.7"
-    "@babel/plugin-transform-modules-amd" "^7.25.7"
-    "@babel/plugin-transform-modules-commonjs" "^7.25.7"
-    "@babel/plugin-transform-modules-systemjs" "^7.25.7"
-    "@babel/plugin-transform-modules-umd" "^7.25.7"
-    "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.7"
-    "@babel/plugin-transform-new-target" "^7.25.7"
-    "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.8"
-    "@babel/plugin-transform-numeric-separator" "^7.25.8"
-    "@babel/plugin-transform-object-rest-spread" "^7.25.8"
-    "@babel/plugin-transform-object-super" "^7.25.7"
-    "@babel/plugin-transform-optional-catch-binding" "^7.25.8"
-    "@babel/plugin-transform-optional-chaining" "^7.25.8"
-    "@babel/plugin-transform-parameters" "^7.25.7"
-    "@babel/plugin-transform-private-methods" "^7.25.7"
-    "@babel/plugin-transform-private-property-in-object" "^7.25.8"
-    "@babel/plugin-transform-property-literals" "^7.25.7"
-    "@babel/plugin-transform-regenerator" "^7.25.7"
-    "@babel/plugin-transform-reserved-words" "^7.25.7"
-    "@babel/plugin-transform-shorthand-properties" "^7.25.7"
-    "@babel/plugin-transform-spread" "^7.25.7"
-    "@babel/plugin-transform-sticky-regex" "^7.25.7"
-    "@babel/plugin-transform-template-literals" "^7.25.7"
-    "@babel/plugin-transform-typeof-symbol" "^7.25.7"
-    "@babel/plugin-transform-unicode-escapes" "^7.25.7"
-    "@babel/plugin-transform-unicode-property-regex" "^7.25.7"
-    "@babel/plugin-transform-unicode-regex" "^7.25.7"
-    "@babel/plugin-transform-unicode-sets-regex" "^7.25.7"
+    "@babel/plugin-transform-arrow-functions" "^7.25.9"
+    "@babel/plugin-transform-async-generator-functions" "^7.25.9"
+    "@babel/plugin-transform-async-to-generator" "^7.25.9"
+    "@babel/plugin-transform-block-scoped-functions" "^7.25.9"
+    "@babel/plugin-transform-block-scoping" "^7.25.9"
+    "@babel/plugin-transform-class-properties" "^7.25.9"
+    "@babel/plugin-transform-class-static-block" "^7.26.0"
+    "@babel/plugin-transform-classes" "^7.25.9"
+    "@babel/plugin-transform-computed-properties" "^7.25.9"
+    "@babel/plugin-transform-destructuring" "^7.25.9"
+    "@babel/plugin-transform-dotall-regex" "^7.25.9"
+    "@babel/plugin-transform-duplicate-keys" "^7.25.9"
+    "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.9"
+    "@babel/plugin-transform-dynamic-import" "^7.25.9"
+    "@babel/plugin-transform-exponentiation-operator" "^7.25.9"
+    "@babel/plugin-transform-export-namespace-from" "^7.25.9"
+    "@babel/plugin-transform-for-of" "^7.25.9"
+    "@babel/plugin-transform-function-name" "^7.25.9"
+    "@babel/plugin-transform-json-strings" "^7.25.9"
+    "@babel/plugin-transform-literals" "^7.25.9"
+    "@babel/plugin-transform-logical-assignment-operators" "^7.25.9"
+    "@babel/plugin-transform-member-expression-literals" "^7.25.9"
+    "@babel/plugin-transform-modules-amd" "^7.25.9"
+    "@babel/plugin-transform-modules-commonjs" "^7.25.9"
+    "@babel/plugin-transform-modules-systemjs" "^7.25.9"
+    "@babel/plugin-transform-modules-umd" "^7.25.9"
+    "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.9"
+    "@babel/plugin-transform-new-target" "^7.25.9"
+    "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.9"
+    "@babel/plugin-transform-numeric-separator" "^7.25.9"
+    "@babel/plugin-transform-object-rest-spread" "^7.25.9"
+    "@babel/plugin-transform-object-super" "^7.25.9"
+    "@babel/plugin-transform-optional-catch-binding" "^7.25.9"
+    "@babel/plugin-transform-optional-chaining" "^7.25.9"
+    "@babel/plugin-transform-parameters" "^7.25.9"
+    "@babel/plugin-transform-private-methods" "^7.25.9"
+    "@babel/plugin-transform-private-property-in-object" "^7.25.9"
+    "@babel/plugin-transform-property-literals" "^7.25.9"
+    "@babel/plugin-transform-regenerator" "^7.25.9"
+    "@babel/plugin-transform-regexp-modifiers" "^7.26.0"
+    "@babel/plugin-transform-reserved-words" "^7.25.9"
+    "@babel/plugin-transform-shorthand-properties" "^7.25.9"
+    "@babel/plugin-transform-spread" "^7.25.9"
+    "@babel/plugin-transform-sticky-regex" "^7.25.9"
+    "@babel/plugin-transform-template-literals" "^7.25.9"
+    "@babel/plugin-transform-typeof-symbol" "^7.25.9"
+    "@babel/plugin-transform-unicode-escapes" "^7.25.9"
+    "@babel/plugin-transform-unicode-property-regex" "^7.25.9"
+    "@babel/plugin-transform-unicode-regex" "^7.25.9"
+    "@babel/plugin-transform-unicode-sets-regex" "^7.25.9"
     "@babel/preset-modules" "0.1.6-no-external-plugins"
     babel-plugin-polyfill-corejs2 "^0.4.10"
     babel-plugin-polyfill-corejs3 "^0.10.6"
@@ -1491,10 +1411,10 @@
   resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
   integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
 
-"@babel/runtime@7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6"
-  integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==
+"@babel/runtime@7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
+  integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
   dependencies:
     regenerator-runtime "^0.14.0"
 
@@ -1514,23 +1434,14 @@
     "@babel/parser" "^7.24.7"
     "@babel/types" "^7.24.7"
 
-"@babel/template@^7.25.0":
-  version "7.25.0"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a"
-  integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==
-  dependencies:
-    "@babel/code-frame" "^7.24.7"
-    "@babel/parser" "^7.25.0"
-    "@babel/types" "^7.25.0"
-
-"@babel/template@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769"
-  integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==
+"@babel/template@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016"
+  integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==
   dependencies:
-    "@babel/code-frame" "^7.25.7"
-    "@babel/parser" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/code-frame" "^7.25.9"
+    "@babel/parser" "^7.25.9"
+    "@babel/types" "^7.25.9"
 
 "@babel/traverse@^7.10.3", "@babel/traverse@^7.24.6", "@babel/traverse@^7.24.7":
   version "7.24.7"
@@ -1548,29 +1459,16 @@
     debug "^4.3.1"
     globals "^11.1.0"
 
-"@babel/traverse@^7.25.2":
-  version "7.25.2"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.2.tgz#1a0a4aef53177bead359ccd0c89f4426c805b2ae"
-  integrity sha512-s4/r+a7xTnny2O6FcZzqgT6nE4/GHEdcqj4qAeglbUOh0TeglEfmNJFAd/OLoVtGd6ZhAO8GCVvCNUO5t/VJVQ==
+"@babel/traverse@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84"
+  integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
   dependencies:
-    "@babel/code-frame" "^7.24.7"
-    "@babel/generator" "^7.25.0"
-    "@babel/parser" "^7.25.0"
-    "@babel/template" "^7.25.0"
-    "@babel/types" "^7.25.2"
-    debug "^4.3.1"
-    globals "^11.1.0"
-
-"@babel/traverse@^7.25.7":
-  version "7.25.7"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8"
-  integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==
-  dependencies:
-    "@babel/code-frame" "^7.25.7"
-    "@babel/generator" "^7.25.7"
-    "@babel/parser" "^7.25.7"
-    "@babel/template" "^7.25.7"
-    "@babel/types" "^7.25.7"
+    "@babel/code-frame" "^7.25.9"
+    "@babel/generator" "^7.25.9"
+    "@babel/parser" "^7.25.9"
+    "@babel/template" "^7.25.9"
+    "@babel/types" "^7.25.9"
     debug "^4.3.1"
     globals "^11.1.0"
 
@@ -1583,23 +1481,13 @@
     "@babel/helper-validator-identifier" "^7.24.7"
     to-fast-properties "^2.0.0"
 
-"@babel/types@^7.25.0", "@babel/types@^7.25.2":
-  version "7.25.2"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.2.tgz#55fb231f7dc958cd69ea141a4c2997e819646125"
-  integrity sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==
-  dependencies:
-    "@babel/helper-string-parser" "^7.24.8"
-    "@babel/helper-validator-identifier" "^7.24.7"
-    to-fast-properties "^2.0.0"
-
-"@babel/types@^7.25.7", "@babel/types@^7.25.8":
-  version "7.25.8"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1"
-  integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==
+"@babel/types@^7.25.9", "@babel/types@^7.26.0":
+  version "7.26.0"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff"
+  integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==
   dependencies:
-    "@babel/helper-string-parser" "^7.25.7"
-    "@babel/helper-validator-identifier" "^7.25.7"
-    to-fast-properties "^2.0.0"
+    "@babel/helper-string-parser" "^7.25.9"
+    "@babel/helper-validator-identifier" "^7.25.9"
 
 "@bazel/bazelisk@1.12.1":
   version "1.12.1"
@@ -1718,10 +1606,10 @@
     enabled "2.0.x"
     kuler "^2.0.0"
 
-"@discoveryjs/json-ext@0.6.1":
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.6.1.tgz#593da7a17a31a72a874e313677183334a49b01c9"
-  integrity sha512-boghen8F0Q8D+0/Q1/1r6DUEieUJ8w2a1gIknExMSHBsJFOr2+0KUfHiVYBvucPwl3+RU5PFBK833FjFCh3BhA==
+"@discoveryjs/json-ext@0.6.3":
+  version "0.6.3"
+  resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz#f13c7c205915eb91ae54c557f5e92bddd8be0e83"
+  integrity sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==
 
 "@esbuild/aix-ppc64@0.20.2":
   version "0.20.2"
@@ -2376,32 +2264,32 @@
     protobufjs "^7.2.5"
     yargs "^17.7.2"
 
-"@inquirer/checkbox@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-4.0.0.tgz#89ba37dde46c6d9fec2f826866e8c2fd3dc64d76"
-  integrity sha512-TNd+u1fAG8vf8YMgXzK2BI0u0xsphFv//T5rpF1eZ+8AAXby5Ll1qptr4/XVS45dvWDIzuBmmWIpVJRvnaNqzQ==
+"@inquirer/checkbox@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-4.0.2.tgz#e45e0ad2611f2cb2d337ba36c7d955b53f195914"
+  integrity sha512-+gznPl8ip8P8HYHYecDtUtdsh1t2jvb+sWCD72GAiZ9m45RqwrLmReDaqdC0umQfamtFXVRoMVJ2/qINKGm9Tg==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/figures" "^1.0.7"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/figures" "^1.0.8"
+    "@inquirer/type" "^3.0.1"
     ansi-escapes "^4.3.2"
     yoctocolors-cjs "^2.1.2"
 
-"@inquirer/confirm@5.0.0", "@inquirer/confirm@^5.0.0":
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.0.0.tgz#9ecf8214452c48e8061aed0d513964f05c92d4a3"
-  integrity sha512-6QEzj6bZg8atviRIL+pR0tODC854cYSjvZxkyCarr8DVaOJPEyuGys7GmEG3W0Rb8kKSQec7P6okt0sJvNneFw==
+"@inquirer/confirm@5.0.2", "@inquirer/confirm@^5.0.2":
+  version "5.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.0.2.tgz#2b9dcf6b7da5f518c74abe4aeaf3173253d83c93"
+  integrity sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/type" "^3.0.1"
 
-"@inquirer/core@^10.0.0":
-  version "10.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.0.0.tgz#aa821527e8f6f82990b3fa18a35f8489ffb02c5f"
-  integrity sha512-7dwoKCGvgZGHWTZfOj2KLmbIAIdiXP9NTrwGaTO/XDfKMEmyBahZpnombiG6JDHmiOrmK3GLEJRXrWExXCDLmQ==
+"@inquirer/core@^10.1.0":
+  version "10.1.0"
+  resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.1.0.tgz#c5fdc34c4cafd7248da29a3c3b3120fe6e1c45be"
+  integrity sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==
   dependencies:
-    "@inquirer/figures" "^1.0.7"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/figures" "^1.0.8"
+    "@inquirer/type" "^3.0.1"
     ansi-escapes "^4.3.2"
     cli-width "^4.1.0"
     mute-stream "^2.0.0"
@@ -2410,22 +2298,22 @@
     wrap-ansi "^6.2.0"
     yoctocolors-cjs "^2.1.2"
 
-"@inquirer/editor@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-4.0.0.tgz#9fab50aa83a8b8625d1fe78a45aa239e217d63d3"
-  integrity sha512-bhHAP7hIOxUjiTZrpjyAYD+2RFRa+PNutWeW7JdDPcWWG3GVRiFsu3pBGw9kN2PktoiilDWFGSR0dwXBzGQang==
+"@inquirer/editor@^4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-4.1.0.tgz#bc1a8bebe5897d4b44b0bfab1aeb1b5172f8d812"
+  integrity sha512-K1gGWsxEqO23tVdp5MT3H799OZ4ER1za7Dlc8F4um0W7lwSv0KGR/YyrUEyimj0g7dXZd8XknM/5QA2/Uy+TbA==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/type" "^3.0.1"
     external-editor "^3.1.0"
 
-"@inquirer/expand@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-4.0.0.tgz#ec5ef1f0ed7dfcc207958d189eed90c785b76b43"
-  integrity sha512-mR7JHNIvCB4o12f75KN42he7s1O9tmcSN4wJ6l04oymfXKLn+lYJFI7z9lbe4/Ald6fm8nuF38fuY5hNPl3B+A==
+"@inquirer/expand@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-4.0.2.tgz#7b5c332ad604d7d076e7052b8e5006a3b61c3274"
+  integrity sha512-WdgCX1cUtinz+syKyZdJomovULYlKUWZbVYZzhf+ZeeYf4htAQ3jLymoNs3koIAKfZZl3HUBb819ClCBfyznaw==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/type" "^3.0.1"
     yoctocolors-cjs "^2.1.2"
 
 "@inquirer/figures@^1.0.2":
@@ -2433,79 +2321,79 @@
   resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.3.tgz#1227cc980f88e6d6ab85abadbf164f5038041edd"
   integrity sha512-ErXXzENMH5pJt5/ssXV0DfWUZqly8nGzf0UcBV9xTnP+KyffE2mqyxIMBrZ8ijQck2nU0TQm40EQB53YreyWHw==
 
-"@inquirer/figures@^1.0.7":
-  version "1.0.7"
-  resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.7.tgz#d050ccc0eabfacc0248c4ff647a9dfba1b01594b"
-  integrity sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==
+"@inquirer/figures@^1.0.8":
+  version "1.0.8"
+  resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.8.tgz#d9e414a1376a331a0e71b151fea27c48845788b0"
+  integrity sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==
 
-"@inquirer/input@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-4.0.0.tgz#4d3ad7bacb33a5a7dd0314f237facd28f40c6caa"
-  integrity sha512-LD7MNzaX+q2OpU4Fn0i/SedhnnBCAnEzRr6L0MP6ohofFFlx9kp5EXX7flbRZlUnh8icOwC3NFmXTyP76hvo0g==
+"@inquirer/input@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-4.0.2.tgz#be77b79a1ed182444a6eef2d850309639aa9df22"
+  integrity sha512-yCLCraigU085EcdpIVEDgyfGv4vBiE4I+k1qRkc9C5dMjWF42ADMGy1RFU94+eZlz4YlkmFsiyHZy0W1wdhaNg==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/type" "^3.0.1"
 
-"@inquirer/number@^3.0.0":
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-3.0.0.tgz#6191f1c04b576a1c78ac3fa95af30bf1ef00ff18"
-  integrity sha512-DUYfROyQNWm3q+JXL3S6s1/y/cOWRstnmt5zDXhdYNJ5N8TgCnHcDXKwW/dRZL7eBZupmDVHxdKCWZDUYUqmeg==
+"@inquirer/number@^3.0.2":
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-3.0.2.tgz#7e8315b41601d377cc09802b66f32b481e14fd68"
+  integrity sha512-MKQhYofdUNk7eqJtz52KvM1dH6R93OMrqHduXCvuefKrsiMjHiMwjc3NZw5Imm2nqY7gWd9xdhYrtcHMJQZUxA==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/type" "^3.0.1"
 
-"@inquirer/password@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-4.0.0.tgz#84245a9c2fec74bd5b01d504b6f9dd499d4ee36f"
-  integrity sha512-W4QRSzJDMKIvWSvQWOIhs6qba1MJ6yIoy+sazSFhl2QIwn58B0Yw3iZ/zLk3QqVcCsTmKcyrSNVWUJ5RVDLStw==
+"@inquirer/password@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-4.0.2.tgz#5913e2818b3de1ee6f63ec1b0891a43c1d4bdca9"
+  integrity sha512-tQXGSu7IO07gsYlGy3VgXRVsbOWqFBMbqAUrJSc1PDTQQ5Qdm+QVwkP0OC0jnUZ62D19iPgXOMO+tnWG+HhjNQ==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/type" "^3.0.1"
     ansi-escapes "^4.3.2"
 
-"@inquirer/prompts@7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-7.0.0.tgz#7c8137ae4a99d67bba83762bc22eee24c44155bb"
-  integrity sha512-y8kX/TmyBqV0H1i3cWbhiTljcuBtgVgyVXAVub3ba1j5/G+dxhYohK1JLRkaosPGKKf3LnEJsYK+GPabpfnaHw==
-  dependencies:
-    "@inquirer/checkbox" "^4.0.0"
-    "@inquirer/confirm" "^5.0.0"
-    "@inquirer/editor" "^4.0.0"
-    "@inquirer/expand" "^4.0.0"
-    "@inquirer/input" "^4.0.0"
-    "@inquirer/number" "^3.0.0"
-    "@inquirer/password" "^4.0.0"
-    "@inquirer/rawlist" "^4.0.0"
-    "@inquirer/search" "^3.0.0"
-    "@inquirer/select" "^4.0.0"
-
-"@inquirer/rawlist@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-4.0.0.tgz#144c16e4387598ac90c78236e0803e79850099a4"
-  integrity sha512-frzJNoMsQBO1fxLXrtpxt2c8hUy/ASEmBpIOEnXY2CjylPnLsVyxrEq7hcOIqVJKHn1tIPfplfiSPowOTrrUDg==
+"@inquirer/prompts@7.1.0":
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-7.1.0.tgz#a55ee589c0eed0ca2ee0fbc7fc63f42f4c31a24e"
+  integrity sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==
+  dependencies:
+    "@inquirer/checkbox" "^4.0.2"
+    "@inquirer/confirm" "^5.0.2"
+    "@inquirer/editor" "^4.1.0"
+    "@inquirer/expand" "^4.0.2"
+    "@inquirer/input" "^4.0.2"
+    "@inquirer/number" "^3.0.2"
+    "@inquirer/password" "^4.0.2"
+    "@inquirer/rawlist" "^4.0.2"
+    "@inquirer/search" "^3.0.2"
+    "@inquirer/select" "^4.0.2"
+
+"@inquirer/rawlist@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-4.0.2.tgz#78a58294505bed2a5e133153340f187967916702"
+  integrity sha512-3XGcskMoVF8H0Dl1S5TSZ3rMPPBWXRcM0VeNVsS4ByWeWjSeb0lPqfnBg6N7T0608I1B2bSVnbi2cwCrmOD1Yw==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/type" "^3.0.1"
     yoctocolors-cjs "^2.1.2"
 
-"@inquirer/search@^3.0.0":
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-3.0.0.tgz#a5a649349b2c38f06acbbfc92f15197adbfe75db"
-  integrity sha512-AT9vkC2KD/PLHZZXIW5Tn/FnJzEU3xEZMLxNo9OggKoreDEKfTOKVM1LkYbDg6UQUOOjntXd0SsrvoHfCzS8cw==
+"@inquirer/search@^3.0.2":
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-3.0.2.tgz#71fccc766045f2ec37afc402d72ce31838768281"
+  integrity sha512-Zv4FC7w4dJ13BOJfKRQCICQfShinGjb1bCEIHxTSnjj2telu3+3RHwHubPG9HyD4aix5s+lyAMEK/wSFD75HLA==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/figures" "^1.0.7"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/figures" "^1.0.8"
+    "@inquirer/type" "^3.0.1"
     yoctocolors-cjs "^2.1.2"
 
-"@inquirer/select@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-4.0.0.tgz#6b795e288319d9f3e3c471ac79b13f44592c3257"
-  integrity sha512-XTN4AIFusWbNCBU1Xm2YDxbtH94e/FOrC27U3QargSsoDT1mRm+aLfqE+oOZnUuxwtTnInRT8UHRU3MVOu52wg==
+"@inquirer/select@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-4.0.2.tgz#c38ef154524a6859de4a1af11a90ad3f9638c9f2"
+  integrity sha512-uSWUzaSYAEj0hlzxa1mUB6VqrKaYx0QxGBLZzU4xWFxaSyGaXxsSE4OSOwdU24j0xl8OajgayqFXW0l2bkl2kg==
   dependencies:
-    "@inquirer/core" "^10.0.0"
-    "@inquirer/figures" "^1.0.7"
-    "@inquirer/type" "^3.0.0"
+    "@inquirer/core" "^10.1.0"
+    "@inquirer/figures" "^1.0.8"
+    "@inquirer/type" "^3.0.1"
     ansi-escapes "^4.3.2"
     yoctocolors-cjs "^2.1.2"
 
@@ -2516,10 +2404,10 @@
   dependencies:
     mute-stream "^1.0.0"
 
-"@inquirer/type@^3.0.0":
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.0.tgz#1762ebe667ec1d838012b20bf0cf90b841ba68bc"
-  integrity sha512-YYykfbw/lefC7yKj7nanzQXILM7r3suIvyFlCcMskc99axmsSewXWkAfXKwMbgxL76iAFVmRwmYdwNZNc8gjog==
+"@inquirer/type@^3.0.1":
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.1.tgz#619ce9f65c3e114d8e39c41822bed3440d20b478"
+  integrity sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==
 
 "@isaacs/cliui@^8.0.2":
   version "8.0.2"
@@ -2628,10 +2516,10 @@
   resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1"
   integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==
 
-"@listr2/prompt-adapter-inquirer@2.0.17":
-  version "2.0.17"
-  resolved "https://registry.yarnpkg.com/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.17.tgz#6222dc55700db8a584af726ba980b20cd2040c62"
-  integrity sha512-RqeiaslWDOP6d5QqQdg+PxB3sC5QBTnti84LEzYtxRsQlHf5+IzFiJOhrnHIxuaEwtbtlU8pugIcc6e6lrobkQ==
+"@listr2/prompt-adapter-inquirer@2.0.18":
+  version "2.0.18"
+  resolved "https://registry.yarnpkg.com/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz#f1bff90f201269914023b17cb383c8febd6287f2"
+  integrity sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==
   dependencies:
     "@inquirer/type" "^1.5.5"
 
@@ -2647,60 +2535,60 @@
   resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.0.11.tgz#8b0034d9f9a5c859f629a5c1e760bf43258e9e6c"
   integrity sha512-7rO1BiJDWy0WEHDknVSuROMmBHD0Vh5KsgQojN8ulNbOJf0f3KsjoVB3HDPlVO3n75hTjxGn0rG19im28H3DVQ==
 
-"@lmdb/lmdb-darwin-arm64@3.1.3":
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.1.3.tgz#c66fa459c6a67ca3e91e70af813295b01f449681"
-  integrity sha512-VV667lP23gIsQkb80rnQwAHjj6F1uZp30qTnvLSlep3pOomzXcQBMFp4ZmJLeGJnnPy54JjNsYBFyg9X95wCPw==
+"@lmdb/lmdb-darwin-arm64@3.1.5":
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.1.5.tgz#72d229714c0eb66ce0b235bea1ff62f68e762407"
+  integrity sha512-ue5PSOzHMCIYrfvPP/MRS6hsKKLzqqhcdAvJCO8uFlDdj598EhgnacuOTuqA6uBK5rgiZXfDWyb7DVZSiBKxBA==
 
 "@lmdb/lmdb-darwin-x64@3.0.11":
   version "3.0.11"
   resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.0.11.tgz#e7290bec89c21d94ae501f014d12ac24ae8283a5"
   integrity sha512-rqkwNYEqQ6BR51ffHasIMh/8+slTPf1kfoAdreLDsUkpAJ/hntW0QP9eMC9eOwRjfuOURdlgGLeCaaCpDTxMCQ==
 
-"@lmdb/lmdb-darwin-x64@3.1.3":
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.1.3.tgz#8d2389c9718cd33d807517f039bab8f7b18db04c"
-  integrity sha512-kuhKKJxGCQr9gBtUd7cVBBn6OtwQg7vIiD5gHEZb+jWLJulg6N4uPSLTab8W9tvpb3ryRTAejMt7F89/2MoRrQ==
+"@lmdb/lmdb-darwin-x64@3.1.5":
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.1.5.tgz#e9fa7e7e915cca533e9cec79d68c0309e49594d2"
+  integrity sha512-CGhsb0R5vE6mMNCoSfxHFD8QTvBHM51gs4DBeigTYHWnYv2V5YpJkC4rMo5qAAFifuUcc0+a8a3SIU0c9NrfNw==
 
 "@lmdb/lmdb-linux-arm64@3.0.11":
   version "3.0.11"
   resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.0.11.tgz#399299cc2f4f97c78666f2c5273842c77847f2c2"
   integrity sha512-P5d7Uj297g2tlKsvDZDqZNEZ3mw0npTrQuizPS63tXV1VGz/bHMuqL1/NWmJqAtVSPZdhQe0DD/sbBai7Ra6UA==
 
-"@lmdb/lmdb-linux-arm64@3.1.3":
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.1.3.tgz#6d2adf765d1dfa1aebed00b67f47a72531cf217c"
-  integrity sha512-XnSHGKsJ1Fr5LBjyDkG7JnVJlduhg7AhV1J6YQujStsKnehuiidsNW0InEJrAO4QMHqquwnCfLvU9PPJfpFVYw==
+"@lmdb/lmdb-linux-arm64@3.1.5":
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.1.5.tgz#ca7ff0df918edb65c91330e16e81076cd85edaff"
+  integrity sha512-LAjaoOcBHGj6fiYB8ureiqPoph4eygbXu4vcOF+hsxiY74n8ilA7rJMmGUT0K0JOB5lmRQHSmor3mytRjS4qeQ==
 
 "@lmdb/lmdb-linux-arm@3.0.11":
   version "3.0.11"
   resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.0.11.tgz#943db4a560115bbb96b77be564d128c41898e193"
   integrity sha512-uGR/sHB5p5d5dzP2+sbrf42++qw8PQbB6CqgHMBfZcXTUWz+A84XWWbl9UMg+6XY11mBHKUpzhswbHnpmE3iAg==
 
-"@lmdb/lmdb-linux-arm@3.1.3":
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.1.3.tgz#9c972e3e8b04cd220fba56603b37818f96329d41"
-  integrity sha512-R0CkYoJPHUfxPe2LaAqMGwTf5+1eXchUMNISO8OKEvKkS/zg2emIYTOb29v1k8WGSmdJkgQneBav/W3h5NorzA==
+"@lmdb/lmdb-linux-arm@3.1.5":
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.1.5.tgz#94dbd35ce8faa0810b6e7babbfb4f505bd80b2a3"
+  integrity sha512-3WeW328DN+xB5PZdhSWmqE+t3+44xWXEbqQ+caWJEZfOFdLp9yklBZEbVqVdqzznkoaXJYxTCp996KD6HmANeg==
 
 "@lmdb/lmdb-linux-x64@3.0.11":
   version "3.0.11"
   resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.0.11.tgz#ec5e071a157f185c2920ce99769dbf5a2fffe8f1"
   integrity sha512-xiO21qpfu/cu1Pcf/2+l2eG/96wFTzgPa25/qQ/VdvlrnKfYhtDzBo06lmfa6xrEzQZJ/kdFzwHZuafCDE58iA==
 
-"@lmdb/lmdb-linux-x64@3.1.3":
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.1.3.tgz#1c40f6325c65f7a72f01553436c4692bdb1fe727"
-  integrity sha512-epvFL9/Tem00evtuq05kqWbRppJ4G/D8wa6LnQmOu779VmbrY6+M3v3h4fnt2QqMQt3+J6Cg/gZACDlDcH+eUw==
+"@lmdb/lmdb-linux-x64@3.1.5":
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.1.5.tgz#0aa94acf4ef029690569119c1f811bebe9d3d8f9"
+  integrity sha512-k/IklElP70qdCXOQixclSl2GPLFiopynGoKX1FqDd1/H0E3Fo1oPwjY2rEVu+0nS3AOw1sryStdXk8CW3cVIsw==
 
 "@lmdb/lmdb-win32-x64@3.0.11":
   version "3.0.11"
   resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.11.tgz#76fdd3338a5f55e778f3c9121cce2cacf87b48a6"
   integrity sha512-tjlzuLdmTlsWVdj7Wso/p3wJtLMqznkeGEELRMjRQCgas8mONBuwmk9jFO30Di86z4QxL1agZvugUrPMCm/iDw==
 
-"@lmdb/lmdb-win32-x64@3.1.3":
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.1.3.tgz#9e5d354d845add483aa1831752663d2d879ce726"
-  integrity sha512-S6P96biJyrt/CUYSP0v4OH1U9ITzHhHCh1kn7hHOscS3S1+T/D74sCJKQ9xb/Raos2NJHqtZ8EyQVEVjOzmqbg==
+"@lmdb/lmdb-win32-x64@3.1.5":
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.1.5.tgz#d748edd97f62cace4f716395cc1b8807616ecdae"
+  integrity sha512-KYar6W8nraZfSJspcK7Kp7hdj238X/FNauYbZyrqPBrtsXI1hvI4/KcRcRGP50aQoV7fkKDyJERlrQGMGTZUsA==
 
 "@material/material-color-utilities@^0.3.0":
   version "0.3.0"
@@ -2925,10 +2813,10 @@
     "@napi-rs/nice-win32-ia32-msvc" "1.0.1"
     "@napi-rs/nice-win32-x64-msvc" "1.0.1"
 
-"@ngtools/webpack@19.0.0-next.11":
-  version "19.0.0-next.11"
-  resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-19.0.0-next.11.tgz#db1c98d707ba6ad47744424ba71c051f13804960"
-  integrity sha512-FsWp25WqpCXPBkiZI2+WNTvLekYD5XOgT7xczfoCtIe0y4GT7xcuRZPgStQKyS85kBnwq6kUqnWW/WN8+Qz2Mg==
+"@ngtools/webpack@19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-19.0.0.tgz#0ea7824e5268fcd10d5183f6f076a19186c1a5b0"
+  integrity sha512-UuLK1P184R12l6obaVzGk5yzCMQNwfahlkhNapbntvvFw27O76nEYVFM5y8tPkhC3XrsH4v6Ag21q+WADkR9jQ==
 
 "@nodelib/fs.scandir@2.1.5":
   version "2.1.5"
@@ -3369,10 +3257,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.1.tgz#c3a7938551273a2b72820cf5d22e54cf41dc206e"
   integrity sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==
 
-"@rollup/rollup-android-arm-eabi@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54"
-  integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==
+"@rollup/rollup-android-arm-eabi@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz#f221c519a6efb5d3652bff32351522e0fb98e392"
+  integrity sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==
 
 "@rollup/rollup-android-arm64@4.18.0":
   version "4.18.0"
@@ -3384,10 +3272,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.1.tgz#fa3693e4674027702c42fcbbb86bbd0c635fd3b9"
   integrity sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==
 
-"@rollup/rollup-android-arm64@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e"
-  integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==
+"@rollup/rollup-android-arm64@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz#196a2379d81011422fe1128e512a8811605ede16"
+  integrity sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==
 
 "@rollup/rollup-darwin-arm64@4.18.0":
   version "4.18.0"
@@ -3399,10 +3287,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.1.tgz#e19922f4ac1e4552a230ff8f49d5688c5c07d284"
   integrity sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==
 
-"@rollup/rollup-darwin-arm64@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz#627007221b24b8cc3063703eee0b9177edf49c1f"
-  integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==
+"@rollup/rollup-darwin-arm64@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz#0c83e5f25adae7f0543ac29a0ebd485a0e7cd3e4"
+  integrity sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==
 
 "@rollup/rollup-darwin-x64@4.18.0":
   version "4.18.0"
@@ -3414,10 +3302,20 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.1.tgz#897f8d47b115ea84692a29cf2366899499d4d915"
   integrity sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==
 
-"@rollup/rollup-darwin-x64@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724"
-  integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==
+"@rollup/rollup-darwin-x64@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz#8131b174ca8cec04e2041e42eb8382afe31095c8"
+  integrity sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==
+
+"@rollup/rollup-freebsd-arm64@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz#550a0ebf5bea6ceee79dc2f75a0bcef7d660de2c"
+  integrity sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==
+
+"@rollup/rollup-freebsd-x64@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz#51ca2e6d9ce72e63d5201607651732e5300a6f81"
+  integrity sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==
 
 "@rollup/rollup-linux-arm-gnueabihf@4.18.0":
   version "4.18.0"
@@ -3429,10 +3327,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.1.tgz#7d1e2a542f3a5744f5c24320067bd5af99ec9d62"
   integrity sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==
 
-"@rollup/rollup-linux-arm-gnueabihf@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb"
-  integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==
+"@rollup/rollup-linux-arm-gnueabihf@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz#ae71d6aa81e702c4efb72c1a67a6a4e790267a1b"
+  integrity sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==
 
 "@rollup/rollup-linux-arm-musleabihf@4.18.0":
   version "4.18.0"
@@ -3444,10 +3342,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.1.tgz#88bec1c9df85fc5e24d49f783e19934717dd69b5"
   integrity sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==
 
-"@rollup/rollup-linux-arm-musleabihf@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3"
-  integrity sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==
+"@rollup/rollup-linux-arm-musleabihf@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz#6aa7baa5c39c095fa5f9804e283e126697e0342a"
+  integrity sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==
 
 "@rollup/rollup-linux-arm64-gnu@4.18.0":
   version "4.18.0"
@@ -3459,10 +3357,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz#6dc60f0fe7bd49ed07a2d4d9eab15e671b3bd59d"
   integrity sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==
 
-"@rollup/rollup-linux-arm64-gnu@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496"
-  integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==
+"@rollup/rollup-linux-arm64-gnu@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz#2b06e147ca68c7729ca38e5c7a514d1b00f4d151"
+  integrity sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==
 
 "@rollup/rollup-linux-arm64-musl@4.18.0":
   version "4.18.0"
@@ -3474,10 +3372,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.1.tgz#a03b78775c129e8333aca9e1e420e8e217ee99b9"
   integrity sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==
 
-"@rollup/rollup-linux-arm64-musl@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065"
-  integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==
+"@rollup/rollup-linux-arm64-musl@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz#70f8cacb255800e4cad41bdbe447432354288909"
+  integrity sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==
 
 "@rollup/rollup-linux-powerpc64le-gnu@4.18.0":
   version "4.18.0"
@@ -3489,10 +3387,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.1.tgz#ee3810647faf2c105a5a4e71260bb90b96bf87bc"
   integrity sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==
 
-"@rollup/rollup-linux-powerpc64le-gnu@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d"
-  integrity sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==
+"@rollup/rollup-linux-powerpc64le-gnu@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz#21aed3ef42518b7fe33f4037a14b0939a071cf75"
+  integrity sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==
 
 "@rollup/rollup-linux-riscv64-gnu@4.18.0":
   version "4.18.0"
@@ -3504,10 +3402,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.1.tgz#385d76a088c27db8054d9f3f28d64d89294f838e"
   integrity sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==
 
-"@rollup/rollup-linux-riscv64-gnu@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983"
-  integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==
+"@rollup/rollup-linux-riscv64-gnu@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz#fe27eb8cbd3a6e0706459781c2463b624f785696"
+  integrity sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==
 
 "@rollup/rollup-linux-s390x-gnu@4.18.0":
   version "4.18.0"
@@ -3519,10 +3417,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.1.tgz#daa2b62a6e6f737ebef6700a12a93c9764e18583"
   integrity sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==
 
-"@rollup/rollup-linux-s390x-gnu@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58"
-  integrity sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==
+"@rollup/rollup-linux-s390x-gnu@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz#80289a528dd333b0e277efd93bfa8e2cdd27e5eb"
+  integrity sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==
 
 "@rollup/rollup-linux-x64-gnu@4.18.0":
   version "4.18.0"
@@ -3534,10 +3432,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.1.tgz#790ae96118cc892464e9f10da358c0c8a6b9acdd"
   integrity sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==
 
-"@rollup/rollup-linux-x64-gnu@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b"
-  integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==
+"@rollup/rollup-linux-x64-gnu@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz#9909570be5cb738c23858c94308d37dde363eb7e"
+  integrity sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==
 
 "@rollup/rollup-linux-x64-musl@4.18.0":
   version "4.18.0"
@@ -3549,10 +3447,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.1.tgz#d613147f7ac15fafe2a0b6249e8484e161ca2847"
   integrity sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==
 
-"@rollup/rollup-linux-x64-musl@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127"
-  integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==
+"@rollup/rollup-linux-x64-musl@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz#371315e032497f7a46f64b4ebcd207313b7f6669"
+  integrity sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==
 
 "@rollup/rollup-win32-arm64-msvc@4.18.0":
   version "4.18.0"
@@ -3564,10 +3462,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.1.tgz#18349db8250559a5460d59eb3575f9781be4ab98"
   integrity sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==
 
-"@rollup/rollup-win32-arm64-msvc@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5"
-  integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==
+"@rollup/rollup-win32-arm64-msvc@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz#f4b4e0747710ba287eb2e2a011538ee2ed7f74d3"
+  integrity sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==
 
 "@rollup/rollup-win32-ia32-msvc@4.18.0":
   version "4.18.0"
@@ -3579,10 +3477,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.1.tgz#199648b68271f7ab9d023f5c077725d51d12d466"
   integrity sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==
 
-"@rollup/rollup-win32-ia32-msvc@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2"
-  integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==
+"@rollup/rollup-win32-ia32-msvc@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz#2eeabbc99342dafe04613a76c441be4ebcca49c3"
+  integrity sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==
 
 "@rollup/rollup-win32-x64-msvc@4.18.0":
   version "4.18.0"
@@ -3594,10 +3492,10 @@
   resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz#4d3ec02dbf280c20bfeac7e50cd5669b66f9108f"
   integrity sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==
 
-"@rollup/rollup-win32-x64-msvc@4.24.0":
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818"
-  integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==
+"@rollup/rollup-win32-x64-msvc@4.26.0":
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz#a3ae3da434a4ba0785312e963ae4c1239470403a"
+  integrity sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==
 
 "@rushstack/node-core-library@4.3.0":
   version "4.3.0"
@@ -3669,13 +3567,13 @@
     argparse "~1.0.9"
     string-argv "~0.3.1"
 
-"@schematics/angular@19.0.0-next.11", "@schematics/angular@^19.0.0-next.10":
-  version "19.0.0-next.11"
-  resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-19.0.0-next.11.tgz#19a8d9169f6ead0ba296928134de0c15d3107be1"
-  integrity sha512-U6Po5TQ7vp24dmTvoOb6R2uWvCbAE2DdPF7E0ZWVlSINPCfwPsxarKtGpZV+02G/nSgNreuQ7dJAeFDDwSMAIw==
+"@schematics/angular@19.0.0", "@schematics/angular@^19.0.0":
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-19.0.0.tgz#842a6112d16e87e76e22424419f71c047fc73560"
+  integrity sha512-2U8dlhURoQfS99ZF67RVeARFeJn4Z0Lg2dfYbGj+ooRH5YMtAZq8zAIRCfyC3OMiJEZM6BbGigCD6gNoAhP0RQ==
   dependencies:
-    "@angular-devkit/core" "19.0.0-next.11"
-    "@angular-devkit/schematics" "19.0.0-next.11"
+    "@angular-devkit/core" "19.0.0"
+    "@angular-devkit/schematics" "19.0.0"
     jsonc-parser "3.3.1"
 
 "@sigstore/bundle@^3.0.0":
@@ -3920,7 +3818,23 @@
   dependencies:
     "@types/node" "*"
 
-"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.5":
+"@types/eslint-scope@^3.7.7":
+  version "3.7.7"
+  resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5"
+  integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==
+  dependencies:
+    "@types/eslint" "*"
+    "@types/estree" "*"
+
+"@types/eslint@*":
+  version "9.6.1"
+  resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584"
+  integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==
+  dependencies:
+    "@types/estree" "*"
+    "@types/json-schema" "*"
+
+"@types/estree@*", "@types/estree@1.0.5":
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
   integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
@@ -3930,7 +3844,7 @@
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
   integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
 
-"@types/estree@1.0.6":
+"@types/estree@1.0.6", "@types/estree@^1.0.6":
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
   integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
@@ -4014,7 +3928,7 @@
   resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-4.6.4.tgz#76350389d51412047934992bacc40750c69d82a8"
   integrity sha512-qCw5sVW+ylTnrEhe5kfX4l6MgU9REXIVDa/lWEcvTOUmd+LqDYwyjovDq+Zk9blElaEHOj1URDQ/djEBVRf+pw==
 
-"@types/json-schema@^7.0.6", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
+"@types/json-schema@*", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
   version "7.0.15"
   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
   integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
@@ -4328,10 +4242,10 @@
   dependencies:
     "@types/node" "*"
 
-"@types/youtube@^0.0.50":
-  version "0.0.50"
-  resolved "https://registry.yarnpkg.com/@types/youtube/-/youtube-0.0.50.tgz#c28cefde8e3f17ac3564bd83952eacf806d96eea"
-  integrity sha512-d4GpH4uPYp9W07kc487tiq6V/EUHl18vZWFMbQoe4Sk9LXEWzFi/BMf9x7TI4m7/j7gU3KeX8H6M8aPBgykeLw==
+"@types/youtube@^0.1.0":
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/@types/youtube/-/youtube-0.1.0.tgz#0e116bd0a8ddb93daf1372fb5e07f576cf9fe5cc"
+  integrity sha512-Pg33m3X2mFgdmhtvzOlAfUfgOa3341N3/2JCrVY/mXVxb4hagcqqEG6w4vGCfB64StQNWHSj/T8Eotb1Rko/FQ==
 
 "@typescript-eslint/types@4.33.0":
   version "4.33.0"
@@ -4586,11 +4500,6 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
     mime-types "~2.1.34"
     negotiator "0.6.3"
 
-acorn-import-attributes@^1.9.5:
-  version "1.9.5"
-  resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef"
-  integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==
-
 acorn-jsx@^5.3.1:
   version "5.3.2"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -4608,11 +4517,16 @@ acorn@^7.4.0:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
   integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
 
-acorn@^8.11.0, acorn@^8.4.1, acorn@^8.7.0, acorn@^8.7.1, acorn@^8.8.2:
+acorn@^8.11.0, acorn@^8.4.1, acorn@^8.7.0, acorn@^8.8.2:
   version "8.12.0"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.0.tgz#1627bfa2e058148036133b8d9b51a700663c294c"
   integrity sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==
 
+acorn@^8.14.0:
+  version "8.14.0"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0"
+  integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
+
 adjust-sourcemap-loader@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99"
@@ -5238,6 +5152,20 @@ bcrypt-pbkdf@^1.0.0:
   dependencies:
     tweetnacl "^0.14.3"
 
+beasties@0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/beasties/-/beasties-0.1.0.tgz#f8f8ba22ff79c86f4dcebe50527cefdf9f0d52c4"
+  integrity sha512-+Ssscd2gVG24qRNC+E2g88D+xsQW4xwakWtKAiGEQ3Pw54/FGdyo9RrfxhGhEv6ilFVbB7r3Lgx+QnAxnSpECw==
+  dependencies:
+    css-select "^5.1.0"
+    css-what "^6.1.0"
+    dom-serializer "^2.0.0"
+    domhandler "^5.0.3"
+    htmlparser2 "^9.0.0"
+    picocolors "^1.1.1"
+    postcss "^8.4.47"
+    postcss-media-query-parser "^0.2.3"
+
 before-after-hook@^2.2.0:
   version "2.2.3"
   resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c"
@@ -5555,7 +5483,7 @@ browser-sync@^3.0.0:
     ua-parser-js "^1.0.33"
     yargs "^17.3.1"
 
-browserslist@^4.21.10, browserslist@^4.21.5, browserslist@^4.22.2, browserslist@^4.23.0:
+browserslist@^4.21.5, browserslist@^4.22.2, browserslist@^4.23.0:
   version "4.23.1"
   resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.1.tgz#ce4af0534b3d37db5c1a4ca98b9080f985041e96"
   integrity sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==
@@ -5565,16 +5493,6 @@ browserslist@^4.21.10, browserslist@^4.21.5, browserslist@^4.22.2, browserslist@
     node-releases "^2.0.14"
     update-browserslist-db "^1.0.16"
 
-browserslist@^4.23.1:
-  version "4.23.2"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.2.tgz#244fe803641f1c19c28c48c4b6ec9736eb3d32ed"
-  integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==
-  dependencies:
-    caniuse-lite "^1.0.30001640"
-    electron-to-chromium "^1.4.820"
-    node-releases "^2.0.14"
-    update-browserslist-db "^1.1.0"
-
 browserslist@^4.23.3:
   version "4.23.3"
   resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800"
@@ -5878,11 +5796,6 @@ caniuse-lite@^1.0.30001599, caniuse-lite@^1.0.30001629:
   resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz#b15f52d2bdb95fad32c2f53c0b68032b85188a78"
   integrity sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==
 
-caniuse-lite@^1.0.30001640:
-  version "1.0.30001645"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001645.tgz#4c4b7427683dea1170a152cd1654be8d0da7bd71"
-  integrity sha512-GFtY2+qt91kzyMk6j48dJcwJVq5uTkk71XxE3RtScx7XWRLsO7bU44LOFkOZYR8w9YMS0UhPSYpN/6rAMImmLw==
-
 caniuse-lite@^1.0.30001646:
   version "1.0.30001653"
   resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz#b8af452f8f33b1c77f122780a4aecebea0caca56"
@@ -6642,19 +6555,6 @@ critters@0.0.22:
     postcss "^8.4.23"
     postcss-media-query-parser "^0.2.3"
 
-critters@0.0.25:
-  version "0.0.25"
-  resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.25.tgz#8568e6add4a8f68d0b1dbe0c4839286947b37888"
-  integrity sha512-ROF/tjJyyRdM8/6W0VqoN5Ql05xAGnkf5b7f3sTEl1bI5jTQQf8O918RD/V9tEb9pRY/TKcvJekDbJtniHyPtQ==
-  dependencies:
-    chalk "^4.1.0"
-    css-select "^5.1.0"
-    dom-serializer "^2.0.0"
-    domhandler "^5.0.2"
-    htmlparser2 "^8.0.2"
-    postcss "^8.4.23"
-    postcss-media-query-parser "^0.2.3"
-
 cross-env@^5.1.3:
   version "5.2.1"
   resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d"
@@ -7365,7 +7265,7 @@ domutils@^1.5.1:
     dom-serializer "0"
     domelementtype "1"
 
-domutils@^3.0.1:
+domutils@^3.0.1, domutils@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
   integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
@@ -7500,11 +7400,6 @@ electron-to-chromium@^1.4.796:
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.808.tgz#85b2f93a5e32c2949a1a4d39375851945c936835"
   integrity sha512-0ItWyhPYnww2VOuCGF4s1LTfbrdAV2ajy/TN+ZTuhR23AHI6rWHCrBXJ/uxoXOvRRqw8qjYVrG81HFI7x/2wdQ==
 
-electron-to-chromium@^1.4.820:
-  version "1.5.4"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz#cd477c830dd6fca41fbd5465c1ff6ce08ac22343"
-  integrity sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==
-
 electron-to-chromium@^1.5.28:
   version "1.5.40"
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.40.tgz#5f6aec13751123c5c3185999ebe3e7bcaf828c2b"
@@ -7654,7 +7549,7 @@ entities@^2.0.0:
   resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
   integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
 
-entities@^4.2.0, entities@^4.3.0, entities@^4.4.0:
+entities@^4.2.0, entities@^4.3.0, entities@^4.4.0, entities@^4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
   integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
@@ -9624,6 +9519,16 @@ htmlparser2@^8.0.2:
     domutils "^3.0.1"
     entities "^4.4.0"
 
+htmlparser2@^9.0.0:
+  version "9.1.0"
+  resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23"
+  integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==
+  dependencies:
+    domelementtype "^2.3.0"
+    domhandler "^5.0.3"
+    domutils "^3.1.0"
+    entities "^4.5.0"
+
 http-cache-semantics@3.8.1:
   version "3.8.1"
   resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
@@ -9816,6 +9721,11 @@ immutable@^4.0.0:
   resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.6.tgz#6a05f7858213238e587fb83586ffa3b4b27f0447"
   integrity sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==
 
+immutable@^5.0.2:
+  version "5.0.3"
+  resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.0.3.tgz#aa037e2313ea7b5d400cd9298fa14e404c933db1"
+  integrity sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==
+
 import-fresh@^3.2.1, import-fresh@^3.3.0:
   version "3.3.0"
   resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
@@ -11042,23 +10952,23 @@ lmdb@3.0.11:
     "@lmdb/lmdb-linux-x64" "3.0.11"
     "@lmdb/lmdb-win32-x64" "3.0.11"
 
-lmdb@3.1.3:
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-3.1.3.tgz#3eeb892a693d70886edb0e2896625f5a2f5570cf"
-  integrity sha512-WQcfSoOTw+XfBXQN4dRN1Ke5vv+NgmOWs4wH8oh4jYFmPZIaVPiQVF+0nGdjQDLGDcrMMyr2C34cG6WZPes6xQ==
+lmdb@3.1.5:
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-3.1.5.tgz#3e6c2f4e765a2a61cc10e08477e0a267e423183f"
+  integrity sha512-46Mch5Drq+A93Ss3gtbg+Xuvf5BOgIuvhKDWoGa3HcPHI6BL2NCOkRdSx1D4VfzwrxhnsjbyIVsLRlQHu6URvw==
   dependencies:
-    msgpackr "^1.10.2"
+    msgpackr "^1.11.2"
     node-addon-api "^6.1.0"
     node-gyp-build-optional-packages "5.2.2"
-    ordered-binary "^1.4.1"
+    ordered-binary "^1.5.3"
     weak-lru-cache "^1.2.2"
   optionalDependencies:
-    "@lmdb/lmdb-darwin-arm64" "3.1.3"
-    "@lmdb/lmdb-darwin-x64" "3.1.3"
-    "@lmdb/lmdb-linux-arm" "3.1.3"
-    "@lmdb/lmdb-linux-arm64" "3.1.3"
-    "@lmdb/lmdb-linux-x64" "3.1.3"
-    "@lmdb/lmdb-win32-x64" "3.1.3"
+    "@lmdb/lmdb-darwin-arm64" "3.1.5"
+    "@lmdb/lmdb-darwin-x64" "3.1.5"
+    "@lmdb/lmdb-linux-arm" "3.1.5"
+    "@lmdb/lmdb-linux-arm64" "3.1.5"
+    "@lmdb/lmdb-linux-x64" "3.1.5"
+    "@lmdb/lmdb-win32-x64" "3.1.5"
 
 loader-runner@^4.2.0:
   version "4.3.0"
@@ -11781,10 +11691,10 @@ min-indent@^1.0.0:
   resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
   integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
 
-mini-css-extract-plugin@2.9.1:
-  version "2.9.1"
-  resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz#4d184f12ce90582e983ccef0f6f9db637b4be758"
-  integrity sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ==
+mini-css-extract-plugin@2.9.2:
+  version "2.9.2"
+  resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz#966031b468917a5446f4c24a80854b2947503c5b"
+  integrity sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==
   dependencies:
     schema-utils "^4.0.0"
     tapable "^2.2.1"
@@ -12042,7 +11952,14 @@ msgpackr-extract@^3.0.2:
     "@msgpackr-extract/msgpackr-extract-linux-x64" "3.0.3"
     "@msgpackr-extract/msgpackr-extract-win32-x64" "3.0.3"
 
-msgpackr@^1.10.2, msgpackr@^1.9.9:
+msgpackr@^1.11.2:
+  version "1.11.2"
+  resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.11.2.tgz#4463b7f7d68f2e24865c395664973562ad24473d"
+  integrity sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==
+  optionalDependencies:
+    msgpackr-extract "^3.0.2"
+
+msgpackr@^1.9.9:
   version "1.10.2"
   resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.10.2.tgz#a73de4767f76659e8c69cf9c80fdfce83937a44a"
   integrity sha512-L60rsPynBvNE+8BWipKKZ9jHcSGbtyJYIwjRq0VrIvQ08cRjntGXJYW/tmciZ2IHWIY8WEW32Qa2xbh5+SKBZA==
@@ -12598,6 +12515,11 @@ ordered-binary@^1.4.1:
   resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.5.1.tgz#94ccbf14181711081ee23931db0dc3f58aaa0df6"
   integrity sha512-5VyHfHY3cd0iza71JepYG50My+YUbrFtGoUz2ooEydPyPM7Aai/JW098juLr+RG6+rDJuzNNTsEQu2DZa1A41A==
 
+ordered-binary@^1.5.3:
+  version "1.5.3"
+  resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.5.3.tgz#8bee2aa7a82c3439caeb1e80c272fd4cf51170fb"
+  integrity sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==
+
 os-filter-obj@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/os-filter-obj/-/os-filter-obj-2.0.0.tgz#1c0b62d5f3a2442749a2d139e6dddee6e81d8d16"
@@ -12783,10 +12705,10 @@ package-json@^6.3.0:
     registry-url "^5.0.0"
     semver "^6.2.0"
 
-pacote@19.0.1:
-  version "19.0.1"
-  resolved "https://registry.yarnpkg.com/pacote/-/pacote-19.0.1.tgz#66d22dbd274ed8a7c30029d70eb8030f5151e6fc"
-  integrity sha512-zIpxWAsr/BvhrkSruspG8aqCQUUrWtpwx0GjiRZQhEM/pZXrigA32ElN3vTcCPUDOFmHr6SFxwYrvVUs5NTEUg==
+pacote@20.0.0:
+  version "20.0.0"
+  resolved "https://registry.yarnpkg.com/pacote/-/pacote-20.0.0.tgz#c974373d8e0859d00e8f9158574350f8c1b168e5"
+  integrity sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==
   dependencies:
     "@npmcli/git" "^6.0.0"
     "@npmcli/installed-package-contents" "^3.0.0"
@@ -13043,6 +12965,11 @@ picocolors@^1.1.0:
   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59"
   integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==
 
+picocolors@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+  integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
 picomatch@4.0.2:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
@@ -13217,13 +13144,13 @@ postcss-values-parser@^2.0.1:
     indexes-of "^1.0.1"
     uniq "^1.0.1"
 
-postcss@8.4.47:
-  version "8.4.47"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365"
-  integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
+postcss@8.4.49:
+  version "8.4.49"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19"
+  integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==
   dependencies:
     nanoid "^3.3.7"
-    picocolors "^1.1.0"
+    picocolors "^1.1.1"
     source-map-js "^1.2.1"
 
 postcss@^8.1.7, postcss@^8.2.14, postcss@^8.4.17, postcss@^8.4.19, postcss@^8.4.23, postcss@^8.4.33, postcss@^8.4.38:
@@ -13244,6 +13171,15 @@ postcss@^8.4.43:
     picocolors "^1.0.1"
     source-map-js "^1.2.0"
 
+postcss@^8.4.47:
+  version "8.4.47"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365"
+  integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
+  dependencies:
+    nanoid "^3.3.7"
+    picocolors "^1.1.0"
+    source-map-js "^1.2.1"
+
 preact-render-to-string@^6.2.1:
   version "6.5.5"
   resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-6.5.5.tgz#831dc3b343320d2d38c23d9cea0d7530d262f948"
@@ -14205,29 +14141,31 @@ rollup-plugin-sourcemaps@^0.6.3:
     "@rollup/pluginutils" "^3.0.9"
     source-map-resolve "^0.6.0"
 
-rollup@4.24.0:
-  version "4.24.0"
-  resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.0.tgz#c14a3576f20622ea6a5c9cad7caca5e6e9555d05"
-  integrity sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==
+rollup@4.26.0:
+  version "4.26.0"
+  resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.26.0.tgz#a3e5fb29d50953633a2fd4506da6448d93268944"
+  integrity sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==
   dependencies:
     "@types/estree" "1.0.6"
   optionalDependencies:
-    "@rollup/rollup-android-arm-eabi" "4.24.0"
-    "@rollup/rollup-android-arm64" "4.24.0"
-    "@rollup/rollup-darwin-arm64" "4.24.0"
-    "@rollup/rollup-darwin-x64" "4.24.0"
-    "@rollup/rollup-linux-arm-gnueabihf" "4.24.0"
-    "@rollup/rollup-linux-arm-musleabihf" "4.24.0"
-    "@rollup/rollup-linux-arm64-gnu" "4.24.0"
-    "@rollup/rollup-linux-arm64-musl" "4.24.0"
-    "@rollup/rollup-linux-powerpc64le-gnu" "4.24.0"
-    "@rollup/rollup-linux-riscv64-gnu" "4.24.0"
-    "@rollup/rollup-linux-s390x-gnu" "4.24.0"
-    "@rollup/rollup-linux-x64-gnu" "4.24.0"
-    "@rollup/rollup-linux-x64-musl" "4.24.0"
-    "@rollup/rollup-win32-arm64-msvc" "4.24.0"
-    "@rollup/rollup-win32-ia32-msvc" "4.24.0"
-    "@rollup/rollup-win32-x64-msvc" "4.24.0"
+    "@rollup/rollup-android-arm-eabi" "4.26.0"
+    "@rollup/rollup-android-arm64" "4.26.0"
+    "@rollup/rollup-darwin-arm64" "4.26.0"
+    "@rollup/rollup-darwin-x64" "4.26.0"
+    "@rollup/rollup-freebsd-arm64" "4.26.0"
+    "@rollup/rollup-freebsd-x64" "4.26.0"
+    "@rollup/rollup-linux-arm-gnueabihf" "4.26.0"
+    "@rollup/rollup-linux-arm-musleabihf" "4.26.0"
+    "@rollup/rollup-linux-arm64-gnu" "4.26.0"
+    "@rollup/rollup-linux-arm64-musl" "4.26.0"
+    "@rollup/rollup-linux-powerpc64le-gnu" "4.26.0"
+    "@rollup/rollup-linux-riscv64-gnu" "4.26.0"
+    "@rollup/rollup-linux-s390x-gnu" "4.26.0"
+    "@rollup/rollup-linux-x64-gnu" "4.26.0"
+    "@rollup/rollup-linux-x64-musl" "4.26.0"
+    "@rollup/rollup-win32-arm64-msvc" "4.26.0"
+    "@rollup/rollup-win32-ia32-msvc" "4.26.0"
+    "@rollup/rollup-win32-x64-msvc" "4.26.0"
     fsevents "~2.3.2"
 
 rollup@^2.66.1:
@@ -14400,10 +14338,10 @@ safe-stable-stringify@^2.3.1:
   resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
   integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
 
-sass-loader@16.0.2:
-  version "16.0.2"
-  resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-16.0.2.tgz#e581bc13d7cb5090e27f155c6aa2855c08cafe86"
-  integrity sha512-Ll6iXZ1EYwYT19SqW4mSBb76vSSi8JgzElmzIerhEGgzB5hRjDQIWsPmuk1UrAXkR16KJHqVY0eH+5/uw9Tmfw==
+sass-loader@16.0.3:
+  version "16.0.3"
+  resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-16.0.3.tgz#17b944fab6702dc7a52c5d2a88cbfa38c39cdc75"
+  integrity sha512-gosNorT1RCkuCMyihv6FBRR7BMV06oKRAs+l4UMp1mlcVg9rWN6KMmUj3igjQwmYys4mDP3etEYJgiHRbgHCHA==
   dependencies:
     neo-async "^2.6.2"
 
@@ -14423,24 +14361,27 @@ sass@1.77.2:
     immutable "^4.0.0"
     source-map-js ">=0.6.2 <2.0.0"
 
-sass@1.79.5:
-  version "1.79.5"
-  resolved "https://registry.yarnpkg.com/sass/-/sass-1.79.5.tgz#646c627601cd5f84c64f7b1485b9292a313efae4"
-  integrity sha512-W1h5kp6bdhqFh2tk3DsI771MoEJjvrSY/2ihJRJS4pjIyfJCw0nTsxqhnrUzaLMOJjFchj8rOvraI/YUVjtx5g==
+sass@1.80.7:
+  version "1.80.7"
+  resolved "https://registry.yarnpkg.com/sass/-/sass-1.80.7.tgz#7569334c39220f8ca62fcea38dce60f809ba345c"
+  integrity sha512-MVWvN0u5meytrSjsU7AWsbhoXi1sc58zADXFllfZzbsBT1GHjjar6JwBINYPRrkx/zqnQ6uqbQuHgE95O+C+eQ==
   dependencies:
-    "@parcel/watcher" "^2.4.1"
     chokidar "^4.0.0"
-    immutable "^4.0.0"
+    immutable "^5.0.2"
     source-map-js ">=0.6.2 <2.0.0"
+  optionalDependencies:
+    "@parcel/watcher" "^2.4.1"
 
-sass@^1.77.8:
-  version "1.77.8"
-  resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.8.tgz#9f18b449ea401759ef7ec1752a16373e296b52bd"
-  integrity sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==
+sass@^1.80.6:
+  version "1.80.6"
+  resolved "https://registry.yarnpkg.com/sass/-/sass-1.80.6.tgz#5d0aa55763984effe41e40019c9571ab73e6851f"
+  integrity sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg==
   dependencies:
-    chokidar ">=3.0.0 <4.0.0"
+    chokidar "^4.0.0"
     immutable "^4.0.0"
     source-map-js ">=0.6.2 <2.0.0"
+  optionalDependencies:
+    "@parcel/watcher" "^2.4.1"
 
 saucelabs@^1.5.0:
   version "1.5.0"
@@ -15737,10 +15678,10 @@ terser-webpack-plugin@^5.3.10:
     serialize-javascript "^6.0.1"
     terser "^5.26.0"
 
-terser@5.34.1:
-  version "5.34.1"
-  resolved "https://registry.yarnpkg.com/terser/-/terser-5.34.1.tgz#af40386bdbe54af0d063e0670afd55c3105abeb6"
-  integrity sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==
+terser@5.36.0:
+  version "5.36.0"
+  resolved "https://registry.yarnpkg.com/terser/-/terser-5.36.0.tgz#8b0dbed459ac40ff7b4c9fd5a3a2029de105180e"
+  integrity sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==
   dependencies:
     "@jridgewell/source-map" "^0.3.3"
     acorn "^8.8.2"
@@ -15985,10 +15926,10 @@ tsickle@0.39.1:
   resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.39.1.tgz#7ccf672cde5b430f5dd0b281ee49e170ef390ff9"
   integrity sha512-CCc9cZhZbKoNizVM+K3Uqgit/go8GacjpqTv1cpwG/n2P0gB9GMoWZbxrUULDE9Wz26Lh86CGf6QyIPUVV1lnQ==
 
-tslib@2.7.0:
-  version "2.7.0"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
-  integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
+tslib@2.8.1:
+  version "2.8.1"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
+  integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
 
 tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0:
   version "1.14.1"
@@ -16578,10 +16519,10 @@ vite@5.2.12:
   optionalDependencies:
     fsevents "~2.3.3"
 
-vite@5.4.9:
-  version "5.4.9"
-  resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.9.tgz#215c80cbebfd09ccbb9ceb8c0621391c9abdc19c"
-  integrity sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==
+vite@5.4.11:
+  version "5.4.11"
+  resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5"
+  integrity sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==
   dependencies:
     esbuild "^0.21.3"
     postcss "^8.4.43"
@@ -16795,18 +16736,18 @@ webpack-subresource-integrity@5.1.0:
   dependencies:
     typed-assert "^1.0.8"
 
-webpack@5.95.0:
-  version "5.95.0"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.95.0.tgz#8fd8c454fa60dad186fbe36c400a55848307b4c0"
-  integrity sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==
+webpack@5.96.1:
+  version "5.96.1"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.96.1.tgz#3676d1626d8312b6b10d0c18cc049fba7ac01f0c"
+  integrity sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==
   dependencies:
-    "@types/estree" "^1.0.5"
+    "@types/eslint-scope" "^3.7.7"
+    "@types/estree" "^1.0.6"
     "@webassemblyjs/ast" "^1.12.1"
     "@webassemblyjs/wasm-edit" "^1.12.1"
     "@webassemblyjs/wasm-parser" "^1.12.1"
-    acorn "^8.7.1"
-    acorn-import-attributes "^1.9.5"
-    browserslist "^4.21.10"
+    acorn "^8.14.0"
+    browserslist "^4.24.0"
     chrome-trace-event "^1.0.2"
     enhanced-resolve "^5.17.1"
     es-module-lexer "^1.2.1"
