@funnelsgrove/cli 0.1.87 → 0.1.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/apiClient.d.ts +1 -0
  2. package/dist/apiClient.js +32 -1
  3. package/funnel-contract-compatibility.json +28 -28
  4. package/package.json +3 -3
  5. package/template_docs/.funnelsgrove-docs.json +3 -3
  6. package/template_docs/docs/funnelsgrove/migrations/step-contract-v3.md +1 -1
  7. package/template_docs/funnel-docs.config.json +1 -1
  8. package/template_scaffold/.funnelsgrove-docs.json +3 -3
  9. package/template_scaffold/.funnelsgrove-scaffold.json +26 -471
  10. package/template_scaffold/PLAN.md +15 -29
  11. package/template_scaffold/context/build-context.md +3 -3
  12. package/template_scaffold/docs/funnelsgrove/migrations/step-contract-v3.md +1 -1
  13. package/template_scaffold/funnel-docs.config.json +1 -1
  14. package/template_scaffold/package-lock.json +9 -9
  15. package/template_scaffold/package.json +2 -2
  16. package/template_scaffold/public/assets/email-capture-preview.svg +5 -0
  17. package/template_scaffold/public/assets/paywall-preview.svg +6 -0
  18. package/template_scaffold/src/app/sdk/page.tsx +14 -26
  19. package/template_scaffold/src/components/FunnelFlow.tsx +8 -1
  20. package/template_scaffold/src/config/billing.plans.ts +71 -21
  21. package/template_scaffold/src/config/funnel.manifest.ts +20 -59
  22. package/template_scaffold/src/runtime/checkout-runtime-config.ts +0 -7
  23. package/template_scaffold/src/runtime/step-registry.ts +0 -28
  24. package/template_scaffold/src/steps/content/step-01.content.ts +4 -9
  25. package/template_scaffold/src/steps/content/step-32-paywall.content.ts +12 -50
  26. package/template_scaffold/src/steps/step-01.tsx +43 -50
  27. package/template_scaffold/src/steps/step-31-email-capture.tsx +18 -1
  28. package/template_scaffold/src/steps/step-32-paywall.tsx +93 -299
  29. package/template_scaffold/src/steps/step-33-subscription-started.tsx +1 -1
  30. package/template_scaffold/src/steps/step-content.registry.ts +1 -26
  31. package/template_scaffold/public/claimbee/bee.png +0 -0
  32. package/template_scaffold/public/claimbee/device-iphone.png +0 -0
  33. package/template_scaffold/public/claimbee/device-macbook.png +0 -0
  34. package/template_scaffold/public/claimbee/device-none.png +0 -0
  35. package/template_scaffold/public/claimbee/device-watch.png +0 -0
  36. package/template_scaffold/public/claimbee/glow.svg +0 -3
  37. package/template_scaffold/public/claimbee/steps-sprite-alt.png +0 -0
  38. package/template_scaffold/public/claimbee/steps-sprite-default.png +0 -0
  39. package/template_scaffold/public/claimbee/testimonial-avatar.png +0 -0
  40. package/template_scaffold/public/claimbee/testimonial-star.svg +0 -3
  41. package/template_scaffold/public/paywall/ai-claim-assistant.png +0 -0
  42. package/template_scaffold/public/paywall/claim-history.png +0 -0
  43. package/template_scaffold/public/paywall/clear-progress.png +0 -0
  44. package/template_scaffold/public/paywall/hero.png +0 -0
  45. package/template_scaffold/public/paywall/money-alerts.png +0 -0
  46. package/template_scaffold/public/paywall/money-back-badge.png +0 -0
  47. package/template_scaffold/public/paywall/paywall-image.png +0 -0
  48. package/template_scaffold/public/paywall/r1.png +0 -0
  49. package/template_scaffold/public/paywall/r2.png +0 -0
  50. package/template_scaffold/public/paywall/r3.png +0 -0
  51. package/template_scaffold/public/paywall/r4.png +0 -0
  52. package/template_scaffold/public/paywall/r5.png +0 -0
  53. package/template_scaffold/public/paywall/r6.png +0 -0
  54. package/template_scaffold/public/paywall/special-offer-gift.png +0 -0
  55. package/template_scaffold/public/please/bee.png +0 -0
  56. package/template_scaffold/public/please/device-iphone.png +0 -0
  57. package/template_scaffold/public/please/device-macbook.png +0 -0
  58. package/template_scaffold/public/please/device-none.png +0 -0
  59. package/template_scaffold/public/please/device-watch.png +0 -0
  60. package/template_scaffold/public/please/glow.svg +0 -3
  61. package/template_scaffold/public/please/steps-sprite-alt.png +0 -0
  62. package/template_scaffold/public/please/steps-sprite-default.png +0 -0
  63. package/template_scaffold/public/please/testimonial-avatar.png +0 -0
  64. package/template_scaffold/public/please/testimonial-star.svg +0 -3
  65. package/template_scaffold/public/upsell/upgrade-hero.png +0 -0
  66. package/template_scaffold/src/assets/claimbee/bee.png +0 -0
  67. package/template_scaffold/src/assets/claimbee/device-iphone.png +0 -0
  68. package/template_scaffold/src/assets/claimbee/device-macbook.png +0 -0
  69. package/template_scaffold/src/assets/claimbee/device-none.png +0 -0
  70. package/template_scaffold/src/assets/claimbee/device-watch.png +0 -0
  71. package/template_scaffold/src/assets/claimbee/glow.svg +0 -3
  72. package/template_scaffold/src/assets/claimbee/steps-sprite-alt.png +0 -0
  73. package/template_scaffold/src/assets/claimbee/steps-sprite-default.png +0 -0
  74. package/template_scaffold/src/assets/claimbee/testimonial-avatar.png +0 -0
  75. package/template_scaffold/src/assets/claimbee/testimonial-star.svg +0 -3
  76. package/template_scaffold/src/components/FunnelStepImage.tsx +0 -28
  77. package/template_scaffold/src/config/offer-sets.generated.ts +0 -4
  78. package/template_scaffold/src/steps/content/manage-subscription.content.ts +0 -62
  79. package/template_scaffold/src/steps/content/paywall.content.ts +0 -191
  80. package/template_scaffold/src/steps/content/step-02.content.ts +0 -77
  81. package/template_scaffold/src/steps/content/step-03.content.ts +0 -40
  82. package/template_scaffold/src/steps/content/step-04.content.ts +0 -49
  83. package/template_scaffold/src/steps/editor/manage-subscription.editor.ts +0 -179
  84. package/template_scaffold/src/steps/editor/paywall.editor.ts +0 -232
  85. package/template_scaffold/src/steps/editor/step-02.editor.ts +0 -41
  86. package/template_scaffold/src/steps/editor/step-03.editor.ts +0 -58
  87. package/template_scaffold/src/steps/editor/step-04.editor.ts +0 -98
  88. package/template_scaffold/src/steps/pricing/paywall-b.pricing.ts +0 -12
  89. package/template_scaffold/src/steps/step-02.tsx +0 -140
  90. package/template_scaffold/src/steps/step-03.tsx +0 -262
  91. package/template_scaffold/src/steps/step-04.tsx +0 -673
  92. package/template_scaffold/src/steps/step-32b-paywall-b.tsx +0 -35
  93. package/template_scaffold/src/steps/step-35-manage-subscription.tsx +0 -46
  94. package/template_scaffold/src/steps/use-claimbee-step-content.ts +0 -15
  95. package/template_scaffold/tests/funnel-agent-docs.test.ts +0 -751
  96. package/template_scaffold/tests/package.test.ts +0 -37
  97. package/template_scaffold/tests/src/app/[stepId]/page.test.tsx +0 -59
  98. package/template_scaffold/tests/src/app/layout.test.ts +0 -26
  99. package/template_scaffold/tests/src/components/FunnelFlow.test.tsx +0 -38
  100. package/template_scaffold/tests/src/components/FunnelStepImage.test.ts +0 -15
  101. package/template_scaffold/tests/src/config/billing.plans.test.ts +0 -143
  102. package/template_scaffold/tests/src/config/funnel.manifest.test.ts +0 -166
  103. package/template_scaffold/tests/src/contract/funnel-project.validation.test.ts +0 -79
  104. package/template_scaffold/tests/src/contract/golden/golden-fixtures.test.ts +0 -190
  105. package/template_scaffold/tests/src/contract/validate-funnel.cli.test.ts +0 -191
  106. package/template_scaffold/tests/src/runtime/checkout-runtime-config.test.ts +0 -60
  107. package/template_scaffold/tests/src/runtime/funnel-runtime.test.ts +0 -25
  108. package/template_scaffold/tests/src/runtime/step-content-context.test.ts +0 -38
  109. package/template_scaffold/tests/src/runtime/use-funnel-flow-controller.integration.test.ts +0 -203
  110. package/template_scaffold/tests/src/runtime/use-funnel-flow-controller.test.ts +0 -76
  111. package/template_scaffold/tests/src/steps/paywall-checkout-options.test.ts +0 -104
  112. package/template_scaffold/tests/src/steps/shared-header-contract.test.ts +0 -29
  113. package/template_scaffold/tests/src/steps/step-01.test.ts +0 -38
  114. package/template_scaffold/tests/src/steps/step-02.test.ts +0 -43
  115. package/template_scaffold/tests/src/steps/step-03.test.ts +0 -15
  116. package/template_scaffold/tests/src/steps/step-04.test.ts +0 -32
  117. package/template_scaffold/tests/src/steps/step-31-email-capture.test.ts +0 -22
  118. package/template_scaffold/tests/src/steps/step-32-paywall.test.ts +0 -773
  119. package/template_scaffold/tests/src/steps/step-33-subscription-started.test.ts +0 -44
  120. package/template_scaffold/tests/src/steps/step-34-upsell-form.test.ts +0 -27
  121. package/template_scaffold/tests/src/steps/step-image-migration.test.ts +0 -20
