ITW Premium — Expected Output Spec
Status: COMPLETE -- Agent-derived from codebase analysis. Flagged items require founder confirmation.
Product: IllustrateTheWord Premium | Price: $9.95/mo ($99.50/yr) | Trial: None
URL: illustratetheword.com | Auth: Supabase Auth (email/password + Google OAuth)
Codebase: sermon-illustrations/
User State Definition
| Field | Value |
|---|---|
| Product | itw_premium (or itw_premium_annual) |
| Subscription table | user_subscriptions |
| Auth | Supabase Auth (email + password OR Google OAuth) |
| Content access | All 3 tiers: public, free_signup, premium |
| Library access | 100% of illustrations (~50,000+) |
| Favorites | Unlimited |
| Collections | Unlimited named collections |
| Sermon slides | Unlimited downloads |
| Copy to clipboard | Yes |
| LensLines | Full access to tradition-specific perspectives |
Access Tier Breakdown
| Tier | % of Library | Content Types | Requires |
|---|---|---|---|
public | ~18% | All historical_illustration + top ~50 per non-premium type | Nothing (anonymous OK) |
free_signup | ~68% | Majority of the library | Free account |
premium | ~14% | movie_analogy, devotional, lens_perspective, application_point, show_dont_tell_prompt, spiritual_discipline, character_profile, vivid_retelling, tv_analogy + high-quality sermon_illustration | Paid subscription ($9.95/mo) |
A. Discovery Paths (Touchpoints 1--8)
How a prospective ITW Premium customer first encounters the product.
Touchpoint 1: Homepage
URL: https://illustratetheword.com/
Component: sermon-illustrations/src/app/page.tsx
Should See:
- Cinematic video hero (
HeroVideocomponent) with search bar overlay - Dynamic count: "50,000+ Sermon Illustrations"
- "This Sunday" lectionary readings section (auto-detected from RCL calendar)
- 5 browse category cards: By Topic, By Scripture, By Emotion, By Tradition, By Source Type
- Recently updated illustrations (6 cards)
- "Surprise Me" random discovery button
- Search bar prominent above the fold
- Footer with links to About, Help, Contact, Pricing, Privacy, Terms
Should NOT See:
- Aggressive Free vs Premium tier distinction above the fold
- "Upgrade to Premium" CTA on the homepage
- Pricing information on the homepage
- CWA branding in the main content area
CTA -> Destination:
- Search bar ->
/search?q=[query] - Browse cards ->
/topics,/scriptures,/emotions,/traditions,/sources - "This Sunday" -> Lectionary readings with linked illustrations
- "Surprise Me" -> Random illustration detail page
Notes:
The homepage is a content-first browse experience, not a marketing landing page. A pastor discovers the gate organically when they click a locked illustration.
Touchpoint 2: Topic/Scripture/Emotion Browse Pages (SEO landing)
URL: https://illustratetheword.com/topics/[slug] (and /scriptures/, /emotions/, /traditions/, /sources/)
Component: Various under sermon-illustrations/src/app/topics/, scriptures/, etc.
Should See:
- Page heading with topic/scripture/emotion name
- Grid of illustration cards matching the filter
- Each card shows: title, teaser, content type emoji badge, theological tradition badge
- Cards for ALL tiers visible (public, free_signup, premium) -- no content hidden from browse
- Pagination for large result sets
- Search/filter refinement options
Should NOT See:
- Lock icons or "Premium" badges on cards in the browse grid
- Any content hidden from the browse listing (all tiers show cards)
- The gate only appears on the detail page, not the browse page
CTA -> Destination:
- Click card ->
/illustrations/[slug](detail page where gating occurs)
Touchpoint 3: Illustration Detail Page (Public Tier)
URL: https://illustratetheword.com/illustrations/[slug] (for visibility_tier = 'public')
Component: sermon-illustrations/src/app/illustrations/[slug]/page.tsx
Should See:
- Full illustration content (title, body text, formatted with bold/italic)
- Metadata: scripture references, topics/themes, emotions, theological tradition badge
- CopyButton (clipboard) -- available to all logged-in users
- ShareButton (social sharing)
- FavoriteButton (heart icon) -- requires login
- AddToCollectionButton -- requires login
- PersonalizeButton -- customize for context
- Related illustrations section (6 cards)
- Scripture-related illustrations section
- LensLines for the passage (if applicable)
- StockPhotos component (contextual images)
- MovieInfo component (if movie analogy)
- ChurchWiseAIPromo section at bottom
- Schema.org structured data
Should NOT See:
- Any paywall or gate (public tier is fully visible)
- "Upgrade" messaging on public content
Touchpoint 4: Illustration Detail Page (Free Signup Tier -- Anonymous Visitor)
URL: https://illustratetheword.com/illustrations/[slug] (for visibility_tier = 'free_signup', user NOT logged in)
Component: sermon-illustrations/src/app/illustrations/[slug]/page.tsx
Should See:
- Title and metadata (scripture, topics, emotions, tradition)
- Teaser / first paragraph of the illustration
- Content gate: "Sign up free to read this illustration"
- CTA button: "Sign Up Free" ->
/signup - Related illustrations visible below the gate
- Schema.org structured data with partial content
Should NOT See:
- Full illustration body text
- CopyButton functional (hidden or disabled)
- Premium upgrade messaging (this is a free_signup gate, not a premium gate)
CTA -> Destination:
- "Sign Up Free" ->
/signup - If coming from a specific illustration: signup redirects back to the illustration after confirmation
Touchpoint 5: Illustration Detail Page (Premium Tier -- Free User)
URL: https://illustratetheword.com/illustrations/[slug] (for visibility_tier = 'premium', user logged in but NOT subscribed)
Component: sermon-illustrations/src/app/illustrations/[slug]/page.tsx
Should See:
- Title and metadata
- Teaser / first paragraph
- Content gate with Lock icon: "This is a premium illustration"
- CTA button: "Unlock with Premium -- $9.95/mo" ->
/pricing?checkout=monthly - Secondary CTA: "Learn more about Premium" ->
/pricing - Related illustrations visible below
- ChurchWiseAIPromo at bottom
Should NOT See:
- Full illustration body text
- Aggressive upsell or FOMO language
- Multiple overlapping CTAs
CTA -> Destination:
- "Unlock with Premium" ->
/pricing?checkout=monthly
Touchpoint 6: Pricing Page
URL: https://illustratetheword.com/pricing
Component: sermon-illustrations/src/app/pricing/page.tsx
Should See:
- Amber gradient hero: "Simple, Transparent Pricing"
- Monthly / Annual billing toggle (Annual shows "Save X%" badge)
- Two side-by-side cards:
- Free ($0/forever): Browse public illustrations, Search by topic/scripture/emotion, 17 traditions, Lectionary calendar, 1 sermon slide/week. CTA: "Get started free" ->
/signup - Premium ($9.95/mo or $8.29/mo annual): Everything in Free + Unlock all 50,000+ illustrations, Movie analogies/devotionals/application points, LensLines, Unlimited slide downloads, Save and organize favorites, Priority access. CTA: "Subscribe" -> Stripe checkout (or
/signupif not logged in)
- Free ($0/forever): Browse public illustrations, Search by topic/scripture/emotion, 17 traditions, Lectionary calendar, 1 sermon slide/week. CTA: "Get started free" ->
- "Most Popular" badge on Premium card
- "Your Plan" badge if already subscribed
- "Manage subscription" link if already subscribed -> Stripe portal
- Checkout cancelled banner (if returning from cancelled Stripe)
- Auto-checkout trigger if coming from
?checkout=monthlyor?checkout=annual - FAQ section with support email link
Should NOT See:
- A third "free_signup" tier card (two tiers only: Free and Premium)
- CWA chatbot/voice pricing
- Complex tier comparison tables
CTA -> Destination:
- "Get started free" ->
/signup - "Subscribe" (not logged in) ->
/signup?plan=premium - "Subscribe" (logged in, not premium) -> Stripe checkout via
/api/stripe/checkout - "Manage subscription" (premium) -> Stripe Customer Portal via
/api/stripe/portal
Touchpoint 7: Signup Page
URL: https://illustratetheword.com/signup
Component: sermon-illustrations/src/app/signup/page.tsx
Implementation Note: This page (and the signin page) has two email inputs — the auth form input (data-testid="itw-signup-auth-email") and a newsletter subscription input in the page footer. Always use data-testid selectors for auth form interactions to avoid strict mode violations from the duplicate field.
Should See:
- BookOpen icon + "Create your free account" heading
- "Unlock thousands of sermon illustrations" subheading
- Google OAuth button: "Sign up with Google" (prominent, at top)
- Divider: "or sign up with email"
- Email form fields: Name (optional), Email (required), Password (required, min 8 chars), Confirm Password (required)
- Password visibility toggle (eye icon)
- Newsletter opt-in checkbox: "Email me this Sunday's top illustrations and new features"
- Cloudflare Turnstile captcha
- "Create free account" submit button
- "Already have an account? Sign in" link ->
/signin - Common password rejection (20 common passwords blocked)
- Password mismatch inline validation
Should NOT See:
- Church name or denomination fields (individual pastor accounts)
- Credit card fields (free signup)
- CWA branding
- Premium pricing information (this is a free account creation)
CTA -> Destination:
- "Create free account" -> email confirmation sent ->
/auth/callback-> homepage (or/pricing?checkout=monthlyif came from premium content) - "Sign up with Google" -> Google OAuth ->
/auth/callback
Touchpoint 8: Email Confirmation
URL: Email inbox -> confirmation link -> illustratetheword.com/auth/callback
Component: sermon-illustrations/src/app/auth/callback/ (Supabase Auth callback)
Should See:
- In email: Supabase default confirmation email with verification link
- After clicking: redirect to the site, now logged in
- If came from premium gated content: redirected to
/pricing?checkout=monthlyto complete premium subscription - If came from normal signup: redirected to homepage
Should NOT See:
- Broken redirect loops
- Error states (should handle gracefully)
B. Free Experience (Touchpoints 9--13)
What a free logged-in user can do.
Touchpoint 9: Browsing as Free User
URL: Any browse page (topics, scriptures, emotions, traditions, sources, search) Component: Various browse pages
Should See:
- Full card listings for all illustrations (all tiers show in browse)
- Full content for
publictier illustrations - Full content for
free_signuptier illustrations (the bulk of the library, ~68%) - Premium illustrations show title + teaser but gated on detail page
- Search works across all tiers
- Filter works across all tiers
Should NOT See:
- Lock icons on cards in browse (gate is only on detail page)
- Reduced search results (all tiers in search)
Touchpoint 10: Favorites Page
URL: https://illustratetheword.com/favorites
Component: sermon-illustrations/src/app/favorites/page.tsx
Should See:
- Heart icon heading + "Your Favorites"
- Grid of saved illustrations (from
user_favoritestable) - Sorted by quality score (descending)
- Each card shows same format as browse pages
- If no favorites: empty state with "Start saving illustrations" prompt
Should NOT See:
- Premium-only gate on the favorites feature itself (available to all logged-in users)
- Limit on number of favorites
✅ Verified 2026-04-27: free authed users see /pricing anchor instead of save action. e2e/content-gating.spec.ts FA-075 describe block green across 4 viewports.
Touchpoint 11: Collections Page
URL: https://illustratetheword.com/collections
Component: sermon-illustrations/src/app/collections/page.tsx
Should See:
- Named collections the user has created
- Ability to create, rename, delete collections
- Add illustrations to collections from detail pages (via AddToCollectionButton)
Should NOT See:
- The collections page itself is accessible to all logged-in users (to view existing collections)
- However, creating a collection and adding to a collection MUST be Premium-only actions — non-Premium users see an upgrade prompt instead
✅ Verified 2026-04-27: non-premium users see /pricing anchor with PRO badge. Pattern is also the model FA-075 mirrored for FavoriteButton.
FLAGGED FOR FOUNDER REVIEW:
Verify that the collections feature is fully implemented and functional. The route exists but completeness needs confirmation.
Touchpoint 12: Lectionary Calendar
URL: https://illustratetheword.com/lectionary
Component: sermon-illustrations/src/app/lectionary/page.tsx
Should See:
- RCL (Revised Common Lectionary) calendar
- Upcoming Sundays with readings
- Links to illustrations matching each reading's scripture passage
- Auto-detected current week
Should NOT See:
- Premium gate on the calendar itself (all tiers can browse the calendar)
- Premium illustrations that match lectionary readings will still show title/teaser but gate on detail
Touchpoint 13: Sermon Slides
URL: https://illustratetheword.com/slides
Component: sermon-illustrations/src/app/slides/page.tsx
Should See:
- Sermon slide generation/download feature
- Free tier: 1 slide download per week limit
- Download button with remaining count
Should NOT See:
- Unlimited access (that's Premium)
C. Upgrade Journey (Touchpoints 14--17)
The path from free user to Premium subscriber.
Touchpoint 14: Premium Gate Encounter
URL: https://illustratetheword.com/illustrations/[slug] (premium content)
Component: sermon-illustrations/src/app/illustrations/[slug]/page.tsx
Should See:
- Title, metadata, teaser visible
- Lock icon with "This is a premium illustration"
- CTA: "Unlock with Premium -- $9.95/mo" ->
/pricing?checkout=monthly - Related free illustrations visible below (encourage continued browsing)
Should NOT See:
- Blurred content overlay (content is simply cut off, not blurred)
- Aggressive "limited time" or FOMO messaging
- Multiple redundant upgrade CTAs
Touchpoint 15: Pricing Page (Upgrade Intent)
URL: https://illustratetheword.com/pricing?checkout=monthly or ?checkout=annual
Component: sermon-illustrations/src/app/pricing/page.tsx
Should See:
- Same as Touchpoint 6 but with:
- Ready-to-subscribe banner: "Ready to unlock full access? Compare plans below and click Subscribe when you're ready."
- Premium card highlighted with pulse animation (
animate-pulse-once) - Billing toggle pre-set if
?checkout=annualparameter present - Auto-checkout may trigger if user is logged in and not premium
Touchpoint 16: Stripe Checkout
URL: Stripe hosted checkout (redirected from /api/stripe/checkout)
Component: Stripe hosted checkout page
Should See:
- Product name: "IllustrateTheWord Premium" (monthly or annual)
- Price: $9.95/mo or $99.50/yr
- Email pre-filled from Supabase Auth
- Card fields, billing address
- No trial period (immediate charge)
- Stripe branding
Should NOT See:
- "CWA" or "ChurchWiseAI" in the Stripe product name
- Trial badge (there is no trial for ITW)
Touchpoint 17: Post-Checkout Confirmation
URL: https://illustratetheword.com/profile?subscription=success
Component: sermon-illustrations/src/app/profile/page.tsx
Should See:
- Success banner with PartyPopper icon: "Welcome to ITW Premium!"
- Profile page showing "Your Plan: Premium" badge
- Favorites count
- "Manage Subscription" button
- Email display
- The entire library is now unlocked
Should NOT See:
- Welcome modal or guided tour
- Complex onboarding steps (it's a content library, not a SaaS dashboard)
D. Premium Experience (Touchpoints 18--22)
What a paying Premium subscriber sees and can do.
Touchpoint 18: Premium Content Access
URL: https://illustratetheword.com/illustrations/[slug] (any premium illustration)
Component: sermon-illustrations/src/app/illustrations/[slug]/page.tsx
Should See:
- Full illustration content (no gate, no teaser truncation)
- CopyButton functional
- FavoriteButton functional
- AddToCollectionButton functional
- PersonalizeButton functional
- ShareButton functional
- All metadata, related content, LensLines visible
Should NOT See:
- Any paywall or upgrade messaging
- "Premium" indicator on the content itself (content just works)
Touchpoint 19: LensLines
URL: https://illustratetheword.com/lenslines and on detail pages
Component: sermon-illustrations/src/app/lenslines/ + LensLineCompactCard
Should See:
- Tradition-specific perspectives on scripture passages
- Compact cards embedded in illustration detail pages
- Full LensLines browse experience
Should NOT See:
- Access gate (Premium unlocks LensLines content)
Touchpoint 20: Unlimited Sermon Slides
URL: https://illustratetheword.com/slides
Component: sermon-illustrations/src/app/slides/page.tsx
Should See:
- Unlimited slide downloads (no weekly limit)
- Full access to all slide templates/styles
Touchpoint 21: Profile / Account Management
URL: https://illustratetheword.com/profile
Component: sermon-illustrations/src/app/profile/page.tsx
Should See:
- User display name (from Supabase metadata)
- User email (with "Change email" form: enter new email -> confirmation link sent to both old and new)
- Favorites count with link to
/favorites - Subscription status: "Premium" badge
- "Manage Subscription" button -> Stripe Customer Portal
- "Delete Account" section (with "type DELETE" confirmation, destructive action warning)
- Success banner if just subscribed (
?subscription=success)
Should NOT See:
- Password change on this page (use Supabase password reset flow)
- Church/denomination settings (not relevant for ITW)
Touchpoint 22: Stripe Customer Portal (Billing Management)
URL: Stripe Customer Portal (via /api/stripe/portal POST redirect)
Component: Stripe hosted portal
Should See:
- Current subscription: ITW Premium ($9.95/mo or $99.50/yr)
- Cancel subscription option
- Update payment method
- Switch between monthly and annual billing (Stripe handles proration)
- Invoice history
E. Cross-Sell & Ecosystem (Touchpoints 23--24)
Touchpoint 23: ChurchWiseAI Promo on Detail Pages
URL: Any illustration detail page
Component: sermon-illustrations/src/components/illustrations/ChurchWiseAIPromo.tsx
Should See:
- Section titled "Powered by ChurchWiseAI"
- Subtext: "IllustrateTheWord is part of the ChurchWiseAI family -- AI tools built for pastors, churches, and ministry leaders."
- Two product cards:
- PewSearch: "Find Your Church Home" -- "Search Churches" CTA -> pewsearch.com
- ChurchWiseAI: "Voice Agent & Church Chatbot" -- "See AI Tools" CTA -> churchwiseai.com
- Bottom bar: "AI voice agent & chatbot for your church -- from $14.95/mo" + "See Plans" -> churchwiseai.com/pricing
- Compact variant available for sidebar contexts
Should NOT See:
- Aggressive upsell interrupting content flow
- "Buy now" or urgency language
- This section should feel informational, not sales-y
Touchpoint 24: Ecosystem Footer
URL: All pages (global footer)
Component: sermon-illustrations/src/components/layout/Footer.tsx
Should See:
- ITW branding
- Links to About, Help, Contact, Privacy, Terms, Pricing
- Ecosystem mention (PewSearch, ChurchWiseAI)
F. Lifecycle Events (Touchpoints 25--30)
Touchpoint 25: Payment Failed
URL: Email + in-app Component: Stripe webhook handler + profile page
Should See:
- Stripe retry attempts (3 retries over ~7 days)
- Email notification (Stripe default or custom) with link to update payment
- In-app: profile page should show subscription status reflecting payment issue
Should NOT See:
- Immediate content lockout on first failure (grace period during Stripe retries)
FLAGGED FOR FOUNDER REVIEW:
No custom payment failure email or in-app banner exists. Stripe defaults handle retries. Recommendation: add a custom email and profile banner for past_due status.
Touchpoint 26: Subscription Cancelled
URL: Profile page after cancellation
Component: sermon-illustrations/src/app/profile/page.tsx
Should See:
- Subscription status changes from "Premium" to "Free" (after billing period ends)
- Access to premium content revoked (detail pages show gate again)
- Saved favorites preserved (titles visible, premium content shows teaser only)
- Collections preserved
- "Subscribe" button reappears on pricing page
Should NOT See:
- Data deletion (soft delete pattern -- all user data retained)
- Aggressive "come back" messaging
FLAGGED FOR FOUNDER REVIEW:
No custom cancellation email exists. Recommendation: send empathetic cancellation email (data retained, access ends at period, welcome back anytime, no hard feelings).
Touchpoint 27: Re-subscription
URL: /pricing
Component: sermon-illustrations/src/app/pricing/page.tsx
Should See:
- Standard pricing page with Subscribe CTA
- Same Stripe checkout flow as initial subscription
- After re-subscribing: all old favorites and collections immediately accessible again
- Premium content unlocked again
Should NOT See:
- Welcome email treating them as a new user (detect re-subscription)
Touchpoint 28: Annual Billing Switch
URL: Stripe Customer Portal Component: Stripe hosted portal
Should See:
- Option to switch from monthly ($9.95) to annual ($99.50/yr -- save ~17%)
- Stripe handles proration automatically
- No disruption to access during switch
Touchpoint 29: Email -- Weekly Lectionary (Newsletter)
URL: Email inbox Component: MailerLite or custom email system
Should See:
- "This Sunday's top illustrations" if opted in during signup
- Links to relevant illustrations for upcoming lectionary readings
- Gentle reminder of premium content available
- Unsubscribe link
FLAGGED FOR FOUNDER REVIEW:
Verify the newsletter is actually sending. The signup checkbox opts into MailerLite, but the actual email cadence and content need confirmation.
Touchpoint 30: Account Deletion
URL: /profile
Component: sermon-illustrations/src/app/profile/page.tsx (delete section)
Should See:
- "Delete Account" section at bottom of profile
- Warning text explaining consequences
- Requires typing "DELETE" to confirm
- Cancel active subscription first (if applicable)
- After deletion: signed out, redirected to homepage
Should NOT See:
- Easy one-click deletion (requires deliberate confirmation)
Playwright Test Hints
// Touchpoint 1: Homepage loads with illustration count
test('homepage shows illustration count', async ({ page }) => {
await page.goto('https://illustratetheword.com');
await expect(page.getByText(/\d+,000\+ Sermon Illustrations/)).toBeVisible();
});
// Touchpoint 4: Free signup gate on free_signup content
test('anonymous user sees signup gate on free_signup illustration', async ({ page }) => {
// Navigate to a known free_signup illustration
await page.goto('https://illustratetheword.com/illustrations/[known-free-signup-slug]');
await expect(page.getByText('Sign up free')).toBeVisible();
await expect(page.getByRole('link', { name: /sign up/i })).toHaveAttribute('href', '/signup');
});
// Touchpoint 5: Premium gate on premium content
test('free user sees premium gate on premium illustration', async ({ page }) => {
// Login as free user first
// Navigate to a known premium illustration
await expect(page.getByText('This is a premium illustration')).toBeVisible();
await expect(page.getByRole('link', { name: /unlock with premium/i })).toBeVisible();
});
// Touchpoint 6: Pricing page shows both tiers
test('pricing page shows Free and Premium cards', async ({ page }) => {
await page.goto('https://illustratetheword.com/pricing');
await expect(page.getByText('$0')).toBeVisible();
await expect(page.getByText('$9.95')).toBeVisible();
await expect(page.getByTestId('itw-pricing-billing-monthly')).toBeVisible();
await expect(page.getByTestId('itw-pricing-billing-annual')).toBeVisible();
});
// Touchpoint 7: Signup page has all required fields
test('signup page has name, email, password, Google OAuth', async ({ page }) => {
await page.goto('https://illustratetheword.com/signup');
await expect(page.getByTestId('itw-signup-auth-google')).toBeVisible();
await expect(page.getByTestId('itw-signup-auth-email')).toBeVisible();
await expect(page.getByTestId('itw-signup-auth-password')).toBeVisible();
await expect(page.getByTestId('itw-signup-auth-newsletter')).toBeVisible();
});
// Touchpoint 18: Premium user sees full content
test('premium user sees full illustration content', async ({ page }) => {
// Login as premium user
// Navigate to premium illustration
await expect(page.getByText('This is a premium illustration')).not.toBeVisible();
// Full content should be rendered
});
// Touchpoint 21: Profile page shows subscription status
test('profile page shows Premium badge for subscriber', async ({ page }) => {
// Login as premium user
await page.goto('https://illustratetheword.com/profile');
await expect(page.getByText('Premium')).toBeVisible();
await expect(page.getByText('Manage Subscription')).toBeVisible();
});