@hook-sdk/template 0.26.0 → 0.27.0

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.
package/dist/index.cjs CHANGED
@@ -46,10 +46,26 @@ __export(index_exports, {
46
46
  OnboardingFlow: () => OnboardingFlow,
47
47
  PaymentReturnHandler: () => PaymentReturnHandler,
48
48
  Paywall: () => Paywall,
49
+ PaywallAnchorPrice: () => PaywallAnchorPrice,
50
+ PaywallContext: () => PaywallContext,
51
+ PaywallCountdown: () => PaywallCountdown,
49
52
  PaywallCta: () => PaywallCta,
50
53
  PaywallCyclePicker: () => PaywallCyclePicker,
54
+ PaywallEyebrow: () => PaywallEyebrow,
55
+ PaywallFeatures: () => PaywallFeatures,
56
+ PaywallFeaturesCard: () => PaywallFeaturesCard,
57
+ PaywallFinePrint: () => PaywallFinePrint,
58
+ PaywallHeadline: () => PaywallHeadline,
59
+ PaywallHero: () => PaywallHero,
51
60
  PaywallMethodContent: () => PaywallMethodContent,
52
61
  PaywallMethodTabs: () => PaywallMethodTabs,
62
+ PaywallPriceHeadline: () => PaywallPriceHeadline,
63
+ PaywallProvider: () => PaywallProvider,
64
+ PaywallStatsRow: () => PaywallStatsRow,
65
+ PaywallStickyFooter: () => PaywallStickyFooter,
66
+ PaywallTestimonials: () => PaywallTestimonials,
67
+ PaywallTrophyBadge: () => PaywallTrophyBadge,
68
+ PaywallTrustLine: () => PaywallTrustLine,
53
69
  PersistenceRegistry: () => PersistenceRegistry,
54
70
  PixWaitingPageDefault: () => PixWaitingPageDefault,
55
71
  PreAuthShell: () => PreAuthShell,
@@ -80,6 +96,7 @@ __export(index_exports, {
80
96
  useInstallPrompt: () => useInstallPrompt,
81
97
  useLoginForm: () => useLoginForm,
82
98
  useOnboardingStep: () => useOnboardingStep,
99
+ usePaywallContext: () => usePaywallContext,
83
100
  usePaywallState: () => usePaywallState,
84
101
  usePlan: () => usePlan,
85
102
  usePush: () => usePush,
@@ -726,8 +743,8 @@ function usePaywallState() {
726
743
  opening: submitting,
727
744
  availableMethods: methods,
728
745
  monthlyEquivalent,
729
- dismissPix: () => {
730
- },
746
+ // G154 fix (template 0.24.0 + SDK 0.26.0): wired to SDK action.
747
+ dismissPix: subscription.clearPixPending,
731
748
  refreshPlan: () => {
732
749
  }
733
750
  };
@@ -3959,25 +3976,42 @@ function useFeature(name) {
3959
3976
  }
3960
3977
 
3961
3978
  // src/components/paywall/Paywall.tsx
3962
- var import_react29 = require("react");
3979
+ var import_react31 = require("react");
3963
3980
  var import_sdk24 = require("@hook-sdk/sdk");
3964
3981
 
3965
- // src/components/paywall/PaywallMethodTabs.tsx
3982
+ // src/components/paywall/PaywallProvider.tsx
3983
+ var import_react29 = require("react");
3966
3984
  var import_jsx_runtime32 = require("react/jsx-runtime");
3985
+ var PaywallContext = (0, import_react29.createContext)(null);
3986
+ function PaywallProvider({ children }) {
3987
+ const state = usePaywallState();
3988
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PaywallContext.Provider, { value: state, children });
3989
+ }
3990
+
3991
+ // src/components/paywall/usePaywallContext.ts
3992
+ var import_react30 = require("react");
3993
+ function usePaywallContext() {
3994
+ const ctx = (0, import_react30.useContext)(PaywallContext);
3995
+ if (!ctx) {
3996
+ throw new Error("usePaywallContext must be used within <PaywallProvider>");
3997
+ }
3998
+ return ctx;
3999
+ }
4000
+
4001
+ // src/components/paywall/PaywallMethodTabs.tsx
4002
+ var import_jsx_runtime33 = require("react/jsx-runtime");
3967
4003
  function PaywallMethodTabs({
3968
- methods,
3969
- selected,
3970
- onSelect,
3971
4004
  labels,
3972
4005
  className,
3973
4006
  tabClassName,
3974
4007
  tabActiveClassName
3975
4008
  }) {
4009
+ const { methods, selectedMethod, selectMethod } = usePaywallContext();
3976
4010
  if (methods.length < 2) return null;
3977
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
3978
- const active = m === selected;
4011
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
4012
+ const active = m === selectedMethod;
3979
4013
  const label = labels[m] ?? m;
3980
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4014
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3981
4015
  "button",
3982
4016
  {
3983
4017
  type: "button",
@@ -3985,7 +4019,7 @@ function PaywallMethodTabs({
3985
4019
  "aria-selected": active,
3986
4020
  "aria-controls": `paywall-tab-${m}`,
3987
4021
  tabIndex: active ? 0 : -1,
3988
- onClick: () => onSelect(m),
4022
+ onClick: () => selectMethod(m),
3989
4023
  className: [tabClassName, active ? tabActiveClassName : ""].filter(Boolean).join(" "),
3990
4024
  children: label
3991
4025
  },
@@ -3995,36 +4029,51 @@ function PaywallMethodTabs({
3995
4029
  }
3996
4030
 
3997
4031
  // src/components/paywall/PaywallMethodContent.tsx
3998
- var import_jsx_runtime33 = require("react/jsx-runtime");
3999
- function PaywallMethodContent({
4000
- method,
4001
- copy,
4002
- hasConsumedTrial = false,
4003
- className,
4004
- rowClassName
4005
- }) {
4006
- const useCardConsumed = method === "card" && hasConsumedTrial && copy.cardConsumedTrial;
4007
- const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : method === "pix-auto" || method === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
4008
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { role: "tabpanel", id: `paywall-tab-${method}`, className, children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: rowClassName, children: row }, i)) });
4032
+ var import_jsx_runtime34 = require("react/jsx-runtime");
4033
+ function PaywallMethodContent({ copy, className, rowClassName }) {
4034
+ const { selectedMethod, hasConsumedTrial } = usePaywallContext();
4035
+ const useCardConsumed = selectedMethod === "card" && hasConsumedTrial && copy.cardConsumedTrial;
4036
+ const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : selectedMethod === "pix-auto" || selectedMethod === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
4037
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { role: "tabpanel", id: `paywall-tab-${selectedMethod}`, className, children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: rowClassName, children: row }, i)) });
4009
4038
  }
