Skip to content

Campaign Brain Public Website Plan

Developer Resources

CLAUDE.md - AI-assisted development guide

Executive Summary

A conversion-focused marketing site targeting grass-roots campaign managers who need fast, quick, and easy tools. The site combines a traditional marketing funnel with a unique lead-generation mechanism: dynamic district pages that show prospects relevant local data before they sign up.


1. Site Architecture

Primary Domain

  • campaignbrain.ai or nominate.ai (main marketing site)

Wildcard District Domains

  • {district}.nominate.ai → Dynamic district pages
  • Examples: ia03.nominate.ai, mi07.nominate.ai, ca45.nominate.ai

2. Site Map

nominate.ai (root)
├── / (Homepage)
│   └── Hero + Value prop + CTA
├── /features
│   └── Core capabilities overview
├── /pricing
│   └── Simple, transparent pricing
├── /demo
│   └── Interactive preview or video walkthrough
├── /start
│   └── Quick account setup flow (3 steps max)
├── /login
│   └── Redirect to tenant app
└── /districts/{code}
    └── Fallback route for district pages
        (also served via wildcard subdomains)

Wildcard Subdomains:
├── ia03.nominate.ai → Iowa CD-3
├── mi07.nominate.ai → Michigan CD-7
├── tx22.nominate.ai → Texas CD-22
└── [any].nominate.ai → Dynamic generation

3. Page-by-Page Content Plan

3.1 Homepage (/)

Purpose: Hook visitors in 5 seconds, get them to pricing or demo.

Hero Section:

Headline:    "Win Your Campaign. Not a PhD in Software."
Subhead:     "The CRM that grass-roots campaigns actually use.
              Voter outreach, volunteer coordination, and AI-powered
              follow-ups—all in one place."
CTA:         [See Pricing] [Watch 2-Min Demo]

Problem/Solution Block: Three pain points, three solutions. No fluff.

Pain Point Solution
"I'm drowning in spreadsheets" One unified voter database with smart search
"My volunteers forget to follow up" Automated reminder sequences that actually work
"I don't know what's working" Real-time dashboards showing outreach impact

Social Proof: - Quote from a campaign manager (even fictional placeholder initially) - "Trusted by X campaigns across Y states" (update as you grow) - Logos if you have recognizable clients

Feature Highlights: Three cards, icon + headline + one sentence each: 1. Voter Database — Search 8M+ voter records by name, address, or turnout score 2. Multi-Channel Outreach — Phone, door, text, email, postcards from one screen 3. AI Follow-Ups — Claude-powered scheduling that adapts to responses

District Teaser:

"See your district right now"
[Enter district code: ______] [Go]
"Or visit ia03.nominate.ai to see Iowa CD-3"

Footer CTA:

"Ready to stop fighting your tools and start winning votes?"
[Start Free Trial]


3.2 Features Page (/features)

Purpose: Deeper dive for prospects who need convincing.

Structure: Single scrolling page with anchor links. NOT a features matrix.

Sections:

  1. Voter Database
  2. Smart search across millions of records
  3. Turnout scores, political profiles, contact history
  4. Import your own lists, export anytime
  5. Screenshot: Search results table

  6. Outreach Workflows

  7. Phone banking with built-in scripts
  8. Door-to-door canvassing with mobile check-in
  9. Text/SMS campaigns with compliance built in
  10. Email sequences that don't hit spam
  11. Postcard campaigns with print fulfillment
  12. Screenshot: Workflow builder

  13. Volunteer Management

  14. County captain coordination
  15. Shift scheduling and reminders
  16. Performance tracking (calls made, doors knocked)
  17. Screenshot: Volunteer dashboard

  18. AI-Powered Automation

  19. Smart follow-up timing based on response patterns
  20. Suggested talking points for each contact
  21. Automatic WHIP status updates from conversation notes
  22. Screenshot: AI recommendation panel

  23. Reporting & Analytics

  24. Real-time campaign dashboard
  25. Voter contact rates by channel
  26. Geographic heat maps
  27. Export everything to CSV
  28. Screenshot: Analytics dashboard

