diff --git a/pixmaps/ic_question_answer_white_24px.svg b/pixmaps/ic_question_answer_white_24px.svg
new file mode 100644
index 0000000000000000000000000000000000000000..67af418ac6a6a7200104f689e0984a46914dcad1
--- /dev/null
+++ b/pixmaps/ic_question_answer_white_24px.svg
@@ -0,0 +1,4 @@
+<svg fill="#ffffff" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+    <path d="M0 0h24v24H0z" fill="none"/>
+    <path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"/>
+</svg>
\ No newline at end of file
diff --git a/pixmaps/ic_verified_user_white_24px_with_notification.svg b/pixmaps/ic_verified_user_white_24px_with_notification.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bf57c90eb452536ba6f44c56c6fe8761a820aa8f
--- /dev/null
+++ b/pixmaps/ic_verified_user_white_24px_with_notification.svg
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   fill="#000000"
+   height="24"
+   viewBox="0 0 24 24"
+   width="24"
+   version="1.1"
+   id="svg6"
+   sodipodi:docname="ic_verified_user_black_24px_with_notification.svg"
+   inkscape:version="0.92.1 r">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs10" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1600"
+     inkscape:window-height="842"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="9.8333333"
+     inkscape:cx="-19.322034"
+     inkscape:cy="12"
+     inkscape:window-x="0"
+     inkscape:window-y="29"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg6" />
+  <path
+     d="M0 0h24v24H0z"
+     fill="none"
+     id="path2" />
+  <path
+     fill="#ffffff"
+     d="M 12 1 L 10.375 1.7226562 A 6.2377381 6.2377381 0 0 1 11.564453 5.3730469 A 6.2377381 6.2377381 0 0 1 5.3261719 11.611328 A 6.2377381 6.2377381 0 0 1 3.0078125 11.158203 C 3.0802611 16.64804 6.8893005 21.752038 12 23 C 17.16 21.74 21 16.55 21 11 L 21 5 L 12 1 z M 16.589844 7.5800781 L 18 9 L 10 17 L 6 13 L 7.4101562 11.589844 L 10 14.169922 L 16.589844 7.5800781 z "
+     id="path4" />
+  <circle
+     r="4.9901905"
+     cy="5.3728104"
+     cx="5.3271904"
+     style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2.43000579;stroke-opacity:1"
+     id="path12471-2-3-6" />
+</svg>
diff --git a/pixmaps/pixmaps.gresource.xml b/pixmaps/pixmaps.gresource.xml
index bdfbbf9615fb4832435df01a8efb47caa15cdce8..fc8f0823ef4e0d088bc3ef981bb9855b7022985c 100644
--- a/pixmaps/pixmaps.gresource.xml
+++ b/pixmaps/pixmaps.gresource.xml
@@ -30,7 +30,9 @@
     <file alias="quality">ic_high_quality_white_24px.svg</file>
     <file alias="contacts_list">ic_people_black_24px.svg</file>
     <file alias="conversations_list">ic_question_answer_black_24px.svg</file>
+    <file alias="conversations_list_white">ic_question_answer_white_24px.svg</file>
     <file alias="contact_requests_list">ic_verified_user_black_24px_with_notification.svg</file>
+    <file alias="contact_requests_list_white">ic_verified_user_white_24px_with_notification.svg</file>
     <file alias="history_list">ic_history_black_24px.svg</file>
     <file alias="add">add.svg</file>
     <file alias="reject">reject.svg</file>
@@ -54,6 +56,7 @@
     <file alias="bottom_arrow">bottom_arrow.svg</file>
     <file alias="up_arrow">up_arrow.svg</file>
     <file alias="qrcode">qrcode.svg</file>
+    <file alias="qrcode-white">qrcode-white.png</file>
     <file alias="retry">retry.svg</file>
   </gresource>
 </gresources>