4010
4039
 
4011
4040
  // src/components/paywall/PaywallCyclePicker.tsx
4012
- var import_jsx_runtime34 = require("react/jsx-runtime");
4041
+ var import_jsx_runtime35 = require("react/jsx-runtime");
4042
+ var VARIANT_CLASSES = {
4043
+ default: { card: "", cardSelected: "" },
4044
+ "premium-gold": {
4045
+ card: "",
4046
+ cardSelected: "border-2 border-yellow-400/80 ring-2 ring-yellow-400/20"
4047
+ },
4048
+ "pink-pill": {
4049
+ card: "rounded-2xl",
4050
+ cardSelected: "border-2 border-pink-500"
4051
+ }
4052
+ };
4013
4053
  function PaywallCyclePicker({
4014
- cycles,
4015
- selected,
4016
- onSelect,
4017
- priceCentsByCycle,
4018
- anchorCentsByCycle,
4019
- monthlyEquivByCycle,
4020
4054
  labels,
4021
4055
  className,
4022
4056
  cardClassName,
4023
4057
  cardSelectedClassName,
4024
- anchorClassName
4058
+ anchorClassName,
4059
+ variant = "default",
4060
+ render
4025
4061
  }) {
4062
+ const ctx = usePaywallContext();
4063
+ const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;
4064
+ const cycles = ["MONTHLY", "YEARLY"];
4065
+ if (render) {
4066
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className, children: render({ cycles, selected, setCycle, plan, anchorPriceCents }) });
4067
+ }
4026
4068
  if (cycles.length < 2) return null;
4027
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4069
+ const v = VARIANT_CLASSES[variant];
4070
+ const composedCardClassName = [v.card, cardClassName].filter(Boolean).join(" ");
4071
+ const composedCardSelectedClassName = [v.cardSelected, cardSelectedClassName].filter(Boolean).join(" ");
4072
+ const monthlyCents = plan?.monthlyCents ?? 0;
4073
+ const yearlyCents = plan?.yearlyCents ?? 0;
4074
+ const anchorMonthly = plan?.anchorMonthlyCents ?? null;
4075
+ const anchorYearly = plan?.anchorYearlyCents ?? null;
4076
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
4028
4077
  "div",
4029
4078
  {
4030
4079
  role: "radiogroup",
@@ -4034,21 +4083,25 @@ function PaywallCyclePicker({
4034
4083
  const active = c === selected;
4035
4084
  const label = c === "YEARLY" ? labels.annualLabel : labels.monthlyLabel;
4036
4085
  const suffix = c === "YEARLY" ? labels.annualSuffix : labels.monthlySuffix;
4037
- const mainCents = c === "YEARLY" ? monthlyEquivByCycle[c] : priceCentsByCycle[c];
4038
- const anchorCents = anchorCentsByCycle[c];
4039
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
4086
+ const mainCents = c === "YEARLY" ? Math.round(yearlyCents / 12) : monthlyCents;
4087
+ const anchorCents = c === "YEARLY" ? anchorYearly : anchorMonthly;
4088
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
4040
4089
  "button",
4041
4090
  {
4042
4091
  type: "button",
4043
4092
  role: "radio",
4044
4093
  "aria-checked": active,
4045
- onClick: () => onSelect(c),
4046
- className: ["flex flex-col items-center gap-0.5", cardClassName, active ? cardSelectedClassName : ""].filter(Boolean).join(" "),
4094
+ onClick: () => setCycle(c),
4095
+ className: [
4096
+ "flex flex-col items-center gap-0.5",
4097
+ composedCardClassName,
4098
+ active ? composedCardSelectedClassName : ""
4099
+ ].filter(Boolean).join(" "),
4047
4100
  children: [
4048
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
4049
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
4050
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-xs opacity-60 leading-tight", children: label }),
4051
- anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: anchorClassName ?? "text-xs opacity-50", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("s", { children: formatBRL(anchorCents) }) }) : null
4101
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
4102
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
4103
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-xs opacity-60 leading-tight", children: label }),
4104
+ anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: anchorClassName ?? "text-xs opacity-50", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("s", { children: formatBRL(anchorCents) }) }) : null
4052
4105
  ]
