Trial paywall — 3 billing options (NZD)
primary
Reach: StartTrialModal over the running app — an NZD web user on demo data who has not started a trial (also renders full-page at /onboarding/payment)
The main design question, decided: prod's BillingPlanToggle kept and extended from two pills to three - Annual, Monthly, 2 Years. Stacked plan cards were built first and rejected on 2026-07-28 in favour of staying closest to prod. Annual stays the default. Everything below the toggle follows the selected pill: Annual "then $99/year [Save $249]", Monthly "then $29/month" with no badge (prod computes savings only on the annual selection), 2 Years "then $149/2 years [Save $547]" plus a "$6.21 per month" subline on the BOOST row. The savings badges are prod's own dollar formula, computeAnnualSavings() = (monthly x 12) - annual, extended to 24 months. Selecting 2 Years also shows "Promo codes don't apply to the 2-year plan" (FR6).
Trial paywall — non-NZD user (2 options)
state
Reach: StartTrialModal over the running app — a user whose currency is not NZD
The NZD-only absence state. Prod's two-pill toggle exactly as it is today (Annual, Monthly) at the real prod USD prices (US$29/month, US$249/year). No third pill, no disabled pill and no error, so the absence looks intentional rather than broken. The USD annual price carries no baked-in discount — the lifetime 60% coupon behind the NZ$99 price is NZD-only — so the same dollar formula gives a much smaller badge, Save $99.
Trial paywall — submitting (pending CTA)
state
Reach: StartTrialModal over the running app — after tapping "Start My Trial", while the checkout request is in flight
The CTA's pending state: spinner, disabled button, disabled toggle pills and disabled tier rows. The double-tap guard — a second tap must not create a second Stripe payment intent and charge the $1 trial twice. This state depicts someone who chose the 2-year option, so it also shows FR6 in the UI: the line "Promo codes don't apply to the 2-year plan". There is no promo-code field on the paywall; codes arrive only through a promo_code URL parameter on marketing links.
Settings — active 2-year subscriber
primary
Reach: Top-bar gear → Settings → Billing & Subscription
Landing screen. Adds a billing-option line under "You are currently on the BOOST plan.": 2-year plan, renews 28/07/2028 — the same date the confirm modal promises. Today the card names the tier only, so Monthly, 12-month and 2-year subscribers all read the same.
Settings — pending switch to 2-year
state
Reach: Settings → Billing & Subscription, for a 12-month subscriber with a scheduled change
Coral scheduled-change note in the real formatScheduledChangeNote() shape, with a new '2-year' interval word: "Your plan changes to SortMe Boost (2-year) on 3 Nov 2026."
Settings — 2-year subscriber with a scheduled downgrade to Monthly
state
Reach: Settings → Billing & Subscription, for a 2-year subscriber who scheduled a downgrade
AC5, the 2-year side. Same formatScheduledChangeNote() sentence shape, naming the target plan: "Your plan changes to SortMe Boost (monthly) on 28 Jul 2028." The effective date is the end of the 2-year period, so it sits nearly two years out — the case any "end of your current billing period" wording hides.
Settings — failed 2-year renewal
state
Reach: Settings → Billing & Subscription, when useSubscription().isPaymentFailed
The billing-payment-failed region from settings.manifest.json in its triggering state, adapted for a 2-year subscriber. Names the amount and the plan, because a failed 2-year renewal is $149.00 — five times a monthly charge.
Plans modal — third BOOST option
primary
Reach: Settings → "Learn more about SortMe Plans", for a monthly subscriber
The SortMe Plans modal over the settings page. Both cards gain a third price row, highlighted as best value: BOOST $149.00 / 2 years ($6.21 per month) and PRO $399.00 / 2 years ($16.63 per month). The BOOST Monthly row reads "Current plan". BOOST and PRO sit side by side from md up, as prod does.
Plans modal — viewed by a 2-year subscriber
state
Reach: Settings → "Learn more about SortMe Plans", for a 2-year subscriber
The 2-year row reads "Current plan", marked at full opacity with a coral ring and a tick (not dimmed, which fails contrast on the coral fill); Monthly and 12-month become "Downgrade", and the heads-up names the real period-end date instead of "the end of your current billing period".
Confirm switch to 2-year billing
state
Reach: Plans modal → 24-month row, for a monthly subscriber
Proration confirm modal for Monthly to 2-year: an immediate in-place swap charged today. The next-payment date matches the settings renewal date (28/07/2028). The annual to 2-year mechanics are still an open engineering question; this is the immediate-variant copy.