@hook-sdk/template 0.23.2 → 0.24.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
@@ -45,10 +45,26 @@ __export(index_exports, {
45
45
  OnboardingFlow: () => OnboardingFlow,
46
46
  PaymentReturnHandler: () => PaymentReturnHandler,
47
47
  Paywall: () => Paywall,
48
+ PaywallAnchorPrice: () => PaywallAnchorPrice,
49
+ PaywallContext: () => PaywallContext,
50
+ PaywallCountdown: () => PaywallCountdown,
48
51
  PaywallCta: () => PaywallCta,
49
52
  PaywallCyclePicker: () => PaywallCyclePicker,
53
+ PaywallEyebrow: () => PaywallEyebrow,
54
+ PaywallFeatures: () => PaywallFeatures,
55
+ PaywallFeaturesCard: () => PaywallFeaturesCard,
56
+ PaywallFinePrint: () => PaywallFinePrint,
57
+ PaywallHeadline: () => PaywallHeadline,
58
+ PaywallHero: () => PaywallHero,
50
59
  PaywallMethodContent: () => PaywallMethodContent,
51
60
  PaywallMethodTabs: () => PaywallMethodTabs,
61
+ PaywallPriceHeadline: () => PaywallPriceHeadline,
62
+ PaywallProvider: () => PaywallProvider,
63
+ PaywallStatsRow: () => PaywallStatsRow,
64
+ PaywallStickyFooter: () => PaywallStickyFooter,
65
+ PaywallTestimonials: () => PaywallTestimonials,
66
+ PaywallTrophyBadge: () => PaywallTrophyBadge,
67
+ PaywallTrustLine: () => PaywallTrustLine,
52
68
  PersistenceRegistry: () => PersistenceRegistry,
53
69
  PreAuthShell: () => PreAuthShell,
54
70
  PushPrompt: () => PushPrompt2,
@@ -77,6 +93,7 @@ __export(index_exports, {
77
93
  useInstallPrompt: () => useInstallPrompt,
78
94
  useLoginForm: () => useLoginForm,
79
95
  useOnboardingStep: () => useOnboardingStep,
96
+ usePaywallContext: () => usePaywallContext,
80
97
  usePaywallState: () => usePaywallState,
81
98
  usePlan: () => usePlan,
82
99
  usePush: () => usePush,
@@ -721,8 +738,8 @@ function usePaywallState() {
721
738
  opening: submitting,
722
739
  availableMethods: methods,
723
740
  monthlyEquivalent,
724
- dismissPix: () => {
725
- },
741
+ // G154 fix (template 0.24.0 + SDK 0.26.0): wired to SDK action.
742
+ dismissPix: subscription.clearPixPending,
726
743
  refreshPlan: () => {
727
744
  }
728
745
  };
@@ -2192,7 +2209,7 @@ function I18nProvider({
2192
2209
  function isDevToolsEnabled() {
2193
2210
  if (typeof window === "undefined") return false;
2194
2211
  const host = window.location.hostname;
2195
- return host.includes(".staging.") || host === "localhost" || host === "127.0.0.1";
2212
+ return host.includes("staging.usehook.net") || host === "localhost" || host === "127.0.0.1";
2196
2213
  }
2197
2214
 
2198
2215
  // src/dev/DevSkipOnboardingFab.tsx
@@ -3375,25 +3392,42 @@ function useFeature(name) {
3375
3392
  }
3376
3393
 
3377
3394
  // src/components/paywall/Paywall.tsx
3378
- var import_react26 = require("react");
3395
+ var import_react28 = require("react");
3379
3396
  var import_sdk22 = require("@hook-sdk/sdk");
3380
3397
 
3381
- // src/components/paywall/PaywallMethodTabs.tsx
3398
+ // src/components/paywall/PaywallProvider.tsx
3399
+ var import_react26 = require("react");
3382
3400
  var import_jsx_runtime30 = require("react/jsx-runtime");
3401
+ var PaywallContext = (0, import_react26.createContext)(null);
3402
+ function PaywallProvider({ children }) {
3403
+ const state = usePaywallState();
3404
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PaywallContext.Provider, { value: state, children });
3405
+ }
3406
+
3407
+ // src/components/paywall/usePaywallContext.ts
3408
+ var import_react27 = require("react");
3409
+ function usePaywallContext() {
3410
+ const ctx = (0, import_react27.useContext)(PaywallContext);
3411
+ if (!ctx) {
3412
+ throw new Error("usePaywallContext must be used within <PaywallProvider>");
3413
+ }
3414
+ return ctx;
3415
+ }
3416
+
3417
+ // src/components/paywall/PaywallMethodTabs.tsx
3418
+ var import_jsx_runtime31 = require("react/jsx-runtime");
3383
3419
  function PaywallMethodTabs({
3384
- methods,
3385
- selected,
3386
- onSelect,
3387
3420
  labels,
3388
3421
  className,
3389
3422
  tabClassName,
3390
3423
  tabActiveClassName
3391
3424
  }) {
3425
+ const { methods, selectedMethod, selectMethod } = usePaywallContext();
3392
3426
  if (methods.length < 2) return null;
3393
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
3394
- const active = m === selected;
3427
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
3428
+ const active = m === selectedMethod;
3395
3429
  const label = labels[m] ?? m;
3396
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3430
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3397
3431
  "button",
3398
3432
  {
3399
3433
  type: "button",
@@ -3401,7 +3435,7 @@ function PaywallMethodTabs({
3401
3435
  "aria-selected": active,
3402
3436
  "aria-controls": `paywall-tab-${m}`,
3403
3437
  tabIndex: active ? 0 : -1,
3404
- onClick: () => onSelect(m),
3438
+ onClick: () => selectMethod(m),
3405
3439
  className: [tabClassName, active ? tabActiveClassName : ""].filter(Boolean).join(" "),
3406
3440
  children: label
3407
3441
  },
@@ -3411,36 +3445,51 @@ function PaywallMethodTabs({
3411
3445
  }
3412
3446
 
3413
3447
  // src/components/paywall/PaywallMethodContent.tsx
3414
- var import_jsx_runtime31 = require("react/jsx-runtime");
3415
- function PaywallMethodContent({
3416
- method,
3417
- copy,
3418
- hasConsumedTrial = false,
3419
- className,
3420
- rowClassName
3421
- }) {
3422
- const useCardConsumed = method === "card" && hasConsumedTrial && copy.cardConsumedTrial;
3423
- const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : method === "pix-auto" || method === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
3424
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { role: "tabpanel", id: `paywall-tab-${method}`, className, children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: rowClassName, children: row }, i)) });
3448
+ var import_jsx_runtime32 = require("react/jsx-runtime");
3449
+ function PaywallMethodContent({ copy, className, rowClassName }) {
3450
+ const { selectedMethod, hasConsumedTrial } = usePaywallContext();
3451
+ const useCardConsumed = selectedMethod === "card" && hasConsumedTrial && copy.cardConsumedTrial;
3452
+ const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : selectedMethod === "pix-auto" || selectedMethod === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
3453
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { role: "tabpanel", id: `paywall-tab-${selectedMethod}`, className, children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: rowClassName, children: row }, i)) });
3425
3454
  }
3426
3455
 
3427
3456
  // src/components/paywall/PaywallCyclePicker.tsx
3428
- var import_jsx_runtime32 = require("react/jsx-runtime");
3457
+ var import_jsx_runtime33 = require("react/jsx-runtime");
3458
+ var VARIANT_CLASSES = {
3459
+ default: { card: "", cardSelected: "" },
3460
+ "premium-gold": {
3461
+ card: "",
3462
+ cardSelected: "border-2 border-yellow-400/80 ring-2 ring-yellow-400/20"
3463
+ },
3464
+ "pink-pill": {
3465
+ card: "rounded-2xl",
3466
+ cardSelected: "border-2 border-pink-500"
3467
+ }
3468
+ };
3429
3469
  function PaywallCyclePicker({
3430
- cycles,
3431
- selected,
3432
- onSelect,
3433
- priceCentsByCycle,
3434
- anchorCentsByCycle,
3435
- monthlyEquivByCycle,
3436
3470
  labels,
3437
3471
  className,
3438
3472
  cardClassName,
3439
3473
  cardSelectedClassName,
3440
- anchorClassName
3474
+ anchorClassName,
3475
+ variant = "default",
3476
+ render
3441
3477
  }) {
3478
+ const ctx = usePaywallContext();
3479
+ const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;
3480
+ const cycles = ["MONTHLY", "YEARLY"];
3481
+ if (render) {
3482
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className, children: render({ cycles, selected, setCycle, plan, anchorPriceCents }) });
3483
+ }
3442
3484
  if (cycles.length < 2) return null;
3443
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
3485
+ const v = VARIANT_CLASSES[variant];
3486
+ const composedCardClassName = [v.card, cardClassName].filter(Boolean).join(" ");
3487
+ const composedCardSelectedClassName = [v.cardSelected, cardSelectedClassName].filter(Boolean).join(" ");
3488
+ const monthlyCents = plan?.monthlyCents ?? 0;
3489
+ const yearlyCents = plan?.yearlyCents ?? 0;
3490
+ const anchorMonthly = plan?.anchorMonthlyCents ?? null;
3491
+ const anchorYearly = plan?.anchorYearlyCents ?? null;
3492
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3444
3493
  "div",
3445
3494
  {
3446
3495
  role: "radiogroup",
@@ -3450,21 +3499,25 @@ function PaywallCyclePicker({
3450
3499
  const active = c === selected;
3451
3500
  const label = c === "YEARLY" ? labels.annualLabel : labels.monthlyLabel;
3452
3501
  const suffix = c === "YEARLY" ? labels.annualSuffix : labels.monthlySuffix;
3453
- const mainCents = c === "YEARLY" ? monthlyEquivByCycle[c] : priceCentsByCycle[c];
3454
- const anchorCents = anchorCentsByCycle[c];
3455
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
3502
+ const mainCents = c === "YEARLY" ? Math.round(yearlyCents / 12) : monthlyCents;
3503
+ const anchorCents = c === "YEARLY" ? anchorYearly : anchorMonthly;
3504
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
3456
3505
  "button",
3457
3506
  {
3458
3507
  type: "button",
3459
3508
  role: "radio",
3460
3509
  "aria-checked": active,
3461
- onClick: () => onSelect(c),
3462
- className: ["flex flex-col items-center gap-0.5", cardClassName, active ? cardSelectedClassName : ""].filter(Boolean).join(" "),
3510
+ onClick: () => setCycle(c),
3511
+ className: [
3512
+ "flex flex-col items-center gap-0.5",
3513
+ composedCardClassName,
3514
+ active ? composedCardSelectedClassName : ""
3515
+ ].filter(Boolean).join(" "),
3463
3516
  children: [
3464
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
3465
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
3466
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-xs opacity-60 leading-tight", children: label }),
3467
- anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: anchorClassName ?? "text-xs opacity-50", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("s", { children: formatBRL(anchorCents) }) }) : null
3517
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
3518
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
3519
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-xs opacity-60 leading-tight", children: label }),
3520
+ anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: anchorClassName ?? "text-xs opacity-50", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("s", { children: formatBRL(anchorCents) }) }) : null
3468
3521
  ]
3469
3522
  },