diff --git a/pixmaps/qrcode-white.png b/pixmaps/qrcode-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1233599514f7442ff94ff2b55852df2a1cbd0ec
Binary files /dev/null and b/pixmaps/qrcode-white.png differ
diff --git a/src/chatview.cpp b/src/chatview.cpp
index 3200d62298dc7215845d6a558f7665dbb0b8f189..4e6cb6a881560476772755e6a860ef38d0e70c1f 100644
--- a/src/chatview.cpp
+++ b/src/chatview.cpp
@@ -26,6 +26,7 @@
 // std
 #include <algorithm>
 #include <fstream>
+#include <sstream>
 
 // GTK
 #include <glib/gi18n.h>
@@ -107,6 +108,8 @@ struct _ChatViewPrivate
 
     bool ready_ {false};
     bool readyToRecord_ {false};
+    bool useDarkTheme {false};
+    std::string background;
     CppImpl* cpp;
 
     bool video_started_by_settings;
@@ -183,6 +186,34 @@ chat_view_dispose(GObject *object)
     G_OBJECT_CLASS(chat_view_parent_class)->dispose(object);
 }
 
+void
+chat_view_set_dark_mode(ChatView *self, gboolean darkMode, const std::string& background)
+{
+    auto priv = CHAT_VIEW_GET_PRIVATE(self);
+    priv->useDarkTheme = darkMode;
+    priv->background = background;
+    if (!priv->ready_) return;
+    webkit_chat_set_dark_mode(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), darkMode, background);
+}
+
+gboolean
+on_redraw(GtkWidget*, cairo_t*, ChatView* self)
+{
+    g_return_val_if_fail(IS_CHAT_VIEW(self), G_SOURCE_REMOVE);
+    auto* priv = CHAT_VIEW_GET_PRIVATE(CHAT_VIEW(self));
+
+    auto color = get_ambient_color(gtk_widget_get_toplevel(GTK_WIDGET(self)));
+    bool current_theme = (color.red + color.green + color.blue) / 3 < .5;
+    if (priv->useDarkTheme != current_theme) {
+        std::stringstream background;
+        background << "#" << std::hex << (int)(color.red * 256)
+                          << (int)(color.green * 256)
+                          << (int)(color.blue * 256);
+        chat_view_set_dark_mode(self, current_theme, background.str());
+    }
+    return false;
+}
+
 static void
 hide_chat_view(G_GNUC_UNUSED GtkWidget *widget, ChatView *self)
 {
@@ -713,6 +744,7 @@ webkit_chat_container_ready(ChatView* self)
     display_links_toggled(self);
     print_text_recording(self);
     load_participants_images(self);
+    webkit_chat_set_dark_mode(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), priv->useDarkTheme, priv->background);
 
     priv->ready_ = true;
     for (const auto& interaction: priv->cpp->interactionsBuffer_) {
@@ -993,6 +1025,14 @@ build_chat_view(ChatView* self)
         G_CALLBACK(on_webkit_drag_drop),
         self
     );