4053
4106
  },
4054
4107
  c
@@ -4058,38 +4111,6 @@ function PaywallCyclePicker({
4058
4111
  );
4059
4112
  }
4060
4113
 
4061
- // src/components/paywall/PaywallCta.tsx
4062
- var import_jsx_runtime35 = require("react/jsx-runtime");
4063
- function PaywallCta({
4064
- ctaLabel,
4065
- loadingLabel,
4066
- switchHint,
4067
- trustLine,
4068
- onClick,
4069
- disabled = false,
4070
- loading = false,
4071
- className,
4072
- buttonClassName,
4073
- switchHintClassName,
4074
- trustClassName
4075
- }) {
4076
- const label = loading && loadingLabel ? loadingLabel : ctaLabel;
4077
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className, children: [
4078
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
4079
- "button",
4080
- {
4081
- type: "button",
4082
- onClick,
4083
- disabled: disabled || loading,
4084
- className: buttonClassName,
4085
- children: label
4086
- }
4087
- ),
4088
- switchHint ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
4089
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: trustClassName, children: trustLine })
4090
- ] });
4091
- }
4092
-
4093
4114
  // src/components/paywall/Paywall.tsx
4094
4115
  var import_jsx_runtime36 = require("react/jsx-runtime");
4095
4116
  var NBSP = "\xA0";
@@ -4098,22 +4119,43 @@ function Paywall({
4098
4119
  themeClasses = {},
4099
4120
  slots = {},
4100
4121
  onBeforeCheckout
4122
+ }) {
4123
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PaywallProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4124
+ PaywallInner,
4125
+ {
4126
+ copy,
4127
+ themeClasses,
4128
+ slots,
4129
+ onBeforeCheckout
4130
+ }
4131
+ ) });
4132
+ }
4133
+ function PaywallInner({
4134
+ copy,
4135
+ themeClasses = {},
4136
+ slots = {},
4137
+ onBeforeCheckout
4101
4138
  }) {
4102
4139
  const { track: track2 } = (0, import_sdk24.useHook)();
4103
- const s = usePaywallState();
4140
+ const s = usePaywallContext();
4104
4141
  const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, "g"), " ");
4105
- const monthlyEquivLabel = formatBRL(s.currentMonthlyEquivCents).replace(new RegExp(NBSP, "g"), " ");
4106
4142
  const trialDaysCardLabel = String(s.trialDaysCard);
