Skip to main content

Living Word Lead-Gen Phase 1B — In-Game CTA Surfaces

Canonical spec. Ships immediately after PR #559 (Phase 1A foundation) merges. All copy is verbatim from the founder-approved strategic spec (drafts/2026-05-23-living-word-lead-gen-spec.md) and honors decisions B1/B2/B3 locked 2026-05-23. The contemplative tone of the game is the proof; these CTAs are the credits sequence around that proof, never interruptions of it. Every surface honors the AI Bridge Principle — CTAs are clearly authored-by-the-builders messaging, never voiced by an in-character NPC.

§1. Founder-locked decisions (verbatim)

From drafts/2026-05-23-living-word-founder-decisions.md, STATUS table 2026-05-23. Engineering MUST NOT re-litigate.

#DecisionAnswerRationale
B1Domain routing for /from-living-wordRoute to churchwiseai.com (conversion stays on trust brand)as recommended
B2Early-scene CTA prominenceHide first 2 scenesas recommended
B3Legacy Bloom finale CTA panelKeep the panelas recommended
  • B1. Every CTA in Phase 1B links to the absolute URL https://churchwiseai.com/from-living-word?... even when the player is on livingword.bible. NO mirroring on livingword.bible.
  • B2. Scene-completion bloom card is HIDDEN during the player's first 2 scene completions; first appears at the 3rd. Counter is per-browser localStorage (lw-scene-completions-shown:cta), increments on every completion (including hidden ones), visibility check is counter >= 3.
  • B3. Finale panel ships. Fades in AFTER the existing LegacyBloomCinematic finishes — cinematic itself is NEVER modified, shortened, or interrupted.

§2. Scope

Three in-game surfaces. Each MUST:

  • Log impression + click events to lw_lead_gen_events (Phase 1A migration 2026-05-23c-lw-lead-gen-events.sql).
  • Use trackLeadGenEvent() from src/lib/living-word/lead-gen-client.ts (no direct fetch).
  • Route clicks to https://churchwiseai.com/from-living-word with UTM tags per §8.
  • Be dismissible per-session where applicable (no permanent suppression — Phase 2).
  • NEVER interrupt or block gameplay; appear only at natural completion moments.
  • Honor the AI Bridge Principle — never NPC-voiced, never imply the AI is recommending a purchase.

Out of scope (do NOT build): founder lead-gen dashboard (Phase 1C); A/B copy testing (Phase 2); landing-page segmentation (Phase 2); in-game email capture (anti-goal).

§3. Surface 1 — Scene-completion bloom card

When. Fires when a scene meets all three: (a) gatekeeper enemy defeated, (b) relic collected, (c) reward_giver NPC visited. Today's LivingWordAdventure.tsx signals scene completion via handleReachExit(); the card mounts in whatever scene-completion UI surface engineering chooses (see §13).

Where. INSIDE the scene-completion experience, BELOW the existing "Walk on" CTA. Never above; never replacing. "Walk on" stays primary.

Visibility (Decision B2). Hidden during first 2 scene completions. Pattern:

const completionCount = Number(localStorage.getItem('lw-scene-completions-shown:cta') ?? '0');
const nextCount = completionCount + 1;
localStorage.setItem('lw-scene-completions-shown:cta', String(nextCount));
const showCard = nextCount >= 3 && !dismissedThisSession;

dismissedThisSession lives in component state (NOT localStorage) so the card returns next session.

Card content (verbatim, strategic spec §T2):

Built by ChurchWiseAI

The narrative AI, the in-character dialogue, the lens-aware tutoring — this is the same engine that answers your congregation's questions 24/7 via voice and chatbot.

[See what it does for ministry →]

CTA URL: https://churchwiseai.com/from-living-word?utm_source=living-word&utm_medium=in-game&utm_campaign=scene-completion-v1&scene_id=<active_scene_id> (scene_id is NOT a utm_* param).

Events.

EventWhenMetadata
scene_completion_impressiononce per render where card visible (NOT scenes 1-2)scene_id
scene_completion_clickon CTA clickscene_id

Dismiss. Small × top-right. Hides for rest of session. Returns next session.

Styling. Light stone bg (NOT the cream parchment of the game world), navy accent border, sacred-gold "Built by" badge top-left, Inter sans (NOT Playfair). NOT animated. Never jarring.

§4. Surface 2 — NPC chat-close CTA line

When. Every NPC chat end-state: turn-cap, user × close, OR crisis deflection — i.e., whenever endConversation flips true in NpcChatModal.tsx. ALL THREE paths.

Where. INSIDE the existing end-state block (NpcChatModal.tsx:456-471), BELOW the existing "Walk on" button. Text-only — no card chrome.

Voice separation (load-bearing for AI Bridge). The two pieces of copy at chat-close MUST read as different voice tiers:

