diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ConnectionIndicator.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ConnectionIndicator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e3c80ae5c8524445eccf7ba6f165d9049740bd9e
--- /dev/null
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ConnectionIndicator.kt
@@ -0,0 +1,43 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2021-2022 The Briar Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.briarproject.briar.desktop.contact
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
+import org.briarproject.briar.desktop.theme.contactConnected
+import org.briarproject.briar.desktop.theme.outline
+
+@Composable
+fun ConnectionIndicator(
+    modifier: Modifier = Modifier.size(16.dp),
+    isConnected: Boolean,
+    notConnectedColor: Color = Color.Transparent,
+) = Box(
+    modifier = modifier
+        .border(1.dp, MaterialTheme.colors.outline, CircleShape)
+        .background(if (isConnected) MaterialTheme.colors.contactConnected else notConnectedColor, CircleShape)
+)
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
index 0e98b2bb6f26449763a98af6a3e678ec59d7eb70..9622f9083beb33562650ac606f2eb618246cba63 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
@@ -18,8 +18,7 @@
 
 package org.briarproject.briar.desktop.contact
 
-import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.clickable
+import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -30,8 +29,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.Card
+import androidx.compose.foundation.selection.selectable
 import androidx.compose.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
@@ -41,13 +39,12 @@ import androidx.compose.material.icons.filled.Delete
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.style.TextOverflow.Companion.Ellipsis
 import androidx.compose.ui.unit.dp
 import org.briarproject.bramble.api.contact.ContactId
 import org.briarproject.bramble.api.identity.AuthorId
-import org.briarproject.briar.desktop.theme.outline
 import org.briarproject.briar.desktop.theme.selectedCard
-import org.briarproject.briar.desktop.theme.surfaceVariant
 import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
 import org.briarproject.briar.desktop.ui.HorizontalDivider
 import org.briarproject.briar.desktop.ui.MessageCounter
