diff --git a/apps/machine/src/App.vue b/apps/machine/src/App.vue
index 48cfc8a..f28b639 100644
--- a/apps/machine/src/App.vue
+++ b/apps/machine/src/App.vue
@@ -8,6 +8,7 @@ import { classifyInitError } from '@/services/init-error'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Sun, Moon } from 'lucide-vue-next'
+import PairingWizard from '@/components/PairingWizard.vue'
const atmStore = useAtmStore()
const route = useRoute()
@@ -61,6 +62,14 @@ const isKnownMaintenanceScreen = computed(
() => !!atmStore.initError && atmStore.initError in MAINTENANCE_SCREENS
)
+/**
+ * `unpaired` is interactive, not a dead-end: render the QR-pairing wizard so
+ * the operator can scan a spire-seed on-machine (aiolabs/bitspire#52). The
+ * wizard only works under Electron (needs the seed-persist + relaunch bridge);
+ * in browser dev it falls back to the static card.
+ */
+const showPairingWizard = computed(() => atmStore.initError === 'unpaired' && isElectron)
+
const formattedBtcPrice = computed(() => {
if (atmStore.btcPrice === null) return null
const local = `${atmStore.fiatCode}/BTC: ${atmStore.fiatSymbol}${Math.round(atmStore.btcPrice).toLocaleString()}`
@@ -160,9 +169,12 @@ function toggleLiveServices() {
+
+
+