VoiceTextTypography
In-character"The conversation has ended. Walk on — there is more of the story ahead."existing — small body text, stone-600
Builder creditsline belowtext-xs italic text-stone-500, sans-serif

Line content (verbatim, strategic spec §T3):

You just had a conversation with an AI character built by ChurchWiseAI. Imagine her answering your congregation's questions, day or night.

(Pronoun "her" tracks spec verbatim; founder may approve a neutral swap for male-coded NPCs, but default ship is verbatim.)

CTA URL: https://churchwiseai.com/from-living-word?utm_source=living-word&utm_medium=in-game&utm_campaign=npc-chat-close-v1&npc_id=<active_npc_id>

Events.

EventWhenMetadata
npc_chat_close_impressionwhen end-state renders (every time)npc_id
npc_chat_close_clickon CTA clicknpc_id

Hard constraint. The line MUST NOT appear DURING an active conversation. End-state only. Non-negotiable — interrupting mid-dialogue with Scribe Eden breaks the contemplative spell that is the entire strategic point.

§5. Surface 3 — Legacy Bloom finale panel (Decision B3)

When. AFTER LegacyBloomCinematic completes its full 7-second sequence (or its 4-second reduced-motion still). Cinematic's onComplete() callback signals the moment.

Where. Fades in exactly 1500ms after onComplete() fires. The 1500ms silence is intentional — the cinematic's last frame and the "Behold, I make all things new." text get a full beat before the credits panel arrives. Implemented as a SEPARATE component mounted by LivingWordAdventure.tsx after the cinematic unmounts. The cinematic itself is NEVER modified — the 1500ms delay lives in the parent, not the cinematic.

Panel content (verbatim, strategic spec §T4):

Built by ChurchWiseAI

You just walked from Eden to the New Creation. The seed you planted in chapter one bloomed at the end — the same way Scripture's threads carry from Genesis 1 to Revelation 22.

ChurchWiseAI builds AI tools for churches that hold this same story-shaped quality: voice agents, chatbots, and Pro Websites that talk like a pastor who's read the whole book.

[See what it does for your church →]

[Share Living Word with another teacher →]

Primary CTA URL: https://churchwiseai.com/from-living-word?utm_source=living-word&utm_medium=in-game&utm_campaign=legacy-bloom-finale-v1

Secondary CTA — share. Pre-filled mailto: link:

  • Subject: I just finished Living Word
  • Body:

Hey — I just finished a game called Living Word that walks through the whole biblical narrative from Eden to New Creation. The AI characters teach in tradition-specific voices and it's free. I thought you might appreciate it (or want to share it with your students/youth group). Here: https://livingword.bible/?ref=share

(Refine body to founder voice before ship.)

Events.

EventWhenMetadata
legacy_bloom_impressionwhen panel fades in (after +1500ms)
legacy_bloom_clickon EITHER CTAaction: 'cwa_demo' | 'share'
share_clickon secondary CTA — fires IN ADDITION to legacy_bloom_click