Bottom CTA:

"See it in action with your actual district data"
[Enter Your District] or [Start Free Trial]


3.3 Pricing Page (/pricing)

Purpose: Remove all friction. Transparent, simple, no "contact sales."

Pricing Philosophy: - Grass-roots campaigns are budget-conscious - They hate hidden fees and "enterprise" gates - Offer a free tier or trial to reduce risk

Suggested Tiers:

┌─────────────────┬─────────────────┬─────────────────┐
│    STARTER      │    CAMPAIGN     │   ORGANIZATION  │
│      Free       │   $99/month     │   $299/month    │
├─────────────────┼─────────────────┼─────────────────┤
│ 1 user          │ 5 users         │ Unlimited users │
│ 500 contacts    │ 10,000 contacts │ 100,000 contacts│
│ Basic search    │ Full database   │ Full database   │
│ Email only      │ All channels    │ All channels    │
│ —               │ AI follow-ups   │ AI follow-ups   │
│ —               │ —               │ API access      │
│ —               │ —               │ Priority support│
├─────────────────┼─────────────────┼─────────────────┤
│ [Start Free]    │ [Start Trial]   │ [Start Trial]   │
└─────────────────┴─────────────────┴─────────────────┘

All plans include: Voter data access, WHIP tracking, basic reporting
No contracts. Cancel anytime. Upgrade or downgrade instantly.

FAQ Section: - "Can I import my existing voter file?" → Yes, CSV upload supported - "Is my data secure?" → Yes, encrypted at rest and in transit - "Do you offer discounts for down-ballot races?" → Yes, contact us - "What if I need more contacts?" → Upgrade anytime, prorated


3.4 Demo Page (/demo)

Purpose: Let prospects see the product without signing up.

Options (pick one or both):

Option A: Video Walkthrough - 2-minute Loom-style video - Show: Login → Search voter → Add to workflow → See automation trigger - Embed with thumbnail showing the dashboard

Option B: Interactive Preview - Sandboxed version with fake data - Let them click around - Prompt to sign up when they try to "save" anything

Content:

"See Campaign Brain in Action"

[Video thumbnail with play button]

"This 2-minute walkthrough shows you how to:
✓ Find voters in your district
✓ Create an outreach workflow
✓ Let AI handle the follow-ups"

[Watch Demo]  [Skip to Pricing]


3.5 Quick Start Flow (/start)

Purpose: Account creation in under 2 minutes.

Philosophy: - Absolute minimum fields - Show progress (Step 1 of 3) - Delay optional setup until after they're in

Step 1: Basic Info

"Let's get you started"

Campaign Name: [________________________]
Your Email:    [________________________]
Password:      [________________________]

[Continue →]

"Already have an account? [Log in]"

Step 2: Your District

"What race are you running?"

State:    [Dropdown_________▼]
District: [Dropdown_________▼]
Race Type: ○ Congressional  ○ State Senate
           ○ State House    ○ County/Local

[Continue →]

Step 3: Confirmation

"You're in!"

Your campaign site: yourcampaign.nominate.ai
Dashboard: [Go to Dashboard →]

"We've loaded your district's voter data.
 Start exploring, or check your email for a quick-start guide."

Post-Signup: - Auto-provision tenant - Pre-load relevant voter data - Send welcome email with 3 quick wins


3.6 Dynamic District Pages (/{district} or {district}.nominate.ai)

Purpose: Lead generation through relevant, personalized content.

URL Patterns: - ia03.nominate.ai → Iowa Congressional District 3 - mi07.nominate.ai → Michigan Congressional District 7 - ny14.nominate.ai → New York Congressional District 14

Page Structure:

