diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index c3ee0d930a..668afe7fde 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -160,18 +160,6 @@ module ApplicationHelper
     output.compact_blank.join(' ')
   end
 
-  def theme_style_tags(theme)
-    if theme == 'system'
-      concat stylesheet_pack_tag('mastodon-light', media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous')
-      concat stylesheet_pack_tag('default', media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous')
-      concat tag.meta name: 'theme-color', content: Themes::MASTODON_DARK_THEME_COLOR, media: '(prefers-color-scheme: dark)'
-      concat tag.meta name: 'theme-color', content: Themes::MASTODON_LIGHT_THEME_COLOR, media: '(prefers-color-scheme: light)'
-    else
-      concat stylesheet_pack_tag theme, media: 'all', crossorigin: 'anonymous'
-      concat tag.meta name: 'theme-color', content: theme == 'mastodon-light' ? Themes::MASTODON_LIGHT_THEME_COLOR : Themes::MASTODON_DARK_THEME_COLOR
-    end
-  end
-
   def cdn_host
     Rails.configuration.action_controller.asset_host
   end
diff --git a/app/helpers/theme_helper.rb b/app/helpers/theme_helper.rb
new file mode 100644
index 0000000000..83527ce611
--- /dev/null
+++ b/app/helpers/theme_helper.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module ThemeHelper
+  def theme_style_tags(theme)
+    if theme == 'system'
+      concat stylesheet_pack_tag('mastodon-light', media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous')
+      concat stylesheet_pack_tag('default', media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous')
+    else
+      stylesheet_pack_tag theme, media: 'all', crossorigin: 'anonymous'
+    end
+  end
+
+  def theme_color_tags(theme)
+    if theme == 'system'
+      concat tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:dark], media: '(prefers-color-scheme: dark)')
+      concat tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:light], media: '(prefers-color-scheme: light)')
+    else
+      tag.meta name: 'theme-color', content: theme_color_for(theme)
+    end
+  end
+
+  private
+
+  def theme_color_for(theme)
+    theme == 'mastodon-light' ? Themes::THEME_COLORS[:light] : Themes::THEME_COLORS[:dark]
+  end
+end
diff --git a/app/lib/themes.rb b/app/lib/themes.rb
index 3ad2304977..b6da980733 100644
--- a/app/lib/themes.rb
+++ b/app/lib/themes.rb
@@ -6,8 +6,10 @@ require 'yaml'
 class Themes
   include Singleton
 
-  MASTODON_DARK_THEME_COLOR = '#191b22'
-  MASTODON_LIGHT_THEME_COLOR = '#f3f5f7'
+  THEME_COLORS = {
+    dark: '#191b22',
+    light: '#f3f5f7',
+  }.freeze
 
   def initialize
     @conf = YAML.load_file(Rails.root.join('config', 'themes.yml'))
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index c353b1d872..9d7669d685 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -21,6 +21,7 @@
 
     %link{ rel: 'mask-icon', href: frontend_asset_path('images/logo-symbol-icon.svg'), color: '#6364FF' }/
     %link{ rel: 'manifest', href: manifest_path(format: :json) }/
+    = theme_color_tags current_theme
     %meta{ name: 'apple-mobile-web-app-capable', content: 'yes' }/
 
     %title= html_title
diff --git a/spec/helpers/theme_helper_spec.rb b/spec/helpers/theme_helper_spec.rb
new file mode 100644
index 0000000000..c0b6380a1f
--- /dev/null
+++ b/spec/helpers/theme_helper_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe ThemeHelper do
+  describe 'theme_style_tags' do
+    let(:result) { helper.theme_style_tags(theme) }
+
+    context 'when using system theme' do
+      let(:theme) { 'system' }
+
+      it 'returns the mastodon-light and default stylesheets with correct color schemes' do
+        expect(html_links.first.attributes.symbolize_keys)
+          .to include(
+            href: have_attributes(value: match(/mastodon-light/)),
+            media: have_attributes(value: 'not all and (prefers-color-scheme: dark)')
+          )
+        expect(html_links.last.attributes.symbolize_keys)
+          .to include(
+            href: have_attributes(value: match(/default/)),
+            media: have_attributes(value: '(prefers-color-scheme: dark)')
+          )
+      end
+    end
+
+    context 'when using other theme' do
+      let(:theme) { 'contrast' }
+
+      it 'returns the theme stylesheet without color scheme information' do
+        expect(html_links.first.attributes.symbolize_keys)
+          .to include(
+            href: have_attributes(value: match(/contrast/)),
+            media: have_attributes(value: 'all')
+          )
+      end
+    end
+  end
+
+  describe 'theme_color_tags' do
+    let(:result) { helper.theme_color_tags(theme) }
+
+    context 'when using system theme' do
+      let(:theme) { 'system' }
+
+      it 'returns the mastodon-light and default stylesheets with correct color schemes' do
+        expect(html_theme_colors.first.attributes.symbolize_keys)
+          .to include(
+            content: have_attributes(value: Themes::THEME_COLORS[:dark]),
+            media: have_attributes(value: '(prefers-color-scheme: dark)')
+          )
+        expect(html_theme_colors.last.attributes.symbolize_keys)
+          .to include(
+            content: have_attributes(value: Themes::THEME_COLORS[:light]),
+            media: have_attributes(value: '(prefers-color-scheme: light)')
+          )
+      end
+    end
+
+    context 'when using mastodon-light theme' do
+      let(:theme) { 'mastodon-light' }
+
+      it 'returns the theme stylesheet without color scheme information' do
+        expect(html_theme_colors.first.attributes.symbolize_keys)
+          .to include(
+            content: have_attributes(value: Themes::THEME_COLORS[:light])
+          )
+      end
+    end
+
+    context 'when using other theme' do
+      let(:theme) { 'contrast' }
+
+      it 'returns the theme stylesheet without color scheme information' do
+        expect(html_theme_colors.first.attributes.symbolize_keys)
+          .to include(
+            content: have_attributes(value: Themes::THEME_COLORS[:dark])
+          )
+      end
+    end
+  end
+
+  private
+
+  def html_links
+    Nokogiri::HTML5.fragment(result).css('link')
+  end
+
+  def html_theme_colors
+    Nokogiri::HTML5.fragment(result).css('meta[name=theme-color]')
+  end
+end