@hook-sdk/template 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +36 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +36 -31
- 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/defaults/ErrorBoundary.tsx","../src/i18n/I18nProvider.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/hooks/useLoginForm.ts","../src/errors.ts","../src/hooks/useSignupForm.ts","../src/hooks/useForgotForm.ts","../src/hooks/useResetForm.ts","../src/hooks/usePlan.ts","../src/utils/price.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 { 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';\n\nexport type { AuthScreenProps };\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\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 } = 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 {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 </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 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});\n\nconst PaywallNonFreeSchema = z.object({\n mode: z.enum(['trial', 'pay_first']),\n trialDays: z.number().int().nonnegative().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` no-op (SDK polling auto-clears pixPending on settle)\n * - `monthlyEquivalent(cycle)` helper\n */\nexport function usePaywallState() {\n const { subscription, plan } = 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 const defaultMethod: CheckoutMethod = methods[0] ?? declaredMethods[0] ?? '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 const initialCycle: CheckoutCycle = isFree\n ? 'MONTHLY'\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 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 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 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 }, [selectedMethod, availability, subscription, cycle, cpf, card, buildError]);\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 // 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 dismissPix: () => {},\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","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","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 } = useHook();\n const subRef = useRef(subscription);\n subRef.current = subscription;\n const runIdRef = useRef(0);\n const cyclesRef = useRef(0);\n const [state, setState] = useState<ReturnState>('idle');\n\n const runPoll = useCallback(() => {\n const runId = ++runIdRef.current;\n cyclesRef.current += 1;\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 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 // Cycle exhausted. After MAX_CYCLES, escalate to timeout state.\n if (cyclesRef.current >= MAX_CYCLES) {\n setState('timeout');\n } else {\n setState('waiting');\n }\n return;\n }\n setTimeout(tick, delay);\n };\n void tick();\n }, []);\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';\nimport { detectPlatform } from '../hooks/useInstallPrompt';\n\nexport interface PushPromptTexts {\n cta: string;\n declineCta: string;\n iosInstallTitle: string;\n iosInstallBody: string;\n iosInstallCta?: string;\n deniedTitle: string;\n deniedBody: string;\n /**\n * Audit Wave 3 — Fix #33: per-platform recovery copy shown when permission\n * is denied. All four are optional; if the matching platform's copy is\n * missing the recovery paragraph is omitted (back-compat for callers that\n * haven't supplied them yet).\n */\n deniedRecoveryIos?: string;\n deniedRecoveryAndroid?: string;\n deniedRecoveryDesktop?: string;\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\nfunction platformRecoveryCopy(texts: PushPromptTexts): string | null {\n if (typeof navigator === 'undefined') return null;\n const ua = navigator.userAgent || '';\n const platform = detectPlatform(ua);\n switch (platform) {\n case 'ios-safari':\n case 'ios-other':\n return texts.deniedRecoveryIos ?? null;\n case 'android':\n return texts.deniedRecoveryAndroid ?? null;\n case 'desktop':\n return texts.deniedRecoveryDesktop ?? null;\n case 'in-app':\n return texts.deniedRecoveryInApp ?? null;\n default:\n return null;\n }\n}\n\nexport function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequested, className }: PushPromptProps) {\n const { state, subscribe } = usePush();\n\n // Audit Wave 3 — Fix #32. `dismissed` collapses to nothing so the prompt\n // doesn't re-render after the user clicked \"Agora não\". TTL is 7d (handled\n // in usePush). `subscribed` always hides too.\n if (state.kind === 'subscribed' || state.kind === 'dismissed') return null;\n\n if (state.kind === 'ios_needs_install') {\n return (\n <div className={className} role=\"region\" aria-label={texts.iosInstallTitle}>\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 === 'denied') {\n const recovery = platformRecoveryCopy(texts);\n return (\n <div className={className} role=\"region\" aria-label={texts.deniedTitle}>\n <h3>{texts.deniedTitle}</h3>\n <p>{texts.deniedBody}</p>\n {recovery && <p data-testid=\"denied-recovery\">{recovery}</p>}\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","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 { SdkError, SdkAuthError, SdkRateLimitError } from '@hook-sdk/sdk';\n\nexport type AuthFormErrorCode =\n | 'invalid_credentials'\n | 'rate_limited'\n | 'email_unverified'\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 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 { 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 = 12;\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 { 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","/**\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","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} from './AppRoot';\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// 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 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","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","useHook","useContext","useMemo","result","Fragment","jsx","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","Fragment","jsx","jsxs","useEffect","jsx","useCallback","useEffect","useRef","useState","useHook","Fragment","jsx","jsxs","overlayStyle","Fragment","jsx","jsxs","useMemo","useHook","useCallback","useEffect","useState","useHook","DISMISS_TTL_MS","jsx","jsxs","PushPrompt","usePersistedState","jsx","jsxs","usePersistedState","jsx","jsx","jsxs","useCallback","useMemo","useState","useHook","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","useHook","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/defaults/ErrorBoundary.tsx","../src/i18n/I18nProvider.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/hooks/useLoginForm.ts","../src/errors.ts","../src/hooks/useSignupForm.ts","../src/hooks/useForgotForm.ts","../src/hooks/useResetForm.ts","../src/hooks/usePlan.ts","../src/utils/price.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 { 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';\n\nexport type { AuthScreenProps };\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\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 } = 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 {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 </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 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});\n\nconst PaywallNonFreeSchema = z.object({\n mode: z.enum(['trial', 'pay_first']),\n trialDays: z.number().int().nonnegative().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` no-op (SDK polling auto-clears pixPending on settle)\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 const defaultMethod: CheckoutMethod = methods[0] ?? declaredMethods[0] ?? '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 const initialCycle: CheckoutCycle = isFree\n ? 'MONTHLY'\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 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 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 // 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 dismissPix: () => {},\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","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","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 <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","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 { SdkError, SdkAuthError, SdkRateLimitError } from '@hook-sdk/sdk';\n\nexport type AuthFormErrorCode =\n | 'invalid_credentials'\n | 'rate_limited'\n | 'email_unverified'\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 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 { 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 = 12;\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 { 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","/**\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","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} from './AppRoot';\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// 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 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","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","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","Fragment","jsx","jsxs","useEffect","jsx","useCallback","useEffect","useRef","useState","useHook","Fragment","jsx","jsxs","track","overlayStyle","Fragment","jsx","jsxs","useMemo","useHook","useCallback","useEffect","useState","useHook","DISMISS_TTL_MS","jsx","jsxs","PushPrompt","usePersistedState","jsx","jsxs","usePersistedState","jsx","jsx","jsxs","useCallback","useMemo","useState","useHook","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","useHook","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"]}
|