+
+    g_signal_connect(
+        self,
+        "draw",
+        G_CALLBACK(on_redraw),
+        self
+    );
+
     priv->new_interaction_connection = QObject::connect(
     &*(*priv->accountInfo_)->conversationModel, &lrc::api::ConversationModel::newInteraction,
     [self, priv](const std::string& uid, uint64_t interactionId, lrc::api::interaction::Info interaction) {
diff --git a/src/conversationsview.cpp b/src/conversationsview.cpp
index 856ce28a4373fbf1573655e25124e2169a100024..38e0e949cbd4143b12dcb45fc3982cf29119651e 100644
--- a/src/conversationsview.cpp
+++ b/src/conversationsview.cpp
@@ -63,6 +63,8 @@ struct _ConversationsViewPrivate
 
     GtkWidget* popupMenu_;
 
+    bool useDarkTheme {false};
+
     QMetaObject::Connection selection_updated;
     QMetaObject::Connection layout_changed;
     QMetaObject::Connection modelSortedConnection_;
@@ -143,6 +145,8 @@ render_name_and_last_interaction(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
     auto contactUri = conversation.participants.front();
     auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
 
+    auto grey = priv->useDarkTheme? "#bbb" : "#666";
+
     gtk_tree_model_get (model, iter,
                         0 /* col# */, &uid /* data */,
                         1 /* col# */, &alias /* data */,
@@ -161,23 +165,27 @@ render_name_and_last_interaction(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
     } else if (std::string(alias).empty()) {
         // If no alias to show, use the best id
         text = g_markup_printf_escaped(
-            "<span font_weight=\"bold\">%s</span>\n<span size=\"smaller\" color=\"#666\">%s</span>",
+            "<span font_weight=\"bold\">%s</span>\n<span size=\"smaller\" color=\"%s\">%s</span>",
             bestId,
+            grey,
             lastInteraction
         );
     } else if (std::string(alias) == std::string(bestId)) {
         // If the alias and the best id are identical, show only the alias
         text = g_markup_printf_escaped(
-            "<span font_weight=\"bold\">%s</span>\n<span size=\"smaller\" color=\"#666\">%s</span>",
+            "<span font_weight=\"bold\">%s</span>\n<span size=\"smaller\" color=\"%s\">%s</span>",
             alias,
+            grey,
             lastInteraction
         );
     } else {
         // If the alias is not empty and not equals to the best id, show both the alias and the best id
         text = g_markup_printf_escaped(
-            "<span font_weight=\"bold\">%s</span>\n<span size=\"smaller\" color=\"#666\">%s</span>\n<span size=\"smaller\" color=\"#666\">%s</span>",
+            "<span font_weight=\"bold\">%s</span>\n<span size=\"smaller\" color=\"%s\">%s</span>\n<span size=\"smaller\" color=\"%s\">%s</span>",
             alias,
+            grey,
             bestId,
+            grey,
             lastInteraction
         );
     }
@@ -783,3 +791,11 @@ conversations_view_get_current_selected(ConversationsView *self)
     }
     return -1;
 }
+
+void
+conversations_view_set_theme(ConversationsView *self, bool darkTheme) {
+    g_return_if_fail(IS_CONVERSATIONS_VIEW(self));
+    auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(self);
+    priv->useDarkTheme = darkTheme;
+}
+
diff --git a/src/conversationsview.h b/src/conversationsview.h
index 1cecda7d53f7badd9d6ca7ad300e8c4fbb67bf4d..caba2491b03121629cfad45f23ccfafe313304b6 100644
--- a/src/conversationsview.h
+++ b/src/conversationsview.h
@@ -39,5 +39,6 @@ GType      conversations_view_get_type            (void) G_GNUC_CONST;
 GtkWidget *conversations_view_new                 (AccountInfoPointer const & accountInfo);
 void       conversations_view_select_conversation (ConversationsView *self, const std::string& uid);
 int        conversations_view_get_current_selected(ConversationsView *self);
+void       conversations_view_set_theme(ConversationsView *self, bool darkTheme);
 
 G_END_DECLS
diff --git a/src/ringmainwindow.cpp b/src/ringmainwindow.cpp
index 8c56d400dd92992cd6f796a4983989b4c6aba3c8..4a2680af496fedf5b66686d4baa8da864c01f128 100644
--- a/src/ringmainwindow.cpp
+++ b/src/ringmainwindow.cpp
@@ -24,6 +24,7 @@
 #include <glib/gi18n.h>
 // std
 #include <algorithm>
+#include <sstream>
 
 // Qt
 #include <QSize>
@@ -56,6 +57,7 @@
 #include "mediasettingsview.h"
 #include "models/gtkqtreemodel.h"
 #include "ringwelcomeview.h"
+#include "utils/drawing.h"
 #include "utils/files.h"
 #include "ringnotify.h"
 #include "accountinfopointer.h"
@@ -113,10 +115,13 @@ struct RingMainWindowPrivate
     GtkWidget *treeview_contact_requests;
     GtkWidget *scrolled_window_contact_requests;
     GtkWidget *webkit_chat_container; ///< The webkit_chat_container is created once, then reused for all chat views
+    GtkWidget *image_contact_requests_list;
+    GtkWidget *image_conversations_list;
 
     GtkWidget *notifier;
 
     GSettings *settings;
+    bool useDarkTheme {false};
 
     details::CppImpl* cpp; ///< Non-UI and C++ only code
 
@@ -485,6 +490,47 @@ send_text_event(RingMainWindow* self)
     return G_SOURCE_REMOVE;
 }
 
+gboolean
+on_redraw(GtkWidget*, cairo_t*, RingMainWindow* self)
+{
+    g_return_val_if_fail(IS_RING_MAIN_WINDOW(self), G_SOURCE_REMOVE);
+    auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
+
+    auto color = get_ambient_color(GTK_WIDGET(self));
+    bool current_theme = (color.red + color.green + color.blue) / 3 < .5;
+    conversations_view_set_theme(CONVERSATIONS_VIEW(priv->treeview_conversations), current_theme);
+    if (priv->useDarkTheme != current_theme) {
+        ring_welcome_set_theme(RING_WELCOME_VIEW(priv->welcome_view), current_theme);
+        ring_welcome_update_view(RING_WELCOME_VIEW(priv->welcome_view));
+
+        gtk_image_set_from_resource(GTK_IMAGE(priv->image_contact_requests_list), current_theme?
+            "/net/jami/JamiGnome/contact_requests_list_white" : "/net/jami/JamiGnome/contact_requests_list");
+        gtk_image_set_from_resource(GTK_IMAGE(priv->image_conversations_list), current_theme?
+            "/net/jami/JamiGnome/conversations_list_white" : "/net/jami/JamiGnome/conversations_list");
+
+        priv->useDarkTheme = current_theme;
+
+        std::stringstream background;
+        background << "#" << std::hex << (int)(color.red * 256)
+                          << (int)(color.green * 256)
+                          << (int)(color.blue * 256);
+
+        auto provider = gtk_css_provider_new();
+        std::string background_search_entry = "background: " + background.str() + ";";
+        std::string css_style = ".search-entry-style { border: 0; border-radius: 0; } \
+        .spinner-style { border: 0; background: white; } \
+        .new-conversation-style { border: 0; " + background_search_entry + " transition: all 0.3s ease; border-radius: 0; } \
+        .new-conversation-style:hover {  background: " + (priv->useDarkTheme ? "#003b4e" : "#bae5f0") + "; }";
+        gtk_css_provider_load_from_data(provider,
+            css_style.c_str(),
+            -1, nullptr
+        );
+        gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()),
+                                                  GTK_STYLE_PROVIDER(provider),
+                                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    }
+}
+
 static void
 on_send_text_clicked(G_GNUC_UNUSED GtkWidget*, gchar* uid, gchar* body, RingMainWindow* self)
 {
@@ -1290,18 +1336,7 @@ CppImpl::init()
     g_signal_connect_swapped(widgets->button_new_conversation, "clicked", G_CALLBACK(on_search_entry_activated), self);
     g_signal_connect(widgets->search_entry, "search-changed", G_CALLBACK(on_search_entry_text_changed), self);
     g_signal_connect(widgets->search_entry, "key-release-event", G_CALLBACK(on_search_entry_key_released), self);
-
-    auto provider = gtk_css_provider_new();
-    gtk_css_provider_load_from_data(provider,
-        ".search-entry-style { border: 0; border-radius: 0; } \
-        .spinner-style { border: 0; background: white; } \
-        .new-conversation-style { border: 0; background: white; transition: all 0.3s ease; border-radius: 0; } \
-        .new-conversation-style:hover {  background: #bae5f0; }",
-        -1, nullptr
-    );
-    gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()),
-                                              GTK_STYLE_PROVIDER(provider),
-                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    g_signal_connect(widgets->search_entry, "draw", G_CALLBACK(on_redraw), self);
 
 
     /* react to digit key press/release events */
