UI and OCR refresh — 2026-10-07

Follow-up: Physical-phone verification is now complete, including actual ML Kit batch measurements and an editor layout fix. The desktop-stage limitations below describe the initial pass.

Interface

Applied ibelick baseline-ui to the existing KivyMD primitives: consistent spacing, readable contrast, shared colors, clear primary actions, and restrained surfaces. Web-specific CSS/ARIA instructions do not translate directly to this native Kivy app.

The shared palette now uses warm paper backgrounds and a single forest-green accent. Home has a prominent spending summary; navigation has quieter selected states. Receipt cards have more internal space. Capture, review fields, Insights, settings, the editor, dialogs and keypad use consistent surfaces. Capture buttons have shorter labels and 48dp targets. Settings has one Accurate option; the old Batch accurate preference maps to Accurate without losing its full-quality policy. No shader dependency or new animation was added: this interface benefits more from legibility and low rendering overhead than decorative effects.

Desktop previews use isolated mock data, not the user’s database:

Home Library Review
Home Library Review

Additional previews: Capture, Insights, Settings, 320×640 Home, and 892×412 Library.

OCR changes

  • Accurate mode now runs up to two Android receipts concurrently through the existing full-quality service. Single receipts use one worker. Desktop retains its existing four-worker limit. RECEIPT_APP_OCR_MAX_WORKERS remains an override; set it to 1 for devices with limited memory.
  • A worker-sized submission window avoids queueing a whole import. Cancellation prevents starting the remaining receipts; already-running recognition finishes safely. Old batches cannot clear a newer scan’s loading state or progress.
  • Progress reports completed receipts, while results remain in selection order. One failed receipt does not discard successful results from other workers.
  • Shared ML Kit client cleanup waits for in-flight tasks, so a failing receipt cannot close a recognizer still in use by another receipt.
  • Desktop segmentation attempts reuse one decoded/resized image per variant, retaining the same LANCZOS pixels, configurations, order, confidence checks and fallback variants. Original files are unchanged. Images remain worker-local.

The Android full-quality service has a more conservative early-exit gate than some of the former sequential UI path’s heuristics. Difficult receipts may take more attempts; the change does not reduce the fallback budget or image resolution. The pre-existing Smart and Fast options still trade retries for speed when the user explicitly selects them; they are not the default.

Evidence and limits

129 automated tests passed on Python 3.12, Kivy 2.3.1 and KivyMD 1.2.0. New regressions check overlapping full-quality jobs, cancellation of large batches, result ordering, failure isolation, stale progress, exact resized desktop pixels, recognition evidence, image closure, and deferred recognizer cleanup.

Recorded measurements:

  • Eight fixed-cost mocked receipts: approximately 2× scheduling throughput with two workers. This is a deterministic provider experiment, not phone inference.
  • One existing Tim Hortons fixture, real desktop Tesseract: 4.909s before and 4.726s after, with identical raw OCR text, date, total and merchant. This small single-run difference is a smoke check, not a general speed estimate.
  • Desktop render checks: 412×892, 320×640 and 892×412. Populated review, Insights and settings checked at 412×892. Native Android rendering, TalkBack, memory pressure and real ML Kit concurrent throughput have not been remeasured. Yesterday’s physical-device results belong to the previous build.

Reproduce with dependencies installed and a working desktop display:

python -m unittest discover -s tests
python tools/benchmark_ocr_batch.py
PYTHONPATH=. UI_LABEL=preview UI_SELECTED=1 python tools/preview_ui.py
PYTHONPATH=. UI_WIDTH=320 UI_HEIGHT=640 python tools/preview_ui.py
python tools/benchmark_ocr_receipts.py tests/TestRecipts --only Tim_Hortons

Memory

Used ECC knowledge-ops to retrieve the existing papernest OCR verification and patterns/papernest-ui-2026-10-06 entries before editing. This report is the repo-owned record; papernest/ui-ocr-refresh-2026-10-07 records the decisions, validation and remaining device checks for future sessions. Existing historical reports and their benchmark results are preserved.