3470
3523
  c
@@ -3474,38 +3527,6 @@ function PaywallCyclePicker({
3474
3527
  );
3475
3528
  }
3476
3529
 
3477
- // src/components/paywall/PaywallCta.tsx
3478
- var import_jsx_runtime33 = require("react/jsx-runtime");
3479
- function PaywallCta({
3480
- ctaLabel,
3481
- loadingLabel,
3482
- switchHint,
3483
- trustLine,
3484
- onClick,
3485
- disabled = false,
3486
- loading = false,
3487
- className,
3488
- buttonClassName,
3489
- switchHintClassName,
3490
- trustClassName
3491
- }) {
3492
- const label = loading && loadingLabel ? loadingLabel : ctaLabel;
3493
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className, children: [
3494
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3495
- "button",
3496
- {
3497
- type: "button",
3498
- onClick,
3499
- disabled: disabled || loading,
3500
- className: buttonClassName,
3501
- children: label
3502
- }
3503
- ),
3504
- switchHint ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
3505
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: trustClassName, children: trustLine })
3506
- ] });
3507
- }
3508
-
3509
3530
  // src/components/paywall/Paywall.tsx
3510
3531
  var import_jsx_runtime34 = require("react/jsx-runtime");
3511
3532
  var NBSP = "\xA0";
