@hook-sdk/template 0.23.3 → 0.25.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,
@@ -85,14 +102,14 @@ __export(index_exports, {
85
102
  useSignupForm: () => useSignupForm,
86
103
  useSubscription: () => useSubscription,
87
104
  useToast: () => useToast,
88
- useTrackOnboardingStep: () => import_sdk23.useTrackOnboardingStep
105
+ useTrackOnboardingStep: () => import_sdk24.useTrackOnboardingStep
89
106
  });
90
107
  module.exports = __toCommonJS(index_exports);
91
108
 
92
109
  // src/AppRoot.tsx
93
- var import_react15 = require("react");
110
+ var import_react16 = require("react");
94
111
  var import_react_router_dom2 = require("react-router-dom");
95
- var import_sdk8 = require("@hook-sdk/sdk");
112
+ var import_sdk9 = require("@hook-sdk/sdk");
96
113
 
97
114
  // src/config/AppConfigContext.tsx
98
115
  var import_react = require("react");
@@ -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
  };
@@ -2122,10 +2139,54 @@ function SessionExpiredBanner() {
2122
2139
  ] });
2123
2140
  }
2124
2141
 
2125
- // src/defaults/ErrorBoundary.tsx
2142
+ // src/internal/EmailVerifyBanner.tsx
2126
2143
  var import_react11 = require("react");
2144
+ var import_sdk5 = require("@hook-sdk/sdk");
2127
2145
  var import_jsx_runtime18 = require("react/jsx-runtime");
2128
- var ErrorBoundary = class extends import_react11.Component {
2146
+ function EmailVerifyBanner() {
2147
+ const { user, auth } = (0, import_sdk5.useHook)();
2148
+ const [sending, setSending] = (0, import_react11.useState)(false);
2149
+ const [sent, setSent] = (0, import_react11.useState)(false);
2150
+ if (!user || user.emailVerified) return null;
2151
+ async function handleResend() {
2152
+ if (sending || sent) return;
2153
+ setSending(true);
2154
+ try {
2155
+ await auth.resendVerify();
2156
+ setSent(true);
2157
+ } catch {
2158
+ } finally {
2159
+ setSending(false);
2160
+ }
2161
+ }
2162
+ const label = sent ? "Enviado!" : sending ? "Enviando..." : "Reenviar link";
2163
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2164
+ "div",
2165
+ {
2166
+ role: "status",
2167
+ "data-testid": "email-verify-banner",
2168
+ className: "sticky top-0 inset-x-0 z-50 bg-yellow-100 text-yellow-900 border-b border-yellow-200 px-4 py-2 flex items-center justify-between gap-3 text-sm",
2169
+ children: [
2170
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Confirma teu e-mail pra liberar tudo." }),
2171
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2172
+ "button",
2173
+ {
2174
+ type: "button",
2175
+ onClick: handleResend,
2176
+ disabled: sending || sent,
2177
+ className: "px-3 py-1 rounded text-xs font-medium bg-yellow-900 text-yellow-50 hover:bg-yellow-800 disabled:opacity-60 disabled:cursor-not-allowed",
2178
+ children: label
2179
+ }
2180
+ )
2181
+ ]
2182
+ }
2183
+ );
2184
+ }
2185
+
2186
+ // src/defaults/ErrorBoundary.tsx
2187
+ var import_react12 = require("react");
2188
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2189
+ var ErrorBoundary = class extends import_react12.Component {
2129
2190
  state = { error: null };
2130
2191
  static getDerivedStateFromError(error) {
2131
2192
  return { error };
@@ -2142,21 +2203,21 @@ var ErrorBoundary = class extends import_react11.Component {
2142
2203
  }
2143
2204
  render() {
2144
2205
  if (this.state.error) {
2145
- return this.props.fallback ?? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
2146
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { children: "Algo deu errado" }),
2147
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
2206
+ return this.props.fallback ?? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
2207
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { children: "Algo deu errado" }),
2208
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
2148
2209
  ] });
2149
2210
  }
2150
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: this.props.children });
2211
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: this.props.children });
2151
2212
  }
2152
2213
  };
2153
2214
 
2154
2215
  // src/i18n/I18nProvider.tsx
2155
- var import_react12 = require("react");
2216
+ var import_react13 = require("react");
2156
2217
  var import_i18next = __toESM(require("i18next"), 1);
2157
2218
  var import_react_i18next = require("react-i18next");
2158
- var import_sdk5 = require("@hook-sdk/sdk");
2159
- var import_jsx_runtime19 = require("react/jsx-runtime");
2219
+ var import_sdk6 = require("@hook-sdk/sdk");
2220
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2160
2221
  function ensureInitialized(defaultLocale, supportedLocales, resources, initialLocale) {
2161
2222
  if (import_i18next.default.isInitialized) return;
2162
2223
  import_i18next.default.use(import_react_i18next.initReactI18next).init({
@@ -2178,14 +2239,14 @@ function I18nProvider({
2178
2239
  resources,
2179
2240
  children
2180
2241
  }) {
2181
- const [userLocale] = (0, import_sdk5.usePersistedState)("user-locale", defaultLocale);
2242
+ const [userLocale] = (0, import_sdk6.usePersistedState)("user-locale", defaultLocale);
2182
2243
  ensureInitialized(defaultLocale, supportedLocales, resources, userLocale);
2183
- (0, import_react12.useEffect)(() => {
2244
+ (0, import_react13.useEffect)(() => {
2184
2245
  if (import_i18next.default.isInitialized && import_i18next.default.language !== userLocale) {
2185
2246
  import_i18next.default.changeLanguage(userLocale);
2186
2247
  }
2187
2248
  }, [userLocale]);
2188
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_i18next.I18nextProvider, { i18n: import_i18next.default, children });
2249
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_i18next.I18nextProvider, { i18n: import_i18next.default, children });
2189
2250
  }
2190
2251
 
2191
2252
  // src/dev/env.ts
@@ -2196,9 +2257,9 @@ function isDevToolsEnabled() {
2196
2257
  }
2197
2258
 
2198
2259
  // src/dev/DevSkipOnboardingFab.tsx
2199
- var import_react13 = require("react");
2200
- var import_sdk6 = require("@hook-sdk/sdk");
2201
- var import_jsx_runtime20 = require("react/jsx-runtime");
2260
+ var import_react14 = require("react");
2261
+ var import_sdk7 = require("@hook-sdk/sdk");
2262
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2202
2263
  var STORAGE_KEY = "hook_dev_skip_email";
2203
2264
  var TEST_EMAIL_DOMAIN = "@hook.test";
2204
2265
  var TEST_PASSWORD = "SkipTest!2026";
@@ -2265,18 +2326,18 @@ var STYLES = {
2265
2326
  };
2266
2327
  var CONFIRM_TIMEOUT_MS = 3e3;
2267
2328
  function DevSkipOnboardingFab({ defaults }) {
2268
- const hook = (0, import_sdk6.useHook)();
2329
+ const hook = (0, import_sdk7.useHook)();
2269
2330
  const { slug } = useAppConfig();
2270
- const [state, setState] = (0, import_react13.useState)("idle");
2271
- const [errorMsg, setErrorMsg] = (0, import_react13.useState)(null);
2272
- const timerRef = (0, import_react13.useRef)(null);
2273
- const clearTimer = (0, import_react13.useCallback)(() => {
2331
+ const [state, setState] = (0, import_react14.useState)("idle");
2332
+ const [errorMsg, setErrorMsg] = (0, import_react14.useState)(null);
2333
+ const timerRef = (0, import_react14.useRef)(null);
2334
+ const clearTimer = (0, import_react14.useCallback)(() => {
2274
2335
  if (timerRef.current) {
2275
2336
  clearTimeout(timerRef.current);
2276
2337
  timerRef.current = null;
2277
2338
  }
2278
2339
  }, []);
2279
- const onClick = (0, import_react13.useCallback)(async () => {
2340
+ const onClick = (0, import_react14.useCallback)(async () => {
2280
2341
  if (state === "busy") return;
2281
2342
  if (state === "idle" || state === "error") {
2282
2343
  setState("confirm");
@@ -2305,7 +2366,7 @@ function DevSkipOnboardingFab({ defaults }) {
2305
2366
  ...state === "confirm" || state === "error" ? STYLES.confirm : {},
2306
2367
  ...state === "busy" ? STYLES.busy : {}
2307
2368
  };
2308
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2369
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2309
2370
  "button",
2310
2371
  {
2311
2372
  type: "button",
@@ -2320,21 +2381,21 @@ function DevSkipOnboardingFab({ defaults }) {
2320
2381
  }
2321
2382
 
2322
2383
  // src/internal/PaymentReturnHandler.tsx
2323
- var import_react14 = require("react");
2324
- var import_sdk7 = require("@hook-sdk/sdk");
2325
- var import_jsx_runtime21 = require("react/jsx-runtime");
2384
+ var import_react15 = require("react");
2385
+ var import_sdk8 = require("@hook-sdk/sdk");
2386
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2326
2387
  var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
2327
2388
  var MAX_CYCLES = 3;
2328
2389
  var SUPPORT_MAILTO = "mailto:suporte@usehook.net?subject=Pagamento%20pendente";
2329
2390
  function PaymentReturnHandler({ children }) {
2330
- const { subscription, track: track2 } = (0, import_sdk7.useHook)();
2331
- const subRef = (0, import_react14.useRef)(subscription);
2391
+ const { subscription, track: track2 } = (0, import_sdk8.useHook)();
2392
+ const subRef = (0, import_react15.useRef)(subscription);
2332
2393
  subRef.current = subscription;
2333
- const runIdRef = (0, import_react14.useRef)(0);
2334
- const cyclesRef = (0, import_react14.useRef)(0);
2335
- const startMsRef = (0, import_react14.useRef)(0);
2336
- const [state, setState] = (0, import_react14.useState)("idle");
2337
- const runPoll = (0, import_react14.useCallback)(() => {
2394
+ const runIdRef = (0, import_react15.useRef)(0);
2395
+ const cyclesRef = (0, import_react15.useRef)(0);
2396
+ const startMsRef = (0, import_react15.useRef)(0);
2397
+ const [state, setState] = (0, import_react15.useState)("idle");
2398
+ const runPoll = (0, import_react15.useCallback)(() => {
2338
2399
  const runId = ++runIdRef.current;
2339
2400
  const isFirstRun = cyclesRef.current === 0;
2340
2401
  cyclesRef.current += 1;
@@ -2382,7 +2443,7 @@ function PaymentReturnHandler({ children }) {
2382
2443
  };
2383
2444
  void tick();
2384
2445
  }, [track2]);
2385
- (0, import_react14.useEffect)(() => {
2446
+ (0, import_react15.useEffect)(() => {
2386
2447
  if (typeof window === "undefined") return;
2387
2448
  const url = new URL(window.location.href);
2388
2449
  if (url.searchParams.get("paymentReturn") !== "1") return;
@@ -2392,26 +2453,26 @@ function PaymentReturnHandler({ children }) {
2392
2453
  runIdRef.current++;
2393
2454
  };
2394
2455
  }, [runPoll]);
2395
- const goHome = (0, import_react14.useCallback)(() => {
2456
+ const goHome = (0, import_react15.useCallback)(() => {
2396
2457
  const cleanUrl = new URL(window.location.href);
2397
2458
  cleanUrl.searchParams.delete("paymentReturn");
2398
2459
  cleanUrl.pathname = "/app/home";
2399
2460
  window.location.href = cleanUrl.toString();
2400
2461
  }, []);
2401
2462
  if (state === "confirming") {
2402
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
2463
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
2403
2464
  }
2404
2465
  if (state === "waiting") {
2405
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
2406
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
2407
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
2466
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
2467
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
2468
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
2408
2469
  ] }) });
2409
2470
  }
2410
2471
  if (state === "timeout") {
2411
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "alert", "aria-live": "assertive", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { maxWidth: 360, textAlign: "center", lineHeight: 1.5 }, children: [
2412
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 16 }, children: "Ainda n\xE3o conseguimos confirmar seu pagamento com o banco. Voc\xEA pode tentar de novo, voltar pro app, ou falar com a gente." }),
2413
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
2414
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2472
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "alert", "aria-live": "assertive", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { maxWidth: 360, textAlign: "center", lineHeight: 1.5 }, children: [
2473
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginBottom: 16 }, children: "Ainda n\xE3o conseguimos confirmar seu pagamento com o banco. Voc\xEA pode tentar de novo, voltar pro app, ou falar com a gente." }),
2474
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
2475
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2415
2476
  "button",
2416
2477
  {
2417
2478
  type: "button",
@@ -2424,7 +2485,7 @@ function PaymentReturnHandler({ children }) {
2424
2485
  children: "Tentar de novo"
2425
2486
  }
2426
2487
  ),
2427
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2488
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2428
2489
  "button",
2429
2490
  {
2430
2491
  type: "button",
@@ -2434,7 +2495,7 @@ function PaymentReturnHandler({ children }) {
2434
2495
  children: "Voltar pro app"
2435
2496
  }
2436
2497
  ),
2437
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2498
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2438
2499
  "a",
2439
2500
  {
2440
2501
  href: SUPPORT_MAILTO,
@@ -2446,7 +2507,7 @@ function PaymentReturnHandler({ children }) {
2446
2507
  ] })
2447
2508
  ] }) });
2448
2509
  }
2449
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_jsx_runtime21.Fragment, { children });
2510
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children });
2450
2511
  }