4107
- const ctaLabel = (0, import_react29.useMemo)(() => {
4143
+ const ctaLabel = (0, import_react31.useMemo)(() => {
4108
4144
  if (s.isFree) return copy.freeCta ?? "Come\xE7ar agora";
4109
4145
  if (s.selectedMethod === "card") {
4110
4146
  if (s.hasConsumedTrial && copy.cardConsumedTrial) {
4111
- return interp(copy.cardConsumedTrial.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
4147
+ return interp(copy.cardConsumedTrial.ctaTemplate, {
4148
+ price: priceLabel,
4149
+ days: trialDaysCardLabel
4150
+ });
4112
4151
  }
4113
4152
  if (s.trialDaysCard > 0) {
4114
4153
  return interp(copy.card.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
4115
4154
  }
4116
- return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel }) : `Assinar por ${priceLabel}`;
4155
+ return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, {
4156
+ price: priceLabel,
4157
+ days: trialDaysCardLabel
4158
+ }) : `Assinar por ${priceLabel}`;
4117
4159
  }
4118
4160
  return interp(copy.pix.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
4119
4161
  }, [
@@ -4125,11 +4167,11 @@ function Paywall({
4125
4167
  priceLabel,
4126
4168
  trialDaysCardLabel
4127
4169
  ]);
4128
- const switchHint = (0, import_react29.useMemo)(() => {
4170
+ const switchHint = (0, import_react31.useMemo)(() => {
4129
4171
  if (s.methods.length < 2) return void 0;
4130
4172
  return s.selectedMethod === "card" ? copy.card.switchHint : copy.pix.switchHint;
4131
4173
  }, [s.methods.length, s.selectedMethod, copy]);
4132
- (0, import_react29.useEffect)(() => {
4174
+ (0, import_react31.useEffect)(() => {
4133
4175
  if (!s.initialLoadComplete) return;
4134
4176
  track2("paywall_view", {
4135
4177
  default_method: s.selectedMethod,
@@ -4162,21 +4204,6 @@ function Paywall({
4162
4204
  slots.cyclePickerSlot ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4163
4205
  PaywallCyclePicker,
4164
4206
  {
4165
- cycles: ["MONTHLY", "YEARLY"],
4166
- selected: s.cycle,
4167
- onSelect: s.selectCycle,
4168
- priceCentsByCycle: {
4169
- MONTHLY: priceCentsForCycle(s, "MONTHLY"),
4170
- YEARLY: priceCentsForCycle(s, "YEARLY")
4171
- },
4172
- anchorCentsByCycle: {
4173
- MONTHLY: anchorForCycle(s, "MONTHLY"),
4174
- YEARLY: anchorForCycle(s, "YEARLY")
4175
- },
4176
- monthlyEquivByCycle: {
4177
- MONTHLY: priceCentsForCycle(s, "MONTHLY"),
4178
- YEARLY: Math.round(priceCentsForCycle(s, "YEARLY") / 12)
4179
- },
4180
4207
  labels: copy.cycle,
4181
4208
  cardClassName: themeClasses.cycleCard,
4182
4209
  cardSelectedClassName: themeClasses.cycleCardSelected,
@@ -4186,9 +4213,6 @@ function Paywall({
4186
4213
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4187
4214
  PaywallMethodTabs,
4188
4215
  {
4189
- methods: s.methods,
4190
- selected: s.selectedMethod,
4191
- onSelect: s.selectMethod,
4192
4216
  labels: { "pix-auto": copy.pix.tabLabel, card: copy.card.tabLabel },
4193
4217
  className: themeClasses.tabs,
4194
4218
  tabClassName: themeClasses.tab,
@@ -4198,7 +4222,6 @@ function Paywall({
4198
4222
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4199
4223
  PaywallMethodContent,
4200
4224
  {
4201
- method: s.selectedMethod,
4202
4225
  copy: {
4203
4226
  pix: interpolateCopy(copy.pix, priceLabel, trialDaysCardLabel),
4204
4227
  card: interpolateCopy(copy.card, priceLabel, trialDaysCardLabel),
@@ -4209,27 +4232,27 @@ function Paywall({
4209
4232
  ctaTemplate: copy.cardConsumedTrial.ctaTemplate
4210
4233
  } : void 0
4211
4234
  },
4212
- hasConsumedTrial: s.hasConsumedTrial,
4213
4235
  className: themeClasses.tabContent,
4214
4236
  rowClassName: themeClasses.tabContentRow
4215
4237
  }
4216
4238
  ),
4217
4239
  slots.beforeCtaSlot,
4218
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4219
- PaywallCta,
4220
- {
4221
- ctaLabel,
4222
- loadingLabel: "Abrindo checkout\u2026",
4223
- switchHint,
4224
- trustLine: copy.trustLine,
4225
- onClick: handleCta,
4226
- disabled: s.submitting,
4227
- loading: s.submitting,
4228
- buttonClassName: ctaTheme,
4229
- switchHintClassName: themeClasses.switchHint,
4230
- trustClassName: themeClasses.trustLine
4231
- }
4232
- )
4240
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
4241
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4242
+ "button",
4243
+ {
4244
+ type: "button",
4245
+ onClick: () => {
4246
+ void handleCta();
4247
+ },
4248
+ disabled: s.submitting,
4249
+ className: ctaTheme,
4250
+ children: s.submitting ? "Abrindo checkout\u2026" : ctaLabel
4251
+ }
4252
+ ),
4253
+ switchHint ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: themeClasses.switchHint, children: switchHint }) : null,
4254
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: themeClasses.trustLine, children: copy.trustLine })
4255
+ ] })
4233
4256
  ] });
4234
4257
  }
4235
4258
  function interp(tpl, vars) {
@@ -4243,13 +4266,438 @@ function interpolateCopy(m, price, days) {
4243
4266
  switchHint: m.switchHint
4244
4267
  };
4245
4268
  }
4246
- function priceCentsForCycle(s, c) {
4247
- return s.plan ? c === "YEARLY" ? s.plan.yearlyCents ?? 0 : s.plan.monthlyCents : 0;
4269
+
4270
+ // src/components/paywall/PaywallCta.tsx
4271
+ var import_jsx_runtime37 = require("react/jsx-runtime");
4272
+ function PaywallCta({
4273
+ ctaLabel,
4274
+ loadingLabel,
4275
+ switchHint,
4276
+ trustLine,
4277
+ className,
4278
+ buttonClassName,
4279
+ switchHintClassName,
4280
+ trustClassName
4281
+ }) {
4282
+ const { submit, submitting } = usePaywallContext();
4283
+ const label = submitting && loadingLabel ? loadingLabel : ctaLabel;
4284
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className, children: [
4285
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
4286
+ "button",
4287
+ {
4288
+ type: "button",
4289
+ onClick: () => {
4290
+ void submit();
4291
+ },
4292
+ disabled: submitting,
4293
+ className: buttonClassName,
4294
+ children: label
4295
+ }
4296
+ ),
4297
+ switchHint ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
4298
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: trustClassName, children: trustLine })
4299
+ ] });
4300
+ }
4301
+
4302
+ // src/components/paywall/blocks/PaywallEyebrow.tsx
4303
+ var import_jsx_runtime38 = require("react/jsx-runtime");
4304
+ var DEFAULT_EYEBROW_CLASSES = "text-xs uppercase tracking-widest font-semibold opacity-70";
4305
+ function PaywallEyebrow({ text, className }) {
4306
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: [DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(" "), children: text });
4307
+ }
4308
+
4309
+ // src/components/paywall/blocks/PaywallHero.tsx
4310
+ var import_jsx_runtime39 = require("react/jsx-runtime");
4311
+ var DEFAULT_GRADIENT = "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent";
4312
+ function PaywallHero({
4313
+ src,
4314
+ alt = "",
4315
+ headline,
4316
+ aspectRatio = "16/9",
4317
+ gradientClassName,
4318
+ className,
4319
+ headlineClassName,
4320
+ imgClassName,
4321
+ render
4322
+ }) {
4323
+ if (render) {
4324
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className, children: render({ src, headline }) });
4325
+ }
4326
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
4327
+ "div",
4328
+ {
4329
+ className: ["relative overflow-hidden", className].filter(Boolean).join(" "),
4330
+ style: { aspectRatio },
4331
+ children: [
4332
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4333
+ "img",
4334
+ {
4335
+ src,
4336
+ alt,
4337
+ className: ["absolute inset-0 w-full h-full object-cover", imgClassName].filter(Boolean).join(" ")
4338
+ }
4339
+ ),
4340
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: gradientClassName ?? DEFAULT_GRADIENT, "aria-hidden": "true" }),
4341
+ headline ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4342
+ "h1",
4343
+ {
4344
+ className: ["absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl", headlineClassName].filter(Boolean).join(" "),
4345
+ children: headline
4346
+ }
4347
+ ) : null
4348
+ ]
4349
+ }
4350
+ );
4351
+ }
4352
+
4353
+ // src/components/paywall/blocks/PaywallHeadline.tsx
4354
+ var import_jsx_runtime40 = require("react/jsx-runtime");
4355
+ var DEFAULT_HEADLINE_CLASSES = "text-2xl font-bold leading-tight";
4356
+ function PaywallHeadline({ text, className, as = "h1" }) {
4357
+ const Tag = as;
4358
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Tag, { className: [DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(" "), children: text });
4359
+ }
4360
+
4361
+ // src/components/paywall/blocks/PaywallPriceHeadline.tsx
4362
+ var import_jsx_runtime41 = require("react/jsx-runtime");
4363
+ var DEFAULT_CLASS = "text-2xl font-bold leading-tight";
4364
+ var CYCLE_LABEL = {
4365
+ MONTHLY: "mensal",
4366
+ YEARLY: "anual"
4367
+ };
4368
+ function PaywallPriceHeadline({
4369
+ template,
4370
+ className,
4371
+ as = "h1",
4372
+ render
4373
+ }) {
4374
+ const { cycle, currentMonthlyEquivCents, plan } = usePaywallContext();
4375
+ const yearlyCents = plan?.yearlyCents ?? null;
4376
+ const pricePerDay = formatBRL(dailyFromYearly(yearlyCents));
4377
+ const monthlyEquiv = currentMonthlyEquivCents ?? 0;
4378
+ const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();
4379
+ const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(" ");
4380
+ if (render) {
4381
+ const RootTag2 = as;
4382
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(RootTag2, { className: [className].filter(Boolean).join(" ") || void 0, children: render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle }) });
4383
+ }
4384
+ const text = template.replaceAll("{pricePerDay}", pricePerDay).replaceAll("{currentMonthlyEquiv}", formatBRL(monthlyEquiv)).replaceAll("{cycle}", cycleLabel);
4385
+ const RootTag = as;
4386
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(RootTag, { className: rootClasses, children: text });
4387
+ }
4388
+
4389
+ // src/components/paywall/blocks/PaywallCountdown.tsx
4390
+ var import_react32 = require("react");
4391
+ var import_jsx_runtime42 = require("react/jsx-runtime");
4392
+ var DEFAULT_COUNTDOWN_CLASSES = "font-mono tabular-nums";
4393
+ function resolveDeadlineMs(deadline) {
4394
+ if (deadline instanceof Date) return deadline.getTime();
4395
+ if (typeof deadline === "string") return new Date(deadline).getTime();
4396
+ const { sessionStorageKey, durationMs } = deadline;
4397
+ if (typeof window === "undefined" || typeof window.sessionStorage === "undefined") {
4398
+ return Date.now() + durationMs;
4399
+ }
4400
+ const stored = window.sessionStorage.getItem(sessionStorageKey);
4401
+ const parsed = stored ? Number.parseInt(stored, 10) : NaN;
4402
+ const now = Date.now();
4403
+ if (!Number.isFinite(parsed) || parsed < now) {
4404
+ const target = now + durationMs;
4405
+ window.sessionStorage.setItem(sessionStorageKey, String(target));
4406
+ return target;
4407
+ }
4408
+ return parsed;
4409
+ }
4410
+ function computeRemaining(deadlineMs) {
4411
+ const diff = Math.max(0, deadlineMs - Date.now());
4412
+ const totalSeconds = Math.floor(diff / 1e3);
4413
+ const h = Math.floor(totalSeconds / 3600);
4414
+ const m = Math.floor(totalSeconds % 3600 / 60);
4415
+ const s = totalSeconds % 60;
4416
+ return { h, m, s, expired: diff === 0 };
4417
+ }
4418
+ function pad(n) {
4419
+ return String(n).padStart(2, "0");
4420
+ }
4421
+ function PaywallCountdown({
4422
+ deadline,
4423
+ format = "h:m:s",
4424
+ onExpire,
4425
+ className,
4426
+ render
4427
+ }) {
4428
+ const deadlineMsRef = (0, import_react32.useRef)(null);
4429
+ if (deadlineMsRef.current === null) {
4430
+ deadlineMsRef.current = resolveDeadlineMs(deadline);
4431
+ }
4432
+ const [state, setState] = (0, import_react32.useState)(() => computeRemaining(deadlineMsRef.current));
4433
+ const expiredCalledRef = (0, import_react32.useRef)(false);
4434
+ (0, import_react32.useEffect)(() => {
4435
+ if (state.expired) {
4436
+ if (!expiredCalledRef.current) {
4437
+ expiredCalledRef.current = true;
4438
+ onExpire?.();
4439
+ }
4440
+ return;
4441
+ }
4442
+ const tick = () => {
4443
+ const next = computeRemaining(deadlineMsRef.current);
4444
+ setState(next);
4445
+ if (next.expired && !expiredCalledRef.current) {
4446
+ expiredCalledRef.current = true;
4447
+ onExpire?.();
4448
+ }
4449
+ };
4450
+ const id = setInterval(tick, 1e3);
4451
+ return () => clearInterval(id);
4452
+ }, [state.expired]);
4453
+ if (render) {
4454
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, children: render(state) });
4455
+ }
4456
+ const formatted = format === "h:m:s" ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}` : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;
4457
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: [DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(" "), children: formatted });
4458
+ }
4459
+
4460
+ // src/components/paywall/blocks/PaywallFeatures.tsx
4461
+ var import_jsx_runtime43 = require("react/jsx-runtime");
4462
+ function PaywallFeatures({
4463
+ items,
4464
+ IconComponent,
4465
+ className,
4466
+ itemClassName,
4467
+ iconClassName,
4468
+ render,
4469
+ renderItem
4470
+ }) {
4471
+ if (render) {
4472
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className, children: render({ items }) });
4473
+ }
4474
+ if (renderItem) {
4475
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { children: renderItem(item, idx) }, idx)) });
4476
+ }
4477
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("li", { className: itemClassName, children: [
4478
+ IconComponent ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(IconComponent, { className: iconClassName }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u2713" }),
4479
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: item })
4480
+ ] }, idx)) });
4481
+ }
4482
+
4483
+ // src/components/paywall/blocks/PaywallFeaturesCard.tsx
4484
+ var import_jsx_runtime44 = require("react/jsx-runtime");
4485
+ var DEFAULT_CARD_CLASSES = "rounded-xl border p-4";
4486
+ function PaywallFeaturesCard({
4487
+ title,
4488
+ items,
4489
+ className,
4490
+ cardClassName,
4491
+ titleClassName,
4492
+ itemClassName,
4493
+ renderItem
4494
+ }) {
4495
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: [DEFAULT_CARD_CLASSES, cardClassName].filter(Boolean).join(" "), children: [
4496
+ title ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: ["font-semibold mb-2", titleClassName].filter(Boolean).join(" "), children: title }) : null,
4497
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("ul", { children: items.map(
4498
+ (item, idx) => renderItem ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("li", { children: renderItem(item, idx) }, idx) : /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("li", { className: itemClassName, children: [
4499
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { "aria-hidden": "true", children: "\u2022" }),
4500
+ " ",
4501
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: item })
4502
+ ] }, idx)
4503
+ ) })
4504
+ ] }) });
4505
+ }
4506
+
4507
+ // src/components/paywall/blocks/PaywallTrophyBadge.tsx
4508
+ var import_jsx_runtime45 = require("react/jsx-runtime");
4509
+ var DEFAULT_CHIP_CLASSES = "inline-flex items-center gap-1 px-3 py-1 rounded-full bg-yellow-100 text-yellow-900 text-sm font-medium";
4510
+ var FLOATING_CLASSES = "absolute top-2 right-2 z-10 shadow-md";
4511
+ function PaywallTrophyBadge({
4512
+ text,
4513
+ className,
4514
+ iconClassName,
4515
+ floating = false,
4516
+ render
4517
+ }) {
4518
+ if (render) {
4519
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className, children: render({ text }) });
4520
+ }
4521
+ const rootClasses = [
4522
+ DEFAULT_CHIP_CLASSES,
4523
+ floating ? FLOATING_CLASSES : "",
4524
+ className
4525
+ ].filter(Boolean).join(" ");
4526
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: rootClasses, children: [
4527
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u{1F3C6}" }),
4528
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: text })
4529
+ ] });
4530
+ }
4531
+
4532
+ // src/components/paywall/blocks/PaywallAnchorPrice.tsx
4533
+ var import_jsx_runtime46 = require("react/jsx-runtime");
4534
+ var DEFAULT_CLASS2 = "text-sm opacity-60 line-through";
4535
+ function PaywallAnchorPrice({
4536
+ className,
4537
+ render
4538
+ }) {
4539
+ const { anchorPriceCents, cycle } = usePaywallContext();
4540
+ if (anchorPriceCents === null || anchorPriceCents === void 0 || anchorPriceCents <= 0) {
4541
+ return null;
4542
+ }
4543
+ void cycle;
4544
+ const formatted = formatBRL(anchorPriceCents);
4545
+ const rootClasses = [DEFAULT_CLASS2, className].filter(Boolean).join(" ");
4546
+ if (render) {
4547
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: className || void 0, children: render({ anchorCents: anchorPriceCents, formatted }) });
4548
+ }
4549
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: rootClasses, children: formatted });
4550
+ }
4551
+
4552
+ // src/components/paywall/blocks/PaywallTestimonials.tsx
4553
+ var import_jsx_runtime47 = require("react/jsx-runtime");
4554
+ var DEFAULT_ROOT = "flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2";
4555
+ var DEFAULT_CARD = "snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2";
4556
+ var DEFAULT_AVATAR = "w-10 h-10 rounded-full object-cover";
4557
+ var DEFAULT_QUOTE = "text-sm leading-snug";
4558
+ var DEFAULT_NAME = "text-xs font-semibold opacity-80";
4559
+ var DEFAULT_STARS = "text-yellow-500 text-sm";
4560
+ function clampStars(n) {
4561
+ return Math.max(0, Math.min(5, Math.round(n)));
4562
+ }
4563
+ function PaywallTestimonials({
4564
+ items,
4565
+ className,
4566
+ cardClassName,
4567
+ avatarClassName,
4568
+ quoteClassName,
4569
+ nameClassName,
4570
+ starsClassName,
4571
+ renderItem
4572
+ }) {
4573
+ const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(" ");
4574
+ const cardClasses = [DEFAULT_CARD, cardClassName].filter(Boolean).join(" ");
4575
+ const avatarClasses = [DEFAULT_AVATAR, avatarClassName].filter(Boolean).join(" ");
4576
+ const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(" ");
4577
+ const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(" ");
4578
+ const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(" ");
4579
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
4580
+ if (renderItem) return renderItem(item, idx);
4581
+ const filled = clampStars(item.stars);
4582
+ const empty = 5 - filled;
4583
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cardClasses, children: [
4584
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
4585
+ item.avatar ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4586
+ "img",
4587
+ {
4588
+ src: item.avatar,
4589
+ alt: "",
4590
+ loading: "lazy",
4591
+ className: avatarClasses,
4592
+ "aria-hidden": "true"
4593
+ }
4594
+ ) : null,
4595
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: nameClasses, children: item.name })
4596
+ ] }),
4597
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: starsClasses, "aria-label": `${filled} de 5 estrelas`, children: [
4598
+ "\u2605".repeat(filled),
4599
+ "\u2606".repeat(empty)
4600
+ ] }),
4601
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: quoteClasses, children: item.quote })
4602
+ ] }, idx);
4603
+ }) });
4604
+ }
4605
+
4606
+ // src/components/paywall/blocks/PaywallStatsRow.tsx
4607
+ var import_jsx_runtime48 = require("react/jsx-runtime");
4608
+ var DEFAULT_ROOT2 = "grid grid-cols-3 gap-4";
4609
+ var DEFAULT_CELL = "flex flex-col items-center text-center";
4610
+ var DEFAULT_VALUE = "text-2xl font-bold";
4611
+ var DEFAULT_LABEL = "text-xs opacity-70";
4612
+ function PaywallStatsRow({
4613
+ stats,
4614
+ className,
4615
+ cellClassName,
4616
+ valueClassName,
4617
+ labelClassName,
4618
+ renderCell
4619
+ }) {
4620
+ const rootClasses = [DEFAULT_ROOT2, className].filter(Boolean).join(" ");
4621
+ const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(" ");
4622
+ const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(" ");
4623
+ const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(" ");
4624
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: rootClasses, children: stats.map((stat, idx) => {
4625
+ if (renderCell) return renderCell(stat, idx);
4626
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cellClasses, children: [
4627
+ stat.icon ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { "aria-hidden": "true", children: stat.icon }) : null,
4628
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: valueClasses, children: stat.value }),
4629
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: labelClasses, children: stat.label })
4630
+ ] }, idx);
4631
+ }) });
4248
4632
  }
4249
- function anchorForCycle(s, c) {
4250
- if (!s.plan) return null;
4251
- if (c === "YEARLY") return s.plan.anchorYearlyCents ?? null;
4252
- return s.plan.anchorMonthlyCents ?? null;
4633
+
4634
+ // src/components/paywall/blocks/PaywallFinePrint.tsx
4635
+ var import_jsx_runtime49 = require("react/jsx-runtime");
4636
+ var DEFAULT_CLASS3 = "text-xs opacity-60 leading-snug";
4637
+ var CYCLE_LABEL2 = {
4638
+ MONTHLY: "mensal",
4639
+ YEARLY: "anual"
4640
+ };
4641
+ function PaywallFinePrint({
4642
+ template,
4643
+ className,
4644
+ render
4645
+ }) {
4646
+ const {
4647
+ currentPriceCents,
4648
+ cycle,
4649
+ trialDaysCard,
4650
+ trialDaysPix,
4651
+ selectedMethod
4652
+ } = usePaywallContext();
4653
+ const trialDays = selectedMethod === "card" ? trialDaysCard : trialDaysPix;
4654
+ const cycleLabel = CYCLE_LABEL2[cycle] ?? cycle.toLowerCase();
4655
+ const priceFormatted = formatBRL(currentPriceCents ?? 0);
4656
+ const rootClasses = [DEFAULT_CLASS3, className].filter(Boolean).join(" ");
4657
+ if (render) {
4658
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: className || void 0, children: render({
4659
+ currentPriceCents: currentPriceCents ?? 0,
4660
+ cycle,
4661
+ trialDays: trialDays ?? 0,
4662
+ selectedMethod
4663
+ }) });
4664
+ }
4665
+ const text = template.replaceAll("{price}", priceFormatted).replaceAll("{trialDays}", String(trialDays ?? 0)).replaceAll("{cycle}", cycleLabel);
4666
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: rootClasses, children: text });
4667
+ }
4668
+
4669
+ // src/components/paywall/blocks/PaywallTrustLine.tsx
4670
+ var import_jsx_runtime50 = require("react/jsx-runtime");
4671
+ var DEFAULT_ROOT3 = "flex items-center gap-3";
4672
+ var DEFAULT_ITEM = "flex items-center gap-1.5 text-xs";
4673
+ function PaywallTrustLine({
4674
+ items,
4675
+ className,
4676
+ itemClassName,
4677
+ renderItem
4678
+ }) {
4679
+ const rootClasses = [DEFAULT_ROOT3, className].filter(Boolean).join(" ");
4680
+ const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(" ");
4681
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
4682
+ if (renderItem) return renderItem(item, idx);
4683
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: itemClasses, children: [
4684
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { "aria-hidden": "true", children: item.icon }),
4685
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { children: item.text })
4686
+ ] }, idx);
4687
+ }) });
4688
+ }
4689
+
4690
+ // src/components/paywall/blocks/PaywallStickyFooter.tsx
4691
+ var import_jsx_runtime51 = require("react/jsx-runtime");
4692
+ var DEFAULT_CLASSES = "sticky bottom-0 left-0 right-0 bg-background";
4693
+ var SAFE_AREA_CLASS = "pb-[env(safe-area-inset-bottom)]";
4694
+ function PaywallStickyFooter({
4695
+ children,
4696
+ className,
4697
+ safeAreaInsets = true
4698
+ }) {
4699
+ const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className].filter(Boolean).join(" ");
4700
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: classes, children });
4253
4701
  }
4254
4702
  // Annotate the CommonJS export names for ESM import in node:
4255
4703
  0 && (module.exports = {
@@ -4269,10 +4717,26 @@ function anchorForCycle(s, c) {
4269
4717
  OnboardingFlow,
4270
4718
  PaymentReturnHandler,
4271
4719
  Paywall,
4720
+ PaywallAnchorPrice,
4721
+ PaywallContext,
4722
+ PaywallCountdown,
4272
4723
  PaywallCta,
4273
4724
  PaywallCyclePicker,
4725
+ PaywallEyebrow,
4726
+ PaywallFeatures,
4727
+ PaywallFeaturesCard,
4728
+ PaywallFinePrint,
4729
+ PaywallHeadline,
4730
+ PaywallHero,
4274
4731
  PaywallMethodContent,
4275
4732
  PaywallMethodTabs,
4733
+ PaywallPriceHeadline,
4734
+ PaywallProvider,
4735
+ PaywallStatsRow,
4736
+ PaywallStickyFooter,
4737
+ PaywallTestimonials,
4738
+ PaywallTrophyBadge,
4739
+ PaywallTrustLine,
4276
4740
  PersistenceRegistry,
4277
4741
  PixWaitingPageDefault,
4278
4742
  PreAuthShell,
@@ -4303,6 +4767,7 @@ function anchorForCycle(s, c) {
4303
4767
  useInstallPrompt,
4304
4768
  useLoginForm,
4305
4769
  useOnboardingStep,
4770
+ usePaywallContext,
4306
4771
  usePaywallState,
4307
4772
  usePlan,
4308
4773
  usePush,