plans/promo-message-improvements.md
promo_click PostHog event (with messageId), exempted from the non-Pro 10% sampling in shouldBypassNonProTelemetrySampling — promos only show to non-Pro users, so sampling would have dropped 90% of clicks.DyadProTrialDialog (no browser context switch); the dialog now takes a utmCampaign prop so checkout/learn-more traffic is attributed per message (streaming-promo-<messageId>).isStreaming to non-Pro users (!settings?.enableDyadPro && !userBudget), then disappears the moment the stream ends — exactly when the user's attention returns to the chat.bg-blue-50 text-blue-700, no dark-mode variants (looks broken/harsh in dark theme, which most devs use).utm_campaign). We can't measure CTR or conversion per message.trialCode=7PRO30, used by DyadProTrialDialog/SetupBanner) that none of these messages mention.promo_impression / promo_click events with a stable messageId.utm_campaign (e.g. utm_campaign=streaming-promo-turbo-edits).DyadProTrialDialog (no context switch, stream keeps going).https://www.dyad.sh/pro?utm_... — consideration page, low bounce.https://academy.dyad.sh/redirect-to-checkout?trialCode=7PRO30&utm_... — same pattern the app already uses. Prefer this over hardcoding /sign-in?redirect_url=...: the redirect endpoint owns the auth flow (survives auth changes) and carries the trial code.DyadProTrialDialog, which offers "Start Free Trial" (checkout) and "Learn more" (/pro). Warm the user before the sign-in wall.