The Accounts calendar strip passed every preview check. On my test iPhone, it answered the wrong question.

Mid-design on Phase O, I deepened the brief: “click the calendar → full-screen, then click a day → day mode.” That sentence was not in any prior specification. It came out of a device QA run on my test iPhone, where I had tapped through the Phase K Accounts screen and realised the horizontal daily-activity strip was answering the wrong question.

The strip had seemed like the natural call. It worked. That was the problem.

What Phase K shipped

Phase K rebuilt the Accounts tab into a stacked-module screen: total-across-accounts hero with a rotating sigil, a 30-day balance trend chart below it, a horizontally-scrollable daily-activity strip at the bottom. An AccountListView sat underneath. Individual account rows carried name, type badge, balance, swipe-to-delete, and a “+” toolbar. The strip is the standard pattern for recent activity in a finance app: compact, one tile per day, scrollable. Not a placeholder. The deliberate design call for that tier of the screen, chosen because it keeps the module’s vertical footprint small while making daily patterns visible.

In the SwiftUI preview, the strip looked correct. In preview, it was correct: tiles rendered, horizontal scroll worked, the layout held. Preview verified everything it could verify.

What device QA found

The full J→K→L→M arc (Energy Dock navigation, rearrangeable Accounts modules, the DNA sweep) was code-signed against my Apple Development identity, built for device, and installed on my test iPhone. First hands-on QA of the whole stack.

Three findings from that pass targeted the calendar surface: issues #4, #7, and #8.

A horizontal strip answers “how much activity was there recently?” That is a question about density and existence. The strip handles it well enough. You can see whether a given week was busy, whether there are gaps, whether the month looks different from the one before. But the question a finance app user usually brings is more specific: “what happened on the 14th?” To answer that from the strip, you scroll the month-long horizontal list to the right tile, then read a compact summary. The interaction model assumes scanning; the use case requires locating.

In Xcode, you see tiles. You do not see a user arriving at the screen with a specific question in mind, a date they are trying to confirm. In preview, scanning and locating look identical. On the device, they did not.

The brief deepened mid-design

Phase O entered the backlog as a strip-to-calendar swap. That is not what shipped.

The design session produced a different deliverable: three navigation levels where the brief had implied one surface replacement. Accounts shows a calendar inline at rest. Tap it and a full-screen month view pushes; tap a date in that view and day mode pushes after it. The flow settled during the session itself: how many levels, what each push contained, what Back should do at each level. It drew from what the strip had failed to provide: a full month in view and drill-down to the day.

Variant B shipped: full-screen month view plus day mode.

Out of scope: calendar-driven editing, event creation, Calendar framework integration. Both views are read-only.

What preview cannot verify

A SwiftUI preview renders a component. It does not simulate a navigation stack.

That distinction becomes critical on a three-level flow. The back-navigation behaviour of Calendar → Day → Back is a runtime property of the NavigationStack that wraps both views. It is not a property of either view in isolation. You can preview the month calendar. You can preview the day detail. You cannot preview what Back does after a user drills two levels in, because the stack that holds the navigation history is not present in preview at all.

This is not a failure of preview. It is the scope of preview. The risk is treating preview coverage as a proxy for integration. When a component passes every visual check in isolation, the preview data cannot tell you whether it composes correctly with the surrounding navigation stack.

Round-2 QA

The back-nav bug was filed as A8 in the round-2 QA pass. Symptom: Calendar → Day → Back dropped the calendar from the stack and landed directly on Accounts. The intermediate level did not survive the return journey.

The fix landed 2026-06-19, in the same branch as the brand fonts and the 20-palette theme library. Device-verified on my test iPhone before the branch closed.

The pattern

SwiftUI Previews compress the component feedback loop. For isolated UI work (a sigil, a badge, a form field, a list row) they are the correct tool, fast and accurate at the scope they cover.

Navigation is outside that scope. So is ergonomics: whether Back is reachable after two levels of push, whether the gesture is comfortable at the top-left of a screen the user arrived at from depth, whether the visual hierarchy communicates the return path. None of that surfaces in preview. All of it surfaces in the first two taps on the device.

The deeper issue is what “it works in preview” means. It means the component renders correctly: layout right, colours right, data shapes fit. That is worth verifying. It is not a statement about whether the component belongs in the navigation at that depth, or whether the user can return from it cleanly, or whether the transition it triggers matches expectation given everything that surrounds it. Preview is isolated by design. The isolation is the feature; the risk is forgetting it.

The Phase O brief was wrong before Phase O started. Not directionally wrong: the calendar direction was correct. But wrong about what “a calendar on the Accounts screen” actually required to be usable. The strip design got built and previewed. It passed every check. Code-signed. Installed on my test iPhone before anyone knew it was the wrong answer. The QA run that identified the gap could have happened two sprints earlier, before the strip was wired to real data, saving a round of implementation work.

For navigation-heavy mobile UI (more than two levels, any Back button with history behind it), on-device runs belong in the design phase, not at the end of implementation. Preview is the component quality gate. The device is the integration test.

Phase O’s month calendar exists because I put the Phase K strip on my test iPhone and it answered the wrong question. The back-nav regression got caught the same way: fixed version on the same device. Both times, the problem surfaced under a thumb on actual glass. Not in a preview pane.

All writing