Phase 1: wrap the reference web app in Capacitor for Android

Wraps reference/sp404-layers as a sideloadable APK without editing the
reference, which stays the frozen spec for the Phase 2 React port.

- sync-www.sh builds www/ from reference/ + native/, asserting each patch
  anchor so a reference change fails loudly rather than shipping broken
- drops the service worker (would serve a stale app after an APK update)
- haptics via a navigator.vibrate override, so buzz() needs no change
- localStorage mirrored into Preferences; sync load()/save() untouched
- hardware back: sheet -> Explore tab -> exit
- edge-to-edge handled in MainActivity: Android 16 + targetSdk 36 removes
  the opt-out, and a WebView never fills env(safe-area-inset-*), so insets
  are pushed into CSS custom properties instead

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-16 00:26:35 +03:00
commit 1a8a12f7f3
75 changed files with 3542 additions and 0 deletions

24
package.json Normal file
View File

@@ -0,0 +1,24 @@
{
"name": "sp404-layers",
"version": "1.0.0",
"private": true,
"description": "SP-404MK2 combo trainer, wrapped as an Android app",
"scripts": {
"sync:www": "bash scripts/sync-www.sh",
"sync": "npm run sync:www && npx cap sync android",
"apk": "npm run sync && cd android && ./gradlew assembleDebug",
"install:apk": "adb install -r android/app/build/outputs/apk/debug/app-debug.apk",
"run:android": "npm run apk && npm run install:apk",
"logcat": "adb logcat -s Capacitor:V Capacitor/Console:V chromium:V"
},
"dependencies": {
"@capacitor/android": "^8.5.2",
"@capacitor/app": "^8.1.1",
"@capacitor/core": "^8.5.2",
"@capacitor/haptics": "^8.0.2",
"@capacitor/preferences": "^8.0.1"
},
"devDependencies": {
"@capacitor/cli": "^8.5.2"
}
}