@@ -2842,6 +2877,8 @@ ring_main_window_class_init(RingMainWindowClass *klass)
     gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, radiobutton_new_account_settings);
     gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, combobox_account_selector);
     gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, scrolled_window_contact_requests);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, image_contact_requests_list);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, image_conversations_list);
 }
 
 GtkWidget *
diff --git a/src/ringwelcomeview.cpp b/src/ringwelcomeview.cpp
index b92f7aec102a40ff8906ce003d9f1da4ad36478b..b1cb9fa053cc04a3643a97ebf6729962e36bc842 100644
--- a/src/ringwelcomeview.cpp
+++ b/src/ringwelcomeview.cpp
@@ -52,6 +52,8 @@ struct _RingWelcomeViewPrivate
     GtkWidget *button_qrcode;
     GtkWidget *revealer_qrcode;
 
+    bool useDarkTheme {false};
+
     AccountInfoPointer const *accountInfo_;
     QMetaObject::Connection nameRegistrationEnded_;
 
@@ -80,6 +82,8 @@ ring_welcome_update_view(RingWelcomeView* self) {
         return;
     }
 
+    auto color = priv->useDarkTheme? "white" : "black";
+
     // Get registeredName, else the ID
     gchar *ring_id = nullptr;
     if(! (*priv->accountInfo_)->registeredName.empty()){
@@ -87,7 +91,7 @@ ring_welcome_update_view(RingWelcomeView* self) {
             GTK_LABEL(priv->label_explanation),
             _("This is your Jami username.\nCopy and share it with your friends!")
         );
-        ring_id = g_markup_printf_escaped("<span fgcolor=\"black\">%s</span>",
+        ring_id = g_markup_printf_escaped("<span fgcolor=\"%s\">%s</span>", color,
                                           (*priv->accountInfo_)->registeredName.c_str());
     }
     else if (!(*priv->accountInfo_)->profileInfo.uri.empty()) {
@@ -95,7 +99,7 @@ ring_welcome_update_view(RingWelcomeView* self) {
             GTK_LABEL(priv->label_explanation),
             _("This is your ID.\nCopy and share it with your friends!")
         );
-        ring_id = g_markup_printf_escaped("<span fgcolor=\"black\">%s</span>",
+        ring_id = g_markup_printf_escaped("<span fgcolor=\"%s\">%s</span>", color,
                                           (*priv->accountInfo_)->profileInfo.uri.c_str());
     } else {
         gtk_label_set_text(GTK_LABEL(priv->label_explanation), NULL);
@@ -112,6 +116,18 @@ ring_welcome_update_view(RingWelcomeView* self) {
 
     g_free(ring_id);
 
+
+    GError *error = NULL;
+    GdkPixbuf *image_qr = gdk_pixbuf_new_from_resource_at_scale(priv->useDarkTheme? "/net/jami/JamiGnome/qrcode-white" : "/net/jami/JamiGnome/qrcode",
+                                                                  -1, 16, TRUE, &error);
+    if (!image_qr) {
+        g_warning("Could not load icon: %s", error->message);
+        g_clear_error(&error);
+    } else {
+        auto image = gtk_image_new_from_pixbuf(image_qr);
+        gtk_button_set_image(GTK_BUTTON(priv->button_qrcode), image);
+    }
+
     priv->nameRegistrationEnded_ = QObject::connect(
         (*priv->accountInfo_)->accountModel,
         &lrc::api::NewAccountModel::nameRegistrationEnded,
@@ -120,7 +136,7 @@ ring_welcome_update_view(RingWelcomeView* self) {
             if (accountId == (*priv->accountInfo_)->id
                 && status == lrc::api::account::RegisterNameStatus::SUCCESS)
                 {
-                    gchar *markup = g_markup_printf_escaped("<span fgcolor=\"black\">%s</span>",
+                    gchar *markup = g_markup_printf_escaped("<span fgcolor=\"%s\">%s</span>", color,
                         name.c_str());
                     gtk_label_set_markup(GTK_LABEL(priv->label_ringid), markup);
                     g_free(markup);
@@ -128,10 +144,20 @@ ring_welcome_update_view(RingWelcomeView* self) {
         });
 }
 
+void
+ring_welcome_set_theme(RingWelcomeView* self, bool useDarkTheme)
+{
+    g_return_if_fail(IS_RING_WELCOME_VIEW(self));
+    auto* priv = RING_WELCOME_VIEW_GET_PRIVATE(self);
+    priv->useDarkTheme = useDarkTheme;
+}
+
+
 static void
 ring_welcome_view_init(RingWelcomeView *self)
 {
-    RingWelcomeViewPrivate *priv = RING_WELCOME_VIEW_GET_PRIVATE(self);
+    g_return_if_fail(IS_RING_WELCOME_VIEW(self));
+    auto* priv = RING_WELCOME_VIEW_GET_PRIVATE(self);
 
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
@@ -229,7 +255,7 @@ ring_welcome_view_init(RingWelcomeView *self)
 
     /* QR code button */
     priv->button_qrcode = gtk_button_new();
-    GdkPixbuf *image_qr = gdk_pixbuf_new_from_resource_at_scale("/net/jami/JamiGnome/qrcode",
+    GdkPixbuf *image_qr = gdk_pixbuf_new_from_resource_at_scale(priv->useDarkTheme? "/net/jami/JamiGnome/qrcode-white" : "/net/jami/JamiGnome/qrcode",
                                                                   -1, 16, TRUE, &error);
     if (!image_qr) {
         g_warning("Could not load icon: %s", error->message);
diff --git a/src/ringwelcomeview.h b/src/ringwelcomeview.h
index d8af9a27c16cdefe5dd5a9662ce9c9fd1ec657ca..0386365c3c28864b664ae7f36c4c75797e600d05 100644
--- a/src/ringwelcomeview.h
+++ b/src/ringwelcomeview.h
@@ -41,5 +41,6 @@ typedef struct _RingWelcomeViewClass RingWelcomeViewClass;
 GType             ring_welcome_view_get_type (void) G_GNUC_CONST;
 GtkWidget*        ring_welcome_view_new      (AccountInfoPointer const & accountInfo);
 void              ring_welcome_update_view   (RingWelcomeView* self);
+void              ring_welcome_set_theme     (RingWelcomeView* self, bool useDarkTheme);
 
 G_END_DECLS
diff --git a/src/utils/drawing.cpp b/src/utils/drawing.cpp
index 90c1115d4f708251fd86ea5b4c9b50fb02dc70c7..a9d6bdc2a3a52cba103baafe7db02d0ac6672b30 100644
--- a/src/utils/drawing.cpp
+++ b/src/utils/drawing.cpp
@@ -373,3 +373,31 @@ ring_draw_unread_messages(const GdkPixbuf *avatar, int unread_count) {
 
     return pixbuf;
 }
+
+GdkRGBA
+get_ambient_color(GtkWidget* widget)
+{
+    auto surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,4,4);
+    auto cr = cairo_create(surface);
+    if (widget) {
+        auto context = gtk_widget_get_style_context(widget);
+        gtk_render_background(context, cr, 0, 0, 1, 1);
+        cairo_surface_flush(surface);
+        auto content = cairo_image_surface_get_data(surface);
+        if(content[3] == 255) {
+            auto ret = GdkRGBA {
+                content[2]/255.0f,
+                content[1]/255.0f,
+                content[0]/255.0f,
+                content[3]/255.0f
+            };
+            cairo_destroy(cr);
+            cairo_surface_destroy(surface);
+            return ret;
+        }
+        widget=gtk_widget_get_parent(GTK_WIDGET(widget));
+    }
+    cairo_destroy(cr);
+    cairo_surface_destroy(surface);
+    return GdkRGBA{1.0f, 1.0f, 1.0f, 1.0f};
+}
\ No newline at end of file
diff --git a/src/utils/drawing.h b/src/utils/drawing.h
index 80f4a76aa32ca8e24d829df92436a40ffa31f769..72f5018c95043855cac4e0be66f9a83d6706d9a3 100644
--- a/src/utils/drawing.h
+++ b/src/utils/drawing.h
@@ -44,4 +44,6 @@ enum class IconStatus {
 };
 GdkPixbuf *ring_draw_status(const GdkPixbuf *avatar, IconStatus status);
 
+GdkRGBA get_ambient_color(GtkWidget* widget);
+
 #endif /* _DRAWING */
diff --git a/src/webkitchatcontainer.cpp b/src/webkitchatcontainer.cpp
index 5397e1a99d5c8a88d17e6cd8459418b2c0cc867d..b8f5ff607b652f07cc325c12ea566db44c36142c 100644
--- a/src/webkitchatcontainer.cpp
+++ b/src/webkitchatcontainer.cpp
@@ -769,6 +769,34 @@ webkit_chat_set_record_visible(WebKitChatContainer *view, bool isVisible)
     g_free(function_call);
 }
 
+void
+webkit_chat_set_dark_mode(WebKitChatContainer *view, bool darkMode, const std::string& background)
+{
+    std::string theme = "";
+    if (darkMode) {
+        theme = "\
+            --jami-light-blue: #003b4e;\
+            --jami-dark-blue: #28b1ed;\
+            --text-color: white;\
+            --timestamp-color: #bbb;\
+            --message-out-bg: #28b1ed;\
+            --message-out-txt: white;\
+            --message-in-bg: #616161;\
+            --message-in-txt: white;\
+            --file-in-timestamp-color: #999;\
+            --file-out-timestamp-color: #eee;\
+            --bg-color: " + background + ";\
+            --non-action-icon-color: white;\
+            --placeholder-text-color: #2b2b2b;\
+            --invite-hover-color: black;\
+            --hairline-color: #262626;\
+        ";
+    }
+    gchar* function_call = g_strdup_printf("setTheme(\"%s\")", theme.c_str());
+    webkit_chat_container_execute_js(view, function_call);
+    g_free(function_call);
+}
+
 void
 webkit_chat_update_chatview_frame(WebKitChatContainer *view, bool accountEnabled, bool isBanned, bool isTemporary, const gchar* alias, const gchar* bestId)
 {
diff --git a/src/webkitchatcontainer.h b/src/webkitchatcontainer.h
index 6d182f644c4c3d7d6c4360fb04ee80e2f2536ad1..44e41556c0d820a3aadd5c2b44ec5b8bf6eba260 100644
--- a/src/webkitchatcontainer.h
+++ b/src/webkitchatcontainer.h
@@ -56,6 +56,7 @@ void       webkit_chat_container_set_display_links    (WebKitChatContainer *view
 void       webkit_chat_container_set_invitation       (WebKitChatContainer *view, bool show, const std::string& contactUri, const std::string& contactId);
 void       webkit_chat_set_header_visible             (WebKitChatContainer *view, bool isVisible);
 void       webkit_chat_set_record_visible             (WebKitChatContainer *view, bool isVisible);
+void       webkit_chat_set_dark_mode                  (WebKitChatContainer *view, bool darkMode, const std::string& background);
 void       webkit_chat_update_chatview_frame          (WebKitChatContainer *view, bool accountEnabled, bool isBanned, bool isInvited, const gchar* alias, const gchar* bestId);
 
 G_END_DECLS