diff --git a/briar-desktop/src/main/kotlin/androidx/compose/material/IconButtonExt.kt b/briar-desktop/src/main/kotlin/androidx/compose/material/IconButtonExt.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d6619e0d021a881cbe8b6ad6c9a498cb694d8b53
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/androidx/compose/material/IconButtonExt.kt
@@ -0,0 +1,97 @@
+/*
+ * 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 androidx.compose.material
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.TooltipArea
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+
+/**
+ * IconButton is a clickable icon, used to represent actions. An IconButton has an overall minimum
+ * touch target size of 48 x 48dp, to meet accessibility guidelines.
+ * This version of [IconButton] enables tooltips on Desktop Devices and internally uses an [Icon] to show [icon].
+ *
+ * @param icon [ImageVector] to draw as icon inside this IconButton
+ * @param contentDescription text used by accessibility services and the tooltip
+ * to describe the action invoked by this IconButton.
+ * @param onClick the lambda to be invoked when this icon is pressed
+ * @param modifier optional [Modifier] for this IconButton
+ * @param iconTint tint to be applied to [icon]. See [Icon] for more information.
+ * @param enabled whether or not this IconButton will handle input events and appear enabled for
+ * semantics purposes
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this IconButton. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this IconButton in different [Interaction]s.
+ * @param extraContent content that is added after the [icon]. This is mainly used for showing [DropdownMenu]s.
+ */
+@OptIn(ExperimentalFoundationApi::class)
+@Composable
+fun IconButton(
+    icon: ImageVector,
+    contentDescription: String,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    iconSize: Dp = 24.dp,
+    iconTint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
+    enabled: Boolean = true,
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    extraContent: (@Composable () -> Unit)? = null
+) = TooltipArea(
+    tooltip = {
+        Surface(
+            modifier = Modifier.shadow(4.dp),
+            shape = RoundedCornerShape(4.dp),
+        ) {
+            Text(
+                text = contentDescription,
+                modifier = Modifier.padding(4.dp)
+            )
+        }
+    },
+    // taken from https://ux.stackexchange.com/questions/358/how-long-should-the-delay-be-before-a-tooltip-pops-up
+    delayMillis = 500,
+    modifier = modifier
+) {
+    IconButton(
+        onClick = onClick,
+        enabled = enabled,
+        interactionSource = interactionSource
+    ) {
+        Icon(
+            icon,
+            contentDescription,
+            Modifier.size(iconSize),
+            iconTint
+        )
+        extraContent?.invoke()
+    }
+}
diff --git a/briar-desktop/src/main/kotlin/androidx/compose/material/OutlinedTextFieldExt.kt b/briar-desktop/src/main/kotlin/androidx/compose/material/OutlinedTextFieldExt.kt
index d2defb118f2a555ff0f74e30b06fb92be6f03e3f..bdcf40982561e41f354744b73443bb4ed069292e 100644
--- a/briar-desktop/src/main/kotlin/androidx/compose/material/OutlinedTextFieldExt.kt
+++ b/briar-desktop/src/main/kotlin/androidx/compose/material/OutlinedTextFieldExt.kt
@@ -228,20 +228,8 @@ fun OutlinedPasswordTextField(
 private fun ShowHidePasswordIcon(
     isVisible: Boolean,
     toggleIsVisible: () -> Unit,
-) {
-    IconButton(
-        onClick = toggleIsVisible
-    ) {
-        if (isVisible) {
-            Icon(
-                imageVector = Icons.Filled.VisibilityOff,
-                contentDescription = i18n("access.password.show"),
-            )
-        } else {
-            Icon(
-                imageVector = Icons.Filled.Visibility,
-                contentDescription = i18n("access.password.hide"),
-            )
-        }
-    }
-}
+) = IconButton(
+    icon = if (isVisible) Icons.Filled.VisibilityOff else Icons.Filled.Visibility,
+    contentDescription = if (isVisible) i18n("access.password.hide") else i18n("access.password.show"),
+    onClick = toggleIsVisible
+)
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 0e98b2bb6f26449763a98af6a3e678ec59d7eb70..73772d5611d06d8060fb4e34eaf4e093439e7cb3 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
@@ -32,7 +32,6 @@ 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.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
@@ -161,11 +160,11 @@ private fun PendingContactRow(contactItem: PendingContactItem, onRemove: () -> U
             )
         }
         IconButton(
+            icon = Icons.Filled.Delete,
+            contentDescription = i18n("access.contacts.pending.remove"),
             onClick = onRemove,
             modifier = Modifier.padding(end = 4.dp).align(Alignment.CenterVertically)
-        ) {
-            Icon(Icons.Filled.Delete, i18n("access.contacts.pending.remove"))
-        }
+        )
     }
 }
 
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/SearchTextField.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/SearchTextField.kt
index fa7db6ab6e46d5e49c41236cd4462320dee3d9f9..1d32ffc4ca6c1039454f5bac0b17d6dc908e83d8 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/SearchTextField.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/SearchTextField.kt
@@ -20,7 +20,6 @@ package org.briarproject.briar.desktop.contact
 
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.Icon
 import androidx.compose.material.LocalTextStyle