Styling. Full-width panel, navy on cream (bg-[#FEFCF8], text text-[#1B365D]). Prominent — highest-conversion moment in the funnel per strategic spec §"Touchpoints." Playfair Display heading; Inter body and CTAs. Primary CTA = sacred-gold button (bg-[#D4AF37]); secondary = ghost outline. Fades in ~600ms.

Dismiss. Small × top-right returns player to post-game free-roam. Panel does NOT auto-dismiss; player chooses one of three actions.

Hard constraint. Panel MUST NOT replace, shorten, or interrupt the cinematic. Founder review will reject any implementation that overlaps.

§6. Implementation details

SurfaceNew/extendsStateAccessibilityMobile
Scene-completion cardnew components/SceneCompletionCtaCard.tsx; mounted by LivingWordAdventure.tsxlocalStorage counter + parent React dismissedThisSession flagrole="complementary", aria-label="Built by ChurchWiseAI — learn more", × aria-label="Dismiss this notice", focus NOT trapped (non-modal), keyboard-reachable via Tab320-640px full-width compact padding; 640+ comfortable padding; ≥768px max-width 32rem
NPC chat-close lineextends NpcChatModal.tsx end-state block (lines ~456-471); reads existing npcId/npcName propsnone beyond endConversationsemantic <a href>, aria-label describes purpose + new-tab, opens target="_blank" rel="noopener noreferrer"text-xs at all viewports, wraps naturally
Legacy Bloom finale panelnew components/LegacyBloomFinalePanel.tsx; mounted by LivingWordAdventure.tsx 1500ms after cinematic's onComplete()parent bloomFinaleVisible boolean + setTimeout in parentrole="dialog", aria-modal="true" (post-game; focus trap appropriate here), focus → heading on fade-in, Escape triggers close, both CTAs and × keyboard-reachable320-640px full-viewport with stacked CTAs; ≥640px side-by-side, max-width 42rem centered

Event-logging call sites.

  • Impressions fire from useEffect on mount (only when surface is visible).
  • Clicks fire from CTA onClick handlers.
  • The share CTA fires BOTH legacy_bloom_click (with action: 'share') AND share_click — both calls in the same handler.

Shared helper signature (no new event types added in Phase 1B — all 7 types used here are already in the Phase 1A LeadGenEventType union):

trackLeadGenEvent({
eventType: '<event from §3/§4/§5>',
placement: '<surface-specific string>',
utmCampaign: '<scene-completion-v1 | npc-chat-close-v1 | legacy-bloom-finale-v1>',
utmMedium: 'in-game',
metadata: { /* scene_id | npc_id | action */ },
});

§7. Visibility logic state table

Player stateScene-completion cardNPC chat-close lineLegacy Bloom panel
Has completed 0 scenesn/a (no completion yet)shown if NPC chat endedn/a
Has completed 1 scenehidden (counter = 1)shownn/a
Has completed 2 sceneshidden (counter = 2)shownn/a
Has completed 3+ scenesshown (dismissible)shownn/a
Has reached Legacy Bloom completionshownshownshown ONCE per save, fades in +1500ms
Has dismissed scene-completion card this sessionhidden until next sessionshownshown
Currently DURING NPC chatn/aNOT shown — end-state onlyn/a
Currently DURING Legacy Bloom cinematicn/an/aNOT shown — only after cinematic completes

§8. UTM tagging summary

All CTAs route to https://churchwiseai.com/from-living-word (Decision B1) with:

ParamValueNotes
utm_sourceliving-wordconstant across all Phase 1 surfaces
utm_mediumin-gamePhase 1B constant; Phase 1A footer uses utm_medium=footer
utm_campaignscene-completion-v1 | npc-chat-close-v1 | legacy-bloom-finale-v1per-surface; -v1 suffix lets Phase 2 ship -v2 A/B without losing baseline
scene_id / npc_id / actionvariesNOT utm_* — extra query params for funnel attribution

The Phase-1A landing page already logs landing_page_view on render and reads UTM params from URL into event metadata. No landing-page changes required.

§9. Anti-goals (load-bearing)

Non-negotiable. Mirrors strategic spec anti-goals.

  • NO CTAs during gameplay or during NPC chat. Completion moments only.
  • NO NPC-voiced cross-sell. Scribe Eden never recommends ChurchWiseAI.
  • NO popup interstitials or page-blocking lightboxes (modals OK; popups NOT).
  • NO "limited time" / "act now" / fake urgency copy. Anywhere. Ever.
  • NO third-party tracking pixels. First-party only via lw_lead_gen_events.
  • NO persistent banner ads (Phase 1A footer is the only persistent surface).
  • NO segmentation by visitor type in Phase 1B (Phase 2).
  • NO mid-cinematic interruption for Legacy Bloom — 1500ms post-cinematic silence is the floor.
  • NO behavioural / geo / time-of-day targeting. All players see same surfaces under same rules.
  • NO A/B testing copy in Phase 1B. Ship v1 as-spec'd; iterate after Phase 1C data.
  • NO email capture inside the game. Landing page only.
  • NO mirroring of /from-living-word on livingword.bible (Decision B1).

§10. Acceptance criteria

Functional MUSTs

  • Scene-completion card appears at 3rd scene completion onward, never at scenes 1-2.
  • lw-scene-completions-shown:cta localStorage counter persists across page reloads and re-entries; resets only on browser data clear.
  • NPC chat-close CTA line appears at EVERY chat end-state — turn-cap, user × close, OR crisis deflection.
  • Legacy Bloom finale panel fades in exactly 1500ms (±100ms) after LegacyBloomCinematic's onComplete(); cinematic byte-for-byte unchanged.
  • All three surfaces log impression + click events to lw_lead_gen_events.
  • All CTAs route to https://churchwiseai.com/from-living-word (absolute, churchwiseai.com host) with UTM params per §8.
  • Share CTA opens mailto: with subject + body pre-filled per §5.
  • All three surfaces render correctly at 320-768px (mobile) and 768-1280px (desktop).
  • 1500ms post-cinematic delay survives reduced-motion mode (4s cinematic version still triggers the panel at +1500ms).

Anti-tests (engineering MUST verify explicitly)

  • Scene-completion card NEVER blocks "Walk on" or scene-transition action.
  • NPC chat-close line NEVER appears DURING active chat — end-state only.
  • Legacy Bloom panel NEVER interrupts the cinematic.
  • NO CTA routes to a domain other than churchwiseai.com.
  • NO CTA copy contains "limited time", "act now", "only X left", or any other urgency cue.
  • NO CTA is voiced by an in-character NPC.
  • NO scene_completion_impression events fire during scenes 1-2 (counter < 3 = hidden = no impression).

§11. Test plan

Integration tests

  • Scene 1: counter "0", mount completion → card NOT in DOM, no impression logged.
  • Scene 3: counter "2" (→3 after increment), mount → card rendered, one impression with expected scene_id.
  • Scene 3 click: click CTA → click event logged; href is absolute churchwiseai.com URL with utm_campaign=scene-completion-v1 + scene_id.
  • Dismiss: click ×, card unmounts; re-mount same session → stays hidden; clear session, re-mount → reappears.
  • NPC chat-close — turn-cap: play to turn-cap end-state → CTA line in DOM, one impression with npc_id.
  • NPC chat-close — user × close: open chat, send one message, click × → end-state renders, CTA line visible.
  • NPC chat-close — crisis deflection: trigger deflection → conversation ends AND CTA line still rendered.
  • NPC chat-close click: click CTA → npc_chat_close_click with npc_id; href absolute churchwiseai.com with utm_campaign=npc-chat-close-v1.
  • NPC chat-close — during chat: any point with endConversation === false → CTA line NOT in DOM.
  • Legacy Bloom panel — delay: complete cinematic → panel mounts at +1500ms (±100ms), NOT before; legacy_bloom_impression logged.
  • Legacy Bloom primary click: click "See what it does" → legacy_bloom_click with action: 'cwa_demo'; href absolute churchwiseai.com with utm_campaign=legacy-bloom-finale-v1.
  • Legacy Bloom share click: click share → BOTH legacy_bloom_click (action: 'share') AND share_click log; href starts mailto:, contains subject + body with livingword.bible link.

Playwright E2E

  • Happy-path scene-completion: play scenes 1 → 2 → 3; no card at 1, 2; card at scene 3.
  • Happy-path NPC chat: chat with Scribe Eden, exchange a few messages, close → CTA line at end-state.
  • Crisis chat path: trigger crisis deflection → conversation ends AND CTA line still appears.
  • Happy-path Legacy Bloom: walk to Tree of Life in New Creation → observe cinematic → panel fades in +1500ms → click primary → navigate to churchwiseai.com/from-living-word.
  • Domain enforcement: intercept all CTA clicks across all 3 surfaces; every navigation target is https://churchwiseai.com/from-living-word (exact host match).

§12. Founder go/no-go gate (after Phase 1B ships)

Phase 1B is DONE and Phase 1C is cleared when:

  • All 3 surfaces live in production.
  • 7 days of data captured in lw_lead_gen_events.
  • Click-through rate ≥1% on at least 2 of 3 surfaces (clicks/impressions per surface). Strategic spec's full-funnel target was ≥2%; per-surface 1% leaves the landing→demo step headroom.
  • Zero brand-misalignment complaints from founder review of user feedback.
  • At least 1 demo booking attributed back via UTM (utm_source=living-word in Cal.com referrer).

If green: proceed to Phase 1C (founder lead-gen dashboard) + queue Phase 2 planning. If any fail: pause Phase 1C, founder + engineering review failure mode, iterate copy/placement before resuming.

§13. Open questions deferred (NOT Phase 1B scope)

These do NOT block ship. Engineering proceeds with this spec; revisit in their proper phase.

  • Segmentation by visitor type (youth pastor / Sunday school teacher / pastor / parent) — Phase 2.
  • A/B test infrastructure for CTA copy — Phase 2.
  • Email opt-in for non-purchasing visitors on landing — Phase 2.
  • Cross-promotion from PewSearch / SermonWise into Living Word — Phase 3.
  • Premium-tier upsell from in-game contexts ($4.95/mo Phase 2-5 unlock) — Phase 3, after Phase 1B+1C data validates the funnel.
  • Scene-completion UI surface — RESOLVED 2026-05-24 (founder). Engineering introduces a new brief scene-completion modal as the bloom card's host. This is the cleanest UX — "Walk on" stays primary inside the modal (positioned above the bloom card), the scene-completion moment gets a small celebratory beat that the current scene-transition feedback band lacks, and the modal becomes a reusable host for future per-scene UI (e.g., scene-specific scripture reflection, future Phase 2 mechanics). The component lives at src/app/living-word/components/SceneCompletionModal.tsx and is invoked from the existing handleReachExit() success path in LivingWordAdventure.tsx (no other scene-completion logic moves into it; it's a presentation-only modal that wraps the existing transition).

End of spec. Engineering may begin Phase 1B implementation immediately after PR #559 merges and the lw_lead_gen_events migration is verified in production. No additional founder decisions required before the first commit.