diff --git a/src/components/Hotkey.vue b/src/components/Hotkey.vue
new file mode 100644
index 0000000..c5790e3
--- /dev/null
+++ b/src/components/Hotkey.vue
@@ -0,0 +1,58 @@
+<!-- Make eslint not whine about putting spaces before the +'s -->
+<!-- eslint-disable prettier/prettier -->
+<template>
+    <template v-if="isCtrl"
+        ><div class="key">Ctrl</div
+        >+</template
+    ><template v-if="isShift"
+        ><div class="key">Shift</div
+        >+</template
+    >
+    <div class="key">{{ key }}</div>
+</template>
+
+<script setup lang="ts">
+import { GenericHotkey } from "features/hotkey";
+import { reactive } from "vue";
+
+const props = defineProps<{
+    hotkey: GenericHotkey;
+}>();
+
+let key = reactive(props.hotkey).key;
+
+let isCtrl = key.startsWith("ctrl+");
+if (isCtrl) key = key.slice(5);
+
+let isShift = key.startsWith("shift+");
+if (isShift) key = key.slice(6);
+
+let isAlpha = key.length == 1 && key.toLowerCase() != key.toUpperCase();
+if (isAlpha) key = key.toUpperCase();
+</script>
+
+<style scoped>
+.key {
+    display: inline-block;
+    height: 1.4em;
+    min-width: 1em;
+    margin-block: 0.1em;
+    padding-inline: 0.2em;
+    vertical-align: 0.1em;
+
+    background: var(--foreground);
+    color: var(--feature-foreground);
+    border: 1px solid #0007;
+    border-radius: 0.3em;
+    box-shadow: 0 0.1em #0007, 0 0.1em var(--foreground);
+
+    font-size: smaller;
+    text-align: center;
+    user-select: none;
+    transition: transform 0s, box-shadow 0s;
+}
+.key:active {
+    transform: translateY(0.1em);
+    box-shadow: none;
+}
+</style>
diff --git a/src/features/hotkey.tsx b/src/features/hotkey.tsx
index bfb958f..b716f9a 100644
--- a/src/features/hotkey.tsx
+++ b/src/features/hotkey.tsx
@@ -13,6 +13,7 @@ import type {
 import { processComputable } from "util/computed";
 import { createLazyProxy } from "util/proxies";
 import { shallowReactive, unref } from "vue";
+import HotkeyVue from "components/Hotkey.vue";
 
 export const hotkeys: Record<string, GenericHotkey | undefined> = shallowReactive({});
 export const HotkeyType = Symbol("Hotkey");
@@ -102,8 +103,8 @@ registerInfoComponent(
                 <br />
                 <h4>Hotkeys</h4>
                 {keys.map(hotkey => (
-                    <div>
-                        {hotkey?.key}: {hotkey?.description}
+                    <div v-if={hotkey !== undefined}>
+                        <HotkeyVue hotkey={hotkey as GenericHotkey} /> {hotkey?.description}
                     </div>
                 ))}
             </div>