┌────────────────────────────────────────────────────────────┐
│  CAMPAIGN BRAIN              [See Pricing] [Start Free]   │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  Iowa Congressional District 3                             │
│  ══════════════════════════════                            │
│                                                            │
│  Ready to win this seat? Here's what you're working with.  │
│                                                            │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐       │
│  │ Population   │ │ Registered   │ │ 2024 Margin  │       │
│  │   847,000    │ │   612,000    │ │    R+4.2     │       │
│  └──────────────┘ └──────────────┘ └──────────────┘       │
│                                                            │
│  District Overview                                         │
│  ─────────────────                                         │
│  [Wikipedia-sourced description of district geography,     │
│   major cities, economic drivers, political history]       │
│                                                            │
│  Counties in This District                                 │
│  ─────────────────────────                                 │
│  • Pottawattamie County (Council Bluffs)                  │
│  • Mills County                                            │
│  • Montgomery County                                       │
│  • ... [expandable list]                                   │
│                                                            │
│  Recent Representatives                                    │
│  ──────────────────────                                    │
│  • 2023-present: Zach Nunn (R)                            │
│  • 2013-2023: David Young (R)                             │
│  • 2009-2013: Leonard Boswell (D)                         │
│                                                            │
│  ════════════════════════════════════════════════════════ │
│                                                            │
│  "Campaign Brain helped me track 50,000 voter contacts    │
│   across 12 counties without losing my mind."             │
│                        — Campaign Manager, Similar Race    │
│                                                            │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  Ready to run in Iowa CD-3?                          │ │
│  │                                                       │ │
│  │  Get instant access to:                              │ │
│  │  ✓ 612,000 registered voter records                  │ │
│  │  ✓ Turnout scores and political profiles             │ │
│  │  ✓ Multi-channel outreach tools                      │ │
│  │  ✓ AI-powered follow-up automation                   │ │
│  │                                                       │ │
│  │  [Start Your Campaign — Free]                        │ │
│  │                                                       │ │
│  │  No credit card required. Upgrade when you're ready. │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                            │
│  Other Districts: [IA-01] [IA-02] [IA-04] [Browse All]    │
│                                                            │
└────────────────────────────────────────────────────────────┘

Data Sources: - Wikipedia API (via wikipedia Python library) - Census data for population - FEC/state SoS for registered voters - Cook PVI or similar for partisan lean - Cache results for 48-72 hours

District Code Parsing:

# Pattern: {state_abbrev}{district_number}
# ia03 → Iowa, District 3
# mi07 → Michigan, District 7
# ca45 → California, District 45
# at-large states: ak00, vt00, wy00

def parse_district_code(code: str) -> tuple[str, int]:
    """Parse district code into state and district number."""
    code = code.lower().strip()
    state = code[:2]
    district = int(code[2:])
    return state, district

Fallback for Invalid Codes:

"We couldn't find district '{code}'"

Try one of these formats:
• ia03 — Iowa Congressional District 3
• mi07 — Michigan Congressional District 7
• ca45 — California Congressional District 45

[Browse All Districts] [Go to Homepage]


4. Navigation & Information Architecture

Primary Navigation (all pages)

┌────────────────────────────────────────────────────────────┐
│ [Logo] CAMPAIGN BRAIN    Features  Pricing  Demo  [Login] │
└────────────────────────────────────────────────────────────┘
  • Logo: Links to homepage
  • Features: Single page with anchor sections
  • Pricing: The money page—always accessible
  • Demo: Video or interactive preview
  • Login: Top-right, secondary visual weight
  • CTA Button: "Start Free" appears on hover/scroll or in hero
┌────────────────────────────────────────────────────────────┐
│ CAMPAIGN BRAIN                                             │
│                                                            │
│ Product          Company         Legal                     │
│ Features         About           Privacy Policy            │
│ Pricing          Contact         Terms of Service          │
│ Demo             Blog            Cookie Policy             │
│                                                            │
│ © 2025 Campaign Brain. Made for campaigns that fight.     │
│                                                            │
│ [Twitter] [LinkedIn]                                       │
└────────────────────────────────────────────────────────────┘

Mobile Navigation

  • Hamburger menu (standard)
  • "Start Free" button always visible
  • District search prominent on homepage

5. Technical Implementation

Stack

Component Technology
Framework FastHTML
Styling Campaign Brain CSS (from style guide)
Icons Lucide
District Data wikipedia-python + caching
Hosting Existing infrastructure
Forms HTMX for progressive enhancement

