diff --git a/frontend/src/components/AppShell.vue b/frontend/src/components/AppShell.vue
index c1e471e..d5fea3d 100644
--- a/frontend/src/components/AppShell.vue
+++ b/frontend/src/components/AppShell.vue
@@ -1,9 +1,10 @@
diff --git a/frontend/src/stores/ui.ts b/frontend/src/stores/ui.ts
new file mode 100644
index 0000000..0c49810
--- /dev/null
+++ b/frontend/src/stores/ui.ts
@@ -0,0 +1,14 @@
+import { defineStore } from "pinia";
+import { ref } from "vue";
+
+// Cross-component UI signals that don't belong to any single view (e.g. a
+// global shortcut in the app shell asking the board to act).
+export const useUiStore = defineStore("ui", () => {
+ // Bumped to ask the board to open + focus its quick-add composer.
+ const composeTick = ref(0);
+ function requestCompose() {
+ composeTick.value++;
+ }
+
+ return { composeTick, requestCompose };
+});
diff --git a/frontend/src/views/BoardView.vue b/frontend/src/views/BoardView.vue
index 62d61be..67bc498 100644
--- a/frontend/src/views/BoardView.vue
+++ b/frontend/src/views/BoardView.vue
@@ -2,14 +2,24 @@
import { computed, onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
import { useNotesStore, type Note, type NoteView } from "../stores/notes";
+import { useUiStore } from "../stores/ui";
import QuickAdd from "../components/QuickAdd.vue";
import NoteCard from "../components/NoteCard.vue";
import NoteEditor from "../components/NoteEditor.vue";
const notes = useNotesStore();
const route = useRoute();
+const ui = useUiStore();
const editing = ref(null);
+const quickAdd = ref | null>(null);
+
+// The global `c` shortcut bumps composeTick; reopen the composer when we're
+// already on the board (a fresh navigation autofocuses it via the prop).
+watch(
+ () => ui.composeTick,
+ () => quickAdd.value?.open(),
+);
function viewForRoute(name: unknown): NoteView {
if (name === "archive") return "archived";
@@ -77,7 +87,7 @@ async function onDrop(target: Note) {