design: device-first onboarding + soft trial paywall prototype (Graphite / Aurora)

RE
3d ago
+3054-0

What changed and why

A clickable design prototype (not production code) of a device-first first-run flow, in two visual directions, for Nik to review. Proposed with Reid Moncada.

  • Pairing gates onboarding. Right after sign-in we ask "Do you have your Omi?". Yes → find → pair → the existing steps (name, language, permissions, voice intro). It's on the way / I don't have one → buy the pendant ($129, was $179) → order summary → a waiting room whose only way forward is pairing; a delivery push deep-links back into pairing.
  • Soft paywall at the end of onboarding, where intent peaks: Free vs Unlimited, a trial timeline, Yearly preselected, and "Continue with Free" always visible.
  • Trial-length test: the same paywall at 3 / 7 / 14 / 30 days (TrialLength in lib/src/content.dart); headline, button, caption and reminder day follow the length.
  • Two directions: Graphite (black, white, SF-style) and Aurora (black with a violet→amber "listening" glow, pill buttons). Every visual reads from one token class (DfTheme), so mapping a direction onto OmiColors/OmiType later is mechanical.

It lives in prototypes/device_first_onboarding/ as a standalone Flutter package that depends only on Flutter. It does not touch app/, so it can't affect the shipping app. The app/lib UX contract and ARB localisation rules don't apply until a direction moves into the app; the README describes that path. Opened as a draft for direction/feedback, not to merge as is.

Figma: "Omi — Paywall Redesign", pages E · Device-first · Graphite and F · Device-first · Aurora.

Product invariants affected

none

How it was verified

Flutter can't be installed in my sandbox, so I ran checks on GitHub Actions in my fork (Flutter 3.44.5, matching mobile-app-checks.yml), on a fork-only branch whose sole workflow is the check below:

cd prototypes/device_first_onboarding
flutter pub get
dart format --line-length 120 lib test   # no changes
flutter analyze                          # No issues found
flutter test --exclude-tags screenshots  # 90 tests, all passed
flutter test --tags screenshots --update-goldens   # rendered all 40 screens with Roboto

I reviewed the rendered screens (below) for both directions. Not verified: running on a physical device. To try it: flutter create --platforms=ios,android,web . && flutter run inside the folder; the launcher picks direction and trial length.

Tests

test/flow_test.dart:

  • every screen in both directions at 390×844 and 375×667 with no layout overflow (80 cases)
  • the has-an-Omi path from Welcome through pairing and onboarding to a started trial
  • the no-Omi path (buy → checkout → waiting room → pairing) and the on-the-way path (waiting room → delivery push → pairing)
  • each trial arm's copy and "Continue with Free"
  • choosing Monthly
  • "See my plan" stays disabled until setup completes
  • the launcher

test/screenshots_test.dart (tag screenshots) renders review images only.

UI evidence

UI-Evidence: none -- standalone prototype outside app/; screens rendered by flutter test in CI and shown below.

Graphite
Graphite

Aurora
Aurora

Open questions for review

  • Is requiring a paired device before the rest of onboarding the right call, versus letting phone-mic users through?
  • Monthly Unlimited price (shown as $29.99), shipping price and delivery window, and whether Plus belongs on this paywall.
  • Trial plumbing: Stripe trial_period_days today, or App Store / Play intro offers.

Failure-Class: none

🤖 Generated with Claude Code

https://claude.ai/code/session_01F4DaU8i2iCWabU1xfM1wQp