diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ConnectionIndicator.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ConnectionIndicator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d08cda40a6d18bb3bb99201a21cbdb693353de46
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ConnectionIndicator.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.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.secondary else notConnectedColor, CircleShape)
+)
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
index 73772d5611d06d8060fb4e34eaf4e093439e7cb3..0d3dfcfd7c1911b6442f13c51e486c688809a561 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
@@ -18,20 +18,17 @@
 
 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
-import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.defaultMinSize
 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.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
@@ -40,13 +37,14 @@ 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.contact.PendingContactId
+import org.briarproject.bramble.api.contact.PendingContactState
 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
@@ -65,20 +63,31 @@ fun main() = preview(
     "timestamp" to Instant.now().toEpochMilli(),
     "selected" to false,
 ) {
-    ContactCard(
-        ContactItem(
-            idWrapper = RealContactIdWrapper(ContactId(0)),
-            authorId = AuthorId(getRandomIdPersistent()),
-            name = getStringParameter("name"),
-            alias = getStringParameter("alias"),
-            isConnected = getBooleanParameter("isConnected"),
-            isEmpty = getBooleanParameter("isEmpty"),
-            unread = getIntParameter("unread"),
-            timestamp = getLongParameter("timestamp"),
-            avatar = null,
-        ),
-        {}, getBooleanParameter("selected"), {}
-    )
+    Column {
+        ContactCard(
+            ContactItem(
+                idWrapper = RealContactIdWrapper(ContactId(0)),
+                authorId = AuthorId(getRandomIdPersistent()),
+                name = getStringParameter("name"),
+                alias = getStringParameter("alias"),
+                isConnected = getBooleanParameter("isConnected"),
+                isEmpty = getBooleanParameter("isEmpty"),
+                unread = getIntParameter("unread"),
+                timestamp = getLongParameter("timestamp"),
+                avatar = null,
+            ),
+            {}, getBooleanParameter("selected"), {}
+        )
+        ContactCard(
+            PendingContactItem(
+                idWrapper = PendingContactIdWrapper(PendingContactId(getRandomId())),
+                alias = getStringParameter("alias"),
+                timestamp = getLongParameter("timestamp"),
+                state = PendingContactState.ADDING_CONTACT
+            ),
+            {}, false, {}
+        )
+    }
 }
 
 @Composable
@@ -87,22 +96,24 @@ fun ContactCard(
     onSel: () -> Unit,
     selected: Boolean,
     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 -> {
-                RealContactRow(contactItem, padding)
+                RealContactRow(contactItem)
             }
             is PendingContactItem -> {
-                PendingContactRow(contactItem, onRemovePending, padding)
+                PendingContactRow(contactItem, onRemovePending)
             }
         }
     }