@@ -2,30 +2,25 @@
2
2
 
3
3
  import { useEffect, useMemo, useRef, useState } from 'react';
4
4
  import Image from 'next/image';
5
- import Link from 'next/link';
6
- import {
7
- checkoutRuntimeConfig,
8
- resolveClaimbeeCheckoutMode,
9
- } from '@/runtime/checkout-runtime-config';
5
+ import { checkoutRuntimeConfig } from '@/runtime/checkout-runtime-config';
10
6
  import {
11
7
  billingDiscountStorageKeys,
12
8
  billingDiscountList,
13
- claimbeePlansByMode,
9
+ starterPlansByMode,
10
+ starterBillingRuntimeFallback,
14
11
  } from '@/config/billing.plans';
15
12
  import { stepPaywallContent } from '@/steps/content/step-32-paywall.content';
16
- import { useClaimbeeStepContent } from '@/steps/use-claimbee-step-content';
17
13
  import {
18
14
  PaymentRuntimeBoundary,
19
15
  apiService,
20
16
  collectCurrentFunnelAttribution,
21
17
  readPaywallStateValue,
22
18
  runtimePublicConfig,
23
- resolveGeneratedOfferSetRuntime,
24
19
  updatePaywallStateValue,
25
20
  useFunnel,
26
21
  useFunnelRuntimeConfig,
22
+ usePreviewStepLocalizedContent,
27
23
  useRuntimeMode,
28
- type GeneratedOfferSet,
29
24
  type FunnelStepMeta,
30
25
  } from '@funnelsgrove/runtime';
