diff --git a/plan.md b/plan.md
new file mode 100644
index 0000000..4090e7b
--- /dev/null
+++ b/plan.md
@@ -0,0 +1,139 @@
+# Phone Barcode Scanner — Library Refactor Plan
+
+## Goal
+
+Refactor the current monolithic app into a reusable library that can be embedded
+as a feature in other applications, with a clean API and self-contained UI.
+
+
+## Project Structure
+
+```
+phone-barcode/
+ lib/
+ scanner.mjs — camera, decode pipeline, ZXing wrapper (no DOM)
+ scanner-ui.mjs — clones template node into a container, wires controls
+ template.html — UI markup fragment (no /
, just the widget)
+ style.css — scoped styles for the widget
+ index.mjs — public API (re-exports)
+ vendor/
+ zxing.min.js — bundled, populated by `make build`
+ demo/
+ index.html — demo app, built as a consumer of the library
+ app.mjs
+ Makefile
+ package.json
+```
+
+
+## API
+
+### Low-level: bring your own container
+
+```javascript
+import { Barcode_Scanner } from './phone-barcode/index.mjs';
+
+const scanner = new Barcode_Scanner(container_el, {
+ mode: 'continuous', // 'continuous' | 'single' | 'aim-tap'
+ on_scan(text, format) {}, // called on each successful decode
+ on_close() {}, // called when user dismisses
+});
+
+await scanner.start();
+scanner.stop();
+```
+
+The scanner clones the UI template into `container_el` and takes it over.
+Caller is responsible for showing/hiding the container.
+
+### High-level: managed dialog
+
+```javascript
+import { scan_once, scan_continuous } from './phone-barcode/index.mjs';
+
+// Creates a