Key Routes

# routes.py

@app.get("/")
def homepage():
    """Main marketing page."""
    return MarketingLayout(
        Hero(),
        PainPoints(),
        Features(),
        DistrictTeaser(),
        FooterCTA(),
    )

@app.get("/features")
def features():
    """Detailed feature breakdown."""
    return MarketingLayout(FeaturesContent())

@app.get("/pricing")
def pricing():
    """Pricing tiers and FAQ."""
    return MarketingLayout(PricingContent())

@app.get("/demo")
def demo():
    """Video walkthrough or interactive preview."""
    return MarketingLayout(DemoContent())

@app.get("/start")
def start_flow():
    """Account creation wizard."""
    return MarketingLayout(SignupWizard(step=1))

@app.post("/start/step/{step}")
def signup_step(step: int, data: SignupData):
    """Handle signup wizard steps."""
    ...

@app.get("/district/{code}")
def district_page(code: str):
    """Dynamic district page (path-based fallback)."""
    return DistrictPage(code)

# Wildcard subdomain handler (configured at infrastructure level)
# {code}.nominate.ai → district_page(code)

District Data Service

# services/district_data.py

import wikipedia
from functools import lru_cache
from datetime import datetime, timedelta

CACHE_DURATION = timedelta(hours=48)

class DistrictDataService:
    """Fetch and cache district information."""

    def __init__(self):
        self.cache = {}  # In production: Redis

    def get_district_info(self, state: str, district: int) -> DistrictInfo:
        """Get district info, using cache if fresh."""
        cache_key = f"{state}{district:02d}"

        if self._is_cache_valid(cache_key):
            return self.cache[cache_key]["data"]

        info = self._fetch_district_info(state, district)
        self._cache_result(cache_key, info)
        return info

    def _fetch_district_info(self, state: str, district: int) -> DistrictInfo:
        """Fetch from Wikipedia and other sources."""
        state_name = STATE_NAMES[state]

        # Wikipedia search
        query = f"{state_name}'s {district}th congressional district"
        try:
            page = wikipedia.page(query)
            summary = wikipedia.summary(query, sentences=3)
        except wikipedia.DisambiguationError as e:
            # Handle disambiguation
            page = wikipedia.page(e.options[0])
            summary = page.summary[:500]
        except wikipedia.PageError:
            summary = f"Congressional district in {state_name}."

        return DistrictInfo(
            state=state,
            district=district,
            state_name=state_name,
            summary=summary,
            # Add: population, registered_voters, partisan_lean
            # from additional data sources
        )

Signup Flow Handler

# services/signup.py

from pydantic import BaseModel, EmailStr

class SignupStep1(BaseModel):
    campaign_name: str
    email: EmailStr
    password: str

class SignupStep2(BaseModel):
    state: str
    district: int
    race_type: str

async def create_tenant(step1: SignupStep1, step2: SignupStep2) -> Tenant:
    """Create new tenant from signup flow."""
    # Generate subdomain from campaign name
    subdomain = slugify(step1.campaign_name)

    # Create tenant via CBTENANT API
    tenant = await tenant_service.create(
        name=step1.campaign_name,
        subdomain=subdomain,
        admin_email=step1.email,
        admin_password=hash_password(step1.password),
        state=step2.state,
        district=step2.district,
        race_type=step2.race_type,
    )

    # Pre-load district voter data
    await voter_service.load_district_data(tenant.id, step2.state, step2.district)

    # Send welcome email
    await email_service.send_welcome(step1.email, tenant)

    return tenant

6. Content & Copy Guidelines

Voice & Tone

Do Don't
Direct, confident Corporate jargon
"You" focused "We" focused
Active voice Passive voice
Specific numbers Vague claims
Acknowledge pain points Ignore reality

Headlines Formula

[Benefit] without [Pain Point]

Examples:
• "Win Your Campaign. Not a PhD in Software."
• "Track 10,000 Voters. Not 10,000 Spreadsheets."
• "Automate Follow-Ups. Keep the Human Touch."

CTA Button Copy

