diff --git a/admin_theme.info.yml b/admin_theme.info.yml
index b741aa3..389a15c 100644
--- a/admin_theme.info.yml
+++ b/admin_theme.info.yml
@@ -1,5 +1,5 @@
 name: Admin Theme
 type: module
 description: "Enable the administration theme on more paths than possible with Drupal's default administration page."
-core_version_requirement: ^9.5 || ^10.2 || ^11.0
+core_version_requirement: ^9.5 || ^10.2 || ^11.0 || ^12
 configure: system.themes_page
diff --git a/admin_theme.module b/admin_theme.module
index 99b0cde..dbf57eb 100644
--- a/admin_theme.module
+++ b/admin_theme.module
@@ -5,6 +5,8 @@
  * Admin Theme Hook Implementations.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\admin_theme\Hook\AdminThemeHooks;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Form\FormStateInterface;
 
@@ -13,32 +15,9 @@ use Drupal\Core\Form\FormStateInterface;
  *
  * @see admin_theme_form_system_themes_form_alter_submit()
  */
+#[LegacyHook]
 function admin_theme_form_system_themes_admin_form_alter(&$form, FormStateInterface $form_state, $form_id) {
-  // Include paths.
-  $paths = \Drupal::configFactory()->getEditable('admin_theme.settings')->get('paths');
-  /** @var \Drupal\Core\Condition\ConditionInterface $condition */
-  $condition = \Drupal::service('plugin.manager.condition')->createInstance('request_path', ['pages' => $paths]);
-  $form_state->set(['conditions', 'admin_theme_request_path'], $condition);
-
-  $form['admin_theme']['admin_theme_request_path'] = $condition->buildConfigurationForm([], $form_state);
-  $form['admin_theme']['admin_theme_request_path']['#tree'] = TRUE;
-  $form['admin_theme']['admin_theme_request_path']['#type'] = 'fieldset';
-  $form['admin_theme']['admin_theme_request_path']['#title'] = t('Include');
-  unset($form['admin_theme']['admin_theme_request_path']['negate']);
-
-  // Exclude paths.
-  $paths = \Drupal::configFactory()->getEditable('admin_theme.settings')->get('exclude_paths');
-  /** @var \Drupal\Core\Condition\ConditionInterface $condition */
-  $condition = \Drupal::service('plugin.manager.condition')->createInstance('request_path', ['pages' => $paths]);
-  $form_state->set(['conditions', 'admin_theme_exclude_path'], $condition);
-
-  $form['admin_theme']['admin_theme_exclude_path'] = $condition->buildConfigurationForm([], $form_state);
-  $form['admin_theme']['admin_theme_exclude_path']['#tree'] = TRUE;
-  $form['admin_theme']['admin_theme_exclude_path']['#type'] = 'fieldset';
-  $form['admin_theme']['admin_theme_exclude_path']['#title'] = t('Exclude');
-  unset($form['admin_theme']['admin_theme_exclude_path']['negate']);
-
-  $form['#submit'][] = 'admin_theme_form_system_themes_form_alter_submit';
+  \Drupal::service(AdminThemeHooks::class)->formSystemThemesAdminFormAlter($form, $form_state, $form_id);
 }
 
 /**
diff --git a/admin_theme.services.yml b/admin_theme.services.yml
index dd08076..cb608b0 100644
--- a/admin_theme.services.yml
+++ b/admin_theme.services.yml
@@ -4,3 +4,7 @@ services:
     decorates: router.admin_context
     arguments: ['@admin_theme.admin_context.inner', '@plugin.manager.condition', '@config.factory']
     public: false
+
+  Drupal\admin_theme\Hook\AdminThemeHooks:
+    class: Drupal\admin_theme\Hook\AdminThemeHooks
+    autowire: true
diff --git a/src/Hook/AdminThemeHooks.php b/src/Hook/AdminThemeHooks.php
new file mode 100644
index 0000000..5bacc9c
--- /dev/null
+++ b/src/Hook/AdminThemeHooks.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\admin_theme\Hook;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Hook implementations for admin_theme.
+ */
+class AdminThemeHooks {
+  use StringTranslationTrait;
+
+  /**
+   * Implements hook_form_FORM_ID_alter() for system_themes_admin_form.
+   *
+   * @see admin_theme_form_system_themes_form_alter_submit()
+   */
+  #[Hook('form_system_themes_admin_form_alter')]
+  public function formSystemThemesAdminFormAlter(&$form, FormStateInterface $form_state, $form_id) {
+    // Include paths.
+    $paths = \Drupal::configFactory()->getEditable('admin_theme.settings')->get('paths');
+    /** @var \Drupal\Core\Condition\ConditionInterface $condition */
+    $condition = \Drupal::service('plugin.manager.condition')->createInstance('request_path', [
+      'pages' => $paths,
+    ]);
+    $form_state->set([
+      'conditions',
+      'admin_theme_request_path',
+    ], $condition);
+    $form['admin_theme']['admin_theme_request_path'] = $condition->buildConfigurationForm([], $form_state);
+    $form['admin_theme']['admin_theme_request_path']['#tree'] = TRUE;
+    $form['admin_theme']['admin_theme_request_path']['#type'] = 'fieldset';
+    $form['admin_theme']['admin_theme_request_path']['#title'] = $this->t('Include');
+    unset($form['admin_theme']['admin_theme_request_path']['negate']);
+    // Exclude paths.
+    $paths = \Drupal::configFactory()->getEditable('admin_theme.settings')->get('exclude_paths');
+    /** @var \Drupal\Core\Condition\ConditionInterface $condition */
+    $condition = \Drupal::service('plugin.manager.condition')->createInstance('request_path', [
+      'pages' => $paths,
+    ]);
+    $form_state->set([
+      'conditions',
+      'admin_theme_exclude_path',
+    ], $condition);
+    $form['admin_theme']['admin_theme_exclude_path'] = $condition->buildConfigurationForm([], $form_state);
+    $form['admin_theme']['admin_theme_exclude_path']['#tree'] = TRUE;
+    $form['admin_theme']['admin_theme_exclude_path']['#type'] = 'fieldset';
+    $form['admin_theme']['admin_theme_exclude_path']['#title'] = $this->t('Exclude');
+    unset($form['admin_theme']['admin_theme_exclude_path']['negate']);
+    $form['#submit'][] = 'admin_theme_form_system_themes_form_alter_submit';
+  }
+
+}
diff --git a/src/Routing/AdminThemeAdminContext.php b/src/Routing/AdminThemeAdminContext.php
index d7288de..79ed4cb 100644
--- a/src/Routing/AdminThemeAdminContext.php
+++ b/src/Routing/AdminThemeAdminContext.php
@@ -55,7 +55,7 @@ class AdminThemeAdminContext extends AdminContext {
   /**
    * {@inheritdoc}
    */
-  public function isAdminRoute(Route $route = NULL) {
+  public function isAdminRoute(?Route $route = NULL) {
     $excludePaths = (string) $this->configFactory->get('admin_theme.settings')->get('exclude_paths');
     /** @var \Drupal\Core\Condition\ConditionInterface $excludeCondition */
     $excludeCondition = $this->conditionManager->createInstance('request_path', ['pages' => $excludePaths]);