2451
2512
  var overlayStyle2 = {
2452
2513
  position: "fixed",
@@ -2485,7 +2546,7 @@ var linkStyle = {
2485
2546
  };
2486
2547
 
2487
2548
  // src/AppRoot.tsx
2488
- var import_jsx_runtime22 = require("react/jsx-runtime");
2549
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2489
2550
  function buildLegacyConfigShim(config) {
2490
2551
  const paywall = config.paywall;
2491
2552
  const isFree = paywall.mode === "free";
@@ -2559,19 +2620,22 @@ function AppRoot(props) {
2559
2620
  "[hook-template] <AppRoot>: PreAuthFlow slot prop is required when config.onboarding.trigger === 'pre_signup_custom'."
2560
2621
  );
2561
2622
  }
2562
- const legacyShim = (0, import_react15.useMemo)(() => buildLegacyConfigShim(config), [config]);
2623
+ const legacyShim = (0, import_react16.useMemo)(() => buildLegacyConfigShim(config), [config]);
2563
2624
  const Router = testRouter === "memory" ? import_react_router_dom2.MemoryRouter : import_react_router_dom2.BrowserRouter;
2564
2625
  const basename = `/app/${config.slug}`;
2565
2626
  const routerProps = testRouter === "memory" ? { basename, initialEntries: testInitialEntries } : { basename };
2566
2627
  const position = config.install_prompt?.position ?? "post-paywall";
2567
- const subscriptionGated = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SubscriptionGate, { Paywall: Paywall2 ?? FallbackPaywall, children: position === "post-paywall" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(InstallGate, { position: "post-paywall", children: [
2568
- children,
2569
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PushPrompt, {})
2570
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
2571
- children,
2572
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PushPrompt, {})
2573
- ] }) });
2574
- const authGated = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2628
+ const subscriptionGated = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(SubscriptionGate, { Paywall: Paywall2 ?? FallbackPaywall, children: [
2629
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmailVerifyBanner, {}),
2630
+ position === "post-paywall" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(InstallGate, { position: "post-paywall", children: [
2631
+ children,
2632
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PushPrompt, {})
2633
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
2634
+ children,
2635
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PushPrompt, {})
2636
+ ] })
2637
+ ] });
2638
+ const authGated = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2575
2639
  AuthGated,
2576
2640
  {
2577
2641
  config,
@@ -2586,13 +2650,13 @@ function AppRoot(props) {
2586
2650
  children: subscriptionGated
2587
2651
  }
2588
2652
  );
2589
- const routedTree = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Router, { ...routerProps, children: [
2590
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DeepLinkHandler, { deepLinks: config.deepLinks }),
2591
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SessionExpiredBanner, {}),
2592
- position === "pre-auth" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(InstallGate, { position: "pre-auth", children: authGated }) : authGated,
2593
- isDevToolsEnabled() && devSkipOnboarding ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DevSkipOnboardingFab, { defaults: devSkipOnboarding.defaults }) : null
2653
+ const routedTree = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Router, { ...routerProps, children: [
2654
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DeepLinkHandler, { deepLinks: config.deepLinks }),
2655
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SessionExpiredBanner, {}),
2656
+ position === "pre-auth" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InstallGate, { position: "pre-auth", children: authGated }) : authGated,
2657
+ isDevToolsEnabled() && devSkipOnboarding ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DevSkipOnboardingFab, { defaults: devSkipOnboarding.defaults }) : null
2594
2658
  ] });