@@ -110,17 +121,16 @@ 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)) {
+private fun RealContactRow(contactItem: ContactItem) {
+    Row(
+        horizontalArrangement = Arrangement.SpaceBetween,
+        modifier = Modifier.fillMaxWidth(),
+        verticalAlignment = Alignment.CenterVertically
+    ) {
         Row(
-            modifier = Modifier.align(Alignment.CenterVertically).padding(start = 16.dp, end = 8.dp)
-                .weight(1f, fill = false)
+            modifier = Modifier.padding(start = 16.dp, end = 8.dp)
         ) {
-            Box(modifier = Modifier.align(Alignment.CenterVertically)) {
+            Box {
                 ProfileCircle(36.dp, contactItem)
                 MessageCounter(
                     unread = contactItem.unread,
@@ -129,41 +139,35 @@ 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 = (16 + 4).dp).size(16.dp),
+            isConnected = contactItem.isConnected
         )
     }
 }
 
 @Composable
-private fun PendingContactRow(contactItem: PendingContactItem, onRemove: () -> Unit, padding: PaddingValues) {
-    Row(horizontalArrangement = Arrangement.SpaceBetween) {
+private fun PendingContactRow(contactItem: PendingContactItem, onRemove: () -> Unit) {
+    Row(
+        horizontalArrangement = Arrangement.SpaceBetween,
+        modifier = Modifier.fillMaxWidth(),
+        verticalAlignment = Alignment.CenterVertically
+    ) {
         Row(
-            modifier = Modifier.align(Alignment.CenterVertically).padding(start = 16.dp, end = 8.dp)
-                .weight(1f, fill = false)
+            modifier = Modifier.padding(start = 16.dp, end = 8.dp)
         ) {
             ProfileCircle(36.dp)
             PendingContactInfo(
                 contactItem = contactItem,
-                modifier = Modifier.align(Alignment.CenterVertically)
             )
         }
         IconButton(
             icon = Icons.Filled.Delete,
             contentDescription = i18n("access.contacts.pending.remove"),
             onClick = onRemove,
-            modifier = Modifier.padding(end = 4.dp).align(Alignment.CenterVertically)
+            modifier = Modifier.padding(end = 4.dp)
         )
     }
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt
index b0324ffa504334e1c6e59874df4246b2e4a0c1c4..8aff4a2d84bae10b7d1c745cfd90eea7a2b8aa1f 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt
@@ -26,14 +26,14 @@ import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 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.foundation.selection.selectableGroup
 import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Scaffold
+import androidx.compose.material.Surface
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -54,10 +54,11 @@ fun ContactList(
 ) {
     val scrollState = rememberLazyListState()
 
-    Scaffold(
+    Surface(
         modifier = Modifier.fillMaxHeight().width(COLUMN_WIDTH),
-        backgroundColor = MaterialTheme.colors.surfaceVariant,
-        topBar = {
+        color = MaterialTheme.colors.surfaceVariant
+    ) {
+        Column {
             Column(
                 modifier = Modifier.fillMaxWidth().height(HEADER_SIZE + 1.dp),
             ) {
@@ -67,17 +68,15 @@ 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,
                             onSel = { selectContact(contactItem) },
                             selected = isSelected(contactItem),
                             onRemovePending = { if (contactItem is PendingContactItem) removePendingContact(contactItem) },
-                            padding = PaddingValues(end = 16.dp),
                         )
                     }
                 }
@@ -87,6 +86,6 @@ fun ContactList(
                     modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight()
                 )
             }
-        },
-    )
+        }
+    }
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt
index eb6d737b942254902cd17f1688fdb8c45d2ae0ff..b02571f4e96bf91f9412907431575b2d854e82ff 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt
+++ b/briar-desktop/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
@@ -26,6 +25,7 @@ import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
@@ -36,13 +36,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
@@ -57,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(
@@ -69,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.surfaceVariant,
                     )
                 }
                 Text(
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt
index 54b0b9ce8b2d99867dd01acd788e8b5b60aa5568..49e33ff1fbac87d5a974408ca156e7c032143f36 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt
@@ -90,7 +90,6 @@ fun ContactDrawerMakeIntro(
                                 onSel = { viewModel.setSecondContact(contactItem) },
                                 selected = false,
                                 onRemovePending = {},
-                                padding = PaddingValues(end = 16.dp),
                             )
                     }
                 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
index 6d5bdd8b69b382c798525b3140778c56909ee140..a9c17ba486bdb89c157ad0bce81c9b44d809599c 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Surface
@@ -47,7 +48,19 @@ fun BriarSidebar(
     uiMode: UiMode,
     setUiMode: (UiMode) -> Unit,
 ) {
-    Surface(modifier = Modifier.width(SIDEBAR_WIDTH).fillMaxHeight(), color = MaterialTheme.colors.sidebarSurface) {
+    val displayButton = @Composable { selectedMode: UiMode, mode: UiMode, icon: ImageVector ->
+        BriarSidebarButton(
+            selectedMode == mode,
+            { setUiMode(mode) },
+            icon,
+            mode.toString()
+        )
+    }
+
+    Surface(
+        modifier = Modifier.width(SIDEBAR_WIDTH).fillMaxHeight().selectableGroup(),
+        color = MaterialTheme.colors.sidebarSurface
+    ) {
         Column(verticalArrangement = Arrangement.Top) {
             // profile button
             Box(