@@ -3514,22 +3535,43 @@ function Paywall({
3514
3535
  themeClasses = {},
3515
3536
  slots = {},
3516
3537
  onBeforeCheckout
3538
+ }) {
3539
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PaywallProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3540
+ PaywallInner,
3541
+ {
3542
+ copy,
3543
+ themeClasses,
3544
+ slots,
3545
+ onBeforeCheckout
3546
+ }
3547
+ ) });
3548
+ }
3549
+ function PaywallInner({
3550
+ copy,
3551
+ themeClasses = {},
3552
+ slots = {},
3553
+ onBeforeCheckout
3517
3554
  }) {
3518
3555
  const { track: track2 } = (0, import_sdk22.useHook)();
3519
- const s = usePaywallState();
3556
+ const s = usePaywallContext();
3520
3557
  const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, "g"), " ");
3521
- const monthlyEquivLabel = formatBRL(s.currentMonthlyEquivCents).replace(new RegExp(NBSP, "g"), " ");
3522
3558
  const trialDaysCardLabel = String(s.trialDaysCard);
3523
- const ctaLabel = (0, import_react26.useMemo)(() => {
3559
+ const ctaLabel = (0, import_react28.useMemo)(() => {
3524
3560
  if (s.isFree) return copy.freeCta ?? "Come\xE7ar agora";
3525
3561
  if (s.selectedMethod === "card") {
3526
3562
  if (s.hasConsumedTrial && copy.cardConsumedTrial) {
3527
- return interp(copy.cardConsumedTrial.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
3563
+ return interp(copy.cardConsumedTrial.ctaTemplate, {
3564
+ price: priceLabel,
3565
+ days: trialDaysCardLabel
3566
+ });
3528
3567
  }
3529
3568
  if (s.trialDaysCard > 0) {
3530
3569
  return interp(copy.card.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
3531
3570
  }
3532
- return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel }) : `Assinar por ${priceLabel}`;
3571
+ return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, {
3572
+ price: priceLabel,
3573
+ days: trialDaysCardLabel
3574
+ }) : `Assinar por ${priceLabel}`;
3533
3575
  }
3534
3576
  return interp(copy.pix.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
3535
3577
  }, [
@@ -3541,11 +3583,11 @@ function Paywall({
3541
3583
  priceLabel,
3542
3584
  trialDaysCardLabel
3543
3585
  ]);
3544
- const switchHint = (0, import_react26.useMemo)(() => {
3586
+ const switchHint = (0, import_react28.useMemo)(() => {
3545
3587
  if (s.methods.length < 2) return void 0;
3546
3588
  return s.selectedMethod === "card" ? copy.card.switchHint : copy.pix.switchHint;
3547
3589
  }, [s.methods.length, s.selectedMethod, copy]);
3548
- (0, import_react26.useEffect)(() => {
3590
+ (0, import_react28.useEffect)(() => {
3549
3591
  if (!s.initialLoadComplete) return;
3550
3592
  track2("paywall_view", {
3551
3593
  default_method: s.selectedMethod,
@@ -3578,21 +3620,6 @@ function Paywall({
3578
3620
  slots.cyclePickerSlot ?? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3579
3621
  PaywallCyclePicker,
3580
3622
  {
3581
- cycles: ["MONTHLY", "YEARLY"],
3582
- selected: s.cycle,
3583
- onSelect: s.selectCycle,
3584
- priceCentsByCycle: {
3585
- MONTHLY: priceCentsForCycle(s, "MONTHLY"),
3586
- YEARLY: priceCentsForCycle(s, "YEARLY")
3587
- },
3588
- anchorCentsByCycle: {
3589
- MONTHLY: anchorForCycle(s, "MONTHLY"),
3590
- YEARLY: anchorForCycle(s, "YEARLY")
3591
- },
3592
- monthlyEquivByCycle: {
3593
- MONTHLY: priceCentsForCycle(s, "MONTHLY"),
3594
- YEARLY: Math.round(priceCentsForCycle(s, "YEARLY") / 12)
3595
- },
3596
3623
  labels: copy.cycle,
3597
3624
  cardClassName: themeClasses.cycleCard,
3598
3625
  cardSelectedClassName: themeClasses.cycleCardSelected,
@@ -3602,9 +3629,6 @@ function Paywall({
3602
3629
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3603
3630
  PaywallMethodTabs,
3604
3631
  {
3605
- methods: s.methods,
3606
- selected: s.selectedMethod,
3607
- onSelect: s.selectMethod,
3608
3632
  labels: { "pix-auto": copy.pix.tabLabel, card: copy.card.tabLabel },
3609
3633
  className: themeClasses.tabs,
3610
3634
  tabClassName: themeClasses.tab,
@@ -3614,7 +3638,6 @@ function Paywall({
3614
3638
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3615
3639
  PaywallMethodContent,
3616
3640
  {
3617
- method: s.selectedMethod,
3618
3641
  copy: {
3619
3642
  pix: interpolateCopy(copy.pix, priceLabel, trialDaysCardLabel),
3620
3643
  card: interpolateCopy(copy.card, priceLabel, trialDaysCardLabel),
@@ -3625,27 +3648,27 @@ function Paywall({
3625
3648
  ctaTemplate: copy.cardConsumedTrial.ctaTemplate
3626
3649
  } : void 0
3627
3650
  },
3628
- hasConsumedTrial: s.hasConsumedTrial,
3629
3651
  className: themeClasses.tabContent,
3630
3652
  rowClassName: themeClasses.tabContentRow
3631
3653
  }
3632
3654
  ),
3633
3655
  slots.beforeCtaSlot,
3634
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3635
- PaywallCta,
3636
- {
3637
- ctaLabel,
3638
- loadingLabel: "Abrindo checkout\u2026",
3639
- switchHint,
3640
- trustLine: copy.trustLine,
3641
- onClick: handleCta,
3642
- disabled: s.submitting,
3643
- loading: s.submitting,
3644
- buttonClassName: ctaTheme,
3645
- switchHintClassName: themeClasses.switchHint,
3646
- trustClassName: themeClasses.trustLine
3647
- }
3648
- )
3656
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
3657
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3658
+ "button",
3659
+ {
3660
+ type: "button",
3661
+ onClick: () => {
3662
+ void handleCta();
3663
+ },
3664
+ disabled: s.submitting,
3665
+ className: ctaTheme,
3666
+ children: s.submitting ? "Abrindo checkout\u2026" : ctaLabel
3667
+ }
3668
+ ),
3669
+ switchHint ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: themeClasses.switchHint, children: switchHint }) : null,
3670
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: themeClasses.trustLine, children: copy.trustLine })
3671
+ ] })
3649
3672
  ] });
3650
3673
  }
3651
3674
  function interp(tpl, vars) {
@@ -3659,13 +3682,438 @@ function interpolateCopy(m, price, days) {
3659
3682
  switchHint: m.switchHint
3660
3683
  };
3661
3684
  }
3662
- function priceCentsForCycle(s, c) {
3663
- return s.plan ? c === "YEARLY" ? s.plan.yearlyCents ?? 0 : s.plan.monthlyCents : 0;
3685
+
3686
+ // src/components/paywall/PaywallCta.tsx
3687
+ var import_jsx_runtime35 = require("react/jsx-runtime");
3688
+ function PaywallCta({
3689
+ ctaLabel,
3690
+ loadingLabel,
3691
+ switchHint,
3692
+ trustLine,
3693
+ className,
3694
+ buttonClassName,
3695
+ switchHintClassName,
3696
+ trustClassName
3697
+ }) {
3698
+ const { submit, submitting } = usePaywallContext();
3699
+ const label = submitting && loadingLabel ? loadingLabel : ctaLabel;
3700
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className, children: [
3701
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3702
+ "button",
3703
+ {
3704
+ type: "button",
3705
+ onClick: () => {
3706
+ void submit();
3707
+ },
3708
+ disabled: submitting,
3709
+ className: buttonClassName,
3710
+ children: label
3711
+ }
3712
+ ),
3713
+ switchHint ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
3714
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: trustClassName, children: trustLine })
3715
+ ] });
3716
+ }
3717
+
3718
+ // src/components/paywall/blocks/PaywallEyebrow.tsx
3719
+ var import_jsx_runtime36 = require("react/jsx-runtime");
3720
+ var DEFAULT_EYEBROW_CLASSES = "text-xs uppercase tracking-widest font-semibold opacity-70";
3721
+ function PaywallEyebrow({ text, className }) {
3722
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: [DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(" "), children: text });
3664
3723
  }
3665
- function anchorForCycle(s, c) {
3666
- if (!s.plan) return null;
3667
- if (c === "YEARLY") return s.plan.anchorYearlyCents ?? null;
3668
- return s.plan.anchorMonthlyCents ?? null;
3724
+
3725
+ // src/components/paywall/blocks/PaywallHero.tsx
3726
+ var import_jsx_runtime37 = require("react/jsx-runtime");
3727
+ var DEFAULT_GRADIENT = "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent";
3728
+ function PaywallHero({
3729
+ src,
3730
+ alt = "",
3731
+ headline,
3732
+ aspectRatio = "16/9",
3733
+ gradientClassName,
3734
+ className,
3735
+ headlineClassName,
3736
+ imgClassName,
3737
+ render
3738
+ }) {
3739
+ if (render) {
3740
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className, children: render({ src, headline }) });
3741
+ }
3742
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
3743
+ "div",
3744
+ {
3745
+ className: ["relative overflow-hidden", className].filter(Boolean).join(" "),
3746
+ style: { aspectRatio },
3747
+ children: [
3748
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3749
+ "img",
3750
+ {
3751
+ src,
3752
+ alt,
3753
+ className: ["absolute inset-0 w-full h-full object-cover", imgClassName].filter(Boolean).join(" ")
3754
+ }
3755
+ ),
3756
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: gradientClassName ?? DEFAULT_GRADIENT, "aria-hidden": "true" }),
3757
+ headline ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3758
+ "h1",
3759
+ {
3760
+ className: ["absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl", headlineClassName].filter(Boolean).join(" "),
3761
+ children: headline
3762
+ }
3763
+ ) : null
3764
+ ]
3765
+ }
3766
+ );
3767
+ }
3768
+
3769
+ // src/components/paywall/blocks/PaywallHeadline.tsx
3770
+ var import_jsx_runtime38 = require("react/jsx-runtime");
3771
+ var DEFAULT_HEADLINE_CLASSES = "text-2xl font-bold leading-tight";
3772
+ function PaywallHeadline({ text, className, as = "h1" }) {
3773
+ const Tag = as;
3774
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Tag, { className: [DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(" "), children: text });
3775
+ }
3776
+
3777
+ // src/components/paywall/blocks/PaywallPriceHeadline.tsx
3778
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3779
+ var DEFAULT_CLASS = "text-2xl font-bold leading-tight";
3780
+ var CYCLE_LABEL = {
3781
+ MONTHLY: "mensal",
3782
+ YEARLY: "anual"
3783
+ };
3784
+ function PaywallPriceHeadline({
3785
+ template,
3786
+ className,
3787
+ as = "h1",
3788
+ render
3789
+ }) {
3790
+ const { cycle, currentMonthlyEquivCents, plan } = usePaywallContext();
3791
+ const yearlyCents = plan?.yearlyCents ?? null;
3792
+ const pricePerDay = formatBRL(dailyFromYearly(yearlyCents));
3793
+ const monthlyEquiv = currentMonthlyEquivCents ?? 0;
3794
+ const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();
3795
+ const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(" ");
3796
+ if (render) {
3797
+ const RootTag2 = as;
3798
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RootTag2, { className: [className].filter(Boolean).join(" ") || void 0, children: render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle }) });
3799
+ }
3800
+ const text = template.replaceAll("{pricePerDay}", pricePerDay).replaceAll("{currentMonthlyEquiv}", formatBRL(monthlyEquiv)).replaceAll("{cycle}", cycleLabel);
3801
+ const RootTag = as;
3802
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RootTag, { className: rootClasses, children: text });
3803
+ }
3804
+
3805
+ // src/components/paywall/blocks/PaywallCountdown.tsx
3806
+ var import_react29 = require("react");
3807
+ var import_jsx_runtime40 = require("react/jsx-runtime");
3808
+ var DEFAULT_COUNTDOWN_CLASSES = "font-mono tabular-nums";
3809
+ function resolveDeadlineMs(deadline) {
3810
+ if (deadline instanceof Date) return deadline.getTime();
3811
+ if (typeof deadline === "string") return new Date(deadline).getTime();
3812
+ const { sessionStorageKey, durationMs } = deadline;
3813
+ if (typeof window === "undefined" || typeof window.sessionStorage === "undefined") {
3814
+ return Date.now() + durationMs;
3815
+ }
3816
+ const stored = window.sessionStorage.getItem(sessionStorageKey);
3817
+ const parsed = stored ? Number.parseInt(stored, 10) : NaN;
3818
+ const now = Date.now();
3819
+ if (!Number.isFinite(parsed) || parsed < now) {
3820
+ const target = now + durationMs;
3821
+ window.sessionStorage.setItem(sessionStorageKey, String(target));
3822
+ return target;
3823
+ }
3824
+ return parsed;
3825
+ }
3826
+ function computeRemaining(deadlineMs) {
3827
+ const diff = Math.max(0, deadlineMs - Date.now());
3828
+ const totalSeconds = Math.floor(diff / 1e3);
3829
+ const h = Math.floor(totalSeconds / 3600);
3830
+ const m = Math.floor(totalSeconds % 3600 / 60);
3831
+ const s = totalSeconds % 60;
3832
+ return { h, m, s, expired: diff === 0 };
3833
+ }
3834
+ function pad(n) {
3835
+ return String(n).padStart(2, "0");
3836
+ }
3837
+ function PaywallCountdown({
3838
+ deadline,
3839
+ format = "h:m:s",
3840
+ onExpire,
3841
+ className,
3842
+ render
3843
+ }) {
3844
+ const deadlineMsRef = (0, import_react29.useRef)(null);
3845
+ if (deadlineMsRef.current === null) {
3846
+ deadlineMsRef.current = resolveDeadlineMs(deadline);
3847
+ }
3848
+ const [state, setState] = (0, import_react29.useState)(() => computeRemaining(deadlineMsRef.current));
3849
+ const expiredCalledRef = (0, import_react29.useRef)(false);
3850
+ (0, import_react29.useEffect)(() => {
3851
+ if (state.expired) {
3852
+ if (!expiredCalledRef.current) {
3853
+ expiredCalledRef.current = true;
3854
+ onExpire?.();
3855
+ }
3856
+ return;
3857
+ }
3858
+ const tick = () => {
3859
+ const next = computeRemaining(deadlineMsRef.current);
3860
+ setState(next);
3861
+ if (next.expired && !expiredCalledRef.current) {
3862
+ expiredCalledRef.current = true;
3863
+ onExpire?.();
3864
+ }
3865
+ };
3866
+ const id = setInterval(tick, 1e3);
3867
+ return () => clearInterval(id);
3868
+ }, [state.expired]);
3869
+ if (render) {
3870
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className, children: render(state) });
3871
+ }
3872
+ const formatted = format === "h:m:s" ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}` : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;
3873
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: [DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(" "), children: formatted });
3874
+ }
3875
+
3876
+ // src/components/paywall/blocks/PaywallFeatures.tsx
3877
+ var import_jsx_runtime41 = require("react/jsx-runtime");
3878
+ function PaywallFeatures({
3879
+ items,
3880
+ IconComponent,
3881
+ className,
3882
+ itemClassName,
3883
+ iconClassName,
3884
+ render,
3885
+ renderItem
3886
+ }) {
3887
+ if (render) {
3888
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className, children: render({ items }) });
3889
+ }
3890
+ if (renderItem) {
3891
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("li", { children: renderItem(item, idx) }, idx)) });
3892
+ }
3893
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("li", { className: itemClassName, children: [
3894
+ IconComponent ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(IconComponent, { className: iconClassName }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u2713" }),
3895
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: item })
3896
+ ] }, idx)) });
3897
+ }
3898
+
3899
+ // src/components/paywall/blocks/PaywallFeaturesCard.tsx
3900
+ var import_jsx_runtime42 = require("react/jsx-runtime");
3901
+ var DEFAULT_CARD_CLASSES = "rounded-xl border p-4";
3902
+ function PaywallFeaturesCard({
3903
+ title,
3904
+ items,
3905
+ className,
3906
+ cardClassName,
3907
+ titleClassName,
3908
+ itemClassName,
3909
+ renderItem
3910
+ }) {
3911
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: [DEFAULT_CARD_CLASSES, cardClassName].filter(Boolean).join(" "), children: [
3912
+ title ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: ["font-semibold mb-2", titleClassName].filter(Boolean).join(" "), children: title }) : null,
3913
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { children: items.map(
3914
+ (item, idx) => renderItem ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("li", { children: renderItem(item, idx) }, idx) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("li", { className: itemClassName, children: [
3915
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { "aria-hidden": "true", children: "\u2022" }),
3916
+ " ",
3917
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: item })
3918
+ ] }, idx)
3919
+ ) })
3920
+ ] }) });
3921
+ }
3922
+
3923
+ // src/components/paywall/blocks/PaywallTrophyBadge.tsx
3924
+ var import_jsx_runtime43 = require("react/jsx-runtime");
3925
+ 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";
3926
+ var FLOATING_CLASSES = "absolute top-2 right-2 z-10 shadow-md";
3927
+ function PaywallTrophyBadge({
3928
+ text,
3929
+ className,
3930
+ iconClassName,
3931
+ floating = false,
3932
+ render
3933
+ }) {
3934
+ if (render) {
3935
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className, children: render({ text }) });
3936
+ }
3937
+ const rootClasses = [
3938
+ DEFAULT_CHIP_CLASSES,
3939
+ floating ? FLOATING_CLASSES : "",
3940
+ className
3941
+ ].filter(Boolean).join(" ");
3942
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: rootClasses, children: [
3943
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u{1F3C6}" }),
3944
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: text })
3945
+ ] });
3946
+ }
3947
+
3948
+ // src/components/paywall/blocks/PaywallAnchorPrice.tsx
3949
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3950
+ var DEFAULT_CLASS2 = "text-sm opacity-60 line-through";
3951
+ function PaywallAnchorPrice({
3952
+ className,
3953
+ render
3954
+ }) {
3955
+ const { anchorPriceCents, cycle } = usePaywallContext();
3956
+ if (anchorPriceCents === null || anchorPriceCents === void 0 || anchorPriceCents <= 0) {
3957
+ return null;
3958
+ }
3959
+ void cycle;
3960
+ const formatted = formatBRL(anchorPriceCents);
3961
+ const rootClasses = [DEFAULT_CLASS2, className].filter(Boolean).join(" ");
3962
+ if (render) {
3963
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: className || void 0, children: render({ anchorCents: anchorPriceCents, formatted }) });
3964
+ }
3965
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: rootClasses, children: formatted });
3966
+ }
3967
+
3968
+ // src/components/paywall/blocks/PaywallTestimonials.tsx
3969
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3970
+ var DEFAULT_ROOT = "flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2";
3971
+ var DEFAULT_CARD = "snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2";
3972
+ var DEFAULT_AVATAR = "w-10 h-10 rounded-full object-cover";
3973
+ var DEFAULT_QUOTE = "text-sm leading-snug";
3974
+ var DEFAULT_NAME = "text-xs font-semibold opacity-80";
3975
+ var DEFAULT_STARS = "text-yellow-500 text-sm";
3976
+ function clampStars(n) {
3977
+ return Math.max(0, Math.min(5, Math.round(n)));
3978
+ }
3979
+ function PaywallTestimonials({
3980
+ items,
3981
+ className,
3982
+ cardClassName,
3983
+ avatarClassName,
3984
+ quoteClassName,
3985
+ nameClassName,
3986
+ starsClassName,
3987
+ renderItem
3988
+ }) {
3989
+ const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(" ");
3990
+ const cardClasses = [DEFAULT_CARD, cardClassName].filter(Boolean).join(" ");
3991
+ const avatarClasses = [DEFAULT_AVATAR, avatarClassName].filter(Boolean).join(" ");
3992
+ const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(" ");
3993
+ const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(" ");
3994
+ const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(" ");
3995
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
3996
+ if (renderItem) return renderItem(item, idx);
3997
+ const filled = clampStars(item.stars);
3998
+ const empty = 5 - filled;
3999
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: cardClasses, children: [
4000
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center gap-2", children: [
4001
+ item.avatar ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4002
+ "img",
4003
+ {
4004
+ src: item.avatar,
4005
+ alt: "",
4006
+ loading: "lazy",
4007
+ className: avatarClasses,
4008
+ "aria-hidden": "true"
4009
+ }
4010
+ ) : null,
4011
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: nameClasses, children: item.name })
4012
+ ] }),
4013
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: starsClasses, "aria-label": `${filled} de 5 estrelas`, children: [
4014
+ "\u2605".repeat(filled),
4015
+ "\u2606".repeat(empty)
4016
+ ] }),
4017
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: quoteClasses, children: item.quote })
4018
+ ] }, idx);
4019
+ }) });
4020
+ }
4021
+
4022
+ // src/components/paywall/blocks/PaywallStatsRow.tsx
4023
+ var import_jsx_runtime46 = require("react/jsx-runtime");
4024
+ var DEFAULT_ROOT2 = "grid grid-cols-3 gap-4";
4025
+ var DEFAULT_CELL = "flex flex-col items-center text-center";
4026
+ var DEFAULT_VALUE = "text-2xl font-bold";
4027
+ var DEFAULT_LABEL = "text-xs opacity-70";
4028
+ function PaywallStatsRow({
4029
+ stats,
4030
+ className,
4031
+ cellClassName,
4032
+ valueClassName,
4033
+ labelClassName,
4034
+ renderCell
4035
+ }) {
4036
+ const rootClasses = [DEFAULT_ROOT2, className].filter(Boolean).join(" ");
4037
+ const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(" ");
4038
+ const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(" ");
4039
+ const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(" ");
4040
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: rootClasses, children: stats.map((stat, idx) => {
4041
+ if (renderCell) return renderCell(stat, idx);
4042
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cellClasses, children: [
4043
+ stat.icon ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { "aria-hidden": "true", children: stat.icon }) : null,
4044
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: valueClasses, children: stat.value }),
4045
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: labelClasses, children: stat.label })
4046
+ ] }, idx);
4047
+ }) });
4048
+ }
4049
+
4050
+ // src/components/paywall/blocks/PaywallFinePrint.tsx
4051
+ var import_jsx_runtime47 = require("react/jsx-runtime");
4052
+ var DEFAULT_CLASS3 = "text-xs opacity-60 leading-snug";
4053
+ var CYCLE_LABEL2 = {
4054
+ MONTHLY: "mensal",
4055
+ YEARLY: "anual"
4056
+ };
4057
+ function PaywallFinePrint({
4058
+ template,
4059
+ className,
4060
+ render
4061
+ }) {
4062
+ const {
4063
+ currentPriceCents,
4064
+ cycle,
4065
+ trialDaysCard,
4066
+ trialDaysPix,
4067
+ selectedMethod
4068
+ } = usePaywallContext();
4069
+ const trialDays = selectedMethod === "card" ? trialDaysCard : trialDaysPix;
4070
+ const cycleLabel = CYCLE_LABEL2[cycle] ?? cycle.toLowerCase();
4071
+ const priceFormatted = formatBRL(currentPriceCents ?? 0);
4072
+ const rootClasses = [DEFAULT_CLASS3, className].filter(Boolean).join(" ");
4073
+ if (render) {
4074
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: className || void 0, children: render({
4075
+ currentPriceCents: currentPriceCents ?? 0,
4076
+ cycle,
4077
+ trialDays: trialDays ?? 0,
4078
+ selectedMethod
4079
+ }) });
4080
+ }
4081
+ const text = template.replaceAll("{price}", priceFormatted).replaceAll("{trialDays}", String(trialDays ?? 0)).replaceAll("{cycle}", cycleLabel);
4082
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: rootClasses, children: text });
4083
+ }
4084
+
4085
+ // src/components/paywall/blocks/PaywallTrustLine.tsx
4086
+ var import_jsx_runtime48 = require("react/jsx-runtime");
4087
+ var DEFAULT_ROOT3 = "flex items-center gap-3";
4088
+ var DEFAULT_ITEM = "flex items-center gap-1.5 text-xs";
4089
+ function PaywallTrustLine({
4090
+ items,
4091
+ className,
4092
+ itemClassName,
4093
+ renderItem
4094
+ }) {
4095
+ const rootClasses = [DEFAULT_ROOT3, className].filter(Boolean).join(" ");
4096
+ const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(" ");
4097
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
4098
+ if (renderItem) return renderItem(item, idx);
4099
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: itemClasses, children: [
4100
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { "aria-hidden": "true", children: item.icon }),
4101
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { children: item.text })
4102
+ ] }, idx);
4103
+ }) });
4104
+ }
4105
+
4106
+ // src/components/paywall/blocks/PaywallStickyFooter.tsx
4107
+ var import_jsx_runtime49 = require("react/jsx-runtime");
4108
+ var DEFAULT_CLASSES = "sticky bottom-0 left-0 right-0 bg-background";
4109
+ var SAFE_AREA_CLASS = "pb-[env(safe-area-inset-bottom)]";
4110
+ function PaywallStickyFooter({
4111
+ children,
4112
+ className,
4113
+ safeAreaInsets = true
4114
+ }) {
4115
+ const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className].filter(Boolean).join(" ");
4116
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: classes, children });
3669
4117
  }
3670
4118
  // Annotate the CommonJS export names for ESM import in node:
3671
4119
  0 && (module.exports = {
@@ -3684,10 +4132,26 @@ function anchorForCycle(s, c) {
3684
4132
  OnboardingFlow,
3685
4133
  PaymentReturnHandler,
3686
4134
  Paywall,
4135
+ PaywallAnchorPrice,
4136
+ PaywallContext,
4137
+ PaywallCountdown,
3687
4138
  PaywallCta,
3688
4139
  PaywallCyclePicker,
4140
+ PaywallEyebrow,
4141
+ PaywallFeatures,
4142
+ PaywallFeaturesCard,
4143
+ PaywallFinePrint,
4144
+ PaywallHeadline,
4145
+ PaywallHero,
3689
4146
  PaywallMethodContent,
3690
4147
  PaywallMethodTabs,
4148
+ PaywallPriceHeadline,
4149
+ PaywallProvider,
4150
+ PaywallStatsRow,
4151
+ PaywallStickyFooter,
4152
+ PaywallTestimonials,
4153
+ PaywallTrophyBadge,
4154
+ PaywallTrustLine,
3691
4155
  PersistenceRegistry,
3692
4156
  PreAuthShell,
3693
4157
  PushPrompt,
@@ -3716,6 +4180,7 @@ function anchorForCycle(s, c) {
3716
4180
  useInstallPrompt,
3717
4181
  useLoginForm,
3718
4182
  useOnboardingStep,
4183
+ usePaywallContext,
3719
4184
  usePaywallState,
3720
4185
  usePlan,
3721
4186
  usePush,