@@ -90,13 +87,16 @@ fun ContactCard(
     onRemovePending: () -> Unit,
     padding: PaddingValues = PaddingValues(0.dp),
 ) {
-    val bgColor = if (selected) MaterialTheme.colors.selectedCard else MaterialTheme.colors.surfaceVariant
+    val bgColor = if (selected) MaterialTheme.colors.selectedCard else Color.Transparent
 
-    Card(
-        modifier = Modifier.fillMaxWidth().defaultMinSize(minHeight = HEADER_SIZE).clickable(onClick = onSel),
-        shape = RoundedCornerShape(0.dp),
-        backgroundColor = bgColor,
-        contentColor = MaterialTheme.colors.onSurface
+    Column(
+        modifier = Modifier
+            .fillMaxWidth()
+            .defaultMinSize(minHeight = HEADER_SIZE)
+            .selectable(selected, onClick = onSel)
+            .background(bgColor)
+            .padding(vertical = 8.dp),
+        verticalArrangement = Arrangement.Center
     ) {
         when (contactItem) {
             is ContactItem -> {
@@ -112,16 +112,15 @@ fun ContactCard(
 
 @Composable
 private fun RealContactRow(contactItem: ContactItem, padding: PaddingValues) {
-    val outlineColor = MaterialTheme.colors.outline
-    val briarSecondary = MaterialTheme.colors.secondary
-    val briarSurfaceVar = MaterialTheme.colors.surfaceVariant
-
-    Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.padding(padding)) {
+    Row(
+        horizontalArrangement = Arrangement.SpaceBetween,
+        modifier = Modifier.padding(padding),
+        verticalAlignment = Alignment.CenterVertically
+    ) {
         Row(
-            modifier = Modifier.align(Alignment.CenterVertically).padding(start = 16.dp, end = 8.dp)
-                .weight(1f, fill = false)
+            modifier = Modifier.padding(horizontal = 16.dp).weight(1f)
         ) {
-            Box(modifier = Modifier.align(Alignment.CenterVertically)) {
+            Box {
                 ProfileCircle(36.dp, contactItem)
                 MessageCounter(
                     unread = contactItem.unread,
@@ -130,19 +129,11 @@ private fun RealContactRow(contactItem: ContactItem, padding: PaddingValues) {
             }
             RealContactInfo(
                 contactItem = contactItem,
-                modifier = Modifier.align(Alignment.CenterVertically)
             )
         }
-        Canvas(
-            modifier = Modifier.size(24.dp).align(Alignment.CenterVertically),
-            onDraw = {
-                val size = 16.dp
-                drawCircle(color = outlineColor, radius = size.toPx() / 2f)
-                drawCircle(
-                    color = if (contactItem.isConnected) briarSecondary else briarSurfaceVar,
-                    radius = (size - 2.dp).toPx() / 2f
-                )
-            }
+        ConnectionIndicator(
+            modifier = Modifier.padding(end = 18.dp).size(16.dp),
+            isConnected = contactItem.isConnected
         )
     }
 }
@@ -151,8 +142,8 @@ private fun RealContactRow(contactItem: ContactItem, padding: PaddingValues) {
 private fun PendingContactRow(contactItem: PendingContactItem, onRemove: () -> Unit, padding: PaddingValues) {
     Row(horizontalArrangement = Arrangement.SpaceBetween) {
         Row(
-            modifier = Modifier.align(Alignment.CenterVertically).padding(start = 16.dp, end = 8.dp)
-                .weight(1f, fill = false)
+            modifier = Modifier.align(Alignment.CenterVertically).padding(horizontal = 16.dp)
+                .weight(1f)
         ) {
             ProfileCircle(36.dp)
             PendingContactInfo(
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt
index b0324ffa504334e1c6e59874df4246b2e4a0c1c4..9e0dc02552f0a038ee2a31ee4215a19fd904066d 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt
@@ -32,13 +32,12 @@ import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.lazy.rememberLazyListState
 import androidx.compose.foundation.rememberScrollbarAdapter
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Scaffold
+import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
-import org.briarproject.briar.desktop.theme.surfaceVariant
+import org.briarproject.briar.desktop.ui.BackgroundSurface
 import org.briarproject.briar.desktop.ui.Constants.COLUMN_WIDTH
 import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
 
@@ -54,10 +53,11 @@ fun ContactList(
 ) {
     val scrollState = rememberLazyListState()
 
-    Scaffold(
+    BackgroundSurface(
         modifier = Modifier.fillMaxHeight().width(COLUMN_WIDTH),
-        backgroundColor = MaterialTheme.colors.surfaceVariant,
-        topBar = {
+        overlayAlpha = 0.04f
+    ) {
+        Column {
             Column(
                 modifier = Modifier.fillMaxWidth().height(HEADER_SIZE + 1.dp),
             ) {
@@ -67,10 +67,9 @@ fun ContactList(
                     onContactAdd = onContactAdd,
                 )
             }
-        },
-        content = { padding ->
-            Box(modifier = Modifier.padding(padding).fillMaxSize()) {
-                LazyColumn(state = scrollState) {
+
+            Box(modifier = Modifier.fillMaxSize()) {
+                LazyColumn(state = scrollState, modifier = Modifier.selectableGroup()) {
                     items(contactList) { contactItem ->
                         ContactCard(
                             contactItem,
@@ -87,6 +86,6 @@ fun ContactList(
                     modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight()
                 )
             }
-        },
-    )
+        }
+    }
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
index c497b390ef051a91ce401ae6b567e78cfc3d5d32..c162d9bee9fd166d644642c77e0b27764cab5a57 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
@@ -95,6 +95,7 @@ import org.briarproject.briar.desktop.dialogs.DialogType.WARNING
 import org.briarproject.briar.desktop.theme.Orange500
 import org.briarproject.briar.desktop.theme.Red500
 import org.briarproject.briar.desktop.theme.surfaceVariant
+import org.briarproject.briar.desktop.ui.BackgroundSurface
 import org.briarproject.briar.desktop.ui.Constants.DIALOG_WIDTH
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF
@@ -203,7 +204,7 @@ fun AddContactDialog(
         val scaffoldState = rememberScaffoldState()
         val coroutineScope = rememberCoroutineScope()
         val aliasFocusRequester = remember { FocusRequester() }
-        Surface {
+        BackgroundSurface {
             Scaffold(
                 modifier = Modifier.padding(horizontal = 24.dp).padding(top = 24.dp, bottom = 12.dp),
                 topBar = {
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt
index a161b184b35a2ee179923fb6024bd90fbfff5fe7..ea9a365d2ee1edbbbb8620001217e220970eef3a 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt
@@ -18,7 +18,6 @@
 
 package org.briarproject.briar.desktop.conversation
 
-import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
@@ -38,14 +37,12 @@ import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.drawscope.withTransform
 import androidx.compose.ui.text.style.TextOverflow.Companion.Ellipsis
 import androidx.compose.ui.unit.dp
+import org.briarproject.briar.desktop.contact.ConnectionIndicator
 import org.briarproject.briar.desktop.contact.ContactDropDown
 import org.briarproject.briar.desktop.contact.ContactItem
 import org.briarproject.briar.desktop.contact.ProfileCircle
-import org.briarproject.briar.desktop.theme.outline
-import org.briarproject.briar.desktop.theme.surfaceVariant
 import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
 import org.briarproject.briar.desktop.ui.HorizontalDivider
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
@@ -59,9 +56,6 @@ fun ConversationHeader(
     onDeleteContact: () -> Unit,
 ) {
     val (menuState, setMenuState) = remember { mutableStateOf(ContactDropDown.State.CLOSED) }
-    val onlineColor =
-        if (contactItem.isConnected) MaterialTheme.colors.secondary else MaterialTheme.colors.surfaceVariant
-    val outlineColor = MaterialTheme.colors.outline
 
     Box(modifier = Modifier.fillMaxWidth().height(HEADER_SIZE + 1.dp)) {
         Row(
@@ -71,15 +65,10 @@ fun ConversationHeader(
             Row(modifier = Modifier.fillMaxHeight().padding(start = 8.dp).weight(1f, fill = false)) {
                 Box(modifier = Modifier.align(Alignment.CenterVertically)) {
                     ProfileCircle(36.dp, contactItem)
-                    Canvas(
-                        modifier = Modifier,
-                        onDraw = {
-                            val size = 10.dp.toPx()
-                            withTransform({ translate(left = 30f, top = 30f) }) {
-                                drawCircle(color = outlineColor, radius = (size + 2.dp.toPx()) / 2f)
-                                drawCircle(color = onlineColor, radius = size / 2f)
-                            }
-                        }
+                    ConnectionIndicator(
+                        modifier = Modifier.align(Alignment.BottomEnd).size(12.dp),
+                        isConnected = contactItem.isConnected,
+                        notConnectedColor = MaterialTheme.colors.background,
                     )
                 }
                 Text(
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt
index 89abe704c9066450494cfac6b810d00a0485403a..bbfba16678038f90ae450a07f597514d1efc3885 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt
@@ -45,7 +45,6 @@ import org.briarproject.bramble.api.contact.ContactId
 import org.briarproject.briar.desktop.contact.ContactInfoDrawer
 import org.briarproject.briar.desktop.contact.ContactInfoDrawerState
 import org.briarproject.briar.desktop.navigation.SIDEBAR_WIDTH
-import org.briarproject.briar.desktop.theme.surfaceVariant
 import org.briarproject.briar.desktop.ui.Constants.COLUMN_WIDTH
 import org.briarproject.briar.desktop.ui.Loader
 import org.briarproject.briar.desktop.viewmodel.viewModel
@@ -135,7 +134,7 @@ fun ConversationScreen(
             Column(
                 modifier = Modifier.fillMaxHeight().width(COLUMN_WIDTH)
                     .offset(maxWidth + animatedInfoDrawerOffsetX)
-                    .background(MaterialTheme.colors.surfaceVariant)
+                    .background(MaterialTheme.colors.background)
             ) {
                 ContactInfoDrawer(
                     contactItem,
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt
index 1b374b6dc80e2c05342d6d3c4ab8da2031b0b400..f99908b6af8392c2c1761f683bf3910cbfdb472a 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt
@@ -48,6 +48,7 @@ import org.briarproject.briar.desktop.contact.PendingContactIdWrapper
 import org.briarproject.briar.desktop.contact.RealContactIdWrapper
 import org.briarproject.briar.desktop.contact.add.remote.AddContactDialog
 import org.briarproject.briar.desktop.contact.add.remote.AddContactViewModel
+import org.briarproject.briar.desktop.ui.BackgroundSurface
 import org.briarproject.briar.desktop.ui.BriarLogo
 import org.briarproject.briar.desktop.ui.Constants.PARAGRAPH_WIDTH
 import org.briarproject.briar.desktop.ui.VerticalDivider
@@ -132,21 +133,23 @@ fun PendingContactSelected() = Explainer(
 
 @Composable
 fun Explainer(headline: String, text: String, content: @Composable () -> Unit = {}) =
-    Column(
-        modifier = Modifier.padding(16.dp).fillMaxSize(),
-        verticalArrangement = Arrangement.Center,
-        horizontalAlignment = Alignment.CenterHorizontally
-    ) {
-        BriarLogo(modifier = Modifier.size(200.dp))
-        Text(
-            text = headline,
-            modifier = Modifier.padding(top = 16.dp, bottom = 4.dp),
-            style = MaterialTheme.typography.h3
-        )
-        Text(
-            text = text,
-            modifier = Modifier.padding(top = 4.dp, bottom = 16.dp).widthIn(max = PARAGRAPH_WIDTH),
-            style = MaterialTheme.typography.body2.copy(textAlign = TextAlign.Center)
-        )
-        content()
+    BackgroundSurface {
+        Column(
+            modifier = Modifier.padding(16.dp).fillMaxSize(),
+            verticalArrangement = Arrangement.Center,
+            horizontalAlignment = Alignment.CenterHorizontally
+        ) {
+            BriarLogo(modifier = Modifier.size(200.dp))
+            Text(
+                text = headline,
+                modifier = Modifier.padding(top = 16.dp, bottom = 4.dp),
+                style = MaterialTheme.typography.h3
+            )
+            Text(
+                text = text,
+                modifier = Modifier.padding(top = 4.dp, bottom = 16.dp).widthIn(max = PARAGRAPH_WIDTH),
+                style = MaterialTheme.typography.body2.copy(textAlign = TextAlign.Center)
+            )
+            content()
+        }
     }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt b/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt
index ea12210b752777f5bb4ea3b2f8658df28a536cbe..32e55d138baa8cefa96765cf6e1b329b76552a31 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt
@@ -32,7 +32,6 @@ import androidx.compose.material.Button
 import androidx.compose.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Surface
 import androidx.compose.material.Text
 import androidx.compose.material.TextField
 import androidx.compose.material.icons.Icons
@@ -48,7 +47,7 @@ import androidx.compose.ui.unit.dp
 import org.briarproject.briar.desktop.contact.ContactCard
 import org.briarproject.briar.desktop.contact.ContactItem
 import org.briarproject.briar.desktop.contact.ProfileCircle
-import org.briarproject.briar.desktop.theme.surfaceVariant
+import org.briarproject.briar.desktop.ui.BackgroundSurface
 import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
 import org.briarproject.briar.desktop.ui.HorizontalDivider
 import org.briarproject.briar.desktop.utils.InternationalizationUtils
@@ -65,7 +64,7 @@ fun ContactDrawerMakeIntro(
     LaunchedEffect(contactItem) {
         viewModel.setFirstContact(contactItem)
     }
-    Surface(color = MaterialTheme.colors.surfaceVariant, contentColor = MaterialTheme.colors.onSurface) {
+    BackgroundSurface {
         Column {
             if (!viewModel.secondScreen.value) {
                 Row(Modifier.fillMaxWidth().height(HEADER_SIZE)) {
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
index fc3ba64c07894d6f8e0f7539909c85e2eafcbbca..16e6599113ebd6e72eee867e99a553ba477d9f80 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
@@ -53,6 +53,7 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DB_ER
 import org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SERVICE_ERROR
 import org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS
 import org.briarproject.briar.desktop.theme.Red500
+import org.briarproject.briar.desktop.ui.BackgroundSurface
 import org.briarproject.briar.desktop.ui.Constants.STARTUP_FIELDS_WIDTH
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
@@ -109,37 +110,39 @@ fun ErrorScreen(
     text: String,
     onShowAbout: () -> Unit,
     onBackButton: (() -> Unit)? = null,
-) = Box {
-    Column(
-        modifier = Modifier.fillMaxSize().padding(32.dp),
-        horizontalAlignment = CenterHorizontally,
-        verticalArrangement = spacedBy(32.dp)
-    ) {
-        Icon(
-            imageVector = Icons.Filled.Error,
-            contentDescription = i18n("error"),
-            modifier = Modifier.size(128.dp),
-            tint = Red500
-        )
+) = BackgroundSurface {
+    Box {
+        Column(
+            modifier = Modifier.fillMaxSize().padding(32.dp),
+            horizontalAlignment = CenterHorizontally,
+            verticalArrangement = spacedBy(32.dp)
+        ) {
+            Icon(
+                imageVector = Icons.Filled.Error,
+                contentDescription = i18n("error"),
+                modifier = Modifier.size(128.dp),
+                tint = Red500
+            )
 
-        Text(i18n("sorry"), style = MaterialTheme.typography.h5)
-        Text(
-            text = text,
-            style = MaterialTheme.typography.body1,
-            modifier = Modifier.widthIn(max = STARTUP_FIELDS_WIDTH)
-        )
-    }
+            Text(i18n("sorry"), style = MaterialTheme.typography.h5)
+            Text(
+                text = text,
+                style = MaterialTheme.typography.body1,
+                modifier = Modifier.widthIn(max = STARTUP_FIELDS_WIDTH)
+            )
+        }
 
-    if (onBackButton != null) {
-        IconButton(onClick = onBackButton) {
-            Icon(Icons.Filled.ArrowBack, i18n("back"))
+        if (onBackButton != null) {
+            IconButton(onClick = onBackButton) {
+                Icon(Icons.Filled.ArrowBack, i18n("back"))
+            }
         }
-    }
 
-    IconButton(
-        onClick = onShowAbout,
-        modifier = Modifier.align(Alignment.BottomStart)
-    ) {
-        Icon(Icons.Filled.Info, i18n("access.about_briar_desktop"))
+        IconButton(
+            onClick = onShowAbout,
+            modifier = Modifier.align(Alignment.BottomStart)
+        ) {
+            Icon(Icons.Filled.Info, i18n("access.about_briar_desktop"))
+        }
     }
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/login/StartupScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/login/StartupScreen.kt
index cae1225cf1456ecaa9ee97993d96c1e6c97ff304..e2ad0cbc99b573f82827fe0066b85442cfdb941f 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/login/StartupScreen.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/login/StartupScreen.kt
@@ -38,6 +38,7 @@ import androidx.compose.ui.Alignment.Companion.CenterHorizontally
 import androidx.compose.ui.Alignment.Companion.CenterVertically
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
+import org.briarproject.briar.desktop.ui.BackgroundSurface
 import org.briarproject.briar.desktop.ui.BriarLogo
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.viewmodel.viewModel
@@ -61,30 +62,32 @@ fun StartupScreenScaffold(
     onBackButton: () -> Unit = {},
     onShowAbout: () -> Unit = {},
     content: @Composable () -> Unit
-) = Box {
-    Column(
-        modifier = Modifier.padding(16.dp).fillMaxSize(),
-        horizontalAlignment = CenterHorizontally
-    ) {
-        HeaderLine(title)
-        content()
-    }
+) = BackgroundSurface {
+    Box {
+        Column(
+            modifier = Modifier.padding(16.dp).fillMaxSize(),
+            horizontalAlignment = CenterHorizontally
+        ) {
+            HeaderLine(title)
+            content()
+        }
+
+        if (showBackButton) {
+            IconButton(
+                onClick = onBackButton,
+                modifier = Modifier.align(Alignment.TopStart)
+            ) {
+                Icon(Icons.Filled.ArrowBack, i18n("back"))
+            }
+        }
 
-    if (showBackButton) {
         IconButton(
-            onClick = onBackButton,
-            modifier = Modifier.align(Alignment.TopStart)
+            onClick = onShowAbout,
+            modifier = Modifier.align(Alignment.BottomStart)
         ) {
-            Icon(Icons.Filled.ArrowBack, i18n("back"))
+            Icon(Icons.Filled.Info, i18n("access.about_briar_desktop"))
         }
     }
-
-    IconButton(
-        onClick = onShowAbout,
-        modifier = Modifier.align(Alignment.BottomStart)
-    ) {
-        Icon(Icons.Filled.Info, i18n("access.about_briar_desktop"))
-    }
 }
 
 @Composable
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt b/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
index fe080e6eade164bfb2f7089b6dd4e1b83a62c82d..4a2f458135211144734b789f7f2faaac0bc4885a 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
@@ -25,10 +25,11 @@ import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.selection.selectable
+import androidx.compose.foundation.selection.selectableGroup
+import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Surface
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.ChromeReaderMode
 import androidx.compose.material.icons.filled.Contacts
@@ -40,17 +41,23 @@ import androidx.compose.material.icons.filled.WifiTethering
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.unit.dp
 import org.briarproject.bramble.api.identity.LocalAuthor
 import org.briarproject.briar.desktop.contact.ProfileCircle
-import org.briarproject.briar.desktop.theme.sidebarSurface
+import org.briarproject.briar.desktop.ui.BackgroundSurface
 import org.briarproject.briar.desktop.ui.UiMode
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.getDesktopFeatureFlags
 
 val SIDEBAR_WIDTH = 56.dp
 
+/**
+ * The sidebar used in Briar Desktop as main navigation.
+ * It currently follows the MaterialTheme Navigation Rail compact design for all screen sizes,
+ * but could be adapted in future to extend to standard size (72.dp) or even a standard Navigation Drawer for large screens.
+ */
 @Composable
 fun BriarSidebar(
     account: LocalAuthor?,
@@ -67,7 +74,10 @@ fun BriarSidebar(
         )
     }
 
-    Surface(modifier = Modifier.width(SIDEBAR_WIDTH).fillMaxHeight(), color = MaterialTheme.colors.sidebarSurface) {
+    BackgroundSurface(
+        modifier = Modifier.width(SIDEBAR_WIDTH).fillMaxHeight().selectableGroup(),
+        overlayAlpha = 0.08f,
+    ) {
         Column(verticalArrangement = Arrangement.Top) {
             // profile button
             Box(
@@ -109,11 +119,16 @@ fun BriarSidebar(
 
 @Composable
 fun BriarSidebarButton(selected: Boolean, onClick: () -> Unit, icon: ImageVector, contentDescription: String?) {
-    val tint = if (selected) MaterialTheme.colors.primary else MaterialTheme.colors.onSurface
-    IconButton(
-        modifier = Modifier.padding(vertical = 4.dp, horizontal = 12.dp),
-        onClick = onClick
+    val tint = if (selected) MaterialTheme.colors.primaryVariant else MaterialTheme.colors.onBackground.copy(alpha = 0.6f)
+    Box(
+        contentAlignment = Alignment.Center,
+        modifier = Modifier.clip(CircleShape).selectable(selected, onClick = onClick).size(SIDEBAR_WIDTH)
     ) {
-        Icon(icon, contentDescription, tint = tint, modifier = Modifier.size(30.dp))
+        Icon(
+            icon,
+            contentDescription,
+            tint = tint,
+            modifier = Modifier.size(24.dp)
+        )
     }
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/theme/Colors.kt b/src/main/kotlin/org/briarproject/briar/desktop/theme/Colors.kt
index 7ff1bedee63ef77f5e8c6eddb1f5983c66cb408b..4759bf29391ff1e1a691f3fd527e219e91067bd2 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/theme/Colors.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/theme/Colors.kt
@@ -20,10 +20,17 @@ package org.briarproject.briar.desktop.theme
 
 import androidx.compose.ui.graphics.Color
 
+/**
+ * All the colors defined in this file are taken from the Briar Styleguide.
+ * See https://briar-styleguide.netlify.app/design/
+ */
+
 val Night50 = Color(0xffebf3fa)
 val Night500 = Color(0xff435b77)
+val Night600 = Color(0xff374b61)
 val Night700 = Color(0xff2e3d4f)
 val Night800 = Color(0xff212d3b)
+val Night900 = Color(0xff15212d)
 val Night950 = Color(0xff0e171f)
 
 val Gray50 = Color(0xfffafafa)
@@ -36,27 +43,32 @@ val Gray700 = Color(0xff707070)
 val Gray800 = Color(0xff4f4f4f)
 val Gray900 = Color(0xff2e2e2e)
 val Gray950 = Color(0xff1f1f1f)
-val materialDarkBg = Color(0xff121212)
 
 val Red500 = Color(0xffdb3b21)
-val Orange500 = Color(0xfffc9403)
 
-// taken from Android AppCompat DayNight theme as error colors
-// https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-appcompat-release/appcompat/appcompat/src/main/res/values/colors_material.xml#102
-val DeepOrange400 = Color(0xffff7043)
-val DeepOrange500 = Color(0xffff5722)
+val Orange200 = Color(0xfffed69f)
+val Orange500 = Color(0xfffc9403)
+val Orange800 = Color(0xffa35200)
 
+val Blue300 = Color(0xff73afea)
 val Blue400 = Color(0xff418cd8)
-val Blue500 = Color(0xff1f78d1) // todo: unused in Android
+val Blue500 = Color(0xff1f78d1)
 val Blue600 = Color(0xff1b69b6)
 val Blue800 = Color(0xff134a81)
 
 val Lime300 = Color(0xff95DE2D)
+val Lime400 = Color(0xff82c91e)
 val Lime500 = Color(0xff74B816)
+val Lime600 = Color(0xff67a60f)
+val Lime800 = Color(0xff3e620c)
 
+// taken from Android AppCompat DayNight theme as error colors
+// https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-appcompat-release/appcompat/appcompat/src/main/res/values/colors_material.xml#102
+val DeepOrange400 = Color(0xffff7043)
+val DeepOrange500 = Color(0xffff5722)
+
+// taken from Briar Android
 val TextPrimaryMaterialDark = Color(0xffffffff)
 val TextPrimaryMaterialLight = Color(0xde000000)
 val TextSecondaryMaterialDark = Color(0xb3ffffff)
 val TextSecondaryMaterialLight = Color(0x8a000000)
-
-val briarError = Color(0xffb00020)
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/theme/Theme.kt b/src/main/kotlin/org/briarproject/briar/desktop/theme/Theme.kt
index 69d6ae7d859ab7e76df8b2c0305f84686962f730..6833cebead3d9431fb76860668b447725785c45c 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/theme/Theme.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/theme/Theme.kt
@@ -35,11 +35,12 @@ import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.platform.Font
 import androidx.compose.ui.unit.sp
 
-val Colors.divider: Color get() = if (isLight) Gray300 else Gray800
+val Colors.divider: Color get() = if (isLight) Gray300 else Night700
 val Colors.outline: Color get() = if (isLight) Gray900 else Gray200
+@Deprecated("use BackgroundSurface with a suitable overlayAlpha instead")
 val Colors.surfaceVariant: Color get() = if (isLight) Gray100 else Gray950
-val Colors.sidebarSurface: Color get() = if (isLight) Gray200 else Gray900
-val Colors.selectedCard: Color get() = if (isLight) Gray400 else Gray700
+val Colors.selectedCard: Color get() = if (isLight) Gray300 else Night600
+val Colors.contactConnected: Color get() = Lime500
 val Colors.msgStroke: Color get() = if (isLight) Gray300 else Gray900
 val Colors.msgIn: Color get() = if (isLight) Color.White else Night700
 val Colors.msgOut: Color get() = if (isLight) Blue400 else Blue600
@@ -55,10 +56,10 @@ val Colors.warningForeground get() = Color.White
 
 val DarkColors = darkColors(
     primary = Blue500,
-    primaryVariant = Night500,
-    secondary = Lime500,
-    background = materialDarkBg,
-    surface = materialDarkBg,
+    primaryVariant = Blue500,
+    secondary = Lime400,
+    background = Night900,
+    surface = Night800,
     error = DeepOrange400,
     onPrimary = Color.White,
     onSecondary = Color.White,
@@ -67,14 +68,14 @@ val DarkColors = darkColors(
     onError = Color.White,
 )
 val LightColors = lightColors(
-    primary = Blue500,
-    primaryVariant = Night500,
-    secondary = Lime300,
-    background = Color.White,
+    primary = Blue800,
+    primaryVariant = Blue600,
+    secondary = Lime600,
+    background = Gray100,
     surface = Color.White,
     error = DeepOrange500,
     onPrimary = Color.White,
-    onSecondary = Color.Black,
+    onSecondary = Color.White,
     onBackground = Color.Black,
     onSurface = Color.Black,
     onError = Color.White,
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/BackgroundSurface.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/BackgroundSurface.kt
new file mode 100644
index 0000000000000000000000000000000000000000..01f7194b01c9fde65917b257e5d9bcf14dea4d80
--- /dev/null
+++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/BackgroundSurface.kt
@@ -0,0 +1,51 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2021-2022 The Briar Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.briarproject.briar.desktop.ui
+
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.material.contentColorFor
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.compositeOver
+
+/**
+ * A surface that is meant to be used as background, with [MaterialTheme.colors.background] as default color.
+ * It will automatically match the corresponding [contentColor] if the given [color] is part of the Material theme.
+ * An [overlayAlpha] value bigger than zero applies a color overlay to the background color,
+ * that can be used to generate slightly varying colors for different parts of the UI.
+ */
+@Composable
+fun BackgroundSurface(
+    modifier: Modifier = Modifier,
+    shape: Shape = RectangleShape,
+    overlayAlpha: Float = 0f,
+    color: Color = MaterialTheme.colors.background,
+    contentColor: Color = contentColorFor(color),
+    content: @Composable () -> Unit
+) = Surface(
+    modifier = modifier,
+    shape = shape,
+    color = if (overlayAlpha != 0f) contentColor.copy(alpha = overlayAlpha).compositeOver(color) else color,
+    contentColor = contentColor,
+    content = content
+)
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounter.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounter.kt
index 07f2c8d71f9b64e85901401ff4f8b77bd39f40b0..938230e75abf511cda5ff2cb7ba39d1de1aef434 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounter.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounter.kt
@@ -37,19 +37,18 @@ import org.briarproject.briar.desktop.theme.outline
 
 @Composable
 fun MessageCounter(unread: Int, modifier: Modifier = Modifier) {
-    val outlineColor = MaterialTheme.colors.outline
-    val briarSecondary = MaterialTheme.colors.secondary
     if (unread > 0) {
         Box(
             modifier = modifier
                 .height(20.dp)
                 .widthIn(min = 20.dp, max = Dp.Infinity)
-                .border(1.dp, outlineColor, CircleShape)
-                .background(briarSecondary, CircleShape)
+                .border(2.dp, MaterialTheme.colors.outline, CircleShape)
+                .background(MaterialTheme.colors.primary, CircleShape)
                 .padding(horizontal = 6.dp)
         ) {
             Text(
                 modifier = Modifier.align(Alignment.Center),
+                color = MaterialTheme.colors.onPrimary,
                 style = MaterialTheme.typography.overline,
                 textAlign = TextAlign.Center,
                 text = unread.toString(),
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/UiPlaceholder.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/UiPlaceholder.kt
index 39c7f933066370e4df01660133ed1945c40a81e6..4c984fa4de27b2fca1f8b43a88c70ab46d2dcf77 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/ui/UiPlaceholder.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/UiPlaceholder.kt
@@ -26,9 +26,11 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 
 @Composable
-fun UiPlaceholder() = Box(
-    contentAlignment = Alignment.Center,
-    modifier = Modifier.fillMaxSize()
-) {
-    Text("TBD")
+fun UiPlaceholder() = BackgroundSurface {
+    Box(
+        contentAlignment = Alignment.Center,
+        modifier = Modifier.fillMaxSize()
+    ) {
+        Text("TBD")
+    }
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
index fa5c8e52675fc6c5b5afaaa485c48a1dfabaf5ee..a376f5ae14d89657320f1ca6a83c5d53ef8786f9 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
@@ -52,6 +52,7 @@ import androidx.compose.ui.unit.dp
 import androidx.compose.ui.window.singleWindowApplication
 import org.briarproject.bramble.api.UniqueId
 import org.briarproject.briar.desktop.theme.BriarTheme
+import org.briarproject.briar.desktop.ui.BackgroundSurface
 import org.briarproject.briar.desktop.ui.LocalWindowScope
 import kotlin.random.Random
 
@@ -225,7 +226,7 @@ object PreviewUtils {
                     }
 
                     BriarTheme(isDarkTheme = scope.getBooleanParameter("darkTheme")) {
-                        Box(Modifier.fillMaxSize(1f)) {
+                        BackgroundSurface(Modifier.fillMaxSize(1f)) {
                             Column(Modifier.padding(10.dp)) {
                                 content(scope)
                             }