Context Copy
Primary conversion "Start Free"
Secondary conversion "See Pricing"
Demo "Watch 2-Min Demo"
District pages "Start Your Campaign — Free"
Pricing page "Start Free Trial"

Microcopy

  • Form labels: Clear, no asterisks (everything required is required)
  • Error messages: Specific and helpful ("Email must include @")
  • Success states: Celebratory but brief ("You're in!")
  • Loading states: "Working..." or "Setting up your campaign..."

7. SEO & Marketing Integration

Target Keywords

Primary Secondary
campaign CRM political campaign software
voter outreach software campaign management tool
campaign management CRM volunteer coordination app
grassroots campaign tools voter database software

District Page SEO

Each dynamic district page becomes a landing page for: - "{State} {District} campaign tools" - "Run for Congress {State}" - "{District} voter data"

Example meta tags:

<title>Iowa CD-3 Campaign Tools | Campaign Brain</title>
<meta name="description" content="Everything you need to run
  a winning campaign in Iowa's 3rd Congressional District.
  Access 612,000 voter records, outreach tools, and AI-powered
  follow-ups.">

Conversion Tracking

Track these events: 1. Homepage visit 2. Pricing page view 3. Demo video start / complete 4. Signup wizard: Step 1 complete 5. Signup wizard: Step 2 complete 6. Account created (conversion) 7. District page view (with district code)


8. Launch Checklist

Phase 1: MVP (Week 1-2)

  • Homepage with hero, pain points, basic features
  • Pricing page with 3 tiers
  • Signup flow (3 steps)
  • Login redirect to tenant app
  • Basic footer with legal links

Phase 2: District Pages (Week 2-3)

  • District code parser
  • Wikipedia integration
  • District page template
  • Wildcard subdomain routing
  • Cache layer (Redis or file-based)
  • Fallback for invalid codes

Phase 3: Polish (Week 3-4)

  • Demo video or interactive preview
  • Features page with screenshots
  • Mobile responsive refinements
  • SEO meta tags
  • Analytics integration
  • Social proof (testimonials)

Phase 4: Growth (Ongoing)

  • Blog (content marketing)
  • Email capture for non-converters
  • A/B testing headlines
  • District page backlinks

9. Success Metrics

Metric Target (Month 1) Target (Month 3)
Homepage → Pricing 25% 35%
Pricing → Signup Start 15% 20%
Signup Start → Complete 60% 75%
District Page → Signup 10% 15%
Overall Conversion 2% 4%

Appendix A: District Code Reference

At-Large States (use 00):
ak00, de00, mt00, nd00, sd00, vt00, wy00

Multi-District Examples:
ca01-ca52 (52 districts)
tx01-tx38 (38 districts)
fl01-fl28 (28 districts)
ny01-ny26 (26 districts)

State Abbreviations:
AL, AK, AZ, AR, CA, CO, CT, DE, FL, GA, HI, ID, IL, IN, IA, KS,
KY, LA, ME, MD, MA, MI, MN, MS, MO, MT, NE, NV, NH, NJ, NM, NY,
NC, ND, OH, OK, OR, PA, RI, SC, SD, TN, TX, UT, VT, VA, WA, WV,
WI, WY

Appendix B: Sample District Data Response

{
  "code": "ia03",
  "state": "ia",
  "state_name": "Iowa",
  "district": 3,
  "title": "Iowa's 3rd Congressional District",
  "summary": "Iowa's 3rd congressional district is a congressional district in the U.S. state of Iowa. The district is anchored by Des Moines and includes the southwestern portion of the state.",
  "population": 847234,
  "registered_voters": 612000,
  "partisan_lean": "R+4.2",
  "counties": [
    "Polk (partial)",
    "Dallas",
    "Madison",
    "Warren",
    "Pottawattamie",
    "Mills"
  ],
  "current_representative": {
    "name": "Zach Nunn",
    "party": "Republican",
    "since": 2023
  },
  "cached_at": "2025-12-13T10:30:00Z",
  "cache_expires": "2025-12-15T10:30:00Z"
}

Plan Version 1.0 — December 2025