2595
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AppConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PersistenceRegistry, { config: config.persistedKeys, children: config.i18n ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2659
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AppConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PersistenceRegistry, { config: config.persistedKeys, children: config.i18n ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2596
2660
  I18nProvider,
2597
2661
  {
2598
2662
  defaultLocale: config.i18n.defaultLocale,
@@ -2612,37 +2676,37 @@ function AuthGated({
2612
2676
  EmailVerify,
2613
2677
  PreAuthFlow
2614
2678
  }) {
2615
- const { authStatus } = (0, import_sdk8.useHook)();
2679
+ const { authStatus } = (0, import_sdk9.useHook)();
2616
2680
  if (authStatus === "loading") return null;
2617
2681
  if (authStatus !== "authenticated") {
2618
2682
  if (config.onboarding?.trigger === "pre_signup_custom" && PreAuthFlow) {
2619
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_router_dom2.Routes, { children: [
2620
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/signin", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Login, {}) }),
2621
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Signup, {}) }),
2622
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Forgot, {}) }),
2623
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Reset, {}) }),
2624
- EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmailVerify, {}) }) : null,
2625
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/*", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PreAuthFlow, {}) })
2683
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_router_dom2.Routes, { children: [
2684
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/signin", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Login, {}) }),
2685
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Signup, {}) }),
2686
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Forgot, {}) }),
2687
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Reset, {}) }),
2688
+ EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmailVerify, {}) }) : null,
2689
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/*", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PreAuthFlow, {}) })
2626
2690
  ] });
2627
2691
  }
2628
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_router_dom2.Routes, { children: [
2629
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Login, {}) }),
2630
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Signup, {}) }),
2631
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Forgot, {}) }),
2632
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Reset, {}) }),
2633
- EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmailVerify, {}) }) : null,
2634
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Navigate, { to: "/", replace: true }) })
2692
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_router_dom2.Routes, { children: [
2693
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Login, {}) }),
2694
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Signup, {}) }),
2695
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Forgot, {}) }),
2696
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Reset, {}) }),
2697
+ EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmailVerify, {}) }) : null,
2698
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Navigate, { to: "/", replace: true }) })
2635
2699
  ] });
2636
2700
  }
2637
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children });
2701
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children });
2638
2702
  }
2639
2703
  function FallbackPaywall() {
2640
2704
  return null;
2641
2705
  }
2642
2706
 
2643
2707
  // src/hooks/usePush.ts
2644
- var import_react16 = require("react");
2645
- var import_sdk9 = require("@hook-sdk/sdk");
2708
+ var import_react17 = require("react");
2709
+ var import_sdk10 = require("@hook-sdk/sdk");
2646
2710
  var DISMISS_STORAGE_KEY = "push:dismissed-until";
2647
2711
  var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
2648
2712
  function detectIosNeedsInstall() {
@@ -2686,12 +2750,12 @@ function deriveState(push) {
2686
2750
  return { kind: "prompt" };
2687
2751
  }
2688
2752
  function usePush() {
2689
- const { push } = (0, import_sdk9.useHook)();
2690
- const [state, setState] = (0, import_react16.useState)(() => deriveState(push));
2691
- (0, import_react16.useEffect)(() => {
2753
+ const { push } = (0, import_sdk10.useHook)();
2754
+ const [state, setState] = (0, import_react17.useState)(() => deriveState(push));
2755
+ (0, import_react17.useEffect)(() => {
2692
2756
  setState(deriveState(push));
2693
2757
  }, [push]);
2694
- const subscribe = (0, import_react16.useCallback)(async () => {
2758
+ const subscribe = (0, import_react17.useCallback)(async () => {
2695
2759
  try {
2696
2760
  await push.subscribe();
2697
2761
  setState({ kind: "subscribed" });
@@ -2703,7 +2767,7 @@ function usePush() {
2703
2767
  throw e;
2704
2768
  }
2705
2769
  }, [push]);
2706
- const unsubscribe = (0, import_react16.useCallback)(async () => {
2770
+ const unsubscribe = (0, import_react17.useCallback)(async () => {
2707
2771
  try {
2708
2772
  await push.unsubscribe();
2709
2773
  setState({ kind: "prompt" });
@@ -2712,7 +2776,7 @@ function usePush() {
2712
2776
  throw e;
2713
2777
  }
2714
2778
  }, [push]);
2715
- const dismiss = (0, import_react16.useCallback)(() => {
2779
+ const dismiss = (0, import_react17.useCallback)(() => {
2716
2780
  if (typeof localStorage !== "undefined") {
2717
2781
  try {
2718
2782
  localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS2));
@@ -2725,27 +2789,27 @@ function usePush() {
2725
2789
  }
2726
2790
 
2727
2791
  // src/components/PushPrompt.tsx
2728
- var import_jsx_runtime23 = require("react/jsx-runtime");
2792
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2729
2793
  function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
2730
2794
  const { state, subscribe } = usePush();
2731
2795
  if (state.kind === "denied" || state.kind === "dismissed" || state.kind === "subscribed") {
2732
2796
  return null;
2733
2797
  }
2734
2798
  if (state.kind === "ios_needs_install") {
2735
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
2736
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { children: texts.iosInstallTitle }),
2737
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: texts.iosInstallBody }),
2738
- onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
2799
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
2800
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { children: texts.iosInstallTitle }),
2801
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { children: texts.iosInstallBody }),
2802
+ onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
2739
2803
  ] });
2740
2804
  }
2741
2805
  if (state.kind === "unsupported") {
2742
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className, role: "region", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: texts.unsupportedBody }) });
2806
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className, role: "region", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { children: texts.unsupportedBody }) });
2743
2807
  }
2744
2808
  if (state.kind === "error") {
2745
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: state.message }) });
2809
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { children: state.message }) });
2746
2810
  }
2747
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className, role: "region", children: [
2748
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2811
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className, role: "region", children: [
2812
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2749
2813
  "button",
2750
2814
  {
2751
2815
  type: "button",
@@ -2759,67 +2823,67 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
2759
2823
  children: texts.cta
2760
2824
  }
2761
2825
  ),
2762
- onDeclined && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
2826
+ onDeclined && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
2763
2827
  ] });
2764
2828
  }
2765
2829
 
2766
2830
  // src/components/LanguageSwitcher.tsx
2767
- var import_sdk10 = require("@hook-sdk/sdk");
2768
- var import_jsx_runtime24 = require("react/jsx-runtime");
2831
+ var import_sdk11 = require("@hook-sdk/sdk");
2832
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2769
2833
  function LanguageSwitcher({ id, className, label = "Language" }) {
2770
2834
  const config = useAppConfig();
2771
2835
  const i18nConfig = config.i18n;
2772
- const [userLocale, setUserLocale] = (0, import_sdk10.usePersistedState)(
2836
+ const [userLocale, setUserLocale] = (0, import_sdk11.usePersistedState)(
2773
2837
  "user-locale",
2774
2838
  i18nConfig?.defaultLocale ?? "en-US"
2775
2839
  );
2776
2840
  if (!i18nConfig) return null;
2777
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className, children: [
2778
- label ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: label }) : null,
2779
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2841
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className, children: [
2842
+ label ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: label }) : null,
2843
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2780
2844
  "select",
2781
2845
  {
2782
2846
  id,
2783
2847
  value: userLocale,
2784
2848
  onChange: (e) => setUserLocale(e.target.value),
2785
2849
  "data-testid": "language-switcher",
2786
- children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: loc, children: loc }, loc))
2850
+ children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: loc, children: loc }, loc))
2787
2851
  }
2788
2852
  )
2789
2853
  ] });
2790
2854
  }
2791
2855
 
2792
2856
  // src/defaults/LoadingState.tsx
2793
- var import_jsx_runtime25 = require("react/jsx-runtime");
2857
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2794
2858
  function LoadingState({ message }) {
2795
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: message ?? "Carregando..." }) });
2859
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: message ?? "Carregando..." }) });
2796
2860
  }
2797
2861
 
2798
2862
  // src/defaults/EmptyState.tsx
2799
- var import_jsx_runtime26 = require("react/jsx-runtime");
2863
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2800
2864
  function EmptyState({ title, description, action }) {
2801
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
2802
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h2", { style: { marginBottom: 8 }, children: title }),
2803
- description && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { style: { opacity: 0.7 }, children: description }),
2804
- action && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { marginTop: 16 }, children: action })
2865
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
2866
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { style: { marginBottom: 8 }, children: title }),
2867
+ description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { style: { opacity: 0.7 }, children: description }),
2868
+ action && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { style: { marginTop: 16 }, children: action })
2805
2869
  ] });
2806
2870
  }
2807
2871
 
2808
2872
  // src/hooks/useLoginForm.ts
2809
- var import_react17 = require("react");
2810
- var import_sdk12 = require("@hook-sdk/sdk");
2873
+ var import_react18 = require("react");
2874
+ var import_sdk13 = require("@hook-sdk/sdk");
2811
2875
 
2812
2876
  // src/errors.ts
2813
- var import_sdk11 = require("@hook-sdk/sdk");
2877
+ var import_sdk12 = require("@hook-sdk/sdk");
2814
2878
  function mapSdkError(err) {
2815
- if (err instanceof import_sdk11.SdkRateLimitError) {
2879
+ if (err instanceof import_sdk12.SdkRateLimitError) {
2816
2880
  return {
2817
2881
  code: "rate_limited",
2818
2882
  message: `Aguarde ${err.retryAfter}s e tente novamente.`,
2819
2883
  retryAfter: err.retryAfter
2820
2884
  };
2821
2885
  }
2822
- if (err instanceof import_sdk11.SdkAuthError) {
2886
+ if (err instanceof import_sdk12.SdkAuthError) {
2823
2887
  const detail = err.detail;
2824
2888
  if (detail === "email_unverified") {
2825
2889
  return { code: "email_unverified", message: "Confirme seu e-mail antes de entrar." };
@@ -2829,7 +2893,10 @@ function mapSdkError(err) {
2829
2893
  }
2830
2894
  return { code: "invalid_credentials", message: "E-mail ou senha inv\xE1lidos." };
2831
2895
  }
2832
- if (err instanceof import_sdk11.SdkError && err.httpStatus === 0) {
2896
+ if (err instanceof import_sdk12.SdkValidationError && err.code === "auth.email_taken") {
2897
+ return { code: "email_taken", message: "Esse e-mail j\xE1 tem conta." };
2898
+ }
2899
+ if (err instanceof import_sdk12.SdkError && err.httpStatus === 0) {
2833
2900
  return { code: "network", message: "Sem conex\xE3o com o servidor. Verifique sua internet." };
2834
2901
  }
2835
2902
  if (err instanceof TypeError) {
@@ -2842,20 +2909,20 @@ function mapSdkError(err) {
2842
2909
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2843
2910
  var MIN_PASSWORD = 8;
2844
2911
  function useLoginForm() {
2845
- const { auth } = (0, import_sdk12.useHook)();
2846
- const [email, setEmail] = (0, import_react17.useState)("");
2847
- const [password, setPassword] = (0, import_react17.useState)("");
2848
- const [submitting, setSubmitting] = (0, import_react17.useState)(false);
2849
- const [error, setError] = (0, import_react17.useState)(null);
2850
- const [touchedEmail, setTouchedEmail] = (0, import_react17.useState)(false);
2851
- const [touchedPassword, setTouchedPassword] = (0, import_react17.useState)(false);
2852
- const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react17.useState)(false);
2853
- const validateEmail = (0, import_react17.useMemo)(() => {
2912
+ const { auth } = (0, import_sdk13.useHook)();
2913
+ const [email, setEmail] = (0, import_react18.useState)("");
2914
+ const [password, setPassword] = (0, import_react18.useState)("");
2915
+ const [submitting, setSubmitting] = (0, import_react18.useState)(false);
2916
+ const [error, setError] = (0, import_react18.useState)(null);
2917
+ const [touchedEmail, setTouchedEmail] = (0, import_react18.useState)(false);
2918
+ const [touchedPassword, setTouchedPassword] = (0, import_react18.useState)(false);
2919
+ const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react18.useState)(false);
2920
+ const validateEmail = (0, import_react18.useMemo)(() => {
2854
2921
  if (email.length === 0) return null;
2855
2922
  if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
2856
2923
  return null;
2857
2924
  }, [email]);
2858
- const validatePassword = (0, import_react17.useMemo)(() => {
2925
+ const validatePassword = (0, import_react18.useMemo)(() => {
2859
2926
  if (password.length === 0) return null;
2860
2927
  if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
2861
2928
  return null;
@@ -2863,7 +2930,7 @@ function useLoginForm() {
2863
2930
  const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
2864
2931
  const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
2865
2932
  const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && validateEmail === null && validatePassword === null && !submitting;
2866
- const submit = (0, import_react17.useCallback)(async () => {
2933
+ const submit = (0, import_react18.useCallback)(async () => {
2867
2934
  setFormSubmitAttempted(true);
2868
2935
  if (!canSubmit) return false;
2869
2936
  setSubmitting(true);
@@ -2897,32 +2964,32 @@ function useLoginForm() {
2897
2964
  }
2898
2965
 
2899
2966
  // src/hooks/useSignupForm.ts
2900
- var import_react18 = require("react");
2901
- var import_sdk13 = require("@hook-sdk/sdk");
2967
+ var import_react19 = require("react");
2968
+ var import_sdk14 = require("@hook-sdk/sdk");
2902
2969
  var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2903
2970
  var MIN_PASSWORD2 = 8;
2904
2971
  function useSignupForm() {
2905
- const { auth } = (0, import_sdk13.useHook)();
2906
- const [name, setName] = (0, import_react18.useState)("");
2907
- const [email, setEmail] = (0, import_react18.useState)("");
2908
- const [password, setPassword] = (0, import_react18.useState)("");
2909
- const [submitting, setSubmitting] = (0, import_react18.useState)(false);
2910
- const [error, setError] = (0, import_react18.useState)(null);
2911
- const [touchedName, setTouchedName] = (0, import_react18.useState)(false);
2912
- const [touchedEmail, setTouchedEmail] = (0, import_react18.useState)(false);
2913
- const [touchedPassword, setTouchedPassword] = (0, import_react18.useState)(false);
2914
- const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react18.useState)(false);
2915
- const validateName = (0, import_react18.useMemo)(() => {
2972
+ const { auth } = (0, import_sdk14.useHook)();
2973
+ const [name, setName] = (0, import_react19.useState)("");
2974
+ const [email, setEmail] = (0, import_react19.useState)("");
2975
+ const [password, setPassword] = (0, import_react19.useState)("");
2976
+ const [submitting, setSubmitting] = (0, import_react19.useState)(false);
2977
+ const [error, setError] = (0, import_react19.useState)(null);
2978
+ const [touchedName, setTouchedName] = (0, import_react19.useState)(false);
2979
+ const [touchedEmail, setTouchedEmail] = (0, import_react19.useState)(false);
2980
+ const [touchedPassword, setTouchedPassword] = (0, import_react19.useState)(false);
2981
+ const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react19.useState)(false);
2982
+ const validateName = (0, import_react19.useMemo)(() => {
2916
2983
  if (name.length === 0) return null;
2917
2984
  if (name.trim().length < 2) return "Nome muito curto.";
2918
2985
  return null;
2919
2986
  }, [name]);
2920
- const validateEmail = (0, import_react18.useMemo)(() => {
2987
+ const validateEmail = (0, import_react19.useMemo)(() => {
2921
2988
  if (email.length === 0) return null;
2922
2989
  if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
2923
2990
  return null;
2924
2991
  }, [email]);
2925
- const validatePassword = (0, import_react18.useMemo)(() => {
2992
+ const validatePassword = (0, import_react19.useMemo)(() => {
2926
2993
  if (password.length === 0) return null;
2927
2994
  if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
2928
2995
  return null;
@@ -2931,7 +2998,7 @@ function useSignupForm() {
2931
2998
  const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
2932
2999
  const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
2933
3000
  const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && validateName === null && validateEmail === null && validatePassword === null && !submitting;
2934
- const submit = (0, import_react18.useCallback)(async () => {
3001
+ const submit = (0, import_react19.useCallback)(async () => {
2935
3002
  setFormSubmitAttempted(true);
2936
3003
  if (!canSubmit) return false;
2937
3004
  setSubmitting(true);
@@ -2969,25 +3036,25 @@ function useSignupForm() {
2969
3036
  }
2970
3037
 
2971
3038
  // src/hooks/useForgotForm.ts
2972
- var import_react19 = require("react");
2973
- var import_sdk14 = require("@hook-sdk/sdk");
3039
+ var import_react20 = require("react");
3040
+ var import_sdk15 = require("@hook-sdk/sdk");
2974
3041
  var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2975
3042
  function useForgotForm() {
2976
- const { auth } = (0, import_sdk14.useHook)();
2977
- const [email, setEmail] = (0, import_react19.useState)("");
2978
- const [submitting, setSubmitting] = (0, import_react19.useState)(false);
2979
- const [sent, setSent] = (0, import_react19.useState)(false);
2980
- const [error, setError] = (0, import_react19.useState)(null);
2981
- const [touchedEmail, setTouchedEmail] = (0, import_react19.useState)(false);
2982
- const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react19.useState)(false);
2983
- const validateEmail = (0, import_react19.useMemo)(() => {
3043
+ const { auth } = (0, import_sdk15.useHook)();
3044
+ const [email, setEmail] = (0, import_react20.useState)("");
3045
+ const [submitting, setSubmitting] = (0, import_react20.useState)(false);
3046
+ const [sent, setSent] = (0, import_react20.useState)(false);
3047
+ const [error, setError] = (0, import_react20.useState)(null);
3048
+ const [touchedEmail, setTouchedEmail] = (0, import_react20.useState)(false);
3049
+ const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react20.useState)(false);
3050
+ const validateEmail = (0, import_react20.useMemo)(() => {
2984
3051
  if (email.length === 0) return null;
2985
3052
  if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
2986
3053
  return null;
2987
3054
  }, [email]);
2988
3055
  const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
2989
3056
  const canSubmit = email.length > 0 && validateEmail === null && !submitting;
2990
- const submit = (0, import_react19.useCallback)(async () => {
3057
+ const submit = (0, import_react20.useCallback)(async () => {
2991
3058
  setFormSubmitAttempted(true);
2992
3059
  if (!canSubmit) return false;
2993
3060
  setSubmitting(true);
@@ -3018,32 +3085,32 @@ function useForgotForm() {
3018
3085
  }
3019
3086
 
3020
3087
  // src/hooks/useResetForm.ts
3021
- var import_react20 = require("react");
3022
- var import_sdk15 = require("@hook-sdk/sdk");
3088
+ var import_react21 = require("react");
3089
+ var import_sdk16 = require("@hook-sdk/sdk");
3023
3090
  var MIN_PASSWORD3 = 12;
3024
3091
  function useResetForm() {
3025
- const { auth } = (0, import_sdk15.useHook)();
3026
- const [token, setToken] = (0, import_react20.useState)(null);
3027
- const [password, setPassword] = (0, import_react20.useState)("");
3028
- const [confirm, setConfirm] = (0, import_react20.useState)("");
3029
- const [submitting, setSubmitting] = (0, import_react20.useState)(false);
3030
- const [done, setDone] = (0, import_react20.useState)(false);
3031
- const [error, setError] = (0, import_react20.useState)(null);
3032
- const [touchedPassword, setTouchedPassword] = (0, import_react20.useState)(false);
3033
- const [touchedConfirm, setTouchedConfirm] = (0, import_react20.useState)(false);
3034
- const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react20.useState)(false);
3035
- (0, import_react20.useEffect)(() => {
3092
+ const { auth } = (0, import_sdk16.useHook)();
3093
+ const [token, setToken] = (0, import_react21.useState)(null);
3094
+ const [password, setPassword] = (0, import_react21.useState)("");
3095
+ const [confirm, setConfirm] = (0, import_react21.useState)("");
3096
+ const [submitting, setSubmitting] = (0, import_react21.useState)(false);
3097
+ const [done, setDone] = (0, import_react21.useState)(false);
3098
+ const [error, setError] = (0, import_react21.useState)(null);
3099
+ const [touchedPassword, setTouchedPassword] = (0, import_react21.useState)(false);
3100
+ const [touchedConfirm, setTouchedConfirm] = (0, import_react21.useState)(false);
3101
+ const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react21.useState)(false);
3102
+ (0, import_react21.useEffect)(() => {
3036
3103
  if (typeof window === "undefined") return;
3037
3104
  const params = new URLSearchParams(window.location.search);
3038
3105
  const t = params.get("token");
3039
3106
  setToken(t && t.length > 0 ? t : null);
3040
3107
  }, []);
3041
- const validatePassword = (0, import_react20.useMemo)(() => {
3108
+ const validatePassword = (0, import_react21.useMemo)(() => {
3042
3109
  if (password.length === 0) return null;
3043
3110
  if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
3044
3111
  return null;
3045
3112
  }, [password]);
3046
- const validateConfirm = (0, import_react20.useMemo)(() => {
3113
+ const validateConfirm = (0, import_react21.useMemo)(() => {
3047
3114
  if (confirm.length === 0) return null;
3048
3115
  if (confirm !== password) return "Senhas n\xE3o coincidem.";
3049
3116
  return null;
@@ -3051,7 +3118,7 @@ function useResetForm() {
3051
3118
  const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
3052
3119
  const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;
3053
3120
  const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && validatePassword === null && validateConfirm === null && !submitting && !done;
3054
- const submit = (0, import_react20.useCallback)(async () => {
3121
+ const submit = (0, import_react21.useCallback)(async () => {
3055
3122
  setFormSubmitAttempted(true);
3056
3123
  if (!canSubmit || token === null) return;
3057
3124
  setSubmitting(true);
@@ -3091,9 +3158,9 @@ function useResetForm() {
3091
3158
  }
3092
3159
 
3093
3160
  // src/hooks/usePlan.ts
3094
- var import_sdk16 = require("@hook-sdk/sdk");
3161
+ var import_sdk17 = require("@hook-sdk/sdk");
3095
3162
  function usePlan() {
3096
- const { plan } = (0, import_sdk16.useHook)();
3163
+ const { plan } = (0, import_sdk17.useHook)();
3097
3164
  return plan;
3098
3165
  }
3099
3166
 
@@ -3126,12 +3193,12 @@ function discountPercent(anchorCents, realCents) {
3126
3193
  }
3127
3194
 
3128
3195
  // src/hooks/useAuthPrimitives.ts
3129
- var import_react21 = require("react");
3130
- var import_sdk17 = require("@hook-sdk/sdk");
3196
+ var import_react22 = require("react");
3197
+ var import_sdk18 = require("@hook-sdk/sdk");
3131
3198
  var warned = false;
3132
3199
  function useAuthPrimitives() {
3133
- const { auth } = (0, import_sdk17.useHook)();
3134
- (0, import_react21.useEffect)(() => {
3200
+ const { auth } = (0, import_sdk18.useHook)();
3201
+ (0, import_react22.useEffect)(() => {
3135
3202
  if (!warned && process.env.NODE_ENV !== "production") {
3136
3203
  warned = true;
3137
3204
  console.warn(
@@ -3153,9 +3220,9 @@ function useAuthPrimitives() {
3153
3220
  }
3154
3221
 
3155
3222
  // src/hooks/useAuth.ts
3156
- var import_sdk18 = require("@hook-sdk/sdk");
3223
+ var import_sdk19 = require("@hook-sdk/sdk");
3157
3224
  function useAuth() {
3158
- const { user, authStatus, auth } = (0, import_sdk18.useHook)();
3225
+ const { user, authStatus, auth } = (0, import_sdk19.useHook)();
3159
3226
  return {
3160
3227
  user,
3161
3228
  authStatus,
@@ -3164,26 +3231,26 @@ function useAuth() {
3164
3231
  }
3165
3232
 
3166
3233
  // src/index.ts
3167
- var import_sdk23 = require("@hook-sdk/sdk");
3234
+ var import_sdk24 = require("@hook-sdk/sdk");
3168
3235
 
3169
3236
  // src/hooks/useSubscription.ts
3170
- var import_sdk19 = require("@hook-sdk/sdk");
3237
+ var import_sdk20 = require("@hook-sdk/sdk");
3171
3238
  function useSubscription() {
3172
- const { subscription } = (0, import_sdk19.useHook)();
3239
+ const { subscription } = (0, import_sdk20.useHook)();
3173
3240
  return {
3174
3241
  status: subscription.status()
3175
3242
  };
3176
3243
  }
3177
3244
 
3178
3245
  // src/hooks/useReminders.ts
3179
- var import_react22 = require("react");
3180
- var import_sdk20 = require("@hook-sdk/sdk");
3246
+ var import_react23 = require("react");
3247
+ var import_sdk21 = require("@hook-sdk/sdk");
3181
3248
  function useReminders() {
3182
- const { push } = (0, import_sdk20.useHook)();
3249
+ const { push } = (0, import_sdk21.useHook)();
3183
3250
  const r = push.reminders;
3184
- const [reminders, setReminders] = (0, import_react22.useState)([]);
3185
- const [loading, setLoading] = (0, import_react22.useState)(true);
3186
- const reload = (0, import_react22.useCallback)(async () => {
3251
+ const [reminders, setReminders] = (0, import_react23.useState)([]);
3252
+ const [loading, setLoading] = (0, import_react23.useState)(true);
3253
+ const reload = (0, import_react23.useCallback)(async () => {
3187
3254
  setLoading(true);
3188
3255
  try {
3189
3256
  const next = await r.list();
@@ -3192,38 +3259,38 @@ function useReminders() {
3192
3259
  setLoading(false);
3193
3260
  }
3194
3261
  }, [r]);
3195
- (0, import_react22.useEffect)(() => {
3262
+ (0, import_react23.useEffect)(() => {
3196
3263
  void reload();
3197
3264
  }, [reload]);
3198
- const setReminder = (0, import_react22.useCallback)(async (input) => {
3265
+ const setReminder = (0, import_react23.useCallback)(async (input) => {
3199
3266
  await r.set(input);
3200
3267
  await reload();
3201
3268
  }, [r, reload]);
3202
- const deleteReminder = (0, import_react22.useCallback)(async (slot) => {
3269
+ const deleteReminder = (0, import_react23.useCallback)(async (slot) => {
3203
3270
  await r.delete(slot);
3204
3271
  await reload();
3205
3272
  }, [r, reload]);
3206
- const schedule = (0, import_react22.useCallback)(async (items) => {
3273
+ const schedule = (0, import_react23.useCallback)(async (items) => {
3207
3274
  return r.schedule(items);
3208
3275
  }, [r]);
3209
- const setFallbacks = (0, import_react22.useCallback)(async (items) => {
3276
+ const setFallbacks = (0, import_react23.useCallback)(async (items) => {
3210
3277
  return r.setFallbacks(items);
3211
3278
  }, [r]);
3212
3279
  return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
3213
3280
  }
3214
3281
 
3215
3282
  // src/hooks/useToast.ts
3216
- var import_react23 = require("react");
3283
+ var import_react24 = require("react");
3217
3284
  function useToast() {
3218
- const [items, setItems] = (0, import_react23.useState)([]);
3219
- const show = (0, import_react23.useCallback)((message, kind = "info") => {
3285
+ const [items, setItems] = (0, import_react24.useState)([]);
3286
+ const show = (0, import_react24.useCallback)((message, kind = "info") => {
3220
3287
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
3221
3288
  setItems((prev) => [...prev, { id, message, kind }]);
3222
3289
  setTimeout(() => {
3223
3290
  setItems((prev) => prev.filter((t) => t.id !== id));
3224
3291
  }, 4e3);
3225
3292
  }, []);
3226
- const dismiss = (0, import_react23.useCallback)((id) => {
3293
+ const dismiss = (0, import_react24.useCallback)((id) => {
3227
3294
  setItems((prev) => prev.filter((t) => t.id !== id));
3228
3295
  }, []);
3229
3296
  return { items, show, dismiss };
@@ -3231,20 +3298,20 @@ function useToast() {
3231
3298
 
3232
3299
  // src/RouteBoundary.tsx
3233
3300
  var import_react_router_dom3 = require("react-router-dom");
3234
- var import_jsx_runtime27 = require("react/jsx-runtime");
3301
+ var import_jsx_runtime28 = require("react/jsx-runtime");
3235
3302
  function RouteBoundary({ children }) {
3236
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_router_dom3.Routes, { children: [
3303
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_router_dom3.Routes, { children: [
3237
3304
  children,
3238
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_router_dom3.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DefaultNotFound, {}) })
3305
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom3.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DefaultNotFound, {}) })
3239
3306
  ] });
3240
3307
  }
3241
3308
  function DefaultNotFound() {
3242
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
3309
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
3243
3310
  }
3244
3311
 
3245
3312
  // src/PreAuthShell.tsx
3246
3313
  var import_react_router_dom4 = require("react-router-dom");
3247
- var import_jsx_runtime28 = require("react/jsx-runtime");
3314
+ var import_jsx_runtime29 = require("react/jsx-runtime");
3248
3315
  function PreAuthShell({
3249
3316
  basename,
3250
3317
  testRouter,
@@ -3252,20 +3319,20 @@ function PreAuthShell({
3252
3319
  children
3253
3320
  }) {
3254
3321
  if (testRouter === "memory") {
3255
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom4.MemoryRouter, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom4.Routes, { children }) });
3322
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom4.MemoryRouter, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom4.Routes, { children }) });
3256
3323
  }
3257
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom4.BrowserRouter, { basename, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom4.Routes, { children }) });
3324
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom4.BrowserRouter, { basename, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom4.Routes, { children }) });
3258
3325
  }
3259
3326
 
3260
3327
  // src/OnboardingFlow.tsx
3261
- var import_react25 = require("react");
3262
- var import_sdk21 = require("@hook-sdk/sdk");
3328
+ var import_react26 = require("react");
3329
+ var import_sdk22 = require("@hook-sdk/sdk");
3263
3330
 
3264
3331
  // src/hooks/useOnboardingStep.ts
3265
- var import_react24 = require("react");
3266
- var OnboardingStepContext = (0, import_react24.createContext)(null);
3332
+ var import_react25 = require("react");
3333
+ var OnboardingStepContext = (0, import_react25.createContext)(null);
3267
3334
  function useOnboardingStep() {
3268
- const ctx = (0, import_react24.useContext)(OnboardingStepContext);
3335
+ const ctx = (0, import_react25.useContext)(OnboardingStepContext);
3269
3336
  if (!ctx) {
3270
3337
  throw new Error(
3271
3338
  "[hook-template] useOnboardingStep must be used inside <OnboardingFlow>. (G75)"
@@ -3275,7 +3342,7 @@ function useOnboardingStep() {
3275
3342
  }
3276
3343
 
3277
3344
  // src/OnboardingFlow.tsx
3278
- var import_jsx_runtime29 = require("react/jsx-runtime");
3345
+ var import_jsx_runtime30 = require("react/jsx-runtime");
3279
3346
  var isFilled = (v) => v != null && v !== "";
3280
3347
  var CURRENT_STEP_FIELD = "currentStep";
3281
3348
  function readPersistedStepIdx(draft) {
@@ -3288,12 +3355,12 @@ function OnboardingFlow({
3288
3355
  onComplete,
3289
3356
  persistKey
3290
3357
  }) {
3291
- const [draft, setDraft, status] = (0, import_sdk21.usePersistedState)(persistKey, {});
3292
- const draftRef = (0, import_react25.useRef)(draft);
3358
+ const [draft, setDraft, status] = (0, import_sdk22.usePersistedState)(persistKey, {});
3359
+ const draftRef = (0, import_react26.useRef)(draft);
3293
3360
  draftRef.current = draft;
3294
3361
  const idx = readPersistedStepIdx(draft);
3295
3362
  const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));
3296
- const setIdx = (0, import_react25.useCallback)(
3363
+ const setIdx = (0, import_react26.useCallback)(
3297
3364
  (n) => {
3298
3365
  setDraft((prev) => {
3299
3366
  const prevIdx = readPersistedStepIdx(prev);
@@ -3303,7 +3370,7 @@ function OnboardingFlow({
3303
3370
  },
3304
3371
  [setDraft]
3305
3372
  );
3306
- const setValue = (0, import_react25.useCallback)(
3373
+ const setValue = (0, import_react26.useCallback)(
3307
3374
  (patch) => {
3308
3375
  draftRef.current = { ...draftRef.current, ...patch };
3309
3376
  setDraft((prev) => ({ ...prev, ...patch }));
@@ -3311,9 +3378,9 @@ function OnboardingFlow({
3311
3378
  [setDraft]
3312
3379
  );
3313
3380
  const step = steps[clampedIdx];
3314
- const hookCtx = (0, import_sdk21.useHook)();
3381
+ const hookCtx = (0, import_sdk22.useHook)();
3315
3382
  const track2 = typeof hookCtx.track === "function" ? hookCtx.track : void 0;
3316
- (0, import_react25.useEffect)(() => {
3383
+ (0, import_react26.useEffect)(() => {
3317
3384
  if (status.loading) return;
3318
3385
  if (!step) return;
3319
3386
  if (!track2) return;
@@ -3323,11 +3390,11 @@ function OnboardingFlow({
3323
3390
  total_steps: steps.length
3324
3391
  });
3325
3392
  }, [step?.id, clampedIdx, steps.length, status.loading, track2]);
3326
- const valid = (0, import_react25.useMemo)(
3393
+ const valid = (0, import_react26.useMemo)(
3327
3394
  () => step ? (step.validates ?? []).every((field) => isFilled(draft[field])) : false,
3328
3395
  [draft, step]
3329
3396
  );
3330
- const next = (0, import_react25.useCallback)(() => {
3397
+ const next = (0, import_react26.useCallback)(() => {
3331
3398
  if (!step) return;
3332
3399
  const current = draftRef.current;
3333
3400
  const validNow = (step.validates ?? []).every((field) => isFilled(current[field]));
@@ -3338,8 +3405,8 @@ function OnboardingFlow({
3338
3405
  setIdx(clampedIdx + 1);
3339
3406
  }
3340
3407
  }, [clampedIdx, onComplete, step, steps.length, setIdx]);
3341
- const prevStep = (0, import_react25.useCallback)(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);
3342
- const ctx = (0, import_react25.useMemo)(
3408
+ const prevStep = (0, import_react26.useCallback)(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);
3409
+ const ctx = (0, import_react26.useMemo)(
3343
3410
  () => ({
3344
3411
  stepIndex: clampedIdx,
3345
3412
  totalSteps: steps.length,
@@ -3365,7 +3432,7 @@ function OnboardingFlow({
3365
3432
  `[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`
3366
3433
  );
3367
3434
  }
3368
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Screen, {}) });
3435
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Screen, {}) });
3369
3436
  }
3370
3437
 
3371
3438
  // src/hooks/useFeature.ts
@@ -3375,25 +3442,42 @@ function useFeature(name) {
3375
3442
  }
3376
3443
 
3377
3444
  // src/components/paywall/Paywall.tsx
3378
- var import_react26 = require("react");
3379
- var import_sdk22 = require("@hook-sdk/sdk");
3445
+ var import_react29 = require("react");
3446
+ var import_sdk23 = require("@hook-sdk/sdk");
3447
+
3448
+ // src/components/paywall/PaywallProvider.tsx
3449
+ var import_react27 = require("react");
3450
+ var import_jsx_runtime31 = require("react/jsx-runtime");
3451
+ var PaywallContext = (0, import_react27.createContext)(null);
3452
+ function PaywallProvider({ children }) {
3453
+ const state = usePaywallState();
3454
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(PaywallContext.Provider, { value: state, children });
3455
+ }
3456
+
3457
+ // src/components/paywall/usePaywallContext.ts
3458
+ var import_react28 = require("react");
3459
+ function usePaywallContext() {
3460
+ const ctx = (0, import_react28.useContext)(PaywallContext);
3461
+ if (!ctx) {
3462
+ throw new Error("usePaywallContext must be used within <PaywallProvider>");
3463
+ }
3464
+ return ctx;
3465
+ }
3380
3466
 
3381
3467
  // src/components/paywall/PaywallMethodTabs.tsx
3382
- var import_jsx_runtime30 = require("react/jsx-runtime");
3468
+ var import_jsx_runtime32 = require("react/jsx-runtime");
3383
3469
  function PaywallMethodTabs({
3384
- methods,
3385
- selected,
3386
- onSelect,
3387
3470
  labels,
3388
3471
  className,
3389
3472
  tabClassName,
3390
3473
  tabActiveClassName
3391
3474
  }) {
3475
+ const { methods, selectedMethod, selectMethod } = usePaywallContext();
3392
3476
  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;
3477
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
3478
+ const active = m === selectedMethod;
3395
3479
  const label = labels[m] ?? m;
3396
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3480
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
3397
3481
  "button",
3398
3482
  {
3399
3483
  type: "button",
@@ -3401,7 +3485,7 @@ function PaywallMethodTabs({
3401
3485
  "aria-selected": active,
3402
3486
  "aria-controls": `paywall-tab-${m}`,
3403
3487
  tabIndex: active ? 0 : -1,
3404
- onClick: () => onSelect(m),
3488
+ onClick: () => selectMethod(m),
3405
3489
  className: [tabClassName, active ? tabActiveClassName : ""].filter(Boolean).join(" "),
3406
3490
  children: label
3407
3491
  },
@@ -3411,36 +3495,51 @@ function PaywallMethodTabs({
3411
3495
  }
3412
3496
 
3413
3497
  // 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)) });
3498
+ var import_jsx_runtime33 = require("react/jsx-runtime");
3499
+ function PaywallMethodContent({ copy, className, rowClassName }) {
3500
+ const { selectedMethod, hasConsumedTrial } = usePaywallContext();
3501
+ const useCardConsumed = selectedMethod === "card" && hasConsumedTrial && copy.cardConsumedTrial;
3502
+ const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : selectedMethod === "pix-auto" || selectedMethod === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
3503
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { role: "tabpanel", id: `paywall-tab-${selectedMethod}`, className, children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: rowClassName, children: row }, i)) });
3425
3504
  }
3426
3505
 
3427
3506
  // src/components/paywall/PaywallCyclePicker.tsx
3428
- var import_jsx_runtime32 = require("react/jsx-runtime");
3507
+ var import_jsx_runtime34 = require("react/jsx-runtime");
3508
+ var VARIANT_CLASSES = {
3509
+ default: { card: "", cardSelected: "" },
3510
+ "premium-gold": {
3511
+ card: "",
3512
+ cardSelected: "border-2 border-yellow-400/80 ring-2 ring-yellow-400/20"
3513
+ },
3514
+ "pink-pill": {
3515
+ card: "rounded-2xl",
3516
+ cardSelected: "border-2 border-pink-500"
3517
+ }
3518
+ };
3429
3519
  function PaywallCyclePicker({
3430
- cycles,
3431
- selected,
3432
- onSelect,
3433
- priceCentsByCycle,
3434
- anchorCentsByCycle,
3435
- monthlyEquivByCycle,
3436
3520
  labels,
3437
3521
  className,
3438
3522
  cardClassName,
3439
3523
  cardSelectedClassName,
3440
- anchorClassName
3524
+ anchorClassName,
3525
+ variant = "default",
3526
+ render
3441
3527
  }) {
3528
+ const ctx = usePaywallContext();
3529
+ const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;
3530
+ const cycles = ["MONTHLY", "YEARLY"];
3531
+ if (render) {
3532
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className, children: render({ cycles, selected, setCycle, plan, anchorPriceCents }) });
3533
+ }
3442
3534
  if (cycles.length < 2) return null;
3443
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
3535
+ const v = VARIANT_CLASSES[variant];
3536
+ const composedCardClassName = [v.card, cardClassName].filter(Boolean).join(" ");
3537
+ const composedCardSelectedClassName = [v.cardSelected, cardSelectedClassName].filter(Boolean).join(" ");
3538
+ const monthlyCents = plan?.monthlyCents ?? 0;
3539
+ const yearlyCents = plan?.yearlyCents ?? 0;
3540
+ const anchorMonthly = plan?.anchorMonthlyCents ?? null;
3541
+ const anchorYearly = plan?.anchorYearlyCents ?? null;
3542
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3444
3543
  "div",
3445
3544
  {
3446
3545
  role: "radiogroup",
@@ -3450,21 +3549,25 @@ function PaywallCyclePicker({
3450
3549
  const active = c === selected;
3451
3550
  const label = c === "YEARLY" ? labels.annualLabel : labels.monthlyLabel;
3452
3551
  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)(
3552
+ const mainCents = c === "YEARLY" ? Math.round(yearlyCents / 12) : monthlyCents;
3553
+ const anchorCents = c === "YEARLY" ? anchorYearly : anchorMonthly;
3554
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
3456
3555
  "button",
3457
3556
  {
3458
3557
  type: "button",
3459
3558
  role: "radio",
3460
3559
  "aria-checked": active,
3461
- onClick: () => onSelect(c),
3462
- className: ["flex flex-col items-center gap-0.5", cardClassName, active ? cardSelectedClassName : ""].filter(Boolean).join(" "),
3560
+ onClick: () => setCycle(c),
3561
+ className: [
3562
+ "flex flex-col items-center gap-0.5",
3563
+ composedCardClassName,
3564
+ active ? composedCardSelectedClassName : ""
3565
+ ].filter(Boolean).join(" "),
3463
3566
  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
3567
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
3568
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
3569
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-xs opacity-60 leading-tight", children: label }),
3570
+ 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
3468
3571
  ]
3469
3572
  },
3470
3573
  c
@@ -3474,40 +3577,8 @@ function PaywallCyclePicker({
3474
3577
  );
3475
3578
  }
3476
3579
 
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
3580
  // src/components/paywall/Paywall.tsx
3510
- var import_jsx_runtime34 = require("react/jsx-runtime");
3581
+ var import_jsx_runtime35 = require("react/jsx-runtime");
3511
3582
  var NBSP = "\xA0";
3512
3583
  function Paywall({
3513
3584
  copy,
@@ -3515,21 +3586,42 @@ function Paywall({
3515
3586
  slots = {},
3516
3587
  onBeforeCheckout
3517
3588
  }) {
3518
- const { track: track2 } = (0, import_sdk22.useHook)();
3519
- const s = usePaywallState();
3589
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(PaywallProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3590
+ PaywallInner,
3591
+ {
3592
+ copy,
3593
+ themeClasses,
3594
+ slots,
3595
+ onBeforeCheckout
3596
+ }
3597
+ ) });
3598
+ }
3599
+ function PaywallInner({
3600
+ copy,
3601
+ themeClasses = {},
3602
+ slots = {},
3603
+ onBeforeCheckout
3604
+ }) {
3605
+ const { track: track2 } = (0, import_sdk23.useHook)();
3606
+ const s = usePaywallContext();
3520
3607
  const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, "g"), " ");
3521
- const monthlyEquivLabel = formatBRL(s.currentMonthlyEquivCents).replace(new RegExp(NBSP, "g"), " ");
3522
3608
  const trialDaysCardLabel = String(s.trialDaysCard);
3523
- const ctaLabel = (0, import_react26.useMemo)(() => {
3609
+ const ctaLabel = (0, import_react29.useMemo)(() => {
3524
3610
  if (s.isFree) return copy.freeCta ?? "Come\xE7ar agora";
3525
3611
  if (s.selectedMethod === "card") {
3526
3612
  if (s.hasConsumedTrial && copy.cardConsumedTrial) {
3527
- return interp(copy.cardConsumedTrial.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
3613
+ return interp(copy.cardConsumedTrial.ctaTemplate, {
3614
+ price: priceLabel,
3615
+ days: trialDaysCardLabel
3616
+ });
3528
3617
  }
3529
3618
  if (s.trialDaysCard > 0) {
3530
3619
  return interp(copy.card.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
3531
3620
  }
3532
- return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel }) : `Assinar por ${priceLabel}`;
3621
+ return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, {
3622
+ price: priceLabel,
3623
+ days: trialDaysCardLabel
3624
+ }) : `Assinar por ${priceLabel}`;
3533
3625
  }
3534
3626
  return interp(copy.pix.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
3535
3627
  }, [
@@ -3541,11 +3633,11 @@ function Paywall({
3541
3633
  priceLabel,
3542
3634
  trialDaysCardLabel
3543
3635
  ]);
3544
- const switchHint = (0, import_react26.useMemo)(() => {
3636
+ const switchHint = (0, import_react29.useMemo)(() => {
3545
3637
  if (s.methods.length < 2) return void 0;
3546
3638
  return s.selectedMethod === "card" ? copy.card.switchHint : copy.pix.switchHint;
3547
3639
  }, [s.methods.length, s.selectedMethod, copy]);
3548
- (0, import_react26.useEffect)(() => {
3640
+ (0, import_react29.useEffect)(() => {
3549
3641
  if (!s.initialLoadComplete) return;
3550
3642
  track2("paywall_view", {
3551
3643
  default_method: s.selectedMethod,
@@ -3567,54 +3659,35 @@ function Paywall({
3567
3659
  await s.submit();
3568
3660
  };
3569
3661
  const ctaTheme = s.selectedMethod === "card" ? themeClasses.ctaCard : themeClasses.ctaPix;
3570
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: themeClasses.container, children: [
3662
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: themeClasses.container, children: [
3571
3663
  slots.heroSlot,
3572
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h1", { className: themeClasses.headline, children: copy.headline }),
3573
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("ul", { children: copy.features.map((f) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("li", { className: themeClasses.feature, children: [
3664
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h1", { className: themeClasses.headline, children: copy.headline }),
3665
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("ul", { children: copy.features.map((f) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("li", { className: themeClasses.feature, children: [
3574
3666
  "\u2713 ",
3575
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: f })
3667
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: f })
3576
3668
  ] }, f)) }),
3577
- copy.socialProof ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: themeClasses.socialProof, children: copy.socialProof }) : null,
3578
- slots.cyclePickerSlot ?? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3669
+ copy.socialProof ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: themeClasses.socialProof, children: copy.socialProof }) : null,
3670
+ slots.cyclePickerSlot ?? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3579
3671
  PaywallCyclePicker,
3580
3672
  {
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
3673
  labels: copy.cycle,
3597
3674
  cardClassName: themeClasses.cycleCard,
3598
3675
  cardSelectedClassName: themeClasses.cycleCardSelected,
3599
3676
  anchorClassName: themeClasses.anchorPrice
3600
3677
  }
3601
3678
  ),
3602
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3679
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3603
3680
  PaywallMethodTabs,
3604
3681
  {
3605
- methods: s.methods,
3606
- selected: s.selectedMethod,
3607
- onSelect: s.selectMethod,
3608
3682
  labels: { "pix-auto": copy.pix.tabLabel, card: copy.card.tabLabel },
3609
3683
  className: themeClasses.tabs,
3610
3684
  tabClassName: themeClasses.tab,
3611
3685
  tabActiveClassName: themeClasses.tabActive
3612
3686
  }
3613
3687
  ),
3614
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3688
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3615
3689
  PaywallMethodContent,
3616
3690
  {
3617
- method: s.selectedMethod,
3618
3691
  copy: {
3619
3692
  pix: interpolateCopy(copy.pix, priceLabel, trialDaysCardLabel),
3620
3693
  card: interpolateCopy(copy.card, priceLabel, trialDaysCardLabel),
@@ -3625,27 +3698,27 @@ function Paywall({
3625
3698
  ctaTemplate: copy.cardConsumedTrial.ctaTemplate
3626
3699
  } : void 0
3627
3700
  },
3628
- hasConsumedTrial: s.hasConsumedTrial,
3629
3701
  className: themeClasses.tabContent,
3630
3702
  rowClassName: themeClasses.tabContentRow
3631
3703
  }
3632
3704
  ),
3633
3705
  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
- )
3706
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
3707
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3708
+ "button",
3709
+ {
3710
+ type: "button",
3711
+ onClick: () => {
3712
+ void handleCta();
3713
+ },
3714
+ disabled: s.submitting,
3715
+ className: ctaTheme,
3716
+ children: s.submitting ? "Abrindo checkout\u2026" : ctaLabel
3717
+ }
3718
+ ),
3719
+ switchHint ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: themeClasses.switchHint, children: switchHint }) : null,
3720
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: themeClasses.trustLine, children: copy.trustLine })
3721
+ ] })
3649
3722
  ] });
3650
3723
  }
3651
3724
  function interp(tpl, vars) {
@@ -3659,13 +3732,438 @@ function interpolateCopy(m, price, days) {
3659
3732
  switchHint: m.switchHint
3660
3733
  };
3661
3734
  }
3662
- function priceCentsForCycle(s, c) {
3663
- return s.plan ? c === "YEARLY" ? s.plan.yearlyCents ?? 0 : s.plan.monthlyCents : 0;
3735
+
3736
+ // src/components/paywall/PaywallCta.tsx
3737
+ var import_jsx_runtime36 = require("react/jsx-runtime");
3738
+ function PaywallCta({
3739
+ ctaLabel,
3740
+ loadingLabel,
3741
+ switchHint,
3742
+ trustLine,
3743
+ className,
3744
+ buttonClassName,
3745
+ switchHintClassName,
3746
+ trustClassName
3747
+ }) {
3748
+ const { submit, submitting } = usePaywallContext();
3749
+ const label = submitting && loadingLabel ? loadingLabel : ctaLabel;
3750
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className, children: [
3751
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3752
+ "button",
3753
+ {
3754
+ type: "button",
3755
+ onClick: () => {
3756
+ void submit();
3757
+ },
3758
+ disabled: submitting,
3759
+ className: buttonClassName,
3760
+ children: label
3761
+ }
3762
+ ),
3763
+ switchHint ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
3764
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: trustClassName, children: trustLine })
3765
+ ] });
3766
+ }
3767
+
3768
+ // src/components/paywall/blocks/PaywallEyebrow.tsx
3769
+ var import_jsx_runtime37 = require("react/jsx-runtime");
3770
+ var DEFAULT_EYEBROW_CLASSES = "text-xs uppercase tracking-widest font-semibold opacity-70";
3771
+ function PaywallEyebrow({ text, className }) {
3772
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: [DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(" "), children: text });
3664
3773
  }
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;
3774
+
3775
+ // src/components/paywall/blocks/PaywallHero.tsx
3776
+ var import_jsx_runtime38 = require("react/jsx-runtime");
3777
+ var DEFAULT_GRADIENT = "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent";
3778
+ function PaywallHero({
3779
+ src,
3780
+ alt = "",
3781
+ headline,
3782
+ aspectRatio = "16/9",
3783
+ gradientClassName,
3784
+ className,
3785
+ headlineClassName,
3786
+ imgClassName,
3787
+ render
3788
+ }) {
3789
+ if (render) {
3790
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className, children: render({ src, headline }) });
3791
+ }
3792
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
3793
+ "div",
3794
+ {
3795
+ className: ["relative overflow-hidden", className].filter(Boolean).join(" "),
3796
+ style: { aspectRatio },
3797
+ children: [
3798
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3799
+ "img",
3800
+ {
3801
+ src,
3802
+ alt,
3803
+ className: ["absolute inset-0 w-full h-full object-cover", imgClassName].filter(Boolean).join(" ")
3804
+ }
3805
+ ),
3806
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: gradientClassName ?? DEFAULT_GRADIENT, "aria-hidden": "true" }),
3807
+ headline ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3808
+ "h1",
3809
+ {
3810
+ className: ["absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl", headlineClassName].filter(Boolean).join(" "),
3811
+ children: headline
3812
+ }
3813
+ ) : null
3814
+ ]
3815
+ }
3816
+ );
3817
+ }
3818
+
3819
+ // src/components/paywall/blocks/PaywallHeadline.tsx
3820
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3821
+ var DEFAULT_HEADLINE_CLASSES = "text-2xl font-bold leading-tight";
3822
+ function PaywallHeadline({ text, className, as = "h1" }) {
3823
+ const Tag = as;
3824
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Tag, { className: [DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(" "), children: text });
3825
+ }
3826
+
3827
+ // src/components/paywall/blocks/PaywallPriceHeadline.tsx
3828
+ var import_jsx_runtime40 = require("react/jsx-runtime");
3829
+ var DEFAULT_CLASS = "text-2xl font-bold leading-tight";
3830
+ var CYCLE_LABEL = {
3831
+ MONTHLY: "mensal",
3832
+ YEARLY: "anual"
3833
+ };
3834
+ function PaywallPriceHeadline({
3835
+ template,
3836
+ className,
3837
+ as = "h1",
3838
+ render
3839
+ }) {
3840
+ const { cycle, currentMonthlyEquivCents, plan } = usePaywallContext();
3841
+ const yearlyCents = plan?.yearlyCents ?? null;
3842
+ const pricePerDay = formatBRL(dailyFromYearly(yearlyCents));
3843
+ const monthlyEquiv = currentMonthlyEquivCents ?? 0;
3844
+ const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();
3845
+ const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(" ");
3846
+ if (render) {
3847
+ const RootTag2 = as;
3848
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(RootTag2, { className: [className].filter(Boolean).join(" ") || void 0, children: render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle }) });
3849
+ }
3850
+ const text = template.replaceAll("{pricePerDay}", pricePerDay).replaceAll("{currentMonthlyEquiv}", formatBRL(monthlyEquiv)).replaceAll("{cycle}", cycleLabel);
3851
+ const RootTag = as;
3852
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(RootTag, { className: rootClasses, children: text });
3853
+ }
3854
+
3855
+ // src/components/paywall/blocks/PaywallCountdown.tsx
3856
+ var import_react30 = require("react");
3857
+ var import_jsx_runtime41 = require("react/jsx-runtime");
3858
+ var DEFAULT_COUNTDOWN_CLASSES = "font-mono tabular-nums";
3859
+ function resolveDeadlineMs(deadline) {
3860
+ if (deadline instanceof Date) return deadline.getTime();
3861
+ if (typeof deadline === "string") return new Date(deadline).getTime();
3862
+ const { sessionStorageKey, durationMs } = deadline;
3863
+ if (typeof window === "undefined" || typeof window.sessionStorage === "undefined") {
3864
+ return Date.now() + durationMs;
3865
+ }
3866
+ const stored = window.sessionStorage.getItem(sessionStorageKey);
3867
+ const parsed = stored ? Number.parseInt(stored, 10) : NaN;
3868
+ const now = Date.now();
3869
+ if (!Number.isFinite(parsed) || parsed < now) {
3870
+ const target = now + durationMs;
3871
+ window.sessionStorage.setItem(sessionStorageKey, String(target));
3872
+ return target;
3873
+ }
3874
+ return parsed;
3875
+ }
3876
+ function computeRemaining(deadlineMs) {
3877
+ const diff = Math.max(0, deadlineMs - Date.now());
3878
+ const totalSeconds = Math.floor(diff / 1e3);
3879
+ const h = Math.floor(totalSeconds / 3600);
3880
+ const m = Math.floor(totalSeconds % 3600 / 60);
3881
+ const s = totalSeconds % 60;
3882
+ return { h, m, s, expired: diff === 0 };
3883
+ }
3884
+ function pad(n) {
3885
+ return String(n).padStart(2, "0");
3886
+ }
3887
+ function PaywallCountdown({
3888
+ deadline,
3889
+ format = "h:m:s",
3890
+ onExpire,
3891
+ className,
3892
+ render
3893
+ }) {
3894
+ const deadlineMsRef = (0, import_react30.useRef)(null);
3895
+ if (deadlineMsRef.current === null) {
3896
+ deadlineMsRef.current = resolveDeadlineMs(deadline);
3897
+ }
3898
+ const [state, setState] = (0, import_react30.useState)(() => computeRemaining(deadlineMsRef.current));
3899
+ const expiredCalledRef = (0, import_react30.useRef)(false);
3900
+ (0, import_react30.useEffect)(() => {
3901
+ if (state.expired) {
3902
+ if (!expiredCalledRef.current) {
3903
+ expiredCalledRef.current = true;
3904
+ onExpire?.();
3905
+ }
3906
+ return;
3907
+ }
3908
+ const tick = () => {
3909
+ const next = computeRemaining(deadlineMsRef.current);
3910
+ setState(next);
3911
+ if (next.expired && !expiredCalledRef.current) {
3912
+ expiredCalledRef.current = true;
3913
+ onExpire?.();
3914
+ }
3915
+ };
3916
+ const id = setInterval(tick, 1e3);
3917
+ return () => clearInterval(id);
3918
+ }, [state.expired]);
3919
+ if (render) {
3920
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className, children: render(state) });
3921
+ }
3922
+ const formatted = format === "h:m:s" ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}` : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;
3923
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: [DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(" "), children: formatted });
3924
+ }
3925
+
3926
+ // src/components/paywall/blocks/PaywallFeatures.tsx
3927
+ var import_jsx_runtime42 = require("react/jsx-runtime");
3928
+ function PaywallFeatures({
3929
+ items,
3930
+ IconComponent,
3931
+ className,
3932
+ itemClassName,
3933
+ iconClassName,
3934
+ render,
3935
+ renderItem
3936
+ }) {
3937
+ if (render) {
3938
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, children: render({ items }) });
3939
+ }
3940
+ if (renderItem) {
3941
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("li", { children: renderItem(item, idx) }, idx)) });
3942
+ }
3943
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("li", { className: itemClassName, children: [
3944
+ IconComponent ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(IconComponent, { className: iconClassName }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u2713" }),
3945
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: item })
3946
+ ] }, idx)) });
3947
+ }
3948
+
3949
+ // src/components/paywall/blocks/PaywallFeaturesCard.tsx
3950
+ var import_jsx_runtime43 = require("react/jsx-runtime");
3951
+ var DEFAULT_CARD_CLASSES = "rounded-xl border p-4";
3952
+ function PaywallFeaturesCard({
3953
+ title,
3954
+ items,
3955
+ className,
3956
+ cardClassName,
3957
+ titleClassName,
3958
+ itemClassName,
3959
+ renderItem
3960
+ }) {
3961
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: [DEFAULT_CARD_CLASSES, cardClassName].filter(Boolean).join(" "), children: [
3962
+ title ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: ["font-semibold mb-2", titleClassName].filter(Boolean).join(" "), children: title }) : null,
3963
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { children: items.map(
3964
+ (item, idx) => renderItem ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { children: renderItem(item, idx) }, idx) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("li", { className: itemClassName, children: [
3965
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { "aria-hidden": "true", children: "\u2022" }),
3966
+ " ",
3967
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: item })
3968
+ ] }, idx)
3969
+ ) })
3970
+ ] }) });
3971
+ }
3972
+
3973
+ // src/components/paywall/blocks/PaywallTrophyBadge.tsx
3974
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3975
+ 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";
3976
+ var FLOATING_CLASSES = "absolute top-2 right-2 z-10 shadow-md";
3977
+ function PaywallTrophyBadge({
3978
+ text,
3979
+ className,
3980
+ iconClassName,
3981
+ floating = false,
3982
+ render
3983
+ }) {
3984
+ if (render) {
3985
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className, children: render({ text }) });
3986
+ }
3987
+ const rootClasses = [
3988
+ DEFAULT_CHIP_CLASSES,
3989
+ floating ? FLOATING_CLASSES : "",
3990
+ className
3991
+ ].filter(Boolean).join(" ");
3992
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: rootClasses, children: [
3993
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u{1F3C6}" }),
3994
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: text })
3995
+ ] });
3996
+ }
3997
+
3998
+ // src/components/paywall/blocks/PaywallAnchorPrice.tsx
3999
+ var import_jsx_runtime45 = require("react/jsx-runtime");
4000
+ var DEFAULT_CLASS2 = "text-sm opacity-60 line-through";
4001
+ function PaywallAnchorPrice({
4002
+ className,
4003
+ render
4004
+ }) {
4005
+ const { anchorPriceCents, cycle } = usePaywallContext();
4006
+ if (anchorPriceCents === null || anchorPriceCents === void 0 || anchorPriceCents <= 0) {
4007
+ return null;
4008
+ }
4009
+ void cycle;
4010
+ const formatted = formatBRL(anchorPriceCents);
4011
+ const rootClasses = [DEFAULT_CLASS2, className].filter(Boolean).join(" ");
4012
+ if (render) {
4013
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: className || void 0, children: render({ anchorCents: anchorPriceCents, formatted }) });
4014
+ }
4015
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: rootClasses, children: formatted });
4016
+ }
4017
+
4018
+ // src/components/paywall/blocks/PaywallTestimonials.tsx
4019
+ var import_jsx_runtime46 = require("react/jsx-runtime");
4020
+ var DEFAULT_ROOT = "flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2";
4021
+ var DEFAULT_CARD = "snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2";
4022
+ var DEFAULT_AVATAR = "w-10 h-10 rounded-full object-cover";
4023
+ var DEFAULT_QUOTE = "text-sm leading-snug";
4024
+ var DEFAULT_NAME = "text-xs font-semibold opacity-80";
4025
+ var DEFAULT_STARS = "text-yellow-500 text-sm";
4026
+ function clampStars(n) {
4027
+ return Math.max(0, Math.min(5, Math.round(n)));
4028
+ }
4029
+ function PaywallTestimonials({
4030
+ items,
4031
+ className,
4032
+ cardClassName,
4033
+ avatarClassName,
4034
+ quoteClassName,
4035
+ nameClassName,
4036
+ starsClassName,
4037
+ renderItem
4038
+ }) {
4039
+ const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(" ");
4040
+ const cardClasses = [DEFAULT_CARD, cardClassName].filter(Boolean).join(" ");
4041
+ const avatarClasses = [DEFAULT_AVATAR, avatarClassName].filter(Boolean).join(" ");
4042
+ const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(" ");
4043
+ const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(" ");
4044
+ const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(" ");
4045
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
4046
+ if (renderItem) return renderItem(item, idx);
4047
+ const filled = clampStars(item.stars);
4048
+ const empty = 5 - filled;
4049
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cardClasses, children: [
4050
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
4051
+ item.avatar ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4052
+ "img",
4053
+ {
4054
+ src: item.avatar,
4055
+ alt: "",
4056
+ loading: "lazy",
4057
+ className: avatarClasses,
4058
+ "aria-hidden": "true"
4059
+ }
4060
+ ) : null,
4061
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: nameClasses, children: item.name })
4062
+ ] }),
4063
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: starsClasses, "aria-label": `${filled} de 5 estrelas`, children: [
4064
+ "\u2605".repeat(filled),
4065
+ "\u2606".repeat(empty)
4066
+ ] }),
4067
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: quoteClasses, children: item.quote })
4068
+ ] }, idx);
4069
+ }) });
4070
+ }
4071
+
4072
+ // src/components/paywall/blocks/PaywallStatsRow.tsx
4073
+ var import_jsx_runtime47 = require("react/jsx-runtime");
4074
+ var DEFAULT_ROOT2 = "grid grid-cols-3 gap-4";
4075
+ var DEFAULT_CELL = "flex flex-col items-center text-center";
4076
+ var DEFAULT_VALUE = "text-2xl font-bold";
4077
+ var DEFAULT_LABEL = "text-xs opacity-70";
4078
+ function PaywallStatsRow({
4079
+ stats,
4080
+ className,
4081
+ cellClassName,
4082
+ valueClassName,
4083
+ labelClassName,
4084
+ renderCell
4085
+ }) {
4086
+ const rootClasses = [DEFAULT_ROOT2, className].filter(Boolean).join(" ");
4087
+ const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(" ");
4088
+ const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(" ");
4089
+ const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(" ");
4090
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: rootClasses, children: stats.map((stat, idx) => {
4091
+ if (renderCell) return renderCell(stat, idx);
4092
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cellClasses, children: [
4093
+ stat.icon ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { "aria-hidden": "true", children: stat.icon }) : null,
4094
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: valueClasses, children: stat.value }),
4095
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: labelClasses, children: stat.label })
4096
+ ] }, idx);
4097
+ }) });
4098
+ }
4099
+
4100
+ // src/components/paywall/blocks/PaywallFinePrint.tsx
4101
+ var import_jsx_runtime48 = require("react/jsx-runtime");
4102
+ var DEFAULT_CLASS3 = "text-xs opacity-60 leading-snug";
4103
+ var CYCLE_LABEL2 = {
4104
+ MONTHLY: "mensal",
4105
+ YEARLY: "anual"
4106
+ };
4107
+ function PaywallFinePrint({
4108
+ template,
4109
+ className,
4110
+ render
4111
+ }) {
4112
+ const {
4113
+ currentPriceCents,
4114
+ cycle,
4115
+ trialDaysCard,
4116
+ trialDaysPix,
4117
+ selectedMethod
4118
+ } = usePaywallContext();
4119
+ const trialDays = selectedMethod === "card" ? trialDaysCard : trialDaysPix;
4120
+ const cycleLabel = CYCLE_LABEL2[cycle] ?? cycle.toLowerCase();
4121
+ const priceFormatted = formatBRL(currentPriceCents ?? 0);
4122
+ const rootClasses = [DEFAULT_CLASS3, className].filter(Boolean).join(" ");
4123
+ if (render) {
4124
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: className || void 0, children: render({
4125
+ currentPriceCents: currentPriceCents ?? 0,
4126
+ cycle,
4127
+ trialDays: trialDays ?? 0,
4128
+ selectedMethod
4129
+ }) });
4130
+ }
4131
+ const text = template.replaceAll("{price}", priceFormatted).replaceAll("{trialDays}", String(trialDays ?? 0)).replaceAll("{cycle}", cycleLabel);
4132
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: rootClasses, children: text });
4133
+ }
4134
+
4135
+ // src/components/paywall/blocks/PaywallTrustLine.tsx
4136
+ var import_jsx_runtime49 = require("react/jsx-runtime");
4137
+ var DEFAULT_ROOT3 = "flex items-center gap-3";
4138
+ var DEFAULT_ITEM = "flex items-center gap-1.5 text-xs";
4139
+ function PaywallTrustLine({
4140
+ items,
4141
+ className,
4142
+ itemClassName,
4143
+ renderItem
4144
+ }) {
4145
+ const rootClasses = [DEFAULT_ROOT3, className].filter(Boolean).join(" ");
4146
+ const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(" ");
4147
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
4148
+ if (renderItem) return renderItem(item, idx);
4149
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: itemClasses, children: [
4150
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { "aria-hidden": "true", children: item.icon }),
4151
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { children: item.text })
4152
+ ] }, idx);
4153
+ }) });
4154
+ }
4155
+
4156
+ // src/components/paywall/blocks/PaywallStickyFooter.tsx
4157
+ var import_jsx_runtime50 = require("react/jsx-runtime");
4158
+ var DEFAULT_CLASSES = "sticky bottom-0 left-0 right-0 bg-background";
4159
+ var SAFE_AREA_CLASS = "pb-[env(safe-area-inset-bottom)]";
4160
+ function PaywallStickyFooter({
4161
+ children,
4162
+ className,
4163
+ safeAreaInsets = true
4164
+ }) {
4165
+ const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className].filter(Boolean).join(" ");
4166
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: classes, children });
3669
4167
  }
3670
4168
  // Annotate the CommonJS export names for ESM import in node:
3671
4169
  0 && (module.exports = {
@@ -3684,10 +4182,26 @@ function anchorForCycle(s, c) {
3684
4182
  OnboardingFlow,
3685
4183
  PaymentReturnHandler,
3686
4184
  Paywall,
4185
+ PaywallAnchorPrice,
4186
+ PaywallContext,
4187
+ PaywallCountdown,
3687
4188
  PaywallCta,
3688
4189
  PaywallCyclePicker,
4190
+ PaywallEyebrow,
4191
+ PaywallFeatures,
4192
+ PaywallFeaturesCard,
4193
+ PaywallFinePrint,
4194
+ PaywallHeadline,
4195
+ PaywallHero,
3689
4196
  PaywallMethodContent,
3690
4197
  PaywallMethodTabs,
4198
+ PaywallPriceHeadline,
4199
+ PaywallProvider,
4200
+ PaywallStatsRow,
4201
+ PaywallStickyFooter,
4202
+ PaywallTestimonials,
4203
+ PaywallTrophyBadge,
4204
+ PaywallTrustLine,
3691
4205
  PersistenceRegistry,
3692
4206
  PreAuthShell,
3693
4207
  PushPrompt,
@@ -3716,6 +4230,7 @@ function anchorForCycle(s, c) {
3716
4230
  useInstallPrompt,
3717
4231
  useLoginForm,
3718
4232
  useOnboardingStep,
4233
+ usePaywallContext,
3719
4234
  usePaywallState,
3720
4235
  usePlan,
3721
4236
  usePush,