31
26
  import { getPathForStep } from '@/runtime/funnel-runtime';
@@ -36,16 +31,14 @@ import {
36
31
  activateSecondPaywallDiscount,
37
32
  advancePaywallDiscountState,
38
33
  buildBillingDiscountCatalog,
39
- buildConfigPaywallPlans,
40
34
  buildDiscountedPaywallPlans,
41
35
  buildPaywallRenewalDisclaimer,
42
36
  getDefaultPlanId,
43
37
  getPaywallPromoDisplayName,
44
38
  resolvePaywallDiscountState,
39
+ resolvePublishedBillingRuntime,
45
40
  serializePaywallDiscountState,
46
41
  useStripeSubscriptionCheckoutSession,
47
- type BillingFallbackPlanConfig,
48
- type BillingPlanCatalog,
49
42
  type PaywallDiscountState,
50
43
  type PlatformWalletPaymentMethod,
51
44
  type StripeSubscriptionWalletSurfaceAvailability,
@@ -53,6 +46,7 @@ import {
53
46
  } from '@funnelsgrove/payments';
54
47
  import { stepSubscriptionStartedId } from '@/steps/step-33-subscription-started';
55
48
  import { funnelManifest } from '@/config/funnel.manifest';
49
+ import { getStepContentLocale } from '@/runtime/step-content-context';
56
50
 
57
51
  export const stepPaywallId = 'paywall';
58
52
 
@@ -63,7 +57,7 @@ export const stepPaywall = {
63
57
  kind: 'paywall',
64
58
  figmaNodeId: '6992-6210',
65
59
  title: 'Paywall',
66
- description: 'ClaimBee paywall rebuilt from Figma node 6992:6210 with a local three-plan catalog and FAQ accordion.',
60
+ description: 'Starter paywall with a local three-plan catalog and FAQ accordion.',
67
61
  actionBar: {
68
62
  hidden: true,
69
63
  },
@@ -89,25 +83,8 @@ const paywallWalletMethodWrapperClassNames: Record<PlatformWalletPaymentMethod,
89
83
  googlePay: 'paywall-v2-google-pay-shell',
90
84
  };
91
85
 
92
- const claimbeeStoryBackgroundColors = ['var(--color-secondary-text)', 'var(--color-primary)', 'var(--color-secondary)'] as const;
93
- const paywallFeatureTileColorClassNames = [
94
- 'paywall-v2-feature-title--orange',
95
- 'paywall-v2-feature-title--orange',
96
- 'paywall-v2-feature-title--green',
97
- 'paywall-v2-feature-title--green',
98
- ] as const;
99
- const paywallDetailImageDimensions = {
100
- tracking: {
101
- width: 172,
102
- height: 70,
103
- },
104
- alerts: {
105
- width: 127,
106
- height: 108,
107
- },
108
- } as const;
109
- const defaultSelectedPlan = 'secondary';
110
- export const CLAIMBEE_PAYWALL_DISCOUNT_STORAGE_KEYS = billingDiscountStorageKeys;
86
+ const storyBackgroundColors = ['var(--color-secondary-text)', 'var(--color-primary)', 'var(--color-secondary)'] as const;
87
+ export const PAYWALL_DISCOUNT_STORAGE_KEYS = billingDiscountStorageKeys;
111
88
  const deferPaywallStateSync = (syncState: () => void): (() => void) => {
112
89
  const timeoutId = window.setTimeout(syncState, 0);
113
90
  return () => window.clearTimeout(timeoutId);
@@ -141,55 +118,41 @@ function StepPaywallRuntime({
141
118
  analyticsStepName = stepPaywall.name || stepPaywall.title,
142
119
  }: StepPaywallProps = {}) {
143
120
  const [runtimeMode] = useRuntimeMode();
144
- const checkoutMode = useMemo(
145
- () => resolveClaimbeeCheckoutMode(runtimeMode),
146
- [runtimeMode],
147
- );
121
+ const checkoutMode = runtimeMode;
148
122
  const { user, setUser, attributes, featureFlags, completeStep } = useFunnel();
149
123
  const publishedRuntime = useFunnelRuntimeConfig();
150
- const content = useClaimbeeStepContent(stepPaywallId, stepPaywallContent);
124
+ const content = usePreviewStepLocalizedContent(
125
+ stepPaywallId,
126
+ stepPaywallContent,
127
+ getStepContentLocale(attributes),
128
+ );
151
129
  const supportEmail = runtimePublicConfig.supportEmail;
152
- const publishedOfferSetRuntime = useMemo(
153
- () => publishedRuntime.config && publishedRuntime.config.offerSets.length > 0
154
- ? resolveGeneratedOfferSetRuntime<BillingFallbackPlanConfig>({
155
- offerSets: publishedRuntime.config.offerSets as readonly GeneratedOfferSet[],
156
- baseCatalogsByMode: claimbeePlansByMode,
157
- fallbackDiscounts: billingDiscountList,
158
- })
159
- : null,
160
- [publishedRuntime.config],
130
+ const paywallPreviewAsset = funnelManifest.assets.paywallPreview;
131
+ const activeBillingRuntime = useMemo(
132
+ () => resolvePublishedBillingRuntime({
133
+ config: publishedRuntime.config?.offerSets.length
134
+ ? publishedRuntime.config
135
+ : starterBillingRuntimeFallback,
136
+ featureFlags,
137
+ mode: checkoutMode,
138
+ search: typeof window === 'undefined' ? '' : window.location.search,
139
+ baseCatalogsByMode: starterPlansByMode,
140
+ fallbackDiscounts: billingDiscountList,
141
+ }),
142
+ [checkoutMode, featureFlags, publishedRuntime.config],
161
143
  );
162
144
  const activeBillingDiscounts = useMemo(
163
- () => buildBillingDiscountCatalog(
164
- publishedOfferSetRuntime?.getDiscountList(checkoutMode) ?? billingDiscountList,
165
- ),
166
- [checkoutMode, publishedOfferSetRuntime],
167
- );
168
- const activePlanCatalog = useMemo<BillingPlanCatalog>(
169
- () => publishedOfferSetRuntime?.getPlanCatalog(checkoutMode) as BillingPlanCatalog
170
- || (checkoutMode === 'test' ? claimbeePlansByMode.test : claimbeePlansByMode.live),
171
- [checkoutMode, publishedOfferSetRuntime],
172
- );
173
- const activePlanKeys = useMemo(
174
- () => publishedOfferSetRuntime?.planKeys.length
175
- ? publishedOfferSetRuntime.planKeys
176
- : ['primary', 'secondary', 'tertiary'],
177
- [publishedOfferSetRuntime],
178
- );
179
- const availablePlans = useMemo(
180
- () => buildConfigPaywallPlans(
181
- activePlanCatalog,
182
- activePlanKeys,
183
- ),
184
- [activePlanCatalog, activePlanKeys],
145
+ () => activeBillingRuntime.discounts ?? buildBillingDiscountCatalog(billingDiscountList),
146
+ [activeBillingRuntime.discounts],
185
147
  );
148
+ const availablePlans = activeBillingRuntime.plans;
186
149
  const initialPlanId = useMemo(
187
150
  () =>
188
- availablePlans.find((plan) => plan.id === defaultSelectedPlan)?.id ??
151
+ availablePlans.find((plan) => plan.id === activeBillingRuntime.defaultPlanKey)?.id ??
189
152
  getDefaultPlanId(availablePlans) ??
190
153
  availablePlans[0]?.id ??
191
154
  null,
192
- [availablePlans],
155
+ [activeBillingRuntime.defaultPlanKey, availablePlans],
193
156
  );
194
157
  const [selectedPlanId, setSelectedPlanId] = useState<string | null>(
195
158
  initialPlanId,
@@ -259,7 +222,7 @@ function StepPaywallRuntime({
259
222
  quote: item.quote,
260
223
  author: item.author,
261
224
  backgroundColor:
262
- claimbeeStoryBackgroundColors[index % claimbeeStoryBackgroundColors.length],
225
+ storyBackgroundColors[index % storyBackgroundColors.length],
263
226
  })),
264
227
  [content.stories.items],
265
228
  );
@@ -293,7 +256,7 @@ function StepPaywallRuntime({
293
256
  return buildPaywallRenewalDisclaimer({
294
257
  plan: selectedPlan,
295
258
  hasActiveDiscount: Boolean(activeCouponId),
296
- productName: 'ClaimBee',
259
+ productName: 'the app',
297
260
  });
298
261
  }, [activeCouponId, selectedPlan]);
299
262
  const appliedDiscountAmountCents = useMemo(() => {
@@ -430,7 +393,7 @@ function StepPaywallRuntime({
430
393
  discounts: activeBillingDiscounts,
431
394
  nowMs: Date.now(),
432
395
  storedValue: readPaywallStateValue({
433
- legacyKeys: CLAIMBEE_PAYWALL_DISCOUNT_STORAGE_KEYS,
396
+ legacyKeys: PAYWALL_DISCOUNT_STORAGE_KEYS,
434
397
  }),
435
398
  }),
436
399
  );
@@ -487,7 +450,7 @@ function StepPaywallRuntime({
487
450
  updatePaywallStateValue(
488
451
  () => serializedDiscountSnapshot,
489
452
  {
490
- legacyKeys: CLAIMBEE_PAYWALL_DISCOUNT_STORAGE_KEYS,
453
+ legacyKeys: PAYWALL_DISCOUNT_STORAGE_KEYS,
491
454
  },
492
455
  );
493
456
  }, [discountStateReady, serializedDiscountSnapshot]);
@@ -767,14 +730,16 @@ function StepPaywallRuntime({
767
730
  ))}
768
731
  </section>
769
732
 
770
- <Image
771
- src={content.hero.image.src}
772
- alt={content.hero.image.alt || ''}
773
- width={390}
774
- height={288}
775
- className='paywall-v2-hero'
776
- priority
777
- />
733
+ <div className='paywall-v2-hero'>
734
+ <Image
735
+ src={paywallPreviewAsset.src}
736
+ alt=''
737
+ width={paywallPreviewAsset.width}
738
+ height={paywallPreviewAsset.height}
739
+ className='paywall-v2-hero-image'
740
+ aria-hidden='true'
741
+ />
742
+ </div>
778
743
 
779
744
  {activeCouponId ? (
780
745
  <section
@@ -941,31 +906,11 @@ function StepPaywallRuntime({
941
906
  </p>
942
907
  </div>
943
908
 
944
- <article className='paywall-v2-feature-card paywall-v2-feature-card--large'>
945
- <Image
946
- src={content.featureGrid.assistant.image?.src || '/paywall/ai-claim-assistant.png'}
947
- alt={content.featureGrid.assistant.image?.alt || ''}
948
- width={289}
949
- height={105}
950
- className='paywall-v2-feature-hero-image'
951
- />
952
- <div className='paywall-v2-feature-copy'>
953
- <p className='paywall-v2-feature-name'>{content.featureGrid.assistant.title}</p>
954
- <p className='paywall-v2-feature-description'>
955
- {content.featureGrid.assistant.description}
956
- </p>
957
- </div>
958
- </article>
959
-
960
- <div className='paywall-v2-feature-row'>
961
- {content.featureGrid.quickFeatures.slice(0, 2).map((feature, index) => (
909
+ <div className='paywall-v2-feature-row paywall-v2-feature-row--light'>
910
+ {[content.featureGrid.assistant, ...content.featureGrid.quickFeatures].map((feature) => (
962
911
  <article key={feature.id} className='paywall-v2-feature-card paywall-v2-feature-card--small'>
963
- <p
964
- className={[
965
- 'paywall-v2-feature-tile-title',
966
- paywallFeatureTileColorClassNames[index],
967
- ].join(' ')}
968
- >
912
+ <span className='paywall-v2-feature-check' aria-hidden='true'>✓</span>
913
+ <p className='paywall-v2-feature-tile-title'>
969
914
  {(feature.title || '').split('\n').map((line) => (
970
915
  <span key={line}>{line}</span>
971
916
  ))}
@@ -973,84 +918,13 @@ function StepPaywallRuntime({
973
918
  </article>
974
919
  ))}
975
920
  </div>
976
-
977
- <article className='paywall-v2-feature-card paywall-v2-feature-card--mid'>
978
- <Image
979
- src={content.featureGrid.history.image?.src || '/paywall/claim-history.png'}
980
- alt={content.featureGrid.history.image?.alt || ''}
981
- width={160}
982
- height={129}
983
- className='paywall-v2-feature-mid-image'
984
- />
985
- <p className='paywall-v2-feature-mid-title'>
986
- {(content.featureGrid.history.title || '').split('\n').map((line) => (
987
- <span key={line}>
988
- {line}
989
- <br />
990
- </span>
991
- ))}
992
- </p>
993
- </article>
994
-
995
- <div className='paywall-v2-feature-row'>
996
- {content.featureGrid.quickFeatures.slice(2).map((feature, index) => (
997
- <article key={feature.id} className='paywall-v2-feature-card paywall-v2-feature-card--small'>
998
- <p
999
- className={[
1000
- 'paywall-v2-feature-tile-title',
1001
- paywallFeatureTileColorClassNames[index + 2],
1002
- ].join(' ')}
1003
- >
1004
- {(feature.title || '').split('\n').map((line) => (
1005
- <span key={line}>{line}</span>
1006
- ))}
1007
- </p>
1008
- </article>
1009
- ))}
1010
- </div>
1011
-
1012
- <div className='paywall-v2-feature-row paywall-v2-feature-row--tall'>
1013
- {content.featureGrid.detailedFeatures.map((feature) => {
1014
- const imageDimensions =
1015
- paywallDetailImageDimensions[
1016
- feature.id as keyof typeof paywallDetailImageDimensions
1017
- ] || {
1018
- width: 160,
1019
- height: 90,
1020
- };
1021
-
1022
- return (
1023
- <article key={feature.id} className='paywall-v2-feature-card paywall-v2-feature-card--tall'>
1024
- <Image
1025
- src={feature.image?.src || ''}
1026
- alt={feature.image?.alt || ''}
1027
- width={imageDimensions.width}
1028
- height={imageDimensions.height}
1029
- className='paywall-v2-feature-detail-image'
1030
- />
1031
- <div className='paywall-v2-feature-detail-copy'>
1032
- <p className='paywall-v2-feature-detail-title'>
1033
- {(feature.title || '').split('\n').map((line) => (
1034
- <span key={line}>{line}</span>
1035
- ))}
1036
- </p>
1037
- <p className='paywall-v2-feature-detail-description'>
1038
- {(feature.description || '').split('\n').map((line) => (
1039
- <span key={line}>{line}</span>
1040
- ))}
1041
- </p>
1042
- </div>
1043
- </article>
1044
- );
1045
- })}
1046
- </div>
1047
921
  </section>
1048
922
 
1049
923
  <section className='paywall-v2-feedback' aria-live='polite'>
1050
924
  <h3 className='paywall-v2-feedback-title'>{content.stories.title}</h3>
1051
925
  <article
1052
926
  className='paywall-v2-feedback-card'
1053
- style={{ backgroundColor: activeStory?.backgroundColor || claimbeeStoryBackgroundColors[0] }}
927
+ style={{ backgroundColor: activeStory?.backgroundColor || storyBackgroundColors[0] }}
1054
928
  >
1055
929
  <p className='paywall-v2-feedback-quote'>{activeStory?.quote}</p>
1056
930
  <p className='paywall-v2-feedback-author'>- {activeStory?.author}</p>
@@ -1090,20 +964,14 @@ function StepPaywallRuntime({
1090
964
  </section>
1091
965
 
1092
966
  <section className='paywall-v2-guarantee-card'>
1093
- <Image
1094
- src={content.guarantee.image.src}
1095
- alt={content.guarantee.image.alt || ''}
1096
- width={184}
1097
- height={184}
1098
- className='paywall-v2-badge'
1099
- />
967
+ <div className='paywall-v2-badge' aria-hidden='true'>30</div>
1100
968
  <div className='paywall-v2-guarantee-copy'>
1101
969
  <p className='paywall-v2-guarantee-title'>{content.guarantee.title}</p>
1102
970
  <p className='paywall-v2-guarantee-text'>
1103
971
  {content.guarantee.description}{' '}
1104
- <Link href={content.guarantee.links[0]?.href || '/refund-policy'}>
972
+ <a href={content.guarantee.links[0]?.href || '/refund-policy'}>
1105
973
  {content.guarantee.links[0]?.label || 'refund policy'}
1106
- </Link>{' '}
974
+ </a>{' '}
1107
975
  for details and limitations.
1108
976
  </p>
1109
977
  </div>
@@ -1291,10 +1159,21 @@ const stepPaywallStyles = `
1291
1159
  }
1292
1160
 
1293
1161
  .paywall-v2-hero {
1294
- display: block;
1162
+ position: relative;
1163
+ display: grid;
1164
+ place-items: center;
1295
1165
  width: min(100%, 390px);
1296
- height: auto;
1297
- margin: -12px auto 0;
1166
+ height: 230px;
1167
+ margin: 20px auto 8px;
1168
+ overflow: hidden;
1169
+ border-radius: 32px;
1170
+ background: linear-gradient(145deg, #d8edff, #f7fbff);
1171
+ }
1172
+
1173
+ .paywall-v2-hero-image {
1174
+ width: 160px;
1175
+ height: 120px;
1176
+ object-fit: contain;
1298
1177
  }
1299
1178
 
1300
1179
  .paywall-v2-promo-banner {
@@ -2016,10 +1895,15 @@ const stepPaywallStyles = `
2016
1895
  }
2017
1896
 
2018
1897
  .paywall-v2-badge {
2019
- width: 184px;
2020
- height: 184px;
2021
- object-fit: cover;
2022
- object-position: center 54%;
1898
+ display: grid;
1899
+ width: 104px;
1900
+ height: 104px;
1901
+ place-items: center;
1902
+ border: 8px double var(--color-primary);
1903
+ border-radius: 999px;
1904
+ color: var(--color-primary);
1905
+ font-size: 34px;
1906
+ font-weight: 800;
2023
1907
  }
2024
1908
 
2025
1909
  .paywall-v2-guarantee-copy {
@@ -2093,37 +1977,6 @@ const stepPaywallStyles = `
2093
1977
  gap: 16px;
2094
1978
  }
2095
1979
 
2096
- .paywall-v2-feature-hero-image {
2097
- width: 289px;
2098
- height: 105px;
2099
- object-fit: contain;
2100
- flex-shrink: 0;
2101
- }
2102
-
2103
- .paywall-v2-feature-copy {
2104
- width: 100%;
2105
- display: flex;
2106
- flex-direction: column;
2107
- gap: 8px;
2108
- text-align: center;
2109
- }
2110
-
2111
- .paywall-v2-feature-name {
2112
- margin: 0;
2113
- color: var(--color-secondary-text);
2114
- font-size: 18px;
2115
- font-weight: 600;
2116
- line-height: 1.25;
2117
- }
2118
-
2119
- .paywall-v2-feature-description {
2120
- margin: 0;
2121
- color: #6074e2;
2122
- font-size: 14px;
2123
- font-weight: 500;
2124
- line-height: 1.25;
2125
- }
2126
-
2127
1980
  .paywall-v2-feature-row {
2128
1981
  margin-top: 24px;
2129
1982
  display: grid;
@@ -2134,100 +1987,41 @@ const stepPaywallStyles = `
2134
1987
  .paywall-v2-feature-card--small {
2135
1988
  min-height: 122px;
2136
1989
  display: flex;
1990
+ flex-direction: column;
2137
1991
  align-items: center;
2138
1992
  justify-content: center;
1993
+ gap: 10px;
2139
1994
  padding: 10px;
2140
1995
  }
2141
1996
 
2142
- .paywall-v2-feature-tile-title,
2143
- .paywall-v2-feature-detail-title,
2144
- .paywall-v2-feature-detail-description {
2145
- margin: 0;
2146
- display: flex;
2147
- flex-direction: column;
2148
- }
2149
-
2150
- .paywall-v2-feature-tile-title {
2151
- font-size: 18px;
2152
- font-weight: 600;
2153
- line-height: 1.25;
2154
- text-align: center;
2155
- }
2156
-
2157
- .paywall-v2-feature-title--orange {
2158
- color: var(--color-secondary);
1997
+ .paywall-v2-feature-row--light {
1998
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2159
1999
  }
2160
2000
 
2161
- .paywall-v2-feature-title--green {
2001
+ .paywall-v2-feature-check {
2002
+ display: grid;
2003
+ width: 32px;
2004
+ height: 32px;
2005
+ place-items: center;
2006
+ border-radius: 999px;
2007
+ background: color-mix(in srgb, var(--color-primary) 14%, white);
2162
2008
  color: var(--color-primary);
2009
+ font-weight: 800;
2163
2010
  }
2164
2011
 
2165
- .paywall-v2-feature-card--mid {
2166
- margin-top: 24px;
2167
- min-height: 196px;
2168
- padding: 5px 16px 16px;
2012
+ .paywall-v2-feature-tile-title {
2013
+ margin: 0;
2169
2014
  display: flex;
2170
2015
  flex-direction: column;
2171
- align-items: center;
2172
- gap: 12px;
2173
2016
  }
2174
2017
 
2175
- .paywall-v2-feature-mid-image {
2176
- width: 160px;
2177
- height: 129px;
2178
- object-fit: contain;
2179
- flex-shrink: 0;
2180
- }
2181
-
2182
- .paywall-v2-feature-mid-title {
2183
- margin: 0;
2184
- color: var(--color-secondary-text);
2018
+ .paywall-v2-feature-tile-title {
2185
2019
  font-size: 18px;
2186
2020
  font-weight: 600;
2187
2021
  line-height: 1.25;
2188
2022
  text-align: center;
2189
2023
  }
2190
2024
 
2191
- .paywall-v2-feature-row--tall {
2192
- align-items: stretch;
2193
- }
2194
-
2195
- .paywall-v2-feature-card--tall {
2196
- min-height: 255px;
2197
- padding: 16px 12px 24px;
2198
- display: flex;
2199
- flex-direction: column;
2200
- align-items: center;
2201
- gap: 14px;
2202
- }
2203
-
2204
- .paywall-v2-feature-detail-image {
2205
- height: auto;
2206
- object-fit: contain;
2207
- flex-shrink: 0;
2208
- }
2209
-
2210
- .paywall-v2-feature-detail-copy {
2211
- display: flex;
2212
- flex-direction: column;
2213
- gap: 8px;
2214
- text-align: center;
2215
- }
2216
-
2217
- .paywall-v2-feature-detail-title {
2218
- color: var(--color-secondary-text);
2219
- font-size: 16px;
2220
- font-weight: 600;
2221
- line-height: 1.25;
2222
- }
2223
-
2224
- .paywall-v2-feature-detail-description {
2225
- color: #6074e2;
2226
- font-size: 12px;
2227
- font-weight: 500;
2228
- line-height: 1.25;
2229
- }
2230
-
2231
2025
  @media (max-width: 429px) {
2232
2026
  .paywall-v2-step {
2233
2027
  padding: 0 16px 48px;
@@ -23,7 +23,7 @@ export const stepSubscriptionStarted: FunnelStepMeta = {
23
23
  kind: 'subscription-handoff',
24
24
  figmaNodeId: 'final-step-deep-link',
25
25
  title: 'Subscription Started',
26
- description: 'Post-checkout app handoff and deep-link step.',
26
+ description: 'Post-checkout and returning-subscriber app handoff step.',
27
27
  actionBar: {
28
28
  hidden: true,
29
29
  },
@@ -1,23 +1,8 @@
1
- import type { FunnelChoiceOption } from '@funnelsgrove/runtime';
2
- import { stepTwoOptions } from './content/step-02.content';
3
-
4
1
  export const stepContentRegistry = {
5
2
  'step-1': {
6
3
  contentPath: 'src/steps/content/step-01.content.ts',
7
4
  editorPath: 'src/steps/editor/step-01.editor.ts',
8
5
  },
9
- 'step-2': {
10
- contentPath: 'src/steps/content/step-02.content.ts',
11
- editorPath: 'src/steps/editor/step-02.editor.ts',
12
- },
13
- 'step-3': {
14
- contentPath: 'src/steps/content/step-03.content.ts',
15
- editorPath: 'src/steps/editor/step-03.editor.ts',
16
- },
17
- 'step-4': {
18
- contentPath: 'src/steps/content/step-04.content.ts',
19
- editorPath: 'src/steps/editor/step-04.editor.ts',
20
- },
21
6
  'email-capture': {
22
7
  contentPath: 'src/steps/content/email-capture.content.ts',
23
8
  editorPath: 'src/steps/editor/email-capture.editor.ts',
@@ -26,20 +11,10 @@ export const stepContentRegistry = {
26
11
  contentPath: 'src/steps/content/step-32-paywall.content.ts',
27
12
  editorPath: 'src/steps/editor/step-32-paywall.editor.ts',
28
13
  },
29
- 'paywall-b': {
30
- contentPath: 'src/steps/content/step-32-paywall.content.ts',
31
- editorPath: 'src/steps/editor/step-32-paywall.editor.ts',
32
- },
33
- 'manage-subscription': {
34
- contentPath: 'src/steps/content/manage-subscription.content.ts',
35
- editorPath: 'src/steps/editor/manage-subscription.editor.ts',
36
- },
37
14
  'subscription-started': {
38
15
  contentPath: 'src/steps/content/subscription-started.content.ts',
39
16
  editorPath: 'src/steps/editor/subscription-started.editor.ts',
40
17
  },
41
18
  } as const;
42
19
 
43
- export const contentOptionsByStepId = {
44
- 'step-2': stepTwoOptions,
45
- } as const satisfies Record<string, readonly FunnelChoiceOption[]>;
20
+ export const contentOptionsByStepId = {} as const;
@@ -1,3 +0,0 @@
1
- <svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 116 109.5" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path id="Vector 11" d="M0 22.5L51 0H85L116 22.5V54.5V89L74.5 109.5L42 103L9 89L0 61.5V22.5Z" fill="var(--fill-0, #FEFDF5)"/>
3
- </svg>
@@ -1,3 +0,0 @@
1
- <svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 16.1222 15.4039" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path id="Star 1" d="M7.37895 0.495601C7.59366 -0.165201 8.52852 -0.1652 8.74323 0.495602L10.1545 4.83902C10.2505 5.13454 10.5259 5.33462 10.8366 5.33462H15.4036C16.0984 5.33462 16.3873 6.22372 15.8251 6.63212L12.1304 9.3165C11.879 9.49914 11.7738 9.82288 11.8699 10.1184L13.2811 14.4618C13.4958 15.1226 12.7395 15.6721 12.1774 15.2637L8.48267 12.5793C8.23129 12.3967 7.89089 12.3967 7.63951 12.5793L3.94477 15.2637C3.38266 15.6721 2.62635 15.1226 2.84105 14.4618L4.25232 10.1184C4.34834 9.82288 4.24315 9.49914 3.99176 9.3165L0.297032 6.63212C-0.26508 6.22372 0.0238078 5.33462 0.718616 5.33462H5.28555C5.59628 5.33462 5.87167 5.13454 5.96769 4.83902L7.37895 0.495601Z" fill="var(--fill-0, #F28100)"/>
3
- </svg>