High-fidelity mockups for every screen in the PRD, grounded in Apple's Liquid Glass adoption guidance and the offline Apple API docset — with two options where the design decision is genuinely open, and a recommendation for each.
Flighty's Apple Design Award philosophy is the bar: "We want it to work so well that it feels almost boringly obvious." World-class iOS design in 2026 is not decoration — it is six disciplines applied without exception. Every screen below is judged against these.
Flighty borrowed 50 years of airport departure-board conventions. Intelli-Expense borrows the two artifacts its users already trust: the paper receipt (the scan is always visible, always primary) and the finance ledger (tabular numerals, per-currency subtotals, date-grouped rows). Nothing needs explaining because it looks like what it replaces.
Source: Apple "Behind the Design: Flighty" (developer.apple.com/news)Expense apps drown users in numbers. Each screen gets exactly one large, light-weight money figure (the group total, the extracted total); everything else steps down through weight and color, not size. Calm hierarchy is what separates Flighty-class apps from dashboards.
Source: swiftui-design-principles skill — weight-based hierarchy, ≤5 type sizesiOS 26's Liquid Glass exists to "bring focus to the underlying content." So: no custom bar backgrounds, floating system tab bar that minimizes on scroll, scroll-edge effects instead of opaque headers, and glass reserved for the few controls that deserve it — never decorative.
Source: docset /documentation/technologyoverviews/adopting-liquid-glassThe extraction pipeline's honesty is the product's soul. When the model is torn, the UI offers two tappable readings with a calm "which is correct?" — no red, no alarm, no modal. The user is the confirmer, not the debugger. This turns the scariest part of AI UX (being wrong) into the most delightful (being asked).
PRD §5.4, §6.3 — ambiguity UX as a first-class requirementCapture → review → save is the entire app; everything else is furniture. The capture affordance is reachable in one thumb-tap from anywhere, processing shows the receipt (not a spinner), and Save is one prominent action. Speed is a design feature: p50 < 5s is in the PRD as a UX number, not a perf number.
PRD §5.4, §9 — invest UX in the heart of the appEmpty states teach the next action. The Apple Intelligence gate explains and self-dismisses. Model-downloading degrades to deterministic extraction with a one-line note. Nothing dead-ends, nothing shows a raw error, and no failure ever loses a captured image.
PRD §5.0, §5.5, §6.4 — designed failure states are must-havesRestraint is the system: SF Pro only, semantic system colors plus one brand accent, a base-4 spacing grid, and five fixed expense-type identities (SF Symbol + accent color) reused identically in review, lists, totals and CSV — exactly as the PRD's §4.5 demands.
| Token | Rule | Why (grounded) |
|---|---|---|
| Type | SF Pro. Five roles only: LargeTitle 34 bold · hero money ~31 light with tabular numerals · body 17/15 · footnote 13 · caption 11 semibold uppercase. Dynamic Type styles, never fixed sizes in code. | Weight-based hierarchy; money in light weight reads elegant, not shouty. Tabular numerals so amounts align in every list. |
| Color | Semantic system colors everywhere (systemGroupedBackground, secondaryLabel, separator). One brand accent. Type colors only ever mean expense type. | Free dark mode + accessibility contrast; Liquid Glass adapts semantic colors automatically. Color that always means the same thing becomes navigation. |
| Spacing | 4/8 grid: 16pt content margins, 12–16pt card padding, 24pt between sections. | iOS 26 grouped lists gained taller rows and bigger radii — standard components inherit the new metrics for free. |
| Shape | System-provided radii; custom cards use concentric corners. Never hand-tuned per view. | "The shape of the hardware informs the curvature of controls" — concentric shapes are an explicit iOS 26 guideline. |
| Glass | System bars/sheets only, plus exactly two custom uses: the capture accessory and the floating Save bar. | Docset: "Avoid overusing Liquid Glass effects… limit to the most important functional elements." |
| Haptics | .success on save, .selection on chip picks, .warning only for duplicate notice. | PRD §5.5; confirmation you can feel closes the loop faster than any toast. |
Dark mode costs nothing where the system owns color: semantic backgrounds, labels, separators and Liquid Glass adapt automatically. Only the custom tokens need explicit dark variants — each defined once as an asset-catalog color set with Any + Dark appearances. Code references the named color; it never branches on colorScheme.
| Token | Light | Dark | Rule |
|---|---|---|---|
| Ledger Green | #1E7A55 | #34C08A | Brightens the way Apple's system tints do — deep pigment on white, luminous on black. Still the only brand accent: Save, selection, active tab, links. |
| Ledger Green Soft | #E7F2ED | rgba(52,192,138,.16) | Selected-chip and icon-tile fill becomes a translucent green wash so it sits on any dark surface. |
| Food | #FF9500 | #FF9F0A | The four vivid type colors follow Apple's documented system-color dark variants (systemOrange, systemIndigo, systemBlue; taxi's custom teal brightens in step with systemTeal). Identity is unchanged — same symbol, same meaning, slightly more luminous. |
| Hotel | #5856D6 | #5E5CE6 | |
| Flight | #007AFF | #0A84FF | |
| Taxi / Transport | #2AA8BD | #3FC2D9 | |
| Other | #8E8E93 | #8E8E93 | systemGray is identical in both appearances — no variant needed. |
| Attention edge | #FF9500 | #FF9F0A | The 2.5pt warm edge tint on uncertain fields tracks the Food/systemOrange pair. |
| Duplicate banner | #FFF8EC / #8A4D05 | #2B2013 / #F0B35E | Same warm, non-alarming voice: dim amber surface, luminous amber text. Still never red. |
| Everything else | semantic system colors | systemGroupedBackground → true black canvas, secondarySystemGroupedBackground → #1C1C1E cards, labels/separators/fills adapt for free. Hardcoding any of these is a defect. | |
#1C1C1E cards, brightened Ledger Green on the capture bar and active tab. Same layout, zero code branches.colorScheme branches and raw hex are both defects.#1C1C1E cards, #2C2C2E tertiary fills. Shadows stay system-default; glass gets its depth from the material, not from heavier borders.#1C1C1E and white-on-Ledger-Green in its dark variant. Test at Increased Contrast and with Reduce Transparency, which replaces glass with solid surfaces.LedgerGreen, ExpenseFood…), each with Any + Dark appearances; SwiftUI Color("LedgerGreen") / generated symbols. No @Environment(\.colorScheme) in feature code..background, .secondary, list styles) — grouped lists, bars and sheets are already correct.design/ui-spec.html; acceptance #10 (fully usable in dark mode) covers this.Onboarding does two jobs — say what the app does, get Apple Intelligence on — then gets out of the way. One welcome screen, one conditional gate. Most users never see the gate at all.
.appleIntelligenceNotEnabled, .deviceNotEligible); .modelNotReady lets the user in immediately — hard-blocking a person standing at a cash register would lose the receipt.scenePhase and re-checking SystemLanguageModel.default.availability.SystemLanguageModel.default.availability branching per PRD §5.0; re-check on scenePhase == .active.UIApplication.openSettingsURLString only — no private App-prefs: URLs (App Review risk, PRD §5.0).@AppStorage, never in CloudKit.Three tabs (Groups · Receipts · Settings) is settled by the PRD. The open decision is the "prominent Add affordance." iOS 26 gives us a new, honest answer: the tab bar's bottom accessory. Both options below show the same Groups home screen.
tabViewBottomAccessory(content:) (iOS 26.0+, per the docset) floats the accessory above the tab bar and collapses inline with it when the bar minimizes on scroll — capture stays one thumb-tap away on both browsing tabs without stealing a tab slot or hiding in a corner.Where a trip becomes a record: one hero total per currency, the per-type breakdown as quiet chips, then receipts by date. Export lives in the toolbar, exactly where iOS puts share actions.
secondaryLabel-small. No pie charts, no progress rings — PRD non-goals kept out.List + sections keyed by receipt date; header card as a plain section header view (no custom bar backgrounds — glass stays system-owned).ToolbarItem with square.and.arrow.up → §8 zip flow. Toolbar icons only, labeled for VoiceOver (docset toolbars guidance).ExpenseGroup (PRD §4.1), formatted with Decimal.FormatStyle.Currency per receipt currency.VisionKit's document camera is system UI — we design what happens the instant the shutter closes. The receipt itself is the loading indicator: the user watches their capture being read, never a spinner.
VNDocumentCameraViewController wrapped in UIViewControllerRepresentable; multi-page → one ReceiptAttachment per page.TimelineView + linear gradient mask, gated on accessibilityReduceMotion.The PRD calls this screen the explicit priority. Both options obey the same laws: the paper stays visible, ambiguity is two tappable chips, required fields (type + payment) are structurally unmissable, and Save is the single hero action. They differ in what comes first: the document order or the user's attention.
.selection haptics and fills the field; more than ~3 ambiguous fields ⇒ fall back to empty editable fields (PRD §5.4's wall-of-choices rule)..success haptic + the receipt visibly flying into its group row.The flat, searchable record of everything — and the per-receipt page where the original paper and the extracted record live side by side, forever editable.
.searchable on this tab, sliding up with the keyboard per the Liquid Glass search conventions. Filters are chips that compose (group ∧ type ∧ payment ∧ has-photo, PRD §7) and each shows an ✕ to remove — state visible, reversible, no hidden filter drawer.ExtractionRecord.rawOCRText; the footnote states when it was scanned and that extraction was on-device. Trust is shown, not claimed..searchable + #Predicate-backed filters; month sections from Date.FormatStyle().month(.wide).year().TabView(.page) over attachments; zoom via full-screen cover with pinch (MagnifyGesture).thumbnailData only — 1,000-receipt scroll stays smooth (PRD §9).Manual entry is the review form minus the image, opened as an inset sheet — four required fields and nothing else demanding attention. Settings is deliberately boring: defaults, status, privacy, version.
.presentationDetents([.large]) with system glass. No custom chrome to maintain.Locale.current including per-app language (PRD §3.2-A).The whole app funnels here: group detail → share icon → a zip your finance team opens without questions. The UI is a progress card that morphs into the system share sheet.
Berlin-June-2026.zip, date folders, 2026-06-14_Lufthansa_EUR-420.00.jpg — a finance admin can audit it without opening the app. Manual entries get a .txt stub so the record is complete (PRD §8).ShareLink / UIActivityViewController from a temp URL; clean up in defer.| Screen | Options shown | Recommendation | Primary APIs (verified in docset) |
|---|---|---|---|
| Welcome + AI gates | 1 (+2 gate states) | As shown; gate auto-dismisses on foreground | SystemLanguageModel.default.availability, @AppStorage, scenePhase |
| Structure / Add | A capture accessory · B toolbar + | A, with B's menu behind ⋯ / long-press | TabView + Tab, tabViewBottomAccessory(content:) (iOS 26.0+), tabBarMinimizeBehavior |
| Groups home | 1 (+ empty state) | Inset-grouped rows, per-currency totals, type dots | List, ContentUnavailableView, swipe actions |
| Group detail | 1 | Hero total + breakdown chips + date sections | List sections, ToolbarItem export, computed totals on ExpenseGroup |
| Processing | 1 | Scan-line over the capture, stage hints, Cancel | VNDocumentCameraViewController, RecognizeDocumentsRequest, TimelineView |
| Review & Confirm | A anchored form · B triage-first | A + B's ambiguity count/auto-scroll; B = A/B candidate | Form/List, choice chips as Button rows, @Generable alternates, sensoryFeedback |
| Receipts | 1 | Month sections, composable filter chips | .searchable, #Predicate, TabView(.page) in detail |
| Manual entry | 1 | Amount-hero sheet, optional fields folded | .presentationDetents, .keyboardType(.decimalPad), Decimal end-to-end |
| Settings | 1 | Defaults · CSV · iCloud status · privacy · version | Form grouped, CloudKit status via CKContainer.accountStatus |
| Export | 1 | Progress card → system share sheet | ShareLink, background zip, temp-dir cleanup |
/documentation/swiftui/view/tabviewbottomaccessory(content:) (Platforms: iOS 26.0+), /documentation/swiftui/tabrole/search, /documentation/technologyoverviews/adopting-liquid-glass — floating tab bars, glass restraint, sheet/list metrics, toolbar and search conventions.