The Movement Athlete · React Native · 5 August 2026

Paywall rebuild — start here

A UI-only change to the existing “Upgrade to Premium” screen. Purchase, restore, terms, analytics and RevenueCat are already wired — nothing here asks you to integrate anything. The component is written; you swap the layout and map data you already have.

Step 0 · Download the package Everything below lives in this zip — the component, the fixtures, the assets, the build notes. Grab it before you read on. TMA_PAYWALL_RN_PACKAGE_2026-08-05.zip ↓ The design contract — open this first Three interactive states. Tap the plan tiers and the dock and timeline re-price — that behaviour, and every measurement, token, string and figure inside it, is what “done” means. Open the interactive spec →
Estimate: 5 hours max — here's how we got there
#MilestoneEst.
1Unzip, drop the component in, render it on the fixtures30 min
2Reconcile with the existing screens — keep your hooks; delete the stand-in nav if the coral header already has Restore60 min
3Route all three pricing pages at the one component via variant; map offerings to tiers; point existing handlers + analytics at its props60 min
4The three derived strings + trialDaysthe only genuinely new logic45 min
5The seven copy fixes below the fold20 min
6On-device pass: all three states, two currencies, airplane mode, VoiceOver, payment-sheet parity, restore60 min
Total~4 h 15
It's short because four things that normally eat time are already done: the component is written, the fixtures mean QA isn't blocked behind the wiring, the assets ship at three densities, and the wiring example is in the notes. 🔴 That number assumes the three pages go onto one component — rebuilt separately it is closer to double. If you think the estimate is wrong, say so before you start, and please don't push past 5 hours without coming back to us first.

01 Scope — exactly

In: everything from under the coral header down to the docked button, plus one copy line in the “What you get” section, plus seven broken strings listed in COPY_FIXES_BELOW_FOLD.md.

All three pricing pages — full price, 30% off, 50% off. They already exist and their offers are already configured; we are not creating anything, only updating the UI on each.

🔴 Please put all three on ONE component
The three pages are the same screen with a different price source. Drive them from variant: 'full' | 'off30' | 'off50' rather than applying the new layout to each page separately. It is less work — one layout to build and review instead of three — and three copies drifting apart is how the current bug survived: prices went stale on some surfaces and not others, with no single place to look. If that is awkward in the existing structure, tell us before starting.

Out: the coral header stays. Everything below “What you get” stays — testimonial carousel, transformation photos, feature panels, FAQ. If a change seems to need something outside that boundary, stop and tell us rather than absorbing it.

02 Why we’re doing it

Each plan currently shows a large unit price — $8 / week and $6.4 / month. Those strings are byte-identical on a UK device and on a device charging in pesos, while the amount actually charged changes underneath them. They were hardcoded into the layout and never bound to the store product.

It isn’t cosmetic
As displayed, the quarterly plan reads as 5.4× the yearly. What we actually charge makes it 1.26×. The screen argues against the plan we most want people to choose. The removed Lifetime card also rendered a stray $ followed by ₱58,000.00 — same root cause.

03 What’s in the folder

FileWhat it’s for
src/PaywallScreen.tsxDrop-in component — layout, copy, styles, tier selection, timeline binding all done
src/SealShield.tsxThe guarantee shield, ready (react-native-svg)
fixtures/tiers.mock.tsRun the screen before wiring anything — all three states on mock data
assets/Three images at @1x / @2x / @3x, correctly named — no need to regenerate
spec/INTERACTIVE_SPEC.html
also live at the link above
🔴 THE UX/UI CONTRACT. Open it and tap the tiers — that behaviour is the acceptance criteria, not an illustration of it. Measurements, tokens, copy strings and every figure are inside
PAYWALL_BUILD_NOTES.mdWiring example, the five rules, App Review requirements, on-device checklist
COPY_FIXES_BELOW_FOLD.mdSeven broken strings on sections we are not redesigning
spec/WHY_THIS_CHANGE_audit.mdThe full audit — context, not required reading

04 The job, in order

  1. Download the package and unzip it.
  2. Open the design contract and use it — tap the tiers, scroll each phone. Then render it on fixtures: <PaywallScreen {...mockProps('full')} /> — the whole screen works, including tier selection and re-pricing. Check it against the contract side by side before touching the store.
  3. Map your existing offerings to the tiers prop, order [annual, quarterly]. The wiring example in the build notes is about fifteen lines.
  4. Point your existing handlers and analytics at the component’s props — the three events are already called inside it.
  5. Add the derived strings — per-day, per-week, localised zero, and trialDays from the introductory-offer period. This is the only genuinely new logic in the job.
  6. Work the on-device checklist at the end of the build notes, including a second currency. That last one matters more than it looks.

05 The one rule everything hangs off

No price literal anywhere in the UI

Every figure — per-day, per-week, charged amount, struck-through list price, renewal price — derives from the localised store product at render time. If offerings fail to load, render the retry state; never a fallback price.

Worth naming explicitly: the SDK was already wired on this screen and the prices were still wrong, because two display strings bypassed it. Please don’t stub literals in during development and rely on removing them later — as far as we can tell, that’s how the current defect arrived.

Four more, all in the build notes: a percentage discount must map to a real configured offer · a discount and a free trial can’t both be the introductory offer, so the promo states carry no trial copy · the timeline and dock bind to the selected tier · one percentage per state, applied to both tiers.

06 Three states, and what they charge

State12-Month3-MonthTrialOn-card saving
full$159.99$49.997 days20% · $39.97/yr
vs paying quarterly
off50$79.99$24.99none50% · $80.00
vs list
off30$111.99$34.99none30% · $48.00
vs list

One component, variant: 'full' | 'off30' | 'off50'. US price points shown so you can check the arithmetic — every other storefront renders its own localised figures. All three offers are already configured in App Store Connect, and all three pages already exist — this pass updates the UI on each.

07 Two placeholders, and one thing to raise if it bites

If the drop-in doesn’t drop in
The component assumes a screen thin enough to swap wholesale. If the existing file is more tangled than that, take the JSX and the StyleSheet and paste them into what’s already there, keeping your own hooks — that’s usually the cheaper path. Either way is fine; tell us which you took.

Questions on anything here, ask before assuming — every value in the component matches the design contract deliberately. Prices shown are US; all figures render localised from the store on device.