@@ -53,15 +52,12 @@ fun SearchTextField(searchValue: String, onValueChange: (String) -> Unit, onCont
         },
         trailingIcon = {
             ColoredIconButton(
+                icon = Icons.Filled.PersonAdd,
+                iconSize = 20.dp,
+                contentDescription = i18n("access.contacts.add"),
                 onClick = onContactAdd,
                 modifier = Modifier.padding(end = 8.dp)
-            ) {
-                Icon(
-                    Icons.Filled.PersonAdd,
-                    i18n("access.contacts.add"),
-                    modifier = Modifier.size(20.dp)
-                )
-            }
+            )
         },
         modifier = Modifier.fillMaxSize()
     )
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
index c497b390ef051a91ce401ae6b567e78cfc3d5d32..aab5f86a7dc9555cfee3de2c04009555f84caadd 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
@@ -362,7 +362,7 @@ fun OwnLink(
     }
 }
 
-@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
+@OptIn(ExperimentalComposeUiApi::class)
 @Composable
 fun ContactLink(
     remoteHandshakeLink: String,
@@ -394,55 +394,32 @@ fun ContactLink(
             letterSpacing = (-0.5).sp,
         ),
         trailingIcon = {
-            TooltipArea(
-                tooltip = {
-                    Surface(
-                        modifier = Modifier.shadow(4.dp),
-                        shape = RoundedCornerShape(4.dp),
-                    ) {
-                        Text(
-                            text = i18n("contact.add.remote.paste_tooltip"),
-                            modifier = Modifier.padding(8.dp),
-                            color = MaterialTheme.colors.onSurface,
-                        )
+            IconButton(
+                icon = Icons.Filled.ContentPaste,
+                iconTint = MaterialTheme.colors.onSurface,
+                contentDescription = i18n("contact.add.remote.paste_tooltip"),
+                onClick = {
+                    val clipboardText = clipboardManager.getText().toString()
+                    if (clipboardText.isNotEmpty()) {
+                        setRemoteHandshakeLink(clipboardManager.getText().toString())
+                        coroutineScope.launch {
+                            scaffoldState.snackbarHostState.showSnackbar(
+                                message = i18n("contact.add.remote.link_pasted_snackbar"),
+                                duration = SnackbarDuration.Short,
+                            )
+                        }
+                        aliasFocusRequester.requestFocus()
+                    } else {
+                        coroutineScope.launch {
+                            scaffoldState.snackbarHostState.showSnackbar(
+                                message = i18n("contact.add.remote.paste_error_snackbar"),
+                                duration = SnackbarDuration.Short,
+                            )
+                        }
                     }
                 },
-                modifier = Modifier.padding(start = 30.dp),
-                delayMillis = 200,
-                tooltipPlacement = TooltipPlacement.ComponentRect(
-                    alignment = Alignment.BottomCenter,
-                )
-            ) {
-                IconButton(
-                    {
-                        val clipboardText = clipboardManager.getText().toString()
-                        if (clipboardText.isNotEmpty()) {
-                            setRemoteHandshakeLink(clipboardManager.getText().toString())
-                            coroutineScope.launch {
-                                scaffoldState.snackbarHostState.showSnackbar(
-                                    message = i18n("contact.add.remote.link_pasted_snackbar"),
-                                    duration = SnackbarDuration.Short,
-                                )
-                            }
-                            aliasFocusRequester.requestFocus()
-                        } else {
-                            coroutineScope.launch {
-                                scaffoldState.snackbarHostState.showSnackbar(
-                                    message = i18n("contact.add.remote.paste_error_snackbar"),
-                                    duration = SnackbarDuration.Short,
-                                )
-                            }
-                        }
-                    },
-                    Modifier.pointerHoverIcon(PointerIconDefaults.Default)
-                ) {
-                    Icon(
-                        Icons.Filled.ContentPaste,
-                        "contact.add.remote.paste_tooltip",
-                        tint = MaterialTheme.colors.onSurface
-                    )
-                }
-            }
+                modifier = Modifier.pointerHoverIcon(PointerIconDefaults.Default)
+            )
         }
     )
 }
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 a161b184b35a2ee179923fb6024bd90fbfff5fe7..eb6d737b942254902cd17f1688fdb8c45d2ae0ff 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
@@ -26,8 +26,6 @@ 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.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
@@ -92,10 +90,11 @@ fun ConversationHeader(
                 )
             }
             IconButton(
+                icon = Icons.Filled.MoreVert,
+                contentDescription = i18n("access.contact.menu"),
                 onClick = { setMenuState(ContactDropDown.State.MAIN) },
                 modifier = Modifier.align(Alignment.CenterVertically).padding(end = 16.dp)
             ) {
-                Icon(Icons.Filled.MoreVert, i18n("access.contact.menu"), modifier = Modifier.size(24.dp))
                 ContactDropDown(
                     menuState,
                     setMenuState,
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationInput.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationInput.kt
index ca555805176a263cca0b087ff4ee40e8be49f182..1787696cd4793c265fb8b2d21a18b104907d6969 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationInput.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationInput.kt
@@ -27,7 +27,6 @@ import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.AlertDialog
 import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
@@ -115,6 +114,8 @@ fun ConversationInput(
             leadingIcon = {
                 val windowScope = LocalWindowScope.current!!
                 ColoredIconButton(
+                    icon = if (image == null) Icons.Filled.Add else Icons.Filled.Close,
+                    contentDescription = if (image == null) i18n("access.attachment_add") else i18n("access.attachment_remove"),
                     onClick = {
                         if (image == null) {
                             pickImageUsingDialog(windowScope.window, updateImage)
@@ -122,27 +123,17 @@ fun ConversationInput(
                             updateImage(null)
                         }
                     },
-                    Modifier.padding(4.dp),
-                ) {
-                    if (image == null) {
-                        Icon(Icons.Filled.Add, i18n("access.attachment_add"), Modifier.size(24.dp))
-                    } else {
-                        Icon(Icons.Filled.Close, i18n("access.attachment_remove"), Modifier.size(24.dp))
-                    }
-                }
+                    modifier = Modifier.padding(4.dp),
+                )
             },
             trailingIcon = {
                 IconButton(
+                    icon = Icons.Filled.Send,
+                    iconTint = MaterialTheme.colors.sendButton,
+                    contentDescription = i18n("access.message.send"),
                     onClick = onSend,
                     modifier = Modifier.padding(4.dp).size(32.dp).pointerHoverIcon(PointerIconDefaults.Default),
-                ) {
-                    Icon(
-                        Icons.Filled.Send,
-                        i18n("access.message.send"),
-                        tint = MaterialTheme.colors.sendButton,
-                        modifier = Modifier.size(24.dp)
-                    )
-                }
+                )
             }
         )
     }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt
