aboutsummaryrefslogtreecommitdiffstats
path: root/src/style.css
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-06-23 23:05:52 -0700
committerAdam Soltys <[email protected]>2026-06-23 23:05:52 -0700
commitd5e55c9c577feb6f8000bad3c37045a2cd7c9b4c (patch)
treec4260128cae53c949c29e1fe802c4d4a5aca94d0 /src/style.css
parentca7d85e8603ad5ee6a31afbf56777cedfc3931b5 (diff)
downloadcoinosv3-d5e55c9c577feb6f8000bad3c37045a2cd7c9b4c.tar.gz
coinosv3-d5e55c9c577feb6f8000bad3c37045a2cd7c9b4c.zip
Add QR scanner to the send page (lazy-loaded decoder)
Scan a Bitcoin address, a BIP21 URI (fills address + amount), or a signed-transaction QR (opens a broadcast confirmation, then relays it) from a viewfinder button on the Send form. Decoder strategy keeps the main bundle small: - Prefer the native BarcodeDetector (Chrome desktop/Android) — no lib. - Otherwise lazy-load jsQR from a separate dist/jsqr.js, only when the scanner is opened. jsQR stays out of index.html (~424 KB vs ~551 KB) and off the initial load. - The service worker precaches jsqr.js so offline scanning works for installed PWAs on browsers without BarcodeDetector. The scanner needs a camera + secure context, so it never shows on a standalone file:// page; offline air-gapped signing is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'src/style.css')
-rw-r--r--src/style.css7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/style.css b/src/style.css
index 8a32bf4..69c3169 100644
--- a/src/style.css
+++ b/src/style.css
@@ -199,6 +199,13 @@ textarea { resize: vertical; min-height: 84px; font-family: var(--mono); font-si
border-radius: 50%; animation: spin .7s linear infinite; display: inline-block; vertical-align: middle;
}
.spinner.sm { width: 13px; height: 13px; border-width: 2px; }
+
+/* ---- qr scanner overlay ---- */
+.scan-overlay { position: fixed; inset: 0; z-index: 60; background: #000; display: flex; align-items: center; justify-content: center; overflow: hidden; }
+.scan-overlay video { width: 100%; height: 100%; object-fit: cover; }
+.scan-frame { position: absolute; width: min(70vw, 260px); height: min(70vw, 260px); border: 3px solid #fff; border-radius: 18px; box-shadow: 0 0 0 9999px rgba(0,0,0,0.45); }
+.scan-hint { position: absolute; bottom: 70px; left: 0; right: 0; text-align: center; color: #fff; font-size: 14px; padding: 0 24px; text-shadow: 0 1px 3px rgba(0,0,0,0.7); }
+.scan-close { position: absolute; top: 16px; right: 16px; width: 42px; height: 42px; border-radius: 50%; background: rgba(0,0,0,0.5); color: #fff; border: 1px solid rgba(255,255,255,0.4); font-size: 18px; line-height: 1; cursor: pointer; }
@keyframes spin { to { transform: rotate(360deg); } }
.toast {
position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);