diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 196ebf4..538d1ab 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -3098,12 +3098,15 @@ function drupal_common_theme() {
     ),
     'task_list' => array(
       'variables' => array('items' => NULL, 'active' => NULL,  'variant' => NULL),
+      'template' => 'task-list',
     ),
     'authorize_message' => array(
       'variables' => array('message' => NULL, 'success' => TRUE),
+      'template' => 'authorize-message',
     ),
     'authorize_report' => array(
       'variables' => array('messages' => array()),
+      'template' => 'authorize-report',
     ),
     // From pager.inc.
     'pager' => array(
diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc
index 5c35ac3..2ee47b7 100644
--- a/core/includes/theme.maintenance.inc
+++ b/core/includes/theme.maintenance.inc
@@ -106,17 +106,16 @@ function _theme_load_offline_registry($theme, $base_theme = NULL, $theme_engine
 }
 
 /**
- * Returns HTML for a list of maintenance tasks to perform.
+ * Prepares variables for maintenance task list templates.
  *
- * @param $variables
+ * Default template: task-list.html.twig.
+ *
+ * @param array $variables
  *   An associative array containing:
  *   - items: An associative array of maintenance tasks.
  *   - active: The key for the currently active maintenance task.
- *   - variant: A variant name to be used for a CSS class.
- *
- * @ingroup themeable
  */
-function theme_task_list($variables) {
+function template_preprocess_task_list(&$variables) {
   $items = $variables['items'];
   $active = $variables['active'];
   if (isset($variables['variant'])) {
@@ -127,76 +126,76 @@ function theme_task_list($variables) {
   }
 
   $done = isset($items[$active]) || $active == NULL;
-  $output = '<h2 class="visually-hidden">Installation tasks</h2>';
-  $output .= '<ol class="' . $class . '">';
+  $tasks = array();
 
   foreach ($items as $k => $item) {
+    $tasks[$k]['item'] = $item;
     if ($active == $k) {
-      $class = 'active';
-      $status = '(' . t('active') . ')';
+      $tasks[$k]['attributes']['class'][] = 'active';
+      $tasks[$k]['status'] = $t('active');
       $done = FALSE;
     }
     else {
-      $class = $done ? 'done' : '';
-      $status = $done ? '(' . t('done') . ')' : '';
+      $tasks[$k]['attributes']['class'][] = $done ? 'done' : '';
+      $tasks[$k]['status'] = $done ? $t('done') : '';
     }
-    $output .= '<li';
-    $output .= ($class ? ' class="' . $class . '"' : '') . '>';
-    $output .= $item;
-    $output .= ($status ? '<span class="visually-hidden"> ' . $status . '</span>' : '');
-    $output .= '</li>';
   }
-  $output .= '</ol>';
-  return $output;
+
+  $variables['tasks'] = $tasks;
 }
 
 /**
- * Returns HTML for a results report of an operation run by authorize.php.
+ * Returns HTML for the installation page.
+ *
+ * Note: this function is not themeable.
  *
  * @param $variables
  *   An associative array containing:
- *   - messages: An array of result messages.
+ *   - content: The page content to show.
+ */
+function theme_install_page($variables) {
+  drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
+  return theme('maintenance_page', $variables);
+}
+
+/**
+ * Prepares variables for authorize.php operation report templates.
  *
- * @ingroup themeable
+ * This report displays the results of an operation run via authorize.php.
+ *
+ * Default template: authorize-report.html.twig.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - messages: An array of result messages.
  */
-function theme_authorize_report($variables) {
+function template_preprocess_authorize_report(&$variables) {
   $messages = $variables['messages'];
-  $output = '';
+  // Top level attributes.
+  $attributes = $variables['attributes'] ?: array();
+  $variables['attributes'] = $attributes;
+
   if (!empty($messages)) {
-    $output .= '<div id="authorize-results">';
+    $lists = array();
+    $variables['attributes']['id'] = 'authorize-results';
     foreach ($messages as $heading => $logs) {
       $items = array();
       foreach ($logs as $number => $log_message) {
         if ($number === '#abort') {
           continue;
         }
-        $items[] = theme('authorize_message', array('message' => $log_message['message'], 'success' => $log_message['success']));
+        $items[] = array(
+          '#theme' => 'authorize_message',
+          '#message' => $log_message['message'],
+          '#success' => $log_message['success'],
+        );
       }
-      $output .= theme('item_list',  array('items' => $items, 'title' => $heading));
+      $lists[] = array(
+        '#theme' => 'item_list',
+        '#items' => $items,
+        '#title' => $heading,
+      );
     }
-    $output .= '</div>';
-  }
-  return $output;
-}
-
-/**
- * Returns HTML for a single log message from the authorize.php batch operation.
- *
- * @param $variables
- *   An associative array containing:
- *   - message: The log message.
- *   - success: A boolean indicating failure or success.
- *
- * @ingroup themeable
- */
-function theme_authorize_message($variables) {
-  $message = $variables['message'];
-  $success = $variables['success'];
-  if ($success) {
-    $item = array('data' => $message, 'class' => array('success'));
-  }
-  else {
-    $item = array('data' => '<strong>' . $message . '</strong>', 'class' => array('failure'));
+    $variables['report'] = $lists;
   }
-  return $item;
 }
diff --git a/core/modules/system/templates/authorize-message.html.twig b/core/modules/system/templates/authorize-message.html.twig
new file mode 100644
index 0000000..4579f2d
--- /dev/null
+++ b/core/modules/system/templates/authorize-message.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a log message in an authorize.php report.
+ *
+ * This template displays a single message in an authorize.php batch operation
+ * report.
+ *
+ * Available variables:
+ * - message: The log message.
+ * - success: A flag indicating failure or success.
+ *
+ * @ingroup themeable
+ */
+#}
+{% if success %}
+  <span class="success">{{ message }}</span>
+{% else %}
+  <span class="failure"><strong>{{ message }}</strong></span>
+{% endif %}
diff --git a/core/modules/system/templates/authorize-report.html.twig b/core/modules/system/templates/authorize-report.html.twig
new file mode 100644
index 0000000..e3c5dbb
--- /dev/null
+++ b/core/modules/system/templates/authorize-report.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * Default theme implementation for authorize.php operation report templates.
+ *
+ * This report displays the results of an operation run via authorize.php.
+ *
+ * Available variables:
+ * - report: A list of result messages.
+ * - attributes: HTML attributes for the element.
+ *
+ * @see template_preprocess_authorize_report()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if report %}
+  <div{{ attributes }}>
+    {% for messages in report %}
+      {{ messages }}
+    {% endfor %}
+  </div>
+{% endif %}
diff --git a/core/modules/system/templates/task-list.html.twig b/core/modules/system/templates/task-list.html.twig
new file mode 100644
index 0000000..02780c1
--- /dev/null
+++ b/core/modules/system/templates/task-list.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a list of maintenance tasks to perform.
+ *
+ * Available variables:
+ * - tasks: A list of maintenance tasks to perform. Each item in the list has
+ *   the following variables:
+ *   - item: The maintenance task.
+ *   - attributes: HTML attributes for the maintenance task.
+ *   - status: (optional) Text describing the status of the maintenance task,
+ *     'active' or 'done'.
+ *
+ * @ingroup themeable
+ */
+#}
+<h2 class="element-invisible">Installation tasks</h2>
+<ol class="task-list">
+{% for task in tasks %}
+  <li{{ task.attributes }}>
+    {{- task.item -}}
+    {%- if task.status %} <span class="element-invisible">({{ task.status }})</span>{% endif -%}
+  </li>
+{% endfor %}
+</ol>