index 1b374b6dc80e2c05342d6d3c4ab8da2031b0b400..67511a08d261cf4248df9a67f210356554ce04b8 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt
@@ -18,7 +18,6 @@
 
 package org.briarproject.briar.desktop.conversation
 
-import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
@@ -28,9 +27,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.widthIn
-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.Text
 import androidx.compose.material.icons.Icons
@@ -38,7 +34,6 @@ import androidx.compose.material.icons.filled.PersonAdd
 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.TextAlign
 import androidx.compose.ui.unit.dp
 import org.briarproject.briar.desktop.contact.ConfirmRemovePendingContactDialog
@@ -49,6 +44,7 @@ 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.BriarLogo
+import org.briarproject.briar.desktop.ui.ColoredIconButton
 import org.briarproject.briar.desktop.ui.Constants.PARAGRAPH_WIDTH
 import org.briarproject.briar.desktop.ui.VerticalDivider
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
@@ -104,18 +100,12 @@ fun NoContactsYet(onContactAdd: () -> Unit) = Explainer(
     headline = i18n("welcome.title"),
     text = i18n("welcome.text"),
 ) {
-    IconButton(
+    ColoredIconButton(
+        icon = Icons.Filled.PersonAdd,
+        iconSize = 20.dp,
+        contentDescription = i18n("access.contacts.add"),
         onClick = onContactAdd,
-        modifier = Modifier.padding(end = 10.dp).size(32.dp)
-            .background(MaterialTheme.colors.primary, CircleShape)
-    ) {
-        Icon(
-            Icons.Filled.PersonAdd,
-            i18n("access.contacts.add"),
-            tint = Color.White,
-            modifier = Modifier.size(20.dp)
-        )
-    }
+    )
 }
 
 @Composable
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/expiration/ExpirationBanner.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/expiration/ExpirationBanner.kt
index a2b206d18a77939f1bc1702b0ce5bb42b95355cf..78a179ea7829394a66f4b71d8c8bcb6ab7f99d69 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/expiration/ExpirationBanner.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/expiration/ExpirationBanner.kt
@@ -108,8 +108,11 @@ fun ExpirationBanner(
             style = MaterialTheme.typography.body2,
             modifier = Modifier.weight(1f, true).padding(vertical = 12.dp)
         )
