@hook-sdk/template 0.28.8 → 0.28.10
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 +126 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +126 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/AppRoot.tsx","../src/config/AppConfigContext.tsx","../src/config/schema.ts","../src/PersistenceRegistry.tsx","../src/DeepLinkHandler.tsx","../src/internal/TemplateConfigContext.tsx","../src/internal/ThemeProvider.tsx","../src/hooks/usePaywallState.ts","../src/errors/asaas-pt-br.ts","../src/hooks/usePaywallTracker.ts","../src/internal/SubscriptionGate.tsx","../src/components/InstallGate/InstallGate.tsx","../src/hooks/useInstallPrompt.ts","../src/components/InstallGate/copy.ts","../src/components/InstallGate/InstallSplash.tsx","../src/components/InstallGate/icons.tsx","../src/components/InstallGate/variants/AndroidNativeVariant.tsx","../src/components/InstallGate/variants/AndroidManualVariant.tsx","../src/components/InstallGate/variants/AndroidPendingVariant.tsx","../src/components/InstallGate/Step.tsx","../src/components/InstallGate/variants/IOSafariVariant.tsx","../src/components/InstallGate/variants/IOSOtherVariant.tsx","../src/components/InstallGate/variants/InAppBrowserVariant.tsx","../src/components/InstallGate/variants/DesktopVariant.tsx","../src/internal/PushPrompt.tsx","../src/internal/SessionExpiredBanner.tsx","../src/internal/EmailVerifyBanner.tsx","../src/defaults/ErrorBoundary.tsx","../src/i18n/I18nProvider.tsx","../src/dev/env.ts","../src/dev/DevSkipOnboardingFab.tsx","../src/internal/PaymentReturnHandler.tsx","../src/hooks/usePush.ts","../src/components/PushPrompt.tsx","../src/components/LanguageSwitcher.tsx","../src/defaults/LoadingState.tsx","../src/defaults/EmptyState.tsx","../src/defaults/CheckoutPageDefault.tsx","../src/hooks/useCheckoutForm.ts","../src/errors.ts","../src/hooks/usePlan.ts","../src/components/paywall/Paywall.tsx","../src/utils/price.ts","../src/components/paywall/PaywallProvider.tsx","../src/components/paywall/usePaywallContext.ts","../src/components/paywall/PaywallMethodTabs.tsx","../src/components/paywall/PaywallMethodContent.tsx","../src/components/paywall/PaywallCyclePicker.tsx","../src/components/paywall/PaywallCta.tsx","../src/components/paywall/blocks/PaywallEyebrow.tsx","../src/components/paywall/blocks/PaywallHero.tsx","../src/components/paywall/blocks/PaywallHeadline.tsx","../src/components/paywall/blocks/PaywallPriceHeadline.tsx","../src/components/paywall/blocks/PaywallCountdown.tsx","../src/components/paywall/blocks/PaywallFeatures.tsx","../src/components/paywall/blocks/PaywallFeaturesCard.tsx","../src/components/paywall/blocks/PaywallTrophyBadge.tsx","../src/components/paywall/blocks/PaywallAnchorPrice.tsx","../src/components/paywall/blocks/PaywallTestimonials.tsx","../src/components/paywall/blocks/PaywallStatsRow.tsx","../src/components/paywall/blocks/PaywallFinePrint.tsx","../src/components/paywall/blocks/PaywallTrustLine.tsx","../src/components/paywall/blocks/PaywallStickyFooter.tsx","../src/defaults/PixWaitingPageDefault.tsx","../src/hooks/useLoginForm.ts","../src/hooks/useSignupForm.ts","../src/hooks/useForgotForm.ts","../src/hooks/useResetForm.ts","../src/hooks/useAuthPrimitives.ts","../src/hooks/useAuth.ts","../src/index.ts","../src/hooks/useSubscription.ts","../src/hooks/useReminders.ts","../src/hooks/useToast.ts","../src/RouteBoundary.tsx","../src/PreAuthShell.tsx","../src/OnboardingFlow.tsx","../src/hooks/useOnboardingStep.ts","../src/hooks/useFeature.ts"],"sourcesContent":["/**\n * @golden-path — único componente público do template.\n *\n * v0.10.0 (R2-W3 Task 11): config-driven AppRoot.\n *\n * Apps consume:\n * <AppRoot\n * config={appConfig} // new typed AppConfig (zod-validated)\n * Login={MyLogin} // required slot\n * Signup={MySignup} // required slot\n * Forgot={MyForgot} // required slot\n * Reset={MyReset} // required slot\n * EmailVerify={MyEmailVerify} // required iff config.authFlow.requiresEmailVerify\n * Paywall={MyPaywall} // required iff config.paywall.mode != \"free\"\n * Onboarding={{ welcome: Welcome, ... }} // required iff config.onboarding && trigger != \"pre_signup_custom\"\n * PreAuthFlow={MyPreAuth} // required iff config.onboarding?.trigger === \"pre_signup_custom\"\n * >\n * <RouteBoundary>\n * <Route path=\"/\" element={<Home />} />\n * ...\n * </RouteBoundary>\n * </AppRoot>\n *\n * BREAKING vs v0.9.x:\n * - Default* screens are gone. Apps must provide all auth slot screens.\n * - `config` shape changed (see template/src/types/AppConfig.ts).\n * - AppRoot mounts a BrowserRouter with `basename={`/app/${config.slug}`}`.\n * Apps no longer mount their own Router.\n *\n * IMPORTANT (architectural constraint, see existing comment from v0.9.x):\n * AppRoot does NOT mount <HookProvider>. The shell (frontend/shell/AppLoader.tsx)\n * already wraps the bundle with the runtime config ({ appId, apiHost, assetsHost }).\n * Mounting again would create two HookProvider instances — duplicate auth state +\n * duplicate HTTP clients with mismatched apiHost — and break in staging/prod where\n * shell and API live on different hosts. Tests must wrap explicitly.\n *\n * Note: a TemplateConfigProvider compat shim is mounted internally so existing\n * gates (InstallGate, ThemeProvider, SubscriptionGate) keep working with the\n * derived old-shape config. They will migrate to AppConfig in template 0.11.\n */\nimport { useMemo, type ComponentType, type ReactNode } from 'react';\nimport { BrowserRouter, MemoryRouter, Navigate, Route, Routes } from 'react-router-dom';\nimport { useHook } from '@hook-sdk/sdk';\nimport { AppConfigProvider } from './config/AppConfigContext';\nimport { parseAppConfig } from './config/schema';\nimport { PersistenceRegistry } from './PersistenceRegistry';\nimport { DeepLinkHandler } from './DeepLinkHandler';\nimport { TemplateConfigProvider } from './internal/TemplateConfigContext';\nimport { ThemeProvider } from './internal/ThemeProvider';\nimport { SubscriptionGate } from './internal/SubscriptionGate';\nimport { InstallGate } from './components/InstallGate';\nimport { PushPrompt } from './internal/PushPrompt';\nimport { SessionExpiredBanner } from './internal/SessionExpiredBanner';\nimport { EmailVerifyBanner } from './internal/EmailVerifyBanner';\nimport { ErrorBoundary } from './defaults/ErrorBoundary';\nimport { I18nProvider } from './i18n/I18nProvider';\nimport type { AppConfig } from './types/AppConfig';\nimport type { AppConfig as OldAppConfig } from '../../scripts/schemas/app-config';\nimport type { AuthScreenProps } from './types/AppRootSlots';\nimport { isDevToolsEnabled } from './dev/env';\nimport { DevSkipOnboardingFab, type SkipDefaults } from './dev/DevSkipOnboardingFab';\n\nexport type { AuthScreenProps };\nexport type { SkipDefaults };\n\nexport type AppRootSlots = {\n Login: ComponentType<AuthScreenProps>;\n Signup: ComponentType<AuthScreenProps>;\n Forgot: ComponentType<AuthScreenProps>;\n Reset: ComponentType<AuthScreenProps>;\n /** Required when config.authFlow.requiresEmailVerify === true. */\n EmailVerify?: ComponentType<AuthScreenProps>;\n /** Required when config.paywall.mode !== \"free\". */\n Paywall?: ComponentType;\n /** Map of step id → component. Used when config.onboarding && trigger !== \"pre_signup_custom\". */\n Onboarding?: Record<string, ComponentType>;\n /** Required when config.onboarding?.trigger === \"pre_signup_custom\". */\n PreAuthFlow?: ComponentType;\n};\n\nexport type AppRootProps = AppRootSlots & {\n config: AppConfig;\n children?: ReactNode;\n /** Test-only: skip BrowserRouter (which fights jsdom's document.location). */\n testRouter?: 'memory';\n /** Test-only: initial entries for MemoryRouter. */\n testInitialEntries?: string[];\n /**\n * Staging-only dev tools. When this prop is set AND\n * `VITE_HOOK_DEV_TOOLS=1` AND the hostname is staging/localhost, AppRoot\n * mounts a floating \"skip onboarding\" button that pre-fills\n * `appData.onboarding_data` with the supplied defaults and lands the user\n * on `/app/<slug>/`. Tree-shaken from prod builds via the build-time env\n * replacement (see `dev/env.ts`).\n */\n devSkipOnboarding?: { defaults: SkipDefaults };\n};\n\nexport { PaymentReturnHandler } from './internal/PaymentReturnHandler';\n\n/**\n * Build a v0.9-shaped TemplateConfig from the new AppConfig so existing internal\n * gates (InstallGate / ThemeProvider / SubscriptionGate / InstallSplash /\n * DesktopVariant) keep functioning unchanged. Removed in template 0.11 once\n * those gates migrate to consume AppConfig directly.\n */\nfunction buildLegacyConfigShim(config: AppConfig): OldAppConfig {\n const paywall = config.paywall;\n const isFree = paywall.mode === 'free';\n const monthlyCents = isFree ? 0 : paywall.prices.monthlyCents;\n const trialDays = isFree ? 0 : (paywall.trialDays ?? 0);\n return {\n slug: config.slug,\n name: config.name,\n email_alias: config.slug,\n // Map branding into the legacy theme shape so InstallSplash (and\n // anything else reading theme.icon_url / theme.logo_url) can surface\n // the app icon instead of the generic \"first letter of name\" fallback.\n // Falls back to logoUrl when iconUrl is unset — apps that haven't\n // adopted iconUrl keep their previous behavior unchanged.\n theme: {\n primary_color: config.branding.primaryColor,\n icon_url: config.branding.iconUrl ?? config.branding.logoUrl,\n logo_url: config.branding.logoUrl,\n },\n features_enabled: ((config.features_enabled ?? []) as OldAppConfig['features_enabled']),\n dependencies_allowlist: ['react', 'react-dom'],\n subscription: {\n mode: paywall.mode,\n price_cents: monthlyCents,\n currency: 'brl',\n trial_days: trialDays,\n paywall_config: {\n title: config.name,\n benefits: ['Acesso completo'],\n cta: 'Assinar',\n },\n },\n sdk_version_required: '>=0.16.0',\n max_bundle_size_kb: 500,\n } as OldAppConfig;\n}\n\nexport function AppRoot(props: AppRootProps) {\n const {\n config: rawConfig,\n children,\n testRouter,\n testInitialEntries,\n Login,\n Signup,\n Forgot,\n Reset,\n EmailVerify,\n Paywall,\n Onboarding,\n PreAuthFlow,\n devSkipOnboarding,\n } = props;\n\n if (!Login || !Signup || !Forgot || !Reset) {\n throw new Error(\n '[hook-template] <AppRoot>: Login, Signup, Forgot, Reset slot props are required.',\n );\n }\n\n const config = parseAppConfig(rawConfig);\n\n if (config.paywall.mode !== 'free' && !Paywall) {\n throw new Error(\n \"[hook-template] <AppRoot>: Paywall slot prop is required when config.paywall.mode != 'free'.\",\n );\n }\n if (config.authFlow.requiresEmailVerify && !EmailVerify) {\n throw new Error(\n '[hook-template] <AppRoot>: EmailVerify slot prop is required when config.authFlow.requiresEmailVerify === true.',\n );\n }\n if (config.onboarding?.trigger === 'pre_signup_custom' && !PreAuthFlow) {\n throw new Error(\n \"[hook-template] <AppRoot>: PreAuthFlow slot prop is required when config.onboarding.trigger === 'pre_signup_custom'.\",\n );\n }\n\n const legacyShim = useMemo(() => buildLegacyConfigShim(config), [config]);\n const Router = testRouter === 'memory' ? MemoryRouter : BrowserRouter;\n const basename = `/app/${config.slug}`;\n\n const routerProps = testRouter === 'memory'\n ? { basename, initialEntries: testInitialEntries }\n : { basename };\n\n const position = config.install_prompt?.position ?? 'post-paywall';\n\n const subscriptionGated = (\n <SubscriptionGate Paywall={Paywall ?? FallbackPaywall}>\n <EmailVerifyBanner />\n {position === 'post-paywall' ? (\n <InstallGate position=\"post-paywall\">\n {children}\n <PushPrompt />\n </InstallGate>\n ) : (\n <>\n {children}\n <PushPrompt />\n </>\n )}\n </SubscriptionGate>\n );\n\n const authGated = (\n <AuthGated\n config={config}\n Login={Login}\n Signup={Signup}\n Forgot={Forgot}\n Reset={Reset}\n EmailVerify={EmailVerify}\n Paywall={Paywall}\n Onboarding={Onboarding}\n PreAuthFlow={PreAuthFlow}\n >\n {subscriptionGated}\n </AuthGated>\n );\n\n const routedTree = (\n <Router {...routerProps}>\n <DeepLinkHandler deepLinks={config.deepLinks} />\n {/* Outside AuthGated so banner can observe authenticated→anonymous transitions; AuthGated unmounts children on anon. */}\n <SessionExpiredBanner />\n {position === 'pre-auth' ? (\n <InstallGate position=\"pre-auth\">{authGated}</InstallGate>\n ) : (\n authGated\n )}\n {isDevToolsEnabled() && devSkipOnboarding ? (\n <DevSkipOnboardingFab defaults={devSkipOnboarding.defaults} />\n ) : null}\n </Router>\n );\n\n return (\n <ErrorBoundary>\n <AppConfigProvider config={config}>\n <TemplateConfigProvider config={legacyShim}>\n <ThemeProvider>\n <PersistenceRegistry config={config.persistedKeys}>\n {config.i18n ? (\n <I18nProvider\n defaultLocale={config.i18n.defaultLocale}\n supportedLocales={config.i18n.supportedLocales}\n resources={config.i18n.resources}\n >\n {routedTree}\n </I18nProvider>\n ) : (\n routedTree\n )}\n </PersistenceRegistry>\n </ThemeProvider>\n </TemplateConfigProvider>\n </AppConfigProvider>\n </ErrorBoundary>\n );\n}\n\n/**\n * Renders the auth-flow Routes when unauthenticated; renders children when\n * authenticated. Supports two anonymous flows:\n *\n * - Default: linear `/`, `/signup`, `/forgot`, `/reset`, optional `/verify`.\n * - `pre_signup_custom`: app provides its own Routes via <PreAuthFlow>; we\n * only mount the auth screens at fixed paths and delegate everything else\n * to PreAuthFlow.\n */\nfunction AuthGated({\n children,\n config,\n Login,\n Signup,\n Forgot,\n Reset,\n EmailVerify,\n PreAuthFlow,\n}: AppRootProps & { children?: ReactNode }) {\n const { authStatus } = useHook();\n if (authStatus === 'loading') return null;\n if (authStatus !== 'authenticated') {\n // Plan-V — pay-first signup mode: no /signup route mounted in the\n // pre-auth funnel. New users sign up via the checkout form inside\n // PreAuthFlow (/paywall/checkout). Existing users land on /signin (or\n // any /signin link); legacy /signup still exists on the backend so\n // direct hits won't 404, but the bundle never exposes the path.\n if (config.authFlow.signupMode === 'pay_first' && PreAuthFlow) {\n return (\n <Routes>\n <Route path=\"/signin\" element={<Login />} />\n <Route path=\"/forgot\" element={<Forgot />} />\n <Route path=\"/reset\" element={<Reset />} />\n {EmailVerify ? <Route path=\"/verify\" element={<EmailVerify />} /> : null}\n <Route path=\"/*\" element={<PreAuthFlow />} />\n </Routes>\n );\n }\n if (config.onboarding?.trigger === 'pre_signup_custom' && PreAuthFlow) {\n return (\n <Routes>\n <Route path=\"/signin\" element={<Login />} />\n <Route path=\"/signup\" element={<Signup />} />\n <Route path=\"/forgot\" element={<Forgot />} />\n <Route path=\"/reset\" element={<Reset />} />\n {EmailVerify ? <Route path=\"/verify\" element={<EmailVerify />} /> : null}\n <Route path=\"/*\" element={<PreAuthFlow />} />\n </Routes>\n );\n }\n return (\n <Routes>\n <Route path=\"/\" element={<Login />} />\n <Route path=\"/signup\" element={<Signup />} />\n <Route path=\"/forgot\" element={<Forgot />} />\n <Route path=\"/reset\" element={<Reset />} />\n {EmailVerify ? <Route path=\"/verify\" element={<EmailVerify />} /> : null}\n <Route path=\"*\" element={<Navigate to=\"/\" replace />} />\n </Routes>\n );\n }\n return <>{children}</>;\n}\n\n// Internal fallback Paywall, only ever reached via the SubscriptionGate when\n// config.paywall.mode === 'free' (in which case SubscriptionGate short-circuits\n// and never renders Paywall). Here purely to satisfy the SubscriptionGate prop\n// type without making Paywall a forced required slot in 'free' mode.\nfunction FallbackPaywall() {\n return null;\n}\n","import { createContext, useContext, type ReactNode } from 'react';\nimport type { AppConfig } from '../types/AppConfig';\n\nexport const AppConfigContext = createContext<AppConfig | null>(null);\n\nexport function AppConfigProvider({\n config,\n children,\n}: {\n config: AppConfig;\n children: ReactNode;\n}) {\n return <AppConfigContext.Provider value={config}>{children}</AppConfigContext.Provider>;\n}\n\nexport function useAppConfig(): AppConfig {\n const v = useContext(AppConfigContext);\n if (!v) {\n throw new Error(\n '[hook-template] useAppConfig: AppConfigProvider missing — wrap your app in <AppRoot>',\n );\n }\n return v;\n}\n","import { z } from 'zod';\nimport type { AppConfig } from '../types/AppConfig';\n\nconst SnakeKeyRE = /^[a-z0-9][a-z0-9_.-]{0,127}$/;\n\nconst AuthFlowSchema = z.object({\n minPassword: z.number().int().min(6).max(64),\n requiresEmailVerify: z.boolean(),\n googleOAuth: z.boolean(),\n postAuthLanding: z.string().startsWith('/'),\n preAuthRoutes: z.array(z.string().startsWith('/')),\n // Plan-V — pay-first signup mode. See types/AppConfig.ts AuthFlowConfig.\n signupMode: z.enum(['pre_signup', 'pay_first']).optional(),\n});\n\nconst PaywallNonFreeSchema = z.object({\n mode: z.enum(['trial', 'pay_first']),\n // Legacy flat trial — fallback when per-method fields aren't set.\n trialDays: z.number().int().nonnegative().optional(),\n // Per-method trial (ADR-022 Amendment 2026-05-12 + G154). PIX Auto can't\n // offer trial on Asaas today (Jornada 2 unavailable), so apps that mix\n // methods must split the value to avoid bait-and-switch on PIX shoppers.\n trialDaysCard: z.number().int().nonnegative().optional(),\n trialDaysPix: z.number().int().nonnegative().optional(),\n // Which method the paywall preselects. null/undefined = no preselection\n // (user picks). Per-app override reflects audience, not Hook bias.\n defaultMethod: z.enum(['card', 'pix-auto', 'pix-once']).nullable().optional(),\n cycles: z.array(z.enum(['MONTHLY', 'YEARLY'])).min(1),\n prices: z.object({\n monthlyCents: z.number().int().nonnegative(),\n yearlyCents: z.number().int().nonnegative(),\n }),\n anchorPrices: z\n .object({\n monthlyCents: z.number().int().nonnegative(),\n yearlyCents: z.number().int().nonnegative(),\n })\n .optional(),\n checkoutMethods: z.array(z.enum(['card', 'pix-auto', 'pix-once'])).min(1),\n requiresCpf: z.boolean(),\n cancelWindowDays: z.number().int().nonnegative().optional(),\n errorMessages: z.enum(['default', 'custom']),\n});\n\nconst PaywallFreeSchema = z.object({ mode: z.literal('free') });\nconst PaywallSchema = z.discriminatedUnion('mode', [PaywallNonFreeSchema, PaywallFreeSchema]);\n\nconst PersistedKeySchema = z.object({\n key: z\n .string()\n .regex(SnakeKeyRE, 'key must be snake_case (matches /^[a-z0-9][a-z0-9_.-]{0,127}$/)'),\n default: z.unknown(),\n guardRegen: z.boolean().optional(),\n debounceMs: z.number().int().positive().optional(),\n});\n\nconst OnboardingSchema = z.object({\n trigger: z.enum(['pre_signup', 'post_signup', 'pre_signup_custom', 'optional']),\n steps: z\n .array(\n z.object({\n id: z.string().regex(SnakeKeyRE),\n screen: z.string(),\n validates: z.array(z.string()).optional(),\n }),\n )\n .min(1),\n persistTo: z.literal('appData'),\n persistKey: z.string().regex(SnakeKeyRE),\n});\n\nconst DeepLinksSchema = z\n .object({\n passwordReset: z.string().startsWith('/').optional(),\n emailVerify: z.string().startsWith('/').optional(),\n })\n .strict();\n\nconst I18nConfigSchema = z\n .object({\n defaultLocale: z.string().min(2),\n supportedLocales: z.array(z.string().min(2)).min(1),\n resources: z.record(z.string(), z.record(z.string(), z.string())),\n })\n .strict()\n .refine((v) => v.supportedLocales.includes(v.defaultLocale), {\n message: 'i18n.defaultLocale must be a member of i18n.supportedLocales',\n path: ['defaultLocale'],\n });\n\nconst InstallPromptSchema = z\n .object({\n position: z.enum(['pre-auth', 'post-paywall']).optional(),\n })\n .strict();\n\nexport const AppConfigSchema = z\n .object({\n slug: z.string().regex(/^[a-z0-9-]+$/),\n name: z.string().min(1),\n branding: z.object({\n primaryColor: z.string(),\n logoUrl: z.string().url(),\n iconUrl: z.string().url().optional(),\n }),\n authFlow: AuthFlowSchema,\n paywall: PaywallSchema,\n persistedKeys: z.array(PersistedKeySchema),\n onboarding: OnboardingSchema.optional(),\n deepLinks: DeepLinksSchema.optional(),\n i18n: I18nConfigSchema.optional(),\n features_enabled: z.array(z.string()).optional(),\n install_prompt: InstallPromptSchema.optional(),\n // Build-time injected theme metadata (e.g. icon_url for InstallSplash).\n // Apps don't author this directly; deploy workflows fill it from\n // env-resolved bundle host. Permissive shape so apps/workflows can\n // extend without re-bumping the template schema.\n theme: z.object({}).passthrough().optional(),\n // G133 — per-tenant public app-data keys allowlist. Optional; default\n // backfill em migration 0044 = canonical 6. Apps com keys próprias\n // declaram aqui pra evitar 402 spam pós-signup no SubscriptionGate.\n publicKeys: z.array(z.string().regex(SnakeKeyRE)).optional(),\n })\n .strict();\n\nexport function parseAppConfig(input: unknown): AppConfig {\n const r = AppConfigSchema.safeParse(input);\n if (!r.success) {\n const messages = r.error.issues\n .map((i) => `[${i.path.join('.')}] ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid app.config.json:\\n${messages}`);\n }\n return r.data as AppConfig;\n}\n","import { useEffect, type ReactNode } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type { PersistedKey } from './types/AppConfig';\n\nexport type PersistenceRegistryProps = {\n config: PersistedKey[];\n children: ReactNode;\n};\n\n/**\n * Fire-and-forget prefetch of every key declared in `app.config.json.persistedKeys`\n * via `appData.bulkRead`. Does NOT gate render — children mount immediately;\n * `usePersistedState` consumers hit cache as soon as the prefetch resolves.\n *\n * Use when the consuming app tolerates a brief flash of `defaultValue` before\n * hydrated state lands. For strict \"no flash\" semantics use `<PersistedKeysPrefetch>`\n * (gating variant in `internal/`).\n */\nexport function PersistenceRegistry({ config, children }: PersistenceRegistryProps) {\n const { appData } = useHook();\n useEffect(() => {\n if (config.length === 0) return;\n const keys = config.map((c) => c.key);\n const bulk = (appData as unknown as { bulkRead?: (k: string[]) => Promise<unknown> })\n .bulkRead;\n bulk?.(keys).catch(() => {\n // best-effort; usePersistedState hits the network on miss\n });\n }, [config, appData]);\n return <>{children}</>;\n}\n","import { useEffect } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport type { DeepLinks } from './types/AppConfig';\n\n/**\n * Reads `?token=` from the URL on mount + on location change. When present and\n * the current pathname is `/`, redirects to the configured deep-link path\n * (passwordReset or emailVerify) substituting `:token` for the actual value.\n *\n * Mounts once inside `<AppRoot>` (post-Router); a no-op when `deepLinks` is\n * undefined or no `token` is in the URL.\n */\nexport function DeepLinkHandler({ deepLinks }: { deepLinks?: DeepLinks }) {\n const nav = useNavigate();\n const loc = useLocation();\n useEffect(() => {\n if (!deepLinks) return;\n const params = new URLSearchParams(loc.search);\n const token = params.get('token');\n if (!token) return;\n if (\n deepLinks.passwordReset &&\n deepLinks.passwordReset.includes(':token') &&\n loc.pathname === '/'\n ) {\n nav(deepLinks.passwordReset.replace(':token', token));\n return;\n }\n if (\n deepLinks.emailVerify &&\n deepLinks.emailVerify.includes(':token') &&\n loc.pathname === '/'\n ) {\n nav(deepLinks.emailVerify.replace(':token', token));\n }\n }, [deepLinks, loc, nav]);\n return null;\n}\n","import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport type { AppConfig } from '../../../scripts/schemas/app-config';\n\nexport type SubscriptionMode = 'trial' | 'pay_first' | 'free';\n\nexport interface TemplateConfig extends AppConfig {\n /** Resolved subscription mode. Defaults to 'trial' when absent in app.config.json. */\n mode: SubscriptionMode;\n}\n\nconst TemplateConfigContext = createContext<TemplateConfig | null>(null);\n\nexport function TemplateConfigProvider({\n config,\n children,\n}: {\n config: AppConfig;\n children: ReactNode;\n}) {\n const value = useMemo<TemplateConfig>(() => ({\n ...config,\n mode: (config.subscription?.mode as SubscriptionMode | undefined) ?? 'trial',\n }), [config]);\n\n return (\n <TemplateConfigContext.Provider value={value}>\n {children}\n </TemplateConfigContext.Provider>\n );\n}\n\nexport function useTemplateConfig(): TemplateConfig {\n const ctx = useContext(TemplateConfigContext);\n if (ctx === null) {\n throw new Error('useTemplateConfig must be used inside <TemplateConfigProvider>');\n }\n return ctx;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from './TemplateConfigContext';\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n const config = useTemplateConfig();\n const style = {\n '--hook-color-primary': config.theme.primary_color,\n ...(config.theme.background_color && {\n '--hook-color-background': config.theme.background_color,\n }),\n } as CSSProperties;\n\n return <div style={style}>{children}</div>;\n}\n","import { useCallback, useContext, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type {\n CheckoutArgs,\n CheckoutCardData,\n CheckoutCycle,\n CheckoutHolderInfo,\n CheckoutMethod,\n CheckoutResult,\n PixPending as SdkPixPending,\n} from '@hook-sdk/sdk';\n\n// SDK 0.16's MethodUnavailableResult discriminator. Re-declared here to keep\n// the narrowing type-guard local; the SDK exports this as part of CheckoutResult.\ninterface CheckoutFailureShape {\n ok: false;\n code: 'method_unavailable';\n method: CheckoutMethod;\n reason: string;\n}\n\nfunction isCheckoutFailure(r: CheckoutResult): r is CheckoutFailureShape {\n return 'ok' in r && (r as { ok?: unknown }).ok === false;\n}\nimport { AppConfigContext } from '../config/AppConfigContext';\nimport type { AppConfig, PaywallConfig } from '../types/AppConfig';\nimport { asaasErrorMessage } from '../errors/asaas-pt-br';\nimport { usePaywallTracker } from './usePaywallTracker';\n\n// Permissive fallback used when usePaywallState is rendered outside an\n// <AppConfigProvider> (legacy callers + standalone unit tests). Mirrors the\n// pre-config-driven default behavior: card + pix-auto are available, CPF is\n// required, errorMessages map to PT-BR via asaasErrorMessage.\nconst FALLBACK_PAYWALL: PaywallConfig = {\n mode: 'pay_first',\n cycles: ['MONTHLY'],\n prices: { monthlyCents: 0, yearlyCents: 0 },\n checkoutMethods: ['card', 'pix-auto'],\n requiresCpf: true,\n errorMessages: 'default',\n};\n\nexport type SubscriptionStatus =\n | 'active'\n | 'trialing'\n | 'expired'\n | 'canceled'\n | 'past_due'\n | 'pending'\n | 'none';\n\nexport type PaymentMethod = CheckoutMethod;\n\nexport interface PaywallError {\n code: string;\n message: string;\n userMessage: string;\n}\n\n/**\n * Local pixPending shape — re-exposes SDK's reactive `subscription.pixPending`\n * with two extra UI-facing fields:\n * - `expiresAt`: null (kept for compat; SDK does not surface expiry on auto/once)\n * - `paid`: derived from `subscription.current.status` — flips true when the\n * underlying subscription transitions to ACTIVE/TRIAL after the user pays\n * the QR code. SDK clears the underlying pixPending shortly after; this\n * wrapper preserves the \"paid\" frame for ~1 render so the paywall can show\n * confirmation copy before unmounting the modal.\n */\nexport interface PixPending {\n method: 'pix-auto' | 'pix-once';\n qrCodePayload: string | null;\n qrCodeBase64: string | null;\n expiresAt: string | null;\n paid: boolean;\n}\n\nexport interface CardFormState {\n number: string;\n cvv: string;\n expiry: string;\n holder: string;\n}\n\nexport interface CardFormStateWithSetter extends CardFormState {\n set: (patch: Partial<CardFormState>) => void;\n}\n\nexport interface CpfState {\n required: boolean;\n value: string;\n set: (v: string) => void;\n valid: boolean;\n}\n\nexport interface PaywallCheckoutArgs {\n cpf: string;\n cycle: CheckoutCycle;\n method: 'card' | 'pix-auto' | 'pix-once';\n card?: CheckoutCardData;\n holderInfo?: CheckoutHolderInfo;\n remoteIp?: string;\n}\n\nexport interface PaywallPlanDerived {\n monthlyCents: number;\n yearlyCents: number | null;\n anchorMonthlyCents?: number;\n anchorYearlyCents?: number;\n monthlyEquivalent: number;\n discountPercent: number;\n}\n\nconst isMethodAvailable = (\n availability: { card: boolean | null; 'pix-auto': boolean | null; 'pix-once': boolean | null },\n method: CheckoutMethod,\n): boolean => availability[method] !== false;\n\n/**\n * Headless paywall state — owns:\n * - reactive subscription status (proxied from SDK)\n * - cycle / selectedMethod / cpf / card form state\n * - methods list (config.paywall.checkoutMethods filtered by SDK methodAvailability)\n * - submit() — high-level no-args entrypoint that uses internal state\n * - error mapping via asaasErrorMessage when paywall.errorMessages === 'default'\n *\n * Backward-compat aliases preserved for SDK 0.13/template 0.9 consumers:\n * - `availableMethods` mirrors `methods`\n * - `opening` mirrors `submitting`\n * - `checkout(args)` takes legacy args + validates card/holderInfo presence\n * - `dismissPix` clears SDK `pixPending` (template 0.24.0 + SDK 0.26.0 wire,\n * resolves G154; was no-op pre-0.24 and apps had to maintain a local\n * `pixActive` flag to bridge the gap).\n * - `monthlyEquivalent(cycle)` helper\n */\nexport function usePaywallState() {\n const { subscription, plan, authStatus, track } = useHook();\n // Null-tolerant: tests + legacy callers may render without AppConfigProvider.\n // Real apps always wrap via <AppRoot>, so the null path only fires in unit\n // tests for hooks that pre-date the config-driven runtime.\n const configFromCtx = useContext(AppConfigContext) as AppConfig | null;\n const paywall: PaywallConfig = configFromCtx?.paywall ?? FALLBACK_PAYWALL;\n const isFree = paywall.mode === 'free';\n\n const declaredMethods = useMemo<readonly CheckoutMethod[]>(\n () => (isFree ? [] : paywall.checkoutMethods),\n [isFree, paywall],\n );\n\n // Fallback when SDK predates methodAvailability (legacy test mocks).\n const availability = subscription.methodAvailability ?? {\n card: null,\n 'pix-auto': null,\n 'pix-once': null,\n };\n\n const methods = useMemo<readonly CheckoutMethod[]>(\n () => declaredMethods.filter((m) => isMethodAvailable(availability, m)),\n [declaredMethods, availability],\n );\n\n // ADR-022 Amendment 2026-05-12: paywall preselection follows the app's\n // declared `defaultMethod` when available + available + present. Falls back\n // to the first available method in the configured order. Apps with a\n // PIX-first audience (papomaterno, personalburn) set `defaultMethod=pix-auto`;\n // apps that lead with trial (beluzi card-only) set `defaultMethod=card`.\n const configDefault =\n !isFree && 'defaultMethod' in paywall ? paywall.defaultMethod ?? null : null;\n const defaultMethod: CheckoutMethod =\n (configDefault && methods.includes(configDefault) ? configDefault : null) ??\n methods[0] ??\n declaredMethods[0] ??\n 'card';\n const [selectedMethodRaw, setSelectedMethod] = useState<CheckoutMethod>(defaultMethod);\n\n // If the currently selected method has been flagged unavailable, fall back\n // to the first available one. Caller still sees a valid value.\n const selectedMethod: CheckoutMethod = methods.includes(selectedMethodRaw)\n ? selectedMethodRaw\n : (methods[0] ?? selectedMethodRaw);\n\n // Default cycle: YEARLY when offered (higher AOV per spec); else fall back to\n // first declared cycle, else MONTHLY. Apps that want MONTHLY-default can\n // declare `cycles: [\"MONTHLY\"]` only or override post-mount via setCycle.\n const initialCycle: CheckoutCycle = isFree\n ? 'MONTHLY'\n : paywall.cycles.includes('YEARLY')\n ? 'YEARLY'\n : (paywall.cycles[0] ?? 'MONTHLY');\n const [cycle, setCycle] = useState<CheckoutCycle>(initialCycle);\n\n const cpfRequired = !isFree && paywall.requiresCpf;\n const [cpf, setCpf] = useState('');\n const cpfValid = useMemo(() => /^[0-9]{11}$/.test(cpf), [cpf]);\n\n const [card, setCardState] = useState<CardFormState>({\n number: '',\n cvv: '',\n expiry: '',\n holder: '',\n });\n const setCard = useCallback((patch: Partial<CardFormState>) => {\n setCardState((prev) => ({ ...prev, ...patch }));\n }, []);\n\n const [error, setError] = useState<PaywallError | null>(null);\n const [submitting, setSubmitting] = useState(false);\n\n const status = subscription.status() as SubscriptionStatus;\n const daysLeftInTrial = subscription.daysLeftInTrial();\n\n /**\n * Per-method trial accessor (ADR-022 Amendment 2026-05-12 + G154).\n *\n * Resolution order:\n * 1. method-specific override (`paywall.trialDaysCard` / `trialDaysPix`)\n * 2. legacy flat `paywall.trialDays`\n * 3. method-aware default: 7 for card, 0 for pix-auto/pix-once (Asaas\n * cannot offer trial on PIX — BCB Jornada 2 unavailable).\n *\n * Consumers render asymmetric paywall copy:\n * - method-card: \"Grátis por N dias, depois R$ X/mês\" (only when N > 0)\n * - method-pix: \"Pague R$ X agora · acesso liberado em segundos\"\n *\n * Never reuse a global \"free trial!\" headline when both methods are\n * visible — that bait-and-switches PIX-first shoppers (insight doc\n * 2026-05-12-asaas-jornada-2-research.md §\"shopper C\").\n */\n const trialDaysForMethod = useCallback(\n (method: CheckoutMethod): number => {\n if (isFree) return 0;\n if (method === 'card') {\n if (typeof paywall.trialDaysCard === 'number') return paywall.trialDaysCard;\n if (typeof paywall.trialDays === 'number') return paywall.trialDays;\n return 7;\n }\n // pix-auto + pix-once: Asaas can't authorize without an immediate\n // charge today (G154). Default 0 unless an app explicitly opts in\n // (legacy apps that haven't migrated off the R$ 0,01 capture trick).\n if (typeof paywall.trialDaysPix === 'number') return paywall.trialDaysPix;\n if (typeof paywall.trialDays === 'number') return paywall.trialDays;\n return 0;\n },\n [isFree, paywall],\n );\n\n const trialDaysCard = trialDaysForMethod('card');\n const trialDaysPix = trialDaysForMethod('pix-auto');\n const initialLoadComplete = subscription.initialLoadComplete;\n // Backend-authoritative access flag. Distingue CANCELLED-com-trial-vivo\n // (hasAccess=true) de CANCELLED-expirado (hasAccess=false). SubscriptionGate\n // usa isso pra liberar app durante o restante do período pago/trial após\n // cancel — comportamento alinhado com App Store/Play Store.\n const hasAccess = subscription.hasAccess;\n\n // Re-expose SDK pixPending with legacy enrichment (expiresAt, paid).\n const pixPending = useMemo<PixPending | null>(() => {\n const sdkPix: SdkPixPending | null = subscription.pixPending;\n if (!sdkPix) return null;\n const liveStatus = subscription.current?.status;\n const paid = liveStatus === 'ACTIVE' || liveStatus === 'TRIAL';\n return {\n method: sdkPix.method,\n qrCodePayload: sdkPix.qrCodePayload,\n qrCodeBase64: sdkPix.qrCodeBase64,\n expiresAt: null,\n paid,\n };\n }, [subscription.pixPending, subscription.current]);\n\n const monthlyEquivalent = useCallback(\n (c: CheckoutCycle): number => {\n const monthlyCents = plan.data?.priceCents ?? (isFree ? 0 : paywall.prices.monthlyCents);\n const yearlyCents = plan.data?.yearlyPriceCents ?? (isFree ? null : paywall.prices.yearlyCents);\n if (c === 'YEARLY' && yearlyCents) return Math.round(yearlyCents / 12);\n return monthlyCents;\n },\n [plan, paywall, isFree],\n );\n\n const planDerived = useMemo<PaywallPlanDerived | null>(() => {\n if (isFree) return null;\n const monthlyCents = paywall.prices.monthlyCents;\n const yearlyCents = paywall.prices.yearlyCents;\n const anchor = paywall.anchorPrices;\n const discount = anchor && anchor.yearlyCents > 0\n ? Math.round((1 - paywall.prices.yearlyCents / anchor.yearlyCents) * 100)\n : 0;\n return {\n monthlyCents,\n yearlyCents,\n anchorMonthlyCents: anchor?.monthlyCents,\n anchorYearlyCents: anchor?.yearlyCents,\n monthlyEquivalent: cycle === 'YEARLY' ? Math.round(yearlyCents / 12) : monthlyCents,\n discountPercent: discount,\n };\n }, [paywall, cycle, isFree]);\n\n // ===== Conversion-max derivations (template 0.21) =====\n\n /**\n * Inferred from SDK subscription status. The user has consumed their trial\n * once the backend has ever transitioned them past 'none'. Card tab copy\n * shifts to no-trial framing when true (see PaywallMethodContent).\n */\n const hasConsumedTrial = useMemo<boolean>(() => {\n return ['active', 'trialing', 'past_due', 'canceled', 'expired'].includes(status);\n }, [status]);\n\n /** Price for the currently selected cycle (used by CTA + cycle card). */\n const currentPriceCents = useMemo<number>(() => {\n if (isFree) return 0;\n return cycle === 'YEARLY' ? paywall.prices.yearlyCents : paywall.prices.monthlyCents;\n }, [paywall, cycle, isFree]);\n\n /** Monthly-equivalent. For YEARLY cycle, divides by 12. */\n const currentMonthlyEquivCents = useMemo<number>(() => {\n if (isFree) return 0;\n if (cycle === 'YEARLY') return Math.round(paywall.prices.yearlyCents / 12);\n return paywall.prices.monthlyCents;\n }, [paywall, cycle, isFree]);\n\n /** Anchor (strikethrough) price for the current cycle. null when not set. */\n const anchorPriceCents = useMemo<number | null>(() => {\n if (isFree) return null;\n const a = paywall.anchorPrices;\n if (!a) return null;\n return cycle === 'YEARLY' ? a.yearlyCents : a.monthlyCents;\n }, [paywall, cycle, isFree]);\n\n /** Telemetry-wrapped setters. */\n const selectMethod = useCallback(\n (next: CheckoutMethod) => {\n if (next === selectedMethod) return;\n track('paywall_method_tab_clicked', { method: next, from_method: selectedMethod });\n setSelectedMethod(next);\n },\n [selectedMethod, track],\n );\n\n const selectCycle = useCallback(\n (next: CheckoutCycle) => {\n if (next === cycle) return;\n track('paywall_cycle_clicked', { cycle: next, from_cycle: cycle });\n setCycle(next);\n },\n [cycle, track],\n );\n\n const useDefaultMessages = paywall.mode !== 'free' && paywall.errorMessages === 'default';\n\n const buildError = useCallback(\n (code: string, fallbackMessage: string): PaywallError => ({\n code,\n message: fallbackMessage,\n // fallbackMessage carries Asaas's PT-BR description (\"O CEP informado é inválido.\")\n // that distinguishes invalid_holderInfo sub-cases (CEP vs phone vs name).\n userMessage: useDefaultMessages ? asaasErrorMessage(code, fallbackMessage) : fallbackMessage,\n }),\n [useDefaultMessages],\n );\n\n /**\n * High-level no-args submit — uses internal state (selectedMethod, cycle,\n * cpf, card). Returns the discriminated CheckoutResult so caller can read\n * `result.method` for success or `result.ok === false` + `result.code` for\n * gated/disabled methods. Pre-flight rejects when methodAvailability already\n * has the selected method flagged false (no backend round-trip).\n */\n const submit = useCallback(async (): Promise<CheckoutResult | undefined> => {\n // Defense-in-depth: AuthGated prevents this from running unauthed in\n // practice (paywall is structurally unreachable pre-auth). If the\n // invariant breaks at runtime for an anonymous caller, emit the alarm\n // + abort so we get a regression signal without sending a 401-doomed\n // request. 'loading' is a transient race (user taps during ~200ms auth\n // rehydration) — abort silently without polluting the alarm cohort.\n if (authStatus === 'loading') return undefined;\n if (authStatus !== 'authenticated') {\n track('unauthenticated_submit_attempted', {\n method: selectedMethod,\n cycle,\n cpf_valid: cpfValid,\n });\n return undefined;\n }\n\n track('payment_attempted', {\n method: selectedMethod,\n cycle,\n cpf_valid: cpfValid,\n selected_amount_cents:\n cycle === 'YEARLY'\n ? (plan.data?.yearlyPriceCents ?? (isFree ? 0 : paywall.prices.yearlyCents))\n : (plan.data?.priceCents ?? (isFree ? 0 : paywall.prices.monthlyCents)),\n });\n\n setSubmitting(true);\n setError(null);\n\n const methodToUse = selectedMethod;\n\n if (!isMethodAvailable(availability, methodToUse)) {\n const code = 'method_unavailable';\n setError(buildError(code, `method ${methodToUse} unavailable`));\n setSubmitting(false);\n return {\n ok: false,\n code: 'method_unavailable',\n method: methodToUse,\n reason: 'pre_flight_unavailable',\n };\n }\n\n try {\n let result: CheckoutResult;\n if (methodToUse === 'card') {\n const [expMonthRaw = '', expYearRaw = ''] = card.expiry.split('/');\n const expYearTrimmed = expYearRaw.trim();\n const cardData: CheckoutCardData = {\n number: card.number,\n holderName: card.holder,\n expiryMonth: expMonthRaw.trim(),\n expiryYear: expYearTrimmed.length === 2 ? `20${expYearTrimmed}` : expYearTrimmed,\n ccv: card.cvv,\n };\n const holderInfo: CheckoutHolderInfo = {\n name: card.holder,\n email: '',\n cpfCnpj: cpf,\n postalCode: '',\n addressNumber: '',\n };\n result = await subscription.checkout({\n method: 'card',\n cycle,\n cpf,\n card: cardData,\n holderInfo,\n });\n } else if (methodToUse === 'pix-auto') {\n result = await subscription.checkout({ method: 'pix-auto', cycle, cpf });\n } else {\n result = await subscription.checkout({ method: 'pix-once', cycle, cpf });\n }\n\n if (isCheckoutFailure(result)) {\n setError(buildError(result.code, `${result.code}: ${result.reason}`));\n setSubmitting(false);\n return result;\n }\n\n await subscription.refresh();\n setSubmitting(false);\n return result;\n } catch (err) {\n const code = (err as { code?: string })?.code ?? 'generic_decline';\n const message = err instanceof Error ? err.message : String(err);\n setError(buildError(code, message));\n setSubmitting(false);\n return undefined;\n }\n }, [authStatus, track, selectedMethod, availability, subscription, cycle, cpf, cpfValid, card, buildError, plan, paywall]);\n\n /**\n * Legacy direct-args entrypoint — kept for SDK 0.13/template 0.9 callers\n * (incl. DefaultPaywall) until they migrate to `submit()`. Validates\n * card/holderInfo presence for `method === 'card'` to preserve the old\n * test contract (synthetic Error surfacing).\n */\n const checkout = useCallback(\n async (args: PaywallCheckoutArgs): Promise<void> => {\n setSubmitting(true);\n setError(null);\n try {\n if (args.method === 'card') {\n if (!args.card || !args.holderInfo) {\n throw Object.assign(\n new Error('card and holderInfo are required when method is \"card\"'),\n { code: 'validation' },\n );\n }\n const sdkArgs: CheckoutArgs = {\n method: 'card',\n cycle: args.cycle,\n cpf: args.cpf,\n card: args.card,\n holderInfo: args.holderInfo,\n ...(args.remoteIp ? { remoteIp: args.remoteIp } : {}),\n };\n const result = await subscription.checkout(sdkArgs);\n if (isCheckoutFailure(result)) {\n setError(buildError(result.code, `${result.code}: ${result.reason}`));\n setSubmitting(false);\n return;\n }\n await subscription.refresh();\n setSubmitting(false);\n return;\n }\n if (args.method === 'pix-auto') {\n const result = await subscription.checkout({\n method: 'pix-auto',\n cycle: args.cycle,\n cpf: args.cpf,\n });\n if (isCheckoutFailure(result)) {\n setError(buildError(result.code, `${result.code}: ${result.reason}`));\n setSubmitting(false);\n return;\n }\n setSubmitting(false);\n return;\n }\n // method === 'pix-once'\n const result = await subscription.checkout({\n method: 'pix-once',\n cycle: args.cycle,\n cpf: args.cpf,\n });\n if (isCheckoutFailure(result)) {\n setError(buildError(result.code, `${result.code}: ${result.reason}`));\n setSubmitting(false);\n return;\n }\n setSubmitting(false);\n } catch (err) {\n const code = (err as { code?: string })?.code ?? 'generic_decline';\n const message = err instanceof Error ? err.message : String(err);\n setError(buildError(code, message));\n setSubmitting(false);\n }\n },\n [subscription, buildError],\n );\n\n const cancel = useCallback(async () => {\n try {\n await subscription.cancel();\n await subscription.refresh();\n } catch (err) {\n const code = (err as { code?: string })?.code ?? 'generic_decline';\n const message = err instanceof Error ? err.message : String(err);\n setError(buildError(code, message));\n }\n }, [subscription, buildError]);\n\n const cardState: CardFormStateWithSetter = useMemo(\n () => ({ ...card, set: setCard }),\n [card, setCard],\n );\n\n const cpfState: CpfState = useMemo(\n () => ({ required: cpfRequired, value: cpf, set: setCpf, valid: cpfValid }),\n [cpfRequired, cpf, cpfValid],\n );\n\n // Analytics: emit `paywall_step_viewed` on every canonical step transition.\n // Fire-and-forget; no impact on render or checkout latency. See\n // hooks/usePaywallTracker.ts for the step-derivation contract + Studio\n // consumer in DropoffSection.\n usePaywallTracker({\n selectedMethod,\n cycle,\n cpfRequired,\n cpfValid,\n pixPendingShown: pixPending !== null,\n pixPaid: pixPending?.paid === true,\n hasError: error !== null,\n submitting,\n });\n\n return {\n // Subscription status (reactive, proxied from SDK)\n status,\n hasAccess,\n daysLeftInTrial,\n initialLoadComplete,\n\n // Plan derivation from config (sync, no fetch)\n plan: planDerived,\n\n // Cycle + method selection\n cycle,\n setCycle,\n methods,\n selectedMethod,\n setSelectedMethod,\n\n // Conversion-max derivations (template 0.21)\n hasConsumedTrial,\n currentPriceCents,\n currentMonthlyEquivCents,\n anchorPriceCents,\n selectMethod,\n selectCycle,\n isFree,\n\n // Per-method trial (ADR-022 Amendment 2026-05-12). Use these to render\n // asymmetric copy per method card on the paywall — never a global\n // \"free trial!\" headline when both methods are visible.\n trialDaysForMethod,\n trialDaysCard,\n trialDaysPix,\n\n // Form state\n cpfState,\n cardState,\n\n // High-level + legacy actions\n submit,\n checkout,\n cancel,\n\n // PIX state (proxied from SDK; legacy `paid`/`expiresAt` derived)\n pixPending,\n\n // Error + submit progress\n error,\n submitting,\n\n // Backward-compat aliases (deprecated; remove in template 0.11)\n opening: submitting,\n availableMethods: methods,\n monthlyEquivalent,\n // G154 fix (template 0.24.0 + SDK 0.26.0): wired to SDK action.\n dismissPix: subscription.clearPixPending,\n refreshPlan: () => {},\n };\n}\n","// Maps Asaas error codes (and a few synthetic ones surfaced by the SDK)\n// to user-facing PT-BR messages. Used by usePaywallState + paywall screens\n// when `app.config.json.paywall.errorMessages === \"default\"`.\n\nconst MAP: Record<string, string> = {\n invalid_cpf: 'CPF inválido. Confira os números e tente novamente.',\n cpf_required: 'Por favor, informe seu CPF para continuar.',\n card_declined: 'Cartão recusado pela operadora. Tente outro cartão ou método.',\n insufficient_funds: 'Saldo insuficiente no cartão. Tente outro método.',\n card_expired: 'Cartão expirado. Use um cartão válido.',\n invalid_card_number: 'Número de cartão inválido.',\n invalid_cvv: 'Código de segurança (CVV) inválido.',\n invalid_expiration: 'Data de validade inválida.',\n generic_decline:\n 'Pagamento recusado. Tente novamente em instantes ou use outro método.',\n webhook_unverified:\n 'Não conseguimos confirmar seu pagamento. Atualize a página em alguns segundos.',\n pix_expired: 'QR Code do PIX expirou. Gere um novo.',\n pix_not_paid_yet: 'PIX ainda não foi pago. Aguardando confirmação.',\n};\n\n/**\n * Map Asaas error → PT-BR user-facing message.\n *\n * Two inputs because backend folds Asaas's specific error code into a\n * compound code (`payments.capture_card.tokenize_failed:invalid_holderInfo`)\n * and only the *description* string (\"O CEP informado é inválido.\")\n * distinguishes between sub-cases of `invalid_holderInfo` (CEP, phone, name).\n *\n * Asaas keeps a snapshot of Correios CEPs that lags real registrations by\n * months — CEPs of recently-cadastrated streets (ex: bairros novos) get\n * rejected even though they're valid in ViaCEP/BrasilAPI. We don't suggest\n * a fictitious CEP (would mess up nota fiscal/comms); we explain the issue\n * is on the processor's side and ask user to try a nearby street's CEP.\n */\nexport function asaasErrorMessage(code: string, description?: string): string {\n // Substring match em description tem prioridade — é mais específico que code.\n if (description) {\n const lower = description.toLowerCase();\n if (lower.includes('cep')) {\n return 'Nosso processador de pagamentos não reconheceu esse CEP — a base deles pode estar desatualizada. Tente outro CEP.';\n }\n if (lower.includes('telefone') || lower.includes('contato com ddd')) {\n return 'Telefone inválido. Confira o número com DDD e tente novamente.';\n }\n }\n return MAP[code] ?? 'Ocorreu um erro inesperado. Tente novamente em instantes.';\n}\n","import { useEffect, useRef } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type { CheckoutMethod, CheckoutCycle } from '@hook-sdk/sdk';\n\n/**\n * Canonical paywall step values. Bundle-side (template-controlled), so the list\n * is fixed — Studio dropoff queries can rely on a stable enumeration.\n *\n * - `plan_select` — paywall just opened, user choosing cycle (monthly/yearly)\n * - `method_select` — user picking payment method (card / pix-auto / pix-once)\n * - `cpf_input` — entering CPF (only when paywall.requiresCpf)\n * - `card_form` — filling card data (number, cvv, expiry, holder)\n * - `pix_qr_shown` — PIX QR code rendered, waiting for payment\n * - `error` — checkout failed (declined, validation, etc.)\n * - `success` — checkout succeeded; subscription is ACTIVE/TRIAL\n */\nexport type PaywallStep =\n | 'plan_select'\n | 'method_select'\n | 'cpf_input'\n | 'card_form'\n | 'pix_qr_shown'\n | 'error'\n | 'success';\n\ninterface PaywallStateSnapshot {\n selectedMethod: CheckoutMethod;\n cycle: CheckoutCycle;\n cpfRequired: boolean;\n cpfValid: boolean;\n pixPendingShown: boolean;\n pixPaid: boolean;\n hasError: boolean;\n submitting: boolean;\n}\n\n/**\n * Maps the paywall headless state into a canonical step name. Pure function to\n * keep the tracker testable. Order of branches matters: terminal states first\n * (success > error > pixQR), then progressive (cardForm > cpf > method > plan).\n */\nfunction deriveStep(s: PaywallStateSnapshot): PaywallStep {\n if (s.pixPaid) return 'success';\n if (s.hasError) return 'error';\n if (s.pixPendingShown) return 'pix_qr_shown';\n if (s.selectedMethod === 'card' && s.cpfValid) return 'card_form';\n if (s.cpfRequired && !s.cpfValid) return 'cpf_input';\n // After method is picked but before CPF/card details — user is on the methods\n // sheet. We collapse plan_select into method_select once a method exists,\n // since most paywalls show plan + method together; plan_select only shows\n // before any state has settled (e.g. paywall just mounted with no method\n // available yet — rare).\n if (s.selectedMethod) return 'method_select';\n return 'plan_select';\n}\n\n/**\n * Side-effect hook: emits `paywall_step_viewed` whenever the derived step\n * changes. Fire-and-forget via SDK `track()`. Caller plugs this into\n * `usePaywallState` so every paywall in the platform reports drop-off without\n * any per-app instrumentation.\n *\n * Dedupe via ref: same step in a row never re-emits, even if other paywall\n * state churns (e.g. card form keystrokes). Only step transitions count.\n */\nexport function usePaywallTracker(snapshot: PaywallStateSnapshot): void {\n // Defensive: useHook() may return a partial mock in tests that pre-date the\n // `track` field. Treat missing track as a no-op so analytics never breaks\n // the paywall in legacy test envs.\n const ctx = useHook() as ReturnType<typeof useHook> & {\n track?: (event: string, props?: Record<string, unknown>) => void;\n };\n const track = typeof ctx.track === 'function' ? ctx.track : undefined;\n const lastStepRef = useRef<PaywallStep | null>(null);\n\n const step = deriveStep(snapshot);\n\n useEffect(() => {\n if (lastStepRef.current === step) return;\n lastStepRef.current = step;\n if (!track) return;\n track('paywall_step_viewed', {\n step,\n method: snapshot.selectedMethod,\n cycle: snapshot.cycle,\n });\n // Intentionally only depend on `step` — other props are read for the event\n // payload but shouldn't trigger re-emission. Keeping snapshot.* in the dep\n // array would re-fire on any keystroke during card form fill.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [step]);\n}\n\n// Exported for tests.\nexport const _internals = { deriveStep };\n","import type { ComponentType, ReactNode } from 'react';\nimport { useTemplateConfig } from './TemplateConfigContext';\nimport { usePaywallState, type SubscriptionStatus } from '../hooks/usePaywallState';\n\ninterface Props {\n Paywall: ComponentType;\n children: ReactNode;\n}\n\nconst BLOCKING: ReadonlySet<SubscriptionStatus> = new Set([\n 'pending',\n 'expired',\n 'canceled',\n 'none',\n]);\n\nexport function SubscriptionGate({ Paywall, children }: Props) {\n const { mode } = useTemplateConfig();\n const { status, hasAccess, initialLoadComplete } = usePaywallState();\n\n // free: nunca bloqueia, independente de status.\n if (mode === 'free') return <>{children}</>;\n // G68: evita flash de paywall no cold start antes do 1º /me resolver.\n // Quando não há cache local (primeiro login, novo device), sub === null e\n // status='none' — BLOCKING dispararia o paywall por ~1-2s até o fetch\n // voltar. Com cache (user já pago), sub já vem populado do localStorage\n // e status reflete o último valor conhecido → sem flash.\n // Render nulo (em vez de paywall/spinner) porque AuthGate/AppShell já\n // cobrem o skeleton visual. Flash rápido de nada > flash de paywall.\n if (!initialLoadComplete && status === 'none') return null;\n // Backend-authoritative override: sub CANCELLED com trial_ends_at ou\n // current_period_end no futuro → hasAccess=true (App Store-style: cancela\n // mas usa até fim do período pago). SDK mapStatus retorna \"canceled\" sem\n // distinguir; aqui respeitamos o flag autoritativo do backend.\n // Não cobre \"none\" (sub null = nunca pagou) — só status conhecido + ainda\n // dentro do período. Defesa em profundidade: hasAccess pode ser null se o\n // /me ainda não voltou; nesse caso fail-closed via BLOCKING normal.\n if (hasAccess === true && status !== 'none') return <>{children}</>;\n // pending/expired/canceled/none → Paywall.\n if (BLOCKING.has(status)) return <Paywall />;\n // trialing/active/past_due → libera (past_due é window de grace).\n return <>{children}</>;\n}\n","/**\n * InstallGate — wrapper que decide entre splash bloqueante e pass-through.\n *\n * Colocado em AppRoot entre ThemeProvider e AuthGate. Ver ADR-017 + doc 16.\n *\n * Comportamento:\n * - feature `pwa-install` desabilitado em app.config.json → renderiza children\n * - Standalone detectado → renderiza children\n * - Platform == desktop + !installable → renderiza children (sem banner)\n * - Platform == desktop + installable → renderiza children + banner soft lateral\n * - Mobile/in-app + não-installed + não-dismissed → splash bloqueante (substitui children)\n * - Mobile dismissido → renderiza children\n */\n\nimport { useEffect, useRef, type ReactNode } from 'react';\nimport { useTemplateConfig } from '../../internal/TemplateConfigContext';\nimport { shouldBlockInstall, useInstallPrompt } from '../../hooks/useInstallPrompt';\nimport { AndroidNativeVariant } from './variants/AndroidNativeVariant';\nimport { AndroidManualVariant } from './variants/AndroidManualVariant';\nimport { AndroidPendingVariant } from './variants/AndroidPendingVariant';\nimport { IOSafariVariant } from './variants/IOSafariVariant';\nimport { IOSOtherVariant } from './variants/IOSOtherVariant';\nimport { InAppBrowserVariant } from './variants/InAppBrowserVariant';\nimport { DesktopVariant } from './variants/DesktopVariant';\n\ninterface InstallGateProps {\n children: ReactNode;\n /**\n * Position of the gate in the AppRoot render tree.\n * Forwarded to `pwa_install_splash_shown` analytics for funnel analysis.\n * AppRoot reads `config.install_prompt?.position` and passes it here.\n */\n position?: 'pre-auth' | 'post-paywall';\n}\n\nexport function InstallGate({ children, position }: InstallGateProps) {\n const { slug, features_enabled } = useTemplateConfig();\n const enabled = features_enabled.includes('pwa-install' as never);\n\n const installState = useInstallPrompt(slug);\n const shouldBlock = enabled && shouldBlockInstall(installState);\n\n // Analytics: dispara `pwa_install_splash_shown` 1× por sessão+variant\n const trackedRef = useRef<string | null>(null);\n useEffect(() => {\n if (!shouldBlock) return;\n if (typeof window === 'undefined') return;\n const variantKey = `${slug}:${installState.variant}`;\n if (trackedRef.current === variantKey) return;\n trackedRef.current = variantKey;\n window.posthog?.capture?.('pwa_install_splash_shown', {\n slug,\n platform: installState.platform,\n browser: installState.iosBrowser ?? installState.androidBrowser ?? null,\n in_app_app: installState.inAppApp,\n variant: installState.variant,\n ...(position !== undefined ? { position } : {}),\n });\n }, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp, position]);\n\n if (!enabled) return <>{children}</>;\n if (installState.isInstalled) return <>{children}</>;\n\n // Desktop: banner soft, children renderiza normal em paralelo\n if (installState.variant === 'desktop') {\n const showBanner = !installState.isDismissedSession && !installState.isDismissedPermanent;\n return (\n <>\n {children}\n {showBanner && <DesktopVariant state={installState} actions={installState} />}\n </>\n );\n }\n\n if (!shouldBlock) return <>{children}</>;\n\n // Mobile / in-app: splash bloqueante substitui children\n switch (installState.variant) {\n case 'android-native':\n return <AndroidNativeVariant state={installState} actions={installState} />;\n case 'android-manual':\n return <AndroidManualVariant state={installState} actions={installState} />;\n case 'android-pending':\n return <AndroidPendingVariant />;\n case 'ios-safari':\n return <IOSafariVariant state={installState} actions={installState} />;\n case 'ios-other':\n return <IOSOtherVariant state={installState} actions={installState} />;\n case 'in-app':\n return <InAppBrowserVariant state={installState} actions={installState} />;\n case 'none':\n default:\n return <>{children}</>;\n }\n}\n","/**\n * useInstallPrompt — headless hook pra PWA install prompt.\n *\n * Responsabilidades:\n * - Detectar plataforma (Android / iOS Safari / iOS outros / in-app / desktop)\n * - Detectar browser específico (Chrome, Firefox, Samsung, Instagram, ...)\n * - Detectar standalone mode (PWA já instalado)\n * - Gerenciar dismissal graduada (session → permanente 14d)\n * - Expor `promptInstall()` que dispara `window.__pwaInstallPrompt.prompt()`\n *\n * Não renderiza UI. Componente `<InstallGate>` consome o hook e renderiza.\n *\n * Porta regexes + lógica de `hook-old/src/hooks/usePWAInstall.ts` com\n * divergências deliberadas (ver docs/adr/017 + P20 plan):\n * - enum InAppApp granular pra copy por rede social (G60 amendment)\n * - dismissal graduada em vez de permanente direto\n * - TTL de 14d no permanent dismiss\n * - tracking `skipCount` separado\n *\n * Gotchas de referência:\n * - G61: beforeinstallprompt capturado pré-React (shell main.tsx faz)\n * - G62: distinção ios-safari vs ios-other (Chrome iOS não instala)\n * - G63: in-app browsers checados ANTES de Android/iOS\n */\n\nimport { useCallback, useEffect, useState } from 'react';\n\n// --- Types ---------------------------------------------------------------\n\nexport type Platform =\n | 'android'\n | 'ios-safari'\n | 'ios-other'\n | 'in-app'\n | 'desktop'\n | 'unknown';\n\nexport type IOSBrowser = 'safari' | 'chrome' | 'firefox' | 'edge' | 'other';\n\nexport type AndroidBrowser =\n | 'chrome'\n | 'firefox'\n | 'opera'\n | 'samsung'\n | 'edge'\n | 'other';\n\nexport type InAppApp =\n | 'instagram'\n | 'facebook'\n | 'tiktok'\n | 'whatsapp'\n | 'twitter'\n | 'linkedin'\n | 'telegram'\n | 'line'\n | 'snapchat'\n | 'pinterest'\n | 'wechat'\n | 'other';\n\nexport type InstallVariant =\n | 'android-native'\n | 'android-manual'\n | 'android-pending'\n | 'ios-safari'\n | 'ios-other'\n | 'in-app'\n | 'desktop'\n | 'none';\n\n/**\n * Janela de espera por `beforeinstallprompt` no Android antes de cair pra\n * variant manual. Em redes lentas / 1ª visita / Chrome warm-up, o evento\n * chega 1–3s pós-load. Se decidirmos variant no mount, mostramos\n * instruções manuais por alguns segundos antes do botão \"Instalar\"\n * aparecer (race UX). Esperar até este timeout e só então cair pra manual\n * elimina o flash. 3s cobre P95 sem deixar a tela parada longa demais.\n */\nconst ANDROID_PROMPT_WAIT_MS = 3000;\n\ninterface BeforeInstallPromptEvent extends Event {\n prompt: () => Promise<void>;\n userChoice: Promise<{ outcome: 'accepted' | 'dismissed'; platform: string }>;\n}\n\ndeclare global {\n interface Window {\n __pwaInstallPrompt?: BeforeInstallPromptEvent | null;\n posthog?: { capture?: (event: string, props?: Record<string, unknown>) => void };\n }\n}\n\nexport interface InstallState {\n platform: Platform;\n iosBrowser: IOSBrowser | null;\n androidBrowser: AndroidBrowser | null;\n inAppApp: InAppApp | null;\n isInstallable: boolean;\n isInstalled: boolean;\n isDismissedSession: boolean;\n isDismissedPermanent: boolean;\n skipCount: number;\n variant: InstallVariant;\n}\n\nexport interface InstallActions {\n promptInstall: () => Promise<boolean>;\n dismissSession: () => void;\n dismissPermanent: () => void;\n copyLink: () => Promise<void>;\n reset: () => void;\n}\n\n// --- Regex canônicas (portadas verbatim de hook-old) ---------------------\n\nconst IOS_RE = /iPad|iPhone|iPod/;\nconst IOS_NON_SAFARI_RE = /CriOS|FxiOS|EdgiOS/;\nconst ANDROID_RE = /Android/;\nconst IN_APP_RE =\n /Instagram|FBAN|FBAV|BytedanceWebview|TikTok|Line\\/|Twitter|Snapchat|Pinterest|LinkedIn|WhatsApp|MicroMessenger|Telegram/i;\n\n// --- Constants ----------------------------------------------------------\n\nconst PERMANENT_DISMISS_REPROMPT_DAYS = 14;\nconst SESSION_SKIPS_BEFORE_PERMANENT_OPTION = 2;\n\n// --- Storage keys -------------------------------------------------------\n\nconst storageKey = {\n sessionSkip: (slug: string) => `install:${slug}:session-skip`,\n dismissedAt: (slug: string) => `install:${slug}:dismissed-at`,\n installedAt: (slug: string) => `install:${slug}:installed-at`,\n skipCount: (slug: string) => `install:${slug}:skip-count`,\n};\n\n// --- Detection (pure functions) -----------------------------------------\n\nexport function detectPlatform(ua: string): Platform {\n if (IN_APP_RE.test(ua)) return 'in-app'; // MUST check first (G63)\n const isIOS = IOS_RE.test(ua);\n if (isIOS) {\n const isSafari = /Safari/.test(ua) && !IOS_NON_SAFARI_RE.test(ua);\n return isSafari ? 'ios-safari' : 'ios-other';\n }\n if (ANDROID_RE.test(ua)) return 'android';\n return 'desktop';\n}\n\nexport function detectIOSBrowser(ua: string): IOSBrowser | null {\n if (!IOS_RE.test(ua)) return null;\n if (/CriOS/.test(ua)) return 'chrome';\n if (/FxiOS/.test(ua)) return 'firefox';\n if (/EdgiOS/.test(ua)) return 'edge';\n if (/Safari/.test(ua)) return 'safari';\n return 'other';\n}\n\nexport function detectAndroidBrowser(ua: string): AndroidBrowser | null {\n if (!ANDROID_RE.test(ua)) return null;\n if (/EdgA/.test(ua)) return 'edge';\n if (/OPR|OPT/.test(ua)) return 'opera';\n if (/SamsungBrowser/.test(ua)) return 'samsung';\n if (/Firefox/.test(ua)) return 'firefox';\n if (/Chrome/.test(ua)) return 'chrome';\n return 'other';\n}\n\nexport function detectInAppApp(ua: string): InAppApp | null {\n if (!IN_APP_RE.test(ua)) return null;\n if (/Instagram/i.test(ua)) return 'instagram';\n if (/FBAN|FBAV/.test(ua)) return 'facebook';\n if (/BytedanceWebview|TikTok/i.test(ua)) return 'tiktok';\n if (/WhatsApp/i.test(ua)) return 'whatsapp';\n if (/Twitter/i.test(ua)) return 'twitter';\n if (/LinkedIn/i.test(ua)) return 'linkedin';\n if (/Telegram/i.test(ua)) return 'telegram';\n if (/Line\\//i.test(ua)) return 'line';\n if (/Snapchat/i.test(ua)) return 'snapchat';\n if (/Pinterest/i.test(ua)) return 'pinterest';\n if (/MicroMessenger/i.test(ua)) return 'wechat';\n return 'other';\n}\n\nexport function detectStandalone(): { installed: boolean; source: 'match_media' | 'navigator_standalone' | 'storage_marker' | null } {\n if (typeof window === 'undefined' || typeof navigator === 'undefined') {\n return { installed: false, source: null };\n }\n const mm = window.matchMedia?.('(display-mode: standalone)');\n if (mm?.matches) return { installed: true, source: 'match_media' };\n const fs = window.matchMedia?.('(display-mode: fullscreen)');\n if (fs?.matches) return { installed: true, source: 'match_media' };\n // @ts-expect-error — legacy iOS Safari property\n if (navigator.standalone === true) return { installed: true, source: 'navigator_standalone' };\n return { installed: false, source: null };\n}\n\n// --- Analytics helper ----------------------------------------------------\n\nfunction track(event: string, props: Record<string, unknown>): void {\n if (typeof window === 'undefined') return;\n window.posthog?.capture?.(event, props);\n}\n\n// --- Variant picker ------------------------------------------------------\n\nfunction pickVariant(\n state: Omit<InstallState, 'variant'>,\n promptWaitElapsed: boolean,\n): InstallVariant {\n if (state.isInstalled) return 'none';\n switch (state.platform) {\n case 'android':\n if (state.isInstallable) return 'android-native';\n // Não recebemos beforeinstallprompt ainda. Espera até `promptWaitElapsed`\n // antes de cair em manual — Chrome dispara o evento 1-3s pós-load em\n // muitos casos. Sem essa espera, mostramos instruções manuais e troca\n // pra botão depois (race UX).\n return promptWaitElapsed ? 'android-manual' : 'android-pending';\n case 'ios-safari':\n return 'ios-safari';\n case 'ios-other':\n return 'ios-other';\n case 'in-app':\n return 'in-app';\n case 'desktop':\n return state.isInstallable ? 'desktop' : 'none';\n default:\n return 'none';\n }\n}\n\n// --- Hook ---------------------------------------------------------------\n\nfunction safeStorage(): { getItem(k: string): string | null; setItem(k: string, v: string): void; removeItem(k: string): void } | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n localStorage.setItem('__install_probe', '1');\n localStorage.removeItem('__install_probe');\n return localStorage;\n } catch {\n return null;\n }\n}\n\nfunction readPermanentDismiss(slug: string): { dismissed: boolean; dismissedAt: string | null } {\n const storage = safeStorage();\n if (!storage) return { dismissed: false, dismissedAt: null };\n const raw = storage.getItem(storageKey.dismissedAt(slug));\n if (!raw) return { dismissed: false, dismissedAt: null };\n const parsed = Date.parse(raw);\n if (Number.isNaN(parsed)) return { dismissed: false, dismissedAt: null };\n const daysAgo = (Date.now() - parsed) / (1000 * 60 * 60 * 24);\n return { dismissed: daysAgo < PERMANENT_DISMISS_REPROMPT_DAYS, dismissedAt: raw };\n}\n\nfunction readInstalledMarker(slug: string): boolean {\n const storage = safeStorage();\n if (!storage) return false;\n return storage.getItem(storageKey.installedAt(slug)) !== null;\n}\n\nfunction readSkipCount(slug: string): number {\n const storage = safeStorage();\n if (!storage) return 0;\n const raw = storage.getItem(storageKey.skipCount(slug));\n const n = raw ? Number.parseInt(raw, 10) : 0;\n return Number.isFinite(n) && n >= 0 ? n : 0;\n}\n\nfunction readSessionSkip(slug: string): boolean {\n if (typeof sessionStorage === 'undefined') return false;\n try {\n return sessionStorage.getItem(storageKey.sessionSkip(slug)) === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * Hook principal. Passar o slug do app (usado pra namespacing de storage +\n * analytics). Componentes do template pegam via useTemplateConfig().slug.\n */\nexport function useInstallPrompt(slug: string): InstallState & InstallActions {\n const ua =\n typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string'\n ? navigator.userAgent\n : '';\n\n const platform = detectPlatform(ua);\n const iosBrowser = detectIOSBrowser(ua);\n const androidBrowser = detectAndroidBrowser(ua);\n const inAppApp = detectInAppApp(ua);\n\n const [isInstallable, setIsInstallable] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false;\n return window.__pwaInstallPrompt != null;\n });\n\n const [isInstalled, setIsInstalled] = useState<boolean>(() => {\n const { installed } = detectStandalone();\n return installed || readInstalledMarker(slug);\n });\n\n const [isDismissedSession, setIsDismissedSession] = useState<boolean>(() => readSessionSkip(slug));\n const [isDismissedPermanent, setIsDismissedPermanent] = useState<boolean>(() => readPermanentDismiss(slug).dismissed);\n const [skipCount, setSkipCount] = useState<number>(() => readSkipCount(slug));\n\n // Anti-flash: no mount, Android sem beforeinstallprompt fica em estado\n // pendente até `ANDROID_PROMPT_WAIT_MS` passar. Só aí caímos pra manual.\n // Inicia true se evento já chegou pré-React (capture.ts no shell).\n const [promptWaitElapsed, setPromptWaitElapsed] = useState<boolean>(() => {\n if (typeof window === 'undefined') return true;\n return window.__pwaInstallPrompt != null;\n });\n useEffect(() => {\n if (promptWaitElapsed) return;\n const id = setTimeout(() => setPromptWaitElapsed(true), ANDROID_PROMPT_WAIT_MS);\n return () => clearTimeout(id);\n }, [promptWaitElapsed]);\n\n // beforeinstallprompt listener (fallback — shell main.tsx já captura antes,\n // mas se evento vier pós-React em algum edge case, pegamos aqui também)\n useEffect(() => {\n if (typeof window === 'undefined') return;\n if (window.__pwaInstallPrompt) {\n setIsInstallable(true);\n }\n const onPrompt = (e: Event) => {\n e.preventDefault();\n window.__pwaInstallPrompt = e as BeforeInstallPromptEvent;\n setIsInstallable(true);\n };\n const onInstalled = () => {\n setIsInstalled(true);\n setIsInstallable(false);\n window.__pwaInstallPrompt = null;\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.installedAt(slug), new Date().toISOString());\n };\n window.addEventListener('beforeinstallprompt', onPrompt);\n window.addEventListener('appinstalled', onInstalled);\n return () => {\n window.removeEventListener('beforeinstallprompt', onPrompt);\n window.removeEventListener('appinstalled', onInstalled);\n };\n }, [slug]);\n\n // Standalone changes (user instala durante sessão) → update gate\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia?.('(display-mode: standalone)');\n if (!mq) return;\n const handler = (e: MediaQueryListEvent) => {\n if (e.matches) {\n setIsInstalled(true);\n track('pwa_install_standalone_detected', { slug, source: 'match_media' });\n }\n };\n mq.addEventListener?.('change', handler);\n return () => mq.removeEventListener?.('change', handler);\n }, [slug]);\n\n const variant = pickVariant(\n {\n platform,\n iosBrowser,\n androidBrowser,\n inAppApp,\n isInstallable,\n isInstalled,\n isDismissedSession,\n isDismissedPermanent,\n skipCount,\n },\n promptWaitElapsed,\n );\n\n const promptInstall = useCallback(async (): Promise<boolean> => {\n if (typeof window === 'undefined') return false;\n const prompt = window.__pwaInstallPrompt;\n if (!prompt) return false;\n\n track('pwa_install_prompt_clicked', { slug });\n\n try {\n await prompt.prompt();\n const { outcome } = await prompt.userChoice;\n track('pwa_install_prompt_outcome', { slug, outcome });\n if (outcome === 'accepted') {\n setIsInstalled(true);\n setIsInstallable(false);\n window.__pwaInstallPrompt = null;\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.installedAt(slug), new Date().toISOString());\n return true;\n }\n return false;\n } catch {\n return false;\n }\n }, [slug]);\n\n const dismissSession = useCallback(() => {\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.setItem(storageKey.sessionSkip(slug), 'true');\n } catch {\n /* ignore */\n }\n }\n const storage = safeStorage();\n const newCount = skipCount + 1;\n if (storage) storage.setItem(storageKey.skipCount(slug), String(newCount));\n setSkipCount(newCount);\n setIsDismissedSession(true);\n track('pwa_install_session_skip', { slug, platform, skip_count: newCount });\n }, [slug, skipCount, platform]);\n\n const dismissPermanent = useCallback(() => {\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.dismissedAt(slug), new Date().toISOString());\n setIsDismissedPermanent(true);\n track('pwa_install_permanent_dismiss', { slug, platform, prior_skip_count: skipCount });\n }, [slug, platform, skipCount]);\n\n const copyLink = useCallback(async (): Promise<void> => {\n if (typeof navigator === 'undefined' || typeof location === 'undefined') return;\n try {\n await navigator.clipboard?.writeText?.(location.href);\n } catch {\n /* ignore — caller surfaces via toast */\n }\n }, []);\n\n const reset = useCallback(() => {\n const storage = safeStorage();\n if (storage) {\n storage.removeItem(storageKey.dismissedAt(slug));\n storage.removeItem(storageKey.installedAt(slug));\n storage.removeItem(storageKey.skipCount(slug));\n }\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.removeItem(storageKey.sessionSkip(slug));\n } catch {\n /* ignore */\n }\n }\n setIsDismissedSession(false);\n setIsDismissedPermanent(false);\n setSkipCount(0);\n }, [slug]);\n\n return {\n platform,\n iosBrowser,\n androidBrowser,\n inAppApp,\n isInstallable,\n isInstalled,\n isDismissedSession,\n isDismissedPermanent,\n skipCount,\n variant,\n promptInstall,\n dismissSession,\n dismissPermanent,\n copyLink,\n reset,\n };\n}\n\n/**\n * Exposto pra InstallGate decidir se renderiza splash (não faz parte do hook\n * retornado pra manter surface pequena — componente usa).\n */\nexport function shouldBlockInstall(state: InstallState, now: number = Date.now()): boolean {\n if (state.isInstalled) return false;\n if (state.variant === 'none') return false;\n if (state.isDismissedSession) return false;\n if (state.isDismissedPermanent) {\n // readPermanentDismiss já checou TTL; redundante, mas explicit pra tests\n void now;\n return false;\n }\n // Desktop só bloqueia se não-installable (banner soft vem por fora)\n if (state.platform === 'desktop' && !state.isInstallable) return false;\n if (state.platform === 'unknown') return false;\n return true;\n}\n\n/**\n * Exposto pra decidir se mostra \"Não me pergunte mais\".\n */\nexport function shouldShowPermanentOption(state: InstallState): boolean {\n return state.skipCount >= SESSION_SKIPS_BEFORE_PERMANENT_OPTION;\n}\n","/**\n * Copy pt-BR do PWA install prompt. Hardcoded (template não tem i18n).\n * Design doc: docs/superpowers/specs/2026-04-22-p20-pwa-install-prompt-design.md\n */\n\nexport const INSTALL_COPY = {\n android: {\n native: {\n title: 'Instale no seu celular',\n subtitle: 'Acesso rápido, sem precisar do navegador',\n cta: 'Baixar',\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n manual: {\n title: 'Instale em 2 toques',\n subtitle: 'Toque no menu do navegador e escolha \"Instalar aplicativo\"',\n step1: 'Toque no menu do navegador',\n step2: 'Escolha \"Instalar aplicativo\"',\n cta: 'Entendi',\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n },\n iosSafari: {\n title: 'Adicione à sua Tela de Início',\n subtitle: 'Siga os 3 passos',\n step1: {\n title: 'Toque em Compartilhar',\n subtitle: 'Na barra inferior do Safari',\n },\n step2: {\n title: 'Role e toque em \"Adicionar à Tela de Início\"',\n iconLabel: 'Adicionar à Tela de Início',\n },\n step3: {\n title: 'Toque em \"Adicionar\" pra confirmar',\n buttonLabel: 'Adicionar',\n },\n skip: 'Continuar no Safari',\n skipPermanent: 'Não me pergunte mais',\n },\n iosOther: {\n title: 'Adicione à sua Tela de Início',\n subtitle: 'Siga os 3 passos',\n step1: {\n title: 'Toque em Compartilhar',\n subtitle: 'Geralmente no topo ou no menu do navegador',\n },\n step2: {\n title: 'Role e toque em \"Adicionar à Tela de Início\"',\n iconLabel: 'Adicionar à Tela de Início',\n },\n step3: {\n title: 'Toque em \"Adicionar\" pra confirmar',\n buttonLabel: 'Adicionar',\n },\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n inApp: {\n instagram: {\n title: 'Pra instalar, abra fora do Instagram',\n step1: 'Toque em ⋯ (canto superior direito)',\n step2: 'Escolha \"Abrir no navegador externo\"',\n },\n facebook: {\n title: 'Pra instalar, abra fora do Facebook',\n step1: 'Toque em ⋮',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n tiktok: {\n title: 'Pra instalar, abra fora do TikTok',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no Safari\" (iOS) ou \"Abrir no Chrome\" (Android)',\n },\n whatsapp: {\n title: 'Pra instalar, abra fora do WhatsApp',\n step1: 'Toque longo no link',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n twitter: {\n title: 'Pra instalar, abra fora do Twitter',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n linkedin: {\n title: 'Pra instalar, abra fora do LinkedIn',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n telegram: {\n title: 'Pra instalar, abra fora do Telegram',\n step1: 'Toque em ⋮',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n line: {\n title: 'Pra instalar, abra fora do LINE',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n snapchat: {\n title: 'Pra instalar, abra fora do Snapchat',\n step1: 'Mantenha pressionado o link',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n pinterest: {\n title: 'Pra instalar, abra fora do Pinterest',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n wechat: {\n title: 'Pra instalar, abra fora do WeChat',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n other: {\n title: 'Abra no navegador do celular',\n step1: 'Toque no menu do app atual',\n step2: 'Escolha \"Abrir no Chrome\" ou \"Abrir no Safari\"',\n },\n copy: 'Copiar link',\n copiedToast: 'Link copiado. Cole no Chrome/Safari.',\n skip: 'Continuar aqui mesmo',\n skipPermanent: 'Não me pergunte mais',\n },\n desktop: {\n title: 'Instale no computador',\n subtitle: 'Acesso rápido',\n cta: 'Baixar',\n close: 'Fechar',\n },\n} as const;\n","/**\n * InstallSplash — layout full-screen compartilhado pras variants.\n * Variant renderiza seu próprio conteúdo via children.\n */\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from '../../internal/TemplateConfigContext';\n\ninterface InstallSplashProps {\n children: ReactNode;\n title: string;\n subtitle?: string;\n}\n\nexport function InstallSplash({ children, title, subtitle }: InstallSplashProps) {\n const { name, theme } = useTemplateConfig();\n const iconUrl = theme.icon_url || theme.logo_url || null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"install-splash-title\"\n aria-describedby={subtitle ? 'install-splash-subtitle' : undefined}\n style={overlayStyle}\n >\n <div style={cardStyle}>\n <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 16 }}>\n {iconUrl ? (\n <img\n src={iconUrl}\n alt={`Ícone de ${name}`}\n style={{ width: 80, height: 80, borderRadius: 20, objectFit: 'cover' }}\n />\n ) : (\n <div\n style={{\n width: 80,\n height: 80,\n borderRadius: 20,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 36,\n fontWeight: 700,\n }}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n )}\n </div>\n\n <h1 id=\"install-splash-title\" style={titleStyle}>\n {title}\n </h1>\n\n {subtitle && (\n <p id=\"install-splash-subtitle\" style={subtitleStyle}>\n {subtitle}\n </p>\n )}\n\n <div style={{ marginTop: 24 }}>{children}</div>\n\n <p style={footerStyle}>por Hook</p>\n </div>\n </div>\n );\n}\n\n// --- Shared styles (exported pra reuso nas variants) -------------------\n\nexport const primaryButtonStyle: CSSProperties = {\n width: '100%',\n padding: '14px 20px',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n border: 'none',\n borderRadius: 999,\n fontSize: 17,\n fontWeight: 600,\n cursor: 'pointer',\n marginBottom: 12,\n};\n\nexport const secondaryButtonStyle: CSSProperties = {\n width: '100%',\n padding: '12px 20px',\n background: 'transparent',\n color: 'var(--hook-color-primary)',\n border: '1px solid var(--hook-color-primary)',\n borderRadius: 999,\n fontSize: 15,\n fontWeight: 500,\n cursor: 'pointer',\n marginBottom: 12,\n};\n\nexport const skipLinkStyle: CSSProperties = {\n display: 'block',\n width: '100%',\n padding: '10px',\n marginTop: 8,\n background: 'transparent',\n color: '#555',\n border: 'none',\n fontSize: 14,\n textDecoration: 'underline',\n cursor: 'pointer',\n textAlign: 'center',\n};\n\nexport const skipPermanentLinkStyle: CSSProperties = {\n ...skipLinkStyle,\n color: '#999',\n fontSize: 13,\n marginTop: 4,\n};\n\n// --- Internal layout styles --------------------------------------------\n\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--hook-color-background, #fafafa)',\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 20,\n overflow: 'auto',\n};\n\nconst cardStyle: CSSProperties = {\n width: '100%',\n maxWidth: 420,\n padding: 24,\n textAlign: 'center',\n};\n\nconst titleStyle: CSSProperties = {\n fontSize: 24,\n fontWeight: 700,\n lineHeight: 1.2,\n margin: '0 0 8px 0',\n color: '#111',\n};\n\nconst subtitleStyle: CSSProperties = {\n fontSize: 15,\n lineHeight: 1.4,\n color: '#555',\n margin: 0,\n};\n\nconst footerStyle: CSSProperties = {\n fontSize: 11,\n color: '#aaa',\n marginTop: 32,\n letterSpacing: 0.5,\n};\n","/**\n * SVG icons inline pro InstallGate. Template não depende de lucide-react;\n * copiamos só os 6 necessários (~1.8 KB total minified).\n *\n * Base: ícones de `lucide-react` com ajustes pra iOS share button (precisa\n * estética específica vs o genérico). Paths conferidos com as versões em\n * hook-old.\n */\n\nimport type { CSSProperties } from 'react';\n\ninterface IconProps {\n size?: number;\n style?: CSSProperties;\n 'aria-hidden'?: boolean | 'true' | 'false';\n className?: string;\n}\n\nconst defaultSvgProps = (size: number) => ({\n width: size,\n height: size,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n});\n\n/** iOS Safari share button — square com seta pra cima */\nexport function ShareIconIOS({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M12 2L12 15\" />\n <path d=\"M8 6L12 2L16 6\" />\n <path d=\"M4 11v9a2 2 0 002 2h12a2 2 0 002-2v-9\" />\n </svg>\n );\n}\n\n/** Share genérico — 3 círculos conectados */\nexport function ShareIconGeneric({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"18\" cy=\"5\" r=\"3\" />\n <circle cx=\"6\" cy=\"12\" r=\"3\" />\n <circle cx=\"18\" cy=\"19\" r=\"3\" />\n <path d=\"M8.59 13.51l6.83 3.98\" />\n <path d=\"M15.41 6.51l-6.82 3.98\" />\n </svg>\n );\n}\n\n/** Menu ⋮ (Android Chrome, Facebook) */\nexport function MenuDotsVerticalIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"5\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"19\" r=\"1.5\" />\n </svg>\n );\n}\n\n/** Menu ⋯ (Instagram, TikTok — horizontal) */\nexport function MenuDotsHorizontalIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"5\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"19\" cy=\"12\" r=\"1.5\" />\n </svg>\n );\n}\n\n/** Square + (iOS \"Adicionar à Tela de Início\") */\nexport function SquarePlusIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M12 8v8\" />\n <path d=\"M8 12h8\" />\n </svg>\n );\n}\n\n/** Download (Android Chrome \"Instalar aplicativo\") */\nexport function DownloadIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n );\n}\n\n/** External link (pra in-app \"Abrir no navegador\") */\nexport function ExternalLinkIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n );\n}\n\n/** X (close) */\nexport function XIcon({ size = 20, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { DownloadIcon } from '../icons';\n\nexport function AndroidNativeVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.android.native;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <button\n data-testid=\"install-prompt-cta-android-native\"\n type=\"button\"\n onClick={() => void actions.promptInstall()}\n style={{ ...primaryButtonStyle, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}\n >\n <DownloadIcon size={18} />\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { MenuDotsVerticalIcon, DownloadIcon } from '../icons';\n\nexport function AndroidManualVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.android.manual;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title}>\n <Step n={1} icon={<MenuDotsVerticalIcon size={20} />}>\n {copy.step1}\n </Step>\n <Step n={2} icon={<DownloadIcon size={18} />}>\n {copy.step2}\n </Step>\n\n <button\n data-testid=\"install-prompt-cta-android-manual\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={primaryButtonStyle}\n >\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\nfunction Step({ n, icon, children }: { n: number; icon: React.ReactNode; children: React.ReactNode }) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: '#f5f5f7',\n borderRadius: 12,\n marginBottom: 10,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 14,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1, fontSize: 15, color: '#333' }}>{children}</div>\n <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>\n </div>\n );\n}\n","import { InstallSplash } from '../InstallSplash';\nimport { INSTALL_COPY } from '../copy';\n\n/**\n * AndroidPendingVariant — splash silencioso enquanto aguarda\n * `beforeinstallprompt`. Chrome dispara o evento async (até ~3s pós-load).\n * Mostrando manual imediato + trocando pra native depois cria flash UX.\n *\n * Aqui não renderizamos CTA: nem botão \"Instalar\" (sem evento ainda)\n * nem instruções manuais (podemos receber o evento e ter botão real).\n * Mostra só ícone + título do app + spinner sutil. Variant é trocado\n * automaticamente pra android-native ou android-manual em até 3s.\n */\nexport function AndroidPendingVariant() {\n const copy = INSTALL_COPY.android.native;\n return (\n <InstallSplash title={copy.title}>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 16,\n padding: '24px 0',\n }}\n >\n <Spinner />\n </div>\n </InstallSplash>\n );\n}\n\nfunction Spinner() {\n return (\n <div\n aria-hidden\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n border: '3px solid #e5e5e7',\n borderTopColor: 'var(--hook-color-primary)',\n animation: 'hook-install-spin 0.8s linear infinite',\n }}\n >\n <style>{`@keyframes hook-install-spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function Step({\n n,\n title,\n subtitle,\n visual,\n}: {\n n: number;\n title: string;\n subtitle?: string;\n visual?: ReactNode;\n}) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 12,\n marginBottom: 16,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 32,\n height: 32,\n borderRadius: 10,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 15,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1 }}>\n <p style={{ margin: 0, fontSize: 15, fontWeight: 500, color: '#111', lineHeight: 1.3 }}>\n {title}\n </p>\n {subtitle && (\n <p style={{ margin: '4px 0 0 0', fontSize: 13, color: '#777' }}>{subtitle}</p>\n )}\n {visual}\n </div>\n </div>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport { InstallSplash, skipLinkStyle, skipPermanentLinkStyle } from '../InstallSplash';\nimport { ShareIconIOS, SquarePlusIcon } from '../icons';\nimport { Step } from '../Step';\n\nexport function IOSafariVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.iosSafari;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <Step\n n={1}\n title={copy.step1.title}\n subtitle={copy.step1.subtitle}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 0',\n marginTop: 8,\n }}\n >\n <ShareIconIOS size={32} style={{ color: 'var(--hook-color-primary)' }} />\n </div>\n }\n />\n\n <Step\n n={2}\n title={copy.step2.title}\n visual={\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 14px',\n marginTop: 8,\n }}\n >\n <SquarePlusIcon size={22} style={{ color: '#555' }} />\n <span style={{ fontSize: 14, color: '#333' }}>{copy.step2.iconLabel}</span>\n </div>\n }\n />\n\n <Step\n n={3}\n title={copy.step3.title}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '10px 14px',\n marginTop: 8,\n }}\n >\n <span\n style={{\n color: 'var(--hook-color-primary)',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {copy.step3.buttonLabel}\n </span>\n </div>\n }\n />\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={{ ...skipLinkStyle, marginTop: 16 }}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport { InstallSplash, skipLinkStyle, skipPermanentLinkStyle } from '../InstallSplash';\nimport { ShareIconIOS, SquarePlusIcon } from '../icons';\nimport { Step } from '../Step';\n\nexport function IOSOtherVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.iosOther;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <Step\n n={1}\n title={copy.step1.title}\n subtitle={copy.step1.subtitle}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 0',\n marginTop: 8,\n }}\n >\n <ShareIconIOS size={32} style={{ color: 'var(--hook-color-primary)' }} />\n </div>\n }\n />\n\n <Step\n n={2}\n title={copy.step2.title}\n visual={\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 14px',\n marginTop: 8,\n }}\n >\n <SquarePlusIcon size={22} style={{ color: '#555' }} />\n <span style={{ fontSize: 14, color: '#333' }}>{copy.step2.iconLabel}</span>\n </div>\n }\n />\n\n <Step\n n={3}\n title={copy.step3.title}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '10px 14px',\n marginTop: 8,\n }}\n >\n <span\n style={{\n color: 'var(--hook-color-primary)',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {copy.step3.buttonLabel}\n </span>\n </div>\n }\n />\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={{ ...skipLinkStyle, marginTop: 16 }}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n","import { useState } from 'react';\nimport type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { MenuDotsHorizontalIcon, MenuDotsVerticalIcon, ExternalLinkIcon } from '../icons';\n\nexport function InAppBrowserVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const app = state.inAppApp ?? 'other';\n const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;\n const copy = INSTALL_COPY.inApp;\n const showPermanent = shouldShowPermanentOption(state);\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await actions.copyLink();\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n // Ícone varia: FB/Telegram usam ⋮; Instagram/TikTok/Twitter/LinkedIn/Pinterest usam ⋯\n const DotsIcon =\n app === 'facebook' || app === 'telegram' ? MenuDotsVerticalIcon : MenuDotsHorizontalIcon;\n\n return (\n <InstallSplash title={appCopy.title}>\n <Step n={1} icon={<DotsIcon size={20} />}>\n {appCopy.step1}\n </Step>\n <Step n={2} icon={<ExternalLinkIcon size={18} />}>\n {appCopy.step2}\n </Step>\n\n <button\n data-testid=\"install-prompt-cta-inapp-copy\"\n type=\"button\"\n onClick={() => void handleCopy()}\n style={{ ...primaryButtonStyle, marginTop: 8 }}\n >\n {copied ? copy.copiedToast : copy.copy}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\nfunction Step({\n n,\n icon,\n children,\n}: {\n n: number;\n icon: React.ReactNode;\n children: React.ReactNode;\n}) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: '#f5f5f7',\n borderRadius: 12,\n marginBottom: 10,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 14,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1, fontSize: 14, color: '#333' }}>{children}</div>\n <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\nimport type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { useTemplateConfig } from '../../../internal/TemplateConfigContext';\nimport { INSTALL_COPY } from '../copy';\nimport { DownloadIcon, XIcon } from '../icons';\n\n/**\n * Desktop variant — NÃO-bloqueante. Banner soft no canto inferior direito.\n * Só aparece se `beforeinstallprompt` disparou (Chrome/Edge desktop).\n */\nexport function DesktopVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const { name, theme } = useTemplateConfig();\n const copy = INSTALL_COPY.desktop;\n const iconUrl = theme.icon_url || theme.logo_url || null;\n\n // Guard defensivo: só renderiza se installable\n if (!state.isInstallable) return null;\n\n return (\n <div\n role=\"complementary\"\n aria-label={copy.title}\n style={bannerStyle}\n >\n {iconUrl ? (\n <img\n src={iconUrl}\n alt=\"\"\n style={{ width: 40, height: 40, borderRadius: 10, objectFit: 'cover', flexShrink: 0 }}\n />\n ) : (\n <div\n style={{\n width: 40,\n height: 40,\n borderRadius: 10,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 18,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n )}\n\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 14, fontWeight: 600, color: '#111' }}>{copy.title}</div>\n <div style={{ fontSize: 12, color: '#666' }}>{copy.subtitle}</div>\n </div>\n\n <button\n data-testid=\"install-prompt-cta-desktop\"\n type=\"button\"\n onClick={() => void actions.promptInstall()}\n style={{\n padding: '8px 14px',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n border: 'none',\n borderRadius: 999,\n fontSize: 13,\n fontWeight: 600,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n flexShrink: 0,\n }}\n >\n <DownloadIcon size={14} />\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-desktop-close\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n aria-label={copy.close}\n style={{\n background: 'transparent',\n border: 'none',\n cursor: 'pointer',\n color: '#888',\n padding: 4,\n flexShrink: 0,\n }}\n >\n <XIcon size={16} />\n </button>\n </div>\n );\n}\n\nconst bannerStyle: CSSProperties = {\n position: 'fixed',\n bottom: 24,\n right: 24,\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 16px',\n background: '#fff',\n border: '1px solid rgba(0,0,0,0.08)',\n borderRadius: 16,\n boxShadow: '0 10px 30px rgba(0,0,0,0.12)',\n maxWidth: 400,\n};\n","// Side-effect-only component: observa estado e dispara push.subscribe() quando\n// apropriado. NUNCA renderiza UI bloqueante — sempre retorna null. No MVP, o SDK\n// stub de push lança 'unsupported_mvp', então este componente não faz nada.\n// Quando P14 entregar VAPID real, adicionar gate por 2ª sessão + dismissed_at.\nexport function PushPrompt() {\n return null;\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nconst DISMISS_KEY = 'hook:session-expired-dismissed-until';\nconst DISMISS_TTL_MS = 60 * 60 * 1000; // 1h\n\n/**\n * SessionExpiredBanner — Wave 4 Fix #27.\n *\n * Surfaces \"Sua sessão expirou\" when the SDK transitions from\n * authenticated → anonymous. Cold-mount anonymous (no prior session)\n * stays silent because that's the expected first-page-load state.\n *\n * Mounted from AppRoot.tsx (golden-path) so every template-consuming app\n * inherits the UX. Apps that need a different banner can fork the file\n * post-eject; the base template is informational only — actual redirect\n * to /login is handled by AuthGated routing already.\n */\nexport function SessionExpiredBanner() {\n const { authStatus } = useHook() as { authStatus?: string };\n const wasAuthRef = useRef(false);\n const [show, setShow] = useState(false);\n\n useEffect(() => {\n if (authStatus === 'authenticated') {\n wasAuthRef.current = true;\n setShow(false);\n return;\n }\n if (authStatus === 'anonymous' && wasAuthRef.current) {\n const until = Number(localStorage.getItem(DISMISS_KEY) ?? '0');\n if (Date.now() < until) {\n setShow(false);\n return;\n }\n setShow(true);\n }\n }, [authStatus]);\n\n if (!show) return null;\n\n function dismiss() {\n localStorage.setItem(DISMISS_KEY, String(Date.now() + DISMISS_TTL_MS));\n setShow(false);\n }\n\n return (\n <div role=\"alert\" className=\"fixed top-0 inset-x-0 bg-red-600 text-white px-4 py-2 flex items-center justify-between gap-3 text-sm shadow\" style={{ zIndex: 10001 }}>\n <span>\n <strong>Sua sessão expirou.</strong> Faça login novamente para continuar.\n </span>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={dismiss}\n className=\"px-3 py-1 bg-white text-red-700 rounded text-xs font-medium hover:bg-red-50\"\n >\n Fazer login\n </button>\n <button\n type=\"button\"\n onClick={dismiss}\n aria-label=\"Fechar\"\n className=\"px-2 py-1 text-white/80 hover:text-white text-xs\"\n >\n Fechar\n </button>\n </div>\n </div>\n );\n}\n","/**\n * EmailVerifyBanner — sticky top banner shown to authenticated users\n * whose `emailVerified === false`. Disappears automatically when the\n * user clicks the email-verify link and `/auth/me` reflects the change.\n *\n * Mounted from AppRoot.tsx (golden-path) inside the AuthGated tree, so\n * every template-consuming app inherits the UX without app-side wiring.\n *\n * Copy is hardcoded pt-BR for MVP (both shipped apps are pt-BR-only).\n * i18n integration is a future-iteration concern once a second locale\n * ships.\n *\n * Design: spec 2026-05-13-signup-ux-email-verify-banner-design.md.\n */\nimport { useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport function EmailVerifyBanner() {\n const { user, auth } = useHook();\n const [sending, setSending] = useState(false);\n const [sent, setSent] = useState(false);\n\n if (!user || user.emailVerified) return null;\n\n async function handleResend() {\n if (sending || sent) return;\n setSending(true);\n try {\n await auth.resendVerify();\n setSent(true);\n } catch {\n // Silent fail per spec: banner is low-stakes. User can click again.\n } finally {\n setSending(false);\n }\n }\n\n const label = sent ? 'Enviado!' : sending ? 'Enviando...' : 'Reenviar link';\n\n return (\n <div\n role=\"status\"\n data-testid=\"email-verify-banner\"\n 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\"\n >\n <span>Confirma teu e-mail pra liberar tudo.</span>\n <button\n type=\"button\"\n onClick={handleResend}\n disabled={sending || sent}\n 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\"\n >\n {label}\n </button>\n </div>\n );\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error, info: { componentStack: string }) {\n // Spread error.message + stack as plain strings so browsers print them\n // inline (default behavior with a bare Error logs only the constructor\n // name \"Error\" until the dev clicks to expand the object — fine in\n // dev, useless when triaging from a screenshotted prod console).\n console.error(\n '[ErrorBoundary] caught:',\n error?.message || '(no message)',\n '\\nstack:',\n error?.stack || '(no stack)',\n '\\ncomponentStack:',\n info?.componentStack || '(no componentStack)',\n );\n }\n\n render() {\n if (this.state.error) {\n return this.props.fallback ?? (\n <div role=\"alert\" style={{ padding: 24, textAlign: 'center' }}>\n <h2>Algo deu errado</h2>\n <p style={{ opacity: 0.7 }}>Recarregue a página pra tentar de novo.</p>\n </div>\n );\n }\n return <>{this.props.children}</>;\n }\n}\n","/**\n * I18nProvider — react-i18next wiring for Hook apps.\n *\n * Mounted internally by <AppRoot> when `config.i18n` is present (see\n * spec rev 14 §13 #18 + plan T6.2). User-locale persists via the SDK's\n * usePersistedState under the key `user-locale`, so it survives reload\n * and propagates across tabs (best-effort).\n *\n * Implementation notes:\n * - i18n is initialised once per module load (i18next is a singleton).\n * We initialise synchronously the first time the provider renders so\n * the very first paint already has translations (no flash of keys / no\n * Suspense fallback).\n * - Subsequent locale changes go through `i18n.changeLanguage` from a\n * useEffect, so React state stays the source of truth.\n * - Resources are passed as a flat `{ locale: { key: string } }` map; we\n * wrap them in the i18next-expected `{ translation: ... }` namespace.\n * - We do NOT use the languagedetector plugin here even though the\n * package is declared in dependencies — Hook drives locale exclusively\n * from `usePersistedState` so the source of truth is consistent across\n * the app. The dep is shipped per plan so apps may opt in via a custom\n * provider.\n */\nimport { useEffect, type ReactNode } from 'react';\nimport i18n from 'i18next';\nimport { I18nextProvider, initReactI18next } from 'react-i18next';\nimport { usePersistedState } from '@hook-sdk/sdk';\n\nexport interface I18nProviderProps {\n defaultLocale: string;\n supportedLocales: string[];\n resources: Record<string, Record<string, string>>;\n children: ReactNode;\n}\n\nfunction ensureInitialized(\n defaultLocale: string,\n supportedLocales: string[],\n resources: Record<string, Record<string, string>>,\n initialLocale: string,\n) {\n if (i18n.isInitialized) return;\n i18n.use(initReactI18next).init({\n resources: Object.fromEntries(\n supportedLocales.map((l) => [l, { translation: resources[l] ?? {} }]),\n ),\n lng: initialLocale,\n fallbackLng: defaultLocale,\n interpolation: { escapeValue: false },\n // useTranslation suspends by default until i18next is \"ready\". Inline\n // resources are sync, so suspending creates a guaranteed empty render\n // tick — confusing in apps and breaks tests that don't use Suspense.\n react: { useSuspense: false },\n });\n}\n\nexport function I18nProvider({\n defaultLocale,\n supportedLocales,\n resources,\n children,\n}: I18nProviderProps) {\n const [userLocale] = usePersistedState<string>('user-locale', defaultLocale);\n\n // Synchronous init on the first render (idempotent) so the initial paint\n // already has translations — no Suspense fallback, no flash of keys.\n ensureInitialized(defaultLocale, supportedLocales, resources, userLocale);\n\n useEffect(() => {\n if (i18n.isInitialized && i18n.language !== userLocale) {\n i18n.changeLanguage(userLocale);\n }\n }, [userLocale]);\n\n return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>;\n}\n","/**\n * Runtime gate for dev-only tools (e.g. <DevSkipOnboardingFab>).\n *\n * History:\n * v0.23.0 / v0.23.1 also gated on `import.meta.env.VITE_HOOK_DEV_TOOLS`.\n * That was intended as a build-time DCE signal so the dev module would\n * tree-shake out of prod bundles. Empirically vite's static replacement\n * does NOT apply to template code consumed from node_modules when the\n * creator app uses `build.lib` mode — every consumer ended up with\n * `undefined !== '1'` → DCE killed the FAB from STAGING bundles too.\n *\n * Pragmatic fix: drop the env gate and rely on the runtime hostname\n * check alone. The FAB code now ships in prod bundles too (~5 KB), but\n * it never renders on prod hostnames because `.staging.` / `localhost`\n * is the only path that returns `true`. Visual safety = hostname check\n * at render. Compliance / privacy = no real user can ever trigger the\n * auto-signup branch on a `usehook.net` (prod) origin.\n *\n * If a creator app wants the build-time DCE back, the consumer's\n * `vite.config.ts` `define` block must explicitly substitute\n * `import.meta.env.VITE_HOOK_DEV_TOOLS` — vite's auto-replacement skips\n * `node_modules` in lib mode.\n */\nexport function isDevToolsEnabled(): boolean {\n if (typeof window === 'undefined') return false;\n\n const host = window.location.hostname;\n // `staging.usehook.net` is the shell-served URL (apps live under\n // `/app/<slug>/`); `*.staging.usehook.net` covers any future per-app\n // staging subdomain. The substring match catches both. Earlier versions\n // only checked `.staging.` (dots on both sides) which missed the shell\n // root.\n return (\n host.includes('staging.usehook.net') ||\n host === 'localhost' ||\n host === '127.0.0.1'\n );\n}\n","/**\n * Staging-only \"skip onboarding\" floating button.\n *\n * Mounted by <AppRoot> when `isDevToolsEnabled()` is true AND the\n * `devSkipOnboarding` prop is passed. The whole module is intended to be\n * tree-shaken from prod bundles via the build-time env replacement in\n * `./env.ts` — never reference it from prod code paths.\n *\n * See `docs/superpowers/specs/2026-05-12-dev-skip-onboarding-fab-design.md`\n * (mirrored into `/Users/ryan/.claude/plans/for-all-of-the-replicated-planet.md`)\n * for the full design + safety gates.\n */\nimport { useCallback, useRef, useState } from 'react';\nimport { useHook, usePersistedState, type HookContextValue } from '@hook-sdk/sdk';\nimport { useAppConfig } from '../config/AppConfigContext';\n\nexport interface SkipDefaults {\n /**\n * Final flag the host app's ProtectedRoute reads. If unset here, the helper\n * forces it to `true` after merging defaults.\n */\n onboarding_completed?: boolean;\n /**\n * Free-form per-app fields (userName, mainGoal, faixa, kids[], etc.). The\n * helper merges this object verbatim into `appData.set('onboarding_data', …)`.\n */\n [field: string]: unknown;\n /**\n * Optional per-app seed callback. Use to insert anything that lives outside\n * `onboarding_data` (e.g. seed first workout in `hook.db.collection('workouts')`).\n * Awaited after `appData.set` and before the hard reload.\n */\n __seed?: (hook: HookContextValue) => Promise<void>;\n}\n\nconst STORAGE_KEY = 'hook_dev_skip_email';\nconst TEST_EMAIL_DOMAIN = '@hook.test';\nconst TEST_PASSWORD = 'SkipTest!2026';\n\nfunction makeEmail(): string {\n return `ryan+skip-${Date.now()}${TEST_EMAIL_DOMAIN}`;\n}\n\n/**\n * Try to sign up a fresh test user. Retries on 409 (email collision) by\n * rotating the timestamp suffix. Throws after `maxAttempts` retries.\n */\nasync function ensureSignedIn(hook: HookContextValue, maxAttempts = 3): Promise<string | null> {\n if (hook.authStatus === 'authenticated') return null;\n\n let lastErr: unknown;\n for (let i = 0; i < maxAttempts; i += 1) {\n const email = makeEmail();\n try {\n await hook.auth.signup({ email, password: TEST_PASSWORD, name: 'Ryan Test' });\n try {\n window.sessionStorage.setItem(STORAGE_KEY, email);\n } catch {\n // ignore — sessionStorage may be unavailable in some test envs\n }\n return email;\n } catch (err) {\n lastErr = err;\n // Slight jitter then retry; the next loop creates a new timestamp.\n await new Promise((r) => setTimeout(r, 30));\n }\n }\n throw lastErr ?? new Error('signup failed after retries');\n}\n\n/**\n * Programmatic skip helper. Exposed for advanced consumers / tests; the FAB\n * just calls this on confirm.\n */\nexport async function skipOnboarding(\n hook: HookContextValue,\n defaults: SkipDefaults,\n appSlug: string,\n): Promise<void> {\n const { __seed, ...rest } = defaults;\n await ensureSignedIn(hook);\n await hook.appData.set('onboarding_data', {\n ...rest,\n onboarding_completed: true,\n });\n if (__seed) {\n await __seed(hook);\n }\n // Dev-tool fire log. Stays out of PostHog allowlist so this module pulls\n // zero analytics-events surface (and remains tree-shake-friendly). If we\n // ever need a prod-tripwire telemetry signal, add `dev_skip_onboarding`\n // to `analytics-events.ts` ALLOWED_EVENTS and swap this for `hook.track`.\n // eslint-disable-next-line no-console\n console.info('[hook-template] dev_skip_onboarding fired', {\n app_slug: appSlug,\n hostname: window.location.hostname,\n });\n // Hard reload to the app's home so the post-auth providers re-mount with\n // fresh state. Router navigate is not enough — pre-auth providers may have\n // already captured an anonymous-flow snapshot.\n window.location.assign(`/app/${appSlug}/`);\n}\n\nconst STYLES = {\n base: {\n position: 'fixed',\n bottom: '16px',\n right: '16px',\n zIndex: 2147483647,\n padding: '10px 14px',\n borderRadius: '999px',\n border: 'none',\n background: '#F59E0B',\n color: '#111827',\n fontWeight: 600,\n fontSize: '13px',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n boxShadow: '0 4px 14px rgba(0, 0, 0, 0.25)',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n } as const,\n confirm: { background: '#DC2626', color: '#FFFFFF' } as const,\n busy: { opacity: 0.6, cursor: 'wait' } as const,\n};\n\ntype FabState = 'idle' | 'confirm' | 'busy' | 'error';\n\nconst CONFIRM_TIMEOUT_MS = 3000;\n\nexport function DevSkipOnboardingFab({ defaults }: { defaults: SkipDefaults }) {\n const hook = useHook();\n const { slug } = useAppConfig();\n const [state, setState] = useState<FabState>('idle');\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Reactively read onboarding state to hide the FAB once the user has crossed\n // onboarding. Pre-auth visitors keep seeing it (auto-signup branch handles\n // the rest of the skip). `enabled: false` pre-auth so we don't fire 401s on\n // the appData fetch.\n const isAuthed = hook.authStatus === 'authenticated';\n const [onboarding] = usePersistedState<{ onboarding_completed?: boolean } | null>(\n 'onboarding_data',\n null,\n { enabled: isAuthed },\n );\n const onboardingCompleted =\n isAuthed && onboarding?.onboarding_completed === true;\n\n const clearTimer = useCallback(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n\n const onClick = useCallback(async () => {\n if (state === 'busy') return;\n\n if (state === 'idle' || state === 'error') {\n setState('confirm');\n setErrorMsg(null);\n clearTimer();\n timerRef.current = setTimeout(() => setState('idle'), CONFIRM_TIMEOUT_MS);\n return;\n }\n\n // state === 'confirm' → execute\n clearTimer();\n setState('busy');\n try {\n await skipOnboarding(hook, defaults, slug);\n // window.location.assign navigates away; this line typically never runs.\n } catch (err) {\n setState('error');\n setErrorMsg(err instanceof Error ? err.message : String(err));\n }\n }, [state, hook, defaults, slug, clearTimer]);\n\n const label = (() => {\n if (state === 'busy') return 'skipping…';\n if (state === 'confirm') return 'tap again to confirm';\n if (state === 'error') return `failed — tap to retry`;\n return hook.authStatus === 'authenticated' ? '⚡ skip onboarding' : '⚡ skip + signup';\n })();\n\n // Hide once the user is past onboarding. By definition there's nothing\n // left to skip; keeping the FAB visible adds noise on every post-onboarding\n // screen.\n if (onboardingCompleted) return null;\n\n const style = {\n ...STYLES.base,\n ...(state === 'confirm' || state === 'error' ? STYLES.confirm : {}),\n ...(state === 'busy' ? STYLES.busy : {}),\n };\n\n return (\n <button\n type=\"button\"\n data-testid=\"dev-skip-onboarding-fab\"\n aria-label=\"Skip onboarding (staging dev only)\"\n style={style}\n onClick={onClick}\n title={errorMsg ?? undefined}\n >\n {label}\n </button>\n );\n}\n","import { useCallback, useEffect, useRef, useState, type CSSProperties, type ReactNode } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\n/**\n * Detecta `?paymentReturn=1` na URL (usuário voltando do checkout Asaas) e\n * polla `subscription.refresh()` com backoff exponencial (2s, 5s, 10s, 20s, 40s\n * — total ~77s) até status ∈ {active, trialing}.\n *\n * Regras de projeto (2026-04-21, pós-incidente QA papomaterno):\n *\n * - **Effect `[]`**: nunca `[subscription]`. O objeto `subscription` é\n * referencialmente memoizado pelo SDK mas re-memoiza a cada mudança de\n * `sub` (quando `/me` resolve). Re-dispara em cada render causava storm\n * exponencial (258→654 req em 20s observados em QA). Lemos a última\n * referência via `subRef.current` e rodamos o polling só 1× por mount.\n *\n * - **Backoff** em vez de 1s constante: evita martelar o backend quando\n * webhook atrasa e respeita o orçamento de ~77s total (cobre p99 observado\n * em staging). `http.ts` já respeita `Retry-After` em 429, mas backoff\n * reduz a chance de bater o rate limit em primeiro lugar.\n *\n * - **Aceita `trialing`** além de `active`: em `mode=pay_first` post-checkout\n * vira ACTIVE; em `mode=trial` o backend pode manter TRIAL com\n * trial_ends_at avançado. Ambos = libera o gate (`SubscriptionGate` trata\n * os dois como non-blocking).\n *\n * - **Timeout → estado `waiting` bloqueante com botão \"Atualizar\"**: se a\n * gente renderizasse children, o `SubscriptionGate` mostraria paywall de\n * novo (status=none sem subscription row) — user cliparia \"Pagar\" em\n * looping. Bloquear é menos ruim.\n *\n * - **Wave 5 #12 — escape após 3 retries**: cada ciclo (initial + 2 retries\n * via \"Atualizar\") esgota o backoff. Ao terminar o 3º ciclo sem\n * `active|trialing`, sai pro estado `timeout` com 3 botões:\n * • \"Tentar de novo\" → recomeça o polling.\n * • \"Voltar pro app\" → navega `/app/home` + remove `paymentReturn`.\n * • \"Falar com suporte\" → mailto. Evita user travado em looping de\n * \"Atualizar\" se o webhook não chegar nunca.\n *\n * Precisa estar dentro de <HookProvider> (fornecido pelo shell).\n * Exportado para teste isolado.\n */\nconst BACKOFF_MS = [2_000, 5_000, 10_000, 20_000, 40_000] as const; // ~77s total\nconst MAX_CYCLES = 3 as const;\nconst SUPPORT_MAILTO = 'mailto:suporte@usehook.net?subject=Pagamento%20pendente';\n\ntype ReturnState = 'idle' | 'confirming' | 'waiting' | 'timeout';\n\nexport function PaymentReturnHandler({ children }: { children: ReactNode }) {\n const { subscription, track } = useHook();\n const subRef = useRef(subscription);\n subRef.current = subscription;\n const runIdRef = useRef(0);\n const cyclesRef = useRef(0);\n const startMsRef = useRef(0);\n const [state, setState] = useState<ReturnState>('idle');\n\n const runPoll = useCallback(() => {\n const runId = ++runIdRef.current;\n // isFirstRun gates `payment_confirmation_started` to the first cycle of\n // a session (cyclesRef === 0). Cycles 2 and 3 — re-entries via the\n // \"Atualizar\" button after a backoff exhaust — do NOT re-fire `_started`.\n // After MAX_CYCLES exhausts and the user clicks \"Tentar de novo\",\n // cyclesRef is reset to 0 and `_started` fires again, by design: each\n // retry session is treated as a fresh confirmation attempt in PostHog.\n // `total_duration_ms` therefore measures the *current* session, not the\n // lifetime from the initial paymentReturn=1.\n const isFirstRun = cyclesRef.current === 0;\n cyclesRef.current += 1;\n if (isFirstRun) {\n startMsRef.current = Date.now();\n track('payment_confirmation_started', {});\n }\n setState('confirming');\n let attempts = 0;\n\n const tick = async () => {\n if (runIdRef.current !== runId) return;\n attempts++;\n try {\n await subRef.current.refresh();\n } catch {\n // swallow — http.ts já honra Retry-After em 429 e retry em 5xx.\n }\n if (runIdRef.current !== runId) return;\n const status = subRef.current.status();\n if (status === 'active' || status === 'trialing') {\n track('payment_confirmation_succeeded', {\n cycle_count: cyclesRef.current,\n attempt_count: attempts,\n duration_ms: Date.now() - startMsRef.current,\n });\n const cleanUrl = new URL(window.location.href);\n cleanUrl.searchParams.delete('paymentReturn');\n window.history.replaceState({}, '', cleanUrl.toString());\n cyclesRef.current = 0;\n setState('idle');\n return;\n }\n const delay = BACKOFF_MS[attempts - 1];\n if (delay === undefined) {\n if (cyclesRef.current >= MAX_CYCLES) {\n track('payment_confirmation_timed_out', {\n total_duration_ms: Date.now() - startMsRef.current,\n });\n setState('timeout');\n } else {\n setState('waiting');\n }\n return;\n }\n setTimeout(tick, delay);\n };\n void tick();\n }, [track]);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const url = new URL(window.location.href);\n if (url.searchParams.get('paymentReturn') !== '1') return;\n cyclesRef.current = 0;\n runPoll();\n return () => {\n // Invalida o run ativo — qualquer tick() pendente vai ver runId velho\n // e retornar sem tocar state. Cobre unmount e StrictMode double-invoke.\n runIdRef.current++;\n };\n }, [runPoll]);\n\n const goHome = useCallback(() => {\n const cleanUrl = new URL(window.location.href);\n cleanUrl.searchParams.delete('paymentReturn');\n cleanUrl.pathname = '/app/home';\n window.location.href = cleanUrl.toString();\n }, []);\n\n if (state === 'confirming') {\n return (\n <div role=\"status\" aria-live=\"polite\" style={overlayStyle}>\n Confirmando pagamento…\n </div>\n );\n }\n\n if (state === 'waiting') {\n return (\n <div role=\"status\" aria-live=\"polite\" style={overlayStyle}>\n <div style={{ maxWidth: 320, textAlign: 'center', lineHeight: 1.5 }}>\n <div style={{ marginBottom: 16 }}>\n Pagamento aceito. Estamos confirmando com o banco — pode levar\n alguns minutos.\n </div>\n <button type=\"button\" onClick={runPoll} style={buttonStyle}>\n Atualizar\n </button>\n </div>\n </div>\n );\n }\n\n if (state === 'timeout') {\n return (\n <div role=\"alert\" aria-live=\"assertive\" style={overlayStyle}>\n <div style={{ maxWidth: 360, textAlign: 'center', lineHeight: 1.5 }}>\n <div style={{ marginBottom: 16 }}>\n Ainda não conseguimos confirmar seu pagamento com o banco. Você\n pode tentar de novo, voltar pro app, ou falar com a gente.\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n <button\n type=\"button\"\n onClick={() => {\n cyclesRef.current = 0;\n runPoll();\n }}\n style={buttonStyle}\n data-testid=\"payment-timeout-retry\"\n >\n Tentar de novo\n </button>\n <button\n type=\"button\"\n onClick={goHome}\n style={secondaryButtonStyle}\n data-testid=\"payment-timeout-home\"\n >\n Voltar pro app\n </button>\n <a\n href={SUPPORT_MAILTO}\n style={linkStyle}\n data-testid=\"payment-timeout-support\"\n >\n Falar com suporte\n </a>\n </div>\n </div>\n </div>\n );\n }\n\n return <>{children}</>;\n}\n\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'rgba(0,0,0,0.4)',\n zIndex: 9999,\n color: 'white',\n fontSize: '1rem',\n padding: 24,\n};\n\nconst buttonStyle: CSSProperties = {\n background: 'white',\n color: 'black',\n border: 'none',\n borderRadius: 8,\n padding: '10px 24px',\n fontSize: '1rem',\n fontWeight: 600,\n cursor: 'pointer',\n};\n\nconst secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'transparent',\n color: 'white',\n border: '1px solid rgba(255,255,255,0.5)',\n};\n\nconst linkStyle: CSSProperties = {\n color: 'white',\n textDecoration: 'underline',\n fontSize: '0.9rem',\n marginTop: 4,\n textAlign: 'center',\n};\n","import { useCallback, useEffect, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport type PushUiState =\n | { kind: 'unsupported' }\n | { kind: 'ios_needs_install' }\n | { kind: 'prompt' }\n | { kind: 'subscribed' }\n | { kind: 'denied' }\n | { kind: 'dismissed' }\n | { kind: 'error'; code: string; message: string };\n\n// Audit Wave 3 — Fix #32. Dismiss persists 7 days via localStorage so the\n// prompt doesn't re-render every page load. Mirrors useInstallPrompt's\n// dismissPermanent pattern (per-device; push permission is per-device too).\nconst DISMISS_STORAGE_KEY = 'push:dismissed-until';\nconst DISMISS_TTL_MS = 7 * 24 * 60 * 60 * 1000;\n\nfunction detectIosNeedsInstall(): boolean {\n if (typeof navigator === 'undefined' || typeof window === 'undefined') return false;\n const ua = navigator.userAgent || '';\n const isIos = /iPhone|iPad|iPod/.test(ua);\n if (!isIos) return false;\n const mm = window.matchMedia?.('(display-mode: standalone)');\n const standalone = mm?.matches === true;\n // @ts-expect-error — legacy iOS property\n const legacyStandalone = typeof navigator.standalone === 'boolean' ? navigator.standalone : false;\n return !(standalone || legacyStandalone);\n}\n\nfunction readDismissedUntil(): number | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(DISMISS_STORAGE_KEY);\n if (raw === null) return null;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) ? n : null;\n } catch {\n return null;\n }\n}\n\nfunction isDismissedNow(): boolean {\n const until = readDismissedUntil();\n return until !== null && until > Date.now();\n}\n\nfunction deriveState(push: ReturnType<typeof useHook>['push']): PushUiState {\n if (!push.isAvailable()) {\n if (detectIosNeedsInstall()) return { kind: 'ios_needs_install' };\n return { kind: 'unsupported' };\n }\n const status = push.status();\n if (status === 'granted') return { kind: 'subscribed' };\n if (status === 'denied') return { kind: 'denied' };\n if (status === 'unsupported') {\n if (detectIosNeedsInstall()) return { kind: 'ios_needs_install' };\n return { kind: 'unsupported' };\n }\n // status === 'prompt' — gate by dismiss TTL so dismissed users don't see\n // the prompt re-render on every page load.\n if (isDismissedNow()) return { kind: 'dismissed' };\n return { kind: 'prompt' };\n}\n\nexport function usePush() {\n const { push } = useHook();\n const [state, setState] = useState<PushUiState>(() => deriveState(push));\n\n useEffect(() => { setState(deriveState(push)); }, [push]);\n\n const subscribe = useCallback(async () => {\n try {\n await push.subscribe();\n setState({ kind: 'subscribed' });\n } catch (e: any) {\n const code = e?.code ?? 'push.unknown';\n const message = e?.message ?? 'Push subscription failed';\n if (code === 'push.permission_denied') setState({ kind: 'denied' });\n else setState({ kind: 'error', code, message });\n throw e;\n }\n }, [push]);\n\n const unsubscribe = useCallback(async () => {\n try {\n await push.unsubscribe();\n setState({ kind: 'prompt' });\n } catch (e: any) {\n setState({ kind: 'error', code: e?.code ?? 'push.unknown', message: e?.message ?? 'failed' });\n throw e;\n }\n }, [push]);\n\n const dismiss = useCallback(() => {\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS));\n } catch {\n // localStorage quota exceeded or sandboxed iframe — best-effort.\n }\n }\n setState({ kind: 'dismissed' });\n }, []);\n\n return { state, subscribe, unsubscribe, dismiss };\n}\n","import { usePush } from '../hooks/usePush';\n\nexport interface PushPromptTexts {\n cta: string;\n declineCta: string;\n iosInstallTitle: string;\n iosInstallBody: string;\n iosInstallCta?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedTitle?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedBody?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedRecoveryIos?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedRecoveryAndroid?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedRecoveryDesktop?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedRecoveryInApp?: string;\n unsupportedBody: string;\n}\n\nexport interface PushPromptProps {\n texts: PushPromptTexts;\n onSubscribed?: () => void;\n onDeclined?: () => void;\n onInstallRequested?: () => void;\n className?: string;\n}\n\nexport function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequested, className }: PushPromptProps) {\n const { state, subscribe } = usePush();\n\n // Hook policy: never nag on `denied`. The browser-level block is sticky and\n // a banner cannot recover it — the user must flip permission via browser\n // settings. Rendering a persistent banner is noise. `dismissed`/`subscribed`\n // also no-render (Fix #32: dismiss honors a 7d TTL inside usePush).\n if (state.kind === 'denied' || state.kind === 'dismissed' || state.kind === 'subscribed') {\n return null;\n }\n\n if (state.kind === 'ios_needs_install') {\n return (\n <div className={className} role=\"region\" aria-label={texts.iosInstallTitle}>\n {onDeclined && (\n <button\n type=\"button\"\n onClick={onDeclined}\n aria-label=\"Fechar\"\n className=\"push-prompt-close\"\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n width: 32,\n height: 32,\n border: 'none',\n background: 'transparent',\n fontSize: 20,\n lineHeight: 1,\n cursor: 'pointer',\n color: 'inherit',\n }}\n >\n ×\n </button>\n )}\n <h3>{texts.iosInstallTitle}</h3>\n <p>{texts.iosInstallBody}</p>\n {onInstallRequested && texts.iosInstallCta && (\n <button onClick={onInstallRequested}>{texts.iosInstallCta}</button>\n )}\n </div>\n );\n }\n\n if (state.kind === 'unsupported') {\n return (\n <div className={className} role=\"region\">\n <p>{texts.unsupportedBody}</p>\n </div>\n );\n }\n\n if (state.kind === 'error') {\n return (\n <div className={className} role=\"region\" aria-label=\"error\">\n <p>{state.message}</p>\n </div>\n );\n }\n\n // kind === 'prompt'\n return (\n <div className={className} role=\"region\">\n <button\n type=\"button\"\n onClick={async () => {\n try {\n await subscribe();\n onSubscribed?.();\n } catch {\n // state is already set to 'denied' or 'error' by usePush.subscribe\n }\n }}\n >\n {texts.cta}\n </button>\n {onDeclined && (\n <button type=\"button\" onClick={onDeclined}>\n {texts.declineCta}\n </button>\n )}\n </div>\n );\n}\n","/**\n * LanguageSwitcher — controlled <select> bound to the persisted user locale.\n *\n * Reads `config.i18n.supportedLocales` from <AppConfigProvider>; renders\n * `null` when the app hasn't declared an i18n config (so accidental usage\n * doesn't crash). On change, writes via `usePersistedState('user-locale')`,\n * which the I18nProvider effect picks up to call `i18n.changeLanguage`.\n *\n * Visual: minimal default styling. Apps customize via `className` or by\n * composing their own switcher on top of `usePersistedState`.\n */\nimport { usePersistedState } from '@hook-sdk/sdk';\nimport { useAppConfig } from '../config/AppConfigContext';\n\nexport type LanguageSwitcherProps = {\n /** Optional id for label association. */\n id?: string;\n /** Optional CSS class for app styling. */\n className?: string;\n /** Optional label text; defaults to 'Language'. */\n label?: string;\n};\n\nexport function LanguageSwitcher({ id, className, label = 'Language' }: LanguageSwitcherProps) {\n const config = useAppConfig();\n const i18nConfig = config.i18n;\n // Hooks must run unconditionally; pass a stable fallback default and bail\n // on render if the app isn't configured for i18n.\n const [userLocale, setUserLocale] = usePersistedState<string>(\n 'user-locale',\n i18nConfig?.defaultLocale ?? 'en-US',\n );\n\n if (!i18nConfig) return null;\n\n return (\n <label className={className}>\n {label ? <span>{label}</span> : null}\n <select\n id={id}\n value={userLocale}\n onChange={(e) => setUserLocale(e.target.value)}\n data-testid=\"language-switcher\"\n >\n {i18nConfig.supportedLocales.map((loc) => (\n <option key={loc} value={loc}>\n {loc}\n </option>\n ))}\n </select>\n </label>\n );\n}\n","export function LoadingState({ message }: { message?: string }) {\n return (\n <div role=\"status\" aria-live=\"polite\" style={{ padding: 24, textAlign: 'center' }}>\n <span>{message ?? 'Carregando...'}</span>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function EmptyState({ title, description, action }: {\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div role=\"status\" style={{ padding: 32, textAlign: 'center' }}>\n <h2 style={{ marginBottom: 8 }}>{title}</h2>\n {description && <p style={{ opacity: 0.7 }}>{description}</p>}\n {action && <div style={{ marginTop: 16 }}>{action}</div>}\n </div>\n );\n}\n","/**\n * Plan-V — turnkey default CheckoutPage.\n *\n * Layout mirrors the Personalburn checkout reference (Camila design,\n * `Checkout PB/screens.jsx#ScreenPayment`). 3-field contact section\n * (email → name → cpf), horizontal method tabs with subtitle, method-aware\n * body block (card fields with MM/AA combined input, or PIX explainer card),\n * mini plan-summary card, fixed footer CTA with method-aware copy + icon.\n *\n * Apps either mount this directly or build a custom visual on top of\n * `useCheckoutForm`. Cycle (MONTHLY/YEARLY) and method come from\n * sessionStorage[\"hook:paywall:intent\"] written by the pre-checkout offer\n * panel; if absent, defaults match the reference (YEARLY + card).\n *\n * On submit:\n * - Card: cookies set by backend, redirect to result.redirect.\n * - Pix-auto: redirect to /paywall/pix-wait (page reads QR from session).\n *\n * 409 collision → emailTaken banner with link to /signin?email=…\n */\nimport { useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCheckoutForm, type CheckoutFormMethod, type CheckoutFormCycle } from '../hooks/useCheckoutForm';\nimport { usePlan } from '../hooks/usePlan';\nimport { PaywallStickyFooter } from '../components/paywall';\n\nconst INTENT_KEY = 'hook:paywall:intent';\nconst PIX_PAYLOAD_KEY = 'hook:paywall:pix-pending';\n\ntype StoredIntent = {\n method?: CheckoutFormMethod;\n cycle?: CheckoutFormCycle;\n};\n\nfunction readIntent(): StoredIntent {\n if (typeof window === 'undefined') return {};\n try {\n const raw = sessionStorage.getItem(INTENT_KEY);\n if (!raw) return {};\n return JSON.parse(raw) as StoredIntent;\n } catch {\n return {};\n }\n}\n\nfunction formatBrl(cents: number): string {\n return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(cents / 100);\n}\n\nfunction formatCardNumber(v: string): string {\n const digits = v.replace(/\\D/g, '').slice(0, 16);\n return digits.replace(/(.{4})/g, '$1 ').trim();\n}\n\nfunction formatExpiryMmAa(v: string): string {\n const d = v.replace(/\\D/g, '').slice(0, 4);\n if (d.length < 3) return d;\n return d.slice(0, 2) + '/' + d.slice(2);\n}\n\nfunction parseExpiryMmAa(v: string): { month: string; year: string } {\n const d = v.replace(/\\D/g, '');\n return { month: d.slice(0, 2), year: d.slice(2, 4) };\n}\n\nfunction formatCpf(v: string): string {\n const d = v.replace(/\\D/g, '').slice(0, 11);\n if (d.length <= 3) return d;\n if (d.length <= 6) return d.slice(0, 3) + '.' + d.slice(3);\n if (d.length <= 9) return d.slice(0, 3) + '.' + d.slice(3, 6) + '.' + d.slice(6);\n return d.slice(0, 3) + '.' + d.slice(3, 6) + '.' + d.slice(6, 9) + '-' + d.slice(9);\n}\n\nfunction detectCardBrand(num: string): string {\n const n = num.replace(/\\s/g, '');\n if (/^4/.test(n)) return 'VISA';\n if (/^(5[1-5]|2[2-7])/.test(n)) return 'MASTER';\n if (/^3[47]/.test(n)) return 'AMEX';\n if (/^(4011|4312|4389|4514|6011|6362|6363)/.test(n)) return 'ELO';\n if (/^(606282|3841)/.test(n)) return 'HIPER';\n return '';\n}\n\nexport function CheckoutPageDefault() {\n const navigate = useNavigate();\n const plan = usePlan();\n const intent = useMemo(readIntent, []);\n const defaultMethod: CheckoutFormMethod =\n intent.method === 'pix-auto' ? 'pix-auto' : 'card';\n const defaultCycle: CheckoutFormCycle =\n intent.cycle === 'MONTHLY' ? 'MONTHLY' : 'YEARLY';\n\n const form = useCheckoutForm({ defaultMethod, defaultCycle });\n\n // Combined MM/AA visual state. useCheckoutForm stores month + year\n // separately; this syncs them.\n const [expiryMmAa, setExpiryMmAa] = useState('');\n useEffect(() => {\n const { month, year } = parseExpiryMmAa(expiryMmAa);\n if (month !== form.card.expiryMonth || year !== form.card.expiryYear) {\n form.setCard({ expiryMonth: month, expiryYear: year });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expiryMmAa]);\n\n useEffect(() => {\n if (form.emailTaken && form.loginUrl) {\n const t = setTimeout(() => navigate(form.loginUrl!), 1200);\n return () => clearTimeout(t);\n }\n }, [form.emailTaken, form.loginUrl, navigate]);\n\n const planInfo = plan.data\n ? {\n priceCents: plan.data.priceCents,\n yearlyPriceCents: plan.data.yearlyPriceCents,\n trialDays: plan.data.trialDays,\n }\n : null;\n\n const annual = form.cycle === 'YEARLY';\n const cyclePrice = useMemo(() => {\n if (!planInfo) return null;\n return annual\n ? planInfo.yearlyPriceCents ?? planInfo.priceCents * 12\n : planInfo.priceCents;\n }, [planInfo, annual]);\n\n const monthlyText = useMemo(() => {\n if (!planInfo) return '';\n const monthly = annual && planInfo.yearlyPriceCents\n ? Math.round(planInfo.yearlyPriceCents / 12)\n : planInfo.priceCents;\n return formatBrl(monthly);\n }, [planInfo, annual]);\n\n const todayCents = useMemo(() => {\n if (form.method === 'pix-auto') return cyclePrice ?? 0;\n const trialDays = planInfo?.trialDays ?? 0;\n if (trialDays > 0) return 0;\n return cyclePrice ?? 0;\n }, [form.method, cyclePrice, planInfo]);\n\n const todayAmount = formatBrl(todayCents);\n const cyclePriceText = cyclePrice !== null ? formatBrl(cyclePrice) : '';\n\n const annualSavingsCents = useMemo(() => {\n if (!planInfo || !planInfo.yearlyPriceCents) return 0;\n return planInfo.priceCents * 12 - planInfo.yearlyPriceCents;\n }, [planInfo]);\n\n const trialDays = planInfo?.trialDays ?? 7;\n const cardBrand = detectCardBrand(form.card.number);\n\n async function onSubmit(e: React.FormEvent) {\n e.preventDefault();\n const result = await form.submit();\n if (!result) return;\n if (form.method === 'pix-auto' && result.pix_qr_payload) {\n try {\n sessionStorage.setItem(\n PIX_PAYLOAD_KEY,\n JSON.stringify({\n payload: result.pix_qr_payload,\n base64: result.pix_qr_base64 ?? null,\n subscriptionId: result.subscription_id,\n pixAuthorizationId: result.pix_authorization_id ?? null,\n }),\n );\n } catch { /* ignore quota errors */ }\n navigate(result.redirect.replace(/^.*\\/app\\/[^/]+/, ''));\n return;\n }\n // Card-path success: navega pra /paywall/pronta (tela \"Pronta\" + email\n // de boas-vindas com magic-link + senha). Cada app monta Route /paywall/pronta\n // → PaywallProntaPreAuth wrapper que renderiza PaywallStepPronta dentro de\n // <PaywallProvider>. CTA \"Vamos lá\" → /app/home (postAuthLanding).\n navigate('/paywall/pronta');\n }\n\n return (\n <div className=\"flex-1 flex flex-col bg-background min-h-0\">\n <form onSubmit={onSubmit} className=\"flex-1 flex flex-col min-h-0\">\n {/*\n Vertical rhythm system — keep edits on this scale, do not add ad-hoc\n one-off margins/paddings:\n section gap 24px (space-y-6 on this scroll body)\n intra-section 16px (space-y-4 — field↔field, tabs↔body)\n label → input 8px (FieldLabel mb-2)\n input → hint 6px (FieldHint / error mt-1.5)\n heading → content 16px (h2 mb-4)\n card padding 16px (p-4)\n */}\n <div className=\"flex-1 overflow-y-auto px-5 pt-5 pb-6 space-y-6\">\n {form.emailTaken ? (\n <div role=\"alert\" className=\"rounded-2xl bg-destructive/10 p-4 text-sm text-destructive border border-destructive/20\">\n Esse e-mail já tem conta nesse app.{' '}\n <a href={form.loginUrl ?? '/signin'} className=\"underline font-semibold\">\n Entrar agora\n </a>\n </div>\n ) : null}\n\n {form.error ? (\n <div role=\"alert\" className=\"rounded-2xl bg-destructive/10 p-4 text-sm text-destructive border border-destructive/20\">\n {form.error.message || 'Não foi possível concluir o pagamento. Tente novamente.'}\n </div>\n ) : null}\n\n {/* Reassurance banner — switches by method */}\n {form.method === 'card' ? (\n <div className=\"rounded-2xl bg-card border-[1.5px] border-foreground p-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <ShieldIcon className=\"w-4 h-4\" />\n <div className=\"text-sm font-bold\">Você NÃO será cobrada hoje</div>\n </div>\n <div className=\"flex justify-between items-baseline text-sm text-muted-foreground\">\n <span>R$ 0,00 agora</span>\n <span className=\"opacity-50\">·</span>\n <span>{monthlyText}/mês após {trialDays} dias</span>\n </div>\n <div className=\"mt-2.5 text-[11px] text-muted-foreground flex items-center gap-1.5\">\n <BellIcon className=\"w-2.5 h-2.5\" />\n Avisamos por email 2 dias antes da primeira cobrança\n </div>\n </div>\n ) : (\n <div className=\"rounded-2xl p-4 bg-emerald-50 border-[1.5px] border-emerald-600/60\">\n <div className=\"flex items-center gap-2 mb-2 text-emerald-900\">\n <ShieldIcon className=\"w-4 h-4\" />\n <div className=\"text-sm font-bold\">Garantia incondicional de {trialDays} dias</div>\n </div>\n <div className=\"text-sm text-emerald-900 leading-snug\">\n Você paga hoje via Pix.<br />\n Não gostou em {trialDays} dias? Devolvemos <b>100%</b> sem perguntas — direto pelo app.\n </div>\n </div>\n )}\n\n {/* Contact: email → name → cpf */}\n <section>\n <h2 className=\"font-display text-2xl mb-4 leading-tight text-foreground\">Quase lá.</h2>\n\n <div className=\"space-y-4\">\n <div>\n <FieldLabel>Email</FieldLabel>\n <FieldInput\n type=\"email\"\n inputMode=\"email\"\n autoComplete=\"email\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck={false}\n placeholder=\"seu@email.com\"\n value={form.email}\n onChange={form.setEmail}\n onBlur={form.markEmailTouched}\n error={form.emailError}\n valid={form.emailStatus === 'available'}\n />\n {!form.emailError && (\n <FieldHint>\n {form.emailStatus === 'checking' ? 'Verificando…' :\n form.emailStatus === 'available' ? '✓ Disponível' :\n 'Você vai usar este email para entrar no app'}\n </FieldHint>\n )}\n </div>\n\n <div>\n <FieldLabel>Nome completo</FieldLabel>\n <FieldInput\n type=\"text\"\n autoComplete=\"name\"\n placeholder=\"como está no documento\"\n value={form.name}\n onChange={form.setName}\n onBlur={form.markNameTouched}\n error={form.nameError}\n valid={!!form.name && !form.nameError}\n />\n </div>\n\n <div>\n <FieldLabel>CPF</FieldLabel>\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"000.000.000-00\"\n value={form.cpf}\n onChange={(v) => form.setCpf(formatCpf(v))}\n onBlur={form.markCpfTouched}\n error={form.cpfError}\n valid={!!form.cpf && !form.cpfError}\n />\n </div>\n\n {/* Phone is REQUIRED by Asaas tokenizeCreditCard.creditCardHolderInfo\n when method=card; the API rejects empty phone with 400\n `invalid_holderInfo`. PIX path skips card tokenization so phone\n is optional there. Render only when card so the form stays at\n 3 fields (matches the Personalburn reference mockup) for PIX. */}\n {form.method === 'card' ? (\n <div>\n <FieldLabel>Telefone</FieldLabel>\n <FieldInput\n type=\"tel\"\n inputMode=\"tel\"\n autoComplete=\"tel\"\n placeholder=\"(11) 99999-9999\"\n value={form.phone}\n onChange={form.setPhone}\n onBlur={form.markPhoneTouched}\n error={form.phoneError}\n valid={!!form.phone && !form.phoneError}\n />\n {!form.phoneError && (\n <FieldHint>\n Usado pra confirmar pagamento e tratar disputas.\n </FieldHint>\n )}\n </div>\n ) : null}\n </div>\n </section>\n\n {/* Payment: method tabs + method-conditional body, one section so the\n tabs and their fields share a 16px intra-section rhythm. */}\n <section className=\"space-y-4\">\n <div>\n <FieldLabel>Forma de pagamento</FieldLabel>\n <div role=\"tablist\" className=\"flex gap-1.5 bg-muted p-1 rounded-xl\">\n <TabButton\n active={form.method === 'card'}\n onClick={() => form.setMethod('card')}\n icon={<CardIcon className=\"w-3.5 h-3.5\" />}\n label=\"Cartão\"\n subtitle={trialDays > 0 ? `${trialDays} dias grátis` : 'pague hoje'}\n subtitleActiveClass=\"text-emerald-700\"\n />\n <TabButton\n active={form.method === 'pix-auto'}\n onClick={() => form.setMethod('pix-auto')}\n icon={<PixIcon className=\"w-3.5 h-3.5\" />}\n label=\"Pix\"\n subtitle={`pague hoje · garantia ${trialDays}d`}\n subtitleActiveClass=\"text-foreground/70\"\n />\n </div>\n </div>\n\n {form.method === 'card' ? (\n <div className=\"space-y-4\">\n <div>\n <FieldLabel>Número do cartão</FieldLabel>\n <div className=\"relative\">\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-number\"\n placeholder=\"0000 0000 0000 0000\"\n value={form.card.number}\n onChange={(v) => form.setCard({ number: formatCardNumber(v) })}\n style={cardBrand ? { paddingRight: '4.5rem' } : undefined}\n />\n {cardBrand && (\n <span className=\"absolute right-3 top-1/2 -translate-y-1/2 text-[10px] font-bold tracking-wide px-1.5 py-0.5 rounded bg-muted text-muted-foreground\">\n {cardBrand}\n </span>\n )}\n </div>\n </div>\n\n <div className=\"flex gap-3\">\n <div className=\"flex-1\">\n <FieldLabel>Validade</FieldLabel>\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-exp\"\n placeholder=\"MM/AA\"\n value={expiryMmAa}\n onChange={(v) => setExpiryMmAa(formatExpiryMmAa(v))}\n />\n </div>\n <div className=\"flex-1\">\n <FieldLabel>CVV</FieldLabel>\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-csc\"\n placeholder=\"3 dígitos\"\n value={form.card.ccv}\n onChange={(v) => form.setCard({ ccv: v.replace(/\\D/g, '').slice(0, 4) })}\n />\n </div>\n </div>\n\n <div>\n <FieldLabel>Nome no cartão</FieldLabel>\n <FieldInput\n type=\"text\"\n autoComplete=\"cc-name\"\n placeholder=\"como está no cartão\"\n value={form.card.holderName}\n onChange={(v) => form.setCard({ holderName: v })}\n />\n </div>\n </div>\n ) : (\n <div className=\"rounded-2xl bg-card border border-border p-4 flex gap-3.5 items-center\">\n <div className=\"w-[72px] h-[72px] rounded-xl shrink-0 border-2 border-foreground relative overflow-hidden bg-muted\">\n <div className=\"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[22px] h-[22px] bg-background flex items-center justify-center\">\n <PixIcon className=\"w-3.5 h-3.5 text-foreground\" />\n </div>\n </div>\n <div className=\"flex-1\">\n <div className=\"text-xs font-bold uppercase tracking-wider text-muted-foreground\">\n pagamento em segundos\n </div>\n <div className=\"text-sm text-foreground mt-1 leading-snug\">\n Geramos seu <b>QR Pix</b> no próximo passo. Pague pelo app do banco e seu acesso libera <b>imediatamente</b>.\n </div>\n </div>\n </div>\n )}\n </section>\n\n {/* Plan summary card */}\n <section>\n <div className=\"bg-muted rounded-2xl p-4\">\n <div className=\"flex justify-between gap-3\">\n <div>\n <div className=\"text-sm font-semibold text-foreground\">\n {annual ? 'Plano Anual' : 'Plano Mensal'}\n </div>\n <div className=\"text-[11px] text-muted-foreground\">Coach</div>\n </div>\n <div className=\"text-right\">\n {/* For pix-auto the cycle price equals the today amount shown\n below, so showing it here too reads as a duplicated value.\n Card method keeps it — there it differs from \"today\" (R$0). */}\n {form.method !== 'pix-auto' && (\n <div className=\"text-sm font-bold text-foreground\">\n {cyclePriceText}/{annual ? 'ano' : 'mês'}\n </div>\n )}\n {annual && annualSavingsCents > 0 && (\n <div className=\"text-[11px] text-emerald-700 font-semibold\">\n economia {formatBrl(annualSavingsCents)}\n </div>\n )}\n </div>\n </div>\n <div className=\"h-px bg-border my-3\" />\n <div className=\"flex justify-between items-baseline gap-3\">\n <div className=\"text-sm font-bold text-foreground\">Você paga hoje</div>\n <div className=\"text-2xl font-bold font-display tracking-tight text-foreground\">\n {todayAmount}\n </div>\n </div>\n {/* Sub-note on its own full-width line — competing for width with\n the R$ amount above squeezed it into an ugly 2-line wrap. */}\n {form.method === 'card' && trialDays > 0 && (\n <div className=\"mt-1.5 text-[11px] text-muted-foreground\">\n cobrança inicia no dia {trialDays}\n </div>\n )}\n {form.method === 'pix-auto' && (\n <div className=\"mt-1.5 text-[11px] text-emerald-700 font-semibold\">\n reembolso garantido até o dia {trialDays}\n </div>\n )}\n </div>\n </section>\n\n </div>\n\n {/* Fixed CTA footer — sibling of the scroll body so it never overlaps\n the form content. (Old `sticky bottom-0` lived INSIDE the scroll\n container and floated over the card fields / plan summary.) */}\n <PaywallStickyFooter className=\"px-5 pt-5 pb-6 border-t border-border\">\n <button\n type=\"submit\"\n disabled={!form.canSubmit}\n className=\"w-full rounded-full bg-primary text-primary-foreground h-14 px-5 text-base font-bold inline-flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed shadow-lg\"\n >\n {form.submitting ? (\n <>\n <Spinner /> {form.method === 'pix-auto' ? 'Gerando QR…' : 'Confirmando…'}\n </>\n ) : form.method === 'card' ? (\n <>\n <LockIcon className=\"w-3.5 h-3.5\" /> Confirmar e começar grátis\n </>\n ) : (\n <>\n <PixIcon className=\"w-3.5 h-3.5\" /> Gerar QR Pix\n </>\n )}\n </button>\n <div className=\"text-center mt-3 text-xs text-muted-foreground\">\n Ao continuar, você concorda com nossos <u>Termos</u>. Pagamento seguro Asaas.\n </div>\n <div className=\"mt-3 flex items-center justify-center gap-4 text-[11px] text-muted-foreground\">\n <span className=\"inline-flex items-center gap-1\">\n <LockIcon className=\"w-2.5 h-2.5 opacity-60\" /> SSL 256-bit\n </span>\n <span className=\"w-px h-2.5 bg-border\" />\n <span>Pagamento via Asaas</span>\n <span className=\"w-px h-2.5 bg-border\" />\n <span>Garantia {trialDays} dias</span>\n </div>\n </PaywallStickyFooter>\n </form>\n </div>\n );\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Internals\n// ───────────────────────────────────────────────────────────────────────\n\nfunction FieldLabel({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2\">\n {children}\n </div>\n );\n}\n\ninterface FieldInputProps {\n value: string;\n onChange: (v: string) => void;\n onBlur?: () => void;\n type?: string;\n inputMode?: 'text' | 'numeric' | 'tel' | 'email';\n autoComplete?: string;\n autoCapitalize?: string;\n autoCorrect?: string;\n spellCheck?: boolean;\n placeholder?: string;\n error?: string | null;\n valid?: boolean;\n style?: React.CSSProperties;\n}\n\nfunction FieldInput(props: FieldInputProps) {\n const baseClass = 'w-full px-4 rounded-xl bg-card text-base text-foreground outline-none border-[1.5px] transition-colors';\n const stateClass = props.error\n ? 'border-destructive focus:border-destructive'\n : props.valid\n ? 'border-emerald-600 focus:border-emerald-700'\n : 'border-border focus:border-foreground';\n return (\n <>\n <input\n type={props.type ?? 'text'}\n inputMode={props.inputMode}\n autoComplete={props.autoComplete}\n autoCapitalize={props.autoCapitalize}\n autoCorrect={props.autoCorrect}\n spellCheck={props.spellCheck}\n placeholder={props.placeholder}\n value={props.value}\n onChange={(e) => props.onChange(e.target.value)}\n onBlur={props.onBlur}\n style={{ height: '52px', ...props.style }}\n className={`${baseClass} ${stateClass}`}\n />\n {props.error ? (\n <div className=\"mt-1.5 text-xs text-destructive font-medium\">{props.error}</div>\n ) : null}\n </>\n );\n}\n\nfunction FieldHint({ children }: { children: React.ReactNode }) {\n return <div className=\"mt-1.5 text-xs text-muted-foreground\">{children}</div>;\n}\n\ninterface TabButtonProps {\n active: boolean;\n onClick: () => void;\n icon: React.ReactNode;\n label: string;\n subtitle: string;\n subtitleActiveClass: string;\n}\n\nfunction TabButton({ active, onClick, icon, label, subtitle, subtitleActiveClass }: TabButtonProps) {\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={onClick}\n className={`flex-1 flex flex-col items-center justify-center gap-0.5 py-2.5 px-1.5 rounded-lg text-sm font-semibold transition-colors ${\n active\n ? 'bg-card text-foreground shadow-sm'\n : 'bg-transparent text-muted-foreground'\n }`}\n style={{ minHeight: 56 }}\n >\n <span className=\"inline-flex items-center gap-1.5\">\n {icon} {label}\n </span>\n <span className={`text-[10px] font-medium ${active ? subtitleActiveClass : 'text-muted-foreground/70'}`}>\n {subtitle}\n </span>\n </button>\n );\n}\n\nfunction CardIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"2.5\" y=\"5.5\" width=\"19\" height=\"13\" rx=\"2.5\" />\n <path d=\"M2.5 10h19\" />\n </svg>\n );\n}\n\nfunction PixIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12 2L2 12l10 10 10-10L12 2zm0 4.83L17.17 12 12 17.17 6.83 12 12 6.83z\" />\n </svg>\n );\n}\n\nfunction LockIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"4\" y=\"10\" width=\"16\" height=\"11\" rx=\"2.5\" />\n <path d=\"M7.5 10V7a4.5 4.5 0 119 0v3\" />\n </svg>\n );\n}\n\nfunction ShieldIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M12 2.5l8 3v6c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10v-6l8-3z\" />\n <path d=\"M9 12l2 2 4-4\" />\n </svg>\n );\n}\n\nfunction BellIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M6 17V11a6 6 0 1112 0v6l1.5 2H4.5L6 17z\" />\n <path d=\"M10 21a2 2 0 004 0\" />\n </svg>\n );\n}\n\nfunction Spinner() {\n return (\n <span\n className=\"w-4 h-4 rounded-full border-2 border-white/40 border-t-white\"\n style={{ animation: 'spin 0.7s linear infinite' }}\n />\n );\n}\n","/**\n * Plan-V — headless hook for the pay-first CheckoutPage.\n *\n * Apps compose the visual layer; this hook owns: field state, validation,\n * email-existence debounced check, submit (card / pix-auto) via SDK\n * `auth.subscribeAnonymous`, and `EmailTakenError` translation.\n *\n * See docs/superpowers/specs/2026-05-13-pay-first-signup-design.md §\"Template\".\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useHook,\n EmailTakenError,\n type SubscribeAnonymousArgs,\n type SubscribeAnonymousResult,\n} from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst PHONE_RE = /^[0-9()+\\-\\s]{8,20}$/;\nconst CHECK_DEBOUNCE_MS = 400;\n\nexport type CheckoutFormCycle = 'MONTHLY' | 'YEARLY';\nexport type CheckoutFormMethod = 'card' | 'pix-auto';\n\nexport interface CheckoutCardInput {\n number: string;\n expiryMonth: string;\n expiryYear: string;\n ccv: string;\n holderName: string;\n}\n\nexport interface UseCheckoutFormResult {\n // Field state — controlled values + setters.\n name: string;\n setName: (v: string) => void;\n email: string;\n setEmail: (v: string) => void;\n emailConfirm: string;\n setEmailConfirm: (v: string) => void;\n phone: string;\n setPhone: (v: string) => void;\n cpf: string;\n setCpf: (v: string) => void;\n\n // Method + cycle selection.\n method: CheckoutFormMethod;\n setMethod: (m: CheckoutFormMethod) => void;\n cycle: CheckoutFormCycle;\n setCycle: (c: CheckoutFormCycle) => void;\n\n // Card-specific fields (only relevant when method === 'card').\n card: CheckoutCardInput;\n setCard: (patch: Partial<CheckoutCardInput>) => void;\n\n // Per-field errors (null until touched OR after first submit attempt).\n nameError: string | null;\n emailError: string | null;\n emailConfirmError: string | null;\n phoneError: string | null;\n cpfError: string | null;\n markNameTouched: () => void;\n markEmailTouched: () => void;\n markEmailConfirmTouched: () => void;\n markPhoneTouched: () => void;\n markCpfTouched: () => void;\n\n /**\n * Result of the debounced server-side email-exists check, used to swap\n * the CTA into \"Email já cadastrado · Entrar\" on the checkout form.\n */\n emailStatus: 'idle' | 'checking' | 'exists' | 'available';\n\n /**\n * Submit the form. Calls `auth.subscribeAnonymous`. Returns the result on\n * success, null on validation failure, or throws on payment failure (caller\n * should display a banner). EmailTakenError is caught + translated into\n * `emailStatus='exists'` + `emailTaken=true` so the caller can redirect.\n */\n submit: () => Promise<SubscribeAnonymousResult | null>;\n submitting: boolean;\n canSubmit: boolean;\n formSubmitAttempted: boolean;\n error: AuthFormError | null;\n\n /** True after a 409 collision; caller redirects to /login?email=… */\n emailTaken: boolean;\n loginUrl: string | null;\n}\n\nexport interface UseCheckoutFormArgs {\n defaultMethod: CheckoutFormMethod;\n defaultCycle: CheckoutFormCycle;\n}\n\nexport function useCheckoutForm(args: UseCheckoutFormArgs): UseCheckoutFormResult {\n const { auth } = useHook();\n\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [emailConfirm, setEmailConfirm] = useState('');\n const [phone, setPhone] = useState('');\n const [cpf, setCpf] = useState('');\n\n const [method, setMethod] = useState<CheckoutFormMethod>(args.defaultMethod);\n const [cycle, setCycle] = useState<CheckoutFormCycle>(args.defaultCycle);\n\n const [card, setCardState] = useState<CheckoutCardInput>({\n number: '',\n expiryMonth: '',\n expiryYear: '',\n ccv: '',\n holderName: '',\n });\n const setCard = useCallback((patch: Partial<CheckoutCardInput>) => {\n setCardState((prev) => ({ ...prev, ...patch }));\n }, []);\n\n const [touchedName, setTouchedName] = useState(false);\n const [touchedEmail, setTouchedEmail] = useState(false);\n const [touchedEmailConfirm, setTouchedEmailConfirm] = useState(false);\n const [touchedPhone, setTouchedPhone] = useState(false);\n const [touchedCpf, setTouchedCpf] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n const [emailTaken, setEmailTaken] = useState(false);\n const [loginUrl, setLoginUrl] = useState<string | null>(null);\n\n const [emailStatus, setEmailStatus] = useState<UseCheckoutFormResult['emailStatus']>('idle');\n const lastCheckedEmail = useRef<string>('');\n\n // Debounced email-exists check.\n useEffect(() => {\n if (!email || !EMAIL_RE.test(email)) {\n setEmailStatus('idle');\n return;\n }\n if (email === lastCheckedEmail.current) return;\n const timer = setTimeout(async () => {\n setEmailStatus('checking');\n try {\n const result = await auth.checkEmailExists({ email });\n lastCheckedEmail.current = email;\n setEmailStatus(result.exists ? 'exists' : 'available');\n } catch {\n // Network error — be permissive (don't block submit on lookup\n // failure; server-side INSERT will still catch a collision).\n setEmailStatus('idle');\n }\n }, CHECK_DEBOUNCE_MS);\n return () => clearTimeout(timer);\n }, [email, auth]);\n\n // Validation.\n const validateName = useMemo(() => {\n if (name.length === 0) return null;\n if (name.trim().length < 2) return 'Nome muito curto.';\n return null;\n }, [name]);\n const validateEmail = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n const validateEmailConfirm = useMemo(() => {\n if (emailConfirm.length === 0) return null;\n if (emailConfirm !== email) return 'Os e-mails não coincidem.';\n return null;\n }, [emailConfirm, email]);\n const validatePhone = useMemo(() => {\n if (phone.length === 0) return null;\n if (!PHONE_RE.test(phone)) return 'Telefone inválido.';\n return null;\n }, [phone]);\n const validateCpf = useMemo(() => {\n if (cpf.length === 0) return null;\n const digits = cpf.replace(/\\D/g, '');\n if (digits.length !== 11) return 'CPF deve ter 11 dígitos.';\n if (/^(\\d)\\1+$/.test(digits)) return 'CPF inválido.';\n // Mod-11 check.\n const ok = mod11(digits, 9) === digits[9] && mod11(digits, 10) === digits[10];\n return ok ? null : 'CPF inválido.';\n }, [cpf]);\n\n const nameError = (touchedName || formSubmitAttempted) ? validateName : null;\n const emailError = (touchedEmail || formSubmitAttempted) ? validateEmail : null;\n const emailConfirmError = (touchedEmailConfirm || formSubmitAttempted) ? validateEmailConfirm : null;\n const phoneError = (touchedPhone || formSubmitAttempted) ? validatePhone : null;\n const cpfError = (touchedCpf || formSubmitAttempted) ? validateCpf : null;\n\n // Plan-V 0.28.x — emailConfirm + phone field rules:\n // * `emailConfirm`: optional. When the app's UI drops the second-email\n // input, auto-fill to `email` at submit time (typo guard becomes a\n // no-op).\n // * `phone`: REQUIRED when method === 'card'. Asaas's\n // `tokenizeCreditCard.creditCardHolderInfo.phone` rejects empty with\n // HTTP 400 `invalid_holderInfo`; gate the submit button here so we\n // never round-trip to Asaas with an empty value. PIX skips card\n // tokenization so phone stays optional on that path.\n const phoneOk = method === 'pix-auto'\n ? (phone === '' || PHONE_RE.test(phone))\n : PHONE_RE.test(phone);\n const canSubmit =\n name.trim().length >= 2 &&\n EMAIL_RE.test(email) &&\n (emailConfirm === '' || emailConfirm === email) &&\n phoneOk &&\n validateCpf === null &&\n cpf.replace(/\\D/g, '').length === 11 &&\n emailStatus !== 'exists' &&\n !submitting &&\n (method !== 'card' || (\n card.number.length >= 12 &&\n card.ccv.length >= 3 &&\n card.expiryMonth.length >= 1 &&\n card.expiryYear.length >= 2 &&\n card.holderName.length >= 1\n ));\n\n const submit = useCallback(async (): Promise<SubscribeAnonymousResult | null> => {\n setFormSubmitAttempted(true);\n setError(null);\n setEmailTaken(false);\n setLoginUrl(null);\n if (!canSubmit) return null;\n setSubmitting(true);\n\n try {\n let args: SubscribeAnonymousArgs;\n if (method === 'card') {\n args = {\n method: 'card',\n name: name.trim(),\n email,\n emailConfirm: emailConfirm || email,\n phone,\n cpf: cpf.replace(/\\D/g, ''),\n cycle,\n card: {\n number: card.number.replace(/\\s/g, ''),\n expiryMonth: card.expiryMonth,\n expiryYear: card.expiryYear,\n ccv: card.ccv,\n holderName: card.holderName,\n },\n cardHolderInfo: {\n name: card.holderName || name.trim(),\n email,\n cpfCnpj: cpf.replace(/\\D/g, ''),\n // Plan-V 0.28.4 — Asaas's `creditCardHolderInfo.postalCode`\n // rejects all-zeros with `tokenize_failed:invalid_holderInfo`\n // (\"O CEP informado é inválido.\"). The default CheckoutPage\n // doesn't collect CEP from the user (reference design skipped\n // it), so ship a known-valid placeholder. Apps that need real\n // customer addresses must override CheckoutPageDefault and\n // collect CEP — see personalburn's PaywallStepPagamento for\n // the pattern.\n postalCode: '01001000',\n addressNumber: '100',\n phone,\n },\n };\n } else {\n args = {\n method: 'pix-auto',\n name: name.trim(),\n email,\n emailConfirm: emailConfirm || email,\n phone,\n cpf: cpf.replace(/\\D/g, ''),\n cycle,\n };\n }\n const result = await auth.subscribeAnonymous(args);\n return result;\n } catch (err) {\n if (err instanceof EmailTakenError) {\n setEmailTaken(true);\n setLoginUrl(err.loginUrl);\n setEmailStatus('exists');\n return null;\n }\n setError(mapSdkError(err));\n return null;\n } finally {\n setSubmitting(false);\n }\n }, [auth, canSubmit, method, cycle, name, email, emailConfirm, phone, cpf, card]);\n\n return {\n name, setName,\n email, setEmail,\n emailConfirm, setEmailConfirm,\n phone, setPhone,\n cpf, setCpf,\n method, setMethod,\n cycle, setCycle,\n card, setCard,\n\n nameError, emailError, emailConfirmError, phoneError, cpfError,\n markNameTouched: () => setTouchedName(true),\n markEmailTouched: () => setTouchedEmail(true),\n markEmailConfirmTouched: () => setTouchedEmailConfirm(true),\n markPhoneTouched: () => setTouchedPhone(true),\n markCpfTouched: () => setTouchedCpf(true),\n\n emailStatus,\n submit,\n submitting,\n canSubmit,\n formSubmitAttempted,\n error,\n emailTaken,\n loginUrl,\n };\n}\n\nfunction mod11(digits: string, len: number): string {\n let sum = 0;\n for (let i = 0; i < len; i++) sum += parseInt(digits.charAt(i), 10) * (len + 1 - i);\n const r = (sum * 10) % 11;\n return String(r === 10 ? 0 : r);\n}\n","import { SdkError, SdkAuthError, SdkRateLimitError, SdkValidationError } from '@hook-sdk/sdk';\n\nexport type AuthFormErrorCode =\n | 'invalid_credentials'\n | 'rate_limited'\n | 'email_unverified'\n | 'email_taken'\n | 'account_locked'\n | 'network'\n | 'server';\n\nexport interface AuthFormError {\n code: AuthFormErrorCode;\n message: string;\n retryAfter?: number;\n}\n\n/**\n * Mapeia SdkError do @hook-sdk/sdk pra AuthFormError tipado do template.\n * Usado por useLoginForm/useSignupForm/useForgotForm.\n */\nexport function mapSdkError(err: unknown): AuthFormError {\n if (err instanceof SdkRateLimitError) {\n return {\n code: 'rate_limited',\n message: `Aguarde ${err.retryAfter}s e tente novamente.`,\n retryAfter: err.retryAfter,\n };\n }\n if (err instanceof SdkAuthError) {\n const detail = (err as { detail?: string }).detail;\n if (detail === 'email_unverified') {\n return { code: 'email_unverified', message: 'Confirme seu e-mail antes de entrar.' };\n }\n if (detail === 'account_locked') {\n return { code: 'account_locked', message: 'Conta bloqueada. Contate o suporte.' };\n }\n return { code: 'invalid_credentials', message: 'E-mail ou senha inválidos.' };\n }\n if (err instanceof SdkValidationError && err.code === 'auth.email_taken') {\n return { code: 'email_taken', message: 'Esse e-mail já tem conta.' };\n }\n if (err instanceof SdkError && err.httpStatus === 0) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n // Falhas de rede em POST/PATCH/DELETE não são envolvidas em SdkError pelo\n // HttpClient (só GET tem retry wrap). fetch() lança TypeError cru — tratamos\n // como 'network' pra manter UX consistente com GETs.\n if (err instanceof TypeError) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n return { code: 'server', message: 'Algo deu errado. Tente novamente em instantes.' };\n}\n","import { useHook } from '@hook-sdk/sdk';\nimport type { PlanInfo, PlanState } from '@hook-sdk/sdk';\n\n/**\n * Thin wrapper sobre `useHook().plan`. Existe pra apps importarem \"tudo\n * que precisam\" via `@hook-sdk/template` sem mudar de package pra cada\n * primitive, e pra manter espaço pra evoluir a API (ex: expor campos\n * derivados como `monthlyEquivalent()`) sem mexer no SDK.\n *\n * Retorna o PlanState bruto. Use junto com helpers de `@hook-sdk/template`:\n *\n * const { data, initialLoadComplete } = usePlan();\n * if (!initialLoadComplete) return <Skeleton />;\n * if (!data) return null;\n * return <span>{formatBRL(data.priceCents)}</span>;\n */\nexport function usePlan(): PlanState {\n const { plan } = useHook();\n return plan;\n}\n\nexport type { PlanInfo, PlanState };\n","// template/src/components/paywall/Paywall.tsx\nimport { useEffect, useMemo } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { formatBRL } from '../../utils/price';\nimport { PaywallProvider } from './PaywallProvider';\nimport { usePaywallContext } from './usePaywallContext';\nimport { PaywallMethodTabs } from './PaywallMethodTabs';\nimport { PaywallMethodContent } from './PaywallMethodContent';\nimport { PaywallCyclePicker } from './PaywallCyclePicker';\nimport type { PaywallProps } from './types';\n\n/** Non-breaking space produced by Intl.NumberFormat('pt-BR', { currency:'BRL' }). */\nconst NBSP = ' ';\n\n/**\n * Composed top-level paywall component. Apps wrap it in their `PaywallOffer.tsx`\n * (or `Offer.tsx`) and pass copy + themeClasses + slots. Logic + telemetry live\n * here. To customize layout entirely, drop down to the primitives.\n *\n * Internally wraps a `<PaywallProvider>` so the refactored primitives can read\n * state from context. Apps wanting Level 2 / Level 3 composition can use\n * `<PaywallProvider>` + Lego blocks directly without going through `<Paywall>`.\n */\nexport function Paywall({\n copy,\n themeClasses = {},\n slots = {},\n onBeforeCheckout,\n}: PaywallProps) {\n return (\n <PaywallProvider>\n <PaywallInner\n copy={copy}\n themeClasses={themeClasses}\n slots={slots}\n onBeforeCheckout={onBeforeCheckout}\n />\n </PaywallProvider>\n );\n}\n\nfunction PaywallInner({\n copy,\n themeClasses = {},\n slots = {},\n onBeforeCheckout,\n}: PaywallProps) {\n const { track } = useHook();\n const s = usePaywallContext();\n\n // Interpolate copy templates with current price + trial days.\n // Normalize NBSP (U+00A0) produced by Intl.NumberFormat('pt-BR') to regular\n // space so that template strings like \"Pagar {price} com PIX\" produce plain\n // ASCII-compatible output for accessible-name matching in tests + TTS.\n const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, 'g'), ' ');\n const trialDaysCardLabel = String(s.trialDaysCard);\n\n const ctaLabel = useMemo(() => {\n if (s.isFree) return copy.freeCta ?? 'Começar agora';\n if (s.selectedMethod === 'card') {\n if (s.hasConsumedTrial && copy.cardConsumedTrial) {\n return interp(copy.cardConsumedTrial.ctaTemplate, {\n price: priceLabel,\n days: trialDaysCardLabel,\n });\n }\n if (s.trialDaysCard > 0) {\n return interp(copy.card.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });\n }\n // card-no-trial fallback: reuse the consumed template if provided, else assinar literal.\n return copy.cardConsumedTrial\n ? interp(copy.cardConsumedTrial.ctaTemplate, {\n price: priceLabel,\n days: trialDaysCardLabel,\n })\n : `Assinar por ${priceLabel}`;\n }\n return interp(copy.pix.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });\n }, [\n s.isFree,\n s.selectedMethod,\n s.hasConsumedTrial,\n s.trialDaysCard,\n copy,\n priceLabel,\n trialDaysCardLabel,\n ]);\n\n const switchHint = useMemo(() => {\n if (s.methods.length < 2) return undefined;\n return s.selectedMethod === 'card' ? copy.card.switchHint : copy.pix.switchHint;\n }, [s.methods.length, s.selectedMethod, copy]);\n\n // Mount telemetry — fire once when methods + cycle resolve.\n useEffect(() => {\n if (!s.initialLoadComplete) return;\n track('paywall_view', {\n default_method: s.selectedMethod,\n default_cycle: s.cycle,\n available_methods: s.methods,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [s.initialLoadComplete]);\n\n const handleCta = async () => {\n track('paywall_cta_clicked', {\n method: s.selectedMethod,\n cycle: s.cycle,\n price_cents: s.currentPriceCents,\n had_consumed_trial: s.hasConsumedTrial,\n });\n if (onBeforeCheckout) {\n await onBeforeCheckout(s.selectedMethod, s.cycle);\n return;\n }\n await s.submit();\n };\n\n const ctaTheme =\n s.selectedMethod === 'card' ? themeClasses.ctaCard : themeClasses.ctaPix;\n\n return (\n <div className={themeClasses.container}>\n {slots.heroSlot}\n <h1 className={themeClasses.headline}>{copy.headline}</h1>\n <ul>\n {copy.features.map((f) => (\n <li key={f} className={themeClasses.feature}>\n ✓ <span>{f}</span>\n </li>\n ))}\n </ul>\n {copy.socialProof ? (\n <p className={themeClasses.socialProof}>{copy.socialProof}</p>\n ) : null}\n\n {slots.cyclePickerSlot ?? (\n <PaywallCyclePicker\n labels={copy.cycle}\n cardClassName={themeClasses.cycleCard}\n cardSelectedClassName={themeClasses.cycleCardSelected}\n anchorClassName={themeClasses.anchorPrice}\n />\n )}\n\n <PaywallMethodTabs\n labels={{ 'pix-auto': copy.pix.tabLabel, card: copy.card.tabLabel }}\n className={themeClasses.tabs}\n tabClassName={themeClasses.tab}\n tabActiveClassName={themeClasses.tabActive}\n />\n\n <PaywallMethodContent\n copy={{\n pix: interpolateCopy(copy.pix, priceLabel, trialDaysCardLabel),\n card: interpolateCopy(copy.card, priceLabel, trialDaysCardLabel),\n cardConsumedTrial: copy.cardConsumedTrial\n ? {\n bodyRows: copy.cardConsumedTrial.bodyRows.map((r) =>\n interp(r, { price: priceLabel, days: trialDaysCardLabel }),\n ) as [string, string, string],\n ctaTemplate: copy.cardConsumedTrial.ctaTemplate,\n }\n : undefined,\n }}\n className={themeClasses.tabContent}\n rowClassName={themeClasses.tabContentRow}\n />\n\n {slots.beforeCtaSlot}\n\n {/*\n CTA is rendered inline (not via PaywallCta) because <Paywall> owns\n telemetry + the onBeforeCheckout escape hatch — both couplings the\n Lego primitive doesn't carry. Apps composing their own paywall use\n <PaywallCta> directly (it dispatches context.submit on click).\n */}\n <div>\n <button\n type=\"button\"\n onClick={() => {\n void handleCta();\n }}\n disabled={s.submitting}\n className={ctaTheme}\n >\n {s.submitting ? 'Abrindo checkout…' : ctaLabel}\n </button>\n {switchHint ? (\n <p className={themeClasses.switchHint}>{switchHint}</p>\n ) : null}\n <p className={themeClasses.trustLine}>{copy.trustLine}</p>\n </div>\n </div>\n );\n}\n\nfunction interp(tpl: string, vars: Record<string, string>): string {\n return tpl.replace(/\\{(\\w+)\\}/g, (_m, k) => vars[k] ?? '');\n}\n\nfunction interpolateCopy(\n m: { tabLabel: string; bodyRows: readonly [string, string, string]; ctaTemplate: string; switchHint: string },\n price: string,\n days: string,\n) {\n return {\n tabLabel: m.tabLabel,\n bodyRows: m.bodyRows.map((r) => interp(r, { price, days })) as [string, string, string],\n ctaTemplate: m.ctaTemplate,\n switchHint: m.switchHint,\n };\n}\n","/**\n * Helpers de formatação de preço pro Hook.\n *\n * Preço vive no banco em CENTAVOS (int), sempre. Apps que renderizam preço\n * leem do hook `usePlan()` e passam por `formatBRL(cents)` — nunca formatam\n * inline. Isso evita os dois patterns errados que já vimos em conversões\n * Lovable→Hook: (a) strings hardcoded \"R$ 19,90\" no JSX, (b) divisões ad-hoc\n * por 100 + `toFixed(2)` que ignoram locale.\n *\n * Ver G72 em .claude/skills/hook-conversion-shared/catalog/known-gotchas.md.\n */\n\n/**\n * Formata centavos como BRL no locale pt-BR. Aceita null pra conveniência\n * (callers que lidam com `yearlyPriceCents: number | null`).\n *\n * Examples:\n * formatBRL(1990) → \"R$ 19,90\"\n * formatBRL(4999) → \"R$ 49,99\"\n * formatBRL(23988) → \"R$ 239,88\"\n * formatBRL(0) → \"R$ 0,00\"\n * formatBRL(null) → \"\"\n */\nexport function formatBRL(cents: number | null | undefined): string {\n if (cents === null || cents === undefined) return '';\n const reais = cents / 100;\n return new Intl.NumberFormat('pt-BR', {\n style: 'currency',\n currency: 'BRL',\n }).format(reais);\n}\n\n/**\n * Deriva \"preço mensal\" a partir do preço anual (em centavos). Round half-up\n * pra evitar R$ 19,899... → R$ 19,89 quando o usuário esperava R$ 19,90.\n *\n * Não assume que o creator configurou yearlyPriceCents \"redondo\": se ele\n * setou 23988 (= R$ 239,88), 23988/12 = 1999 (= R$ 19,99). Se setou 23880\n * (= R$ 238,80), 23880/12 = 1990 (= R$ 19,90).\n *\n * Example (papomaterno):\n * monthlyFromYearly(23988) = 1999 → formatBRL = \"R$ 19,99\"\n * monthlyFromYearly(23880) = 1990 → formatBRL = \"R$ 19,90\"\n */\nexport function monthlyFromYearly(yearlyCents: number | null | undefined): number {\n if (yearlyCents === null || yearlyCents === undefined) return 0;\n return Math.round(yearlyCents / 12);\n}\n\n/**\n * Deriva \"preço por dia\" (365 dias) a partir do anual, em centavos. Útil\n * pra copy tipo \"apenas R$ 0,66 por dia, menos que um café\".\n *\n * Example:\n * dailyFromYearly(23988) = 66 → formatBRL = \"R$ 0,66\"\n */\nexport function dailyFromYearly(yearlyCents: number | null | undefined): number {\n if (yearlyCents === null || yearlyCents === undefined) return 0;\n return Math.round(yearlyCents / 365);\n}\n\n/**\n * Deriva o preço-ancoragem (valor \"cheio\" riscado) como múltiplo do preço\n * real. Serve pra ancoragem psicológica em telas de paywall: mostra um valor\n * maior riscado antes do preço real pra o usuário sentir desconto.\n *\n * Com `anchorMultiplier` no `paywall_config`, o creator mantém só o preço\n * real no DB; a ancoragem acompanha automaticamente se o preço muda.\n *\n * Retorna `null` quando o multiplier não é utilizável (falta, ≤ 1, NaN,\n * Infinity). Caller deve cair no fallback (valor absoluto em\n * `paywall_config.anchorPriceCents`) ou pular a renderização da ancoragem.\n *\n * Examples:\n * computeAnchorCents(1999, 2.5) = 4998\n * computeAnchorCents(1999, undefined) = null\n * computeAnchorCents(1999, 1) = null // 1× não ancora nada\n * computeAnchorCents(1999, 0) = null\n * computeAnchorCents(1999, NaN) = null\n */\nexport function computeAnchorCents(\n baseCents: number,\n multiplier: number | null | undefined,\n): number | null {\n if (multiplier === null || multiplier === undefined) return null;\n if (!Number.isFinite(multiplier)) return null;\n if (multiplier <= 1) return null;\n return Math.round(baseCents * multiplier);\n}\n\n/**\n * Percentual de desconto (anchor → real), arredondado pra baixo pra nunca\n * overstate. Retorna 0 quando anchor ≤ real (sem desconto a mostrar).\n *\n * Examples:\n * discountPercent(4998, 1999) = 60 // (4998-1999)/4998 = 0.60...\n * discountPercent(3998, 1999) = 50\n * discountPercent(1000, 2000) = 0 // real > anchor\n * discountPercent(2000, 2000) = 0\n */\nexport function discountPercent(anchorCents: number, realCents: number): number {\n if (anchorCents <= realCents) return 0;\n return Math.floor(((anchorCents - realCents) / anchorCents) * 100);\n}\n","// template/src/components/paywall/PaywallProvider.tsx\nimport { createContext, type ReactNode } from 'react';\nimport { usePaywallState } from '../../hooks/usePaywallState';\n\n/**\n * Full return shape of `usePaywallState()`. Apps consuming via\n * `usePaywallContext()` get the same fields they'd get from the headless\n * hook directly — no internal-only fields hidden.\n *\n * This is the \"Level 3\" escape-hatch contract: any app can drop down to raw\n * context and render an entirely custom paywall, with the template still\n * owning state + telemetry + checkout dispatch.\n */\nexport type PaywallContextValue = ReturnType<typeof usePaywallState>;\n\n/**\n * Context that carries the full paywall state down to Lego blocks. Null\n * outside `<PaywallProvider>`. Consumer hook `usePaywallContext()` throws on\n * null to surface mis-mounted blocks early.\n */\nexport const PaywallContext = createContext<PaywallContextValue | null>(null);\n\nexport type PaywallProviderProps = {\n children: ReactNode;\n};\n\n/**\n * Owns the headless paywall state for one paywall surface. All Lego blocks\n * (PriceHeadline, AnchorPrice, FinePrint, refactored primitives) and the\n * composed `<Paywall>` read state via this provider.\n *\n * Multiple compositions can share state by sharing one `<PaywallProvider>`\n * parent (e.g. side-by-side variants on a dev/test page). Multiple\n * providers in the same tree get independent state.\n */\nexport function PaywallProvider({ children }: PaywallProviderProps) {\n const state = usePaywallState();\n return <PaywallContext.Provider value={state}>{children}</PaywallContext.Provider>;\n}\n","// template/src/components/paywall/usePaywallContext.ts\nimport { useContext } from 'react';\nimport { PaywallContext, type PaywallContextValue } from './PaywallProvider';\n\n/**\n * Consumer hook for the paywall context. Returns the non-null state object\n * (same shape as `usePaywallState()`) when called inside `<PaywallProvider>`.\n *\n * Throws `\"usePaywallContext must be used within <PaywallProvider>\"` when the\n * provider is missing — surfaces mis-mounted Lego blocks at render time\n * instead of silently rendering with stale or default state.\n */\nexport function usePaywallContext(): PaywallContextValue {\n const ctx = useContext(PaywallContext);\n if (!ctx) {\n throw new Error('usePaywallContext must be used within <PaywallProvider>');\n }\n return ctx;\n}\n","// template/src/components/paywall/PaywallMethodTabs.tsx\nimport type { CheckoutMethod } from '../../types/AppConfig';\nimport { usePaywallContext } from './usePaywallContext';\n\nexport type PaywallMethodTabsProps = {\n /** Tab labels keyed by checkout method. App-provided copy (not state). */\n labels: Partial<Record<CheckoutMethod, string>>;\n /** Wrapper className. */\n className?: string;\n /** Individual tab className. */\n tabClassName?: string;\n /** Individual tab className when active. */\n tabActiveClassName?: string;\n};\n\nexport function PaywallMethodTabs({\n labels,\n className,\n tabClassName,\n tabActiveClassName,\n}: PaywallMethodTabsProps) {\n const { methods, selectedMethod, selectMethod } = usePaywallContext();\n\n if (methods.length < 2) return null;\n\n return (\n <div role=\"tablist\" aria-label=\"Método de pagamento\" className={className}>\n {methods.map((m) => {\n const active = m === selectedMethod;\n const label = labels[m] ?? m;\n return (\n <button\n key={m}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n aria-controls={`paywall-tab-${m}`}\n tabIndex={active ? 0 : -1}\n onClick={() => selectMethod(m)}\n className={[tabClassName, active ? tabActiveClassName : '']\n .filter(Boolean)\n .join(' ')}\n >\n {label}\n </button>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/PaywallMethodContent.tsx\nimport type { PaywallCopy } from './types';\nimport { usePaywallContext } from './usePaywallContext';\n\nexport type PaywallMethodContentProps = {\n /**\n * App-provided copy keyed by method. `pix` covers both `pix-auto` and\n * `pix-once`. `cardConsumedTrial` is used when the active method is `card`\n * AND `hasConsumedTrial` (read from context) is true.\n */\n copy: Pick<PaywallCopy, 'pix' | 'card'> & {\n cardConsumedTrial?: PaywallCopy['cardConsumedTrial'];\n };\n /** Tab-panel wrapper className. */\n className?: string;\n /** Per-row className. */\n rowClassName?: string;\n};\n\nexport function PaywallMethodContent({ copy, className, rowClassName }: PaywallMethodContentProps) {\n const { selectedMethod, hasConsumedTrial } = usePaywallContext();\n\n const useCardConsumed =\n selectedMethod === 'card' && hasConsumedTrial && copy.cardConsumedTrial;\n const rows: readonly string[] = useCardConsumed\n ? copy.cardConsumedTrial!.bodyRows\n : selectedMethod === 'pix-auto' || selectedMethod === 'pix-once'\n ? copy.pix.bodyRows\n : copy.card.bodyRows;\n\n return (\n <div role=\"tabpanel\" id={`paywall-tab-${selectedMethod}`} className={className}>\n {rows.map((row, i) => (\n <div key={i} className={rowClassName}>\n {row}\n </div>\n ))}\n </div>\n );\n}\n","// template/src/components/paywall/PaywallCyclePicker.tsx\nimport type { ReactNode } from 'react';\nimport type { Cycle } from '../../types/AppConfig';\nimport { formatBRL } from '../../utils/price';\nimport { usePaywallContext } from './usePaywallContext';\n\nexport type CycleLabels = {\n annualLabel: string;\n monthlyLabel: string;\n annualSuffix: string;\n monthlySuffix: string;\n};\n\n/** Cycle picker visual variants. `default` preserves the current visual. */\nexport type PaywallCyclePickerVariant = 'default' | 'premium-gold' | 'pink-pill';\n\n/** State passed to the optional `render` escape hatch. */\nexport type PaywallCyclePickerRenderArgs = {\n cycles: readonly Cycle[];\n selected: Cycle;\n setCycle: (c: Cycle) => void;\n plan: ReturnType<typeof usePaywallContext>['plan'];\n anchorPriceCents: number | null;\n};\n\nexport type PaywallCyclePickerProps = {\n labels: CycleLabels;\n /** Root wrapper className. */\n className?: string;\n /** Per-card base className. */\n cardClassName?: string;\n /** Applied when the card is selected (in addition to `cardClassName`). */\n cardSelectedClassName?: string;\n /** Anchor strikethrough className inside the card. */\n anchorClassName?: string;\n /** Visual variant. Variants are sugar for className combos. */\n variant?: PaywallCyclePickerVariant;\n /**\n * Render-prop escape hatch. When provided, the picker returns the prop's\n * output wrapped in a root element with the configured `className`. State\n * plumbing stays; visual is 100% the app's.\n */\n render?: (state: PaywallCyclePickerRenderArgs) => ReactNode;\n};\n\n/**\n * Variant → className map. Variants are sugar — they expand to className\n * combos at render time and merge with app-provided className props.\n */\nconst VARIANT_CLASSES: Record<PaywallCyclePickerVariant, { card: string; cardSelected: string }> = {\n default: { card: '', cardSelected: '' },\n 'premium-gold': {\n card: '',\n cardSelected: 'border-2 border-yellow-400/80 ring-2 ring-yellow-400/20',\n },\n 'pink-pill': {\n card: 'rounded-2xl',\n cardSelected: 'border-2 border-pink-500',\n },\n};\n\nexport function PaywallCyclePicker({\n labels,\n className,\n cardClassName,\n cardSelectedClassName,\n anchorClassName,\n variant = 'default',\n render,\n}: PaywallCyclePickerProps) {\n const ctx = usePaywallContext();\n const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;\n\n // Cycles available come from the AppConfig.paywall.cycles via state.\n // Mirror existing default of MONTHLY + YEARLY when the hook doesn't expose\n // an array directly (it doesn't; cycles are derived in usePaywallState\n // but not surfaced on the return). For now, fall back to ['MONTHLY','YEARLY'].\n // The composed <Paywall> always passes both — single-cycle apps render null.\n const cycles: readonly Cycle[] = ['MONTHLY', 'YEARLY'];\n\n // Render-prop escape hatch — app owns the visual entirely.\n if (render) {\n return (\n <div className={className}>\n {render({ cycles, selected, setCycle, plan, anchorPriceCents })}\n </div>\n );\n }\n\n if (cycles.length < 2) return null;\n\n const v = VARIANT_CLASSES[variant];\n const composedCardClassName = [v.card, cardClassName].filter(Boolean).join(' ');\n const composedCardSelectedClassName = [v.cardSelected, cardSelectedClassName]\n .filter(Boolean)\n .join(' ');\n\n // Derive price-by-cycle from plan derivation (computed in usePaywallState).\n // monthlyCents / yearlyCents are present whenever paywall.mode !== 'free'.\n const monthlyCents = plan?.monthlyCents ?? 0;\n const yearlyCents = plan?.yearlyCents ?? 0;\n const anchorMonthly = plan?.anchorMonthlyCents ?? null;\n const anchorYearly = plan?.anchorYearlyCents ?? null;\n\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Ciclo de cobrança\"\n className={['flex flex-row gap-2', className].filter(Boolean).join(' ')}\n >\n {cycles.map((c) => {\n const active = c === selected;\n const label = c === 'YEARLY' ? labels.annualLabel : labels.monthlyLabel;\n const suffix = c === 'YEARLY' ? labels.annualSuffix : labels.monthlySuffix;\n // YEARLY card shows monthly-equiv as the main number; MONTHLY shows raw.\n const mainCents =\n c === 'YEARLY' ? Math.round(yearlyCents / 12) : monthlyCents;\n const anchorCents = c === 'YEARLY' ? anchorYearly : anchorMonthly;\n return (\n <button\n key={c}\n type=\"button\"\n role=\"radio\"\n aria-checked={active}\n onClick={() => setCycle(c)}\n className={[\n 'flex flex-col items-center gap-0.5',\n composedCardClassName,\n active ? composedCardSelectedClassName : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <span className=\"font-bold text-base leading-tight\">{formatBRL(mainCents)}</span>\n <span className=\"text-xs opacity-70 leading-tight\">{suffix}</span>\n <span className=\"text-xs opacity-60 leading-tight\">{label}</span>\n {anchorCents != null && anchorCents > mainCents ? (\n <span className={anchorClassName ?? 'text-xs opacity-50'}>\n <s>{formatBRL(anchorCents)}</s>\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/PaywallCta.tsx\nimport { usePaywallContext } from './usePaywallContext';\n\nexport type PaywallCtaProps = {\n /** Already-interpolated CTA label (e.g. \"Pagar R$ 19,90 com PIX\"). */\n ctaLabel: string;\n /** Label shown while `submitting === true`. Defaults to `ctaLabel`. */\n loadingLabel?: string;\n /**\n * Switch-hint copy shown under the CTA when the other method is available.\n * Caller decides visibility (typically only when `methods.length > 1`).\n */\n switchHint?: string;\n /** Trust line under the CTA / switch hint. */\n trustLine: string;\n /** Wrapper className. */\n className?: string;\n /** Button className. */\n buttonClassName?: string;\n /** Switch-hint paragraph className. */\n switchHintClassName?: string;\n /** Trust-line paragraph className. */\n trustClassName?: string;\n};\n\n/**\n * CTA button + switch hint + trust line. Reads `submit` + `submitting` from\n * context — the button dispatches the checkout on click and disables itself\n * while submitting. Apps wanting a different action (e.g. open a CPF modal\n * first) should compose via `<Paywall onBeforeCheckout>` or use raw context\n * with their own button.\n */\nexport function PaywallCta({\n ctaLabel,\n loadingLabel,\n switchHint,\n trustLine,\n className,\n buttonClassName,\n switchHintClassName,\n trustClassName,\n}: PaywallCtaProps) {\n const { submit, submitting } = usePaywallContext();\n const label = submitting && loadingLabel ? loadingLabel : ctaLabel;\n return (\n <div className={className}>\n <button\n type=\"button\"\n onClick={() => {\n void submit();\n }}\n disabled={submitting}\n className={buttonClassName}\n >\n {label}\n </button>\n {switchHint ? <p className={switchHintClassName}>{switchHint}</p> : null}\n <p className={trustClassName}>{trustLine}</p>\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallEyebrow.tsx\nexport type PaywallEyebrowProps = {\n text: string;\n className?: string;\n};\n\nconst DEFAULT_EYEBROW_CLASSES = 'text-xs uppercase tracking-widest font-semibold opacity-70';\n\nexport function PaywallEyebrow({ text, className }: PaywallEyebrowProps) {\n return (\n <div className={[DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(' ')}>\n {text}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallHero.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallHeroRenderState = {\n src: string;\n headline?: string;\n};\n\nexport type PaywallHeroProps = {\n src: string;\n alt?: string;\n headline?: string;\n aspectRatio?: string;\n gradientClassName?: string;\n className?: string;\n headlineClassName?: string;\n imgClassName?: string;\n render?: (state: PaywallHeroRenderState) => ReactNode;\n};\n\nconst DEFAULT_GRADIENT = 'absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent';\n\nexport function PaywallHero({\n src,\n alt = '',\n headline,\n aspectRatio = '16/9',\n gradientClassName,\n className,\n headlineClassName,\n imgClassName,\n render,\n}: PaywallHeroProps) {\n if (render) {\n return (\n <div className={className}>\n {render({ src, headline })}\n </div>\n );\n }\n\n return (\n <div\n className={['relative overflow-hidden', className].filter(Boolean).join(' ')}\n style={{ aspectRatio }}\n >\n <img\n src={src}\n alt={alt}\n className={['absolute inset-0 w-full h-full object-cover', imgClassName].filter(Boolean).join(' ')}\n />\n <div className={gradientClassName ?? DEFAULT_GRADIENT} aria-hidden=\"true\" />\n {headline ? (\n <h1\n className={['absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl', headlineClassName]\n .filter(Boolean)\n .join(' ')}\n >\n {headline}\n </h1>\n ) : null}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallHeadline.tsx\nexport type PaywallHeadlineProps = {\n text: string;\n className?: string;\n as?: 'h1' | 'h2';\n};\n\nconst DEFAULT_HEADLINE_CLASSES = 'text-2xl font-bold leading-tight';\n\nexport function PaywallHeadline({ text, className, as = 'h1' }: PaywallHeadlineProps) {\n const Tag = as;\n return (\n <Tag className={[DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(' ')}>\n {text}\n </Tag>\n );\n}\n","// template/src/components/paywall/blocks/PaywallPriceHeadline.tsx\nimport type { ReactNode } from 'react';\nimport { usePaywallContext } from '../usePaywallContext';\nimport { dailyFromYearly, formatBRL } from '../../../utils/price';\n\nexport type PaywallPriceHeadlineProps = {\n /**\n * Copy template. Supported substitutions:\n * - `{pricePerDay}` → daily price formatted (BRL), derived from yearly.\n * - `{currentMonthlyEquiv}` → formatted monthly-equivalent BRL.\n * - `{cycle}` → human-readable cycle (\"mensal\" | \"anual\").\n *\n * Example: `\"Comece hoje por {pricePerDay} por dia\"`.\n */\n template: string;\n className?: string;\n as?: 'h1' | 'h2' | 'h3';\n render?: (state: {\n pricePerDay: string;\n currentMonthlyEquivCents: number;\n cycle: string;\n }) => ReactNode;\n};\n\nconst DEFAULT_CLASS = 'text-2xl font-bold leading-tight';\n\nconst CYCLE_LABEL: Record<string, string> = {\n MONTHLY: 'mensal',\n YEARLY: 'anual',\n};\n\nexport function PaywallPriceHeadline({\n template,\n className,\n as = 'h1',\n render,\n}: PaywallPriceHeadlineProps) {\n const { cycle, currentMonthlyEquivCents, plan } = usePaywallContext();\n\n const yearlyCents = plan?.yearlyCents ?? null;\n const pricePerDay = formatBRL(dailyFromYearly(yearlyCents));\n const monthlyEquiv = currentMonthlyEquivCents ?? 0;\n const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();\n\n const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(' ');\n\n if (render) {\n const RootTag = as;\n return (\n <RootTag className={[className].filter(Boolean).join(' ') || undefined}>\n {render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle })}\n </RootTag>\n );\n }\n\n const text = template\n .replaceAll('{pricePerDay}', pricePerDay)\n .replaceAll('{currentMonthlyEquiv}', formatBRL(monthlyEquiv))\n .replaceAll('{cycle}', cycleLabel);\n\n const RootTag = as;\n return <RootTag className={rootClasses}>{text}</RootTag>;\n}\n","// template/src/components/paywall/blocks/PaywallCountdown.tsx\nimport { useEffect, useRef, useState, type ReactNode } from 'react';\n\nexport type PaywallCountdownRenderState = {\n h: number;\n m: number;\n s: number;\n expired: boolean;\n};\n\nexport type PaywallCountdownDeadline =\n | Date\n | string\n | { sessionStorageKey: string; durationMs: number };\n\nexport type PaywallCountdownProps = {\n deadline: PaywallCountdownDeadline;\n format?: 'h:m:s' | 'm:s';\n onExpire?: () => void;\n className?: string;\n render?: (state: PaywallCountdownRenderState) => ReactNode;\n};\n\nconst DEFAULT_COUNTDOWN_CLASSES = 'font-mono tabular-nums';\n\n/**\n * Resolve the absolute deadline timestamp (ms since epoch) from the polymorphic\n * `deadline` prop. For session-storage variant, persists `now + durationMs` on\n * first access so subsequent renders/sessions read the same target.\n */\nfunction resolveDeadlineMs(deadline: PaywallCountdownDeadline): number {\n if (deadline instanceof Date) return deadline.getTime();\n if (typeof deadline === 'string') return new Date(deadline).getTime();\n\n // sessionStorage-backed variant\n const { sessionStorageKey, durationMs } = deadline;\n if (typeof window === 'undefined' || typeof window.sessionStorage === 'undefined') {\n // SSR / no sessionStorage — fall back to now + durationMs (no persistence)\n return Date.now() + durationMs;\n }\n const stored = window.sessionStorage.getItem(sessionStorageKey);\n const parsed = stored ? Number.parseInt(stored, 10) : NaN;\n const now = Date.now();\n if (!Number.isFinite(parsed) || parsed < now) {\n const target = now + durationMs;\n window.sessionStorage.setItem(sessionStorageKey, String(target));\n return target;\n }\n return parsed;\n}\n\nfunction computeRemaining(deadlineMs: number): { h: number; m: number; s: number; expired: boolean } {\n const diff = Math.max(0, deadlineMs - Date.now());\n const totalSeconds = Math.floor(diff / 1000);\n const h = Math.floor(totalSeconds / 3600);\n const m = Math.floor((totalSeconds % 3600) / 60);\n const s = totalSeconds % 60;\n return { h, m, s, expired: diff === 0 };\n}\n\nfunction pad(n: number): string {\n return String(n).padStart(2, '0');\n}\n\nexport function PaywallCountdown({\n deadline,\n format = 'h:m:s',\n onExpire,\n className,\n render,\n}: PaywallCountdownProps) {\n // Resolve once per mount; deadline object identity changes shouldn't churn the timer.\n const deadlineMsRef = useRef<number | null>(null);\n if (deadlineMsRef.current === null) {\n deadlineMsRef.current = resolveDeadlineMs(deadline);\n }\n\n const [state, setState] = useState(() => computeRemaining(deadlineMsRef.current!));\n const expiredCalledRef = useRef(false);\n\n useEffect(() => {\n // If already expired on mount, fire onExpire once and skip the interval.\n if (state.expired) {\n if (!expiredCalledRef.current) {\n expiredCalledRef.current = true;\n onExpire?.();\n }\n return;\n }\n\n const tick = () => {\n const next = computeRemaining(deadlineMsRef.current!);\n setState(next);\n if (next.expired && !expiredCalledRef.current) {\n expiredCalledRef.current = true;\n onExpire?.();\n }\n };\n\n const id = setInterval(tick, 1000);\n return () => clearInterval(id);\n // onExpire intentionally excluded — we only want to fire it once per mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state.expired]);\n\n if (render) {\n return <div className={className}>{render(state)}</div>;\n }\n\n const formatted =\n format === 'h:m:s'\n ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}`\n : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;\n\n return (\n <div className={[DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(' ')}>\n {formatted}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallFeatures.tsx\nimport type { ComponentType, ReactNode } from 'react';\n\nexport type PaywallFeaturesRenderState = {\n items: readonly string[];\n};\n\nexport type PaywallFeaturesProps = {\n items: readonly string[];\n IconComponent?: ComponentType<{ className?: string }>;\n className?: string;\n itemClassName?: string;\n iconClassName?: string;\n render?: (state: PaywallFeaturesRenderState) => ReactNode;\n renderItem?: (item: string, idx: number) => ReactNode;\n};\n\nexport function PaywallFeatures({\n items,\n IconComponent,\n className,\n itemClassName,\n iconClassName,\n render,\n renderItem,\n}: PaywallFeaturesProps) {\n if (render) {\n return <div className={className}>{render({ items })}</div>;\n }\n\n if (renderItem) {\n return (\n <ul className={className}>\n {items.map((item, idx) => (\n <li key={idx}>{renderItem(item, idx)}</li>\n ))}\n </ul>\n );\n }\n\n return (\n <ul className={className}>\n {items.map((item, idx) => (\n <li key={idx} className={itemClassName}>\n {IconComponent ? (\n <IconComponent className={iconClassName} />\n ) : (\n <span className={iconClassName} aria-hidden=\"true\">✓</span>\n )}\n <span>{item}</span>\n </li>\n ))}\n </ul>\n );\n}\n","// template/src/components/paywall/blocks/PaywallFeaturesCard.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallFeaturesCardProps = {\n title?: string;\n items: readonly string[];\n className?: string;\n cardClassName?: string;\n titleClassName?: string;\n itemClassName?: string;\n renderItem?: (item: string, idx: number) => ReactNode;\n};\n\nconst DEFAULT_CARD_CLASSES = 'rounded-xl border p-4';\n\nexport function PaywallFeaturesCard({\n title,\n items,\n className,\n cardClassName,\n titleClassName,\n itemClassName,\n renderItem,\n}: PaywallFeaturesCardProps) {\n return (\n <div className={className}>\n <div className={[DEFAULT_CARD_CLASSES, cardClassName].filter(Boolean).join(' ')}>\n {title ? (\n <div className={['font-semibold mb-2', titleClassName].filter(Boolean).join(' ')}>\n {title}\n </div>\n ) : null}\n <ul>\n {items.map((item, idx) =>\n renderItem ? (\n <li key={idx}>{renderItem(item, idx)}</li>\n ) : (\n <li key={idx} className={itemClassName}>\n <span aria-hidden=\"true\">•</span> <span>{item}</span>\n </li>\n ),\n )}\n </ul>\n </div>\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallTrophyBadge.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallTrophyBadgeRenderState = {\n text: string;\n};\n\nexport type PaywallTrophyBadgeProps = {\n text: string;\n className?: string;\n iconClassName?: string;\n floating?: boolean;\n render?: (state: PaywallTrophyBadgeRenderState) => ReactNode;\n};\n\nconst DEFAULT_CHIP_CLASSES =\n 'inline-flex items-center gap-1 px-3 py-1 rounded-full bg-yellow-100 text-yellow-900 text-sm font-medium';\n\nconst FLOATING_CLASSES = 'absolute top-2 right-2 z-10 shadow-md';\n\nexport function PaywallTrophyBadge({\n text,\n className,\n iconClassName,\n floating = false,\n render,\n}: PaywallTrophyBadgeProps) {\n if (render) {\n return <div className={className}>{render({ text })}</div>;\n }\n\n const rootClasses = [\n DEFAULT_CHIP_CLASSES,\n floating ? FLOATING_CLASSES : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={rootClasses}>\n <span className={iconClassName} aria-hidden=\"true\">\n 🏆\n </span>\n <span>{text}</span>\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallAnchorPrice.tsx\nimport type { ReactNode } from 'react';\nimport { usePaywallContext } from '../usePaywallContext';\nimport { formatBRL } from '../../../utils/price';\n\nexport type PaywallAnchorPriceProps = {\n className?: string;\n render?: (state: { anchorCents: number; formatted: string }) => ReactNode;\n};\n\nconst DEFAULT_CLASS = 'text-sm opacity-60 line-through';\n\nexport function PaywallAnchorPrice({\n className,\n render,\n}: PaywallAnchorPriceProps) {\n const { anchorPriceCents, cycle } = usePaywallContext();\n\n if (anchorPriceCents === null || anchorPriceCents === undefined || anchorPriceCents <= 0) {\n return null;\n }\n\n void cycle;\n\n const formatted = formatBRL(anchorPriceCents);\n const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(' ');\n\n if (render) {\n return (\n <span className={className || undefined}>\n {render({ anchorCents: anchorPriceCents, formatted })}\n </span>\n );\n }\n\n return <span className={rootClasses}>{formatted}</span>;\n}\n","// template/src/components/paywall/blocks/PaywallTestimonials.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallTestimonial = {\n name: string;\n avatar?: string;\n stars: number;\n quote: string;\n};\n\nexport type PaywallTestimonialsProps = {\n items: readonly PaywallTestimonial[];\n className?: string;\n cardClassName?: string;\n avatarClassName?: string;\n quoteClassName?: string;\n nameClassName?: string;\n starsClassName?: string;\n renderItem?: (item: PaywallTestimonial, idx: number) => ReactNode;\n};\n\nconst DEFAULT_ROOT = 'flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2';\nconst DEFAULT_CARD =\n 'snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2';\nconst DEFAULT_AVATAR = 'w-10 h-10 rounded-full object-cover';\nconst DEFAULT_QUOTE = 'text-sm leading-snug';\nconst DEFAULT_NAME = 'text-xs font-semibold opacity-80';\nconst DEFAULT_STARS = 'text-yellow-500 text-sm';\n\nfunction clampStars(n: number): number {\n return Math.max(0, Math.min(5, Math.round(n)));\n}\n\nexport function PaywallTestimonials({\n items,\n className,\n cardClassName,\n avatarClassName,\n quoteClassName,\n nameClassName,\n starsClassName,\n renderItem,\n}: PaywallTestimonialsProps) {\n const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(' ');\n const cardClasses = [DEFAULT_CARD, cardClassName].filter(Boolean).join(' ');\n const avatarClasses = [DEFAULT_AVATAR, avatarClassName].filter(Boolean).join(' ');\n const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(' ');\n const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(' ');\n const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(' ');\n\n return (\n <div className={rootClasses}>\n {items.map((item, idx) => {\n if (renderItem) return renderItem(item, idx);\n const filled = clampStars(item.stars);\n const empty = 5 - filled;\n return (\n <div key={idx} className={cardClasses}>\n <div className=\"flex items-center gap-2\">\n {item.avatar ? (\n <img\n src={item.avatar}\n alt=\"\"\n loading=\"lazy\"\n className={avatarClasses}\n aria-hidden=\"true\"\n />\n ) : null}\n <div className={nameClasses}>{item.name}</div>\n </div>\n <div className={starsClasses} aria-label={`${filled} de 5 estrelas`}>\n {'★'.repeat(filled)}\n {'☆'.repeat(empty)}\n </div>\n <p className={quoteClasses}>{item.quote}</p>\n </div>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallStatsRow.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallStat = {\n value: string;\n label: string;\n icon?: ReactNode;\n};\n\nexport type PaywallStatsRowProps = {\n stats: readonly PaywallStat[];\n className?: string;\n cellClassName?: string;\n valueClassName?: string;\n labelClassName?: string;\n renderCell?: (stat: PaywallStat, idx: number) => ReactNode;\n};\n\nconst DEFAULT_ROOT = 'grid grid-cols-3 gap-4';\nconst DEFAULT_CELL = 'flex flex-col items-center text-center';\nconst DEFAULT_VALUE = 'text-2xl font-bold';\nconst DEFAULT_LABEL = 'text-xs opacity-70';\n\nexport function PaywallStatsRow({\n stats,\n className,\n cellClassName,\n valueClassName,\n labelClassName,\n renderCell,\n}: PaywallStatsRowProps) {\n const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(' ');\n const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(' ');\n const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(' ');\n const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(' ');\n\n return (\n <div className={rootClasses}>\n {stats.map((stat, idx) => {\n if (renderCell) return renderCell(stat, idx);\n return (\n <div key={idx} className={cellClasses}>\n {stat.icon ? <div aria-hidden=\"true\">{stat.icon}</div> : null}\n <div className={valueClasses}>{stat.value}</div>\n <div className={labelClasses}>{stat.label}</div>\n </div>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallFinePrint.tsx\nimport type { ReactNode } from 'react';\nimport { usePaywallContext } from '../usePaywallContext';\nimport { formatBRL } from '../../../utils/price';\n\nexport type PaywallFinePrintProps = {\n /**\n * Copy template. Supported substitutions:\n * - `{price}` → formatted current price (BRL).\n * - `{trialDays}` → method-specific trial days (card vs pix).\n * - `{cycle}` → human-readable cycle (\"mensal\" | \"anual\").\n */\n template: string;\n className?: string;\n render?: (state: {\n currentPriceCents: number;\n cycle: string;\n trialDays: number;\n selectedMethod: string;\n }) => ReactNode;\n};\n\nconst DEFAULT_CLASS = 'text-xs opacity-60 leading-snug';\n\nconst CYCLE_LABEL: Record<string, string> = {\n MONTHLY: 'mensal',\n YEARLY: 'anual',\n};\n\nexport function PaywallFinePrint({\n template,\n className,\n render,\n}: PaywallFinePrintProps) {\n const {\n currentPriceCents,\n cycle,\n trialDaysCard,\n trialDaysPix,\n selectedMethod,\n } = usePaywallContext();\n\n const trialDays = selectedMethod === 'card' ? trialDaysCard : trialDaysPix;\n const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();\n const priceFormatted = formatBRL(currentPriceCents ?? 0);\n\n const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(' ');\n\n if (render) {\n return (\n <p className={className || undefined}>\n {render({\n currentPriceCents: currentPriceCents ?? 0,\n cycle,\n trialDays: trialDays ?? 0,\n selectedMethod,\n })}\n </p>\n );\n }\n\n const text = template\n .replaceAll('{price}', priceFormatted)\n .replaceAll('{trialDays}', String(trialDays ?? 0))\n .replaceAll('{cycle}', cycleLabel);\n\n return <p className={rootClasses}>{text}</p>;\n}\n","// template/src/components/paywall/blocks/PaywallTrustLine.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallTrustLineItem = {\n icon: ReactNode;\n text: string;\n};\n\nexport type PaywallTrustLineProps = {\n items: readonly PaywallTrustLineItem[];\n className?: string;\n itemClassName?: string;\n renderItem?: (item: PaywallTrustLineItem, idx: number) => ReactNode;\n};\n\nconst DEFAULT_ROOT = 'flex items-center gap-3';\nconst DEFAULT_ITEM = 'flex items-center gap-1.5 text-xs';\n\nexport function PaywallTrustLine({\n items,\n className,\n itemClassName,\n renderItem,\n}: PaywallTrustLineProps) {\n const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(' ');\n const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(' ');\n return (\n <div className={rootClasses}>\n {items.map((item, idx) => {\n if (renderItem) return renderItem(item, idx);\n return (\n <span key={idx} className={itemClasses}>\n <span aria-hidden=\"true\">{item.icon}</span>\n <span>{item.text}</span>\n </span>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallStickyFooter.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallStickyFooterProps = {\n children: ReactNode;\n className?: string;\n /**\n * When true (default), appends `pb-[env(safe-area-inset-bottom)]` so the\n * footer clears the home-indicator on iOS. Set false for footers that\n * already opt into their own safe-area handling (e.g. inside a sheet).\n */\n safeAreaInsets?: boolean;\n};\n\nconst DEFAULT_CLASSES = 'sticky bottom-0 left-0 right-0 bg-background';\nconst SAFE_AREA_CLASS = 'pb-[env(safe-area-inset-bottom)]';\n\nexport function PaywallStickyFooter({\n children,\n className,\n safeAreaInsets = true,\n}: PaywallStickyFooterProps) {\n const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className]\n .filter(Boolean)\n .join(' ');\n return <div className={classes}>{children}</div>;\n}\n","/**\n * Plan-V — turnkey default PixWaitingPage. Renders the QR + polls subscription\n * status via SDK until status flips to active/trialing (webhook landed) or\n * the page times out.\n *\n * Reads QR payload from sessionStorage[`hook:paywall:pix-pending`] written by\n * CheckoutPageDefault. If missing, redirects to /paywall/checkout.\n */\nimport { useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useHook } from '@hook-sdk/sdk';\n\nconst PIX_PAYLOAD_KEY = 'hook:paywall:pix-pending';\nconst TIMEOUT_MS = 30 * 60 * 1000; // 30 min.\n\ntype PixPayload = {\n payload: string | null;\n base64: string | null;\n subscriptionId: string;\n pixAuthorizationId: string | null;\n};\n\nfunction readPixPayload(): PixPayload | null {\n if (typeof window === 'undefined') return null;\n try {\n const raw = sessionStorage.getItem(PIX_PAYLOAD_KEY);\n if (!raw) return null;\n return JSON.parse(raw) as PixPayload;\n } catch {\n return null;\n }\n}\n\nfunction clearPixPayload() {\n if (typeof window === 'undefined') return;\n try { sessionStorage.removeItem(PIX_PAYLOAD_KEY); } catch { /* */ }\n}\n\nexport function PixWaitingPageDefault() {\n const navigate = useNavigate();\n const { subscription } = useHook();\n const payload = useMemo(readPixPayload, []);\n const [copied, setCopied] = useState(false);\n const [timedOut, setTimedOut] = useState(false);\n\n // Missing payload → bounce back to checkout.\n useEffect(() => {\n if (!payload) navigate('/paywall/checkout', { replace: true });\n }, [payload, navigate]);\n\n // Land at the top — the checkout form may have been scrolled down when the\n // user hit submit, and we navigate here without resetting scroll.\n useEffect(() => {\n window.scrollTo(0, 0);\n }, []);\n\n // 30-min timeout.\n useEffect(() => {\n const t = setTimeout(() => setTimedOut(true), TIMEOUT_MS);\n return () => clearTimeout(t);\n }, []);\n\n // Watch subscription state. The `useSubscription` hook re-fetches via SDK;\n // if it polls or has SSE, we'll see status flip automatically.\n const hasAccess = subscription.hasAccess;\n useEffect(() => {\n if (hasAccess) {\n clearPixPayload();\n navigate('/', { replace: true });\n }\n }, [hasAccess, navigate]);\n\n async function copyPayload() {\n if (!payload?.payload) return;\n try {\n await navigator.clipboard.writeText(payload.payload);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n /* clipboard denied — keep going */\n }\n }\n\n if (!payload) return null;\n\n if (timedOut) {\n return (\n <div className=\"flex-1 flex flex-col items-center justify-center px-6 py-10 text-center bg-background space-y-4\">\n <h1 className=\"font-display text-2xl text-foreground\">PIX expirado</h1>\n <p className=\"text-sm text-muted-foreground\">O tempo pra pagar acabou. Gere um novo PIX.</p>\n <button\n onClick={() => {\n clearPixPayload();\n navigate('/paywall/checkout', { replace: true });\n }}\n className=\"rounded-xl bg-primary px-6 py-3 text-base font-semibold text-primary-foreground\"\n >\n Tentar novamente\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 flex flex-col items-center px-6 py-8 bg-background space-y-6\">\n <header className=\"text-center space-y-2\">\n <h1 className=\"font-display text-2xl text-foreground\">Pague o PIX</h1>\n <p className=\"text-sm text-muted-foreground\">\n Escaneie o QR Code no app do seu banco. O acesso libera assim que confirmarmos o pagamento.\n </p>\n </header>\n\n {payload.base64 ? (\n <img\n src={`data:image/png;base64,${payload.base64}`}\n alt=\"QR Code PIX\"\n className=\"w-64 h-64 rounded-2xl border border-border bg-card p-2\"\n />\n ) : (\n <div className=\"w-64 h-64 rounded-2xl border border-border bg-card flex items-center justify-center text-sm text-muted-foreground\">\n QR indisponível\n </div>\n )}\n\n {payload.payload ? (\n <button\n onClick={copyPayload}\n className=\"w-full max-w-xs rounded-xl border border-border bg-card px-4 py-3 text-sm font-medium text-foreground\"\n >\n {copied ? '✓ Copiado!' : 'Copiar código PIX'}\n </button>\n ) : null}\n\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <span className=\"inline-block w-2 h-2 rounded-full bg-primary animate-pulse\" />\n Aguardando pagamento…\n </div>\n\n <p className=\"text-center text-xs text-muted-foreground\">\n Pode fechar essa janela — também enviamos um link de acesso pro seu e-mail.\n </p>\n </div>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseLoginFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markEmailTouched: () => void;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markPasswordTouched: () => void;\n /** True after the user has attempted submit at least once. */\n formSubmitAttempted: boolean;\n /**\n * Submete o form. Retorna true se o login deu OK (cookies setados), false\n * se validação falhou, credenciais inválidas, rate-limit ou erro de rede.\n * Em caso de false, `error` state é populado com detalhes.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n /**\n * Dispara OAuth Google: redireciona pro backend `/api/auth/oauth/google/start`.\n * Fire-and-forget — a página é descarregada antes de qualquer retorno.\n * Volta pro app logado (ou com `?oauth_error=...` em falha).\n */\n loginWithGoogle: () => void;\n}\n\nexport function useLoginForm(): UseLoginFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const [touchedEmail, setTouchedEmail] = useState(false);\n const [touchedPassword, setTouchedPassword] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n const validateEmail = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const validatePassword = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;\n const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;\n\n const canSubmit =\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n validateEmail === null &&\n validatePassword === null &&\n !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n setFormSubmitAttempted(true);\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.login({ email, password });\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, password, canSubmit]);\n\n return {\n email, setEmail, emailError,\n markEmailTouched: () => setTouchedEmail(true),\n password, setPassword, passwordError,\n markPasswordTouched: () => setTouchedPassword(true),\n formSubmitAttempted,\n submit, submitting, canSubmit, error,\n loginWithGoogle: () => auth.loginWithGoogle(),\n };\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseSignupFormResult {\n name: string;\n setName: (v: string) => void;\n nameError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markNameTouched: () => void;\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markEmailTouched: () => void;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markPasswordTouched: () => void;\n /** True after the user has attempted submit at least once. */\n formSubmitAttempted: boolean;\n /**\n * Submete o form. Retorna true se o signup deu OK (backend respondeu 2xx),\n * false se validação falhou, houve erro de rede/servidor, ou email já em uso.\n * Em caso de false, `error` state é populado com detalhes.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n /**\n * Dispara OAuth Google: mesmo endpoint que `useLoginForm.loginWithGoogle`.\n * Backend decide entre `signup_new`, `auto_linked`, ou `login_existing`\n * via `linkPolicy` — do ponto de vista do usuário \"criar conta com Google\"\n * e \"entrar com Google\" são o mesmo botão.\n */\n loginWithGoogle: () => void;\n}\n\nexport function useSignupForm(): UseSignupFormResult {\n const { auth } = useHook();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n // Wave 5 #42: per-field touched + formSubmitAttempted gate inline error\n // visibility so the user does not see \"invalid email\" on the first\n // keystroke. Errors only appear after blur OR after the first submit.\n const [touchedName, setTouchedName] = useState(false);\n const [touchedEmail, setTouchedEmail] = useState(false);\n const [touchedPassword, setTouchedPassword] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n const validateName = useMemo(() => {\n if (name.length === 0) return null;\n if (name.trim().length < 2) return 'Nome muito curto.';\n return null;\n }, [name]);\n\n const validateEmail = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const validatePassword = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const nameError = touchedName || formSubmitAttempted ? validateName : null;\n const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;\n const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;\n\n const canSubmit =\n name.trim().length >= 2 &&\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n validateName === null &&\n validateEmail === null &&\n validatePassword === null &&\n !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n setFormSubmitAttempted(true);\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.signup({ name, email, password });\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, name, email, password, canSubmit]);\n\n return {\n name, setName, nameError,\n markNameTouched: () => setTouchedName(true),\n email, setEmail, emailError,\n markEmailTouched: () => setTouchedEmail(true),\n password, setPassword, passwordError,\n markPasswordTouched: () => setTouchedPassword(true),\n formSubmitAttempted,\n submit, submitting, canSubmit, error,\n loginWithGoogle: () => auth.loginWithGoogle(),\n };\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport interface UseForgotFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markEmailTouched: () => void;\n /** True after the user has attempted submit at least once. */\n formSubmitAttempted: boolean;\n /**\n * Submete o form. Retorna true se o backend aceitou a requisição (email\n * de reset foi enfileirado — sem leak de \"existe esse email\" por design),\n * false se validação falhou, rate-limit ou erro de rede.\n * Em caso de sucesso, `sent` state também é setado para true.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n sent: boolean;\n error: AuthFormError | null;\n}\n\nexport function useForgotForm(): UseForgotFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [sent, setSent] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n const [touchedEmail, setTouchedEmail] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n const validateEmail = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;\n const canSubmit = email.length > 0 && validateEmail === null && !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n setFormSubmitAttempted(true);\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.forgot({ email });\n setSent(true);\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, canSubmit]);\n\n return {\n email, setEmail, emailError,\n markEmailTouched: () => setTouchedEmail(true),\n formSubmitAttempted,\n submit, submitting, canSubmit, sent, error,\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst MIN_PASSWORD = 8;\n\nexport interface UseResetFormResult {\n /** Token JWT lido de `?token=` da URL. null se ausente. */\n token: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markPasswordTouched: () => void;\n confirm: string;\n setConfirm: (v: string) => void;\n confirmError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markConfirmTouched: () => void;\n /** True after the user has attempted submit at least once. */\n formSubmitAttempted: boolean;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n /** true após submit 200. UI deve mostrar \"senha alterada, volte pro login\". */\n done: boolean;\n error: AuthFormError | null;\n}\n\n/**\n * Hook headless pro fluxo de reset de senha via link do email.\n *\n * Lê `?token=` da URL atual automaticamente (readonly snapshot no mount).\n * Se token ausente, `canSubmit` fica false + `token: null` pra UI mostrar\n * mensagem \"link inválido\".\n *\n * Após submit 200, todos os refresh tokens do user são revogados pelo\n * backend (forçar re-login). UI deve direcionar pra LoginScreen.\n */\nexport function useResetForm(): UseResetFormResult {\n const { auth } = useHook();\n const [token, setToken] = useState<string | null>(null);\n const [password, setPassword] = useState('');\n const [confirm, setConfirm] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [done, setDone] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const [touchedPassword, setTouchedPassword] = useState(false);\n const [touchedConfirm, setTouchedConfirm] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n useEffect(() => {\n // Snapshot no mount. URL pode ter sido limpa depois (history.replaceState)\n // mas token deve estar no primeiro render.\n if (typeof window === 'undefined') return;\n const params = new URLSearchParams(window.location.search);\n const t = params.get('token');\n setToken(t && t.length > 0 ? t : null);\n }, []);\n\n const validatePassword = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const validateConfirm = useMemo(() => {\n if (confirm.length === 0) return null;\n if (confirm !== password) return 'Senhas não coincidem.';\n return null;\n }, [confirm, password]);\n\n const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;\n const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;\n\n const canSubmit =\n token !== null &&\n password.length >= MIN_PASSWORD &&\n confirm === password &&\n validatePassword === null &&\n validateConfirm === null &&\n !submitting &&\n !done;\n\n const submit = useCallback(async () => {\n setFormSubmitAttempted(true);\n if (!canSubmit || token === null) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.reset({ token, newPassword: password });\n setDone(true);\n // Limpa `?token=&screen=reset` da URL pra AuthGate não re-disparar Reset\n // em re-renders futuros (logout depois do reset, popstate, etc.).\n // Mantém mesmo path, só strip dos query params de auth.\n if (typeof window !== 'undefined') {\n const url = new URL(window.location.href);\n url.searchParams.delete('token');\n url.searchParams.delete('screen');\n window.history.replaceState({}, '', url.toString());\n }\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, token, password, canSubmit]);\n\n return {\n token,\n password, setPassword, passwordError,\n markPasswordTouched: () => setTouchedPassword(true),\n confirm, setConfirm, confirmError,\n markConfirmTouched: () => setTouchedConfirm(true),\n formSubmitAttempted,\n submit, submitting, canSubmit, done, error,\n };\n}\n","import { useEffect } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nlet warned = false;\n\n/** Test-only: reseta flag pra permitir validar warn uma única vez em re-mounts de test */\nexport function __resetWarnForTest() { warned = false; }\n\n/**\n * Escape hatch pra screens FORA do fluxo de auth (ex: settings/trocar-senha).\n * Pra LoginScreen/SignupScreen/ForgotScreen custom, use useLoginForm/useSignupForm/useForgotForm.\n */\nexport function useAuthPrimitives() {\n const { auth } = useHook();\n\n useEffect(() => {\n if (!warned && process.env.NODE_ENV !== 'production') {\n warned = true;\n console.warn(\n '[@hook-sdk/template] useAuthPrimitives() é escape hatch. ' +\n 'Pra login/signup/forgot, use useLoginForm/useSignupForm/useForgotForm. ' +\n 'Docs: docs/19-golden-template.md#escape-hatch',\n );\n }\n }, []);\n\n return {\n login: auth.login,\n signup: auth.signup,\n logout: auth.logout,\n logoutAll: auth.logoutAll,\n forgot: auth.forgot,\n resendVerify: auth.resendVerify,\n changePassword: auth.changePassword,\n changeEmail: auth.changeEmail,\n refresh: auth.refresh,\n };\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre useHook(). Expõe apenas `user`, `authStatus` e `refresh`\n * pros consumidores que não precisam das methods completas do auth.\n */\nexport function useAuth() {\n const { user, authStatus, auth } = useHook();\n return {\n user,\n authStatus,\n refresh: auth.refresh,\n };\n}\n","// Entry point\nexport {\n AppRoot,\n PaymentReturnHandler,\n type AppRootProps,\n type AppRootSlots,\n type AuthScreenProps,\n type SkipDefaults,\n} from './AppRoot';\n\n// Dev-only — staging skip-onboarding helpers. The component is tree-shaken\n// from prod builds via the build-time `VITE_HOOK_DEV_TOOLS` env gate (see\n// `dev/env.ts`). Exposed for advanced consumers that want to mount the FAB\n// outside of AppRoot or call `skipOnboarding` programmatically from tests.\nexport {\n DevSkipOnboardingFab,\n skipOnboarding,\n} from './dev/DevSkipOnboardingFab';\nexport { isDevToolsEnabled } from './dev/env';\n\n// Components\nexport { PushPrompt, type PushPromptProps, type PushPromptTexts } from './components/PushPrompt';\nexport { InstallGate, InstallSplash } from './components/InstallGate';\nexport { LanguageSwitcher, type LanguageSwitcherProps } from './components/LanguageSwitcher';\n\n// i18n\nexport { I18nProvider, type I18nProviderProps } from './i18n/I18nProvider';\n\n// State helpers\nexport { LoadingState } from './defaults/LoadingState';\nexport { EmptyState } from './defaults/EmptyState';\nexport { ErrorBoundary } from './defaults/ErrorBoundary';\n\n// Plan-V — pay-first signup default screens.\nexport { CheckoutPageDefault } from './defaults/CheckoutPageDefault';\nexport { PixWaitingPageDefault } from './defaults/PixWaitingPageDefault';\n\n// DeepLinkHandler — usually mounted by <AppRoot> but exported for advanced use.\nexport { DeepLinkHandler } from './DeepLinkHandler';\n\n// Hooks padrão\nexport { useLoginForm, type UseLoginFormResult } from './hooks/useLoginForm';\nexport { useSignupForm } from './hooks/useSignupForm';\nexport { useForgotForm } from './hooks/useForgotForm';\nexport { useResetForm, type UseResetFormResult } from './hooks/useResetForm';\nexport {\n useCheckoutForm,\n type UseCheckoutFormResult,\n type UseCheckoutFormArgs,\n type CheckoutCardInput,\n type CheckoutFormCycle,\n type CheckoutFormMethod,\n} from './hooks/useCheckoutForm';\nexport {\n usePaywallState,\n type SubscriptionStatus,\n type PaymentMethod,\n type PixPending,\n} from './hooks/usePaywallState';\nexport { usePlan, type PlanInfo, type PlanState } from './hooks/usePlan';\n\n// Price helpers — use junto com usePlan() pra não hardcodar R$ em screens.\n// Ver G72 em .claude/skills/hook-conversion-shared/catalog/known-gotchas.md.\nexport {\n formatBRL,\n monthlyFromYearly,\n dailyFromYearly,\n computeAnchorCents,\n discountPercent,\n} from './utils/price';\n\n// Escape hatch\nexport { useAuthPrimitives } from './hooks/useAuthPrimitives';\n\n// Convenience\nexport { useAuth } from './hooks/useAuth';\n// Re-export from SDK so apps can import everything from @hook-sdk/template.\n// Apps with custom onboarding (Lovable conversions etc — i.e. NOT using the\n// template's <OnboardingFlow>) call this from each screen to feed Studio's\n// \"Onde estão saindo\" dropoff section.\nexport { useTrackOnboardingStep } from '@hook-sdk/sdk';\nexport { useSubscription } from './hooks/useSubscription';\nexport { usePush } from './hooks/usePush';\nexport { useReminders } from './hooks/useReminders';\nexport { useToast, type ToastItem } from './hooks/useToast';\nexport {\n useInstallPrompt,\n shouldBlockInstall,\n shouldShowPermanentOption,\n detectPlatform,\n detectIOSBrowser,\n detectAndroidBrowser,\n detectInAppApp,\n detectStandalone,\n type Platform,\n type IOSBrowser,\n type AndroidBrowser,\n type InAppApp,\n type InstallVariant,\n type InstallState,\n type InstallActions,\n} from './hooks/useInstallPrompt';\n\n// Types\nexport type { AuthFormError, AuthFormErrorCode } from './errors';\n\n// PT-BR error code → user message map (Asaas-driven). Used internally by\n// usePaywallState when paywall.errorMessages === 'default'; exported for\n// apps composing their own error UX.\nexport { asaasErrorMessage } from './errors/asaas-pt-br';\n\n// R2-W3 primitives\nexport { RouteBoundary, type RouteBoundaryProps } from './RouteBoundary';\nexport { PreAuthShell, type PreAuthShellProps } from './PreAuthShell';\nexport { PersistenceRegistry, type PersistenceRegistryProps } from './PersistenceRegistry';\nexport {\n OnboardingFlow,\n type OnboardingFlowProps,\n type OnboardingStepDef,\n} from './OnboardingFlow';\nexport { useOnboardingStep, type OnboardingStepCtx } from './hooks/useOnboardingStep';\nexport { useFeature } from './hooks/useFeature';\nexport { AppConfigProvider, useAppConfig } from './config/AppConfigContext';\nexport { parseAppConfig, AppConfigSchema } from './config/schema';\n\n// AppConfig (R2-W3 — declarative spine)\nexport type {\n AppConfig,\n AuthFlowConfig,\n PaywallConfig,\n PersistedKey,\n OnboardingConfig,\n OnboardingStep,\n DeepLinks,\n I18nConfig,\n Cycle,\n CheckoutMethod,\n} from './types/AppConfig';\nexport type { PushUiState } from './hooks/usePush';\n\n// Paywall composed component + primitives + Lego blocks (template 0.24 — flexibility-max).\n// Three customization levels (see CHANGELOG 0.24.0):\n// L1: <Paywall> opinionated default (back-compat 0.23.x).\n// L2: <PaywallProvider> + Lego blocks (compose per-app layout).\n// L3: <PaywallProvider> + usePaywallContext() (write 100% custom JSX).\nexport {\n // Composed top-level (Level 1).\n Paywall,\n // Headless state plumbing (Level 2 + Level 3).\n PaywallProvider,\n PaywallContext,\n usePaywallContext,\n // Refactored primitives (read state via context).\n PaywallMethodTabs,\n PaywallMethodContent,\n PaywallCyclePicker,\n PaywallCta,\n // Lego blocks (14 new in 0.24.0).\n PaywallEyebrow,\n PaywallHero,\n PaywallHeadline,\n PaywallPriceHeadline,\n PaywallCountdown,\n PaywallFeatures,\n PaywallFeaturesCard,\n PaywallTrophyBadge,\n PaywallAnchorPrice,\n PaywallTestimonials,\n PaywallStatsRow,\n PaywallFinePrint,\n PaywallTrustLine,\n PaywallStickyFooter,\n // Types.\n type PaywallProps,\n type PaywallCopy,\n type PaywallMethodCopy,\n type PaywallThemeClasses,\n type PaywallSlots,\n type PaywallContextValue,\n type PaywallProviderProps,\n type PaywallMethodTabsProps,\n type PaywallMethodContentProps,\n type PaywallCyclePickerProps,\n type PaywallCtaProps,\n type PaywallEyebrowProps,\n type PaywallHeroProps,\n type PaywallHeadlineProps,\n type PaywallPriceHeadlineProps,\n type PaywallCountdownProps,\n type PaywallFeaturesProps,\n type PaywallFeaturesCardProps,\n type PaywallTrophyBadgeProps,\n type PaywallAnchorPriceProps,\n type PaywallTestimonialsProps,\n type PaywallTestimonial,\n type PaywallStatsRowProps,\n type PaywallStat,\n type PaywallFinePrintProps,\n type PaywallTrustLineProps,\n type PaywallStickyFooterProps,\n type CycleLabels,\n} from './components/paywall';\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre `subscription` do SDK. MVP: apenas status (stub retorna 'none').\n */\nexport function useSubscription() {\n const { subscription } = useHook();\n return {\n status: subscription.status(),\n };\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type { ReminderSlot } from '@hook-sdk/sdk';\n\nexport function useReminders() {\n const { push } = useHook();\n const r = push.reminders;\n const [reminders, setReminders] = useState<ReminderSlot[]>([]);\n const [loading, setLoading] = useState(true);\n\n const reload = useCallback(async () => {\n setLoading(true);\n try {\n const next = await r.list();\n setReminders(next);\n } finally {\n setLoading(false);\n }\n }, [r]);\n\n useEffect(() => { void reload(); }, [reload]);\n\n const setReminder = useCallback(async (input: {\n slot: string; timeLocal: string; timezone: string; enabled: boolean;\n }) => {\n await r.set(input);\n await reload();\n }, [r, reload]);\n\n const deleteReminder = useCallback(async (slot: string) => {\n await r.delete(slot);\n await reload();\n }, [r, reload]);\n\n const schedule = useCallback(async (items: Parameters<typeof r.schedule>[0]) => {\n return r.schedule(items);\n }, [r]);\n\n const setFallbacks = useCallback(async (items: Parameters<typeof r.setFallbacks>[0]) => {\n return r.setFallbacks(items);\n }, [r]);\n\n return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };\n}\n","import { useCallback, useState } from 'react';\n\nexport interface ToastItem {\n id: string;\n message: string;\n kind: 'info' | 'error' | 'success';\n}\n\n/**\n * Toast mínimo in-memory. MVP: IA renderiza a lista onde quiser (ex: no final do <Home>).\n * Não opina sobre UI; retorna items + actions.\n */\nexport function useToast() {\n const [items, setItems] = useState<ToastItem[]>([]);\n\n const show = useCallback((message: string, kind: ToastItem['kind'] = 'info') => {\n const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n setItems((prev) => [...prev, { id, message, kind }]);\n setTimeout(() => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, 4000);\n }, []);\n\n const dismiss = useCallback((id: string) => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return { items, show, dismiss };\n}\n","import type { ReactNode } from 'react';\nimport { Routes, Route } from 'react-router-dom';\n\nexport type RouteBoundaryProps = { children: ReactNode };\n\nexport function RouteBoundary({ children }: RouteBoundaryProps) {\n return (\n <Routes>\n {children}\n <Route path=\"*\" element={<DefaultNotFound />} />\n </Routes>\n );\n}\n\nfunction DefaultNotFound() {\n return <div role=\"alert\">Página não encontrada</div>;\n}\n","import type { ReactNode } from 'react';\nimport { BrowserRouter, MemoryRouter, Routes } from 'react-router-dom';\n\nexport type PreAuthShellProps = {\n basename?: string;\n /** Test-only escape hatch — use MemoryRouter so jsdom doesn't fight document.location. */\n testRouter?: 'memory';\n /** Optional initial entries for MemoryRouter; ignored otherwise. */\n testInitialEntries?: string[];\n children: ReactNode;\n};\n\nexport function PreAuthShell({\n basename,\n testRouter,\n testInitialEntries,\n children,\n}: PreAuthShellProps) {\n if (testRouter === 'memory') {\n return (\n <MemoryRouter basename={basename} initialEntries={testInitialEntries}>\n <Routes>{children}</Routes>\n </MemoryRouter>\n );\n }\n return (\n <BrowserRouter basename={basename}>\n <Routes>{children}</Routes>\n </BrowserRouter>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, type ComponentType } from 'react';\nimport { usePersistedState, useHook } from '@hook-sdk/sdk';\nimport { OnboardingStepContext } from './hooks/useOnboardingStep';\n\nexport type OnboardingStepDef = {\n id: string;\n screen: string;\n validates?: string[];\n};\n\nexport type OnboardingFlowProps = {\n steps: OnboardingStepDef[];\n screens: Record<string, ComponentType>;\n onComplete: (value: Record<string, unknown>) => void;\n persistKey: string;\n};\n\nconst isFilled = (v: unknown): boolean => v != null && v !== '';\n\nconst CURRENT_STEP_FIELD = 'currentStep';\n\nfunction readPersistedStepIdx(draft: Record<string, unknown>): number {\n const raw = draft[CURRENT_STEP_FIELD];\n return typeof raw === 'number' && Number.isFinite(raw) && raw >= 0 ? raw : 0;\n}\n\nexport function OnboardingFlow({\n steps,\n screens,\n onComplete,\n persistKey,\n}: OnboardingFlowProps) {\n // Audit Wave 2 (Fix #3): currentStep mora dentro do mesmo blob de\n // `persistKey` (default `onboarding_data`). Cold-start re-mount hidrata\n // currentStep e renderiza no step certo em vez de cair em step 0.\n const [draft, setDraft, status] = usePersistedState<Record<string, unknown>>(persistKey, {});\n const draftRef = useRef(draft);\n draftRef.current = draft;\n\n const idx = readPersistedStepIdx(draft);\n const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));\n\n const setIdx = useCallback(\n (n: number | ((prev: number) => number)) => {\n setDraft((prev) => {\n const prevIdx = readPersistedStepIdx(prev);\n const nextIdx = typeof n === 'function' ? n(prevIdx) : n;\n return { ...prev, [CURRENT_STEP_FIELD]: nextIdx };\n });\n },\n [setDraft],\n );\n\n const setValue = useCallback(\n (patch: Record<string, unknown>) => {\n // Mirror to ref so a `next()` in the same handler sees the new value\n // before React commits the state update.\n draftRef.current = { ...draftRef.current, ...patch };\n setDraft((prev) => ({ ...prev, ...patch }));\n },\n [setDraft],\n );\n\n // step lookup (NOT a hook). Run before useMemo for `valid` to use it.\n const step = steps[clampedIdx];\n\n // Analytics: emit `onboarding_step_viewed` whenever the rendered step changes.\n // Fire-and-forget via SDK track(). `step.id` is app-defined (free string from\n // app.config.json) — Studio dropoff query buckets by `properties.step` to\n // surface where users abandon onboarding pre-trial. Hydration is gated below\n // (status.loading), so this only fires after persisted state is ready.\n // Defensive: legacy test mocks may not expose `track`. Treat missing as no-op.\n const hookCtx = useHook() as ReturnType<typeof useHook> & {\n track?: (event: string, props?: Record<string, unknown>) => void;\n };\n const track = typeof hookCtx.track === 'function' ? hookCtx.track : undefined;\n useEffect(() => {\n if (status.loading) return;\n if (!step) return;\n if (!track) return;\n track('onboarding_step_viewed', {\n step: step.id,\n step_index: clampedIdx,\n total_steps: steps.length,\n });\n }, [step?.id, clampedIdx, steps.length, status.loading, track]);\n\n const valid = useMemo(\n () => (step ? (step.validates ?? []).every((field) => isFilled(draft[field])) : false),\n [draft, step],\n );\n\n const next = useCallback(() => {\n if (!step) return;\n const current = draftRef.current;\n const validNow = (step.validates ?? []).every((field) => isFilled(current[field]));\n if (!validNow) return;\n if (clampedIdx + 1 >= steps.length) {\n onComplete(current);\n } else {\n setIdx(clampedIdx + 1);\n }\n }, [clampedIdx, onComplete, step, steps.length, setIdx]);\n\n const prevStep = useCallback(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);\n\n const ctx = useMemo(\n () => ({\n stepIndex: clampedIdx,\n totalSteps: steps.length,\n value: draft,\n setValue,\n valid,\n next,\n prev: prevStep,\n }),\n [clampedIdx, steps.length, draft, setValue, valid, next, prevStep],\n );\n\n // Audit Wave 2 (Fix #3): block render durante hydration pra evitar\n // flicker step-0 → step-N. Coloca DEPOIS dos hooks (rules-of-hooks:\n // todo hook chamado em toda renderização, mesmo as que retornam null).\n if (status.loading) {\n return null;\n }\n\n if (!step) {\n throw new Error(\n `[hook-template] OnboardingFlow: step index ${clampedIdx} out of range (steps.length=${steps.length})`,\n );\n }\n const Screen = screens[step.screen];\n if (!Screen) {\n throw new Error(\n `[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`,\n );\n }\n\n return (\n <OnboardingStepContext.Provider value={ctx}>\n <Screen />\n </OnboardingStepContext.Provider>\n );\n}\n","import { createContext, useContext } from 'react';\n\nexport type OnboardingStepCtx = {\n stepIndex: number;\n totalSteps: number;\n next: () => void;\n prev: () => void;\n value: Record<string, unknown>;\n setValue: (patch: Record<string, unknown>) => void;\n valid: boolean;\n};\n\nexport const OnboardingStepContext = createContext<OnboardingStepCtx | null>(null);\n\nexport function useOnboardingStep(): OnboardingStepCtx {\n const ctx = useContext(OnboardingStepContext);\n if (!ctx) {\n throw new Error(\n '[hook-template] useOnboardingStep must be used inside <OnboardingFlow>. (G75)',\n );\n }\n return ctx;\n}\n","import { useAppConfig } from '../config/AppConfigContext';\n\n/**\n * Returns `true` when `app.config.json.features_enabled` includes `name`.\n * Use to gate optional UI surfaces (e.g. share button, premium-only screens)\n * without scattering the feature list across the codebase.\n */\nexport function useFeature(name: string): boolean {\n const config = useAppConfig();\n return Array.isArray(config.features_enabled) && config.features_enabled.includes(name);\n}\n"],"mappings":"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","names":["useMemo","useHook","jsx","useEffect","createContext","useContext","jsx","jsx","useContext","useMemo","useHook","useEffect","useHook","track","track","useHook","useContext","useMemo","result","Fragment","jsx","Paywall","useEffect","useRef","useCallback","useEffect","useState","jsx","jsx","jsxs","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","Step","jsx","jsxs","Step","jsx","jsxs","Step","useState","jsx","jsxs","useState","Step","jsx","jsxs","Fragment","jsx","jsxs","useRef","useEffect","useEffect","useRef","useState","useHook","jsx","jsxs","useState","useHook","jsx","jsxs","Fragment","jsx","jsxs","useEffect","jsx","useCallback","useRef","useState","useHook","usePersistedState","jsx","useHook","useState","useRef","usePersistedState","useCallback","useCallback","useEffect","useRef","useState","useHook","Fragment","jsx","jsxs","track","overlayStyle","Fragment","jsx","jsxs","Paywall","useMemo","useHook","useCallback","useEffect","useState","useHook","DISMISS_TTL_MS","jsx","jsxs","PushPrompt","usePersistedState","jsx","jsxs","usePersistedState","jsx","jsx","jsxs","useEffect","useMemo","useState","useNavigate","useCallback","useEffect","useMemo","useRef","useState","useHook","useHook","useState","useCallback","useRef","useEffect","useMemo","args","useHook","useEffect","useMemo","useHook","createContext","jsx","createContext","useContext","useContext","jsx","jsx","jsx","jsxs","jsx","jsxs","track","useHook","useMemo","useEffect","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","RootTag","useEffect","useRef","useState","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","DEFAULT_CLASS","jsx","jsxs","jsx","jsxs","DEFAULT_ROOT","jsx","DEFAULT_CLASS","CYCLE_LABEL","jsx","jsxs","DEFAULT_ROOT","jsx","Fragment","jsx","jsxs","useNavigate","useMemo","useState","useEffect","trialDays","Spinner","useEffect","useMemo","useState","useNavigate","useHook","jsx","jsxs","PIX_PAYLOAD_KEY","useCallback","useMemo","useState","useHook","EMAIL_RE","useHook","useState","useMemo","useCallback","useCallback","useMemo","useState","useHook","EMAIL_RE","MIN_PASSWORD","useHook","useState","useMemo","useCallback","useCallback","useMemo","useState","useHook","EMAIL_RE","useHook","useState","useMemo","useCallback","useCallback","useEffect","useMemo","useState","useHook","MIN_PASSWORD","useHook","useState","useEffect","useMemo","useCallback","useEffect","useHook","useHook","useEffect","useHook","useHook","useCallback","useEffect","useState","useHook","useCallback","useState","Routes","Route","jsx","jsxs","BrowserRouter","MemoryRouter","Routes","jsx","useCallback","useEffect","useMemo","useRef","usePersistedState","useHook","createContext","useContext","jsx","usePersistedState","useRef","useCallback","useHook","track","useEffect","useMemo"]}
|
|
1
|
+
{"version":3,"sources":["../src/AppRoot.tsx","../src/config/AppConfigContext.tsx","../src/config/schema.ts","../src/PersistenceRegistry.tsx","../src/DeepLinkHandler.tsx","../src/internal/TemplateConfigContext.tsx","../src/internal/ThemeProvider.tsx","../src/hooks/usePaywallState.ts","../src/errors/asaas-pt-br.ts","../src/hooks/usePaywallTracker.ts","../src/internal/SubscriptionGate.tsx","../src/components/InstallGate/InstallGate.tsx","../src/hooks/useInstallPrompt.ts","../src/components/InstallGate/copy.ts","../src/components/InstallGate/InstallSplash.tsx","../src/components/InstallGate/icons.tsx","../src/components/InstallGate/variants/AndroidNativeVariant.tsx","../src/components/InstallGate/variants/AndroidManualVariant.tsx","../src/components/InstallGate/variants/AndroidPendingVariant.tsx","../src/components/InstallGate/Step.tsx","../src/components/InstallGate/variants/IOSafariVariant.tsx","../src/components/InstallGate/variants/IOSOtherVariant.tsx","../src/components/InstallGate/variants/InAppBrowserVariant.tsx","../src/components/InstallGate/variants/DesktopVariant.tsx","../src/internal/PushPrompt.tsx","../src/internal/SessionExpiredBanner.tsx","../src/internal/EmailVerifyBanner.tsx","../src/defaults/ErrorBoundary.tsx","../src/i18n/I18nProvider.tsx","../src/dev/env.ts","../src/dev/DevSkipOnboardingFab.tsx","../src/internal/PaymentReturnHandler.tsx","../src/hooks/usePush.ts","../src/components/PushPrompt.tsx","../src/components/LanguageSwitcher.tsx","../src/defaults/LoadingState.tsx","../src/defaults/EmptyState.tsx","../src/defaults/CheckoutPageDefault.tsx","../src/hooks/useCheckoutForm.ts","../src/errors.ts","../src/hooks/usePlan.ts","../src/components/paywall/Paywall.tsx","../src/utils/price.ts","../src/components/paywall/PaywallProvider.tsx","../src/components/paywall/usePaywallContext.ts","../src/components/paywall/PaywallMethodTabs.tsx","../src/components/paywall/PaywallMethodContent.tsx","../src/components/paywall/PaywallCyclePicker.tsx","../src/components/paywall/PaywallCta.tsx","../src/components/paywall/blocks/PaywallEyebrow.tsx","../src/components/paywall/blocks/PaywallHero.tsx","../src/components/paywall/blocks/PaywallHeadline.tsx","../src/components/paywall/blocks/PaywallPriceHeadline.tsx","../src/components/paywall/blocks/PaywallCountdown.tsx","../src/components/paywall/blocks/PaywallFeatures.tsx","../src/components/paywall/blocks/PaywallFeaturesCard.tsx","../src/components/paywall/blocks/PaywallTrophyBadge.tsx","../src/components/paywall/blocks/PaywallAnchorPrice.tsx","../src/components/paywall/blocks/PaywallTestimonials.tsx","../src/components/paywall/blocks/PaywallStatsRow.tsx","../src/components/paywall/blocks/PaywallFinePrint.tsx","../src/components/paywall/blocks/PaywallTrustLine.tsx","../src/components/paywall/blocks/PaywallStickyFooter.tsx","../src/defaults/PixWaitingPageDefault.tsx","../src/hooks/useLoginForm.ts","../src/hooks/useSignupForm.ts","../src/hooks/useForgotForm.ts","../src/hooks/useResetForm.ts","../src/hooks/useAuthPrimitives.ts","../src/hooks/useAuth.ts","../src/index.ts","../src/hooks/useSubscription.ts","../src/hooks/useReminders.ts","../src/hooks/useToast.ts","../src/RouteBoundary.tsx","../src/PreAuthShell.tsx","../src/OnboardingFlow.tsx","../src/hooks/useOnboardingStep.ts","../src/hooks/useFeature.ts"],"sourcesContent":["/**\n * @golden-path — único componente público do template.\n *\n * v0.10.0 (R2-W3 Task 11): config-driven AppRoot.\n *\n * Apps consume:\n * <AppRoot\n * config={appConfig} // new typed AppConfig (zod-validated)\n * Login={MyLogin} // required slot\n * Signup={MySignup} // required slot\n * Forgot={MyForgot} // required slot\n * Reset={MyReset} // required slot\n * EmailVerify={MyEmailVerify} // required iff config.authFlow.requiresEmailVerify\n * Paywall={MyPaywall} // required iff config.paywall.mode != \"free\"\n * Onboarding={{ welcome: Welcome, ... }} // required iff config.onboarding && trigger != \"pre_signup_custom\"\n * PreAuthFlow={MyPreAuth} // required iff config.onboarding?.trigger === \"pre_signup_custom\"\n * >\n * <RouteBoundary>\n * <Route path=\"/\" element={<Home />} />\n * ...\n * </RouteBoundary>\n * </AppRoot>\n *\n * BREAKING vs v0.9.x:\n * - Default* screens are gone. Apps must provide all auth slot screens.\n * - `config` shape changed (see template/src/types/AppConfig.ts).\n * - AppRoot mounts a BrowserRouter with `basename={`/app/${config.slug}`}`.\n * Apps no longer mount their own Router.\n *\n * IMPORTANT (architectural constraint, see existing comment from v0.9.x):\n * AppRoot does NOT mount <HookProvider>. The shell (frontend/shell/AppLoader.tsx)\n * already wraps the bundle with the runtime config ({ appId, apiHost, assetsHost }).\n * Mounting again would create two HookProvider instances — duplicate auth state +\n * duplicate HTTP clients with mismatched apiHost — and break in staging/prod where\n * shell and API live on different hosts. Tests must wrap explicitly.\n *\n * Note: a TemplateConfigProvider compat shim is mounted internally so existing\n * gates (InstallGate, ThemeProvider, SubscriptionGate) keep working with the\n * derived old-shape config. They will migrate to AppConfig in template 0.11.\n */\nimport { useMemo, type ComponentType, type ReactNode } from 'react';\nimport { BrowserRouter, MemoryRouter, Navigate, Route, Routes } from 'react-router-dom';\nimport { useHook } from '@hook-sdk/sdk';\nimport { AppConfigProvider } from './config/AppConfigContext';\nimport { parseAppConfig } from './config/schema';\nimport { PersistenceRegistry } from './PersistenceRegistry';\nimport { DeepLinkHandler } from './DeepLinkHandler';\nimport { TemplateConfigProvider } from './internal/TemplateConfigContext';\nimport { ThemeProvider } from './internal/ThemeProvider';\nimport { SubscriptionGate } from './internal/SubscriptionGate';\nimport { InstallGate } from './components/InstallGate';\nimport { PushPrompt } from './internal/PushPrompt';\nimport { SessionExpiredBanner } from './internal/SessionExpiredBanner';\nimport { EmailVerifyBanner } from './internal/EmailVerifyBanner';\nimport { ErrorBoundary } from './defaults/ErrorBoundary';\nimport { I18nProvider } from './i18n/I18nProvider';\nimport type { AppConfig } from './types/AppConfig';\nimport type { AppConfig as OldAppConfig } from '../../scripts/schemas/app-config';\nimport type { AuthScreenProps } from './types/AppRootSlots';\nimport { isDevToolsEnabled } from './dev/env';\nimport { DevSkipOnboardingFab, type SkipDefaults } from './dev/DevSkipOnboardingFab';\n\nexport type { AuthScreenProps };\nexport type { SkipDefaults };\n\nexport type AppRootSlots = {\n Login: ComponentType<AuthScreenProps>;\n Signup: ComponentType<AuthScreenProps>;\n Forgot: ComponentType<AuthScreenProps>;\n Reset: ComponentType<AuthScreenProps>;\n /** Required when config.authFlow.requiresEmailVerify === true. */\n EmailVerify?: ComponentType<AuthScreenProps>;\n /** Required when config.paywall.mode !== \"free\". */\n Paywall?: ComponentType;\n /** Map of step id → component. Used when config.onboarding && trigger !== \"pre_signup_custom\". */\n Onboarding?: Record<string, ComponentType>;\n /** Required when config.onboarding?.trigger === \"pre_signup_custom\". */\n PreAuthFlow?: ComponentType;\n};\n\nexport type AppRootProps = AppRootSlots & {\n config: AppConfig;\n children?: ReactNode;\n /** Test-only: skip BrowserRouter (which fights jsdom's document.location). */\n testRouter?: 'memory';\n /** Test-only: initial entries for MemoryRouter. */\n testInitialEntries?: string[];\n /**\n * Staging-only dev tools. When this prop is set AND\n * `VITE_HOOK_DEV_TOOLS=1` AND the hostname is staging/localhost, AppRoot\n * mounts a floating \"skip onboarding\" button that pre-fills\n * `appData.onboarding_data` with the supplied defaults and lands the user\n * on `/app/<slug>/`. Tree-shaken from prod builds via the build-time env\n * replacement (see `dev/env.ts`).\n */\n devSkipOnboarding?: { defaults: SkipDefaults };\n};\n\nexport { PaymentReturnHandler } from './internal/PaymentReturnHandler';\n\n/**\n * Build a v0.9-shaped TemplateConfig from the new AppConfig so existing internal\n * gates (InstallGate / ThemeProvider / SubscriptionGate / InstallSplash /\n * DesktopVariant) keep functioning unchanged. Removed in template 0.11 once\n * those gates migrate to consume AppConfig directly.\n */\nfunction buildLegacyConfigShim(config: AppConfig): OldAppConfig {\n const paywall = config.paywall;\n const isFree = paywall.mode === 'free';\n const monthlyCents = isFree ? 0 : paywall.prices.monthlyCents;\n const trialDays = isFree ? 0 : (paywall.trialDays ?? 0);\n return {\n slug: config.slug,\n name: config.name,\n email_alias: config.slug,\n // Map branding into the legacy theme shape so InstallSplash (and\n // anything else reading theme.icon_url / theme.logo_url) can surface\n // the app icon instead of the generic \"first letter of name\" fallback.\n // Falls back to logoUrl when iconUrl is unset — apps that haven't\n // adopted iconUrl keep their previous behavior unchanged.\n theme: {\n primary_color: config.branding.primaryColor,\n icon_url: config.branding.iconUrl ?? config.branding.logoUrl,\n logo_url: config.branding.logoUrl,\n },\n features_enabled: ((config.features_enabled ?? []) as OldAppConfig['features_enabled']),\n dependencies_allowlist: ['react', 'react-dom'],\n subscription: {\n mode: paywall.mode,\n price_cents: monthlyCents,\n currency: 'brl',\n trial_days: trialDays,\n paywall_config: {\n title: config.name,\n benefits: ['Acesso completo'],\n cta: 'Assinar',\n },\n },\n sdk_version_required: '>=0.16.0',\n max_bundle_size_kb: 500,\n } as OldAppConfig;\n}\n\nexport function AppRoot(props: AppRootProps) {\n const {\n config: rawConfig,\n children,\n testRouter,\n testInitialEntries,\n Login,\n Signup,\n Forgot,\n Reset,\n EmailVerify,\n Paywall,\n Onboarding,\n PreAuthFlow,\n devSkipOnboarding,\n } = props;\n\n if (!Login || !Signup || !Forgot || !Reset) {\n throw new Error(\n '[hook-template] <AppRoot>: Login, Signup, Forgot, Reset slot props are required.',\n );\n }\n\n const config = parseAppConfig(rawConfig);\n\n if (config.paywall.mode !== 'free' && !Paywall) {\n throw new Error(\n \"[hook-template] <AppRoot>: Paywall slot prop is required when config.paywall.mode != 'free'.\",\n );\n }\n if (config.authFlow.requiresEmailVerify && !EmailVerify) {\n throw new Error(\n '[hook-template] <AppRoot>: EmailVerify slot prop is required when config.authFlow.requiresEmailVerify === true.',\n );\n }\n if (config.onboarding?.trigger === 'pre_signup_custom' && !PreAuthFlow) {\n throw new Error(\n \"[hook-template] <AppRoot>: PreAuthFlow slot prop is required when config.onboarding.trigger === 'pre_signup_custom'.\",\n );\n }\n\n const legacyShim = useMemo(() => buildLegacyConfigShim(config), [config]);\n const Router = testRouter === 'memory' ? MemoryRouter : BrowserRouter;\n const basename = `/app/${config.slug}`;\n\n const routerProps = testRouter === 'memory'\n ? { basename, initialEntries: testInitialEntries }\n : { basename };\n\n const position = config.install_prompt?.position ?? 'post-paywall';\n\n const subscriptionGated = (\n <SubscriptionGate Paywall={Paywall ?? FallbackPaywall}>\n <EmailVerifyBanner />\n {position === 'post-paywall' ? (\n <InstallGate position=\"post-paywall\">\n {children}\n <PushPrompt />\n </InstallGate>\n ) : (\n <>\n {children}\n <PushPrompt />\n </>\n )}\n </SubscriptionGate>\n );\n\n const authGated = (\n <AuthGated\n config={config}\n Login={Login}\n Signup={Signup}\n Forgot={Forgot}\n Reset={Reset}\n EmailVerify={EmailVerify}\n Paywall={Paywall}\n Onboarding={Onboarding}\n PreAuthFlow={PreAuthFlow}\n >\n {subscriptionGated}\n </AuthGated>\n );\n\n const routedTree = (\n <Router {...routerProps}>\n <DeepLinkHandler deepLinks={config.deepLinks} />\n {/* Outside AuthGated so banner can observe authenticated→anonymous transitions; AuthGated unmounts children on anon. */}\n <SessionExpiredBanner />\n {position === 'pre-auth' ? (\n <InstallGate position=\"pre-auth\">{authGated}</InstallGate>\n ) : (\n authGated\n )}\n {isDevToolsEnabled() && devSkipOnboarding ? (\n <DevSkipOnboardingFab defaults={devSkipOnboarding.defaults} />\n ) : null}\n </Router>\n );\n\n return (\n <ErrorBoundary>\n <AppConfigProvider config={config}>\n <TemplateConfigProvider config={legacyShim}>\n <ThemeProvider>\n <PersistenceRegistry config={config.persistedKeys}>\n {config.i18n ? (\n <I18nProvider\n defaultLocale={config.i18n.defaultLocale}\n supportedLocales={config.i18n.supportedLocales}\n resources={config.i18n.resources}\n >\n {routedTree}\n </I18nProvider>\n ) : (\n routedTree\n )}\n </PersistenceRegistry>\n </ThemeProvider>\n </TemplateConfigProvider>\n </AppConfigProvider>\n </ErrorBoundary>\n );\n}\n\n/**\n * Renders the auth-flow Routes when unauthenticated; renders children when\n * authenticated. Supports two anonymous flows:\n *\n * - Default: linear `/`, `/signup`, `/forgot`, `/reset`, optional `/verify`.\n * - `pre_signup_custom`: app provides its own Routes via <PreAuthFlow>; we\n * only mount the auth screens at fixed paths and delegate everything else\n * to PreAuthFlow.\n */\nfunction AuthGated({\n children,\n config,\n Login,\n Signup,\n Forgot,\n Reset,\n EmailVerify,\n PreAuthFlow,\n}: AppRootProps & { children?: ReactNode }) {\n const { authStatus } = useHook();\n if (authStatus === 'loading') return null;\n if (authStatus !== 'authenticated') {\n // Plan-V — pay-first signup mode: no /signup route mounted in the\n // pre-auth funnel. New users sign up via the checkout form inside\n // PreAuthFlow (/paywall/checkout). Existing users land on /signin (or\n // any /signin link); legacy /signup still exists on the backend so\n // direct hits won't 404, but the bundle never exposes the path.\n if (config.authFlow.signupMode === 'pay_first' && PreAuthFlow) {\n return (\n <Routes>\n <Route path=\"/signin\" element={<Login />} />\n <Route path=\"/forgot\" element={<Forgot />} />\n <Route path=\"/reset\" element={<Reset />} />\n {EmailVerify ? <Route path=\"/verify\" element={<EmailVerify />} /> : null}\n <Route path=\"/*\" element={<PreAuthFlow />} />\n </Routes>\n );\n }\n if (config.onboarding?.trigger === 'pre_signup_custom' && PreAuthFlow) {\n return (\n <Routes>\n <Route path=\"/signin\" element={<Login />} />\n <Route path=\"/signup\" element={<Signup />} />\n <Route path=\"/forgot\" element={<Forgot />} />\n <Route path=\"/reset\" element={<Reset />} />\n {EmailVerify ? <Route path=\"/verify\" element={<EmailVerify />} /> : null}\n <Route path=\"/*\" element={<PreAuthFlow />} />\n </Routes>\n );\n }\n return (\n <Routes>\n <Route path=\"/\" element={<Login />} />\n <Route path=\"/signup\" element={<Signup />} />\n <Route path=\"/forgot\" element={<Forgot />} />\n <Route path=\"/reset\" element={<Reset />} />\n {EmailVerify ? <Route path=\"/verify\" element={<EmailVerify />} /> : null}\n <Route path=\"*\" element={<Navigate to=\"/\" replace />} />\n </Routes>\n );\n }\n return <>{children}</>;\n}\n\n// Internal fallback Paywall, only ever reached via the SubscriptionGate when\n// config.paywall.mode === 'free' (in which case SubscriptionGate short-circuits\n// and never renders Paywall). Here purely to satisfy the SubscriptionGate prop\n// type without making Paywall a forced required slot in 'free' mode.\nfunction FallbackPaywall() {\n return null;\n}\n","import { createContext, useContext, type ReactNode } from 'react';\nimport type { AppConfig } from '../types/AppConfig';\n\nexport const AppConfigContext = createContext<AppConfig | null>(null);\n\nexport function AppConfigProvider({\n config,\n children,\n}: {\n config: AppConfig;\n children: ReactNode;\n}) {\n return <AppConfigContext.Provider value={config}>{children}</AppConfigContext.Provider>;\n}\n\nexport function useAppConfig(): AppConfig {\n const v = useContext(AppConfigContext);\n if (!v) {\n throw new Error(\n '[hook-template] useAppConfig: AppConfigProvider missing — wrap your app in <AppRoot>',\n );\n }\n return v;\n}\n","import { z } from 'zod';\nimport type { AppConfig } from '../types/AppConfig';\n\nconst SnakeKeyRE = /^[a-z0-9][a-z0-9_.-]{0,127}$/;\n\nconst AuthFlowSchema = z.object({\n minPassword: z.number().int().min(6).max(64),\n requiresEmailVerify: z.boolean(),\n googleOAuth: z.boolean(),\n postAuthLanding: z.string().startsWith('/'),\n preAuthRoutes: z.array(z.string().startsWith('/')),\n // Plan-V — pay-first signup mode. See types/AppConfig.ts AuthFlowConfig.\n signupMode: z.enum(['pre_signup', 'pay_first']).optional(),\n});\n\nconst PaywallNonFreeSchema = z.object({\n mode: z.enum(['trial', 'pay_first']),\n // Legacy flat trial — fallback when per-method fields aren't set.\n trialDays: z.number().int().nonnegative().optional(),\n // Per-method trial (ADR-022 Amendment 2026-05-12 + G154). PIX Auto can't\n // offer trial on Asaas today (Jornada 2 unavailable), so apps that mix\n // methods must split the value to avoid bait-and-switch on PIX shoppers.\n trialDaysCard: z.number().int().nonnegative().optional(),\n trialDaysPix: z.number().int().nonnegative().optional(),\n // Which method the paywall preselects. null/undefined = no preselection\n // (user picks). Per-app override reflects audience, not Hook bias.\n defaultMethod: z.enum(['card', 'pix-auto', 'pix-once']).nullable().optional(),\n cycles: z.array(z.enum(['MONTHLY', 'YEARLY'])).min(1),\n prices: z.object({\n monthlyCents: z.number().int().nonnegative(),\n yearlyCents: z.number().int().nonnegative(),\n }),\n anchorPrices: z\n .object({\n monthlyCents: z.number().int().nonnegative(),\n yearlyCents: z.number().int().nonnegative(),\n })\n .optional(),\n checkoutMethods: z.array(z.enum(['card', 'pix-auto', 'pix-once'])).min(1),\n requiresCpf: z.boolean(),\n collectCep: z.boolean().optional(),\n cancelWindowDays: z.number().int().nonnegative().optional(),\n errorMessages: z.enum(['default', 'custom']),\n});\n\nconst PaywallFreeSchema = z.object({ mode: z.literal('free') });\nconst PaywallSchema = z.discriminatedUnion('mode', [PaywallNonFreeSchema, PaywallFreeSchema]);\n\nconst PersistedKeySchema = z.object({\n key: z\n .string()\n .regex(SnakeKeyRE, 'key must be snake_case (matches /^[a-z0-9][a-z0-9_.-]{0,127}$/)'),\n default: z.unknown(),\n guardRegen: z.boolean().optional(),\n debounceMs: z.number().int().positive().optional(),\n});\n\nconst OnboardingSchema = z.object({\n trigger: z.enum(['pre_signup', 'post_signup', 'pre_signup_custom', 'optional']),\n steps: z\n .array(\n z.object({\n id: z.string().regex(SnakeKeyRE),\n screen: z.string(),\n validates: z.array(z.string()).optional(),\n }),\n )\n .min(1),\n persistTo: z.literal('appData'),\n persistKey: z.string().regex(SnakeKeyRE),\n});\n\nconst DeepLinksSchema = z\n .object({\n passwordReset: z.string().startsWith('/').optional(),\n emailVerify: z.string().startsWith('/').optional(),\n })\n .strict();\n\nconst I18nConfigSchema = z\n .object({\n defaultLocale: z.string().min(2),\n supportedLocales: z.array(z.string().min(2)).min(1),\n resources: z.record(z.string(), z.record(z.string(), z.string())),\n })\n .strict()\n .refine((v) => v.supportedLocales.includes(v.defaultLocale), {\n message: 'i18n.defaultLocale must be a member of i18n.supportedLocales',\n path: ['defaultLocale'],\n });\n\nconst InstallPromptSchema = z\n .object({\n position: z.enum(['pre-auth', 'post-paywall']).optional(),\n })\n .strict();\n\nexport const AppConfigSchema = z\n .object({\n slug: z.string().regex(/^[a-z0-9-]+$/),\n name: z.string().min(1),\n branding: z.object({\n primaryColor: z.string(),\n logoUrl: z.string().url(),\n iconUrl: z.string().url().optional(),\n }),\n authFlow: AuthFlowSchema,\n paywall: PaywallSchema,\n persistedKeys: z.array(PersistedKeySchema),\n onboarding: OnboardingSchema.optional(),\n deepLinks: DeepLinksSchema.optional(),\n i18n: I18nConfigSchema.optional(),\n features_enabled: z.array(z.string()).optional(),\n install_prompt: InstallPromptSchema.optional(),\n // Build-time injected theme metadata (e.g. icon_url for InstallSplash).\n // Apps don't author this directly; deploy workflows fill it from\n // env-resolved bundle host. Permissive shape so apps/workflows can\n // extend without re-bumping the template schema.\n theme: z.object({}).passthrough().optional(),\n // G133 — per-tenant public app-data keys allowlist. Optional; default\n // backfill em migration 0044 = canonical 6. Apps com keys próprias\n // declaram aqui pra evitar 402 spam pós-signup no SubscriptionGate.\n publicKeys: z.array(z.string().regex(SnakeKeyRE)).optional(),\n })\n .strict();\n\nexport function parseAppConfig(input: unknown): AppConfig {\n const r = AppConfigSchema.safeParse(input);\n if (!r.success) {\n const messages = r.error.issues\n .map((i) => `[${i.path.join('.')}] ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid app.config.json:\\n${messages}`);\n }\n return r.data as AppConfig;\n}\n","import { useEffect, type ReactNode } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type { PersistedKey } from './types/AppConfig';\n\nexport type PersistenceRegistryProps = {\n config: PersistedKey[];\n children: ReactNode;\n};\n\n/**\n * Fire-and-forget prefetch of every key declared in `app.config.json.persistedKeys`\n * via `appData.bulkRead`. Does NOT gate render — children mount immediately;\n * `usePersistedState` consumers hit cache as soon as the prefetch resolves.\n *\n * Use when the consuming app tolerates a brief flash of `defaultValue` before\n * hydrated state lands. For strict \"no flash\" semantics use `<PersistedKeysPrefetch>`\n * (gating variant in `internal/`).\n */\nexport function PersistenceRegistry({ config, children }: PersistenceRegistryProps) {\n const { appData } = useHook();\n useEffect(() => {\n if (config.length === 0) return;\n const keys = config.map((c) => c.key);\n const bulk = (appData as unknown as { bulkRead?: (k: string[]) => Promise<unknown> })\n .bulkRead;\n bulk?.(keys).catch(() => {\n // best-effort; usePersistedState hits the network on miss\n });\n }, [config, appData]);\n return <>{children}</>;\n}\n","import { useEffect } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport type { DeepLinks } from './types/AppConfig';\n\n/**\n * Reads `?token=` from the URL on mount + on location change. When present and\n * the current pathname is `/`, redirects to the configured deep-link path\n * (passwordReset or emailVerify) substituting `:token` for the actual value.\n *\n * Mounts once inside `<AppRoot>` (post-Router); a no-op when `deepLinks` is\n * undefined or no `token` is in the URL.\n */\nexport function DeepLinkHandler({ deepLinks }: { deepLinks?: DeepLinks }) {\n const nav = useNavigate();\n const loc = useLocation();\n useEffect(() => {\n if (!deepLinks) return;\n const params = new URLSearchParams(loc.search);\n const token = params.get('token');\n if (!token) return;\n if (\n deepLinks.passwordReset &&\n deepLinks.passwordReset.includes(':token') &&\n loc.pathname === '/'\n ) {\n nav(deepLinks.passwordReset.replace(':token', token));\n return;\n }\n if (\n deepLinks.emailVerify &&\n deepLinks.emailVerify.includes(':token') &&\n loc.pathname === '/'\n ) {\n nav(deepLinks.emailVerify.replace(':token', token));\n }\n }, [deepLinks, loc, nav]);\n return null;\n}\n","import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport type { AppConfig } from '../../../scripts/schemas/app-config';\n\nexport type SubscriptionMode = 'trial' | 'pay_first' | 'free';\n\nexport interface TemplateConfig extends AppConfig {\n /** Resolved subscription mode. Defaults to 'trial' when absent in app.config.json. */\n mode: SubscriptionMode;\n}\n\nconst TemplateConfigContext = createContext<TemplateConfig | null>(null);\n\nexport function TemplateConfigProvider({\n config,\n children,\n}: {\n config: AppConfig;\n children: ReactNode;\n}) {\n const value = useMemo<TemplateConfig>(() => ({\n ...config,\n mode: (config.subscription?.mode as SubscriptionMode | undefined) ?? 'trial',\n }), [config]);\n\n return (\n <TemplateConfigContext.Provider value={value}>\n {children}\n </TemplateConfigContext.Provider>\n );\n}\n\nexport function useTemplateConfig(): TemplateConfig {\n const ctx = useContext(TemplateConfigContext);\n if (ctx === null) {\n throw new Error('useTemplateConfig must be used inside <TemplateConfigProvider>');\n }\n return ctx;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from './TemplateConfigContext';\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n const config = useTemplateConfig();\n const style = {\n '--hook-color-primary': config.theme.primary_color,\n ...(config.theme.background_color && {\n '--hook-color-background': config.theme.background_color,\n }),\n } as CSSProperties;\n\n return <div style={style}>{children}</div>;\n}\n","import { useCallback, useContext, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type {\n CheckoutArgs,\n CheckoutCardData,\n CheckoutCycle,\n CheckoutHolderInfo,\n CheckoutMethod,\n CheckoutResult,\n PixPending as SdkPixPending,\n} from '@hook-sdk/sdk';\n\n// SDK 0.16's MethodUnavailableResult discriminator. Re-declared here to keep\n// the narrowing type-guard local; the SDK exports this as part of CheckoutResult.\ninterface CheckoutFailureShape {\n ok: false;\n code: 'method_unavailable';\n method: CheckoutMethod;\n reason: string;\n}\n\nfunction isCheckoutFailure(r: CheckoutResult): r is CheckoutFailureShape {\n return 'ok' in r && (r as { ok?: unknown }).ok === false;\n}\nimport { AppConfigContext } from '../config/AppConfigContext';\nimport type { AppConfig, PaywallConfig } from '../types/AppConfig';\nimport { asaasErrorMessage } from '../errors/asaas-pt-br';\nimport { usePaywallTracker } from './usePaywallTracker';\n\n// Permissive fallback used when usePaywallState is rendered outside an\n// <AppConfigProvider> (legacy callers + standalone unit tests). Mirrors the\n// pre-config-driven default behavior: card + pix-auto are available, CPF is\n// required, errorMessages map to PT-BR via asaasErrorMessage.\nconst FALLBACK_PAYWALL: PaywallConfig = {\n mode: 'pay_first',\n cycles: ['MONTHLY'],\n prices: { monthlyCents: 0, yearlyCents: 0 },\n checkoutMethods: ['card', 'pix-auto'],\n requiresCpf: true,\n errorMessages: 'default',\n};\n\nexport type SubscriptionStatus =\n | 'active'\n | 'trialing'\n | 'expired'\n | 'canceled'\n | 'past_due'\n | 'pending'\n | 'none';\n\nexport type PaymentMethod = CheckoutMethod;\n\nexport interface PaywallError {\n code: string;\n message: string;\n userMessage: string;\n}\n\n/**\n * Local pixPending shape — re-exposes SDK's reactive `subscription.pixPending`\n * with two extra UI-facing fields:\n * - `expiresAt`: null (kept for compat; SDK does not surface expiry on auto/once)\n * - `paid`: derived from `subscription.current.status` — flips true when the\n * underlying subscription transitions to ACTIVE/TRIAL after the user pays\n * the QR code. SDK clears the underlying pixPending shortly after; this\n * wrapper preserves the \"paid\" frame for ~1 render so the paywall can show\n * confirmation copy before unmounting the modal.\n */\nexport interface PixPending {\n method: 'pix-auto' | 'pix-once';\n qrCodePayload: string | null;\n qrCodeBase64: string | null;\n expiresAt: string | null;\n paid: boolean;\n}\n\nexport interface CardFormState {\n number: string;\n cvv: string;\n expiry: string;\n holder: string;\n}\n\nexport interface CardFormStateWithSetter extends CardFormState {\n set: (patch: Partial<CardFormState>) => void;\n}\n\nexport interface CpfState {\n required: boolean;\n value: string;\n set: (v: string) => void;\n valid: boolean;\n}\n\nexport interface PaywallCheckoutArgs {\n cpf: string;\n cycle: CheckoutCycle;\n method: 'card' | 'pix-auto' | 'pix-once';\n card?: CheckoutCardData;\n holderInfo?: CheckoutHolderInfo;\n remoteIp?: string;\n}\n\nexport interface PaywallPlanDerived {\n monthlyCents: number;\n yearlyCents: number | null;\n anchorMonthlyCents?: number;\n anchorYearlyCents?: number;\n monthlyEquivalent: number;\n discountPercent: number;\n}\n\nconst isMethodAvailable = (\n availability: { card: boolean | null; 'pix-auto': boolean | null; 'pix-once': boolean | null },\n method: CheckoutMethod,\n): boolean => availability[method] !== false;\n\n/**\n * Headless paywall state — owns:\n * - reactive subscription status (proxied from SDK)\n * - cycle / selectedMethod / cpf / card form state\n * - methods list (config.paywall.checkoutMethods filtered by SDK methodAvailability)\n * - submit() — high-level no-args entrypoint that uses internal state\n * - error mapping via asaasErrorMessage when paywall.errorMessages === 'default'\n *\n * Backward-compat aliases preserved for SDK 0.13/template 0.9 consumers:\n * - `availableMethods` mirrors `methods`\n * - `opening` mirrors `submitting`\n * - `checkout(args)` takes legacy args + validates card/holderInfo presence\n * - `dismissPix` clears SDK `pixPending` (template 0.24.0 + SDK 0.26.0 wire,\n * resolves G154; was no-op pre-0.24 and apps had to maintain a local\n * `pixActive` flag to bridge the gap).\n * - `monthlyEquivalent(cycle)` helper\n */\nexport function usePaywallState() {\n const { subscription, plan, authStatus, track } = useHook();\n // Null-tolerant: tests + legacy callers may render without AppConfigProvider.\n // Real apps always wrap via <AppRoot>, so the null path only fires in unit\n // tests for hooks that pre-date the config-driven runtime.\n const configFromCtx = useContext(AppConfigContext) as AppConfig | null;\n const paywall: PaywallConfig = configFromCtx?.paywall ?? FALLBACK_PAYWALL;\n const isFree = paywall.mode === 'free';\n\n const declaredMethods = useMemo<readonly CheckoutMethod[]>(\n () => (isFree ? [] : paywall.checkoutMethods),\n [isFree, paywall],\n );\n\n // Fallback when SDK predates methodAvailability (legacy test mocks).\n const availability = subscription.methodAvailability ?? {\n card: null,\n 'pix-auto': null,\n 'pix-once': null,\n };\n\n const methods = useMemo<readonly CheckoutMethod[]>(\n () => declaredMethods.filter((m) => isMethodAvailable(availability, m)),\n [declaredMethods, availability],\n );\n\n // ADR-022 Amendment 2026-05-12: paywall preselection follows the app's\n // declared `defaultMethod` when available + available + present. Falls back\n // to the first available method in the configured order. Apps with a\n // PIX-first audience (papomaterno, personalburn) set `defaultMethod=pix-auto`;\n // apps that lead with trial (beluzi card-only) set `defaultMethod=card`.\n const configDefault =\n !isFree && 'defaultMethod' in paywall ? paywall.defaultMethod ?? null : null;\n const defaultMethod: CheckoutMethod =\n (configDefault && methods.includes(configDefault) ? configDefault : null) ??\n methods[0] ??\n declaredMethods[0] ??\n 'card';\n const [selectedMethodRaw, setSelectedMethod] = useState<CheckoutMethod>(defaultMethod);\n\n // If the currently selected method has been flagged unavailable, fall back\n // to the first available one. Caller still sees a valid value.\n const selectedMethod: CheckoutMethod = methods.includes(selectedMethodRaw)\n ? selectedMethodRaw\n : (methods[0] ?? selectedMethodRaw);\n\n // Default cycle: YEARLY when offered (higher AOV per spec); else fall back to\n // first declared cycle, else MONTHLY. Apps that want MONTHLY-default can\n // declare `cycles: [\"MONTHLY\"]` only or override post-mount via setCycle.\n const initialCycle: CheckoutCycle = isFree\n ? 'MONTHLY'\n : paywall.cycles.includes('YEARLY')\n ? 'YEARLY'\n : (paywall.cycles[0] ?? 'MONTHLY');\n const [cycle, setCycle] = useState<CheckoutCycle>(initialCycle);\n\n const cpfRequired = !isFree && paywall.requiresCpf;\n const [cpf, setCpf] = useState('');\n const cpfValid = useMemo(() => /^[0-9]{11}$/.test(cpf), [cpf]);\n\n const [card, setCardState] = useState<CardFormState>({\n number: '',\n cvv: '',\n expiry: '',\n holder: '',\n });\n const setCard = useCallback((patch: Partial<CardFormState>) => {\n setCardState((prev) => ({ ...prev, ...patch }));\n }, []);\n\n const [error, setError] = useState<PaywallError | null>(null);\n const [submitting, setSubmitting] = useState(false);\n\n const status = subscription.status() as SubscriptionStatus;\n const daysLeftInTrial = subscription.daysLeftInTrial();\n\n /**\n * Per-method trial accessor (ADR-022 Amendment 2026-05-12 + G154).\n *\n * Resolution order:\n * 1. method-specific override (`paywall.trialDaysCard` / `trialDaysPix`)\n * 2. legacy flat `paywall.trialDays`\n * 3. method-aware default: 7 for card, 0 for pix-auto/pix-once (Asaas\n * cannot offer trial on PIX — BCB Jornada 2 unavailable).\n *\n * Consumers render asymmetric paywall copy:\n * - method-card: \"Grátis por N dias, depois R$ X/mês\" (only when N > 0)\n * - method-pix: \"Pague R$ X agora · acesso liberado em segundos\"\n *\n * Never reuse a global \"free trial!\" headline when both methods are\n * visible — that bait-and-switches PIX-first shoppers (insight doc\n * 2026-05-12-asaas-jornada-2-research.md §\"shopper C\").\n */\n const trialDaysForMethod = useCallback(\n (method: CheckoutMethod): number => {\n if (isFree) return 0;\n if (method === 'card') {\n if (typeof paywall.trialDaysCard === 'number') return paywall.trialDaysCard;\n if (typeof paywall.trialDays === 'number') return paywall.trialDays;\n return 7;\n }\n // pix-auto + pix-once: Asaas can't authorize without an immediate\n // charge today (G154). Default 0 unless an app explicitly opts in\n // (legacy apps that haven't migrated off the R$ 0,01 capture trick).\n if (typeof paywall.trialDaysPix === 'number') return paywall.trialDaysPix;\n if (typeof paywall.trialDays === 'number') return paywall.trialDays;\n return 0;\n },\n [isFree, paywall],\n );\n\n const trialDaysCard = trialDaysForMethod('card');\n const trialDaysPix = trialDaysForMethod('pix-auto');\n const initialLoadComplete = subscription.initialLoadComplete;\n // Backend-authoritative access flag. Distingue CANCELLED-com-trial-vivo\n // (hasAccess=true) de CANCELLED-expirado (hasAccess=false). SubscriptionGate\n // usa isso pra liberar app durante o restante do período pago/trial após\n // cancel — comportamento alinhado com App Store/Play Store.\n const hasAccess = subscription.hasAccess;\n\n // Re-expose SDK pixPending with legacy enrichment (expiresAt, paid).\n const pixPending = useMemo<PixPending | null>(() => {\n const sdkPix: SdkPixPending | null = subscription.pixPending;\n if (!sdkPix) return null;\n const liveStatus = subscription.current?.status;\n const paid = liveStatus === 'ACTIVE' || liveStatus === 'TRIAL';\n return {\n method: sdkPix.method,\n qrCodePayload: sdkPix.qrCodePayload,\n qrCodeBase64: sdkPix.qrCodeBase64,\n expiresAt: null,\n paid,\n };\n }, [subscription.pixPending, subscription.current]);\n\n const monthlyEquivalent = useCallback(\n (c: CheckoutCycle): number => {\n const monthlyCents = plan.data?.priceCents ?? (isFree ? 0 : paywall.prices.monthlyCents);\n const yearlyCents = plan.data?.yearlyPriceCents ?? (isFree ? null : paywall.prices.yearlyCents);\n if (c === 'YEARLY' && yearlyCents) return Math.round(yearlyCents / 12);\n return monthlyCents;\n },\n [plan, paywall, isFree],\n );\n\n const planDerived = useMemo<PaywallPlanDerived | null>(() => {\n if (isFree) return null;\n const monthlyCents = paywall.prices.monthlyCents;\n const yearlyCents = paywall.prices.yearlyCents;\n const anchor = paywall.anchorPrices;\n const discount = anchor && anchor.yearlyCents > 0\n ? Math.round((1 - paywall.prices.yearlyCents / anchor.yearlyCents) * 100)\n : 0;\n return {\n monthlyCents,\n yearlyCents,\n anchorMonthlyCents: anchor?.monthlyCents,\n anchorYearlyCents: anchor?.yearlyCents,\n monthlyEquivalent: cycle === 'YEARLY' ? Math.round(yearlyCents / 12) : monthlyCents,\n discountPercent: discount,\n };\n }, [paywall, cycle, isFree]);\n\n // ===== Conversion-max derivations (template 0.21) =====\n\n /**\n * Inferred from SDK subscription status. The user has consumed their trial\n * once the backend has ever transitioned them past 'none'. Card tab copy\n * shifts to no-trial framing when true (see PaywallMethodContent).\n */\n const hasConsumedTrial = useMemo<boolean>(() => {\n return ['active', 'trialing', 'past_due', 'canceled', 'expired'].includes(status);\n }, [status]);\n\n /** Price for the currently selected cycle (used by CTA + cycle card). */\n const currentPriceCents = useMemo<number>(() => {\n if (isFree) return 0;\n return cycle === 'YEARLY' ? paywall.prices.yearlyCents : paywall.prices.monthlyCents;\n }, [paywall, cycle, isFree]);\n\n /** Monthly-equivalent. For YEARLY cycle, divides by 12. */\n const currentMonthlyEquivCents = useMemo<number>(() => {\n if (isFree) return 0;\n if (cycle === 'YEARLY') return Math.round(paywall.prices.yearlyCents / 12);\n return paywall.prices.monthlyCents;\n }, [paywall, cycle, isFree]);\n\n /** Anchor (strikethrough) price for the current cycle. null when not set. */\n const anchorPriceCents = useMemo<number | null>(() => {\n if (isFree) return null;\n const a = paywall.anchorPrices;\n if (!a) return null;\n return cycle === 'YEARLY' ? a.yearlyCents : a.monthlyCents;\n }, [paywall, cycle, isFree]);\n\n /** Telemetry-wrapped setters. */\n const selectMethod = useCallback(\n (next: CheckoutMethod) => {\n if (next === selectedMethod) return;\n track('paywall_method_tab_clicked', { method: next, from_method: selectedMethod });\n setSelectedMethod(next);\n },\n [selectedMethod, track],\n );\n\n const selectCycle = useCallback(\n (next: CheckoutCycle) => {\n if (next === cycle) return;\n track('paywall_cycle_clicked', { cycle: next, from_cycle: cycle });\n setCycle(next);\n },\n [cycle, track],\n );\n\n const useDefaultMessages = paywall.mode !== 'free' && paywall.errorMessages === 'default';\n\n const buildError = useCallback(\n (code: string, fallbackMessage: string): PaywallError => ({\n code,\n message: fallbackMessage,\n // fallbackMessage carries Asaas's PT-BR description (\"O CEP informado é inválido.\")\n // that distinguishes invalid_holderInfo sub-cases (CEP vs phone vs name).\n userMessage: useDefaultMessages ? asaasErrorMessage(code, fallbackMessage) : fallbackMessage,\n }),\n [useDefaultMessages],\n );\n\n /**\n * High-level no-args submit — uses internal state (selectedMethod, cycle,\n * cpf, card). Returns the discriminated CheckoutResult so caller can read\n * `result.method` for success or `result.ok === false` + `result.code` for\n * gated/disabled methods. Pre-flight rejects when methodAvailability already\n * has the selected method flagged false (no backend round-trip).\n */\n const submit = useCallback(async (): Promise<CheckoutResult | undefined> => {\n // Defense-in-depth: AuthGated prevents this from running unauthed in\n // practice (paywall is structurally unreachable pre-auth). If the\n // invariant breaks at runtime for an anonymous caller, emit the alarm\n // + abort so we get a regression signal without sending a 401-doomed\n // request. 'loading' is a transient race (user taps during ~200ms auth\n // rehydration) — abort silently without polluting the alarm cohort.\n if (authStatus === 'loading') return undefined;\n if (authStatus !== 'authenticated') {\n track('unauthenticated_submit_attempted', {\n method: selectedMethod,\n cycle,\n cpf_valid: cpfValid,\n });\n return undefined;\n }\n\n track('payment_attempted', {\n method: selectedMethod,\n cycle,\n cpf_valid: cpfValid,\n selected_amount_cents:\n cycle === 'YEARLY'\n ? (plan.data?.yearlyPriceCents ?? (isFree ? 0 : paywall.prices.yearlyCents))\n : (plan.data?.priceCents ?? (isFree ? 0 : paywall.prices.monthlyCents)),\n });\n\n setSubmitting(true);\n setError(null);\n\n const methodToUse = selectedMethod;\n\n if (!isMethodAvailable(availability, methodToUse)) {\n const code = 'method_unavailable';\n setError(buildError(code, `method ${methodToUse} unavailable`));\n setSubmitting(false);\n return {\n ok: false,\n code: 'method_unavailable',\n method: methodToUse,\n reason: 'pre_flight_unavailable',\n };\n }\n\n try {\n let result: CheckoutResult;\n if (methodToUse === 'card') {\n const [expMonthRaw = '', expYearRaw = ''] = card.expiry.split('/');\n const expYearTrimmed = expYearRaw.trim();\n const cardData: CheckoutCardData = {\n number: card.number,\n holderName: card.holder,\n expiryMonth: expMonthRaw.trim(),\n expiryYear: expYearTrimmed.length === 2 ? `20${expYearTrimmed}` : expYearTrimmed,\n ccv: card.cvv,\n };\n const holderInfo: CheckoutHolderInfo = {\n name: card.holder,\n email: '',\n cpfCnpj: cpf,\n postalCode: '',\n addressNumber: '',\n };\n result = await subscription.checkout({\n method: 'card',\n cycle,\n cpf,\n card: cardData,\n holderInfo,\n });\n } else if (methodToUse === 'pix-auto') {\n result = await subscription.checkout({ method: 'pix-auto', cycle, cpf });\n } else {\n result = await subscription.checkout({ method: 'pix-once', cycle, cpf });\n }\n\n if (isCheckoutFailure(result)) {\n setError(buildError(result.code, `${result.code}: ${result.reason}`));\n setSubmitting(false);\n return result;\n }\n\n await subscription.refresh();\n setSubmitting(false);\n return result;\n } catch (err) {\n const code = (err as { code?: string })?.code ?? 'generic_decline';\n const message = err instanceof Error ? err.message : String(err);\n setError(buildError(code, message));\n setSubmitting(false);\n return undefined;\n }\n }, [authStatus, track, selectedMethod, availability, subscription, cycle, cpf, cpfValid, card, buildError, plan, paywall]);\n\n /**\n * Legacy direct-args entrypoint — kept for SDK 0.13/template 0.9 callers\n * (incl. DefaultPaywall) until they migrate to `submit()`. Validates\n * card/holderInfo presence for `method === 'card'` to preserve the old\n * test contract (synthetic Error surfacing).\n */\n const checkout = useCallback(\n async (args: PaywallCheckoutArgs): Promise<void> => {\n setSubmitting(true);\n setError(null);\n try {\n if (args.method === 'card') {\n if (!args.card || !args.holderInfo) {\n throw Object.assign(\n new Error('card and holderInfo are required when method is \"card\"'),\n { code: 'validation' },\n );\n }\n const sdkArgs: CheckoutArgs = {\n method: 'card',\n cycle: args.cycle,\n cpf: args.cpf,\n card: args.card,\n holderInfo: args.holderInfo,\n ...(args.remoteIp ? { remoteIp: args.remoteIp } : {}),\n };\n const result = await subscription.checkout(sdkArgs);\n if (isCheckoutFailure(result)) {\n setError(buildError(result.code, `${result.code}: ${result.reason}`));\n setSubmitting(false);\n return;\n }\n await subscription.refresh();\n setSubmitting(false);\n return;\n }\n if (args.method === 'pix-auto') {\n const result = await subscription.checkout({\n method: 'pix-auto',\n cycle: args.cycle,\n cpf: args.cpf,\n });\n if (isCheckoutFailure(result)) {\n setError(buildError(result.code, `${result.code}: ${result.reason}`));\n setSubmitting(false);\n return;\n }\n setSubmitting(false);\n return;\n }\n // method === 'pix-once'\n const result = await subscription.checkout({\n method: 'pix-once',\n cycle: args.cycle,\n cpf: args.cpf,\n });\n if (isCheckoutFailure(result)) {\n setError(buildError(result.code, `${result.code}: ${result.reason}`));\n setSubmitting(false);\n return;\n }\n setSubmitting(false);\n } catch (err) {\n const code = (err as { code?: string })?.code ?? 'generic_decline';\n const message = err instanceof Error ? err.message : String(err);\n setError(buildError(code, message));\n setSubmitting(false);\n }\n },\n [subscription, buildError],\n );\n\n const cancel = useCallback(async () => {\n try {\n await subscription.cancel();\n await subscription.refresh();\n } catch (err) {\n const code = (err as { code?: string })?.code ?? 'generic_decline';\n const message = err instanceof Error ? err.message : String(err);\n setError(buildError(code, message));\n }\n }, [subscription, buildError]);\n\n const cardState: CardFormStateWithSetter = useMemo(\n () => ({ ...card, set: setCard }),\n [card, setCard],\n );\n\n const cpfState: CpfState = useMemo(\n () => ({ required: cpfRequired, value: cpf, set: setCpf, valid: cpfValid }),\n [cpfRequired, cpf, cpfValid],\n );\n\n // Analytics: emit `paywall_step_viewed` on every canonical step transition.\n // Fire-and-forget; no impact on render or checkout latency. See\n // hooks/usePaywallTracker.ts for the step-derivation contract + Studio\n // consumer in DropoffSection.\n usePaywallTracker({\n selectedMethod,\n cycle,\n cpfRequired,\n cpfValid,\n pixPendingShown: pixPending !== null,\n pixPaid: pixPending?.paid === true,\n hasError: error !== null,\n submitting,\n });\n\n return {\n // Subscription status (reactive, proxied from SDK)\n status,\n hasAccess,\n daysLeftInTrial,\n initialLoadComplete,\n\n // Plan derivation from config (sync, no fetch)\n plan: planDerived,\n\n // Cycle + method selection\n cycle,\n setCycle,\n methods,\n selectedMethod,\n setSelectedMethod,\n\n // Conversion-max derivations (template 0.21)\n hasConsumedTrial,\n currentPriceCents,\n currentMonthlyEquivCents,\n anchorPriceCents,\n selectMethod,\n selectCycle,\n isFree,\n\n // Per-method trial (ADR-022 Amendment 2026-05-12). Use these to render\n // asymmetric copy per method card on the paywall — never a global\n // \"free trial!\" headline when both methods are visible.\n trialDaysForMethod,\n trialDaysCard,\n trialDaysPix,\n\n // Form state\n cpfState,\n cardState,\n\n // High-level + legacy actions\n submit,\n checkout,\n cancel,\n\n // PIX state (proxied from SDK; legacy `paid`/`expiresAt` derived)\n pixPending,\n\n // Error + submit progress\n error,\n submitting,\n\n // Backward-compat aliases (deprecated; remove in template 0.11)\n opening: submitting,\n availableMethods: methods,\n monthlyEquivalent,\n // G154 fix (template 0.24.0 + SDK 0.26.0): wired to SDK action.\n dismissPix: subscription.clearPixPending,\n refreshPlan: () => {},\n };\n}\n","// Maps Asaas error codes (and a few synthetic ones surfaced by the SDK)\n// to user-facing PT-BR messages. Used by usePaywallState + paywall screens\n// when `app.config.json.paywall.errorMessages === \"default\"`.\n\nconst MAP: Record<string, string> = {\n invalid_cpf: 'CPF inválido. Confira os números e tente novamente.',\n cpf_required: 'Por favor, informe seu CPF para continuar.',\n card_declined: 'Cartão recusado pela operadora. Tente outro cartão ou método.',\n insufficient_funds: 'Saldo insuficiente no cartão. Tente outro método.',\n card_expired: 'Cartão expirado. Use um cartão válido.',\n invalid_card_number: 'Número de cartão inválido.',\n invalid_cvv: 'Código de segurança (CVV) inválido.',\n invalid_expiration: 'Data de validade inválida.',\n generic_decline:\n 'Pagamento recusado. Tente novamente em instantes ou use outro método.',\n webhook_unverified:\n 'Não conseguimos confirmar seu pagamento. Atualize a página em alguns segundos.',\n pix_expired: 'QR Code do PIX expirou. Gere um novo.',\n pix_not_paid_yet: 'PIX ainda não foi pago. Aguardando confirmação.',\n};\n\n/**\n * Map Asaas error → PT-BR user-facing message.\n *\n * Two inputs because backend folds Asaas's specific error code into a\n * compound code (`payments.capture_card.tokenize_failed:invalid_holderInfo`)\n * and only the *description* string (\"O CEP informado é inválido.\")\n * distinguishes between sub-cases of `invalid_holderInfo` (CEP, phone, name).\n *\n * Asaas keeps a snapshot of Correios CEPs that lags real registrations by\n * months — CEPs of recently-cadastrated streets (ex: bairros novos) get\n * rejected even though they're valid in ViaCEP/BrasilAPI. We don't suggest\n * a fictitious CEP (would mess up nota fiscal/comms); we explain the issue\n * is on the processor's side and ask user to try a nearby street's CEP.\n */\nexport function asaasErrorMessage(code: string, description?: string): string {\n // Substring match em description tem prioridade — é mais específico que code.\n if (description) {\n const lower = description.toLowerCase();\n if (lower.includes('cep')) {\n return 'Nosso processador de pagamentos não reconheceu esse CEP — a base deles pode estar desatualizada. Tente outro CEP.';\n }\n if (lower.includes('telefone') || lower.includes('contato com ddd')) {\n return 'Telefone inválido. Confira o número com DDD e tente novamente.';\n }\n }\n return MAP[code] ?? 'Ocorreu um erro inesperado. Tente novamente em instantes.';\n}\n","import { useEffect, useRef } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type { CheckoutMethod, CheckoutCycle } from '@hook-sdk/sdk';\n\n/**\n * Canonical paywall step values. Bundle-side (template-controlled), so the list\n * is fixed — Studio dropoff queries can rely on a stable enumeration.\n *\n * - `plan_select` — paywall just opened, user choosing cycle (monthly/yearly)\n * - `method_select` — user picking payment method (card / pix-auto / pix-once)\n * - `cpf_input` — entering CPF (only when paywall.requiresCpf)\n * - `card_form` — filling card data (number, cvv, expiry, holder)\n * - `pix_qr_shown` — PIX QR code rendered, waiting for payment\n * - `error` — checkout failed (declined, validation, etc.)\n * - `success` — checkout succeeded; subscription is ACTIVE/TRIAL\n */\nexport type PaywallStep =\n | 'plan_select'\n | 'method_select'\n | 'cpf_input'\n | 'card_form'\n | 'pix_qr_shown'\n | 'error'\n | 'success';\n\ninterface PaywallStateSnapshot {\n selectedMethod: CheckoutMethod;\n cycle: CheckoutCycle;\n cpfRequired: boolean;\n cpfValid: boolean;\n pixPendingShown: boolean;\n pixPaid: boolean;\n hasError: boolean;\n submitting: boolean;\n}\n\n/**\n * Maps the paywall headless state into a canonical step name. Pure function to\n * keep the tracker testable. Order of branches matters: terminal states first\n * (success > error > pixQR), then progressive (cardForm > cpf > method > plan).\n */\nfunction deriveStep(s: PaywallStateSnapshot): PaywallStep {\n if (s.pixPaid) return 'success';\n if (s.hasError) return 'error';\n if (s.pixPendingShown) return 'pix_qr_shown';\n if (s.selectedMethod === 'card' && s.cpfValid) return 'card_form';\n if (s.cpfRequired && !s.cpfValid) return 'cpf_input';\n // After method is picked but before CPF/card details — user is on the methods\n // sheet. We collapse plan_select into method_select once a method exists,\n // since most paywalls show plan + method together; plan_select only shows\n // before any state has settled (e.g. paywall just mounted with no method\n // available yet — rare).\n if (s.selectedMethod) return 'method_select';\n return 'plan_select';\n}\n\n/**\n * Side-effect hook: emits `paywall_step_viewed` whenever the derived step\n * changes. Fire-and-forget via SDK `track()`. Caller plugs this into\n * `usePaywallState` so every paywall in the platform reports drop-off without\n * any per-app instrumentation.\n *\n * Dedupe via ref: same step in a row never re-emits, even if other paywall\n * state churns (e.g. card form keystrokes). Only step transitions count.\n */\nexport function usePaywallTracker(snapshot: PaywallStateSnapshot): void {\n // Defensive: useHook() may return a partial mock in tests that pre-date the\n // `track` field. Treat missing track as a no-op so analytics never breaks\n // the paywall in legacy test envs.\n const ctx = useHook() as ReturnType<typeof useHook> & {\n track?: (event: string, props?: Record<string, unknown>) => void;\n };\n const track = typeof ctx.track === 'function' ? ctx.track : undefined;\n const lastStepRef = useRef<PaywallStep | null>(null);\n\n const step = deriveStep(snapshot);\n\n useEffect(() => {\n if (lastStepRef.current === step) return;\n lastStepRef.current = step;\n if (!track) return;\n track('paywall_step_viewed', {\n step,\n method: snapshot.selectedMethod,\n cycle: snapshot.cycle,\n });\n // Intentionally only depend on `step` — other props are read for the event\n // payload but shouldn't trigger re-emission. Keeping snapshot.* in the dep\n // array would re-fire on any keystroke during card form fill.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [step]);\n}\n\n// Exported for tests.\nexport const _internals = { deriveStep };\n","import type { ComponentType, ReactNode } from 'react';\nimport { useTemplateConfig } from './TemplateConfigContext';\nimport { usePaywallState, type SubscriptionStatus } from '../hooks/usePaywallState';\n\ninterface Props {\n Paywall: ComponentType;\n children: ReactNode;\n}\n\nconst BLOCKING: ReadonlySet<SubscriptionStatus> = new Set([\n 'pending',\n 'expired',\n 'canceled',\n 'none',\n]);\n\nexport function SubscriptionGate({ Paywall, children }: Props) {\n const { mode } = useTemplateConfig();\n const { status, hasAccess, initialLoadComplete } = usePaywallState();\n\n // free: nunca bloqueia, independente de status.\n if (mode === 'free') return <>{children}</>;\n // G68: evita flash de paywall no cold start antes do 1º /me resolver.\n // Quando não há cache local (primeiro login, novo device), sub === null e\n // status='none' — BLOCKING dispararia o paywall por ~1-2s até o fetch\n // voltar. Com cache (user já pago), sub já vem populado do localStorage\n // e status reflete o último valor conhecido → sem flash.\n // Render nulo (em vez de paywall/spinner) porque AuthGate/AppShell já\n // cobrem o skeleton visual. Flash rápido de nada > flash de paywall.\n if (!initialLoadComplete && status === 'none') return null;\n // Backend-authoritative override: sub CANCELLED com trial_ends_at ou\n // current_period_end no futuro → hasAccess=true (App Store-style: cancela\n // mas usa até fim do período pago). SDK mapStatus retorna \"canceled\" sem\n // distinguir; aqui respeitamos o flag autoritativo do backend.\n // Não cobre \"none\" (sub null = nunca pagou) — só status conhecido + ainda\n // dentro do período. Defesa em profundidade: hasAccess pode ser null se o\n // /me ainda não voltou; nesse caso fail-closed via BLOCKING normal.\n if (hasAccess === true && status !== 'none') return <>{children}</>;\n // pending/expired/canceled/none → Paywall.\n if (BLOCKING.has(status)) return <Paywall />;\n // trialing/active/past_due → libera (past_due é window de grace).\n return <>{children}</>;\n}\n","/**\n * InstallGate — wrapper que decide entre splash bloqueante e pass-through.\n *\n * Colocado em AppRoot entre ThemeProvider e AuthGate. Ver ADR-017 + doc 16.\n *\n * Comportamento:\n * - feature `pwa-install` desabilitado em app.config.json → renderiza children\n * - Standalone detectado → renderiza children\n * - Platform == desktop + !installable → renderiza children (sem banner)\n * - Platform == desktop + installable → renderiza children + banner soft lateral\n * - Mobile/in-app + não-installed + não-dismissed → splash bloqueante (substitui children)\n * - Mobile dismissido → renderiza children\n */\n\nimport { useEffect, useRef, type ReactNode } from 'react';\nimport { useTemplateConfig } from '../../internal/TemplateConfigContext';\nimport { shouldBlockInstall, useInstallPrompt } from '../../hooks/useInstallPrompt';\nimport { AndroidNativeVariant } from './variants/AndroidNativeVariant';\nimport { AndroidManualVariant } from './variants/AndroidManualVariant';\nimport { AndroidPendingVariant } from './variants/AndroidPendingVariant';\nimport { IOSafariVariant } from './variants/IOSafariVariant';\nimport { IOSOtherVariant } from './variants/IOSOtherVariant';\nimport { InAppBrowserVariant } from './variants/InAppBrowserVariant';\nimport { DesktopVariant } from './variants/DesktopVariant';\n\ninterface InstallGateProps {\n children: ReactNode;\n /**\n * Position of the gate in the AppRoot render tree.\n * Forwarded to `pwa_install_splash_shown` analytics for funnel analysis.\n * AppRoot reads `config.install_prompt?.position` and passes it here.\n */\n position?: 'pre-auth' | 'post-paywall';\n}\n\nexport function InstallGate({ children, position }: InstallGateProps) {\n const { slug, features_enabled } = useTemplateConfig();\n const enabled = features_enabled.includes('pwa-install' as never);\n\n const installState = useInstallPrompt(slug);\n const shouldBlock = enabled && shouldBlockInstall(installState);\n\n // Analytics: dispara `pwa_install_splash_shown` 1× por sessão+variant\n const trackedRef = useRef<string | null>(null);\n useEffect(() => {\n if (!shouldBlock) return;\n if (typeof window === 'undefined') return;\n const variantKey = `${slug}:${installState.variant}`;\n if (trackedRef.current === variantKey) return;\n trackedRef.current = variantKey;\n window.posthog?.capture?.('pwa_install_splash_shown', {\n slug,\n platform: installState.platform,\n browser: installState.iosBrowser ?? installState.androidBrowser ?? null,\n in_app_app: installState.inAppApp,\n variant: installState.variant,\n ...(position !== undefined ? { position } : {}),\n });\n }, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp, position]);\n\n if (!enabled) return <>{children}</>;\n if (installState.isInstalled) return <>{children}</>;\n\n // Desktop: banner soft, children renderiza normal em paralelo\n if (installState.variant === 'desktop') {\n const showBanner = !installState.isDismissedSession && !installState.isDismissedPermanent;\n return (\n <>\n {children}\n {showBanner && <DesktopVariant state={installState} actions={installState} />}\n </>\n );\n }\n\n if (!shouldBlock) return <>{children}</>;\n\n // Mobile / in-app: splash bloqueante substitui children\n switch (installState.variant) {\n case 'android-native':\n return <AndroidNativeVariant state={installState} actions={installState} />;\n case 'android-manual':\n return <AndroidManualVariant state={installState} actions={installState} />;\n case 'android-pending':\n return <AndroidPendingVariant />;\n case 'ios-safari':\n return <IOSafariVariant state={installState} actions={installState} />;\n case 'ios-other':\n return <IOSOtherVariant state={installState} actions={installState} />;\n case 'in-app':\n return <InAppBrowserVariant state={installState} actions={installState} />;\n case 'none':\n default:\n return <>{children}</>;\n }\n}\n","/**\n * useInstallPrompt — headless hook pra PWA install prompt.\n *\n * Responsabilidades:\n * - Detectar plataforma (Android / iOS Safari / iOS outros / in-app / desktop)\n * - Detectar browser específico (Chrome, Firefox, Samsung, Instagram, ...)\n * - Detectar standalone mode (PWA já instalado)\n * - Gerenciar dismissal graduada (session → permanente 14d)\n * - Expor `promptInstall()` que dispara `window.__pwaInstallPrompt.prompt()`\n *\n * Não renderiza UI. Componente `<InstallGate>` consome o hook e renderiza.\n *\n * Porta regexes + lógica de `hook-old/src/hooks/usePWAInstall.ts` com\n * divergências deliberadas (ver docs/adr/017 + P20 plan):\n * - enum InAppApp granular pra copy por rede social (G60 amendment)\n * - dismissal graduada em vez de permanente direto\n * - TTL de 14d no permanent dismiss\n * - tracking `skipCount` separado\n *\n * Gotchas de referência:\n * - G61: beforeinstallprompt capturado pré-React (shell main.tsx faz)\n * - G62: distinção ios-safari vs ios-other (Chrome iOS não instala)\n * - G63: in-app browsers checados ANTES de Android/iOS\n */\n\nimport { useCallback, useEffect, useState } from 'react';\n\n// --- Types ---------------------------------------------------------------\n\nexport type Platform =\n | 'android'\n | 'ios-safari'\n | 'ios-other'\n | 'in-app'\n | 'desktop'\n | 'unknown';\n\nexport type IOSBrowser = 'safari' | 'chrome' | 'firefox' | 'edge' | 'other';\n\nexport type AndroidBrowser =\n | 'chrome'\n | 'firefox'\n | 'opera'\n | 'samsung'\n | 'edge'\n | 'other';\n\nexport type InAppApp =\n | 'instagram'\n | 'facebook'\n | 'tiktok'\n | 'whatsapp'\n | 'twitter'\n | 'linkedin'\n | 'telegram'\n | 'line'\n | 'snapchat'\n | 'pinterest'\n | 'wechat'\n | 'other';\n\nexport type InstallVariant =\n | 'android-native'\n | 'android-manual'\n | 'android-pending'\n | 'ios-safari'\n | 'ios-other'\n | 'in-app'\n | 'desktop'\n | 'none';\n\n/**\n * Janela de espera por `beforeinstallprompt` no Android antes de cair pra\n * variant manual. Em redes lentas / 1ª visita / Chrome warm-up, o evento\n * chega 1–3s pós-load. Se decidirmos variant no mount, mostramos\n * instruções manuais por alguns segundos antes do botão \"Instalar\"\n * aparecer (race UX). Esperar até este timeout e só então cair pra manual\n * elimina o flash. 3s cobre P95 sem deixar a tela parada longa demais.\n */\nconst ANDROID_PROMPT_WAIT_MS = 3000;\n\ninterface BeforeInstallPromptEvent extends Event {\n prompt: () => Promise<void>;\n userChoice: Promise<{ outcome: 'accepted' | 'dismissed'; platform: string }>;\n}\n\ndeclare global {\n interface Window {\n __pwaInstallPrompt?: BeforeInstallPromptEvent | null;\n posthog?: { capture?: (event: string, props?: Record<string, unknown>) => void };\n }\n}\n\nexport interface InstallState {\n platform: Platform;\n iosBrowser: IOSBrowser | null;\n androidBrowser: AndroidBrowser | null;\n inAppApp: InAppApp | null;\n isInstallable: boolean;\n isInstalled: boolean;\n isDismissedSession: boolean;\n isDismissedPermanent: boolean;\n skipCount: number;\n variant: InstallVariant;\n}\n\nexport interface InstallActions {\n promptInstall: () => Promise<boolean>;\n dismissSession: () => void;\n dismissPermanent: () => void;\n copyLink: () => Promise<void>;\n reset: () => void;\n}\n\n// --- Regex canônicas (portadas verbatim de hook-old) ---------------------\n\nconst IOS_RE = /iPad|iPhone|iPod/;\nconst IOS_NON_SAFARI_RE = /CriOS|FxiOS|EdgiOS/;\nconst ANDROID_RE = /Android/;\nconst IN_APP_RE =\n /Instagram|FBAN|FBAV|BytedanceWebview|TikTok|Line\\/|Twitter|Snapchat|Pinterest|LinkedIn|WhatsApp|MicroMessenger|Telegram/i;\n\n// --- Constants ----------------------------------------------------------\n\nconst PERMANENT_DISMISS_REPROMPT_DAYS = 14;\nconst SESSION_SKIPS_BEFORE_PERMANENT_OPTION = 2;\n\n// --- Storage keys -------------------------------------------------------\n\nconst storageKey = {\n sessionSkip: (slug: string) => `install:${slug}:session-skip`,\n dismissedAt: (slug: string) => `install:${slug}:dismissed-at`,\n installedAt: (slug: string) => `install:${slug}:installed-at`,\n skipCount: (slug: string) => `install:${slug}:skip-count`,\n};\n\n// --- Detection (pure functions) -----------------------------------------\n\nexport function detectPlatform(ua: string): Platform {\n if (IN_APP_RE.test(ua)) return 'in-app'; // MUST check first (G63)\n const isIOS = IOS_RE.test(ua);\n if (isIOS) {\n const isSafari = /Safari/.test(ua) && !IOS_NON_SAFARI_RE.test(ua);\n return isSafari ? 'ios-safari' : 'ios-other';\n }\n if (ANDROID_RE.test(ua)) return 'android';\n return 'desktop';\n}\n\nexport function detectIOSBrowser(ua: string): IOSBrowser | null {\n if (!IOS_RE.test(ua)) return null;\n if (/CriOS/.test(ua)) return 'chrome';\n if (/FxiOS/.test(ua)) return 'firefox';\n if (/EdgiOS/.test(ua)) return 'edge';\n if (/Safari/.test(ua)) return 'safari';\n return 'other';\n}\n\nexport function detectAndroidBrowser(ua: string): AndroidBrowser | null {\n if (!ANDROID_RE.test(ua)) return null;\n if (/EdgA/.test(ua)) return 'edge';\n if (/OPR|OPT/.test(ua)) return 'opera';\n if (/SamsungBrowser/.test(ua)) return 'samsung';\n if (/Firefox/.test(ua)) return 'firefox';\n if (/Chrome/.test(ua)) return 'chrome';\n return 'other';\n}\n\nexport function detectInAppApp(ua: string): InAppApp | null {\n if (!IN_APP_RE.test(ua)) return null;\n if (/Instagram/i.test(ua)) return 'instagram';\n if (/FBAN|FBAV/.test(ua)) return 'facebook';\n if (/BytedanceWebview|TikTok/i.test(ua)) return 'tiktok';\n if (/WhatsApp/i.test(ua)) return 'whatsapp';\n if (/Twitter/i.test(ua)) return 'twitter';\n if (/LinkedIn/i.test(ua)) return 'linkedin';\n if (/Telegram/i.test(ua)) return 'telegram';\n if (/Line\\//i.test(ua)) return 'line';\n if (/Snapchat/i.test(ua)) return 'snapchat';\n if (/Pinterest/i.test(ua)) return 'pinterest';\n if (/MicroMessenger/i.test(ua)) return 'wechat';\n return 'other';\n}\n\nexport function detectStandalone(): { installed: boolean; source: 'match_media' | 'navigator_standalone' | 'storage_marker' | null } {\n if (typeof window === 'undefined' || typeof navigator === 'undefined') {\n return { installed: false, source: null };\n }\n const mm = window.matchMedia?.('(display-mode: standalone)');\n if (mm?.matches) return { installed: true, source: 'match_media' };\n const fs = window.matchMedia?.('(display-mode: fullscreen)');\n if (fs?.matches) return { installed: true, source: 'match_media' };\n // @ts-expect-error — legacy iOS Safari property\n if (navigator.standalone === true) return { installed: true, source: 'navigator_standalone' };\n return { installed: false, source: null };\n}\n\n// --- Analytics helper ----------------------------------------------------\n\nfunction track(event: string, props: Record<string, unknown>): void {\n if (typeof window === 'undefined') return;\n window.posthog?.capture?.(event, props);\n}\n\n// --- Variant picker ------------------------------------------------------\n\nfunction pickVariant(\n state: Omit<InstallState, 'variant'>,\n promptWaitElapsed: boolean,\n): InstallVariant {\n if (state.isInstalled) return 'none';\n switch (state.platform) {\n case 'android':\n if (state.isInstallable) return 'android-native';\n // Não recebemos beforeinstallprompt ainda. Espera até `promptWaitElapsed`\n // antes de cair em manual — Chrome dispara o evento 1-3s pós-load em\n // muitos casos. Sem essa espera, mostramos instruções manuais e troca\n // pra botão depois (race UX).\n return promptWaitElapsed ? 'android-manual' : 'android-pending';\n case 'ios-safari':\n return 'ios-safari';\n case 'ios-other':\n return 'ios-other';\n case 'in-app':\n return 'in-app';\n case 'desktop':\n return state.isInstallable ? 'desktop' : 'none';\n default:\n return 'none';\n }\n}\n\n// --- Hook ---------------------------------------------------------------\n\nfunction safeStorage(): { getItem(k: string): string | null; setItem(k: string, v: string): void; removeItem(k: string): void } | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n localStorage.setItem('__install_probe', '1');\n localStorage.removeItem('__install_probe');\n return localStorage;\n } catch {\n return null;\n }\n}\n\nfunction readPermanentDismiss(slug: string): { dismissed: boolean; dismissedAt: string | null } {\n const storage = safeStorage();\n if (!storage) return { dismissed: false, dismissedAt: null };\n const raw = storage.getItem(storageKey.dismissedAt(slug));\n if (!raw) return { dismissed: false, dismissedAt: null };\n const parsed = Date.parse(raw);\n if (Number.isNaN(parsed)) return { dismissed: false, dismissedAt: null };\n const daysAgo = (Date.now() - parsed) / (1000 * 60 * 60 * 24);\n return { dismissed: daysAgo < PERMANENT_DISMISS_REPROMPT_DAYS, dismissedAt: raw };\n}\n\nfunction readInstalledMarker(slug: string): boolean {\n const storage = safeStorage();\n if (!storage) return false;\n return storage.getItem(storageKey.installedAt(slug)) !== null;\n}\n\nfunction readSkipCount(slug: string): number {\n const storage = safeStorage();\n if (!storage) return 0;\n const raw = storage.getItem(storageKey.skipCount(slug));\n const n = raw ? Number.parseInt(raw, 10) : 0;\n return Number.isFinite(n) && n >= 0 ? n : 0;\n}\n\nfunction readSessionSkip(slug: string): boolean {\n if (typeof sessionStorage === 'undefined') return false;\n try {\n return sessionStorage.getItem(storageKey.sessionSkip(slug)) === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * Hook principal. Passar o slug do app (usado pra namespacing de storage +\n * analytics). Componentes do template pegam via useTemplateConfig().slug.\n */\nexport function useInstallPrompt(slug: string): InstallState & InstallActions {\n const ua =\n typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string'\n ? navigator.userAgent\n : '';\n\n const platform = detectPlatform(ua);\n const iosBrowser = detectIOSBrowser(ua);\n const androidBrowser = detectAndroidBrowser(ua);\n const inAppApp = detectInAppApp(ua);\n\n const [isInstallable, setIsInstallable] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false;\n return window.__pwaInstallPrompt != null;\n });\n\n const [isInstalled, setIsInstalled] = useState<boolean>(() => {\n const { installed } = detectStandalone();\n return installed || readInstalledMarker(slug);\n });\n\n const [isDismissedSession, setIsDismissedSession] = useState<boolean>(() => readSessionSkip(slug));\n const [isDismissedPermanent, setIsDismissedPermanent] = useState<boolean>(() => readPermanentDismiss(slug).dismissed);\n const [skipCount, setSkipCount] = useState<number>(() => readSkipCount(slug));\n\n // Anti-flash: no mount, Android sem beforeinstallprompt fica em estado\n // pendente até `ANDROID_PROMPT_WAIT_MS` passar. Só aí caímos pra manual.\n // Inicia true se evento já chegou pré-React (capture.ts no shell).\n const [promptWaitElapsed, setPromptWaitElapsed] = useState<boolean>(() => {\n if (typeof window === 'undefined') return true;\n return window.__pwaInstallPrompt != null;\n });\n useEffect(() => {\n if (promptWaitElapsed) return;\n const id = setTimeout(() => setPromptWaitElapsed(true), ANDROID_PROMPT_WAIT_MS);\n return () => clearTimeout(id);\n }, [promptWaitElapsed]);\n\n // beforeinstallprompt listener (fallback — shell main.tsx já captura antes,\n // mas se evento vier pós-React em algum edge case, pegamos aqui também)\n useEffect(() => {\n if (typeof window === 'undefined') return;\n if (window.__pwaInstallPrompt) {\n setIsInstallable(true);\n }\n const onPrompt = (e: Event) => {\n e.preventDefault();\n window.__pwaInstallPrompt = e as BeforeInstallPromptEvent;\n setIsInstallable(true);\n };\n const onInstalled = () => {\n setIsInstalled(true);\n setIsInstallable(false);\n window.__pwaInstallPrompt = null;\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.installedAt(slug), new Date().toISOString());\n };\n window.addEventListener('beforeinstallprompt', onPrompt);\n window.addEventListener('appinstalled', onInstalled);\n return () => {\n window.removeEventListener('beforeinstallprompt', onPrompt);\n window.removeEventListener('appinstalled', onInstalled);\n };\n }, [slug]);\n\n // Standalone changes (user instala durante sessão) → update gate\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia?.('(display-mode: standalone)');\n if (!mq) return;\n const handler = (e: MediaQueryListEvent) => {\n if (e.matches) {\n setIsInstalled(true);\n track('pwa_install_standalone_detected', { slug, source: 'match_media' });\n }\n };\n mq.addEventListener?.('change', handler);\n return () => mq.removeEventListener?.('change', handler);\n }, [slug]);\n\n const variant = pickVariant(\n {\n platform,\n iosBrowser,\n androidBrowser,\n inAppApp,\n isInstallable,\n isInstalled,\n isDismissedSession,\n isDismissedPermanent,\n skipCount,\n },\n promptWaitElapsed,\n );\n\n const promptInstall = useCallback(async (): Promise<boolean> => {\n if (typeof window === 'undefined') return false;\n const prompt = window.__pwaInstallPrompt;\n if (!prompt) return false;\n\n track('pwa_install_prompt_clicked', { slug });\n\n try {\n await prompt.prompt();\n const { outcome } = await prompt.userChoice;\n track('pwa_install_prompt_outcome', { slug, outcome });\n if (outcome === 'accepted') {\n setIsInstalled(true);\n setIsInstallable(false);\n window.__pwaInstallPrompt = null;\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.installedAt(slug), new Date().toISOString());\n return true;\n }\n return false;\n } catch {\n return false;\n }\n }, [slug]);\n\n const dismissSession = useCallback(() => {\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.setItem(storageKey.sessionSkip(slug), 'true');\n } catch {\n /* ignore */\n }\n }\n const storage = safeStorage();\n const newCount = skipCount + 1;\n if (storage) storage.setItem(storageKey.skipCount(slug), String(newCount));\n setSkipCount(newCount);\n setIsDismissedSession(true);\n track('pwa_install_session_skip', { slug, platform, skip_count: newCount });\n }, [slug, skipCount, platform]);\n\n const dismissPermanent = useCallback(() => {\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.dismissedAt(slug), new Date().toISOString());\n setIsDismissedPermanent(true);\n track('pwa_install_permanent_dismiss', { slug, platform, prior_skip_count: skipCount });\n }, [slug, platform, skipCount]);\n\n const copyLink = useCallback(async (): Promise<void> => {\n if (typeof navigator === 'undefined' || typeof location === 'undefined') return;\n try {\n await navigator.clipboard?.writeText?.(location.href);\n } catch {\n /* ignore — caller surfaces via toast */\n }\n }, []);\n\n const reset = useCallback(() => {\n const storage = safeStorage();\n if (storage) {\n storage.removeItem(storageKey.dismissedAt(slug));\n storage.removeItem(storageKey.installedAt(slug));\n storage.removeItem(storageKey.skipCount(slug));\n }\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.removeItem(storageKey.sessionSkip(slug));\n } catch {\n /* ignore */\n }\n }\n setIsDismissedSession(false);\n setIsDismissedPermanent(false);\n setSkipCount(0);\n }, [slug]);\n\n return {\n platform,\n iosBrowser,\n androidBrowser,\n inAppApp,\n isInstallable,\n isInstalled,\n isDismissedSession,\n isDismissedPermanent,\n skipCount,\n variant,\n promptInstall,\n dismissSession,\n dismissPermanent,\n copyLink,\n reset,\n };\n}\n\n/**\n * Exposto pra InstallGate decidir se renderiza splash (não faz parte do hook\n * retornado pra manter surface pequena — componente usa).\n */\nexport function shouldBlockInstall(state: InstallState, now: number = Date.now()): boolean {\n if (state.isInstalled) return false;\n if (state.variant === 'none') return false;\n if (state.isDismissedSession) return false;\n if (state.isDismissedPermanent) {\n // readPermanentDismiss já checou TTL; redundante, mas explicit pra tests\n void now;\n return false;\n }\n // Desktop só bloqueia se não-installable (banner soft vem por fora)\n if (state.platform === 'desktop' && !state.isInstallable) return false;\n if (state.platform === 'unknown') return false;\n return true;\n}\n\n/**\n * Exposto pra decidir se mostra \"Não me pergunte mais\".\n */\nexport function shouldShowPermanentOption(state: InstallState): boolean {\n return state.skipCount >= SESSION_SKIPS_BEFORE_PERMANENT_OPTION;\n}\n","/**\n * Copy pt-BR do PWA install prompt. Hardcoded (template não tem i18n).\n * Design doc: docs/superpowers/specs/2026-04-22-p20-pwa-install-prompt-design.md\n */\n\nexport const INSTALL_COPY = {\n android: {\n native: {\n title: 'Instale no seu celular',\n subtitle: 'Acesso rápido, sem precisar do navegador',\n cta: 'Baixar',\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n manual: {\n title: 'Instale em 2 toques',\n subtitle: 'Toque no menu do navegador e escolha \"Instalar aplicativo\"',\n step1: 'Toque no menu do navegador',\n step2: 'Escolha \"Instalar aplicativo\"',\n cta: 'Entendi',\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n },\n iosSafari: {\n title: 'Adicione à sua Tela de Início',\n subtitle: 'Siga os 3 passos',\n step1: {\n title: 'Toque em Compartilhar',\n subtitle: 'Na barra inferior do Safari',\n },\n step2: {\n title: 'Role e toque em \"Adicionar à Tela de Início\"',\n iconLabel: 'Adicionar à Tela de Início',\n },\n step3: {\n title: 'Toque em \"Adicionar\" pra confirmar',\n buttonLabel: 'Adicionar',\n },\n skip: 'Continuar no Safari',\n skipPermanent: 'Não me pergunte mais',\n },\n iosOther: {\n title: 'Adicione à sua Tela de Início',\n subtitle: 'Siga os 3 passos',\n step1: {\n title: 'Toque em Compartilhar',\n subtitle: 'Geralmente no topo ou no menu do navegador',\n },\n step2: {\n title: 'Role e toque em \"Adicionar à Tela de Início\"',\n iconLabel: 'Adicionar à Tela de Início',\n },\n step3: {\n title: 'Toque em \"Adicionar\" pra confirmar',\n buttonLabel: 'Adicionar',\n },\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n inApp: {\n instagram: {\n title: 'Pra instalar, abra fora do Instagram',\n step1: 'Toque em ⋯ (canto superior direito)',\n step2: 'Escolha \"Abrir no navegador externo\"',\n },\n facebook: {\n title: 'Pra instalar, abra fora do Facebook',\n step1: 'Toque em ⋮',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n tiktok: {\n title: 'Pra instalar, abra fora do TikTok',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no Safari\" (iOS) ou \"Abrir no Chrome\" (Android)',\n },\n whatsapp: {\n title: 'Pra instalar, abra fora do WhatsApp',\n step1: 'Toque longo no link',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n twitter: {\n title: 'Pra instalar, abra fora do Twitter',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n linkedin: {\n title: 'Pra instalar, abra fora do LinkedIn',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n telegram: {\n title: 'Pra instalar, abra fora do Telegram',\n step1: 'Toque em ⋮',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n line: {\n title: 'Pra instalar, abra fora do LINE',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n snapchat: {\n title: 'Pra instalar, abra fora do Snapchat',\n step1: 'Mantenha pressionado o link',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n pinterest: {\n title: 'Pra instalar, abra fora do Pinterest',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n wechat: {\n title: 'Pra instalar, abra fora do WeChat',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n other: {\n title: 'Abra no navegador do celular',\n step1: 'Toque no menu do app atual',\n step2: 'Escolha \"Abrir no Chrome\" ou \"Abrir no Safari\"',\n },\n copy: 'Copiar link',\n copiedToast: 'Link copiado. Cole no Chrome/Safari.',\n skip: 'Continuar aqui mesmo',\n skipPermanent: 'Não me pergunte mais',\n },\n desktop: {\n title: 'Instale no computador',\n subtitle: 'Acesso rápido',\n cta: 'Baixar',\n close: 'Fechar',\n },\n} as const;\n","/**\n * InstallSplash — layout full-screen compartilhado pras variants.\n * Variant renderiza seu próprio conteúdo via children.\n */\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from '../../internal/TemplateConfigContext';\n\ninterface InstallSplashProps {\n children: ReactNode;\n title: string;\n subtitle?: string;\n}\n\nexport function InstallSplash({ children, title, subtitle }: InstallSplashProps) {\n const { name, theme } = useTemplateConfig();\n const iconUrl = theme.icon_url || theme.logo_url || null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"install-splash-title\"\n aria-describedby={subtitle ? 'install-splash-subtitle' : undefined}\n style={overlayStyle}\n >\n <div style={cardStyle}>\n <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 16 }}>\n {iconUrl ? (\n <img\n src={iconUrl}\n alt={`Ícone de ${name}`}\n style={{ width: 80, height: 80, borderRadius: 20, objectFit: 'cover' }}\n />\n ) : (\n <div\n style={{\n width: 80,\n height: 80,\n borderRadius: 20,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 36,\n fontWeight: 700,\n }}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n )}\n </div>\n\n <h1 id=\"install-splash-title\" style={titleStyle}>\n {title}\n </h1>\n\n {subtitle && (\n <p id=\"install-splash-subtitle\" style={subtitleStyle}>\n {subtitle}\n </p>\n )}\n\n <div style={{ marginTop: 24 }}>{children}</div>\n\n <p style={footerStyle}>por Hook</p>\n </div>\n </div>\n );\n}\n\n// --- Shared styles (exported pra reuso nas variants) -------------------\n\nexport const primaryButtonStyle: CSSProperties = {\n width: '100%',\n padding: '14px 20px',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n border: 'none',\n borderRadius: 999,\n fontSize: 17,\n fontWeight: 600,\n cursor: 'pointer',\n marginBottom: 12,\n};\n\nexport const secondaryButtonStyle: CSSProperties = {\n width: '100%',\n padding: '12px 20px',\n background: 'transparent',\n color: 'var(--hook-color-primary)',\n border: '1px solid var(--hook-color-primary)',\n borderRadius: 999,\n fontSize: 15,\n fontWeight: 500,\n cursor: 'pointer',\n marginBottom: 12,\n};\n\nexport const skipLinkStyle: CSSProperties = {\n display: 'block',\n width: '100%',\n padding: '10px',\n marginTop: 8,\n background: 'transparent',\n color: '#555',\n border: 'none',\n fontSize: 14,\n textDecoration: 'underline',\n cursor: 'pointer',\n textAlign: 'center',\n};\n\nexport const skipPermanentLinkStyle: CSSProperties = {\n ...skipLinkStyle,\n color: '#999',\n fontSize: 13,\n marginTop: 4,\n};\n\n// --- Internal layout styles --------------------------------------------\n\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--hook-color-background, #fafafa)',\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 20,\n overflow: 'auto',\n};\n\nconst cardStyle: CSSProperties = {\n width: '100%',\n maxWidth: 420,\n padding: 24,\n textAlign: 'center',\n};\n\nconst titleStyle: CSSProperties = {\n fontSize: 24,\n fontWeight: 700,\n lineHeight: 1.2,\n margin: '0 0 8px 0',\n color: '#111',\n};\n\nconst subtitleStyle: CSSProperties = {\n fontSize: 15,\n lineHeight: 1.4,\n color: '#555',\n margin: 0,\n};\n\nconst footerStyle: CSSProperties = {\n fontSize: 11,\n color: '#aaa',\n marginTop: 32,\n letterSpacing: 0.5,\n};\n","/**\n * SVG icons inline pro InstallGate. Template não depende de lucide-react;\n * copiamos só os 6 necessários (~1.8 KB total minified).\n *\n * Base: ícones de `lucide-react` com ajustes pra iOS share button (precisa\n * estética específica vs o genérico). Paths conferidos com as versões em\n * hook-old.\n */\n\nimport type { CSSProperties } from 'react';\n\ninterface IconProps {\n size?: number;\n style?: CSSProperties;\n 'aria-hidden'?: boolean | 'true' | 'false';\n className?: string;\n}\n\nconst defaultSvgProps = (size: number) => ({\n width: size,\n height: size,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n});\n\n/** iOS Safari share button — square com seta pra cima */\nexport function ShareIconIOS({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M12 2L12 15\" />\n <path d=\"M8 6L12 2L16 6\" />\n <path d=\"M4 11v9a2 2 0 002 2h12a2 2 0 002-2v-9\" />\n </svg>\n );\n}\n\n/** Share genérico — 3 círculos conectados */\nexport function ShareIconGeneric({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"18\" cy=\"5\" r=\"3\" />\n <circle cx=\"6\" cy=\"12\" r=\"3\" />\n <circle cx=\"18\" cy=\"19\" r=\"3\" />\n <path d=\"M8.59 13.51l6.83 3.98\" />\n <path d=\"M15.41 6.51l-6.82 3.98\" />\n </svg>\n );\n}\n\n/** Menu ⋮ (Android Chrome, Facebook) */\nexport function MenuDotsVerticalIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"5\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"19\" r=\"1.5\" />\n </svg>\n );\n}\n\n/** Menu ⋯ (Instagram, TikTok — horizontal) */\nexport function MenuDotsHorizontalIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"5\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"19\" cy=\"12\" r=\"1.5\" />\n </svg>\n );\n}\n\n/** Square + (iOS \"Adicionar à Tela de Início\") */\nexport function SquarePlusIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M12 8v8\" />\n <path d=\"M8 12h8\" />\n </svg>\n );\n}\n\n/** Download (Android Chrome \"Instalar aplicativo\") */\nexport function DownloadIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n );\n}\n\n/** External link (pra in-app \"Abrir no navegador\") */\nexport function ExternalLinkIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n );\n}\n\n/** X (close) */\nexport function XIcon({ size = 20, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { DownloadIcon } from '../icons';\n\nexport function AndroidNativeVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.android.native;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <button\n data-testid=\"install-prompt-cta-android-native\"\n type=\"button\"\n onClick={() => void actions.promptInstall()}\n style={{ ...primaryButtonStyle, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}\n >\n <DownloadIcon size={18} />\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { MenuDotsVerticalIcon, DownloadIcon } from '../icons';\n\nexport function AndroidManualVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.android.manual;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title}>\n <Step n={1} icon={<MenuDotsVerticalIcon size={20} />}>\n {copy.step1}\n </Step>\n <Step n={2} icon={<DownloadIcon size={18} />}>\n {copy.step2}\n </Step>\n\n <button\n data-testid=\"install-prompt-cta-android-manual\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={primaryButtonStyle}\n >\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\nfunction Step({ n, icon, children }: { n: number; icon: React.ReactNode; children: React.ReactNode }) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: '#f5f5f7',\n borderRadius: 12,\n marginBottom: 10,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 14,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1, fontSize: 15, color: '#333' }}>{children}</div>\n <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>\n </div>\n );\n}\n","import { InstallSplash } from '../InstallSplash';\nimport { INSTALL_COPY } from '../copy';\n\n/**\n * AndroidPendingVariant — splash silencioso enquanto aguarda\n * `beforeinstallprompt`. Chrome dispara o evento async (até ~3s pós-load).\n * Mostrando manual imediato + trocando pra native depois cria flash UX.\n *\n * Aqui não renderizamos CTA: nem botão \"Instalar\" (sem evento ainda)\n * nem instruções manuais (podemos receber o evento e ter botão real).\n * Mostra só ícone + título do app + spinner sutil. Variant é trocado\n * automaticamente pra android-native ou android-manual em até 3s.\n */\nexport function AndroidPendingVariant() {\n const copy = INSTALL_COPY.android.native;\n return (\n <InstallSplash title={copy.title}>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 16,\n padding: '24px 0',\n }}\n >\n <Spinner />\n </div>\n </InstallSplash>\n );\n}\n\nfunction Spinner() {\n return (\n <div\n aria-hidden\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n border: '3px solid #e5e5e7',\n borderTopColor: 'var(--hook-color-primary)',\n animation: 'hook-install-spin 0.8s linear infinite',\n }}\n >\n <style>{`@keyframes hook-install-spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function Step({\n n,\n title,\n subtitle,\n visual,\n}: {\n n: number;\n title: string;\n subtitle?: string;\n visual?: ReactNode;\n}) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 12,\n marginBottom: 16,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 32,\n height: 32,\n borderRadius: 10,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 15,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1 }}>\n <p style={{ margin: 0, fontSize: 15, fontWeight: 500, color: '#111', lineHeight: 1.3 }}>\n {title}\n </p>\n {subtitle && (\n <p style={{ margin: '4px 0 0 0', fontSize: 13, color: '#777' }}>{subtitle}</p>\n )}\n {visual}\n </div>\n </div>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport { InstallSplash, skipLinkStyle, skipPermanentLinkStyle } from '../InstallSplash';\nimport { ShareIconIOS, SquarePlusIcon } from '../icons';\nimport { Step } from '../Step';\n\nexport function IOSafariVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.iosSafari;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <Step\n n={1}\n title={copy.step1.title}\n subtitle={copy.step1.subtitle}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 0',\n marginTop: 8,\n }}\n >\n <ShareIconIOS size={32} style={{ color: 'var(--hook-color-primary)' }} />\n </div>\n }\n />\n\n <Step\n n={2}\n title={copy.step2.title}\n visual={\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 14px',\n marginTop: 8,\n }}\n >\n <SquarePlusIcon size={22} style={{ color: '#555' }} />\n <span style={{ fontSize: 14, color: '#333' }}>{copy.step2.iconLabel}</span>\n </div>\n }\n />\n\n <Step\n n={3}\n title={copy.step3.title}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '10px 14px',\n marginTop: 8,\n }}\n >\n <span\n style={{\n color: 'var(--hook-color-primary)',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {copy.step3.buttonLabel}\n </span>\n </div>\n }\n />\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={{ ...skipLinkStyle, marginTop: 16 }}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport { InstallSplash, skipLinkStyle, skipPermanentLinkStyle } from '../InstallSplash';\nimport { ShareIconIOS, SquarePlusIcon } from '../icons';\nimport { Step } from '../Step';\n\nexport function IOSOtherVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.iosOther;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <Step\n n={1}\n title={copy.step1.title}\n subtitle={copy.step1.subtitle}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 0',\n marginTop: 8,\n }}\n >\n <ShareIconIOS size={32} style={{ color: 'var(--hook-color-primary)' }} />\n </div>\n }\n />\n\n <Step\n n={2}\n title={copy.step2.title}\n visual={\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 14px',\n marginTop: 8,\n }}\n >\n <SquarePlusIcon size={22} style={{ color: '#555' }} />\n <span style={{ fontSize: 14, color: '#333' }}>{copy.step2.iconLabel}</span>\n </div>\n }\n />\n\n <Step\n n={3}\n title={copy.step3.title}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '10px 14px',\n marginTop: 8,\n }}\n >\n <span\n style={{\n color: 'var(--hook-color-primary)',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {copy.step3.buttonLabel}\n </span>\n </div>\n }\n />\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={{ ...skipLinkStyle, marginTop: 16 }}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n","import { useState } from 'react';\nimport type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { MenuDotsHorizontalIcon, MenuDotsVerticalIcon, ExternalLinkIcon } from '../icons';\n\nexport function InAppBrowserVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const app = state.inAppApp ?? 'other';\n const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;\n const copy = INSTALL_COPY.inApp;\n const showPermanent = shouldShowPermanentOption(state);\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await actions.copyLink();\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n // Ícone varia: FB/Telegram usam ⋮; Instagram/TikTok/Twitter/LinkedIn/Pinterest usam ⋯\n const DotsIcon =\n app === 'facebook' || app === 'telegram' ? MenuDotsVerticalIcon : MenuDotsHorizontalIcon;\n\n return (\n <InstallSplash title={appCopy.title}>\n <Step n={1} icon={<DotsIcon size={20} />}>\n {appCopy.step1}\n </Step>\n <Step n={2} icon={<ExternalLinkIcon size={18} />}>\n {appCopy.step2}\n </Step>\n\n <button\n data-testid=\"install-prompt-cta-inapp-copy\"\n type=\"button\"\n onClick={() => void handleCopy()}\n style={{ ...primaryButtonStyle, marginTop: 8 }}\n >\n {copied ? copy.copiedToast : copy.copy}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\nfunction Step({\n n,\n icon,\n children,\n}: {\n n: number;\n icon: React.ReactNode;\n children: React.ReactNode;\n}) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: '#f5f5f7',\n borderRadius: 12,\n marginBottom: 10,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 14,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1, fontSize: 14, color: '#333' }}>{children}</div>\n <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\nimport type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { useTemplateConfig } from '../../../internal/TemplateConfigContext';\nimport { INSTALL_COPY } from '../copy';\nimport { DownloadIcon, XIcon } from '../icons';\n\n/**\n * Desktop variant — NÃO-bloqueante. Banner soft no canto inferior direito.\n * Só aparece se `beforeinstallprompt` disparou (Chrome/Edge desktop).\n */\nexport function DesktopVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const { name, theme } = useTemplateConfig();\n const copy = INSTALL_COPY.desktop;\n const iconUrl = theme.icon_url || theme.logo_url || null;\n\n // Guard defensivo: só renderiza se installable\n if (!state.isInstallable) return null;\n\n return (\n <div\n role=\"complementary\"\n aria-label={copy.title}\n style={bannerStyle}\n >\n {iconUrl ? (\n <img\n src={iconUrl}\n alt=\"\"\n style={{ width: 40, height: 40, borderRadius: 10, objectFit: 'cover', flexShrink: 0 }}\n />\n ) : (\n <div\n style={{\n width: 40,\n height: 40,\n borderRadius: 10,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 18,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n )}\n\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 14, fontWeight: 600, color: '#111' }}>{copy.title}</div>\n <div style={{ fontSize: 12, color: '#666' }}>{copy.subtitle}</div>\n </div>\n\n <button\n data-testid=\"install-prompt-cta-desktop\"\n type=\"button\"\n onClick={() => void actions.promptInstall()}\n style={{\n padding: '8px 14px',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n border: 'none',\n borderRadius: 999,\n fontSize: 13,\n fontWeight: 600,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n flexShrink: 0,\n }}\n >\n <DownloadIcon size={14} />\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-desktop-close\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n aria-label={copy.close}\n style={{\n background: 'transparent',\n border: 'none',\n cursor: 'pointer',\n color: '#888',\n padding: 4,\n flexShrink: 0,\n }}\n >\n <XIcon size={16} />\n </button>\n </div>\n );\n}\n\nconst bannerStyle: CSSProperties = {\n position: 'fixed',\n bottom: 24,\n right: 24,\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 16px',\n background: '#fff',\n border: '1px solid rgba(0,0,0,0.08)',\n borderRadius: 16,\n boxShadow: '0 10px 30px rgba(0,0,0,0.12)',\n maxWidth: 400,\n};\n","// Side-effect-only component: observa estado e dispara push.subscribe() quando\n// apropriado. NUNCA renderiza UI bloqueante — sempre retorna null. No MVP, o SDK\n// stub de push lança 'unsupported_mvp', então este componente não faz nada.\n// Quando P14 entregar VAPID real, adicionar gate por 2ª sessão + dismissed_at.\nexport function PushPrompt() {\n return null;\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nconst DISMISS_KEY = 'hook:session-expired-dismissed-until';\nconst DISMISS_TTL_MS = 60 * 60 * 1000; // 1h\n\n/**\n * SessionExpiredBanner — Wave 4 Fix #27.\n *\n * Surfaces \"Sua sessão expirou\" when the SDK transitions from\n * authenticated → anonymous. Cold-mount anonymous (no prior session)\n * stays silent because that's the expected first-page-load state.\n *\n * Mounted from AppRoot.tsx (golden-path) so every template-consuming app\n * inherits the UX. Apps that need a different banner can fork the file\n * post-eject; the base template is informational only — actual redirect\n * to /login is handled by AuthGated routing already.\n */\nexport function SessionExpiredBanner() {\n const { authStatus } = useHook() as { authStatus?: string };\n const wasAuthRef = useRef(false);\n const [show, setShow] = useState(false);\n\n useEffect(() => {\n if (authStatus === 'authenticated') {\n wasAuthRef.current = true;\n setShow(false);\n return;\n }\n if (authStatus === 'anonymous' && wasAuthRef.current) {\n const until = Number(localStorage.getItem(DISMISS_KEY) ?? '0');\n if (Date.now() < until) {\n setShow(false);\n return;\n }\n setShow(true);\n }\n }, [authStatus]);\n\n if (!show) return null;\n\n function dismiss() {\n localStorage.setItem(DISMISS_KEY, String(Date.now() + DISMISS_TTL_MS));\n setShow(false);\n }\n\n return (\n <div\n role=\"alert\"\n className=\"fixed top-0 inset-x-0 px-4 py-3 flex items-center justify-between gap-3 text-sm font-medium shadow-lg\"\n style={{\n zIndex: 10001,\n backgroundColor: '#991b1b',\n color: '#ffffff',\n }}\n >\n <span>\n <strong className=\"font-bold\">Sua sessão expirou.</strong> Faça login novamente para continuar.\n </span>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={dismiss}\n className=\"px-3 py-1.5 rounded text-xs font-semibold\"\n style={{ backgroundColor: '#ffffff', color: '#991b1b' }}\n >\n Fazer login\n </button>\n <button\n type=\"button\"\n onClick={dismiss}\n aria-label=\"Fechar\"\n className=\"px-2 py-1 text-xs\"\n style={{ color: '#ffffff' }}\n >\n Fechar\n </button>\n </div>\n </div>\n );\n}\n","/**\n * EmailVerifyBanner — sticky top banner shown to authenticated users\n * whose `emailVerified === false`. Disappears automatically when the\n * user clicks the email-verify link and `/auth/me` reflects the change.\n *\n * Mounted from AppRoot.tsx (golden-path) inside the AuthGated tree, so\n * every template-consuming app inherits the UX without app-side wiring.\n *\n * Copy is hardcoded pt-BR for MVP (both shipped apps are pt-BR-only).\n * i18n integration is a future-iteration concern once a second locale\n * ships.\n *\n * Design: spec 2026-05-13-signup-ux-email-verify-banner-design.md.\n */\nimport { useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport function EmailVerifyBanner() {\n const { user, auth } = useHook();\n const [sending, setSending] = useState(false);\n const [sent, setSent] = useState(false);\n\n if (!user || user.emailVerified) return null;\n\n async function handleResend() {\n if (sending || sent) return;\n setSending(true);\n try {\n await auth.resendVerify();\n setSent(true);\n } catch {\n // Silent fail per spec: banner is low-stakes. User can click again.\n } finally {\n setSending(false);\n }\n }\n\n const label = sent ? 'Enviado!' : sending ? 'Enviando...' : 'Reenviar link';\n\n return (\n <div\n role=\"status\"\n data-testid=\"email-verify-banner\"\n 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\"\n >\n <span>Confirma teu e-mail pra liberar tudo.</span>\n <button\n type=\"button\"\n onClick={handleResend}\n disabled={sending || sent}\n 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\"\n >\n {label}\n </button>\n </div>\n );\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error, info: { componentStack: string }) {\n // Spread error.message + stack as plain strings so browsers print them\n // inline (default behavior with a bare Error logs only the constructor\n // name \"Error\" until the dev clicks to expand the object — fine in\n // dev, useless when triaging from a screenshotted prod console).\n console.error(\n '[ErrorBoundary] caught:',\n error?.message || '(no message)',\n '\\nstack:',\n error?.stack || '(no stack)',\n '\\ncomponentStack:',\n info?.componentStack || '(no componentStack)',\n );\n }\n\n render() {\n if (this.state.error) {\n return this.props.fallback ?? (\n <div role=\"alert\" style={{ padding: 24, textAlign: 'center' }}>\n <h2>Algo deu errado</h2>\n <p style={{ opacity: 0.7 }}>Recarregue a página pra tentar de novo.</p>\n </div>\n );\n }\n return <>{this.props.children}</>;\n }\n}\n","/**\n * I18nProvider — react-i18next wiring for Hook apps.\n *\n * Mounted internally by <AppRoot> when `config.i18n` is present (see\n * spec rev 14 §13 #18 + plan T6.2). User-locale persists via the SDK's\n * usePersistedState under the key `user-locale`, so it survives reload\n * and propagates across tabs (best-effort).\n *\n * Implementation notes:\n * - i18n is initialised once per module load (i18next is a singleton).\n * We initialise synchronously the first time the provider renders so\n * the very first paint already has translations (no flash of keys / no\n * Suspense fallback).\n * - Subsequent locale changes go through `i18n.changeLanguage` from a\n * useEffect, so React state stays the source of truth.\n * - Resources are passed as a flat `{ locale: { key: string } }` map; we\n * wrap them in the i18next-expected `{ translation: ... }` namespace.\n * - We do NOT use the languagedetector plugin here even though the\n * package is declared in dependencies — Hook drives locale exclusively\n * from `usePersistedState` so the source of truth is consistent across\n * the app. The dep is shipped per plan so apps may opt in via a custom\n * provider.\n */\nimport { useEffect, type ReactNode } from 'react';\nimport i18n from 'i18next';\nimport { I18nextProvider, initReactI18next } from 'react-i18next';\nimport { usePersistedState } from '@hook-sdk/sdk';\n\nexport interface I18nProviderProps {\n defaultLocale: string;\n supportedLocales: string[];\n resources: Record<string, Record<string, string>>;\n children: ReactNode;\n}\n\nfunction ensureInitialized(\n defaultLocale: string,\n supportedLocales: string[],\n resources: Record<string, Record<string, string>>,\n initialLocale: string,\n) {\n if (i18n.isInitialized) return;\n i18n.use(initReactI18next).init({\n resources: Object.fromEntries(\n supportedLocales.map((l) => [l, { translation: resources[l] ?? {} }]),\n ),\n lng: initialLocale,\n fallbackLng: defaultLocale,\n interpolation: { escapeValue: false },\n // useTranslation suspends by default until i18next is \"ready\". Inline\n // resources are sync, so suspending creates a guaranteed empty render\n // tick — confusing in apps and breaks tests that don't use Suspense.\n react: { useSuspense: false },\n });\n}\n\nexport function I18nProvider({\n defaultLocale,\n supportedLocales,\n resources,\n children,\n}: I18nProviderProps) {\n const [userLocale] = usePersistedState<string>('user-locale', defaultLocale);\n\n // Synchronous init on the first render (idempotent) so the initial paint\n // already has translations — no Suspense fallback, no flash of keys.\n ensureInitialized(defaultLocale, supportedLocales, resources, userLocale);\n\n useEffect(() => {\n if (i18n.isInitialized && i18n.language !== userLocale) {\n i18n.changeLanguage(userLocale);\n }\n }, [userLocale]);\n\n return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>;\n}\n","/**\n * Runtime gate for dev-only tools (e.g. <DevSkipOnboardingFab>).\n *\n * History:\n * v0.23.0 / v0.23.1 also gated on `import.meta.env.VITE_HOOK_DEV_TOOLS`.\n * That was intended as a build-time DCE signal so the dev module would\n * tree-shake out of prod bundles. Empirically vite's static replacement\n * does NOT apply to template code consumed from node_modules when the\n * creator app uses `build.lib` mode — every consumer ended up with\n * `undefined !== '1'` → DCE killed the FAB from STAGING bundles too.\n *\n * Pragmatic fix: drop the env gate and rely on the runtime hostname\n * check alone. The FAB code now ships in prod bundles too (~5 KB), but\n * it never renders on prod hostnames because `.staging.` / `localhost`\n * is the only path that returns `true`. Visual safety = hostname check\n * at render. Compliance / privacy = no real user can ever trigger the\n * auto-signup branch on a `usehook.net` (prod) origin.\n *\n * If a creator app wants the build-time DCE back, the consumer's\n * `vite.config.ts` `define` block must explicitly substitute\n * `import.meta.env.VITE_HOOK_DEV_TOOLS` — vite's auto-replacement skips\n * `node_modules` in lib mode.\n */\nexport function isDevToolsEnabled(): boolean {\n if (typeof window === 'undefined') return false;\n\n const host = window.location.hostname;\n // `staging.usehook.net` is the shell-served URL (apps live under\n // `/app/<slug>/`); `*.staging.usehook.net` covers any future per-app\n // staging subdomain. The substring match catches both. Earlier versions\n // only checked `.staging.` (dots on both sides) which missed the shell\n // root.\n return (\n host.includes('staging.usehook.net') ||\n host === 'localhost' ||\n host === '127.0.0.1'\n );\n}\n","/**\n * Staging-only \"skip onboarding\" floating button.\n *\n * Mounted by <AppRoot> when `isDevToolsEnabled()` is true AND the\n * `devSkipOnboarding` prop is passed. The whole module is intended to be\n * tree-shaken from prod bundles via the build-time env replacement in\n * `./env.ts` — never reference it from prod code paths.\n *\n * See `docs/superpowers/specs/2026-05-12-dev-skip-onboarding-fab-design.md`\n * (mirrored into `/Users/ryan/.claude/plans/for-all-of-the-replicated-planet.md`)\n * for the full design + safety gates.\n */\nimport { useCallback, useRef, useState } from 'react';\nimport { useHook, usePersistedState, type HookContextValue } from '@hook-sdk/sdk';\nimport { useAppConfig } from '../config/AppConfigContext';\n\nexport interface SkipDefaults {\n /**\n * Final flag the host app's ProtectedRoute reads. If unset here, the helper\n * forces it to `true` after merging defaults.\n */\n onboarding_completed?: boolean;\n /**\n * Free-form per-app fields (userName, mainGoal, faixa, kids[], etc.). The\n * helper merges this object verbatim into `appData.set('onboarding_data', …)`.\n */\n [field: string]: unknown;\n /**\n * Optional per-app seed callback. Use to insert anything that lives outside\n * `onboarding_data` (e.g. seed first workout in `hook.db.collection('workouts')`).\n * Awaited after `appData.set` and before the hard reload.\n */\n __seed?: (hook: HookContextValue) => Promise<void>;\n}\n\nconst STORAGE_KEY = 'hook_dev_skip_email';\nconst TEST_EMAIL_DOMAIN = '@hook.test';\nconst TEST_PASSWORD = 'SkipTest!2026';\n\nfunction makeEmail(): string {\n return `ryan+skip-${Date.now()}${TEST_EMAIL_DOMAIN}`;\n}\n\n/**\n * Try to sign up a fresh test user. Retries on 409 (email collision) by\n * rotating the timestamp suffix. Throws after `maxAttempts` retries.\n */\nasync function ensureSignedIn(hook: HookContextValue, maxAttempts = 3): Promise<string | null> {\n if (hook.authStatus === 'authenticated') return null;\n\n let lastErr: unknown;\n for (let i = 0; i < maxAttempts; i += 1) {\n const email = makeEmail();\n try {\n await hook.auth.signup({ email, password: TEST_PASSWORD, name: 'Ryan Test' });\n try {\n window.sessionStorage.setItem(STORAGE_KEY, email);\n } catch {\n // ignore — sessionStorage may be unavailable in some test envs\n }\n return email;\n } catch (err) {\n lastErr = err;\n // Slight jitter then retry; the next loop creates a new timestamp.\n await new Promise((r) => setTimeout(r, 30));\n }\n }\n throw lastErr ?? new Error('signup failed after retries');\n}\n\n/**\n * Programmatic skip helper. Exposed for advanced consumers / tests; the FAB\n * just calls this on confirm.\n */\nexport async function skipOnboarding(\n hook: HookContextValue,\n defaults: SkipDefaults,\n appSlug: string,\n): Promise<void> {\n const { __seed, ...rest } = defaults;\n await ensureSignedIn(hook);\n await hook.appData.set('onboarding_data', {\n ...rest,\n onboarding_completed: true,\n });\n if (__seed) {\n await __seed(hook);\n }\n // Dev-tool fire log. Stays out of PostHog allowlist so this module pulls\n // zero analytics-events surface (and remains tree-shake-friendly). If we\n // ever need a prod-tripwire telemetry signal, add `dev_skip_onboarding`\n // to `analytics-events.ts` ALLOWED_EVENTS and swap this for `hook.track`.\n // eslint-disable-next-line no-console\n console.info('[hook-template] dev_skip_onboarding fired', {\n app_slug: appSlug,\n hostname: window.location.hostname,\n });\n // Hard reload to the app's home so the post-auth providers re-mount with\n // fresh state. Router navigate is not enough — pre-auth providers may have\n // already captured an anonymous-flow snapshot.\n window.location.assign(`/app/${appSlug}/`);\n}\n\nconst STYLES = {\n base: {\n position: 'fixed',\n bottom: '16px',\n right: '16px',\n zIndex: 2147483647,\n padding: '10px 14px',\n borderRadius: '999px',\n border: 'none',\n background: '#F59E0B',\n color: '#111827',\n fontWeight: 600,\n fontSize: '13px',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n boxShadow: '0 4px 14px rgba(0, 0, 0, 0.25)',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n } as const,\n confirm: { background: '#DC2626', color: '#FFFFFF' } as const,\n busy: { opacity: 0.6, cursor: 'wait' } as const,\n};\n\ntype FabState = 'idle' | 'confirm' | 'busy' | 'error';\n\nconst CONFIRM_TIMEOUT_MS = 3000;\n\nexport function DevSkipOnboardingFab({ defaults }: { defaults: SkipDefaults }) {\n const hook = useHook();\n const { slug } = useAppConfig();\n const [state, setState] = useState<FabState>('idle');\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Reactively read onboarding state to hide the FAB once the user has crossed\n // onboarding. Pre-auth visitors keep seeing it (auto-signup branch handles\n // the rest of the skip). `enabled: false` pre-auth so we don't fire 401s on\n // the appData fetch.\n const isAuthed = hook.authStatus === 'authenticated';\n const [onboarding] = usePersistedState<{ onboarding_completed?: boolean } | null>(\n 'onboarding_data',\n null,\n { enabled: isAuthed },\n );\n const onboardingCompleted =\n isAuthed && onboarding?.onboarding_completed === true;\n\n const clearTimer = useCallback(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n\n const onClick = useCallback(async () => {\n if (state === 'busy') return;\n\n if (state === 'idle' || state === 'error') {\n setState('confirm');\n setErrorMsg(null);\n clearTimer();\n timerRef.current = setTimeout(() => setState('idle'), CONFIRM_TIMEOUT_MS);\n return;\n }\n\n // state === 'confirm' → execute\n clearTimer();\n setState('busy');\n try {\n await skipOnboarding(hook, defaults, slug);\n // window.location.assign navigates away; this line typically never runs.\n } catch (err) {\n setState('error');\n setErrorMsg(err instanceof Error ? err.message : String(err));\n }\n }, [state, hook, defaults, slug, clearTimer]);\n\n const label = (() => {\n if (state === 'busy') return 'skipping…';\n if (state === 'confirm') return 'tap again to confirm';\n if (state === 'error') return `failed — tap to retry`;\n return hook.authStatus === 'authenticated' ? '⚡ skip onboarding' : '⚡ skip + signup';\n })();\n\n // Hide once the user is past onboarding. By definition there's nothing\n // left to skip; keeping the FAB visible adds noise on every post-onboarding\n // screen.\n if (onboardingCompleted) return null;\n\n const style = {\n ...STYLES.base,\n ...(state === 'confirm' || state === 'error' ? STYLES.confirm : {}),\n ...(state === 'busy' ? STYLES.busy : {}),\n };\n\n return (\n <button\n type=\"button\"\n data-testid=\"dev-skip-onboarding-fab\"\n aria-label=\"Skip onboarding (staging dev only)\"\n style={style}\n onClick={onClick}\n title={errorMsg ?? undefined}\n >\n {label}\n </button>\n );\n}\n","import { useCallback, useEffect, useRef, useState, type CSSProperties, type ReactNode } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\n/**\n * Detecta `?paymentReturn=1` na URL (usuário voltando do checkout Asaas) e\n * polla `subscription.refresh()` com backoff exponencial (2s, 5s, 10s, 20s, 40s\n * — total ~77s) até status ∈ {active, trialing}.\n *\n * Regras de projeto (2026-04-21, pós-incidente QA papomaterno):\n *\n * - **Effect `[]`**: nunca `[subscription]`. O objeto `subscription` é\n * referencialmente memoizado pelo SDK mas re-memoiza a cada mudança de\n * `sub` (quando `/me` resolve). Re-dispara em cada render causava storm\n * exponencial (258→654 req em 20s observados em QA). Lemos a última\n * referência via `subRef.current` e rodamos o polling só 1× por mount.\n *\n * - **Backoff** em vez de 1s constante: evita martelar o backend quando\n * webhook atrasa e respeita o orçamento de ~77s total (cobre p99 observado\n * em staging). `http.ts` já respeita `Retry-After` em 429, mas backoff\n * reduz a chance de bater o rate limit em primeiro lugar.\n *\n * - **Aceita `trialing`** além de `active`: em `mode=pay_first` post-checkout\n * vira ACTIVE; em `mode=trial` o backend pode manter TRIAL com\n * trial_ends_at avançado. Ambos = libera o gate (`SubscriptionGate` trata\n * os dois como non-blocking).\n *\n * - **Timeout → estado `waiting` bloqueante com botão \"Atualizar\"**: se a\n * gente renderizasse children, o `SubscriptionGate` mostraria paywall de\n * novo (status=none sem subscription row) — user cliparia \"Pagar\" em\n * looping. Bloquear é menos ruim.\n *\n * - **Wave 5 #12 — escape após 3 retries**: cada ciclo (initial + 2 retries\n * via \"Atualizar\") esgota o backoff. Ao terminar o 3º ciclo sem\n * `active|trialing`, sai pro estado `timeout` com 3 botões:\n * • \"Tentar de novo\" → recomeça o polling.\n * • \"Voltar pro app\" → navega `/app/home` + remove `paymentReturn`.\n * • \"Falar com suporte\" → mailto. Evita user travado em looping de\n * \"Atualizar\" se o webhook não chegar nunca.\n *\n * Precisa estar dentro de <HookProvider> (fornecido pelo shell).\n * Exportado para teste isolado.\n */\nconst BACKOFF_MS = [2_000, 5_000, 10_000, 20_000, 40_000] as const; // ~77s total\nconst MAX_CYCLES = 3 as const;\nconst SUPPORT_MAILTO = 'mailto:suporte@usehook.net?subject=Pagamento%20pendente';\n\ntype ReturnState = 'idle' | 'confirming' | 'waiting' | 'timeout';\n\nexport function PaymentReturnHandler({ children }: { children: ReactNode }) {\n const { subscription, track } = useHook();\n const subRef = useRef(subscription);\n subRef.current = subscription;\n const runIdRef = useRef(0);\n const cyclesRef = useRef(0);\n const startMsRef = useRef(0);\n const [state, setState] = useState<ReturnState>('idle');\n\n const runPoll = useCallback(() => {\n const runId = ++runIdRef.current;\n // isFirstRun gates `payment_confirmation_started` to the first cycle of\n // a session (cyclesRef === 0). Cycles 2 and 3 — re-entries via the\n // \"Atualizar\" button after a backoff exhaust — do NOT re-fire `_started`.\n // After MAX_CYCLES exhausts and the user clicks \"Tentar de novo\",\n // cyclesRef is reset to 0 and `_started` fires again, by design: each\n // retry session is treated as a fresh confirmation attempt in PostHog.\n // `total_duration_ms` therefore measures the *current* session, not the\n // lifetime from the initial paymentReturn=1.\n const isFirstRun = cyclesRef.current === 0;\n cyclesRef.current += 1;\n if (isFirstRun) {\n startMsRef.current = Date.now();\n track('payment_confirmation_started', {});\n }\n setState('confirming');\n let attempts = 0;\n\n const tick = async () => {\n if (runIdRef.current !== runId) return;\n attempts++;\n try {\n await subRef.current.refresh();\n } catch {\n // swallow — http.ts já honra Retry-After em 429 e retry em 5xx.\n }\n if (runIdRef.current !== runId) return;\n const status = subRef.current.status();\n if (status === 'active' || status === 'trialing') {\n track('payment_confirmation_succeeded', {\n cycle_count: cyclesRef.current,\n attempt_count: attempts,\n duration_ms: Date.now() - startMsRef.current,\n });\n const cleanUrl = new URL(window.location.href);\n cleanUrl.searchParams.delete('paymentReturn');\n window.history.replaceState({}, '', cleanUrl.toString());\n cyclesRef.current = 0;\n setState('idle');\n return;\n }\n const delay = BACKOFF_MS[attempts - 1];\n if (delay === undefined) {\n if (cyclesRef.current >= MAX_CYCLES) {\n track('payment_confirmation_timed_out', {\n total_duration_ms: Date.now() - startMsRef.current,\n });\n setState('timeout');\n } else {\n setState('waiting');\n }\n return;\n }\n setTimeout(tick, delay);\n };\n void tick();\n }, [track]);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const url = new URL(window.location.href);\n if (url.searchParams.get('paymentReturn') !== '1') return;\n cyclesRef.current = 0;\n runPoll();\n return () => {\n // Invalida o run ativo — qualquer tick() pendente vai ver runId velho\n // e retornar sem tocar state. Cobre unmount e StrictMode double-invoke.\n runIdRef.current++;\n };\n }, [runPoll]);\n\n const goHome = useCallback(() => {\n const cleanUrl = new URL(window.location.href);\n cleanUrl.searchParams.delete('paymentReturn');\n cleanUrl.pathname = '/app/home';\n window.location.href = cleanUrl.toString();\n }, []);\n\n if (state === 'confirming') {\n return (\n <div role=\"status\" aria-live=\"polite\" style={overlayStyle}>\n Confirmando pagamento…\n </div>\n );\n }\n\n if (state === 'waiting') {\n return (\n <div role=\"status\" aria-live=\"polite\" style={overlayStyle}>\n <div style={{ maxWidth: 320, textAlign: 'center', lineHeight: 1.5 }}>\n <div style={{ marginBottom: 16 }}>\n Pagamento aceito. Estamos confirmando com o banco — pode levar\n alguns minutos.\n </div>\n <button type=\"button\" onClick={runPoll} style={buttonStyle}>\n Atualizar\n </button>\n </div>\n </div>\n );\n }\n\n if (state === 'timeout') {\n return (\n <div role=\"alert\" aria-live=\"assertive\" style={overlayStyle}>\n <div style={{ maxWidth: 360, textAlign: 'center', lineHeight: 1.5 }}>\n <div style={{ marginBottom: 16 }}>\n Ainda não conseguimos confirmar seu pagamento com o banco. Você\n pode tentar de novo, voltar pro app, ou falar com a gente.\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n <button\n type=\"button\"\n onClick={() => {\n cyclesRef.current = 0;\n runPoll();\n }}\n style={buttonStyle}\n data-testid=\"payment-timeout-retry\"\n >\n Tentar de novo\n </button>\n <button\n type=\"button\"\n onClick={goHome}\n style={secondaryButtonStyle}\n data-testid=\"payment-timeout-home\"\n >\n Voltar pro app\n </button>\n <a\n href={SUPPORT_MAILTO}\n style={linkStyle}\n data-testid=\"payment-timeout-support\"\n >\n Falar com suporte\n </a>\n </div>\n </div>\n </div>\n );\n }\n\n return <>{children}</>;\n}\n\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'rgba(0,0,0,0.4)',\n zIndex: 9999,\n color: 'white',\n fontSize: '1rem',\n padding: 24,\n};\n\nconst buttonStyle: CSSProperties = {\n background: 'white',\n color: 'black',\n border: 'none',\n borderRadius: 8,\n padding: '10px 24px',\n fontSize: '1rem',\n fontWeight: 600,\n cursor: 'pointer',\n};\n\nconst secondaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: 'transparent',\n color: 'white',\n border: '1px solid rgba(255,255,255,0.5)',\n};\n\nconst linkStyle: CSSProperties = {\n color: 'white',\n textDecoration: 'underline',\n fontSize: '0.9rem',\n marginTop: 4,\n textAlign: 'center',\n};\n","import { useCallback, useEffect, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport type PushUiState =\n | { kind: 'unsupported' }\n | { kind: 'ios_needs_install' }\n | { kind: 'prompt' }\n | { kind: 'subscribed' }\n | { kind: 'denied' }\n | { kind: 'dismissed' }\n | { kind: 'error'; code: string; message: string };\n\n// Audit Wave 3 — Fix #32. Dismiss persists 7 days via localStorage so the\n// prompt doesn't re-render every page load. Mirrors useInstallPrompt's\n// dismissPermanent pattern (per-device; push permission is per-device too).\nconst DISMISS_STORAGE_KEY = 'push:dismissed-until';\nconst DISMISS_TTL_MS = 7 * 24 * 60 * 60 * 1000;\n\nfunction detectIosNeedsInstall(): boolean {\n if (typeof navigator === 'undefined' || typeof window === 'undefined') return false;\n const ua = navigator.userAgent || '';\n const isIos = /iPhone|iPad|iPod/.test(ua);\n if (!isIos) return false;\n const mm = window.matchMedia?.('(display-mode: standalone)');\n const standalone = mm?.matches === true;\n // @ts-expect-error — legacy iOS property\n const legacyStandalone = typeof navigator.standalone === 'boolean' ? navigator.standalone : false;\n return !(standalone || legacyStandalone);\n}\n\nfunction readDismissedUntil(): number | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(DISMISS_STORAGE_KEY);\n if (raw === null) return null;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) ? n : null;\n } catch {\n return null;\n }\n}\n\nfunction isDismissedNow(): boolean {\n const until = readDismissedUntil();\n return until !== null && until > Date.now();\n}\n\nfunction deriveState(push: ReturnType<typeof useHook>['push']): PushUiState {\n if (!push.isAvailable()) {\n if (detectIosNeedsInstall()) return { kind: 'ios_needs_install' };\n return { kind: 'unsupported' };\n }\n const status = push.status();\n if (status === 'granted') return { kind: 'subscribed' };\n if (status === 'denied') return { kind: 'denied' };\n if (status === 'unsupported') {\n if (detectIosNeedsInstall()) return { kind: 'ios_needs_install' };\n return { kind: 'unsupported' };\n }\n // status === 'prompt' — gate by dismiss TTL so dismissed users don't see\n // the prompt re-render on every page load.\n if (isDismissedNow()) return { kind: 'dismissed' };\n return { kind: 'prompt' };\n}\n\nexport function usePush() {\n const { push } = useHook();\n const [state, setState] = useState<PushUiState>(() => deriveState(push));\n\n useEffect(() => { setState(deriveState(push)); }, [push]);\n\n const subscribe = useCallback(async () => {\n try {\n await push.subscribe();\n setState({ kind: 'subscribed' });\n } catch (e: any) {\n const code = e?.code ?? 'push.unknown';\n const message = e?.message ?? 'Push subscription failed';\n if (code === 'push.permission_denied') setState({ kind: 'denied' });\n else setState({ kind: 'error', code, message });\n throw e;\n }\n }, [push]);\n\n const unsubscribe = useCallback(async () => {\n try {\n await push.unsubscribe();\n setState({ kind: 'prompt' });\n } catch (e: any) {\n setState({ kind: 'error', code: e?.code ?? 'push.unknown', message: e?.message ?? 'failed' });\n throw e;\n }\n }, [push]);\n\n const dismiss = useCallback(() => {\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS));\n } catch {\n // localStorage quota exceeded or sandboxed iframe — best-effort.\n }\n }\n setState({ kind: 'dismissed' });\n }, []);\n\n return { state, subscribe, unsubscribe, dismiss };\n}\n","import { usePush } from '../hooks/usePush';\n\nexport interface PushPromptTexts {\n cta: string;\n declineCta: string;\n iosInstallTitle: string;\n iosInstallBody: string;\n iosInstallCta?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedTitle?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedBody?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedRecoveryIos?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedRecoveryAndroid?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedRecoveryDesktop?: string;\n /** @deprecated denied state no longer renders UI; field retained for back-compat. */\n deniedRecoveryInApp?: string;\n unsupportedBody: string;\n}\n\nexport interface PushPromptProps {\n texts: PushPromptTexts;\n onSubscribed?: () => void;\n onDeclined?: () => void;\n onInstallRequested?: () => void;\n className?: string;\n}\n\nexport function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequested, className }: PushPromptProps) {\n const { state, subscribe } = usePush();\n\n // Hook policy: never nag on `denied`. The browser-level block is sticky and\n // a banner cannot recover it — the user must flip permission via browser\n // settings. Rendering a persistent banner is noise. `dismissed`/`subscribed`\n // also no-render (Fix #32: dismiss honors a 7d TTL inside usePush).\n if (state.kind === 'denied' || state.kind === 'dismissed' || state.kind === 'subscribed') {\n return null;\n }\n\n if (state.kind === 'ios_needs_install') {\n return (\n <div className={className} role=\"region\" aria-label={texts.iosInstallTitle}>\n {onDeclined && (\n <button\n type=\"button\"\n onClick={onDeclined}\n aria-label=\"Fechar\"\n className=\"push-prompt-close\"\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n width: 32,\n height: 32,\n border: 'none',\n background: 'transparent',\n fontSize: 20,\n lineHeight: 1,\n cursor: 'pointer',\n color: 'inherit',\n }}\n >\n ×\n </button>\n )}\n <h3>{texts.iosInstallTitle}</h3>\n <p>{texts.iosInstallBody}</p>\n {onInstallRequested && texts.iosInstallCta && (\n <button onClick={onInstallRequested}>{texts.iosInstallCta}</button>\n )}\n </div>\n );\n }\n\n if (state.kind === 'unsupported') {\n return (\n <div className={className} role=\"region\">\n <p>{texts.unsupportedBody}</p>\n </div>\n );\n }\n\n if (state.kind === 'error') {\n return (\n <div className={className} role=\"region\" aria-label=\"error\">\n <p>{state.message}</p>\n </div>\n );\n }\n\n // kind === 'prompt'\n return (\n <div className={className} role=\"region\">\n <button\n type=\"button\"\n onClick={async () => {\n try {\n await subscribe();\n onSubscribed?.();\n } catch {\n // state is already set to 'denied' or 'error' by usePush.subscribe\n }\n }}\n >\n {texts.cta}\n </button>\n {onDeclined && (\n <button type=\"button\" onClick={onDeclined}>\n {texts.declineCta}\n </button>\n )}\n </div>\n );\n}\n","/**\n * LanguageSwitcher — controlled <select> bound to the persisted user locale.\n *\n * Reads `config.i18n.supportedLocales` from <AppConfigProvider>; renders\n * `null` when the app hasn't declared an i18n config (so accidental usage\n * doesn't crash). On change, writes via `usePersistedState('user-locale')`,\n * which the I18nProvider effect picks up to call `i18n.changeLanguage`.\n *\n * Visual: minimal default styling. Apps customize via `className` or by\n * composing their own switcher on top of `usePersistedState`.\n */\nimport { usePersistedState } from '@hook-sdk/sdk';\nimport { useAppConfig } from '../config/AppConfigContext';\n\nexport type LanguageSwitcherProps = {\n /** Optional id for label association. */\n id?: string;\n /** Optional CSS class for app styling. */\n className?: string;\n /** Optional label text; defaults to 'Language'. */\n label?: string;\n};\n\nexport function LanguageSwitcher({ id, className, label = 'Language' }: LanguageSwitcherProps) {\n const config = useAppConfig();\n const i18nConfig = config.i18n;\n // Hooks must run unconditionally; pass a stable fallback default and bail\n // on render if the app isn't configured for i18n.\n const [userLocale, setUserLocale] = usePersistedState<string>(\n 'user-locale',\n i18nConfig?.defaultLocale ?? 'en-US',\n );\n\n if (!i18nConfig) return null;\n\n return (\n <label className={className}>\n {label ? <span>{label}</span> : null}\n <select\n id={id}\n value={userLocale}\n onChange={(e) => setUserLocale(e.target.value)}\n data-testid=\"language-switcher\"\n >\n {i18nConfig.supportedLocales.map((loc) => (\n <option key={loc} value={loc}>\n {loc}\n </option>\n ))}\n </select>\n </label>\n );\n}\n","export function LoadingState({ message }: { message?: string }) {\n return (\n <div role=\"status\" aria-live=\"polite\" style={{ padding: 24, textAlign: 'center' }}>\n <span>{message ?? 'Carregando...'}</span>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function EmptyState({ title, description, action }: {\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div role=\"status\" style={{ padding: 32, textAlign: 'center' }}>\n <h2 style={{ marginBottom: 8 }}>{title}</h2>\n {description && <p style={{ opacity: 0.7 }}>{description}</p>}\n {action && <div style={{ marginTop: 16 }}>{action}</div>}\n </div>\n );\n}\n","/**\n * Plan-V — turnkey default CheckoutPage.\n *\n * Layout mirrors the Personalburn checkout reference (Camila design,\n * `Checkout PB/screens.jsx#ScreenPayment`). 3-field contact section\n * (email → name → cpf), horizontal method tabs with subtitle, method-aware\n * body block (card fields with MM/AA combined input, or PIX explainer card),\n * mini plan-summary card, fixed footer CTA with method-aware copy + icon.\n *\n * Apps either mount this directly or build a custom visual on top of\n * `useCheckoutForm`. Cycle (MONTHLY/YEARLY) and method come from\n * sessionStorage[\"hook:paywall:intent\"] written by the pre-checkout offer\n * panel; if absent, defaults match the reference (YEARLY + card).\n *\n * On submit:\n * - Card: cookies set by backend, redirect to result.redirect.\n * - Pix-auto: redirect to /paywall/pix-wait (page reads QR from session).\n *\n * 409 collision → emailTaken banner with link to /signin?email=…\n */\nimport { useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCheckoutForm, type CheckoutFormMethod, type CheckoutFormCycle } from '../hooks/useCheckoutForm';\nimport { usePlan } from '../hooks/usePlan';\nimport { useAppConfig } from '../config/AppConfigContext';\nimport { PaywallStickyFooter } from '../components/paywall';\n\nconst INTENT_KEY = 'hook:paywall:intent';\nconst PIX_PAYLOAD_KEY = 'hook:paywall:pix-pending';\n\ntype StoredIntent = {\n method?: CheckoutFormMethod;\n cycle?: CheckoutFormCycle;\n};\n\nfunction readIntent(): StoredIntent {\n if (typeof window === 'undefined') return {};\n try {\n const raw = sessionStorage.getItem(INTENT_KEY);\n if (!raw) return {};\n return JSON.parse(raw) as StoredIntent;\n } catch {\n return {};\n }\n}\n\nfunction formatBrl(cents: number): string {\n return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(cents / 100);\n}\n\nfunction formatCardNumber(v: string): string {\n const digits = v.replace(/\\D/g, '').slice(0, 16);\n return digits.replace(/(.{4})/g, '$1 ').trim();\n}\n\nfunction formatExpiryMmAa(v: string): string {\n const d = v.replace(/\\D/g, '').slice(0, 4);\n if (d.length < 3) return d;\n return d.slice(0, 2) + '/' + d.slice(2);\n}\n\nfunction parseExpiryMmAa(v: string): { month: string; year: string } {\n const d = v.replace(/\\D/g, '');\n return { month: d.slice(0, 2), year: d.slice(2, 4) };\n}\n\nfunction formatCpf(v: string): string {\n const d = v.replace(/\\D/g, '').slice(0, 11);\n if (d.length <= 3) return d;\n if (d.length <= 6) return d.slice(0, 3) + '.' + d.slice(3);\n if (d.length <= 9) return d.slice(0, 3) + '.' + d.slice(3, 6) + '.' + d.slice(6);\n return d.slice(0, 3) + '.' + d.slice(3, 6) + '.' + d.slice(6, 9) + '-' + d.slice(9);\n}\n\nfunction detectCardBrand(num: string): string {\n const n = num.replace(/\\s/g, '');\n if (/^4/.test(n)) return 'VISA';\n if (/^(5[1-5]|2[2-7])/.test(n)) return 'MASTER';\n if (/^3[47]/.test(n)) return 'AMEX';\n if (/^(4011|4312|4389|4514|6011|6362|6363)/.test(n)) return 'ELO';\n if (/^(606282|3841)/.test(n)) return 'HIPER';\n return '';\n}\n\nexport function CheckoutPageDefault() {\n const navigate = useNavigate();\n const plan = usePlan();\n const config = useAppConfig();\n const intent = useMemo(readIntent, []);\n const defaultMethod: CheckoutFormMethod =\n intent.method === 'pix-auto' ? 'pix-auto' : 'card';\n const defaultCycle: CheckoutFormCycle =\n intent.cycle === 'MONTHLY' ? 'MONTHLY' : 'YEARLY';\n\n const collectCep = config.paywall.mode !== 'free' && config.paywall.collectCep === true;\n const form = useCheckoutForm({ defaultMethod, defaultCycle, collectCep });\n\n // Combined MM/AA visual state. useCheckoutForm stores month + year\n // separately; this syncs them.\n const [expiryMmAa, setExpiryMmAa] = useState('');\n useEffect(() => {\n const { month, year } = parseExpiryMmAa(expiryMmAa);\n if (month !== form.card.expiryMonth || year !== form.card.expiryYear) {\n form.setCard({ expiryMonth: month, expiryYear: year });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expiryMmAa]);\n\n useEffect(() => {\n if (form.emailTaken && form.loginUrl) {\n const t = setTimeout(() => navigate(form.loginUrl!), 1200);\n return () => clearTimeout(t);\n }\n }, [form.emailTaken, form.loginUrl, navigate]);\n\n const planInfo = plan.data\n ? {\n priceCents: plan.data.priceCents,\n yearlyPriceCents: plan.data.yearlyPriceCents,\n trialDays: plan.data.trialDays,\n }\n : null;\n\n const annual = form.cycle === 'YEARLY';\n const cyclePrice = useMemo(() => {\n if (!planInfo) return null;\n return annual\n ? planInfo.yearlyPriceCents ?? planInfo.priceCents * 12\n : planInfo.priceCents;\n }, [planInfo, annual]);\n\n const monthlyText = useMemo(() => {\n if (!planInfo) return '';\n const monthly = annual && planInfo.yearlyPriceCents\n ? Math.round(planInfo.yearlyPriceCents / 12)\n : planInfo.priceCents;\n return formatBrl(monthly);\n }, [planInfo, annual]);\n\n const todayCents = useMemo(() => {\n if (form.method === 'pix-auto') return cyclePrice ?? 0;\n const trialDays = planInfo?.trialDays ?? 0;\n if (trialDays > 0) return 0;\n return cyclePrice ?? 0;\n }, [form.method, cyclePrice, planInfo]);\n\n const todayAmount = formatBrl(todayCents);\n const cyclePriceText = cyclePrice !== null ? formatBrl(cyclePrice) : '';\n\n const annualSavingsCents = useMemo(() => {\n if (!planInfo || !planInfo.yearlyPriceCents) return 0;\n return planInfo.priceCents * 12 - planInfo.yearlyPriceCents;\n }, [planInfo]);\n\n const trialDays = planInfo?.trialDays ?? 7;\n const cardBrand = detectCardBrand(form.card.number);\n\n async function onSubmit(e: React.FormEvent) {\n e.preventDefault();\n const result = await form.submit();\n if (!result) return;\n if (form.method === 'pix-auto' && result.pix_qr_payload) {\n try {\n sessionStorage.setItem(\n PIX_PAYLOAD_KEY,\n JSON.stringify({\n payload: result.pix_qr_payload,\n base64: result.pix_qr_base64 ?? null,\n subscriptionId: result.subscription_id,\n pixAuthorizationId: result.pix_authorization_id ?? null,\n }),\n );\n } catch { /* ignore quota errors */ }\n navigate(result.redirect.replace(/^.*\\/app\\/[^/]+/, ''));\n return;\n }\n // Card-path success: navega pra /paywall/pronta (tela \"Pronta\" + email\n // de boas-vindas com magic-link + senha). Cada app monta Route /paywall/pronta\n // → PaywallProntaPreAuth wrapper que renderiza PaywallStepPronta dentro de\n // <PaywallProvider>. CTA \"Vamos lá\" → /app/home (postAuthLanding).\n navigate('/paywall/pronta');\n }\n\n return (\n <div className=\"flex-1 flex flex-col bg-background min-h-0\">\n <form onSubmit={onSubmit} className=\"flex-1 flex flex-col min-h-0\">\n {/*\n Vertical rhythm system — keep edits on this scale, do not add ad-hoc\n one-off margins/paddings:\n section gap 24px (space-y-6 on this scroll body)\n intra-section 16px (space-y-4 — field↔field, tabs↔body)\n label → input 8px (FieldLabel mb-2)\n input → hint 6px (FieldHint / error mt-1.5)\n heading → content 16px (h2 mb-4)\n card padding 16px (p-4)\n */}\n <div className=\"flex-1 overflow-y-auto px-5 pt-5 pb-6 space-y-6\">\n {form.emailTaken ? (\n <div role=\"alert\" className=\"rounded-2xl bg-destructive/10 p-4 text-sm text-destructive border border-destructive/20\">\n Esse e-mail já tem conta nesse app.{' '}\n <a href={form.loginUrl ?? '/signin'} className=\"underline font-semibold\">\n Entrar agora\n </a>\n </div>\n ) : null}\n\n {form.error ? (\n <div role=\"alert\" className=\"rounded-2xl bg-destructive/10 p-4 text-sm text-destructive border border-destructive/20\">\n {form.error.message || 'Não foi possível concluir o pagamento. Tente novamente.'}\n </div>\n ) : null}\n\n {/* Reassurance banner — switches by method */}\n {form.method === 'card' ? (\n <div className=\"rounded-2xl bg-card border-[1.5px] border-foreground p-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <ShieldIcon className=\"w-4 h-4\" />\n <div className=\"text-sm font-bold\">Você NÃO será cobrada hoje</div>\n </div>\n <div className=\"flex justify-between items-baseline text-sm text-muted-foreground\">\n <span>R$ 0,00 agora</span>\n <span className=\"opacity-50\">·</span>\n <span>{monthlyText}/mês após {trialDays} dias</span>\n </div>\n <div className=\"mt-2.5 text-[11px] text-muted-foreground flex items-center gap-1.5\">\n <BellIcon className=\"w-2.5 h-2.5\" />\n Avisamos por email 2 dias antes da primeira cobrança\n </div>\n </div>\n ) : (\n <div className=\"rounded-2xl p-4 bg-emerald-50 border-[1.5px] border-emerald-600/60\">\n <div className=\"flex items-center gap-2 mb-2 text-emerald-900\">\n <ShieldIcon className=\"w-4 h-4\" />\n <div className=\"text-sm font-bold\">Garantia incondicional de {trialDays} dias</div>\n </div>\n <div className=\"text-sm text-emerald-900 leading-snug\">\n Você paga hoje via Pix.<br />\n Não gostou em {trialDays} dias? Devolvemos <b>100%</b> sem perguntas — direto pelo app.\n </div>\n </div>\n )}\n\n {/* Contact: email → name → cpf */}\n <section>\n <h2 className=\"font-display text-2xl mb-4 leading-tight text-foreground\">Quase lá.</h2>\n\n <div className=\"space-y-4\">\n <div>\n <FieldLabel>Email</FieldLabel>\n <FieldInput\n type=\"email\"\n inputMode=\"email\"\n autoComplete=\"email\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck={false}\n placeholder=\"seu@email.com\"\n value={form.email}\n onChange={form.setEmail}\n onBlur={form.markEmailTouched}\n error={form.emailError}\n valid={form.emailStatus === 'available'}\n />\n {!form.emailError && (\n <FieldHint>\n {form.emailStatus === 'checking' ? 'Verificando…' :\n form.emailStatus === 'available' ? '✓ Disponível' :\n 'Você vai usar este email para entrar no app'}\n </FieldHint>\n )}\n </div>\n\n <div>\n <FieldLabel>Nome completo</FieldLabel>\n <FieldInput\n type=\"text\"\n autoComplete=\"name\"\n placeholder=\"como está no documento\"\n value={form.name}\n onChange={form.setName}\n onBlur={form.markNameTouched}\n error={form.nameError}\n valid={!!form.name && !form.nameError}\n />\n </div>\n\n <div>\n <FieldLabel>CPF</FieldLabel>\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"000.000.000-00\"\n value={form.cpf}\n onChange={(v) => form.setCpf(formatCpf(v))}\n onBlur={form.markCpfTouched}\n error={form.cpfError}\n valid={!!form.cpf && !form.cpfError}\n />\n </div>\n\n {/* Phone is REQUIRED by Asaas tokenizeCreditCard.creditCardHolderInfo\n when method=card; the API rejects empty phone with 400\n `invalid_holderInfo`. PIX path skips card tokenization so phone\n is optional there. Render only when card so the form stays at\n 3 fields (matches the Personalburn reference mockup) for PIX. */}\n {form.method === 'card' ? (\n <div>\n <FieldLabel>Telefone</FieldLabel>\n <FieldInput\n type=\"tel\"\n inputMode=\"tel\"\n autoComplete=\"tel\"\n placeholder=\"(11) 99999-9999\"\n value={form.phone}\n onChange={form.setPhone}\n onBlur={form.markPhoneTouched}\n error={form.phoneError}\n valid={!!form.phone && !form.phoneError}\n />\n {!form.phoneError && (\n <FieldHint>\n Usado pra confirmar pagamento e tratar disputas.\n </FieldHint>\n )}\n </div>\n ) : null}\n\n {/* CEP + número — só card-path + quando paywall.collectCep=true.\n Asaas valida postalCode contra Receita/Correios pra antifraude\n e NF-e (se ativada na subaccount). Sem isso, ship placeholder. */}\n {collectCep && form.method === 'card' ? (\n <>\n <div>\n <FieldLabel>CEP</FieldLabel>\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"postal-code\"\n placeholder=\"00000-000\"\n value={form.postalCode}\n onChange={(v) => {\n const digits = v.replace(/\\D/g, '').slice(0, 8);\n const formatted = digits.length > 5\n ? `${digits.slice(0, 5)}-${digits.slice(5)}`\n : digits;\n form.setPostalCode(formatted);\n }}\n onBlur={form.markPostalCodeTouched}\n error={form.postalCodeError}\n valid={!!form.postalCode && !form.postalCodeError}\n />\n </div>\n <div>\n <FieldLabel>Número</FieldLabel>\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"100\"\n value={form.addressNumber}\n onChange={form.setAddressNumber}\n onBlur={form.markAddressNumberTouched}\n error={form.addressNumberError}\n valid={!!form.addressNumber && !form.addressNumberError}\n />\n </div>\n </>\n ) : null}\n </div>\n </section>\n\n {/* Payment: method tabs + method-conditional body, one section so the\n tabs and their fields share a 16px intra-section rhythm. */}\n <section className=\"space-y-4\">\n <div>\n <FieldLabel>Forma de pagamento</FieldLabel>\n <div role=\"tablist\" className=\"flex gap-1.5 bg-muted p-1 rounded-xl\">\n <TabButton\n active={form.method === 'card'}\n onClick={() => form.setMethod('card')}\n icon={<CardIcon className=\"w-3.5 h-3.5\" />}\n label=\"Cartão\"\n subtitle={trialDays > 0 ? `${trialDays} dias grátis` : 'pague hoje'}\n subtitleActiveClass=\"text-emerald-700\"\n />\n <TabButton\n active={form.method === 'pix-auto'}\n onClick={() => form.setMethod('pix-auto')}\n icon={<PixIcon className=\"w-3.5 h-3.5\" />}\n label=\"Pix\"\n subtitle={`pague hoje · garantia ${trialDays}d`}\n subtitleActiveClass=\"text-foreground/70\"\n />\n </div>\n </div>\n\n {form.method === 'card' ? (\n <div className=\"space-y-4\">\n <div>\n <FieldLabel>Número do cartão</FieldLabel>\n <div className=\"relative\">\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-number\"\n placeholder=\"0000 0000 0000 0000\"\n value={form.card.number}\n onChange={(v) => form.setCard({ number: formatCardNumber(v) })}\n style={cardBrand ? { paddingRight: '4.5rem' } : undefined}\n />\n {cardBrand && (\n <span className=\"absolute right-3 top-1/2 -translate-y-1/2 text-[10px] font-bold tracking-wide px-1.5 py-0.5 rounded bg-muted text-muted-foreground\">\n {cardBrand}\n </span>\n )}\n </div>\n </div>\n\n <div className=\"flex gap-3\">\n <div className=\"flex-1\">\n <FieldLabel>Validade</FieldLabel>\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-exp\"\n placeholder=\"MM/AA\"\n value={expiryMmAa}\n onChange={(v) => setExpiryMmAa(formatExpiryMmAa(v))}\n />\n </div>\n <div className=\"flex-1\">\n <FieldLabel>CVV</FieldLabel>\n <FieldInput\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-csc\"\n placeholder=\"3 dígitos\"\n value={form.card.ccv}\n onChange={(v) => form.setCard({ ccv: v.replace(/\\D/g, '').slice(0, 4) })}\n />\n </div>\n </div>\n\n <div>\n <FieldLabel>Nome no cartão</FieldLabel>\n <FieldInput\n type=\"text\"\n autoComplete=\"cc-name\"\n placeholder=\"como está no cartão\"\n value={form.card.holderName}\n onChange={(v) => form.setCard({ holderName: v })}\n />\n </div>\n </div>\n ) : (\n <div className=\"rounded-2xl bg-card border border-border p-4 flex gap-3.5 items-center\">\n <div className=\"w-[72px] h-[72px] rounded-xl shrink-0 border-2 border-foreground relative overflow-hidden bg-muted\">\n <div className=\"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[22px] h-[22px] bg-background flex items-center justify-center\">\n <PixIcon className=\"w-3.5 h-3.5 text-foreground\" />\n </div>\n </div>\n <div className=\"flex-1\">\n <div className=\"text-xs font-bold uppercase tracking-wider text-muted-foreground\">\n pagamento em segundos\n </div>\n <div className=\"text-sm text-foreground mt-1 leading-snug\">\n Geramos seu <b>QR Pix</b> no próximo passo. Pague pelo app do banco e seu acesso libera <b>imediatamente</b>.\n </div>\n </div>\n </div>\n )}\n </section>\n\n {/* Plan summary card */}\n <section>\n <div className=\"bg-muted rounded-2xl p-4\">\n <div className=\"flex justify-between gap-3\">\n <div>\n <div className=\"text-sm font-semibold text-foreground\">\n {annual ? 'Plano Anual' : 'Plano Mensal'}\n </div>\n <div className=\"text-[11px] text-muted-foreground\">Coach</div>\n </div>\n <div className=\"text-right\">\n {/* For pix-auto the cycle price equals the today amount shown\n below, so showing it here too reads as a duplicated value.\n Card method keeps it — there it differs from \"today\" (R$0). */}\n {form.method !== 'pix-auto' && (\n <div className=\"text-sm font-bold text-foreground\">\n {cyclePriceText}/{annual ? 'ano' : 'mês'}\n </div>\n )}\n {annual && annualSavingsCents > 0 && (\n <div className=\"text-[11px] text-emerald-700 font-semibold\">\n economia {formatBrl(annualSavingsCents)}\n </div>\n )}\n </div>\n </div>\n <div className=\"h-px bg-border my-3\" />\n <div className=\"flex justify-between items-baseline gap-3\">\n <div className=\"text-sm font-bold text-foreground\">Você paga hoje</div>\n <div className=\"text-2xl font-bold font-display tracking-tight text-foreground\">\n {todayAmount}\n </div>\n </div>\n {/* Sub-note on its own full-width line — competing for width with\n the R$ amount above squeezed it into an ugly 2-line wrap. */}\n {form.method === 'card' && trialDays > 0 && (\n <div className=\"mt-1.5 text-[11px] text-muted-foreground\">\n cobrança inicia no dia {trialDays}\n </div>\n )}\n {form.method === 'pix-auto' && (\n <div className=\"mt-1.5 text-[11px] text-emerald-700 font-semibold\">\n reembolso garantido até o dia {trialDays}\n </div>\n )}\n </div>\n </section>\n\n </div>\n\n {/* Fixed CTA footer — sibling of the scroll body so it never overlaps\n the form content. (Old `sticky bottom-0` lived INSIDE the scroll\n container and floated over the card fields / plan summary.) */}\n <PaywallStickyFooter className=\"px-5 pt-5 pb-6 border-t border-border\">\n <button\n type=\"submit\"\n disabled={!form.canSubmit}\n className=\"w-full rounded-full bg-primary text-primary-foreground h-14 px-5 text-base font-bold inline-flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed shadow-lg\"\n >\n {form.submitting ? (\n <>\n <Spinner /> {form.method === 'pix-auto' ? 'Gerando QR…' : 'Confirmando…'}\n </>\n ) : form.method === 'card' ? (\n <>\n <LockIcon className=\"w-3.5 h-3.5\" /> Confirmar e começar grátis\n </>\n ) : (\n <>\n <PixIcon className=\"w-3.5 h-3.5\" /> Gerar QR Pix\n </>\n )}\n </button>\n <div className=\"text-center mt-3 text-xs text-muted-foreground\">\n Ao continuar, você concorda com nossos <u>Termos</u>. Pagamento seguro Asaas.\n </div>\n <div className=\"mt-3 flex items-center justify-center gap-4 text-[11px] text-muted-foreground\">\n <span className=\"inline-flex items-center gap-1\">\n <LockIcon className=\"w-2.5 h-2.5 opacity-60\" /> SSL 256-bit\n </span>\n <span className=\"w-px h-2.5 bg-border\" />\n <span>Pagamento via Asaas</span>\n <span className=\"w-px h-2.5 bg-border\" />\n <span>Garantia {trialDays} dias</span>\n </div>\n </PaywallStickyFooter>\n </form>\n </div>\n );\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Internals\n// ───────────────────────────────────────────────────────────────────────\n\nfunction FieldLabel({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2\">\n {children}\n </div>\n );\n}\n\ninterface FieldInputProps {\n value: string;\n onChange: (v: string) => void;\n onBlur?: () => void;\n type?: string;\n inputMode?: 'text' | 'numeric' | 'tel' | 'email';\n autoComplete?: string;\n autoCapitalize?: string;\n autoCorrect?: string;\n spellCheck?: boolean;\n placeholder?: string;\n error?: string | null;\n valid?: boolean;\n style?: React.CSSProperties;\n}\n\nfunction FieldInput(props: FieldInputProps) {\n const baseClass = 'w-full px-4 rounded-xl bg-card text-base text-foreground outline-none border-[1.5px] transition-colors';\n const stateClass = props.error\n ? 'border-destructive focus:border-destructive'\n : props.valid\n ? 'border-emerald-600 focus:border-emerald-700'\n : 'border-border focus:border-foreground';\n return (\n <>\n <input\n type={props.type ?? 'text'}\n inputMode={props.inputMode}\n autoComplete={props.autoComplete}\n autoCapitalize={props.autoCapitalize}\n autoCorrect={props.autoCorrect}\n spellCheck={props.spellCheck}\n placeholder={props.placeholder}\n value={props.value}\n onChange={(e) => props.onChange(e.target.value)}\n onBlur={props.onBlur}\n style={{ height: '52px', ...props.style }}\n className={`${baseClass} ${stateClass}`}\n />\n {props.error ? (\n <div className=\"mt-1.5 text-xs text-destructive font-medium\">{props.error}</div>\n ) : null}\n </>\n );\n}\n\nfunction FieldHint({ children }: { children: React.ReactNode }) {\n return <div className=\"mt-1.5 text-xs text-muted-foreground\">{children}</div>;\n}\n\ninterface TabButtonProps {\n active: boolean;\n onClick: () => void;\n icon: React.ReactNode;\n label: string;\n subtitle: string;\n subtitleActiveClass: string;\n}\n\nfunction TabButton({ active, onClick, icon, label, subtitle, subtitleActiveClass }: TabButtonProps) {\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={onClick}\n className={`flex-1 flex flex-col items-center justify-center gap-0.5 py-2.5 px-1.5 rounded-lg text-sm font-semibold transition-colors ${\n active\n ? 'bg-card text-foreground shadow-sm'\n : 'bg-transparent text-muted-foreground'\n }`}\n style={{ minHeight: 56 }}\n >\n <span className=\"inline-flex items-center gap-1.5\">\n {icon} {label}\n </span>\n <span className={`text-[10px] font-medium ${active ? subtitleActiveClass : 'text-muted-foreground/70'}`}>\n {subtitle}\n </span>\n </button>\n );\n}\n\nfunction CardIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"2.5\" y=\"5.5\" width=\"19\" height=\"13\" rx=\"2.5\" />\n <path d=\"M2.5 10h19\" />\n </svg>\n );\n}\n\nfunction PixIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12 2L2 12l10 10 10-10L12 2zm0 4.83L17.17 12 12 17.17 6.83 12 12 6.83z\" />\n </svg>\n );\n}\n\nfunction LockIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"4\" y=\"10\" width=\"16\" height=\"11\" rx=\"2.5\" />\n <path d=\"M7.5 10V7a4.5 4.5 0 119 0v3\" />\n </svg>\n );\n}\n\nfunction ShieldIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M12 2.5l8 3v6c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10v-6l8-3z\" />\n <path d=\"M9 12l2 2 4-4\" />\n </svg>\n );\n}\n\nfunction BellIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M6 17V11a6 6 0 1112 0v6l1.5 2H4.5L6 17z\" />\n <path d=\"M10 21a2 2 0 004 0\" />\n </svg>\n );\n}\n\nfunction Spinner() {\n return (\n <span\n className=\"w-4 h-4 rounded-full border-2 border-white/40 border-t-white\"\n style={{ animation: 'spin 0.7s linear infinite' }}\n />\n );\n}\n","/**\n * Plan-V — headless hook for the pay-first CheckoutPage.\n *\n * Apps compose the visual layer; this hook owns: field state, validation,\n * email-existence debounced check, submit (card / pix-auto) via SDK\n * `auth.subscribeAnonymous`, and `EmailTakenError` translation.\n *\n * See docs/superpowers/specs/2026-05-13-pay-first-signup-design.md §\"Template\".\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useHook,\n EmailTakenError,\n type SubscribeAnonymousArgs,\n type SubscribeAnonymousResult,\n} from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst PHONE_RE = /^[0-9()+\\-\\s]{8,20}$/;\nconst CHECK_DEBOUNCE_MS = 400;\n\nexport type CheckoutFormCycle = 'MONTHLY' | 'YEARLY';\nexport type CheckoutFormMethod = 'card' | 'pix-auto';\n\nexport interface CheckoutCardInput {\n number: string;\n expiryMonth: string;\n expiryYear: string;\n ccv: string;\n holderName: string;\n}\n\nexport interface UseCheckoutFormResult {\n // Field state — controlled values + setters.\n name: string;\n setName: (v: string) => void;\n email: string;\n setEmail: (v: string) => void;\n emailConfirm: string;\n setEmailConfirm: (v: string) => void;\n phone: string;\n setPhone: (v: string) => void;\n cpf: string;\n setCpf: (v: string) => void;\n postalCode: string;\n setPostalCode: (v: string) => void;\n addressNumber: string;\n setAddressNumber: (v: string) => void;\n\n // Method + cycle selection.\n method: CheckoutFormMethod;\n setMethod: (m: CheckoutFormMethod) => void;\n cycle: CheckoutFormCycle;\n setCycle: (c: CheckoutFormCycle) => void;\n\n // Card-specific fields (only relevant when method === 'card').\n card: CheckoutCardInput;\n setCard: (patch: Partial<CheckoutCardInput>) => void;\n\n // Per-field errors (null until touched OR after first submit attempt).\n nameError: string | null;\n emailError: string | null;\n emailConfirmError: string | null;\n phoneError: string | null;\n cpfError: string | null;\n postalCodeError: string | null;\n addressNumberError: string | null;\n markNameTouched: () => void;\n markEmailTouched: () => void;\n markEmailConfirmTouched: () => void;\n markPhoneTouched: () => void;\n markCpfTouched: () => void;\n markPostalCodeTouched: () => void;\n markAddressNumberTouched: () => void;\n\n /**\n * Result of the debounced server-side email-exists check, used to swap\n * the CTA into \"Email já cadastrado · Entrar\" on the checkout form.\n */\n emailStatus: 'idle' | 'checking' | 'exists' | 'available';\n\n /**\n * Submit the form. Calls `auth.subscribeAnonymous`. Returns the result on\n * success, null on validation failure, or throws on payment failure (caller\n * should display a banner). EmailTakenError is caught + translated into\n * `emailStatus='exists'` + `emailTaken=true` so the caller can redirect.\n */\n submit: () => Promise<SubscribeAnonymousResult | null>;\n submitting: boolean;\n canSubmit: boolean;\n formSubmitAttempted: boolean;\n error: AuthFormError | null;\n\n /** True after a 409 collision; caller redirects to /login?email=… */\n emailTaken: boolean;\n loginUrl: string | null;\n}\n\nexport interface UseCheckoutFormArgs {\n defaultMethod: CheckoutFormMethod;\n defaultCycle: CheckoutFormCycle;\n /**\n * Quando true, o submit envia postalCode + addressNumber reais coletados\n * via setPostalCode/setAddressNumber. Quando false (default), envia\n * placeholder `01001000`/`100`. CheckoutPageDefault liga via config\n * `paywall.collectCep`.\n */\n collectCep?: boolean;\n}\n\nexport function useCheckoutForm(hookArgs: UseCheckoutFormArgs): UseCheckoutFormResult {\n const { auth } = useHook();\n\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [emailConfirm, setEmailConfirm] = useState('');\n const [phone, setPhone] = useState('');\n const [cpf, setCpf] = useState('');\n const [postalCode, setPostalCode] = useState('');\n const [addressNumber, setAddressNumber] = useState('');\n\n const [method, setMethod] = useState<CheckoutFormMethod>(hookArgs.defaultMethod);\n const [cycle, setCycle] = useState<CheckoutFormCycle>(hookArgs.defaultCycle);\n\n const [card, setCardState] = useState<CheckoutCardInput>({\n number: '',\n expiryMonth: '',\n expiryYear: '',\n ccv: '',\n holderName: '',\n });\n const setCard = useCallback((patch: Partial<CheckoutCardInput>) => {\n setCardState((prev) => ({ ...prev, ...patch }));\n }, []);\n\n const [touchedName, setTouchedName] = useState(false);\n const [touchedEmail, setTouchedEmail] = useState(false);\n const [touchedEmailConfirm, setTouchedEmailConfirm] = useState(false);\n const [touchedPhone, setTouchedPhone] = useState(false);\n const [touchedCpf, setTouchedCpf] = useState(false);\n const [touchedPostalCode, setTouchedPostalCode] = useState(false);\n const [touchedAddressNumber, setTouchedAddressNumber] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n const [emailTaken, setEmailTaken] = useState(false);\n const [loginUrl, setLoginUrl] = useState<string | null>(null);\n\n const [emailStatus, setEmailStatus] = useState<UseCheckoutFormResult['emailStatus']>('idle');\n const lastCheckedEmail = useRef<string>('');\n\n // Debounced email-exists check.\n useEffect(() => {\n if (!email || !EMAIL_RE.test(email)) {\n setEmailStatus('idle');\n return;\n }\n if (email === lastCheckedEmail.current) return;\n const timer = setTimeout(async () => {\n setEmailStatus('checking');\n try {\n const result = await auth.checkEmailExists({ email });\n lastCheckedEmail.current = email;\n setEmailStatus(result.exists ? 'exists' : 'available');\n } catch {\n // Network error — be permissive (don't block submit on lookup\n // failure; server-side INSERT will still catch a collision).\n setEmailStatus('idle');\n }\n }, CHECK_DEBOUNCE_MS);\n return () => clearTimeout(timer);\n }, [email, auth]);\n\n // Validation.\n const validateName = useMemo(() => {\n if (name.length === 0) return null;\n if (name.trim().length < 2) return 'Nome muito curto.';\n return null;\n }, [name]);\n const validateEmail = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n const validateEmailConfirm = useMemo(() => {\n if (emailConfirm.length === 0) return null;\n if (emailConfirm !== email) return 'Os e-mails não coincidem.';\n return null;\n }, [emailConfirm, email]);\n const validatePhone = useMemo(() => {\n if (phone.length === 0) return null;\n if (!PHONE_RE.test(phone)) return 'Telefone inválido.';\n return null;\n }, [phone]);\n const validateCpf = useMemo(() => {\n if (cpf.length === 0) return null;\n const digits = cpf.replace(/\\D/g, '');\n if (digits.length !== 11) return 'CPF deve ter 11 dígitos.';\n if (/^(\\d)\\1+$/.test(digits)) return 'CPF inválido.';\n // Mod-11 check.\n const ok = mod11(digits, 9) === digits[9] && mod11(digits, 10) === digits[10];\n return ok ? null : 'CPF inválido.';\n }, [cpf]);\n\n // CEP + addressNumber só importam quando hookArgs.collectCep && card path.\n const validatePostalCode = useMemo(() => {\n if (!hookArgs.collectCep) return null;\n if (postalCode.length === 0) return null;\n const digits = postalCode.replace(/\\D/g, '');\n if (digits.length !== 8) return 'CEP deve ter 8 dígitos.';\n return null;\n }, [hookArgs.collectCep, postalCode]);\n const validateAddressNumber = useMemo(() => {\n if (!hookArgs.collectCep) return null;\n if (addressNumber.length === 0) return null;\n if (addressNumber.trim().length === 0) return 'Número obrigatório.';\n return null;\n }, [hookArgs.collectCep, addressNumber]);\n\n const nameError = (touchedName || formSubmitAttempted) ? validateName : null;\n const emailError = (touchedEmail || formSubmitAttempted) ? validateEmail : null;\n const emailConfirmError = (touchedEmailConfirm || formSubmitAttempted) ? validateEmailConfirm : null;\n const phoneError = (touchedPhone || formSubmitAttempted) ? validatePhone : null;\n const cpfError = (touchedCpf || formSubmitAttempted) ? validateCpf : null;\n const postalCodeError = (touchedPostalCode || formSubmitAttempted) ? validatePostalCode : null;\n const addressNumberError = (touchedAddressNumber || formSubmitAttempted) ? validateAddressNumber : null;\n\n // Plan-V 0.28.x — emailConfirm + phone field rules:\n // * `emailConfirm`: optional. When the app's UI drops the second-email\n // input, auto-fill to `email` at submit time (typo guard becomes a\n // no-op).\n // * `phone`: REQUIRED when method === 'card'. Asaas's\n // `tokenizeCreditCard.creditCardHolderInfo.phone` rejects empty with\n // HTTP 400 `invalid_holderInfo`; gate the submit button here so we\n // never round-trip to Asaas with an empty value. PIX skips card\n // tokenization so phone stays optional on that path.\n const phoneOk = method === 'pix-auto'\n ? (phone === '' || PHONE_RE.test(phone))\n : PHONE_RE.test(phone);\n // CEP gate só pra card-path + quando collectCep ligado.\n const cepGateOk =\n !hookArgs.collectCep ||\n method !== 'card' ||\n (postalCode.replace(/\\D/g, '').length === 8 && addressNumber.trim().length > 0);\n\n const canSubmit =\n name.trim().length >= 2 &&\n EMAIL_RE.test(email) &&\n (emailConfirm === '' || emailConfirm === email) &&\n phoneOk &&\n validateCpf === null &&\n cpf.replace(/\\D/g, '').length === 11 &&\n emailStatus !== 'exists' &&\n !submitting &&\n cepGateOk &&\n (method !== 'card' || (\n card.number.length >= 12 &&\n card.ccv.length >= 3 &&\n card.expiryMonth.length >= 1 &&\n card.expiryYear.length >= 2 &&\n card.holderName.length >= 1\n ));\n\n const submit = useCallback(async (): Promise<SubscribeAnonymousResult | null> => {\n setFormSubmitAttempted(true);\n setError(null);\n setEmailTaken(false);\n setLoginUrl(null);\n if (!canSubmit) return null;\n setSubmitting(true);\n\n try {\n let args: SubscribeAnonymousArgs;\n if (method === 'card') {\n args = {\n method: 'card',\n name: name.trim(),\n email,\n emailConfirm: emailConfirm || email,\n phone,\n cpf: cpf.replace(/\\D/g, ''),\n cycle,\n card: {\n number: card.number.replace(/\\s/g, ''),\n expiryMonth: card.expiryMonth,\n expiryYear: card.expiryYear,\n ccv: card.ccv,\n holderName: card.holderName,\n },\n cardHolderInfo: {\n name: card.holderName || name.trim(),\n email,\n cpfCnpj: cpf.replace(/\\D/g, ''),\n // collectCep=true → CEP/número reais do form. Senão placeholder\n // válido (Asaas rejeita all-zeros, então shipping 01001000/100\n // que são válidos mas anonimizam). Apps com NF-e ou antifraude\n // refinada devem setar paywall.collectCep no app.config.json.\n postalCode: hookArgs.collectCep\n ? postalCode.replace(/\\D/g, '')\n : '01001000',\n addressNumber: hookArgs.collectCep\n ? addressNumber.trim()\n : '100',\n phone,\n },\n };\n } else {\n args = {\n method: 'pix-auto',\n name: name.trim(),\n email,\n emailConfirm: emailConfirm || email,\n phone,\n cpf: cpf.replace(/\\D/g, ''),\n cycle,\n };\n }\n const result = await auth.subscribeAnonymous(args);\n return result;\n } catch (err) {\n if (err instanceof EmailTakenError) {\n setEmailTaken(true);\n setLoginUrl(err.loginUrl);\n setEmailStatus('exists');\n return null;\n }\n setError(mapSdkError(err));\n return null;\n } finally {\n setSubmitting(false);\n }\n }, [auth, canSubmit, method, cycle, name, email, emailConfirm, phone, cpf, card]);\n\n return {\n name, setName,\n email, setEmail,\n emailConfirm, setEmailConfirm,\n phone, setPhone,\n cpf, setCpf,\n postalCode, setPostalCode,\n addressNumber, setAddressNumber,\n method, setMethod,\n cycle, setCycle,\n card, setCard,\n\n nameError, emailError, emailConfirmError, phoneError, cpfError,\n postalCodeError, addressNumberError,\n markNameTouched: () => setTouchedName(true),\n markEmailTouched: () => setTouchedEmail(true),\n markEmailConfirmTouched: () => setTouchedEmailConfirm(true),\n markPhoneTouched: () => setTouchedPhone(true),\n markCpfTouched: () => setTouchedCpf(true),\n markPostalCodeTouched: () => setTouchedPostalCode(true),\n markAddressNumberTouched: () => setTouchedAddressNumber(true),\n\n emailStatus,\n submit,\n submitting,\n canSubmit,\n formSubmitAttempted,\n error,\n emailTaken,\n loginUrl,\n };\n}\n\nfunction mod11(digits: string, len: number): string {\n let sum = 0;\n for (let i = 0; i < len; i++) sum += parseInt(digits.charAt(i), 10) * (len + 1 - i);\n const r = (sum * 10) % 11;\n return String(r === 10 ? 0 : r);\n}\n","import { SdkError, SdkAuthError, SdkRateLimitError, SdkValidationError } from '@hook-sdk/sdk';\n\nexport type AuthFormErrorCode =\n | 'invalid_credentials'\n | 'rate_limited'\n | 'email_unverified'\n | 'email_taken'\n | 'account_locked'\n | 'network'\n | 'server';\n\nexport interface AuthFormError {\n code: AuthFormErrorCode;\n message: string;\n retryAfter?: number;\n}\n\n/**\n * Mapeia SdkError do @hook-sdk/sdk pra AuthFormError tipado do template.\n * Usado por useLoginForm/useSignupForm/useForgotForm.\n */\nexport function mapSdkError(err: unknown): AuthFormError {\n if (err instanceof SdkRateLimitError) {\n return {\n code: 'rate_limited',\n message: `Aguarde ${err.retryAfter}s e tente novamente.`,\n retryAfter: err.retryAfter,\n };\n }\n if (err instanceof SdkAuthError) {\n const detail = (err as { detail?: string }).detail;\n if (detail === 'email_unverified') {\n return { code: 'email_unverified', message: 'Confirme seu e-mail antes de entrar.' };\n }\n if (detail === 'account_locked') {\n return { code: 'account_locked', message: 'Conta bloqueada. Contate o suporte.' };\n }\n return { code: 'invalid_credentials', message: 'E-mail ou senha inválidos.' };\n }\n if (err instanceof SdkValidationError && err.code === 'auth.email_taken') {\n return { code: 'email_taken', message: 'Esse e-mail já tem conta.' };\n }\n if (err instanceof SdkError && err.httpStatus === 0) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n // Falhas de rede em POST/PATCH/DELETE não são envolvidas em SdkError pelo\n // HttpClient (só GET tem retry wrap). fetch() lança TypeError cru — tratamos\n // como 'network' pra manter UX consistente com GETs.\n if (err instanceof TypeError) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n return { code: 'server', message: 'Algo deu errado. Tente novamente em instantes.' };\n}\n","import { useHook } from '@hook-sdk/sdk';\nimport type { PlanInfo, PlanState } from '@hook-sdk/sdk';\n\n/**\n * Thin wrapper sobre `useHook().plan`. Existe pra apps importarem \"tudo\n * que precisam\" via `@hook-sdk/template` sem mudar de package pra cada\n * primitive, e pra manter espaço pra evoluir a API (ex: expor campos\n * derivados como `monthlyEquivalent()`) sem mexer no SDK.\n *\n * Retorna o PlanState bruto. Use junto com helpers de `@hook-sdk/template`:\n *\n * const { data, initialLoadComplete } = usePlan();\n * if (!initialLoadComplete) return <Skeleton />;\n * if (!data) return null;\n * return <span>{formatBRL(data.priceCents)}</span>;\n */\nexport function usePlan(): PlanState {\n const { plan } = useHook();\n return plan;\n}\n\nexport type { PlanInfo, PlanState };\n","// template/src/components/paywall/Paywall.tsx\nimport { useEffect, useMemo } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { formatBRL } from '../../utils/price';\nimport { PaywallProvider } from './PaywallProvider';\nimport { usePaywallContext } from './usePaywallContext';\nimport { PaywallMethodTabs } from './PaywallMethodTabs';\nimport { PaywallMethodContent } from './PaywallMethodContent';\nimport { PaywallCyclePicker } from './PaywallCyclePicker';\nimport type { PaywallProps } from './types';\n\n/** Non-breaking space produced by Intl.NumberFormat('pt-BR', { currency:'BRL' }). */\nconst NBSP = ' ';\n\n/**\n * Composed top-level paywall component. Apps wrap it in their `PaywallOffer.tsx`\n * (or `Offer.tsx`) and pass copy + themeClasses + slots. Logic + telemetry live\n * here. To customize layout entirely, drop down to the primitives.\n *\n * Internally wraps a `<PaywallProvider>` so the refactored primitives can read\n * state from context. Apps wanting Level 2 / Level 3 composition can use\n * `<PaywallProvider>` + Lego blocks directly without going through `<Paywall>`.\n */\nexport function Paywall({\n copy,\n themeClasses = {},\n slots = {},\n onBeforeCheckout,\n}: PaywallProps) {\n return (\n <PaywallProvider>\n <PaywallInner\n copy={copy}\n themeClasses={themeClasses}\n slots={slots}\n onBeforeCheckout={onBeforeCheckout}\n />\n </PaywallProvider>\n );\n}\n\nfunction PaywallInner({\n copy,\n themeClasses = {},\n slots = {},\n onBeforeCheckout,\n}: PaywallProps) {\n const { track } = useHook();\n const s = usePaywallContext();\n\n // Interpolate copy templates with current price + trial days.\n // Normalize NBSP (U+00A0) produced by Intl.NumberFormat('pt-BR') to regular\n // space so that template strings like \"Pagar {price} com PIX\" produce plain\n // ASCII-compatible output for accessible-name matching in tests + TTS.\n const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, 'g'), ' ');\n const trialDaysCardLabel = String(s.trialDaysCard);\n\n const ctaLabel = useMemo(() => {\n if (s.isFree) return copy.freeCta ?? 'Começar agora';\n if (s.selectedMethod === 'card') {\n if (s.hasConsumedTrial && copy.cardConsumedTrial) {\n return interp(copy.cardConsumedTrial.ctaTemplate, {\n price: priceLabel,\n days: trialDaysCardLabel,\n });\n }\n if (s.trialDaysCard > 0) {\n return interp(copy.card.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });\n }\n // card-no-trial fallback: reuse the consumed template if provided, else assinar literal.\n return copy.cardConsumedTrial\n ? interp(copy.cardConsumedTrial.ctaTemplate, {\n price: priceLabel,\n days: trialDaysCardLabel,\n })\n : `Assinar por ${priceLabel}`;\n }\n return interp(copy.pix.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });\n }, [\n s.isFree,\n s.selectedMethod,\n s.hasConsumedTrial,\n s.trialDaysCard,\n copy,\n priceLabel,\n trialDaysCardLabel,\n ]);\n\n const switchHint = useMemo(() => {\n if (s.methods.length < 2) return undefined;\n return s.selectedMethod === 'card' ? copy.card.switchHint : copy.pix.switchHint;\n }, [s.methods.length, s.selectedMethod, copy]);\n\n // Mount telemetry — fire once when methods + cycle resolve.\n useEffect(() => {\n if (!s.initialLoadComplete) return;\n track('paywall_view', {\n default_method: s.selectedMethod,\n default_cycle: s.cycle,\n available_methods: s.methods,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [s.initialLoadComplete]);\n\n const handleCta = async () => {\n track('paywall_cta_clicked', {\n method: s.selectedMethod,\n cycle: s.cycle,\n price_cents: s.currentPriceCents,\n had_consumed_trial: s.hasConsumedTrial,\n });\n if (onBeforeCheckout) {\n await onBeforeCheckout(s.selectedMethod, s.cycle);\n return;\n }\n await s.submit();\n };\n\n const ctaTheme =\n s.selectedMethod === 'card' ? themeClasses.ctaCard : themeClasses.ctaPix;\n\n return (\n <div className={themeClasses.container}>\n {slots.heroSlot}\n <h1 className={themeClasses.headline}>{copy.headline}</h1>\n <ul>\n {copy.features.map((f) => (\n <li key={f} className={themeClasses.feature}>\n ✓ <span>{f}</span>\n </li>\n ))}\n </ul>\n {copy.socialProof ? (\n <p className={themeClasses.socialProof}>{copy.socialProof}</p>\n ) : null}\n\n {slots.cyclePickerSlot ?? (\n <PaywallCyclePicker\n labels={copy.cycle}\n cardClassName={themeClasses.cycleCard}\n cardSelectedClassName={themeClasses.cycleCardSelected}\n anchorClassName={themeClasses.anchorPrice}\n />\n )}\n\n <PaywallMethodTabs\n labels={{ 'pix-auto': copy.pix.tabLabel, card: copy.card.tabLabel }}\n className={themeClasses.tabs}\n tabClassName={themeClasses.tab}\n tabActiveClassName={themeClasses.tabActive}\n />\n\n <PaywallMethodContent\n copy={{\n pix: interpolateCopy(copy.pix, priceLabel, trialDaysCardLabel),\n card: interpolateCopy(copy.card, priceLabel, trialDaysCardLabel),\n cardConsumedTrial: copy.cardConsumedTrial\n ? {\n bodyRows: copy.cardConsumedTrial.bodyRows.map((r) =>\n interp(r, { price: priceLabel, days: trialDaysCardLabel }),\n ) as [string, string, string],\n ctaTemplate: copy.cardConsumedTrial.ctaTemplate,\n }\n : undefined,\n }}\n className={themeClasses.tabContent}\n rowClassName={themeClasses.tabContentRow}\n />\n\n {slots.beforeCtaSlot}\n\n {/*\n CTA is rendered inline (not via PaywallCta) because <Paywall> owns\n telemetry + the onBeforeCheckout escape hatch — both couplings the\n Lego primitive doesn't carry. Apps composing their own paywall use\n <PaywallCta> directly (it dispatches context.submit on click).\n */}\n <div>\n <button\n type=\"button\"\n onClick={() => {\n void handleCta();\n }}\n disabled={s.submitting}\n className={ctaTheme}\n >\n {s.submitting ? 'Abrindo checkout…' : ctaLabel}\n </button>\n {switchHint ? (\n <p className={themeClasses.switchHint}>{switchHint}</p>\n ) : null}\n <p className={themeClasses.trustLine}>{copy.trustLine}</p>\n </div>\n </div>\n );\n}\n\nfunction interp(tpl: string, vars: Record<string, string>): string {\n return tpl.replace(/\\{(\\w+)\\}/g, (_m, k) => vars[k] ?? '');\n}\n\nfunction interpolateCopy(\n m: { tabLabel: string; bodyRows: readonly [string, string, string]; ctaTemplate: string; switchHint: string },\n price: string,\n days: string,\n) {\n return {\n tabLabel: m.tabLabel,\n bodyRows: m.bodyRows.map((r) => interp(r, { price, days })) as [string, string, string],\n ctaTemplate: m.ctaTemplate,\n switchHint: m.switchHint,\n };\n}\n","/**\n * Helpers de formatação de preço pro Hook.\n *\n * Preço vive no banco em CENTAVOS (int), sempre. Apps que renderizam preço\n * leem do hook `usePlan()` e passam por `formatBRL(cents)` — nunca formatam\n * inline. Isso evita os dois patterns errados que já vimos em conversões\n * Lovable→Hook: (a) strings hardcoded \"R$ 19,90\" no JSX, (b) divisões ad-hoc\n * por 100 + `toFixed(2)` que ignoram locale.\n *\n * Ver G72 em .claude/skills/hook-conversion-shared/catalog/known-gotchas.md.\n */\n\n/**\n * Formata centavos como BRL no locale pt-BR. Aceita null pra conveniência\n * (callers que lidam com `yearlyPriceCents: number | null`).\n *\n * Examples:\n * formatBRL(1990) → \"R$ 19,90\"\n * formatBRL(4999) → \"R$ 49,99\"\n * formatBRL(23988) → \"R$ 239,88\"\n * formatBRL(0) → \"R$ 0,00\"\n * formatBRL(null) → \"\"\n */\nexport function formatBRL(cents: number | null | undefined): string {\n if (cents === null || cents === undefined) return '';\n const reais = cents / 100;\n return new Intl.NumberFormat('pt-BR', {\n style: 'currency',\n currency: 'BRL',\n }).format(reais);\n}\n\n/**\n * Deriva \"preço mensal\" a partir do preço anual (em centavos). Round half-up\n * pra evitar R$ 19,899... → R$ 19,89 quando o usuário esperava R$ 19,90.\n *\n * Não assume que o creator configurou yearlyPriceCents \"redondo\": se ele\n * setou 23988 (= R$ 239,88), 23988/12 = 1999 (= R$ 19,99). Se setou 23880\n * (= R$ 238,80), 23880/12 = 1990 (= R$ 19,90).\n *\n * Example (papomaterno):\n * monthlyFromYearly(23988) = 1999 → formatBRL = \"R$ 19,99\"\n * monthlyFromYearly(23880) = 1990 → formatBRL = \"R$ 19,90\"\n */\nexport function monthlyFromYearly(yearlyCents: number | null | undefined): number {\n if (yearlyCents === null || yearlyCents === undefined) return 0;\n return Math.round(yearlyCents / 12);\n}\n\n/**\n * Deriva \"preço por dia\" (365 dias) a partir do anual, em centavos. Útil\n * pra copy tipo \"apenas R$ 0,66 por dia, menos que um café\".\n *\n * Example:\n * dailyFromYearly(23988) = 66 → formatBRL = \"R$ 0,66\"\n */\nexport function dailyFromYearly(yearlyCents: number | null | undefined): number {\n if (yearlyCents === null || yearlyCents === undefined) return 0;\n return Math.round(yearlyCents / 365);\n}\n\n/**\n * Deriva o preço-ancoragem (valor \"cheio\" riscado) como múltiplo do preço\n * real. Serve pra ancoragem psicológica em telas de paywall: mostra um valor\n * maior riscado antes do preço real pra o usuário sentir desconto.\n *\n * Com `anchorMultiplier` no `paywall_config`, o creator mantém só o preço\n * real no DB; a ancoragem acompanha automaticamente se o preço muda.\n *\n * Retorna `null` quando o multiplier não é utilizável (falta, ≤ 1, NaN,\n * Infinity). Caller deve cair no fallback (valor absoluto em\n * `paywall_config.anchorPriceCents`) ou pular a renderização da ancoragem.\n *\n * Examples:\n * computeAnchorCents(1999, 2.5) = 4998\n * computeAnchorCents(1999, undefined) = null\n * computeAnchorCents(1999, 1) = null // 1× não ancora nada\n * computeAnchorCents(1999, 0) = null\n * computeAnchorCents(1999, NaN) = null\n */\nexport function computeAnchorCents(\n baseCents: number,\n multiplier: number | null | undefined,\n): number | null {\n if (multiplier === null || multiplier === undefined) return null;\n if (!Number.isFinite(multiplier)) return null;\n if (multiplier <= 1) return null;\n return Math.round(baseCents * multiplier);\n}\n\n/**\n * Percentual de desconto (anchor → real), arredondado pra baixo pra nunca\n * overstate. Retorna 0 quando anchor ≤ real (sem desconto a mostrar).\n *\n * Examples:\n * discountPercent(4998, 1999) = 60 // (4998-1999)/4998 = 0.60...\n * discountPercent(3998, 1999) = 50\n * discountPercent(1000, 2000) = 0 // real > anchor\n * discountPercent(2000, 2000) = 0\n */\nexport function discountPercent(anchorCents: number, realCents: number): number {\n if (anchorCents <= realCents) return 0;\n return Math.floor(((anchorCents - realCents) / anchorCents) * 100);\n}\n","// template/src/components/paywall/PaywallProvider.tsx\nimport { createContext, type ReactNode } from 'react';\nimport { usePaywallState } from '../../hooks/usePaywallState';\n\n/**\n * Full return shape of `usePaywallState()`. Apps consuming via\n * `usePaywallContext()` get the same fields they'd get from the headless\n * hook directly — no internal-only fields hidden.\n *\n * This is the \"Level 3\" escape-hatch contract: any app can drop down to raw\n * context and render an entirely custom paywall, with the template still\n * owning state + telemetry + checkout dispatch.\n */\nexport type PaywallContextValue = ReturnType<typeof usePaywallState>;\n\n/**\n * Context that carries the full paywall state down to Lego blocks. Null\n * outside `<PaywallProvider>`. Consumer hook `usePaywallContext()` throws on\n * null to surface mis-mounted blocks early.\n */\nexport const PaywallContext = createContext<PaywallContextValue | null>(null);\n\nexport type PaywallProviderProps = {\n children: ReactNode;\n};\n\n/**\n * Owns the headless paywall state for one paywall surface. All Lego blocks\n * (PriceHeadline, AnchorPrice, FinePrint, refactored primitives) and the\n * composed `<Paywall>` read state via this provider.\n *\n * Multiple compositions can share state by sharing one `<PaywallProvider>`\n * parent (e.g. side-by-side variants on a dev/test page). Multiple\n * providers in the same tree get independent state.\n */\nexport function PaywallProvider({ children }: PaywallProviderProps) {\n const state = usePaywallState();\n return <PaywallContext.Provider value={state}>{children}</PaywallContext.Provider>;\n}\n","// template/src/components/paywall/usePaywallContext.ts\nimport { useContext } from 'react';\nimport { PaywallContext, type PaywallContextValue } from './PaywallProvider';\n\n/**\n * Consumer hook for the paywall context. Returns the non-null state object\n * (same shape as `usePaywallState()`) when called inside `<PaywallProvider>`.\n *\n * Throws `\"usePaywallContext must be used within <PaywallProvider>\"` when the\n * provider is missing — surfaces mis-mounted Lego blocks at render time\n * instead of silently rendering with stale or default state.\n */\nexport function usePaywallContext(): PaywallContextValue {\n const ctx = useContext(PaywallContext);\n if (!ctx) {\n throw new Error('usePaywallContext must be used within <PaywallProvider>');\n }\n return ctx;\n}\n","// template/src/components/paywall/PaywallMethodTabs.tsx\nimport type { CheckoutMethod } from '../../types/AppConfig';\nimport { usePaywallContext } from './usePaywallContext';\n\nexport type PaywallMethodTabsProps = {\n /** Tab labels keyed by checkout method. App-provided copy (not state). */\n labels: Partial<Record<CheckoutMethod, string>>;\n /** Wrapper className. */\n className?: string;\n /** Individual tab className. */\n tabClassName?: string;\n /** Individual tab className when active. */\n tabActiveClassName?: string;\n};\n\nexport function PaywallMethodTabs({\n labels,\n className,\n tabClassName,\n tabActiveClassName,\n}: PaywallMethodTabsProps) {\n const { methods, selectedMethod, selectMethod } = usePaywallContext();\n\n if (methods.length < 2) return null;\n\n return (\n <div role=\"tablist\" aria-label=\"Método de pagamento\" className={className}>\n {methods.map((m) => {\n const active = m === selectedMethod;\n const label = labels[m] ?? m;\n return (\n <button\n key={m}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n aria-controls={`paywall-tab-${m}`}\n tabIndex={active ? 0 : -1}\n onClick={() => selectMethod(m)}\n className={[tabClassName, active ? tabActiveClassName : '']\n .filter(Boolean)\n .join(' ')}\n >\n {label}\n </button>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/PaywallMethodContent.tsx\nimport type { PaywallCopy } from './types';\nimport { usePaywallContext } from './usePaywallContext';\n\nexport type PaywallMethodContentProps = {\n /**\n * App-provided copy keyed by method. `pix` covers both `pix-auto` and\n * `pix-once`. `cardConsumedTrial` is used when the active method is `card`\n * AND `hasConsumedTrial` (read from context) is true.\n */\n copy: Pick<PaywallCopy, 'pix' | 'card'> & {\n cardConsumedTrial?: PaywallCopy['cardConsumedTrial'];\n };\n /** Tab-panel wrapper className. */\n className?: string;\n /** Per-row className. */\n rowClassName?: string;\n};\n\nexport function PaywallMethodContent({ copy, className, rowClassName }: PaywallMethodContentProps) {\n const { selectedMethod, hasConsumedTrial } = usePaywallContext();\n\n const useCardConsumed =\n selectedMethod === 'card' && hasConsumedTrial && copy.cardConsumedTrial;\n const rows: readonly string[] = useCardConsumed\n ? copy.cardConsumedTrial!.bodyRows\n : selectedMethod === 'pix-auto' || selectedMethod === 'pix-once'\n ? copy.pix.bodyRows\n : copy.card.bodyRows;\n\n return (\n <div role=\"tabpanel\" id={`paywall-tab-${selectedMethod}`} className={className}>\n {rows.map((row, i) => (\n <div key={i} className={rowClassName}>\n {row}\n </div>\n ))}\n </div>\n );\n}\n","// template/src/components/paywall/PaywallCyclePicker.tsx\nimport type { ReactNode } from 'react';\nimport type { Cycle } from '../../types/AppConfig';\nimport { formatBRL } from '../../utils/price';\nimport { usePaywallContext } from './usePaywallContext';\n\nexport type CycleLabels = {\n annualLabel: string;\n monthlyLabel: string;\n annualSuffix: string;\n monthlySuffix: string;\n};\n\n/** Cycle picker visual variants. `default` preserves the current visual. */\nexport type PaywallCyclePickerVariant = 'default' | 'premium-gold' | 'pink-pill';\n\n/** State passed to the optional `render` escape hatch. */\nexport type PaywallCyclePickerRenderArgs = {\n cycles: readonly Cycle[];\n selected: Cycle;\n setCycle: (c: Cycle) => void;\n plan: ReturnType<typeof usePaywallContext>['plan'];\n anchorPriceCents: number | null;\n};\n\nexport type PaywallCyclePickerProps = {\n labels: CycleLabels;\n /** Root wrapper className. */\n className?: string;\n /** Per-card base className. */\n cardClassName?: string;\n /** Applied when the card is selected (in addition to `cardClassName`). */\n cardSelectedClassName?: string;\n /** Anchor strikethrough className inside the card. */\n anchorClassName?: string;\n /** Visual variant. Variants are sugar for className combos. */\n variant?: PaywallCyclePickerVariant;\n /**\n * Render-prop escape hatch. When provided, the picker returns the prop's\n * output wrapped in a root element with the configured `className`. State\n * plumbing stays; visual is 100% the app's.\n */\n render?: (state: PaywallCyclePickerRenderArgs) => ReactNode;\n};\n\n/**\n * Variant → className map. Variants are sugar — they expand to className\n * combos at render time and merge with app-provided className props.\n */\nconst VARIANT_CLASSES: Record<PaywallCyclePickerVariant, { card: string; cardSelected: string }> = {\n default: { card: '', cardSelected: '' },\n 'premium-gold': {\n card: '',\n cardSelected: 'border-2 border-yellow-400/80 ring-2 ring-yellow-400/20',\n },\n 'pink-pill': {\n card: 'rounded-2xl',\n cardSelected: 'border-2 border-pink-500',\n },\n};\n\nexport function PaywallCyclePicker({\n labels,\n className,\n cardClassName,\n cardSelectedClassName,\n anchorClassName,\n variant = 'default',\n render,\n}: PaywallCyclePickerProps) {\n const ctx = usePaywallContext();\n const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;\n\n // Cycles available come from the AppConfig.paywall.cycles via state.\n // Mirror existing default of MONTHLY + YEARLY when the hook doesn't expose\n // an array directly (it doesn't; cycles are derived in usePaywallState\n // but not surfaced on the return). For now, fall back to ['MONTHLY','YEARLY'].\n // The composed <Paywall> always passes both — single-cycle apps render null.\n const cycles: readonly Cycle[] = ['MONTHLY', 'YEARLY'];\n\n // Render-prop escape hatch — app owns the visual entirely.\n if (render) {\n return (\n <div className={className}>\n {render({ cycles, selected, setCycle, plan, anchorPriceCents })}\n </div>\n );\n }\n\n if (cycles.length < 2) return null;\n\n const v = VARIANT_CLASSES[variant];\n const composedCardClassName = [v.card, cardClassName].filter(Boolean).join(' ');\n const composedCardSelectedClassName = [v.cardSelected, cardSelectedClassName]\n .filter(Boolean)\n .join(' ');\n\n // Derive price-by-cycle from plan derivation (computed in usePaywallState).\n // monthlyCents / yearlyCents are present whenever paywall.mode !== 'free'.\n const monthlyCents = plan?.monthlyCents ?? 0;\n const yearlyCents = plan?.yearlyCents ?? 0;\n const anchorMonthly = plan?.anchorMonthlyCents ?? null;\n const anchorYearly = plan?.anchorYearlyCents ?? null;\n\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Ciclo de cobrança\"\n className={['flex flex-row gap-2', className].filter(Boolean).join(' ')}\n >\n {cycles.map((c) => {\n const active = c === selected;\n const label = c === 'YEARLY' ? labels.annualLabel : labels.monthlyLabel;\n const suffix = c === 'YEARLY' ? labels.annualSuffix : labels.monthlySuffix;\n // YEARLY card shows monthly-equiv as the main number; MONTHLY shows raw.\n const mainCents =\n c === 'YEARLY' ? Math.round(yearlyCents / 12) : monthlyCents;\n const anchorCents = c === 'YEARLY' ? anchorYearly : anchorMonthly;\n return (\n <button\n key={c}\n type=\"button\"\n role=\"radio\"\n aria-checked={active}\n onClick={() => setCycle(c)}\n className={[\n 'flex flex-col items-center gap-0.5',\n composedCardClassName,\n active ? composedCardSelectedClassName : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <span className=\"font-bold text-base leading-tight\">{formatBRL(mainCents)}</span>\n <span className=\"text-xs opacity-70 leading-tight\">{suffix}</span>\n <span className=\"text-xs opacity-60 leading-tight\">{label}</span>\n {anchorCents != null && anchorCents > mainCents ? (\n <span className={anchorClassName ?? 'text-xs opacity-50'}>\n <s>{formatBRL(anchorCents)}</s>\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/PaywallCta.tsx\nimport { usePaywallContext } from './usePaywallContext';\n\nexport type PaywallCtaProps = {\n /** Already-interpolated CTA label (e.g. \"Pagar R$ 19,90 com PIX\"). */\n ctaLabel: string;\n /** Label shown while `submitting === true`. Defaults to `ctaLabel`. */\n loadingLabel?: string;\n /**\n * Switch-hint copy shown under the CTA when the other method is available.\n * Caller decides visibility (typically only when `methods.length > 1`).\n */\n switchHint?: string;\n /** Trust line under the CTA / switch hint. */\n trustLine: string;\n /** Wrapper className. */\n className?: string;\n /** Button className. */\n buttonClassName?: string;\n /** Switch-hint paragraph className. */\n switchHintClassName?: string;\n /** Trust-line paragraph className. */\n trustClassName?: string;\n};\n\n/**\n * CTA button + switch hint + trust line. Reads `submit` + `submitting` from\n * context — the button dispatches the checkout on click and disables itself\n * while submitting. Apps wanting a different action (e.g. open a CPF modal\n * first) should compose via `<Paywall onBeforeCheckout>` or use raw context\n * with their own button.\n */\nexport function PaywallCta({\n ctaLabel,\n loadingLabel,\n switchHint,\n trustLine,\n className,\n buttonClassName,\n switchHintClassName,\n trustClassName,\n}: PaywallCtaProps) {\n const { submit, submitting } = usePaywallContext();\n const label = submitting && loadingLabel ? loadingLabel : ctaLabel;\n return (\n <div className={className}>\n <button\n type=\"button\"\n onClick={() => {\n void submit();\n }}\n disabled={submitting}\n className={buttonClassName}\n >\n {label}\n </button>\n {switchHint ? <p className={switchHintClassName}>{switchHint}</p> : null}\n <p className={trustClassName}>{trustLine}</p>\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallEyebrow.tsx\nexport type PaywallEyebrowProps = {\n text: string;\n className?: string;\n};\n\nconst DEFAULT_EYEBROW_CLASSES = 'text-xs uppercase tracking-widest font-semibold opacity-70';\n\nexport function PaywallEyebrow({ text, className }: PaywallEyebrowProps) {\n return (\n <div className={[DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(' ')}>\n {text}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallHero.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallHeroRenderState = {\n src: string;\n headline?: string;\n};\n\nexport type PaywallHeroProps = {\n src: string;\n alt?: string;\n headline?: string;\n aspectRatio?: string;\n gradientClassName?: string;\n className?: string;\n headlineClassName?: string;\n imgClassName?: string;\n render?: (state: PaywallHeroRenderState) => ReactNode;\n};\n\nconst DEFAULT_GRADIENT = 'absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent';\n\nexport function PaywallHero({\n src,\n alt = '',\n headline,\n aspectRatio = '16/9',\n gradientClassName,\n className,\n headlineClassName,\n imgClassName,\n render,\n}: PaywallHeroProps) {\n if (render) {\n return (\n <div className={className}>\n {render({ src, headline })}\n </div>\n );\n }\n\n return (\n <div\n className={['relative overflow-hidden', className].filter(Boolean).join(' ')}\n style={{ aspectRatio }}\n >\n <img\n src={src}\n alt={alt}\n className={['absolute inset-0 w-full h-full object-cover', imgClassName].filter(Boolean).join(' ')}\n />\n <div className={gradientClassName ?? DEFAULT_GRADIENT} aria-hidden=\"true\" />\n {headline ? (\n <h1\n className={['absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl', headlineClassName]\n .filter(Boolean)\n .join(' ')}\n >\n {headline}\n </h1>\n ) : null}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallHeadline.tsx\nexport type PaywallHeadlineProps = {\n text: string;\n className?: string;\n as?: 'h1' | 'h2';\n};\n\nconst DEFAULT_HEADLINE_CLASSES = 'text-2xl font-bold leading-tight';\n\nexport function PaywallHeadline({ text, className, as = 'h1' }: PaywallHeadlineProps) {\n const Tag = as;\n return (\n <Tag className={[DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(' ')}>\n {text}\n </Tag>\n );\n}\n","// template/src/components/paywall/blocks/PaywallPriceHeadline.tsx\nimport type { ReactNode } from 'react';\nimport { usePaywallContext } from '../usePaywallContext';\nimport { dailyFromYearly, formatBRL } from '../../../utils/price';\n\nexport type PaywallPriceHeadlineProps = {\n /**\n * Copy template. Supported substitutions:\n * - `{pricePerDay}` → daily price formatted (BRL), derived from yearly.\n * - `{currentMonthlyEquiv}` → formatted monthly-equivalent BRL.\n * - `{cycle}` → human-readable cycle (\"mensal\" | \"anual\").\n *\n * Example: `\"Comece hoje por {pricePerDay} por dia\"`.\n */\n template: string;\n className?: string;\n as?: 'h1' | 'h2' | 'h3';\n render?: (state: {\n pricePerDay: string;\n currentMonthlyEquivCents: number;\n cycle: string;\n }) => ReactNode;\n};\n\nconst DEFAULT_CLASS = 'text-2xl font-bold leading-tight';\n\nconst CYCLE_LABEL: Record<string, string> = {\n MONTHLY: 'mensal',\n YEARLY: 'anual',\n};\n\nexport function PaywallPriceHeadline({\n template,\n className,\n as = 'h1',\n render,\n}: PaywallPriceHeadlineProps) {\n const { cycle, currentMonthlyEquivCents, plan } = usePaywallContext();\n\n const yearlyCents = plan?.yearlyCents ?? null;\n const pricePerDay = formatBRL(dailyFromYearly(yearlyCents));\n const monthlyEquiv = currentMonthlyEquivCents ?? 0;\n const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();\n\n const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(' ');\n\n if (render) {\n const RootTag = as;\n return (\n <RootTag className={[className].filter(Boolean).join(' ') || undefined}>\n {render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle })}\n </RootTag>\n );\n }\n\n const text = template\n .replaceAll('{pricePerDay}', pricePerDay)\n .replaceAll('{currentMonthlyEquiv}', formatBRL(monthlyEquiv))\n .replaceAll('{cycle}', cycleLabel);\n\n const RootTag = as;\n return <RootTag className={rootClasses}>{text}</RootTag>;\n}\n","// template/src/components/paywall/blocks/PaywallCountdown.tsx\nimport { useEffect, useRef, useState, type ReactNode } from 'react';\n\nexport type PaywallCountdownRenderState = {\n h: number;\n m: number;\n s: number;\n expired: boolean;\n};\n\nexport type PaywallCountdownDeadline =\n | Date\n | string\n | { sessionStorageKey: string; durationMs: number };\n\nexport type PaywallCountdownProps = {\n deadline: PaywallCountdownDeadline;\n format?: 'h:m:s' | 'm:s';\n onExpire?: () => void;\n className?: string;\n render?: (state: PaywallCountdownRenderState) => ReactNode;\n};\n\nconst DEFAULT_COUNTDOWN_CLASSES = 'font-mono tabular-nums';\n\n/**\n * Resolve the absolute deadline timestamp (ms since epoch) from the polymorphic\n * `deadline` prop. For session-storage variant, persists `now + durationMs` on\n * first access so subsequent renders/sessions read the same target.\n */\nfunction resolveDeadlineMs(deadline: PaywallCountdownDeadline): number {\n if (deadline instanceof Date) return deadline.getTime();\n if (typeof deadline === 'string') return new Date(deadline).getTime();\n\n // sessionStorage-backed variant\n const { sessionStorageKey, durationMs } = deadline;\n if (typeof window === 'undefined' || typeof window.sessionStorage === 'undefined') {\n // SSR / no sessionStorage — fall back to now + durationMs (no persistence)\n return Date.now() + durationMs;\n }\n const stored = window.sessionStorage.getItem(sessionStorageKey);\n const parsed = stored ? Number.parseInt(stored, 10) : NaN;\n const now = Date.now();\n if (!Number.isFinite(parsed) || parsed < now) {\n const target = now + durationMs;\n window.sessionStorage.setItem(sessionStorageKey, String(target));\n return target;\n }\n return parsed;\n}\n\nfunction computeRemaining(deadlineMs: number): { h: number; m: number; s: number; expired: boolean } {\n const diff = Math.max(0, deadlineMs - Date.now());\n const totalSeconds = Math.floor(diff / 1000);\n const h = Math.floor(totalSeconds / 3600);\n const m = Math.floor((totalSeconds % 3600) / 60);\n const s = totalSeconds % 60;\n return { h, m, s, expired: diff === 0 };\n}\n\nfunction pad(n: number): string {\n return String(n).padStart(2, '0');\n}\n\nexport function PaywallCountdown({\n deadline,\n format = 'h:m:s',\n onExpire,\n className,\n render,\n}: PaywallCountdownProps) {\n // Resolve once per mount; deadline object identity changes shouldn't churn the timer.\n const deadlineMsRef = useRef<number | null>(null);\n if (deadlineMsRef.current === null) {\n deadlineMsRef.current = resolveDeadlineMs(deadline);\n }\n\n const [state, setState] = useState(() => computeRemaining(deadlineMsRef.current!));\n const expiredCalledRef = useRef(false);\n\n useEffect(() => {\n // If already expired on mount, fire onExpire once and skip the interval.\n if (state.expired) {\n if (!expiredCalledRef.current) {\n expiredCalledRef.current = true;\n onExpire?.();\n }\n return;\n }\n\n const tick = () => {\n const next = computeRemaining(deadlineMsRef.current!);\n setState(next);\n if (next.expired && !expiredCalledRef.current) {\n expiredCalledRef.current = true;\n onExpire?.();\n }\n };\n\n const id = setInterval(tick, 1000);\n return () => clearInterval(id);\n // onExpire intentionally excluded — we only want to fire it once per mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state.expired]);\n\n if (render) {\n return <div className={className}>{render(state)}</div>;\n }\n\n const formatted =\n format === 'h:m:s'\n ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}`\n : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;\n\n return (\n <div className={[DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(' ')}>\n {formatted}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallFeatures.tsx\nimport type { ComponentType, ReactNode } from 'react';\n\nexport type PaywallFeaturesRenderState = {\n items: readonly string[];\n};\n\nexport type PaywallFeaturesProps = {\n items: readonly string[];\n IconComponent?: ComponentType<{ className?: string }>;\n className?: string;\n itemClassName?: string;\n iconClassName?: string;\n render?: (state: PaywallFeaturesRenderState) => ReactNode;\n renderItem?: (item: string, idx: number) => ReactNode;\n};\n\nexport function PaywallFeatures({\n items,\n IconComponent,\n className,\n itemClassName,\n iconClassName,\n render,\n renderItem,\n}: PaywallFeaturesProps) {\n if (render) {\n return <div className={className}>{render({ items })}</div>;\n }\n\n if (renderItem) {\n return (\n <ul className={className}>\n {items.map((item, idx) => (\n <li key={idx}>{renderItem(item, idx)}</li>\n ))}\n </ul>\n );\n }\n\n return (\n <ul className={className}>\n {items.map((item, idx) => (\n <li key={idx} className={itemClassName}>\n {IconComponent ? (\n <IconComponent className={iconClassName} />\n ) : (\n <span className={iconClassName} aria-hidden=\"true\">✓</span>\n )}\n <span>{item}</span>\n </li>\n ))}\n </ul>\n );\n}\n","// template/src/components/paywall/blocks/PaywallFeaturesCard.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallFeaturesCardProps = {\n title?: string;\n items: readonly string[];\n className?: string;\n cardClassName?: string;\n titleClassName?: string;\n itemClassName?: string;\n renderItem?: (item: string, idx: number) => ReactNode;\n};\n\nconst DEFAULT_CARD_CLASSES = 'rounded-xl border p-4';\n\nexport function PaywallFeaturesCard({\n title,\n items,\n className,\n cardClassName,\n titleClassName,\n itemClassName,\n renderItem,\n}: PaywallFeaturesCardProps) {\n return (\n <div className={className}>\n <div className={[DEFAULT_CARD_CLASSES, cardClassName].filter(Boolean).join(' ')}>\n {title ? (\n <div className={['font-semibold mb-2', titleClassName].filter(Boolean).join(' ')}>\n {title}\n </div>\n ) : null}\n <ul>\n {items.map((item, idx) =>\n renderItem ? (\n <li key={idx}>{renderItem(item, idx)}</li>\n ) : (\n <li key={idx} className={itemClassName}>\n <span aria-hidden=\"true\">•</span> <span>{item}</span>\n </li>\n ),\n )}\n </ul>\n </div>\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallTrophyBadge.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallTrophyBadgeRenderState = {\n text: string;\n};\n\nexport type PaywallTrophyBadgeProps = {\n text: string;\n className?: string;\n iconClassName?: string;\n floating?: boolean;\n render?: (state: PaywallTrophyBadgeRenderState) => ReactNode;\n};\n\nconst DEFAULT_CHIP_CLASSES =\n 'inline-flex items-center gap-1 px-3 py-1 rounded-full bg-yellow-100 text-yellow-900 text-sm font-medium';\n\nconst FLOATING_CLASSES = 'absolute top-2 right-2 z-10 shadow-md';\n\nexport function PaywallTrophyBadge({\n text,\n className,\n iconClassName,\n floating = false,\n render,\n}: PaywallTrophyBadgeProps) {\n if (render) {\n return <div className={className}>{render({ text })}</div>;\n }\n\n const rootClasses = [\n DEFAULT_CHIP_CLASSES,\n floating ? FLOATING_CLASSES : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={rootClasses}>\n <span className={iconClassName} aria-hidden=\"true\">\n 🏆\n </span>\n <span>{text}</span>\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallAnchorPrice.tsx\nimport type { ReactNode } from 'react';\nimport { usePaywallContext } from '../usePaywallContext';\nimport { formatBRL } from '../../../utils/price';\n\nexport type PaywallAnchorPriceProps = {\n className?: string;\n render?: (state: { anchorCents: number; formatted: string }) => ReactNode;\n};\n\nconst DEFAULT_CLASS = 'text-sm opacity-60 line-through';\n\nexport function PaywallAnchorPrice({\n className,\n render,\n}: PaywallAnchorPriceProps) {\n const { anchorPriceCents, cycle } = usePaywallContext();\n\n if (anchorPriceCents === null || anchorPriceCents === undefined || anchorPriceCents <= 0) {\n return null;\n }\n\n void cycle;\n\n const formatted = formatBRL(anchorPriceCents);\n const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(' ');\n\n if (render) {\n return (\n <span className={className || undefined}>\n {render({ anchorCents: anchorPriceCents, formatted })}\n </span>\n );\n }\n\n return <span className={rootClasses}>{formatted}</span>;\n}\n","// template/src/components/paywall/blocks/PaywallTestimonials.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallTestimonial = {\n name: string;\n avatar?: string;\n stars: number;\n quote: string;\n};\n\nexport type PaywallTestimonialsProps = {\n items: readonly PaywallTestimonial[];\n className?: string;\n cardClassName?: string;\n avatarClassName?: string;\n quoteClassName?: string;\n nameClassName?: string;\n starsClassName?: string;\n renderItem?: (item: PaywallTestimonial, idx: number) => ReactNode;\n};\n\nconst DEFAULT_ROOT = 'flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2';\nconst DEFAULT_CARD =\n 'snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2';\nconst DEFAULT_AVATAR = 'w-10 h-10 rounded-full object-cover';\nconst DEFAULT_QUOTE = 'text-sm leading-snug';\nconst DEFAULT_NAME = 'text-xs font-semibold opacity-80';\nconst DEFAULT_STARS = 'text-yellow-500 text-sm';\n\nfunction clampStars(n: number): number {\n return Math.max(0, Math.min(5, Math.round(n)));\n}\n\nexport function PaywallTestimonials({\n items,\n className,\n cardClassName,\n avatarClassName,\n quoteClassName,\n nameClassName,\n starsClassName,\n renderItem,\n}: PaywallTestimonialsProps) {\n const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(' ');\n const cardClasses = [DEFAULT_CARD, cardClassName].filter(Boolean).join(' ');\n const avatarClasses = [DEFAULT_AVATAR, avatarClassName].filter(Boolean).join(' ');\n const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(' ');\n const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(' ');\n const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(' ');\n\n return (\n <div className={rootClasses}>\n {items.map((item, idx) => {\n if (renderItem) return renderItem(item, idx);\n const filled = clampStars(item.stars);\n const empty = 5 - filled;\n return (\n <div key={idx} className={cardClasses}>\n <div className=\"flex items-center gap-2\">\n {item.avatar ? (\n <img\n src={item.avatar}\n alt=\"\"\n loading=\"lazy\"\n className={avatarClasses}\n aria-hidden=\"true\"\n />\n ) : null}\n <div className={nameClasses}>{item.name}</div>\n </div>\n <div className={starsClasses} aria-label={`${filled} de 5 estrelas`}>\n {'★'.repeat(filled)}\n {'☆'.repeat(empty)}\n </div>\n <p className={quoteClasses}>{item.quote}</p>\n </div>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallStatsRow.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallStat = {\n value: string;\n label: string;\n icon?: ReactNode;\n};\n\nexport type PaywallStatsRowProps = {\n stats: readonly PaywallStat[];\n className?: string;\n cellClassName?: string;\n valueClassName?: string;\n labelClassName?: string;\n renderCell?: (stat: PaywallStat, idx: number) => ReactNode;\n};\n\nconst DEFAULT_ROOT = 'grid grid-cols-3 gap-4';\nconst DEFAULT_CELL = 'flex flex-col items-center text-center';\nconst DEFAULT_VALUE = 'text-2xl font-bold';\nconst DEFAULT_LABEL = 'text-xs opacity-70';\n\nexport function PaywallStatsRow({\n stats,\n className,\n cellClassName,\n valueClassName,\n labelClassName,\n renderCell,\n}: PaywallStatsRowProps) {\n const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(' ');\n const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(' ');\n const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(' ');\n const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(' ');\n\n return (\n <div className={rootClasses}>\n {stats.map((stat, idx) => {\n if (renderCell) return renderCell(stat, idx);\n return (\n <div key={idx} className={cellClasses}>\n {stat.icon ? <div aria-hidden=\"true\">{stat.icon}</div> : null}\n <div className={valueClasses}>{stat.value}</div>\n <div className={labelClasses}>{stat.label}</div>\n </div>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallFinePrint.tsx\nimport type { ReactNode } from 'react';\nimport { usePaywallContext } from '../usePaywallContext';\nimport { formatBRL } from '../../../utils/price';\n\nexport type PaywallFinePrintProps = {\n /**\n * Copy template. Supported substitutions:\n * - `{price}` → formatted current price (BRL).\n * - `{trialDays}` → method-specific trial days (card vs pix).\n * - `{cycle}` → human-readable cycle (\"mensal\" | \"anual\").\n */\n template: string;\n className?: string;\n render?: (state: {\n currentPriceCents: number;\n cycle: string;\n trialDays: number;\n selectedMethod: string;\n }) => ReactNode;\n};\n\nconst DEFAULT_CLASS = 'text-xs opacity-60 leading-snug';\n\nconst CYCLE_LABEL: Record<string, string> = {\n MONTHLY: 'mensal',\n YEARLY: 'anual',\n};\n\nexport function PaywallFinePrint({\n template,\n className,\n render,\n}: PaywallFinePrintProps) {\n const {\n currentPriceCents,\n cycle,\n trialDaysCard,\n trialDaysPix,\n selectedMethod,\n } = usePaywallContext();\n\n const trialDays = selectedMethod === 'card' ? trialDaysCard : trialDaysPix;\n const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();\n const priceFormatted = formatBRL(currentPriceCents ?? 0);\n\n const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(' ');\n\n if (render) {\n return (\n <p className={className || undefined}>\n {render({\n currentPriceCents: currentPriceCents ?? 0,\n cycle,\n trialDays: trialDays ?? 0,\n selectedMethod,\n })}\n </p>\n );\n }\n\n const text = template\n .replaceAll('{price}', priceFormatted)\n .replaceAll('{trialDays}', String(trialDays ?? 0))\n .replaceAll('{cycle}', cycleLabel);\n\n return <p className={rootClasses}>{text}</p>;\n}\n","// template/src/components/paywall/blocks/PaywallTrustLine.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallTrustLineItem = {\n icon: ReactNode;\n text: string;\n};\n\nexport type PaywallTrustLineProps = {\n items: readonly PaywallTrustLineItem[];\n className?: string;\n itemClassName?: string;\n renderItem?: (item: PaywallTrustLineItem, idx: number) => ReactNode;\n};\n\nconst DEFAULT_ROOT = 'flex items-center gap-3';\nconst DEFAULT_ITEM = 'flex items-center gap-1.5 text-xs';\n\nexport function PaywallTrustLine({\n items,\n className,\n itemClassName,\n renderItem,\n}: PaywallTrustLineProps) {\n const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(' ');\n const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(' ');\n return (\n <div className={rootClasses}>\n {items.map((item, idx) => {\n if (renderItem) return renderItem(item, idx);\n return (\n <span key={idx} className={itemClasses}>\n <span aria-hidden=\"true\">{item.icon}</span>\n <span>{item.text}</span>\n </span>\n );\n })}\n </div>\n );\n}\n","// template/src/components/paywall/blocks/PaywallStickyFooter.tsx\nimport type { ReactNode } from 'react';\n\nexport type PaywallStickyFooterProps = {\n children: ReactNode;\n className?: string;\n /**\n * When true (default), appends `pb-[env(safe-area-inset-bottom)]` so the\n * footer clears the home-indicator on iOS. Set false for footers that\n * already opt into their own safe-area handling (e.g. inside a sheet).\n */\n safeAreaInsets?: boolean;\n};\n\nconst DEFAULT_CLASSES = 'sticky bottom-0 left-0 right-0 bg-background';\nconst SAFE_AREA_CLASS = 'pb-[env(safe-area-inset-bottom)]';\n\nexport function PaywallStickyFooter({\n children,\n className,\n safeAreaInsets = true,\n}: PaywallStickyFooterProps) {\n const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className]\n .filter(Boolean)\n .join(' ');\n return <div className={classes}>{children}</div>;\n}\n","/**\n * Plan-V — turnkey default PixWaitingPage. Renders the QR + polls subscription\n * status via SDK until status flips to active/trialing (webhook landed) or\n * the page times out.\n *\n * Reads QR payload from sessionStorage[`hook:paywall:pix-pending`] written by\n * CheckoutPageDefault. If missing, redirects to /paywall/checkout.\n */\nimport { useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useHook } from '@hook-sdk/sdk';\n\nconst PIX_PAYLOAD_KEY = 'hook:paywall:pix-pending';\nconst TIMEOUT_MS = 30 * 60 * 1000; // 30 min.\n\ntype PixPayload = {\n payload: string | null;\n base64: string | null;\n subscriptionId: string;\n pixAuthorizationId: string | null;\n};\n\nfunction readPixPayload(): PixPayload | null {\n if (typeof window === 'undefined') return null;\n try {\n const raw = sessionStorage.getItem(PIX_PAYLOAD_KEY);\n if (!raw) return null;\n return JSON.parse(raw) as PixPayload;\n } catch {\n return null;\n }\n}\n\nfunction clearPixPayload() {\n if (typeof window === 'undefined') return;\n try { sessionStorage.removeItem(PIX_PAYLOAD_KEY); } catch { /* */ }\n}\n\nexport function PixWaitingPageDefault() {\n const navigate = useNavigate();\n const { subscription } = useHook();\n const payload = useMemo(readPixPayload, []);\n const [copied, setCopied] = useState(false);\n const [timedOut, setTimedOut] = useState(false);\n\n // Missing payload → bounce back to checkout.\n useEffect(() => {\n if (!payload) navigate('/paywall/checkout', { replace: true });\n }, [payload, navigate]);\n\n // Land at the top — the checkout form may have been scrolled down when the\n // user hit submit, and we navigate here without resetting scroll.\n useEffect(() => {\n window.scrollTo(0, 0);\n }, []);\n\n // 30-min timeout.\n useEffect(() => {\n const t = setTimeout(() => setTimedOut(true), TIMEOUT_MS);\n return () => clearTimeout(t);\n }, []);\n\n // Watch subscription state. The `useSubscription` hook re-fetches via SDK;\n // if it polls or has SSE, we'll see status flip automatically.\n const hasAccess = subscription.hasAccess;\n useEffect(() => {\n if (hasAccess) {\n clearPixPayload();\n navigate('/', { replace: true });\n }\n }, [hasAccess, navigate]);\n\n async function copyPayload() {\n if (!payload?.payload) return;\n try {\n await navigator.clipboard.writeText(payload.payload);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n /* clipboard denied — keep going */\n }\n }\n\n if (!payload) return null;\n\n if (timedOut) {\n return (\n <div className=\"flex-1 flex flex-col items-center justify-center px-6 py-10 text-center bg-background space-y-4\">\n <h1 className=\"font-display text-2xl text-foreground\">PIX expirado</h1>\n <p className=\"text-sm text-muted-foreground\">O tempo pra pagar acabou. Gere um novo PIX.</p>\n <button\n onClick={() => {\n clearPixPayload();\n navigate('/paywall/checkout', { replace: true });\n }}\n className=\"rounded-xl bg-primary px-6 py-3 text-base font-semibold text-primary-foreground\"\n >\n Tentar novamente\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 flex flex-col items-center px-6 py-8 bg-background space-y-6\">\n <header className=\"text-center space-y-2\">\n <h1 className=\"font-display text-2xl text-foreground\">Pague o PIX</h1>\n <p className=\"text-sm text-muted-foreground\">\n Escaneie o QR Code no app do seu banco. O acesso libera assim que confirmarmos o pagamento.\n </p>\n </header>\n\n {payload.base64 ? (\n <img\n src={`data:image/png;base64,${payload.base64}`}\n alt=\"QR Code PIX\"\n className=\"w-64 h-64 rounded-2xl border border-border bg-card p-2\"\n />\n ) : (\n <div className=\"w-64 h-64 rounded-2xl border border-border bg-card flex items-center justify-center text-sm text-muted-foreground\">\n QR indisponível\n </div>\n )}\n\n {payload.payload ? (\n <button\n onClick={copyPayload}\n className=\"w-full max-w-xs rounded-xl border border-border bg-card px-4 py-3 text-sm font-medium text-foreground\"\n >\n {copied ? '✓ Copiado!' : 'Copiar código PIX'}\n </button>\n ) : null}\n\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <span className=\"inline-block w-2 h-2 rounded-full bg-primary animate-pulse\" />\n Aguardando pagamento…\n </div>\n\n <p className=\"text-center text-xs text-muted-foreground\">\n Pode fechar essa janela — também enviamos um link de acesso pro seu e-mail.\n </p>\n </div>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseLoginFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markEmailTouched: () => void;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markPasswordTouched: () => void;\n /** True after the user has attempted submit at least once. */\n formSubmitAttempted: boolean;\n /**\n * Submete o form. Retorna true se o login deu OK (cookies setados), false\n * se validação falhou, credenciais inválidas, rate-limit ou erro de rede.\n * Em caso de false, `error` state é populado com detalhes.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n /**\n * Dispara OAuth Google: redireciona pro backend `/api/auth/oauth/google/start`.\n * Fire-and-forget — a página é descarregada antes de qualquer retorno.\n * Volta pro app logado (ou com `?oauth_error=...` em falha).\n */\n loginWithGoogle: () => void;\n}\n\nexport function useLoginForm(): UseLoginFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const [touchedEmail, setTouchedEmail] = useState(false);\n const [touchedPassword, setTouchedPassword] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n const validateEmail = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const validatePassword = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;\n const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;\n\n const canSubmit =\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n validateEmail === null &&\n validatePassword === null &&\n !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n setFormSubmitAttempted(true);\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.login({ email, password });\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, password, canSubmit]);\n\n return {\n email, setEmail, emailError,\n markEmailTouched: () => setTouchedEmail(true),\n password, setPassword, passwordError,\n markPasswordTouched: () => setTouchedPassword(true),\n formSubmitAttempted,\n submit, submitting, canSubmit, error,\n loginWithGoogle: () => auth.loginWithGoogle(),\n };\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseSignupFormResult {\n name: string;\n setName: (v: string) => void;\n nameError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markNameTouched: () => void;\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markEmailTouched: () => void;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markPasswordTouched: () => void;\n /** True after the user has attempted submit at least once. */\n formSubmitAttempted: boolean;\n /**\n * Submete o form. Retorna true se o signup deu OK (backend respondeu 2xx),\n * false se validação falhou, houve erro de rede/servidor, ou email já em uso.\n * Em caso de false, `error` state é populado com detalhes.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n /**\n * Dispara OAuth Google: mesmo endpoint que `useLoginForm.loginWithGoogle`.\n * Backend decide entre `signup_new`, `auto_linked`, ou `login_existing`\n * via `linkPolicy` — do ponto de vista do usuário \"criar conta com Google\"\n * e \"entrar com Google\" são o mesmo botão.\n */\n loginWithGoogle: () => void;\n}\n\nexport function useSignupForm(): UseSignupFormResult {\n const { auth } = useHook();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n // Wave 5 #42: per-field touched + formSubmitAttempted gate inline error\n // visibility so the user does not see \"invalid email\" on the first\n // keystroke. Errors only appear after blur OR after the first submit.\n const [touchedName, setTouchedName] = useState(false);\n const [touchedEmail, setTouchedEmail] = useState(false);\n const [touchedPassword, setTouchedPassword] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n const validateName = useMemo(() => {\n if (name.length === 0) return null;\n if (name.trim().length < 2) return 'Nome muito curto.';\n return null;\n }, [name]);\n\n const validateEmail = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const validatePassword = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const nameError = touchedName || formSubmitAttempted ? validateName : null;\n const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;\n const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;\n\n const canSubmit =\n name.trim().length >= 2 &&\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n validateName === null &&\n validateEmail === null &&\n validatePassword === null &&\n !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n setFormSubmitAttempted(true);\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.signup({ name, email, password });\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, name, email, password, canSubmit]);\n\n return {\n name, setName, nameError,\n markNameTouched: () => setTouchedName(true),\n email, setEmail, emailError,\n markEmailTouched: () => setTouchedEmail(true),\n password, setPassword, passwordError,\n markPasswordTouched: () => setTouchedPassword(true),\n formSubmitAttempted,\n submit, submitting, canSubmit, error,\n loginWithGoogle: () => auth.loginWithGoogle(),\n };\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport interface UseForgotFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markEmailTouched: () => void;\n /** True after the user has attempted submit at least once. */\n formSubmitAttempted: boolean;\n /**\n * Submete o form. Retorna true se o backend aceitou a requisição (email\n * de reset foi enfileirado — sem leak de \"existe esse email\" por design),\n * false se validação falhou, rate-limit ou erro de rede.\n * Em caso de sucesso, `sent` state também é setado para true.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n sent: boolean;\n error: AuthFormError | null;\n}\n\nexport function useForgotForm(): UseForgotFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [sent, setSent] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n const [touchedEmail, setTouchedEmail] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n const validateEmail = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;\n const canSubmit = email.length > 0 && validateEmail === null && !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n setFormSubmitAttempted(true);\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.forgot({ email });\n setSent(true);\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, canSubmit]);\n\n return {\n email, setEmail, emailError,\n markEmailTouched: () => setTouchedEmail(true),\n formSubmitAttempted,\n submit, submitting, canSubmit, sent, error,\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst MIN_PASSWORD = 8;\n\nexport interface UseResetFormResult {\n /** Token JWT lido de `?token=` da URL. null se ausente. */\n token: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markPasswordTouched: () => void;\n confirm: string;\n setConfirm: (v: string) => void;\n confirmError: string | null;\n /** Wave 5 #42: call on input blur so the error becomes visible. */\n markConfirmTouched: () => void;\n /** True after the user has attempted submit at least once. */\n formSubmitAttempted: boolean;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n /** true após submit 200. UI deve mostrar \"senha alterada, volte pro login\". */\n done: boolean;\n error: AuthFormError | null;\n}\n\n/**\n * Hook headless pro fluxo de reset de senha via link do email.\n *\n * Lê `?token=` da URL atual automaticamente (readonly snapshot no mount).\n * Se token ausente, `canSubmit` fica false + `token: null` pra UI mostrar\n * mensagem \"link inválido\".\n *\n * Após submit 200, todos os refresh tokens do user são revogados pelo\n * backend (forçar re-login). UI deve direcionar pra LoginScreen.\n */\nexport function useResetForm(): UseResetFormResult {\n const { auth } = useHook();\n const [token, setToken] = useState<string | null>(null);\n const [password, setPassword] = useState('');\n const [confirm, setConfirm] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [done, setDone] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const [touchedPassword, setTouchedPassword] = useState(false);\n const [touchedConfirm, setTouchedConfirm] = useState(false);\n const [formSubmitAttempted, setFormSubmitAttempted] = useState(false);\n\n useEffect(() => {\n // Snapshot no mount. URL pode ter sido limpa depois (history.replaceState)\n // mas token deve estar no primeiro render.\n if (typeof window === 'undefined') return;\n const params = new URLSearchParams(window.location.search);\n const t = params.get('token');\n setToken(t && t.length > 0 ? t : null);\n }, []);\n\n const validatePassword = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const validateConfirm = useMemo(() => {\n if (confirm.length === 0) return null;\n if (confirm !== password) return 'Senhas não coincidem.';\n return null;\n }, [confirm, password]);\n\n const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;\n const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;\n\n const canSubmit =\n token !== null &&\n password.length >= MIN_PASSWORD &&\n confirm === password &&\n validatePassword === null &&\n validateConfirm === null &&\n !submitting &&\n !done;\n\n const submit = useCallback(async () => {\n setFormSubmitAttempted(true);\n if (!canSubmit || token === null) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.reset({ token, newPassword: password });\n setDone(true);\n // Limpa `?token=&screen=reset` da URL pra AuthGate não re-disparar Reset\n // em re-renders futuros (logout depois do reset, popstate, etc.).\n // Mantém mesmo path, só strip dos query params de auth.\n if (typeof window !== 'undefined') {\n const url = new URL(window.location.href);\n url.searchParams.delete('token');\n url.searchParams.delete('screen');\n window.history.replaceState({}, '', url.toString());\n }\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, token, password, canSubmit]);\n\n return {\n token,\n password, setPassword, passwordError,\n markPasswordTouched: () => setTouchedPassword(true),\n confirm, setConfirm, confirmError,\n markConfirmTouched: () => setTouchedConfirm(true),\n formSubmitAttempted,\n submit, submitting, canSubmit, done, error,\n };\n}\n","import { useEffect } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nlet warned = false;\n\n/** Test-only: reseta flag pra permitir validar warn uma única vez em re-mounts de test */\nexport function __resetWarnForTest() { warned = false; }\n\n/**\n * Escape hatch pra screens FORA do fluxo de auth (ex: settings/trocar-senha).\n * Pra LoginScreen/SignupScreen/ForgotScreen custom, use useLoginForm/useSignupForm/useForgotForm.\n */\nexport function useAuthPrimitives() {\n const { auth } = useHook();\n\n useEffect(() => {\n if (!warned && process.env.NODE_ENV !== 'production') {\n warned = true;\n console.warn(\n '[@hook-sdk/template] useAuthPrimitives() é escape hatch. ' +\n 'Pra login/signup/forgot, use useLoginForm/useSignupForm/useForgotForm. ' +\n 'Docs: docs/19-golden-template.md#escape-hatch',\n );\n }\n }, []);\n\n return {\n login: auth.login,\n signup: auth.signup,\n logout: auth.logout,\n logoutAll: auth.logoutAll,\n forgot: auth.forgot,\n resendVerify: auth.resendVerify,\n changePassword: auth.changePassword,\n changeEmail: auth.changeEmail,\n refresh: auth.refresh,\n };\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre useHook(). Expõe apenas `user`, `authStatus` e `refresh`\n * pros consumidores que não precisam das methods completas do auth.\n */\nexport function useAuth() {\n const { user, authStatus, auth } = useHook();\n return {\n user,\n authStatus,\n refresh: auth.refresh,\n };\n}\n","// Entry point\nexport {\n AppRoot,\n PaymentReturnHandler,\n type AppRootProps,\n type AppRootSlots,\n type AuthScreenProps,\n type SkipDefaults,\n} from './AppRoot';\n\n// Dev-only — staging skip-onboarding helpers. The component is tree-shaken\n// from prod builds via the build-time `VITE_HOOK_DEV_TOOLS` env gate (see\n// `dev/env.ts`). Exposed for advanced consumers that want to mount the FAB\n// outside of AppRoot or call `skipOnboarding` programmatically from tests.\nexport {\n DevSkipOnboardingFab,\n skipOnboarding,\n} from './dev/DevSkipOnboardingFab';\nexport { isDevToolsEnabled } from './dev/env';\n\n// Components\nexport { PushPrompt, type PushPromptProps, type PushPromptTexts } from './components/PushPrompt';\nexport { InstallGate, InstallSplash } from './components/InstallGate';\nexport { LanguageSwitcher, type LanguageSwitcherProps } from './components/LanguageSwitcher';\n\n// i18n\nexport { I18nProvider, type I18nProviderProps } from './i18n/I18nProvider';\n\n// State helpers\nexport { LoadingState } from './defaults/LoadingState';\nexport { EmptyState } from './defaults/EmptyState';\nexport { ErrorBoundary } from './defaults/ErrorBoundary';\n\n// Plan-V — pay-first signup default screens.\nexport { CheckoutPageDefault } from './defaults/CheckoutPageDefault';\nexport { PixWaitingPageDefault } from './defaults/PixWaitingPageDefault';\n\n// DeepLinkHandler — usually mounted by <AppRoot> but exported for advanced use.\nexport { DeepLinkHandler } from './DeepLinkHandler';\n\n// Hooks padrão\nexport { useLoginForm, type UseLoginFormResult } from './hooks/useLoginForm';\nexport { useSignupForm } from './hooks/useSignupForm';\nexport { useForgotForm } from './hooks/useForgotForm';\nexport { useResetForm, type UseResetFormResult } from './hooks/useResetForm';\nexport {\n useCheckoutForm,\n type UseCheckoutFormResult,\n type UseCheckoutFormArgs,\n type CheckoutCardInput,\n type CheckoutFormCycle,\n type CheckoutFormMethod,\n} from './hooks/useCheckoutForm';\nexport {\n usePaywallState,\n type SubscriptionStatus,\n type PaymentMethod,\n type PixPending,\n} from './hooks/usePaywallState';\nexport { usePlan, type PlanInfo, type PlanState } from './hooks/usePlan';\n\n// Price helpers — use junto com usePlan() pra não hardcodar R$ em screens.\n// Ver G72 em .claude/skills/hook-conversion-shared/catalog/known-gotchas.md.\nexport {\n formatBRL,\n monthlyFromYearly,\n dailyFromYearly,\n computeAnchorCents,\n discountPercent,\n} from './utils/price';\n\n// Escape hatch\nexport { useAuthPrimitives } from './hooks/useAuthPrimitives';\n\n// Convenience\nexport { useAuth } from './hooks/useAuth';\n// Re-export from SDK so apps can import everything from @hook-sdk/template.\n// Apps with custom onboarding (Lovable conversions etc — i.e. NOT using the\n// template's <OnboardingFlow>) call this from each screen to feed Studio's\n// \"Onde estão saindo\" dropoff section.\nexport { useTrackOnboardingStep } from '@hook-sdk/sdk';\nexport { useSubscription } from './hooks/useSubscription';\nexport { usePush } from './hooks/usePush';\nexport { useReminders } from './hooks/useReminders';\nexport { useToast, type ToastItem } from './hooks/useToast';\nexport {\n useInstallPrompt,\n shouldBlockInstall,\n shouldShowPermanentOption,\n detectPlatform,\n detectIOSBrowser,\n detectAndroidBrowser,\n detectInAppApp,\n detectStandalone,\n type Platform,\n type IOSBrowser,\n type AndroidBrowser,\n type InAppApp,\n type InstallVariant,\n type InstallState,\n type InstallActions,\n} from './hooks/useInstallPrompt';\n\n// Types\nexport type { AuthFormError, AuthFormErrorCode } from './errors';\n\n// PT-BR error code → user message map (Asaas-driven). Used internally by\n// usePaywallState when paywall.errorMessages === 'default'; exported for\n// apps composing their own error UX.\nexport { asaasErrorMessage } from './errors/asaas-pt-br';\n\n// R2-W3 primitives\nexport { RouteBoundary, type RouteBoundaryProps } from './RouteBoundary';\nexport { PreAuthShell, type PreAuthShellProps } from './PreAuthShell';\nexport { PersistenceRegistry, type PersistenceRegistryProps } from './PersistenceRegistry';\nexport {\n OnboardingFlow,\n type OnboardingFlowProps,\n type OnboardingStepDef,\n} from './OnboardingFlow';\nexport { useOnboardingStep, type OnboardingStepCtx } from './hooks/useOnboardingStep';\nexport { useFeature } from './hooks/useFeature';\nexport { AppConfigProvider, useAppConfig } from './config/AppConfigContext';\nexport { parseAppConfig, AppConfigSchema } from './config/schema';\n\n// AppConfig (R2-W3 — declarative spine)\nexport type {\n AppConfig,\n AuthFlowConfig,\n PaywallConfig,\n PersistedKey,\n OnboardingConfig,\n OnboardingStep,\n DeepLinks,\n I18nConfig,\n Cycle,\n CheckoutMethod,\n} from './types/AppConfig';\nexport type { PushUiState } from './hooks/usePush';\n\n// Paywall composed component + primitives + Lego blocks (template 0.24 — flexibility-max).\n// Three customization levels (see CHANGELOG 0.24.0):\n// L1: <Paywall> opinionated default (back-compat 0.23.x).\n// L2: <PaywallProvider> + Lego blocks (compose per-app layout).\n// L3: <PaywallProvider> + usePaywallContext() (write 100% custom JSX).\nexport {\n // Composed top-level (Level 1).\n Paywall,\n // Headless state plumbing (Level 2 + Level 3).\n PaywallProvider,\n PaywallContext,\n usePaywallContext,\n // Refactored primitives (read state via context).\n PaywallMethodTabs,\n PaywallMethodContent,\n PaywallCyclePicker,\n PaywallCta,\n // Lego blocks (14 new in 0.24.0).\n PaywallEyebrow,\n PaywallHero,\n PaywallHeadline,\n PaywallPriceHeadline,\n PaywallCountdown,\n PaywallFeatures,\n PaywallFeaturesCard,\n PaywallTrophyBadge,\n PaywallAnchorPrice,\n PaywallTestimonials,\n PaywallStatsRow,\n PaywallFinePrint,\n PaywallTrustLine,\n PaywallStickyFooter,\n // Types.\n type PaywallProps,\n type PaywallCopy,\n type PaywallMethodCopy,\n type PaywallThemeClasses,\n type PaywallSlots,\n type PaywallContextValue,\n type PaywallProviderProps,\n type PaywallMethodTabsProps,\n type PaywallMethodContentProps,\n type PaywallCyclePickerProps,\n type PaywallCtaProps,\n type PaywallEyebrowProps,\n type PaywallHeroProps,\n type PaywallHeadlineProps,\n type PaywallPriceHeadlineProps,\n type PaywallCountdownProps,\n type PaywallFeaturesProps,\n type PaywallFeaturesCardProps,\n type PaywallTrophyBadgeProps,\n type PaywallAnchorPriceProps,\n type PaywallTestimonialsProps,\n type PaywallTestimonial,\n type PaywallStatsRowProps,\n type PaywallStat,\n type PaywallFinePrintProps,\n type PaywallTrustLineProps,\n type PaywallStickyFooterProps,\n type CycleLabels,\n} from './components/paywall';\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre `subscription` do SDK. MVP: apenas status (stub retorna 'none').\n */\nexport function useSubscription() {\n const { subscription } = useHook();\n return {\n status: subscription.status(),\n };\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type { ReminderSlot } from '@hook-sdk/sdk';\n\nexport function useReminders() {\n const { push } = useHook();\n const r = push.reminders;\n const [reminders, setReminders] = useState<ReminderSlot[]>([]);\n const [loading, setLoading] = useState(true);\n\n const reload = useCallback(async () => {\n setLoading(true);\n try {\n const next = await r.list();\n setReminders(next);\n } finally {\n setLoading(false);\n }\n }, [r]);\n\n useEffect(() => { void reload(); }, [reload]);\n\n const setReminder = useCallback(async (input: {\n slot: string; timeLocal: string; timezone: string; enabled: boolean;\n }) => {\n await r.set(input);\n await reload();\n }, [r, reload]);\n\n const deleteReminder = useCallback(async (slot: string) => {\n await r.delete(slot);\n await reload();\n }, [r, reload]);\n\n const schedule = useCallback(async (items: Parameters<typeof r.schedule>[0]) => {\n return r.schedule(items);\n }, [r]);\n\n const setFallbacks = useCallback(async (items: Parameters<typeof r.setFallbacks>[0]) => {\n return r.setFallbacks(items);\n }, [r]);\n\n return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };\n}\n","import { useCallback, useState } from 'react';\n\nexport interface ToastItem {\n id: string;\n message: string;\n kind: 'info' | 'error' | 'success';\n}\n\n/**\n * Toast mínimo in-memory. MVP: IA renderiza a lista onde quiser (ex: no final do <Home>).\n * Não opina sobre UI; retorna items + actions.\n */\nexport function useToast() {\n const [items, setItems] = useState<ToastItem[]>([]);\n\n const show = useCallback((message: string, kind: ToastItem['kind'] = 'info') => {\n const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n setItems((prev) => [...prev, { id, message, kind }]);\n setTimeout(() => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, 4000);\n }, []);\n\n const dismiss = useCallback((id: string) => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return { items, show, dismiss };\n}\n","import type { ReactNode } from 'react';\nimport { Routes, Route } from 'react-router-dom';\n\nexport type RouteBoundaryProps = { children: ReactNode };\n\nexport function RouteBoundary({ children }: RouteBoundaryProps) {\n return (\n <Routes>\n {children}\n <Route path=\"*\" element={<DefaultNotFound />} />\n </Routes>\n );\n}\n\nfunction DefaultNotFound() {\n return <div role=\"alert\">Página não encontrada</div>;\n}\n","import type { ReactNode } from 'react';\nimport { BrowserRouter, MemoryRouter, Routes } from 'react-router-dom';\n\nexport type PreAuthShellProps = {\n basename?: string;\n /** Test-only escape hatch — use MemoryRouter so jsdom doesn't fight document.location. */\n testRouter?: 'memory';\n /** Optional initial entries for MemoryRouter; ignored otherwise. */\n testInitialEntries?: string[];\n children: ReactNode;\n};\n\nexport function PreAuthShell({\n basename,\n testRouter,\n testInitialEntries,\n children,\n}: PreAuthShellProps) {\n if (testRouter === 'memory') {\n return (\n <MemoryRouter basename={basename} initialEntries={testInitialEntries}>\n <Routes>{children}</Routes>\n </MemoryRouter>\n );\n }\n return (\n <BrowserRouter basename={basename}>\n <Routes>{children}</Routes>\n </BrowserRouter>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, type ComponentType } from 'react';\nimport { usePersistedState, useHook } from '@hook-sdk/sdk';\nimport { OnboardingStepContext } from './hooks/useOnboardingStep';\n\nexport type OnboardingStepDef = {\n id: string;\n screen: string;\n validates?: string[];\n};\n\nexport type OnboardingFlowProps = {\n steps: OnboardingStepDef[];\n screens: Record<string, ComponentType>;\n onComplete: (value: Record<string, unknown>) => void;\n persistKey: string;\n};\n\nconst isFilled = (v: unknown): boolean => v != null && v !== '';\n\nconst CURRENT_STEP_FIELD = 'currentStep';\n\nfunction readPersistedStepIdx(draft: Record<string, unknown>): number {\n const raw = draft[CURRENT_STEP_FIELD];\n return typeof raw === 'number' && Number.isFinite(raw) && raw >= 0 ? raw : 0;\n}\n\nexport function OnboardingFlow({\n steps,\n screens,\n onComplete,\n persistKey,\n}: OnboardingFlowProps) {\n // Audit Wave 2 (Fix #3): currentStep mora dentro do mesmo blob de\n // `persistKey` (default `onboarding_data`). Cold-start re-mount hidrata\n // currentStep e renderiza no step certo em vez de cair em step 0.\n const [draft, setDraft, status] = usePersistedState<Record<string, unknown>>(persistKey, {});\n const draftRef = useRef(draft);\n draftRef.current = draft;\n\n const idx = readPersistedStepIdx(draft);\n const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));\n\n const setIdx = useCallback(\n (n: number | ((prev: number) => number)) => {\n setDraft((prev) => {\n const prevIdx = readPersistedStepIdx(prev);\n const nextIdx = typeof n === 'function' ? n(prevIdx) : n;\n return { ...prev, [CURRENT_STEP_FIELD]: nextIdx };\n });\n },\n [setDraft],\n );\n\n const setValue = useCallback(\n (patch: Record<string, unknown>) => {\n // Mirror to ref so a `next()` in the same handler sees the new value\n // before React commits the state update.\n draftRef.current = { ...draftRef.current, ...patch };\n setDraft((prev) => ({ ...prev, ...patch }));\n },\n [setDraft],\n );\n\n // step lookup (NOT a hook). Run before useMemo for `valid` to use it.\n const step = steps[clampedIdx];\n\n // Analytics: emit `onboarding_step_viewed` whenever the rendered step changes.\n // Fire-and-forget via SDK track(). `step.id` is app-defined (free string from\n // app.config.json) — Studio dropoff query buckets by `properties.step` to\n // surface where users abandon onboarding pre-trial. Hydration is gated below\n // (status.loading), so this only fires after persisted state is ready.\n // Defensive: legacy test mocks may not expose `track`. Treat missing as no-op.\n const hookCtx = useHook() as ReturnType<typeof useHook> & {\n track?: (event: string, props?: Record<string, unknown>) => void;\n };\n const track = typeof hookCtx.track === 'function' ? hookCtx.track : undefined;\n useEffect(() => {\n if (status.loading) return;\n if (!step) return;\n if (!track) return;\n track('onboarding_step_viewed', {\n step: step.id,\n step_index: clampedIdx,\n total_steps: steps.length,\n });\n }, [step?.id, clampedIdx, steps.length, status.loading, track]);\n\n const valid = useMemo(\n () => (step ? (step.validates ?? []).every((field) => isFilled(draft[field])) : false),\n [draft, step],\n );\n\n const next = useCallback(() => {\n if (!step) return;\n const current = draftRef.current;\n const validNow = (step.validates ?? []).every((field) => isFilled(current[field]));\n if (!validNow) return;\n if (clampedIdx + 1 >= steps.length) {\n onComplete(current);\n } else {\n setIdx(clampedIdx + 1);\n }\n }, [clampedIdx, onComplete, step, steps.length, setIdx]);\n\n const prevStep = useCallback(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);\n\n const ctx = useMemo(\n () => ({\n stepIndex: clampedIdx,\n totalSteps: steps.length,\n value: draft,\n setValue,\n valid,\n next,\n prev: prevStep,\n }),\n [clampedIdx, steps.length, draft, setValue, valid, next, prevStep],\n );\n\n // Audit Wave 2 (Fix #3): block render durante hydration pra evitar\n // flicker step-0 → step-N. Coloca DEPOIS dos hooks (rules-of-hooks:\n // todo hook chamado em toda renderização, mesmo as que retornam null).\n if (status.loading) {\n return null;\n }\n\n if (!step) {\n throw new Error(\n `[hook-template] OnboardingFlow: step index ${clampedIdx} out of range (steps.length=${steps.length})`,\n );\n }\n const Screen = screens[step.screen];\n if (!Screen) {\n throw new Error(\n `[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`,\n );\n }\n\n return (\n <OnboardingStepContext.Provider value={ctx}>\n <Screen />\n </OnboardingStepContext.Provider>\n );\n}\n","import { createContext, useContext } from 'react';\n\nexport type OnboardingStepCtx = {\n stepIndex: number;\n totalSteps: number;\n next: () => void;\n prev: () => void;\n value: Record<string, unknown>;\n setValue: (patch: Record<string, unknown>) => void;\n valid: boolean;\n};\n\nexport const OnboardingStepContext = createContext<OnboardingStepCtx | null>(null);\n\nexport function useOnboardingStep(): OnboardingStepCtx {\n const ctx = useContext(OnboardingStepContext);\n if (!ctx) {\n throw new Error(\n '[hook-template] useOnboardingStep must be used inside <OnboardingFlow>. (G75)',\n );\n }\n return ctx;\n}\n","import { useAppConfig } from '../config/AppConfigContext';\n\n/**\n * Returns `true` when `app.config.json.features_enabled` includes `name`.\n * Use to gate optional UI surfaces (e.g. share button, premium-only screens)\n * without scattering the feature list across the codebase.\n */\nexport function useFeature(name: string): boolean {\n const config = useAppConfig();\n return Array.isArray(config.features_enabled) && config.features_enabled.includes(name);\n}\n"],"mappings":"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","names":["useMemo","useHook","jsx","useEffect","createContext","useContext","jsx","jsx","useContext","useMemo","useHook","useEffect","useHook","track","track","useHook","useContext","useMemo","result","Fragment","jsx","Paywall","useEffect","useRef","useCallback","useEffect","useState","jsx","jsx","jsxs","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","Step","jsx","jsxs","Step","jsx","jsxs","Step","useState","jsx","jsxs","useState","Step","jsx","jsxs","Fragment","jsx","jsxs","useRef","useEffect","useEffect","useRef","useState","useHook","jsx","jsxs","useState","useHook","jsx","jsxs","Fragment","jsx","jsxs","useEffect","jsx","useCallback","useRef","useState","useHook","usePersistedState","jsx","useHook","useState","useRef","usePersistedState","useCallback","useCallback","useEffect","useRef","useState","useHook","Fragment","jsx","jsxs","track","overlayStyle","Fragment","jsx","jsxs","Paywall","useMemo","useHook","useCallback","useEffect","useState","useHook","DISMISS_TTL_MS","jsx","jsxs","PushPrompt","usePersistedState","jsx","jsxs","usePersistedState","jsx","jsx","jsxs","useEffect","useMemo","useState","useNavigate","useCallback","useEffect","useMemo","useRef","useState","useHook","useHook","useState","useCallback","useRef","useEffect","useMemo","useHook","useEffect","useMemo","useHook","createContext","jsx","createContext","useContext","useContext","jsx","jsx","jsx","jsxs","jsx","jsxs","track","useHook","useMemo","useEffect","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","RootTag","useEffect","useRef","useState","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","DEFAULT_CLASS","jsx","jsxs","jsx","jsxs","DEFAULT_ROOT","jsx","DEFAULT_CLASS","CYCLE_LABEL","jsx","jsxs","DEFAULT_ROOT","jsx","Fragment","jsx","jsxs","useNavigate","useMemo","useState","useEffect","trialDays","Spinner","useEffect","useMemo","useState","useNavigate","useHook","jsx","jsxs","PIX_PAYLOAD_KEY","useCallback","useMemo","useState","useHook","EMAIL_RE","useHook","useState","useMemo","useCallback","useCallback","useMemo","useState","useHook","EMAIL_RE","MIN_PASSWORD","useHook","useState","useMemo","useCallback","useCallback","useMemo","useState","useHook","EMAIL_RE","useHook","useState","useMemo","useCallback","useCallback","useEffect","useMemo","useState","useHook","MIN_PASSWORD","useHook","useState","useEffect","useMemo","useCallback","useEffect","useHook","useHook","useEffect","useHook","useHook","useCallback","useEffect","useState","useHook","useCallback","useState","Routes","Route","jsx","jsxs","BrowserRouter","MemoryRouter","Routes","jsx","useCallback","useEffect","useMemo","useRef","usePersistedState","useHook","createContext","useContext","jsx","usePersistedState","useRef","useCallback","useHook","track","useEffect","useMemo"]}
|