# Native PWA design comparison The target is the actual unmodified Yuvomi 2.78.0 PWA, revision `10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`, not a new Material reinterpretation. Android 0.2.2/code 4 is a design pass on the existing native slice. **No page has accepted 1:1 visual/functional parity.** iOS has not received this Android pass. ## Implementation `PwaDesign.kt` maps measured palette/type roles, field shapes and module seals. `PwaIcons.kt` draws upstream module geometry on the native canvas. `PwaShell.kt` provides the capsule/FAB and native sheets; API 31+ uses an in-memory recorded native drawing layer for the blurred backdrop, with opaque older-API fallback. No HTML, JavaScript or browser surface is shipped. `NativePages.kt` / `NativeForms.kt` compose the supported native screens. Personal preferences and shopping lists are loaded from the real API. Widget visibility writes retain other stored widget entries/options; they are personal, not household default edits. Entries hidden/denied to this native UI are retained; new supported selections can be added. Saving is disabled if preference loading did not provide a known configuration, rather than overwriting unknown data. ## Reproducible comparison The fixture has synthetic account/data only: one task, pinned note, list/item, four widgets (`tasks`, `calendar`, `shopping`, `notes`) and three supported mobile favorites (`tasks`, `kitchen`, `notes`). This deliberate **supported-slice** setup is not the PWA's complete/default dashboard or a full navigation comparison. Native integration exports `login`, `dashboard`, `tasks`, `notes`, `shopping`, each in light/dark, plus the compatible `native-dashboard.png` and `viewport.json`. Capture clears `FLAG_SECURE` only in that temporary-fixture test and restores it in `finally`. It waits for IME/window settling and crops `native-screen`, excluding system bars. Ordinary builds remain screenshot-protected. The collector requires the whole allow-listed gallery from exactly one device, rejects missing/invalid/ambiguous output and removes only known stale evidence. Observed API-35 content viewport: **720 × 1184 px, density 2, fontScale 1**, hence 360 × 592 CSS pixels for the browser reference. Root bounds are `[0,48,720,1232]` on the 720 × 1280 emulator. Do not compare a full native root image against a 360 × 640 PWA content viewport. ```sh ANDROID_SERIAL=emulator-5554 python3 scripts/test-integration.py /path/to/pinned-upstream --android --cookie-without-secure PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=ubuntu24.04-x64 \ PLAYWRIGHT_BROWSERS_PATH=/path/to/external/browsers \ FONTCONFIG_FILE=/path/to/isolated/android-roboto/fonts.conf \ python3 scripts/capture-pwa-reference.py /path/to/pinned-upstream \ --playwright-module /path/to/external/node_modules/playwright \ --width 360 --height 592 --output artifacts/visual/pwa-360x592 node scripts/compare-native-pwa.mjs /path/to/external/node_modules/playwright \ /path/to/build/app/outputs/native-screenshots artifacts/visual/pwa-360x592 \ artifacts/visual/comparisons ``` Playwright/Chromium and the emulator's variable Roboto are external tooling, not application dependencies. The reference recorder captures real browser PNGs and computed styles, without editing upstream files. It uses a temporary loopback-only HTTPS fixture, blocks external browser requests and does not export credentials, cookies, generated certificates or keys. Dates/greetings and initial account colors can vary; compare those separately from geometry. Native integration keeps OIDC enabled for the redirect-refusal regression, whereas the password-login reference disables it; their extra SSO controls are not a valid exact login comparison. The comparison compositor refuses mismatched viewport/image sizes or font scale, places the actual captures side by side and records their SHA-256 hashes. It does not replace either screenshot, normalize away UI differences or assert acceptance. ## Explicit remaining differences - Full calendar navigation and its widget action are absent, not fake buttons. - Native SSO/recovery/invites and most modules/settings remain unimplemented. - Advanced task categories/assignment/statuses, note rendering/categories and shopping quick-add/details do not yet match all PWA interactions. - Card internals, utility icons, shadows/glass and form geometry still require visual refinement and broader device/font-size/accessibility testing. - The three supported favorites stand in for unavailable native destinations; this is not full preference/navigation parity. - Apple UI/build validation remains blocked as recorded in [validation](validation.md). Screenshot existence and passing CRUD tests are evidence, **not visual acceptance**. See [native parity](native-parity.md) for the complete scope. ## Reviewed examples from this pass Left is the real PWA, right the actual native capture. Remaining differences are deliberately visible, including the absent calendar action, widget spacing, utility icon/control differences and upstream's dashboard-customization hint. - [Dashboard, light](images/dashboard-light-comparison.png) - [Dashboard, dark](images/dashboard-dark-comparison.png) - [Tasks, light](images/tasks-light-comparison.png) - [Notes, dark](images/notes-dark-comparison.png)