-        IconButton(hide, modifier = Modifier.padding(vertical = 4.dp)) {
-            Icon(Icons.Filled.Close, i18n("hide"), Modifier.size(24.dp))
-        }
+        IconButton(
+            icon = Icons.Filled.Close,
+            contentDescription = i18n("hide"),
+            onClick = hide,
+            modifier = Modifier.padding(vertical = 4.dp)
+        )
     }
 }
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 ea12210b752777f5bb4ea3b2f8658df28a536cbe..54b0b9ce8b2d99867dd01acd788e8b5b60aa5568 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
@@ -70,11 +70,11 @@ fun ContactDrawerMakeIntro(
             if (!viewModel.secondScreen.value) {
                 Row(Modifier.fillMaxWidth().height(HEADER_SIZE)) {
                     IconButton(
+                        icon = Icons.Filled.Close,
+                        contentDescription = i18n("access.introduction.close"),
                         onClick = { closeInfoDrawer(false) },
-                        Modifier.padding(start = 24.dp).size(24.dp).align(Alignment.CenterVertically)
-                    ) {
-                        Icon(Icons.Filled.Close, i18n("access.introduction.close"))
-                    }
+                        modifier = Modifier.padding(start = 24.dp).size(24.dp).align(Alignment.CenterVertically)
+                    )
                     Text(
                         text = i18nF("introduction.title_first", contactItem.displayName),
                         modifier = Modifier.align(Alignment.CenterVertically).padding(start = 16.dp),
@@ -97,11 +97,11 @@ fun ContactDrawerMakeIntro(
             } else {
                 Row(Modifier.fillMaxWidth().height(HEADER_SIZE)) {
                     IconButton(
+                        icon = Icons.Filled.ArrowBack,
+                        contentDescription = i18n("access.introduction.back.contact"),
                         onClick = viewModel::backToFirstScreen,
-                        Modifier.padding(start = 24.dp).size(24.dp).align(Alignment.CenterVertically)
-                    ) {
-                        Icon(Icons.Filled.ArrowBack, i18n("access.introduction.back.contact"))
-                    }
+                        modifier = Modifier.padding(start = 24.dp).size(24.dp).align(Alignment.CenterVertically)
+                    )
                     Text(
                         text = i18n("introduction.title_second"),
                         modifier = Modifier.align(Alignment.CenterVertically).padding(start = 16.dp),
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
index 498043f9c64792296f81d4ba0d31cabe9abf423d..3439a6694acf72a99d72702c1226e39bcd4f1d31 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
@@ -134,16 +134,18 @@ fun ErrorScreen(
         }
 
         if (onBackButton != null) {
-            IconButton(onClick = onBackButton) {
-                Icon(Icons.Filled.ArrowBack, i18n("access.return_to_previous_screen"))
-            }
+            IconButton(
+                icon = Icons.Filled.ArrowBack,
+                contentDescription = i18n("access.return_to_previous_screen"),
+                onClick = onBackButton
+            )
         }
 
         IconButton(
+            icon = Icons.Filled.Info,
+            contentDescription = i18n("access.mode.about"),
             onClick = { showAbout = true },
             modifier = Modifier.align(Alignment.BottomStart)
-        ) {
-            Icon(Icons.Filled.Info, i18n("access.mode.about"))
-        }
+        )
     }
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/login/StartupScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/login/StartupScreen.kt
index fb697f351a2682c68be41403572b6e18592c52b4..122df268c848f34ab482997d1204da1b15139b16 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/login/StartupScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/login/StartupScreen.kt
@@ -25,7 +25,6 @@ import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
-import androidx.compose.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
@@ -73,19 +72,19 @@ fun StartupScreenScaffold(
 
     if (showBackButton) {
         IconButton(
+            icon = Icons.Filled.ArrowBack,
+            contentDescription = i18n("access.return_to_previous_screen"),
             onClick = onBackButton,
             modifier = Modifier.align(Alignment.TopStart)
-        ) {
-            Icon(Icons.Filled.ArrowBack, i18n("access.return_to_previous_screen"))
-        }
+        )
     }
 
     IconButton(
+        icon = Icons.Filled.Info,
+        contentDescription = i18n("access.mode.about"),
         onClick = onShowAbout,
         modifier = Modifier.align(Alignment.BottomStart)
-    ) {
-        Icon(Icons.Filled.Info, i18n("access.mode.about"))
-    }
+    )
 }
 
 @Composable
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 93416d2d82496611ad1c7dfdc8fb26ba8e5dc778..6d5bdd8b69b382c798525b3140778c56909ee140 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
@@ -23,9 +23,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 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.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Surface
@@ -107,13 +105,15 @@ fun BriarSidebarButton(
     selected: Boolean,
     onClick: () -> Unit,
     icon: ImageVector,
-    contentDescription: String?,
+    contentDescription: String,
 ) {
     val tint = if (selected) MaterialTheme.colors.primary else MaterialTheme.colors.onSurface
     IconButton(
+        icon = icon,
+        iconSize = 30.dp,
+        iconTint = tint,
+        contentDescription = contentDescription,
+        onClick = onClick,
         modifier = Modifier.padding(vertical = 4.dp, horizontal = 12.dp),
-        onClick = onClick
-    ) {
-        Icon(icon, contentDescription, tint = tint, modifier = Modifier.size(30.dp))
-    }
+    )
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/AboutScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/AboutScreen.kt
index 8fc879972e0ce54e692edd574d664c4fcb2b199f..1e0d73c543e623b73b23bb93477da37576bcfa95 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/AboutScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/AboutScreen.kt
@@ -15,7 +15,6 @@ import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.lazy.rememberLazyListState
 import androidx.compose.foundation.rememberScrollbarAdapter
 import androidx.compose.foundation.text.selection.SelectionContainer
-import androidx.compose.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
@@ -55,11 +54,11 @@ fun AboutScreen(
     AboutScreen()
 
     IconButton(
+        icon = Icons.Filled.ArrowBack,
+        contentDescription = i18n("access.return_to_previous_screen"),
         onClick = onBackButton,
         modifier = Modifier.align(Alignment.TopStart)
-    ) {
-        Icon(Icons.Filled.ArrowBack, i18n("access.return_to_previous_screen"))
-    }
+    )
 }
 
 @Composable
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/ColoredIconButton.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/ColoredIconButton.kt
index f47501cf9c84e8ce7630c07d24e78c2d6ee000d4..870c8ce0a492e9718afc8d43704568d8f814ab36 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/ColoredIconButton.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/ColoredIconButton.kt
@@ -33,8 +33,10 @@ import androidx.compose.runtime.remember
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.input.pointer.PointerIconDefaults
 import androidx.compose.ui.input.pointer.pointerHoverIcon
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 
 @OptIn(ExperimentalComposeUiApi::class)
@@ -62,3 +64,29 @@ fun ColoredIconButton(
         content = content
     )
 }
+
+@OptIn(ExperimentalComposeUiApi::class)
+@Composable
+fun ColoredIconButton(
+    icon: ImageVector,
+    contentDescription: String,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    iconSize: Dp = 24.dp,
+    color: Color = MaterialTheme.colors.primary,
+    contentColor: Color = contentColorFor(color),
+    enabled: Boolean = true,
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+) = IconButton(
+    icon = icon,
+    contentDescription = contentDescription,
+    onClick = onClick,
+    modifier = modifier
+        .pointerHoverIcon(PointerIconDefaults.Default)
+        .background(color, CircleShape)
+        .then(Modifier.size(32.dp)),
+    iconSize = iconSize,
+    iconTint = contentColor,
+    enabled = enabled,
+    interactionSource = interactionSource
+)