diff --git a/README.md b/README.md
index 5335097..ae44728 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ These aren't prompts. They're complete workflows — scripts, scoring algorithms
| [**Conversion Ops**](./conversion-ops/) | Score any landing page and turn survey data into lead magnets | CRO Audit, Survey-to-Lead-Magnet Engine |
| [**Podcast Ops**](./podcast-ops/) | One episode → 20+ content pieces across every platform | Podcast-to-Everything Pipeline, Content Calendar |
| [**Team Ops**](./team-ops/) | Ruthless performance audits and meeting intelligence | Elon Algorithm, Meeting-to-Action Extractor |
+| [**Sales Playbook**](./sales-playbook/) | Value-based pricing framework that turns $10K deals into $100K deals | Pre-Call Briefing, Tiered Packager, Call Analyzer, Pattern Library |
---
@@ -129,10 +130,16 @@ ai-marketing-skills/
├── podcast-ops/ ← Podcast → content factory
│ ├── SKILL.md
│ └── podcast_pipeline.py
-└── team-ops/ ← Performance audits + meeting intel
+├── team-ops/ ← Performance audits + meeting intel
+│ ├── SKILL.md
+│ ├── team_performance_audit.py
+│ └── meeting_action_extractor.py
+└── sales-playbook/ ← Value-based pricing framework
├── SKILL.md
- ├── team_performance_audit.py
- └── meeting_action_extractor.py
+ ├── value_pricing_briefing.py
+ ├── value_pricing_packager.py
+ ├── call_analyzer.py
+ └── pricing_pattern_library.py
```
---
diff --git a/sales-playbook/README.md b/sales-playbook/README.md
new file mode 100644
index 0000000..7fe17db
--- /dev/null
+++ b/sales-playbook/README.md
@@ -0,0 +1,218 @@
+# 💰 AI Sales Playbook — Value-Based Pricing & Deal Upselling
+
+> **Turn $10K/mo deals into $40-100K/mo using value-based pricing, not discounting.**
+
+A complete framework for value-based pricing in B2B services sales: pre-call competitive briefings, tiered package generation, post-call analysis, and a proven pattern library for training sales teams.
+
+These tools were built from real sales call patterns at [Single Grain](https://www.singlegrain.com/?utm_source=github&utm_medium=skill_repo&utm_campaign=ai_marketing_skills), where deals routinely moved from $10K/mo to $40-100K/mo using the techniques in this playbook. Now open-sourced for any sales team to use.
+
+---
+
+## The Framework
+
+The value-based pricing framework is built on 5 principles:
+
+1. **Lead with data, not your pitch** — Show competitive gaps before discussing services
+2. **Anchor high** — Present premium tier first so the target feels reasonable
+3. **Tie price to value** — Every dollar maps to projected ROI
+4. **Use competitive triggers** — Competitor data activates urgency
+5. **Present tiered options** — 3-4 tiers with clear tradeoffs
+
+---
+
+## Tools
+
+### 1. 📊 Pre-Call Briefing Generator (`value_pricing_briefing.py`)
+
+Walk into every call armed with competitive data that makes the prospect sell themselves on the value.
+
+**What it generates:**
+- Anchor data points (keyword gaps, traffic gaps vs. competitors)
+- Competitive triggers ("CompetitorA is #1 for [keyword], you're #14")
+- Value calculations (position improvement → traffic → paid equivalent value)
+- Conversation hooks (opening questions to surface pain)
+- Objection pre-empts (responses for 6 common objections at this deal size)
+
+```bash
+# Basic briefing
+python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com,comp2.com"
+
+# With industry and deal target
+python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com" --industry saas --deal-target 80000
+
+# JSON output
+python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com,comp2.com" --format json
+```
+
+### 2. 📦 Tiered Package Builder (`value_pricing_packager.py`)
+
+Auto-generates S/M/L + performance-based pricing tiers with pricing psychology built in.
+
+**Tiers generated:**
+| Tier | Purpose | Price vs. Target |
+|------|---------|-----------------|
+| **Powerhouse** | The anchor (makes everything else look reasonable) | 130-150% |
+| **Value** ⭐ | Where you want them to land | 100% |
+| **Baseline** | Floor (proves the model before scaling) | 40-50% |
+| **Performance** | Skin in the game (lower base + bonus triggers) | 30-40% base |
+
+Each tier includes: specific deliverables, monthly price, ROI projection, included vs. excluded features.
+
+```bash
+# Full package generation
+python3 value_pricing_packager.py --target-monthly 80000 --services "seo,cro,content,paid"
+
+# With current spend context
+python3 value_pricing_packager.py --target-monthly 50000 --services "seo,content" --current-spend 10000
+
+# JSON output for integration
+python3 value_pricing_packager.py --target-monthly 80000 --services "seo,cro,content,paid" --format json
+```
+
+### 3. 🎯 Post-Call Deal Analyzer (`call_analyzer.py`)
+
+Score any sales call transcript against the value-based pricing framework.
+
+**Scoring criteria (0-100):**
+| Criterion | Points |
+|-----------|--------|
+| Showed data before pitching | 20 |
+| Presented tiered options | 20 |
+| Anchored high first | 15 |
+| Tied price to value/ROI | 15 |
+| Used competitive triggers | 15 |
+| Got prospect to state their own pain | 15 |
+
+Also extracts: buying signals, objections (categorized), deal probability, upsell opportunities, and recommended next steps.
+
+```bash
+# Analyze a transcript file
+python3 call_analyzer.py --transcript call.txt
+
+# Pipe from stdin
+cat call.txt | python3 call_analyzer.py
+
+# JSON output
+python3 call_analyzer.py --transcript call.txt --format json
+```
+
+### 4. 📚 Pattern Library & Training (`pricing_pattern_library.py`)
+
+10 proven value-based pricing patterns with detailed breakdowns, example dialogue, and interactive training.
+
+**Patterns included:**
+1. Anchor With Data
+2. Tiered Packaging (S/M/L + Performance)
+3. Competitive Ego Trigger
+4. Strategic Involvement Upsell
+5. Bridge Offer
+6. Performance Skin-in-Game
+7. Value Math on Screen
+8. Compound Effect Close
+9. Reference Customer Drop
+10. In-House Team Framing
+
+```bash
+# List all patterns
+python3 pricing_pattern_library.py --list
+
+# Deep dive on a pattern
+python3 pricing_pattern_library.py --pattern "anchor-with-data"
+
+# Get recommendations for a scenario
+python3 pricing_pattern_library.py --scenario "prospect is a $50M SaaS company spending $15K/mo on marketing"
+
+# Interactive training quiz
+python3 pricing_pattern_library.py --quiz
+```
+
+---
+
+## Quick Start
+
+### 1. Clone and install
+
+```bash
+git clone https://github.com/nichochar/ai-marketing-skills.git
+cd ai-marketing-skills/sales-playbook
+pip install -r requirements.txt
+```
+
+### 2. Run a pre-call briefing
+
+```bash
+python3 value_pricing_briefing.py --domain acme.com --competitors "techstart.com,novapay.com" --deal-target 80000
+```
+
+### 3. Generate pricing tiers
+
+```bash
+python3 value_pricing_packager.py --target-monthly 80000 --services "seo,cro,content,paid" --current-spend 15000
+```
+
+### 4. Analyze a call
+
+```bash
+python3 call_analyzer.py --transcript sample_call.txt
+```
+
+### 5. Study the patterns
+
+```bash
+python3 pricing_pattern_library.py --list
+python3 pricing_pattern_library.py --quiz
+```
+
+---
+
+## Optional API Integration
+
+All scripts work without API keys using built-in stubs. For live data:
+
+| API | Used By | Env Variable |
+|-----|---------|-------------|
+| [Ahrefs](https://ahrefs.com/api) | Briefing Generator | `AHREFS_API_KEY` |
+| [SEMrush](https://developer.semrush.com) | Briefing Generator | `SEMRUSH_API_KEY` |
+| [Anthropic](https://docs.anthropic.com) | Call Analyzer, Pattern Library | `ANTHROPIC_API_KEY` |
+| [OpenAI](https://platform.openai.com) | Call Analyzer, Pattern Library | `OPENAI_API_KEY` |
+
+---
+
+## File Structure
+
+```
+sales-playbook/
+├── README.md # This file
+├── SKILL.md # Claude Code skill definition
+├── requirements.txt # Python dependencies
+├── value_pricing_briefing.py # Pre-call briefing generator
+├── value_pricing_packager.py # Tiered package builder
+├── call_analyzer.py # Post-call deal analyzer
+└── pricing_pattern_library.py # Pattern library & training
+```
+
+---
+
+## How It Works Together
+
+1. **Before the call:** Run the briefing generator to get competitive data, value calculations, and conversation hooks
+2. **Preparing the proposal:** Use the package builder to generate tiered pricing with ROI projections
+3. **After the call:** Run the call analyzer to score the conversation and identify next steps
+4. **Ongoing training:** Use the pattern library to study and practice the 10 core patterns
+5. **Continuous improvement:** Analyze call scores over time to identify which patterns your team needs to practice
+
+The result: a systematic approach to value-based pricing that turns data into leverage and conversations into larger deals.
+
+---
+
+
+
+**🧠 [Want these built and managed for you? →](https://singlebrain.com/?utm_source=github&utm_medium=skill_repo&utm_campaign=ai_marketing_skills)**
+
+*This is how we build agents at [Single Brain](https://singlebrain.com/?utm_source=github&utm_medium=skill_repo&utm_campaign=ai_marketing_skills) for our clients.*
+
+[Single Grain](https://www.singlegrain.com/?utm_source=github&utm_medium=skill_repo&utm_campaign=ai_marketing_skills) · our marketing agency
+
+📬 **[Level up your marketing with 14,000+ marketers and founders →](https://levelingup.beehiiv.com/subscribe)** *(free)*
+
+
diff --git a/sales-playbook/SKILL.md b/sales-playbook/SKILL.md
new file mode 100644
index 0000000..f660504
--- /dev/null
+++ b/sales-playbook/SKILL.md
@@ -0,0 +1,81 @@
+# AI Sales Playbook — Value-Based Pricing & Deal Upselling
+
+## Preamble (runs on skill start)
+
+```bash
+# Version check (silent if up to date)
+python3 telemetry/version_check.py 2>/dev/null || true
+
+# Telemetry opt-in (first run only, then remembers your choice)
+python3 telemetry/telemetry_init.py 2>/dev/null || true
+```
+
+> **Privacy:** This skill logs usage locally to `~/.ai-marketing-skills/analytics/`. Remote telemetry is opt-in only. No code, file paths, or repo content is ever collected. See `telemetry/README.md`.
+
+---
+
+Framework for value-based pricing that moves deals from $10K/mo → $40-100K/mo. Pre-call briefings, tiered package generation, post-call analysis, and a pattern library for training sales teams on proven pricing techniques.
+
+## When to Use
+
+Use this skill when:
+- Preparing for a sales call and need competitive data to anchor on value
+- Building tiered pricing proposals for prospects at different deal sizes
+- Analyzing sales call transcripts to score against the value-based pricing framework
+- Training sales reps on proven pricing patterns and objection handling
+- Upselling existing deals by identifying missed value levers
+
+## Tools
+
+### Pre-Call Preparation
+
+| Script | Purpose | Key Command |
+|--------|---------|-------------|
+| `value_pricing_briefing.py` | Generate pre-call briefing with competitive data, value calcs, and conversation hooks | `python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com,comp2.com"` |
+| `value_pricing_packager.py` | Generate tiered S/M/L + performance pricing packages | `python3 value_pricing_packager.py --target-monthly 80000 --services "seo,cro,content,paid"` |
+
+### Post-Call Analysis
+
+| Script | Purpose | Key Command |
+|--------|---------|-------------|
+| `call_analyzer.py` | Score a call transcript against the value-based pricing framework | `python3 call_analyzer.py --transcript call.txt` |
+| `pricing_pattern_library.py` | Reference library of 10 proven pricing patterns + training mode | `python3 pricing_pattern_library.py --list` |
+
+## Configuration
+
+All scripts use environment variables for API keys:
+
+### Optional Environment Variables
+
+- `AHREFS_API_KEY` — Ahrefs API key (Briefing Generator, optional — uses stubs without it)
+- `SEMRUSH_API_KEY` — SEMrush API key (Briefing Generator, optional — uses stubs without it)
+- `ANTHROPIC_API_KEY` — Anthropic API key (Call Analyzer, Pattern Library scenario mode)
+- `OPENAI_API_KEY` — OpenAI API key (alternative to Anthropic for LLM features)
+
+Scripts work without API keys using built-in stubs and sample data for testing.
+
+## Key Concepts
+
+### The Value-Based Pricing Framework
+
+1. **Lead with data, not your pitch** — Show the prospect their competitive gaps before discussing services
+2. **Anchor high** — Present the premium tier first so the target tier feels reasonable
+3. **Tie price to value** — Every dollar of investment maps to projected ROI
+4. **Use competitive triggers** — Competitor rankings activate urgency without being pushy
+5. **Present tiered options** — 3-4 tiers with clear tradeoffs, always including a performance option
+
+### Pricing Framework Score (0-100)
+
+The call analyzer scores calls against these criteria:
+- Showed data before pitching (20 pts)
+- Presented tiered options (20 pts)
+- Anchored high first (15 pts)
+- Tied price to value/ROI (15 pts)
+- Used competitive triggers (15 pts)
+- Got prospect to state their own pain (15 pts)
+
+## Dependencies
+
+- Python 3.9+
+- `requests` (for API integrations)
+- No other external dependencies
diff --git a/sales-playbook/call_analyzer.py b/sales-playbook/call_analyzer.py
new file mode 100644
index 0000000..292af8c
--- /dev/null
+++ b/sales-playbook/call_analyzer.py
@@ -0,0 +1,542 @@
+#!/usr/bin/env python3
+"""
+Value-Based Pricing: Post-Call Deal Analyzer
+
+Feed in a sales call transcript → extracts signals, scores the call against
+the value-based pricing framework, and identifies upsell opportunities.
+
+Usage:
+ python3 call_analyzer.py --transcript call.txt
+ cat call.txt | python3 call_analyzer.py
+ python3 call_analyzer.py --transcript call.txt --format json
+"""
+
+import argparse
+import json
+import os
+import re
+import sys
+from datetime import datetime
+
+# ---------------------------------------------------------------------------
+# LLM Integration Stubs
+# ---------------------------------------------------------------------------
+# To use real LLM analysis:
+# 1. Set ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable
+# 2. The stub below will be replaced with actual API calls
+# 3. Anthropic docs: https://docs.anthropic.com/en/api
+# 4. OpenAI docs: https://platform.openai.com/docs/api-reference
+
+
+def _call_llm(prompt: str, system_prompt: str = "") -> str:
+ """
+ Stub: Call LLM for transcript analysis.
+
+ In production, call:
+ POST https://api.anthropic.com/v1/messages
+ POST https://api.openai.com/v1/chat/completions
+ """
+ anthropic_key = os.environ.get("ANTHROPIC_API_KEY")
+ openai_key = os.environ.get("OPENAI_API_KEY")
+
+ if anthropic_key:
+ # TODO: Implement real Anthropic API call
+ # import requests
+ # resp = requests.post(
+ # "https://api.anthropic.com/v1/messages",
+ # headers={"x-api-key": anthropic_key, "anthropic-version": "2023-06-01", "content-type": "application/json"},
+ # json={"model": "claude-sonnet-4-20250514", "max_tokens": 4096, "system": system_prompt, "messages": [{"role": "user", "content": prompt}]},
+ # )
+ # return resp.json()["content"][0]["text"]
+ pass
+
+ if openai_key:
+ # TODO: Implement real OpenAI API call
+ # import requests
+ # messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": prompt}] if system_prompt else [{"role": "user", "content": prompt}]
+ # resp = requests.post(
+ # "https://api.openai.com/v1/chat/completions",
+ # headers={"Authorization": f"Bearer {openai_key}", "Content-Type": "application/json"},
+ # json={"model": "gpt-4o", "messages": messages, "max_tokens": 4096},
+ # )
+ # return resp.json()["choices"][0]["message"]["content"]
+ pass
+
+ # Fallback: rule-based analysis (no LLM available)
+ return None
+
+
+# ---------------------------------------------------------------------------
+# Rule-Based Signal Detection (fallback when no LLM available)
+# ---------------------------------------------------------------------------
+
+BUYING_SIGNAL_PATTERNS = {
+ "budget_confirmed": {
+ "patterns": [
+ r"budget\s+(?:is|of|around)\s+\$?[\d,]+",
+ r"we(?:'ve| have)\s+(?:allocated|set aside|budgeted)",
+ r"spend(?:ing)?\s+(?:about|around|roughly)\s+\$?[\d,]+",
+ r"our\s+budget\s+(?:for|this)",
+ ],
+ "weight": 25,
+ "description": "Budget discussed or confirmed",
+ },
+ "timeline_established": {
+ "patterns": [
+ r"(?:start|launch|begin|kick off)\s+(?:in|by|before|next)\s+(?:Q[1-4]|January|February|March|April|May|June|July|August|September|October|November|December|\d+\s+(?:weeks?|months?))",
+ r"(?:need|want)\s+(?:this|results|something)\s+(?:by|before|in)",
+ r"(?:timeline|timeframe|deadline)\s+(?:is|would be)",
+ r"ASAP|as soon as possible|urgent",
+ ],
+ "weight": 20,
+ "description": "Timeline or urgency established",
+ },
+ "decision_maker_present": {
+ "patterns": [
+ r"I\s+(?:can|will|am able to)\s+(?:make|approve|sign off)",
+ r"(?:CEO|CMO|VP|CRO|founder|owner|partner)\s+(?:here|speaking|on the call)",
+ r"I\s+(?:don't|do not)\s+need\s+(?:anyone else|approval)",
+ r"the\s+decision\s+(?:is|rests)\s+with\s+me",
+ ],
+ "weight": 20,
+ "description": "Decision maker is present on the call",
+ },
+ "competitive_urgency": {
+ "patterns": [
+ r"competitor[s]?\s+(?:is|are|has|have)\s+(?:doing|beating|ahead|winning|ranking)",
+ r"(?:losing|lost)\s+(?:market share|traffic|rankings|customers)\s+to",
+ r"(?:we need to|have to|must)\s+(?:catch up|compete|keep up)",
+ r"(?:they|competitor)\s+(?:just|recently)\s+(?:launched|started|hired)",
+ ],
+ "weight": 15,
+ "description": "Competitive urgency expressed",
+ },
+ "pain_stated": {
+ "patterns": [
+ r"(?:struggling|frustrated|disappointed|unhappy)\s+with",
+ r"(?:not getting|haven't seen|can't get)\s+(?:results|ROI|traffic|leads)",
+ r"(?:our|the)\s+(?:current|existing)\s+(?:agency|vendor|team)\s+(?:isn't|is not|hasn't)",
+ r"(?:we're|we are)\s+(?:behind|falling behind|not where we)",
+ ],
+ "weight": 20,
+ "description": "Prospect stated their pain/frustration",
+ },
+}
+
+OBJECTION_PATTERNS = {
+ "price": {
+ "patterns": [
+ r"(?:too\s+)?(?:expensive|pricey|costly|much|high)",
+ r"(?:can't|cannot)\s+(?:afford|justify|spend)\s+that",
+ r"(?:over|above|exceeds)\s+(?:our|the)\s+budget",
+ r"(?:less|lower|cheaper|discount|negotiate)",
+ ],
+ "description": "Price objection",
+ },
+ "timing": {
+ "patterns": [
+ r"(?:not|bad)\s+(?:the right|a good)\s+time",
+ r"(?:next|after)\s+(?:quarter|year|Q[1-4])",
+ r"(?:need|want)\s+(?:to wait|more time|to think)",
+ r"(?:revisit|circle back|touch base)\s+(?:later|in|next)",
+ ],
+ "description": "Timing objection",
+ },
+ "authority": {
+ "patterns": [
+ r"(?:need|have)\s+to\s+(?:check|ask|run it by|discuss with|get approval)",
+ r"(?:my|the)\s+(?:boss|CEO|board|team|partner)\s+(?:needs to|has to|would need)",
+ r"(?:not|can't)\s+(?:my|the)\s+(?:decision|call)\s+(?:alone|to make)",
+ ],
+ "description": "Authority objection (not the decision maker)",
+ },
+ "need": {
+ "patterns": [
+ r"(?:not sure|don't know)\s+(?:if|that)\s+we\s+(?:need|require)",
+ r"(?:already|currently)\s+(?:doing|have|using)\s+(?:something|a|an)",
+ r"(?:what|how)\s+(?:is|would be)\s+(?:different|better)\s+(?:than|from)",
+ ],
+ "description": "Need objection (don't see the value)",
+ },
+ "competition": {
+ "patterns": [
+ r"(?:also|already)\s+(?:talking to|evaluating|looking at)\s+(?:other|another)",
+ r"(?:comparing|comparison|vs|versus)\s+(?:other|another|your competitors)",
+ r"(?:got|received|have)\s+(?:other|another|competing)\s+(?:proposals?|quotes?|bids?)",
+ ],
+ "description": "Competition objection (evaluating others)",
+ },
+}
+
+# ---------------------------------------------------------------------------
+# Pricing Framework Scoring
+# ---------------------------------------------------------------------------
+
+FRAMEWORK_CRITERIA = {
+ "showed_data_before_pitching": {
+ "max_points": 20,
+ "description": "Did they show data before pitching?",
+ "patterns": [
+ r"(?:let me|I want to)\s+(?:show|share|pull up)\s+(?:some|the|your)\s+(?:data|numbers|metrics)",
+ r"(?:before|let me start|first)\s+.*(?:data|research|analysis|numbers)",
+ r"(?:I|we)\s+(?:pulled|looked at|analyzed)\s+(?:your|the)\s+(?:data|metrics|rankings|traffic)",
+ ],
+ },
+ "presented_tiered_options": {
+ "max_points": 20,
+ "description": "Did they present tiered options?",
+ "patterns": [
+ r"(?:three|3|four|4|multiple)\s+(?:options?|tiers?|packages?|levels?)",
+ r"(?:option|tier|package)\s+(?:one|two|three|A|B|C|1|2|3)",
+ r"(?:baseline|value|powerhouse|premium|standard|performance)",
+ ],
+ },
+ "anchored_high_first": {
+ "max_points": 15,
+ "description": "Did they anchor high first?",
+ "patterns": [
+ r"(?:first|top|premium|highest|most comprehensive)\s+(?:option|tier|package)",
+ r"(?:start|begin)\s+with\s+(?:the|our)\s+(?:most|top|full|comprehensive)",
+ r"(?:if you want|for maximum|the full)\s+.*(?:\$[\d,]+)",
+ ],
+ },
+ "tied_price_to_value": {
+ "max_points": 15,
+ "description": "Did they tie price to value/ROI?",
+ "patterns": [
+ r"(?:ROI|return|value)\s+(?:of|would be|is)\s+(?:about|roughly|around)?\s*\$?[\d,]+",
+ r"(?:for every|per)\s+\$[\d,]+\s+(?:you|invested)",
+ r"(?:traffic|leads|revenue)\s+(?:worth|valued at|equivalent)\s+\$[\d,]+",
+ r"(?:payback|pays for itself|break even)\s+(?:in|within)\s+\d+",
+ ],
+ },
+ "used_competitive_triggers": {
+ "max_points": 15,
+ "description": "Did they use competitive triggers?",
+ "patterns": [
+ r"(?:your|the)\s+competitor\s+(?:is|has|ranks|gets)",
+ r"(?:they|CompetitorA|competitor)\s+(?:rank|are)\s+(?:#|number)\s*\d+",
+ r"(?:gap|behind|ahead)\s+(?:of|from|vs)\s+(?:your|the)\s+competitor",
+ r"(?:losing|left behind|falling behind)\s+.*(?:competitor|market)",
+ ],
+ },
+ "prospect_stated_own_pain": {
+ "max_points": 15,
+ "description": "Did they get the prospect to state their own pain?",
+ "patterns": [
+ r"(?:what|where)\s+(?:are|is)\s+(?:your|the)\s+biggest\s+(?:challenge|pain|frustration|problem)",
+ r"(?:tell me|walk me through|describe)\s+.*(?:challenge|struggle|issue|problem)",
+ r"(?:what|how)\s+(?:would|does)\s+(?:success|ideal|better)\s+look like",
+ # These detect the PROSPECT responding with pain
+ r"(?:we're|we are|I'm|I am)\s+(?:struggling|frustrated|worried|concerned)",
+ ],
+ },
+}
+
+
+def _detect_patterns(text: str, patterns: list) -> list:
+ """Find all pattern matches in text."""
+ matches = []
+ text_lower = text.lower()
+ for pattern in patterns:
+ found = re.findall(pattern, text_lower)
+ matches.extend(found)
+ return matches
+
+
+def analyze_transcript_rules(transcript: str) -> dict:
+ """Analyze transcript using rule-based pattern matching (no LLM)."""
+ # Detect buying signals
+ buying_signals = []
+ for signal_key, config in BUYING_SIGNAL_PATTERNS.items():
+ matches = _detect_patterns(transcript, config["patterns"])
+ if matches:
+ buying_signals.append({
+ "signal": signal_key,
+ "description": config["description"],
+ "weight": config["weight"],
+ "evidence_count": len(matches),
+ "sample_evidence": matches[:3],
+ })
+
+ # Detect objections
+ objections = []
+ for obj_key, config in OBJECTION_PATTERNS.items():
+ matches = _detect_patterns(transcript, config["patterns"])
+ if matches:
+ objections.append({
+ "category": obj_key,
+ "description": config["description"],
+ "evidence_count": len(matches),
+ "sample_evidence": matches[:3],
+ })
+
+ # Score pricing framework
+ framework_scores = {}
+ total_score = 0
+ for criterion_key, config in FRAMEWORK_CRITERIA.items():
+ matches = _detect_patterns(transcript, config["patterns"])
+ score = min(config["max_points"], len(matches) * (config["max_points"] // 2))
+ framework_scores[criterion_key] = {
+ "description": config["description"],
+ "max_points": config["max_points"],
+ "score": score,
+ "evidence_found": len(matches) > 0,
+ "evidence_count": len(matches),
+ }
+ total_score += score
+
+ # Deal probability estimate
+ signal_weight = sum(s["weight"] for s in buying_signals)
+ objection_penalty = len(objections) * 10
+ deal_probability = min(95, max(5, signal_weight + (total_score // 2) - objection_penalty))
+
+ # Recommended next steps
+ next_steps = _generate_next_steps(buying_signals, objections, framework_scores, total_score)
+
+ # Upsell opportunities
+ upsell_opps = _identify_upsell_opportunities(transcript, buying_signals)
+
+ return {
+ "buying_signals": buying_signals,
+ "objections": objections,
+ "framework_scores": framework_scores,
+ "total_framework_score": total_score,
+ "deal_probability": deal_probability,
+ "next_steps": next_steps,
+ "upsell_opportunities": upsell_opps,
+ "analysis_method": "rule-based (set ANTHROPIC_API_KEY or OPENAI_API_KEY for LLM-powered analysis)",
+ }
+
+
+def _generate_next_steps(buying_signals: list, objections: list, framework_scores: dict, total_score: int) -> list:
+ """Generate recommended next steps based on analysis."""
+ steps = []
+ signal_keys = {s["signal"] for s in buying_signals}
+ objection_keys = {o["category"] for o in objections}
+
+ # Address objections first
+ if "price" in objection_keys:
+ steps.append({
+ "priority": "high",
+ "action": "Send ROI analysis",
+ "detail": "Prospect raised price concerns. Send a detailed ROI breakdown showing the cost-of-inaction vs. investment. Include competitive data showing what they're leaving on the table.",
+ })
+ if "authority" in objection_keys:
+ steps.append({
+ "priority": "high",
+ "action": "Identify and engage decision maker",
+ "detail": "Prospect indicated they need approval from someone else. Request an intro to the decision maker and offer to present directly. Prepare an executive summary.",
+ })
+ if "timing" in objection_keys:
+ steps.append({
+ "priority": "medium",
+ "action": "Create urgency with competitive data",
+ "detail": "Prospect wants to delay. Send competitive intelligence showing what competitors are doing NOW. Frame the cost of waiting in terms of lost ground.",
+ })
+ if "competition" in objection_keys:
+ steps.append({
+ "priority": "high",
+ "action": "Differentiate with case study",
+ "detail": "Prospect is evaluating other options. Send a relevant case study and offer a reference customer call. Emphasize your unique methodology and results.",
+ })
+
+ # Build on buying signals
+ if "budget_confirmed" in signal_keys:
+ steps.append({
+ "priority": "high",
+ "action": "Send tiered proposal within 24 hours",
+ "detail": "Budget is confirmed. Strike while warm. Send the proposal with tiers anchored around the confirmed budget.",
+ })
+ if "competitive_urgency" in signal_keys:
+ steps.append({
+ "priority": "high",
+ "action": "Send competitive gap report",
+ "detail": "Prospect expressed competitive anxiety. Send a detailed competitive analysis showing exactly where they're falling behind and the trajectory if nothing changes.",
+ })
+
+ # Framework improvement suggestions
+ if total_score < 50:
+ steps.append({
+ "priority": "medium",
+ "action": "Schedule follow-up with better framework execution",
+ "detail": f"Framework score was {total_score}/100. Key gaps: {', '.join(k for k, v in framework_scores.items() if not v['evidence_found'])}. Schedule a follow-up call and lead with data + tiered options.",
+ })
+
+ # Default follow-up
+ if not steps:
+ steps.append({
+ "priority": "medium",
+ "action": "Send summary email with next steps",
+ "detail": "Send a concise recap of the conversation, key takeaways, and propose a clear next step (proposal, follow-up call, or pilot).",
+ })
+
+ return steps
+
+
+def _identify_upsell_opportunities(transcript: str, buying_signals: list) -> list:
+ """Identify potential upsell opportunities from conversation."""
+ opportunities = []
+ text_lower = transcript.lower()
+
+ if any(term in text_lower for term in ["content", "blog", "articles", "thought leadership"]):
+ opportunities.append({
+ "opportunity": "Content Marketing Add-On",
+ "signal": "Prospect mentioned content needs during the call",
+ "suggested_approach": "Position content as a compound multiplier for SEO results. 'The SEO work creates the foundation, but content is the fuel. Without it, you're leaving 40-60% of the potential on the table.'",
+ })
+
+ if any(term in text_lower for term in ["conversion", "convert", "leads", "pipeline", "funnel"]):
+ opportunities.append({
+ "opportunity": "CRO / Conversion Optimization",
+ "signal": "Prospect discussed conversion or lead generation challenges",
+ "suggested_approach": "Position CRO as the force multiplier. 'Getting more traffic is half the equation. If your conversion rate goes from 2% to 4%, you just doubled pipeline without spending another dollar on traffic.'",
+ })
+
+ if any(term in text_lower for term in ["paid", "ads", "google ads", "ppc", "media spend", "ad spend"]):
+ opportunities.append({
+ "opportunity": "Paid Media Management",
+ "signal": "Prospect mentioned paid channels",
+ "suggested_approach": "Position organic + paid as complementary. 'Most companies overspend on paid because their organic isn't pulling its weight. We optimize both so you're not paying for clicks you could be earning.'",
+ })
+
+ if any(term in text_lower for term in ["strategy", "strategic", "advisor", "consulting", "leadership"]):
+ opportunities.append({
+ "opportunity": "Strategic Involvement Upsell",
+ "signal": "Prospect values strategic guidance",
+ "suggested_approach": "Position senior strategic involvement as the premium lever. 'Same team, same execution. Add a dedicated senior strategist who joins your leadership meetings and aligns marketing with business objectives. That's the difference between execution and transformation.'",
+ })
+
+ if any(term in text_lower for term in ["international", "global", "multiple markets", "expansion"]):
+ opportunities.append({
+ "opportunity": "International / Multi-Market Expansion",
+ "signal": "Prospect has international or multi-market ambitions",
+ "suggested_approach": "Position multi-market SEO as a separate workstream. 'International SEO is a different discipline. We can layer that on with dedicated regional keyword research and localized content strategy.'",
+ })
+
+ return opportunities
+
+
+def format_scorecard(analysis: dict) -> str:
+ """Format analysis as a readable scorecard."""
+ lines = []
+ lines.append("# 📊 Sales Call Scorecard")
+ lines.append(f"*Analysis method: {analysis['analysis_method']}*")
+ lines.append("")
+
+ # Top-line metrics
+ score = analysis["total_framework_score"]
+ prob = analysis["deal_probability"]
+ score_emoji = "🟢" if score >= 70 else "🟡" if score >= 40 else "🔴"
+ prob_emoji = "🟢" if prob >= 60 else "🟡" if prob >= 30 else "🔴"
+
+ lines.append(f"## {score_emoji} Framework Score: {score}/100")
+ lines.append(f"## {prob_emoji} Deal Probability: {prob}%")
+ lines.append("")
+
+ # Framework breakdown
+ lines.append("## Pricing Framework Breakdown")
+ lines.append("")
+ lines.append("| Criterion | Score | Max | Status |")
+ lines.append("|-----------|-------|-----|--------|")
+ for key, fs in analysis["framework_scores"].items():
+ status = "✅" if fs["evidence_found"] else "❌"
+ lines.append(f"| {fs['description']} | {fs['score']} | {fs['max_points']} | {status} |")
+ lines.append("")
+
+ # Buying signals
+ lines.append("## 🟢 Buying Signals Detected")
+ if analysis["buying_signals"]:
+ for s in analysis["buying_signals"]:
+ lines.append(f"- **{s['description']}** (weight: {s['weight']}, evidence: {s['evidence_count']})")
+ else:
+ lines.append("- No clear buying signals detected. Consider whether the prospect is truly qualified.")
+ lines.append("")
+
+ # Objections
+ lines.append("## 🔴 Objections Raised")
+ if analysis["objections"]:
+ for o in analysis["objections"]:
+ lines.append(f"- **{o['description']}** ({o['category']}, evidence: {o['evidence_count']})")
+ else:
+ lines.append("- No objections detected (or they weren't surfaced).")
+ lines.append("")
+
+ # Upsell opportunities
+ if analysis["upsell_opportunities"]:
+ lines.append("## 💡 Upsell Opportunities")
+ for u in analysis["upsell_opportunities"]:
+ lines.append(f"### {u['opportunity']}")
+ lines.append(f"*Signal:* {u['signal']}")
+ lines.append(f"*Approach:* {u['suggested_approach']}")
+ lines.append("")
+
+ # Next steps
+ lines.append("## ⏭️ Recommended Next Steps")
+ for i, step in enumerate(analysis["next_steps"], 1):
+ priority_icon = "🔴" if step["priority"] == "high" else "🟡" if step["priority"] == "medium" else "🟢"
+ lines.append(f"{i}. {priority_icon} **{step['action']}** [{step['priority']}]")
+ lines.append(f" {step['detail']}")
+ lines.append("")
+
+ return "\n".join(lines)
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Value-Based Pricing: Post-Call Deal Analyzer",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog="""
+Examples:
+ python3 call_analyzer.py --transcript call.txt
+ cat call.txt | python3 call_analyzer.py
+ python3 call_analyzer.py --transcript call.txt --format json
+ """,
+ )
+ parser.add_argument("--transcript", help="Path to transcript file (reads from stdin if not provided)")
+ parser.add_argument("--format", choices=["markdown", "json", "both"], default="markdown", help="Output format (default: markdown)")
+
+ args = parser.parse_args()
+
+ # Read transcript
+ if args.transcript:
+ try:
+ with open(args.transcript, "r") as f:
+ transcript = f.read()
+ except FileNotFoundError:
+ print(f"Error: File not found: {args.transcript}", file=sys.stderr)
+ sys.exit(1)
+ elif not sys.stdin.isatty():
+ transcript = sys.stdin.read()
+ else:
+ print("Error: Provide --transcript FILE or pipe transcript via stdin", file=sys.stderr)
+ sys.exit(1)
+
+ if not transcript.strip():
+ print("Error: Empty transcript", file=sys.stderr)
+ sys.exit(1)
+
+ # Try LLM analysis first, fall back to rule-based
+ llm_result = _call_llm(
+ prompt=f"Analyze this sales call transcript against a value-based pricing framework:\n\n{transcript[:8000]}",
+ system_prompt="You are a sales call analyzer. Extract buying signals, objections, and score the call against value-based pricing principles.",
+ )
+
+ # Use rule-based analysis (LLM stubs not yet implemented)
+ analysis = analyze_transcript_rules(transcript)
+ analysis["generated_at"] = datetime.now().isoformat()
+ analysis["transcript_length"] = len(transcript)
+ analysis["transcript_word_count"] = len(transcript.split())
+
+ if args.format == "json":
+ print(json.dumps(analysis, indent=2))
+ elif args.format == "both":
+ print(format_scorecard(analysis))
+ print("\n---\n## Raw JSON\n")
+ print(json.dumps(analysis, indent=2))
+ else:
+ print(format_scorecard(analysis))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/sales-playbook/pricing_pattern_library.py b/sales-playbook/pricing_pattern_library.py
new file mode 100644
index 0000000..ae49fb1
--- /dev/null
+++ b/sales-playbook/pricing_pattern_library.py
@@ -0,0 +1,724 @@
+#!/usr/bin/env python3
+"""
+Value-Based Pricing: Pattern Library & Training
+
+A reference library of 10 proven value-based pricing patterns, usable as both
+a training tool and a real-time sales assistant.
+
+Usage:
+ python3 pricing_pattern_library.py --list
+ python3 pricing_pattern_library.py --pattern "anchor-with-data"
+ python3 pricing_pattern_library.py --scenario "prospect is a $50M SaaS company spending $15K/mo on marketing"
+ python3 pricing_pattern_library.py --quiz
+"""
+
+import argparse
+import json
+import os
+import random
+import sys
+from datetime import datetime
+
+# ---------------------------------------------------------------------------
+# LLM Integration Stubs
+# ---------------------------------------------------------------------------
+
+
+def _call_llm(prompt: str, system_prompt: str = "") -> str:
+ """
+ Stub: Call LLM for scenario analysis.
+
+ In production, replace with:
+ POST https://api.anthropic.com/v1/messages (ANTHROPIC_API_KEY)
+ POST https://api.openai.com/v1/chat/completions (OPENAI_API_KEY)
+ """
+ anthropic_key = os.environ.get("ANTHROPIC_API_KEY")
+ openai_key = os.environ.get("OPENAI_API_KEY")
+
+ if anthropic_key:
+ # TODO: Implement real Anthropic API call
+ # import requests
+ # resp = requests.post(
+ # "https://api.anthropic.com/v1/messages",
+ # headers={"x-api-key": anthropic_key, "anthropic-version": "2023-06-01", "content-type": "application/json"},
+ # json={"model": "claude-sonnet-4-20250514", "max_tokens": 4096, "system": system_prompt, "messages": [{"role": "user", "content": prompt}]},
+ # )
+ # return resp.json()["content"][0]["text"]
+ pass
+
+ if openai_key:
+ # TODO: Implement real OpenAI API call
+ pass
+
+ return None
+
+
+# ---------------------------------------------------------------------------
+# Pattern Library
+# ---------------------------------------------------------------------------
+# ALL examples are FULLY ANONYMIZED. No real company names, people, or revenue numbers.
+
+PATTERNS = {
+ "anchor-with-data": {
+ "name": "Anchor With Data",
+ "tagline": "Open with their competitive data, not your pitch. Let the gap sell the urgency.",
+ "description": (
+ "Before you say a single word about what you do or what you charge, show the prospect "
+ "their own competitive landscape. Pull their keyword rankings, traffic data, and "
+ "competitor positions. When they see the gap between where they are and where their "
+ "competitor is, the urgency sells itself. You're not pitching; you're diagnosing."
+ ),
+ "when_to_use": [
+ "First call with any prospect who has meaningful organic competition",
+ "When you need to justify a large deal size",
+ "When the prospect thinks they're doing fine (they often don't know the gap)",
+ "Especially effective with data-driven or technical decision makers",
+ ],
+ "example_dialogue": [
+ "Rep: 'Before we talk about anything, I pulled some data I thought you'd find interesting. Mind if I share my screen?'",
+ "Prospect: 'Sure, go ahead.'",
+ "Rep: 'So here's where you rank for your top 10 money keywords. And here's where TechStart Inc ranks for those same keywords. Notice anything?'",
+ "Prospect: '...they're ahead on almost all of them.'",
+ "Rep: 'Right. And here's what that gap means in traffic. They're getting roughly 45,000 visits per month from these keywords alone. You're getting about 8,000. That's 37,000 visits per month that could be yours.'",
+ "Prospect: 'I didn't realize the gap was that big.'",
+ "Rep: 'Most people don't until they see it. Want me to walk through what closing that gap would look like?'",
+ ],
+ "common_mistakes": [
+ "Showing data AFTER pitching your services (loses the anchoring effect)",
+ "Using data that's not relevant to their specific business goals",
+ "Overwhelming with too many data points instead of focusing on 3-5 killer gaps",
+ "Not connecting the data to dollar values (traffic alone doesn't motivate; traffic value does)",
+ ],
+ "success_rate_notes": "Highest-converting opener in our playbook. Calls that lead with competitive data close at 2.3x the rate of calls that lead with capabilities.",
+ },
+ "tiered-packaging": {
+ "name": "Tiered Packaging (S/M/L + Performance)",
+ "tagline": "Always present 3-4 options. Anchor high. Land in the middle.",
+ "description": (
+ "Never present a single price. Always offer 3-4 tiers: a premium anchor (Powerhouse), "
+ "your target tier (Value), a stripped-down floor (Baseline), and a performance option "
+ "(skin in the game). The premium makes the target look reasonable. The baseline creates "
+ "a floor. The performance option catches prospects who stall on fixed pricing."
+ ),
+ "when_to_use": [
+ "Every proposal presentation, without exception",
+ "Especially when moving from a small engagement to a larger one",
+ "When competing against agencies that only present one price",
+ "When the prospect's budget is unclear",
+ ],
+ "example_dialogue": [
+ "Rep: 'Based on what you've told me, I've put together four options. Let me walk you through them.'",
+ "Rep: 'Option 1 is our Powerhouse package at $110,000 per month. This is the full-service, senior-strategist-involved, aggressive-growth option. Everything we talked about plus dedicated executive alignment.'",
+ "Rep: 'Option 2 is our Value package at $80,000 per month. This covers all the critical growth levers we discussed. It's where most of our successful clients land.'",
+ "Rep: 'Option 3 is our Baseline at $35,000 per month. This focuses on the top 2-3 priorities. Good for proving the model before scaling.'",
+ "Rep: 'And Option 4 is our Performance package. Lower base at $28,000 per month, but with bonus triggers tied to traffic and revenue outcomes. We put skin in the game.'",
+ "Prospect: 'Tell me more about Option 2.'",
+ "(This is the expected response. The anchor worked.)",
+ ],
+ "common_mistakes": [
+ "Starting with the cheapest option (kills the anchor effect)",
+ "Making tiers too similar (if they can't tell the difference, they'll pick the cheapest)",
+ "Not having clear 'what's not included' for lower tiers (scarcity drives upgrades)",
+ "Presenting more than 4 options (decision paralysis)",
+ ],
+ "success_rate_notes": "Deals presented with tiered options average 40% higher closed value vs. single-price proposals. The Value tier is selected ~55% of the time when the anchor is presented first.",
+ },
+ "competitive-ego-trigger": {
+ "name": "Competitive Ego Trigger",
+ "tagline": "'Your competitor ranks #1 for [keyword]. You're #14.' Works on every competitive CEO.",
+ "description": (
+ "Competitive business leaders can't stand losing. When you show them specific, "
+ "concrete data about where a competitor is beating them, it triggers an emotional "
+ "response that bypasses rational objections. This isn't manipulation; it's showing "
+ "them reality they didn't have access to. The key is specificity."
+ ),
+ "when_to_use": [
+ "When the decision maker is a CEO, founder, or other competitive leader",
+ "When you have clear data showing competitor advantages",
+ "When the prospect thinks they're 'doing okay' with their current approach",
+ "NOT when the prospect is already anxious (don't pile on)",
+ ],
+ "example_dialogue": [
+ "Rep: 'I looked at your keyword landscape vs. NovaPay. For the keyword \"enterprise payment processing,\" NovaPay ranks #1. You're #14.'",
+ "Prospect: 'We're #14? That can't be right.'",
+ "Rep: 'I double-checked. Here's the screenshot from today. And for \"B2B payment solutions,\" they're #2. You're not in the top 50.'",
+ "Prospect: '...how is that possible? We have a better product.'",
+ "Rep: 'I hear that a lot. Better product doesn't automatically mean better search presence. The good news is, these gaps are closeable. Want me to show you what it would take?'",
+ ],
+ "common_mistakes": [
+ "Being vague ('your competitors are ahead') instead of specific ('#1 vs #14 for [keyword]')",
+ "Using this pattern when the competitor is a 10x larger company (makes the gap feel insurmountable)",
+ "Not having a solution ready (trigger without a path forward just causes frustration)",
+ "Overusing it (pick 2-3 killer examples, not 20)",
+ ],
+ "success_rate_notes": "Triggers a strong emotional response in ~80% of CEO/founder calls. Follow-up meeting request rate increases by 60% when competitive data is presented vs. generic capability pitches.",
+ },
+ "strategic-involvement-upsell": {
+ "name": "Strategic Involvement Upsell",
+ "tagline": "CEO/senior involvement is the premium lever. Same team, add strategy = 3-5x price.",
+ "description": (
+ "The biggest pricing lever isn't more deliverables. It's senior strategic involvement. "
+ "A team executing SEO is worth $15-25K/mo. That same team with a dedicated senior "
+ "strategist who joins leadership meetings, aligns marketing with business strategy, "
+ "and provides executive-level guidance is worth $60-100K/mo. Same execution, different value layer."
+ ),
+ "when_to_use": [
+ "When moving a prospect from a mid-tier to premium engagement",
+ "When the prospect values strategic guidance over tactical execution",
+ "When you're competing against cheaper agencies (you can't win on execution cost; win on strategic value)",
+ "When the prospect's CEO or C-suite is involved in the buying process",
+ ],
+ "example_dialogue": [
+ "Prospect: 'What's the difference between your $30K and $80K packages? Is it just more content?'",
+ "Rep: 'Great question. The execution team is actually very similar. The difference is strategic involvement. At $80K, you get a dedicated senior strategist who joins your leadership team calls, aligns our work with your quarterly business objectives, and provides the kind of strategic guidance that turns marketing from a cost center into a growth engine.'",
+ "Rep: 'Think of it this way: at $30K, we're executing a playbook. At $80K, we're building the playbook WITH your leadership team and adapting it in real-time as the business evolves.'",
+ "Prospect: 'That makes sense. Our current agency just executes what we tell them.'",
+ "Rep: 'And that's exactly the gap we'd fill.'",
+ ],
+ "common_mistakes": [
+ "Positioning the upsell as 'more stuff' instead of 'different level of involvement'",
+ "Not having genuine senior talent to back the claim (this falls apart fast if you oversell)",
+ "Jumping to the strategic pitch before establishing execution credibility",
+ "Not quantifying the value of strategic alignment (tie it to business outcomes, not just marketing metrics)",
+ ],
+ "success_rate_notes": "The strategic involvement lever is the #1 driver of deals moving from $10-20K/mo to $50-100K/mo range. Average deal size increases 3.2x when strategic involvement is successfully positioned.",
+ },
+ "bridge-offer": {
+ "name": "Bridge Offer",
+ "tagline": "'You'll miss Q1 if you hire internally. We bridge the gap.' Creates urgency without being pushy.",
+ "description": (
+ "When a prospect says they want to build in-house, don't fight it. Agree, then show "
+ "them the timeline reality. Hiring takes 3-6 months. Onboarding takes 2-3 more. "
+ "Meanwhile, their competitors aren't waiting. Position yourself as the bridge: start "
+ "now, build momentum, and hand off when their team is ready (or just keep going because "
+ "the results are too good to stop)."
+ ),
+ "when_to_use": [
+ "When the prospect says 'we want to build this capability in-house'",
+ "When there's a clear time-sensitive opportunity (seasonal, competitive, market window)",
+ "When the prospect is comparing your cost to a hire's salary (reframe the comparison)",
+ "Works especially well in tight labor markets",
+ ],
+ "example_dialogue": [
+ "Prospect: 'We're actually thinking about hiring a Head of SEO internally.'",
+ "Rep: 'That's smart. Good SEO leadership is valuable. Quick question: when are you hoping to have that person fully ramped and producing results?'",
+ "Prospect: 'Ideally by Q2.'",
+ "Rep: 'Here's what I typically see: the search takes 2-3 months, then 2-3 months to ramp. So realistically, you're looking at Q3 or Q4 before they're fully contributing. Meanwhile, CloudRetail and your other competitors are investing heavily right now. We can bridge that gap. Start immediately, build the foundation, and either hand off to your new hire or keep working alongside them.'",
+ "Prospect: 'Hm, I hadn't thought about the ramp time.'",
+ "Rep: 'Most people don't. The bridge model de-risks it for you.'",
+ ],
+ "common_mistakes": [
+ "Arguing against in-house (makes you seem threatened)",
+ "Not acknowledging that in-house is a valid long-term strategy",
+ "Failing to quantify the cost of delay (make it concrete: 'every month without action is X in lost traffic value')",
+ "Not offering a genuine transition plan (if you promise to hand off, have a plan for it)",
+ ],
+ "success_rate_notes": "Converts ~35% of 'we want to hire in-house' objections into bridge engagements. Average bridge engagement lasts 8+ months (vs. the expected 3-4) because results create retention.",
+ },
+ "performance-skin-in-game": {
+ "name": "Performance Skin-in-Game",
+ "tagline": "Lower base + bonus on outcomes. Shows confidence. Often closes deals that stall on fixed pricing.",
+ "description": (
+ "When a prospect stalls on a fixed monthly fee, offer a performance structure: lower "
+ "base price + bonus triggers tied to specific outcomes. This shows confidence in your "
+ "ability to deliver and aligns your incentives with theirs. It also reframes the "
+ "conversation from 'how much does this cost' to 'what are we both willing to bet on.'"
+ ),
+ "when_to_use": [
+ "When the prospect says 'I love the plan but the price is too high'",
+ "When you're confident in your ability to deliver measurable results",
+ "When the prospect is risk-averse or has been burned by agencies before",
+ "When competing against cheaper agencies (you're not cheaper; you're more confident)",
+ ],
+ "example_dialogue": [
+ "Prospect: 'I like everything you've shown me but $80K per month is a big commitment given our past experience with agencies.'",
+ "Rep: 'I hear you. And I respect that you've been burned before. Here's what I'd suggest: we do a performance structure. Base of $35K per month covers our team and core execution. Then we set bonus triggers: if organic traffic increases 50% from baseline, that's a 15% bonus. If revenue attributed to organic exceeds 3x the monthly investment, that's another 20%.'",
+ "Rep: 'So if we don't deliver, you're at $35K. If we crush it, we're closer to $55K, but you're making multiples of that in return. We only win big when you win big.'",
+ "Prospect: 'That's actually fair. You're putting your money where your mouth is.'",
+ "Rep: 'Exactly. And frankly, we set the triggers where we expect to hit them. We wouldn't offer this if we didn't believe in the plan.'",
+ ],
+ "common_mistakes": [
+ "Setting bonus triggers that are easy to game (use business outcomes, not vanity metrics)",
+ "Making the base too low (you still need to be profitable at the base)",
+ "Not defining measurement methodology upfront (this causes disputes later)",
+ "Offering performance pricing when you're not confident in results (it will backfire)",
+ ],
+ "success_rate_notes": "Closes ~45% of deals that stall on fixed pricing. Average deal value ends up within 10% of the original fixed proposal because bonuses are typically hit.",
+ },
+ "value-math-on-screen": {
+ "name": "Value Math on Screen",
+ "tagline": "'If we move this keyword from #14 to #3, that's $X/mo in traffic value.' Make the ROI visual and obvious.",
+ "description": (
+ "Don't just tell them the ROI. Show them the math. On screen. In real-time. "
+ "Pull up their keywords, show the current position, the target position, the search "
+ "volume, the CPC, and calculate the traffic value live. When the prospect watches "
+ "the number build up keyword by keyword, they're selling themselves."
+ ),
+ "when_to_use": [
+ "During any pricing discussion (make the value visible before discussing cost)",
+ "When the prospect asks 'what kind of results can we expect?'",
+ "When you need to justify a large deal size",
+ "When competing against cheaper alternatives (show what the cheap option misses)",
+ ],
+ "example_dialogue": [
+ "Rep: 'Let me show you the math on just your top 5 keywords. [shares screen]'",
+ "Rep: 'Keyword 1: \"enterprise analytics platform.\" You're #14, getting roughly 200 visits/mo. If we move you to #3, that's 1,800 visits/mo. At a CPC of $18.50, that's $33,300/mo in paid equivalent value. Just from one keyword.'",
+ "Rep: 'Keyword 2: \"business intelligence software.\" You're #22, getting about 50 visits/mo. Position #3 would be 2,400 visits. At $22 CPC, that's $52,800/mo.'",
+ "Rep: 'Just these 5 keywords represent $X/mo in traffic value. Your total keyword universe is much larger.'",
+ "Prospect: 'When you put it that way, the investment makes a lot more sense.'",
+ ],
+ "common_mistakes": [
+ "Using unrealistic targets (don't promise #1 for everything; #3-5 is more credible)",
+ "Forgetting to mention this is paid equivalent value, not guaranteed revenue",
+ "Not accounting for the time it takes to achieve these rankings",
+ "Showing the math without connecting it to business outcomes (traffic value → leads → revenue)",
+ ],
+ "success_rate_notes": "Deals where value math is shown on screen close at 2.1x the rate of deals where ROI is just mentioned verbally. Average deal size is 35% higher when the math is visible.",
+ },
+ "compound-effect-close": {
+ "name": "Compound Effect Close",
+ "tagline": "'SEO + CRO + content compound on each other. Doing one without the others leaves money on the table.' Justifies the full package.",
+ "description": (
+ "When a prospect wants to cherry-pick individual services, show them how the services "
+ "compound on each other. SEO drives traffic, CRO converts it, content fuels both. "
+ "Doing SEO without CRO means you're driving traffic to a leaky funnel. Doing CRO "
+ "without SEO means you're optimizing a trickle. The math only works when they compound."
+ ),
+ "when_to_use": [
+ "When the prospect wants 'just SEO' or 'just paid' (they're leaving money on the table)",
+ "When justifying a multi-service package over a single-service engagement",
+ "When the prospect is comparing your multi-service price to a single-service competitor",
+ "When you need to prevent scope reduction during negotiation",
+ ],
+ "example_dialogue": [
+ "Prospect: 'Can we start with just the SEO piece? We'll add content and CRO later.'",
+ "Rep: 'You can, and here's what that looks like. SEO alone will move your rankings, but without optimized content, the rankings plateau. And without CRO, you're driving more traffic to a funnel that converts at the same rate.'",
+ "Rep: 'Here's the compound math: SEO alone might give you a 40% traffic increase. Add content, and it's 80% because you're feeding the SEO engine. Add CRO, and even though traffic is the same, leads might double because conversion rate improves. The total impact of all three is roughly 4x what SEO alone delivers. Not 3x, 4x, because they compound.'",
+ "Prospect: 'I see your point. What does the combined package look like?'",
+ ],
+ "common_mistakes": [
+ "Not having the math to back up the compounding claim (be specific, not hand-wavy)",
+ "Refusing to do single services at all (some clients need to start small; offer a path to scale)",
+ "Overselling the compound effect (4x is realistic; 10x is not credible)",
+ "Not having case study data showing compound vs. single-service results",
+ ],
+ "success_rate_notes": "Multi-service proposals using the compound effect framing have a 28% higher close rate and 2.2x average deal value vs. single-service proposals.",
+ },
+ "reference-customer-drop": {
+ "name": "Reference Customer Drop",
+ "tagline": "'One of our clients ranks #1 for [hard keyword]. Happy to connect you.' Social proof at the right moment.",
+ "description": (
+ "The most powerful form of social proof in B2B sales isn't a logo wall or a case study "
+ "PDF. It's a specific, verifiable result dropped at exactly the right moment in the "
+ "conversation, followed by an offer to connect directly. It turns abstract credibility "
+ "into concrete confidence."
+ ),
+ "when_to_use": [
+ "When the prospect expresses skepticism ('can you really do that?')",
+ "When discussing a specific outcome and you have a matching reference",
+ "After showing the value math (proof that the math converts to reality)",
+ "When competing against established agencies (proof beats reputation)",
+ ],
+ "example_dialogue": [
+ "Prospect: 'Those numbers look great on paper, but can you actually get us to page 1 for these keywords?'",
+ "Rep: 'Fair question. One of our clients, a mid-market SaaS company similar to yours, ranks #1 for \"enterprise workflow automation.\" That keyword alone drives over 3,000 visits per month for them. They started at #18.'",
+ "Prospect: 'How long did that take?'",
+ "Rep: 'About 7 months to break into the top 3, 11 months to hit #1. Happy to connect you with their marketing director if you'd like to hear it firsthand.'",
+ "Prospect: 'That would be great, actually.'",
+ ],
+ "common_mistakes": [
+ "Dropping references too early (before the prospect cares about the specific outcome)",
+ "Being vague ('we have great clients') instead of specific ('ranks #1 for [keyword]')",
+ "Not having the reference customer prepped and willing to take the call",
+ "Using the same reference for every prospect (match the reference to the prospect's industry/size)",
+ ],
+ "success_rate_notes": "Deals where a reference call happens close at 3.4x the rate of deals without reference engagement. The key is timing: reference drops work best after value math, not before.",
+ },
+ "in-house-team-framing": {
+ "name": "In-House Team Framing",
+ "tagline": "'Think of us as your in-house team, not a vendor.' Reframes the relationship and justifies premium pricing.",
+ "description": (
+ "When a prospect compares your fee to another agency's fee, you're in a commodity "
+ "conversation you can't win. Reframe: you're not a vendor, you're their in-house "
+ "marketing team, without the overhead of recruiting, salaries, benefits, management, "
+ "and ramp time. This changes the comparison from 'agency A vs. agency B' to 'build "
+ "internally vs. deploy a ready-made team.'"
+ ),
+ "when_to_use": [
+ "When the prospect compares your pricing to cheaper agencies",
+ "When the prospect is considering building in-house as an alternative",
+ "When you need to justify premium pricing vs. commodity competition",
+ "When the prospect values integration and strategic alignment over task execution",
+ ],
+ "example_dialogue": [
+ "Prospect: 'You're quite a bit more expensive than the other agencies we've talked to.'",
+ "Rep: 'I appreciate the transparency. Let me reframe the comparison. The other agencies will execute tasks you assign. We integrate as your marketing team. Think about what it would cost to hire a senior SEO lead, a content strategist, a CRO specialist, and a paid media manager in-house. You're looking at $500-700K per year in fully loaded salary, plus 3-6 months to recruit and ramp each one.'",
+ "Rep: 'For $80K per month, you get that entire team, already trained, already working together, with systems and processes built from working with dozens of companies like yours. No recruiting. No ramp time. No management overhead. And if it's not working, you can walk away. Try doing that with four full-time hires.'",
+ "Prospect: 'When you put it against hiring costs, it's actually not that different.'",
+ "Rep: 'It's usually less. And you get results faster because we're not starting from zero.'",
+ ],
+ "common_mistakes": [
+ "Using this framing when you can't actually deliver at an in-house team level",
+ "Not knowing the actual salary benchmarks for the roles you're replacing (do the math for their market)",
+ "Comparing to junior hires (compare to the senior talent you're actually providing)",
+ "Not backing it up with integration practices (slack channels, meeting cadences, shared dashboards)",
+ ],
+ "success_rate_notes": "The in-house team framing shifts the prospect's mental comparison from 'agency cost' to 'team cost,' typically increasing acceptable price range by 40-60%. Most effective with companies that have recently struggled to hire marketing talent.",
+ },
+}
+
+
+# ---------------------------------------------------------------------------
+# Quiz Mode
+# ---------------------------------------------------------------------------
+
+QUIZ_SCENARIOS = [
+ {
+ "scenario": "A prospect says: 'We like what you're proposing, but your price is about 30% higher than the other agency we're talking to. Can you match their price?'",
+ "best_pattern": "in-house-team-framing",
+ "also_applicable": ["tiered-packaging", "performance-skin-in-game"],
+ "explanation": "Don't compete on price. Reframe the comparison from agency-vs-agency to agency-vs-hiring. If they're comparing you to a cheaper agency, they're thinking about vendors. Shift them to thinking about a team.",
+ },
+ {
+ "scenario": "You're 10 minutes into a first call with the CEO of a mid-market SaaS company. She seems interested but hasn't expressed any specific pain. How do you create urgency?",
+ "best_pattern": "anchor-with-data",
+ "also_applicable": ["competitive-ego-trigger", "value-math-on-screen"],
+ "explanation": "Lead with data. Show her competitive landscape before pitching. The data will surface pain she didn't know she had. Follow up with competitive triggers if she's the competitive type.",
+ },
+ {
+ "scenario": "A prospect on a $15K/mo engagement asks: 'What would it look like to do more with you?' They're happy with results.",
+ "best_pattern": "strategic-involvement-upsell",
+ "also_applicable": ["compound-effect-close", "tiered-packaging"],
+ "explanation": "Don't just offer more deliverables. Offer a different level of engagement: senior strategic involvement, executive alignment, integrated planning. Same team, higher value layer.",
+ },
+ {
+ "scenario": "The VP of Marketing says: 'We've been burned by agencies before. Last one promised the world and delivered nothing. How are you different?'",
+ "best_pattern": "performance-skin-in-game",
+ "also_applicable": ["reference-customer-drop", "value-math-on-screen"],
+ "explanation": "They're risk-averse for good reason. Performance pricing puts your money where your mouth is. Follow with a reference customer who can vouch for results.",
+ },
+ {
+ "scenario": "A prospect wants to hire you for SEO only, even though you know their conversion rate is terrible. They'd get more traffic to a broken funnel.",
+ "best_pattern": "compound-effect-close",
+ "also_applicable": ["value-math-on-screen", "tiered-packaging"],
+ "explanation": "Show the compound math. SEO alone = 40% lift. SEO + CRO = 4x the business impact. Make it clear that doing one without the other leaves money on the table.",
+ },
+ {
+ "scenario": "The prospect says: 'We're planning to hire a Head of Content and a senior SEO manager. We think we can do this in-house for less.'",
+ "best_pattern": "bridge-offer",
+ "also_applicable": ["in-house-team-framing", "strategic-involvement-upsell"],
+ "explanation": "Don't fight the in-house plan. Agree it's smart, then show the timeline reality. Hiring + ramp = 6-9 months. Bridge the gap now, build momentum, and hand off (or keep going because results are too good to stop).",
+ },
+ {
+ "scenario": "You're presenting a $75K/mo proposal. The prospect says: 'We can see the value, but we only have $40K/mo approved for this quarter.'",
+ "best_pattern": "tiered-packaging",
+ "also_applicable": ["performance-skin-in-game", "bridge-offer"],
+ "explanation": "This is exactly why you have tiers. Present the Baseline at ~$35K with a clear path to scale. Or offer Performance pricing with a lower base and bonus triggers. Never just discount.",
+ },
+ {
+ "scenario": "The prospect is skeptical that you can rank for a highly competitive keyword in their industry. 'Everyone says they can do SEO. Nobody delivers.'",
+ "best_pattern": "reference-customer-drop",
+ "also_applicable": ["value-math-on-screen", "anchor-with-data"],
+ "explanation": "Don't argue. Prove. Drop a specific, verifiable reference: 'One of our clients ranks #1 for [similar hard keyword]. Started at #22. Took 9 months. Happy to connect you with them.'",
+ },
+]
+
+
+def list_patterns() -> str:
+ """List all patterns with descriptions."""
+ lines = ["# Value-Based Pricing Pattern Library", ""]
+ lines.append(f"**{len(PATTERNS)} patterns available**")
+ lines.append("")
+ for i, (key, p) in enumerate(PATTERNS.items(), 1):
+ lines.append(f"## {i}. {p['name']}")
+ lines.append(f"*{p['tagline']}*")
+ lines.append("")
+ lines.append(f"**When to use:** {p['when_to_use'][0]}")
+ lines.append(f"**Key insight:** {p['success_rate_notes'][:100]}...")
+ lines.append(f"**Details:** `python3 pricing_pattern_library.py --pattern \"{key}\"`")
+ lines.append("")
+ return "\n".join(lines)
+
+
+def get_pattern(pattern_key: str) -> str:
+ """Get detailed breakdown of a specific pattern."""
+ # Try exact match first, then fuzzy
+ key = pattern_key.lower().replace(" ", "-").replace("_", "-")
+ if key not in PATTERNS:
+ # Try partial match
+ matches = [k for k in PATTERNS if key in k or key in PATTERNS[k]["name"].lower()]
+ if len(matches) == 1:
+ key = matches[0]
+ elif len(matches) > 1:
+ return f"Multiple matches: {', '.join(matches)}. Be more specific."
+ else:
+ return f"Pattern not found: '{pattern_key}'. Use --list to see all patterns."
+
+ p = PATTERNS[key]
+ lines = [f"# {p['name']}", f"*{p['tagline']}*", ""]
+ lines.append("## Description")
+ lines.append(p["description"])
+ lines.append("")
+
+ lines.append("## When to Use")
+ for w in p["when_to_use"]:
+ lines.append(f"- {w}")
+ lines.append("")
+
+ lines.append("## Example Dialogue")
+ for d in p["example_dialogue"]:
+ lines.append(f"> {d}")
+ lines.append("")
+
+ lines.append("## Common Mistakes")
+ for m in p["common_mistakes"]:
+ lines.append(f"- ❌ {m}")
+ lines.append("")
+
+ lines.append("## Success Rate Notes")
+ lines.append(p["success_rate_notes"])
+
+ return "\n".join(lines)
+
+
+def analyze_scenario(scenario: str) -> str:
+ """Analyze a scenario and recommend patterns (uses LLM if available, else rule-based)."""
+ # Try LLM first
+ pattern_summaries = "\n".join(
+ f"- {key}: {p['name']} - {p['tagline']}" for key, p in PATTERNS.items()
+ )
+
+ llm_prompt = f"""Given this sales scenario:
+
+"{scenario}"
+
+And these available value-based pricing patterns:
+{pattern_summaries}
+
+Recommend which 2-3 patterns to apply, in priority order. For each:
+1. Which pattern and why it fits
+2. Specific dialogue to use in this scenario
+3. What to watch out for
+
+Be specific and actionable. Use the pattern names exactly."""
+
+ llm_result = _call_llm(llm_prompt, system_prompt="You are an expert B2B sales coach specializing in value-based pricing.")
+
+ if llm_result:
+ return f"# Scenario Analysis\n\n**Scenario:** {scenario}\n\n{llm_result}"
+
+ # Fallback: keyword-based pattern matching
+ scenario_lower = scenario.lower()
+ scored_patterns = []
+
+ keywords_map = {
+ "anchor-with-data": ["data", "first call", "discovery", "don't know", "competitive", "landscape", "research"],
+ "tiered-packaging": ["budget", "price", "options", "tiers", "proposal", "packages", "how much"],
+ "competitive-ego-trigger": ["competitor", "behind", "losing", "rival", "beating", "ceo", "founder"],
+ "strategic-involvement-upsell": ["expand", "more", "grow", "strategy", "strategic", "upsell", "upgrade"],
+ "bridge-offer": ["in-house", "hire", "internal", "build", "recruit", "team"],
+ "performance-skin-in-game": ["risk", "burned", "skeptic", "trust", "prove", "guarantee", "performance"],
+ "value-math-on-screen": ["roi", "results", "expect", "numbers", "value", "worth", "justify"],
+ "compound-effect-close": ["just seo", "just one", "single", "cherry pick", "only", "one service"],
+ "reference-customer-drop": ["proof", "results", "show me", "example", "case study", "who else"],
+ "in-house-team-framing": ["expensive", "cheaper", "agency", "compare", "cost", "other agencies"],
+ }
+
+ for key, keywords in keywords_map.items():
+ score = sum(1 for kw in keywords if kw in scenario_lower)
+ if score > 0:
+ scored_patterns.append((key, score))
+
+ scored_patterns.sort(key=lambda x: x[1], reverse=True)
+ top_patterns = scored_patterns[:3] if scored_patterns else list(PATTERNS.keys())[:3]
+
+ lines = [f"# Scenario Analysis", "", f"**Scenario:** {scenario}", ""]
+ lines.append("*Analysis: rule-based (set ANTHROPIC_API_KEY or OPENAI_API_KEY for LLM-powered analysis)*")
+ lines.append("")
+ lines.append("## Recommended Patterns (in priority order)")
+ lines.append("")
+ for i, (key, score) in enumerate(top_patterns, 1):
+ p = PATTERNS[key]
+ lines.append(f"### {i}. {p['name']}")
+ lines.append(f"*{p['tagline']}*")
+ lines.append("")
+ lines.append(f"**Why this fits:** {p['when_to_use'][0]}")
+ lines.append("")
+ lines.append("**Key dialogue:**")
+ for d in p["example_dialogue"][:3]:
+ lines.append(f"> {d}")
+ lines.append("")
+ lines.append(f"**Watch out for:** {p['common_mistakes'][0]}")
+ lines.append("")
+
+ return "\n".join(lines)
+
+
+def run_quiz():
+ """Interactive quiz mode."""
+ print("# 🎯 Value-Based Pricing Pattern Quiz")
+ print("I'll present scenarios. You identify the best pattern to apply.")
+ print(f"({len(QUIZ_SCENARIOS)} scenarios available)")
+ print()
+
+ # Shuffle scenarios
+ scenarios = list(QUIZ_SCENARIOS)
+ random.shuffle(scenarios)
+
+ correct = 0
+ total = 0
+
+ pattern_names = {k: PATTERNS[k]["name"] for k in PATTERNS}
+ name_list = "\n".join(f" {i+1}. {name} ({key})" for i, (key, name) in enumerate(pattern_names.items()))
+
+ for i, quiz in enumerate(scenarios):
+ print(f"---")
+ print(f"## Scenario {i + 1}/{len(scenarios)}")
+ print()
+ print(f" {quiz['scenario']}")
+ print()
+ print(f"Which pattern would you apply? (type the number or name)")
+ print(name_list)
+ print()
+
+ try:
+ answer = input("Your answer: ").strip().lower()
+ except (EOFError, KeyboardInterrupt):
+ print("\n\nQuiz ended early.")
+ break
+
+ # Match answer
+ matched_key = None
+ # Try number
+ try:
+ idx = int(answer) - 1
+ keys = list(PATTERNS.keys())
+ if 0 <= idx < len(keys):
+ matched_key = keys[idx]
+ except ValueError:
+ pass
+
+ # Try name/key match
+ if not matched_key:
+ for key in PATTERNS:
+ if answer in key or answer in PATTERNS[key]["name"].lower():
+ matched_key = key
+ break
+
+ total += 1
+ if matched_key == quiz["best_pattern"]:
+ correct += 1
+ print(f"\n✅ Correct! {PATTERNS[quiz['best_pattern']]['name']}")
+ elif matched_key in quiz["also_applicable"]:
+ correct += 0.5
+ print(f"\n🟡 Good choice! {PATTERNS[matched_key]['name']} works here.")
+ print(f" Best pattern: {PATTERNS[quiz['best_pattern']]['name']}")
+ else:
+ print(f"\n❌ Not the best fit.")
+ print(f" Best pattern: {PATTERNS[quiz['best_pattern']]['name']}")
+
+ print(f"\n**Why:** {quiz['explanation']}")
+ print()
+
+ if i < len(scenarios) - 1:
+ try:
+ cont = input("Continue? (y/n): ").strip().lower()
+ if cont == "n":
+ break
+ except (EOFError, KeyboardInterrupt):
+ break
+ print()
+
+ # Score
+ print(f"\n---")
+ print(f"## Final Score: {correct}/{total}")
+ pct = (correct / total * 100) if total > 0 else 0
+ if pct >= 80:
+ print("🏆 Expert level. You know the playbook.")
+ elif pct >= 60:
+ print("👍 Solid. Review the patterns you missed.")
+ elif pct >= 40:
+ print("📚 Getting there. Run `--list` and study the patterns.")
+ else:
+ print("🔄 Time to study. Run `--pattern ` for deep dives on each pattern.")
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Value-Based Pricing: Pattern Library & Training",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog="""
+Examples:
+ python3 pricing_pattern_library.py --list
+ python3 pricing_pattern_library.py --pattern "anchor-with-data"
+ python3 pricing_pattern_library.py --pattern "tiered-packaging"
+ python3 pricing_pattern_library.py --scenario "prospect is a $50M SaaS company spending $15K/mo on marketing"
+ python3 pricing_pattern_library.py --quiz
+ """,
+ )
+ parser.add_argument("--list", action="store_true", help="List all patterns with descriptions")
+ parser.add_argument("--pattern", help="Get detailed breakdown of a specific pattern")
+ parser.add_argument("--scenario", help="Analyze a scenario and recommend patterns")
+ parser.add_argument("--quiz", action="store_true", help="Interactive training mode")
+ parser.add_argument("--format", choices=["markdown", "json"], default="markdown", help="Output format (default: markdown)")
+
+ args = parser.parse_args()
+
+ if not any([args.list, args.pattern, args.scenario, args.quiz]):
+ parser.print_help()
+ sys.exit(0)
+
+ if args.quiz:
+ run_quiz()
+ return
+
+ if args.list:
+ if args.format == "json":
+ output = {k: {"name": v["name"], "tagline": v["tagline"], "when_to_use": v["when_to_use"][0]} for k, v in PATTERNS.items()}
+ print(json.dumps(output, indent=2))
+ else:
+ print(list_patterns())
+
+ elif args.pattern:
+ if args.format == "json":
+ key = args.pattern.lower().replace(" ", "-").replace("_", "-")
+ if key in PATTERNS:
+ print(json.dumps(PATTERNS[key], indent=2))
+ else:
+ matches = [k for k in PATTERNS if key in k]
+ if matches:
+ print(json.dumps(PATTERNS[matches[0]], indent=2))
+ else:
+ print(json.dumps({"error": f"Pattern not found: {args.pattern}"}))
+ else:
+ print(get_pattern(args.pattern))
+
+ elif args.scenario:
+ if args.format == "json":
+ # For JSON, just return the pattern recommendations
+ scenario_lower = args.scenario.lower()
+ keywords_map = {
+ "anchor-with-data": ["data", "first call", "discovery", "competitive"],
+ "tiered-packaging": ["budget", "price", "options", "tiers"],
+ "competitive-ego-trigger": ["competitor", "behind", "losing", "ceo"],
+ "strategic-involvement-upsell": ["expand", "more", "grow", "strategy"],
+ "bridge-offer": ["in-house", "hire", "internal", "build"],
+ "performance-skin-in-game": ["risk", "burned", "skeptic", "prove"],
+ "value-math-on-screen": ["roi", "results", "numbers", "value"],
+ "compound-effect-close": ["just seo", "single", "only", "one service"],
+ "reference-customer-drop": ["proof", "show me", "example", "case study"],
+ "in-house-team-framing": ["expensive", "cheaper", "agency", "compare"],
+ }
+ scored = []
+ for key, keywords in keywords_map.items():
+ score = sum(1 for kw in keywords if kw in scenario_lower)
+ if score > 0:
+ scored.append({"pattern": key, "name": PATTERNS[key]["name"], "relevance_score": score})
+ scored.sort(key=lambda x: x["relevance_score"], reverse=True)
+ print(json.dumps({"scenario": args.scenario, "recommended_patterns": scored[:3]}, indent=2))
+ else:
+ print(analyze_scenario(args.scenario))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/sales-playbook/requirements.txt b/sales-playbook/requirements.txt
new file mode 100644
index 0000000..65588b7
--- /dev/null
+++ b/sales-playbook/requirements.txt
@@ -0,0 +1,5 @@
+# Core dependencies
+requests>=2.28.0
+
+# Optional: python-dotenv for loading .env files
+python-dotenv>=1.0.0
diff --git a/sales-playbook/value_pricing_briefing.py b/sales-playbook/value_pricing_briefing.py
new file mode 100644
index 0000000..6bea03f
--- /dev/null
+++ b/sales-playbook/value_pricing_briefing.py
@@ -0,0 +1,371 @@
+#!/usr/bin/env python3
+"""
+Value-Based Pricing: Pre-Call Briefing Generator
+
+Takes a prospect's domain + competitor domains and outputs everything a
+salesperson needs to anchor the conversation on value, not cost.
+
+Usage:
+ python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com,comp2.com"
+ python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com" --industry saas --deal-target 80000
+ python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com" --format json
+"""
+
+import argparse
+import json
+import os
+import random
+import sys
+from datetime import datetime
+
+# ---------------------------------------------------------------------------
+# API Stubs — Replace with real Ahrefs/SEMrush API calls when keys are available
+# ---------------------------------------------------------------------------
+# To integrate real APIs:
+# 1. Set AHREFS_API_KEY or SEMRUSH_API_KEY environment variables
+# 2. Replace the stub functions below with actual API calls
+# 3. Ahrefs API docs: https://ahrefs.com/api
+# 4. SEMrush API docs: https://developer.semrush.com/api/
+
+
+def _fetch_domain_metrics(domain: str) -> dict:
+ """
+ Stub: Fetch domain authority, backlinks, and traffic estimates.
+
+ In production, call:
+ GET https://api.ahrefs.com/v3/site-explorer/domain-rating
+ GET https://api.semrush.com/?type=domain_ranks&key=KEY&domain=DOMAIN
+ """
+ api_key = os.environ.get("AHREFS_API_KEY") or os.environ.get("SEMRUSH_API_KEY")
+ if api_key:
+ # TODO: Implement real API call here
+ # import requests
+ # resp = requests.get(f"https://api.ahrefs.com/v3/...", headers={"Authorization": f"Bearer {api_key}"})
+ # return resp.json()
+ pass
+
+ # Stub data — deterministic seed from domain for consistency
+ seed = sum(ord(c) for c in domain)
+ rng = random.Random(seed)
+ return {
+ "domain": domain,
+ "domain_authority": rng.randint(15, 85),
+ "monthly_organic_traffic": rng.randint(5000, 500000),
+ "total_keywords": rng.randint(500, 50000),
+ "total_backlinks": rng.randint(1000, 200000),
+ "top_keywords": [
+ {"keyword": f"{domain.split('.')[0]} solutions", "position": rng.randint(1, 20), "volume": rng.randint(500, 10000), "cpc": round(rng.uniform(2.0, 25.0), 2)},
+ {"keyword": f"best {domain.split('.')[0]} alternative", "position": rng.randint(5, 50), "volume": rng.randint(200, 5000), "cpc": round(rng.uniform(3.0, 30.0), 2)},
+ {"keyword": f"{domain.split('.')[0]} pricing", "position": rng.randint(1, 30), "volume": rng.randint(300, 8000), "cpc": round(rng.uniform(5.0, 40.0), 2)},
+ {"keyword": f"{domain.split('.')[0]} vs competitor", "position": rng.randint(3, 40), "volume": rng.randint(100, 3000), "cpc": round(rng.uniform(4.0, 35.0), 2)},
+ {"keyword": f"{domain.split('.')[0]} reviews", "position": rng.randint(2, 25), "volume": rng.randint(400, 6000), "cpc": round(rng.uniform(1.5, 15.0), 2)},
+ ],
+ }
+
+
+def _estimate_traffic_value(volume: int, current_pos: int, target_pos: int, cpc: float) -> dict:
+ """Estimate additional traffic and value from ranking improvement."""
+ # CTR curves by position (approximate)
+ ctr_by_pos = {1: 0.32, 2: 0.24, 3: 0.18, 4: 0.13, 5: 0.10, 6: 0.07, 7: 0.05, 8: 0.04, 9: 0.03, 10: 0.025}
+ current_ctr = ctr_by_pos.get(current_pos, max(0.005, 0.025 - (current_pos - 10) * 0.001))
+ target_ctr = ctr_by_pos.get(target_pos, max(0.005, 0.025 - (target_pos - 10) * 0.001))
+ current_traffic = int(volume * current_ctr)
+ target_traffic = int(volume * target_ctr)
+ additional_traffic = max(0, target_traffic - current_traffic)
+ monthly_value = round(additional_traffic * cpc, 2)
+ return {
+ "current_position": current_pos,
+ "target_position": target_pos,
+ "search_volume": volume,
+ "current_monthly_traffic": current_traffic,
+ "projected_monthly_traffic": target_traffic,
+ "additional_monthly_traffic": additional_traffic,
+ "cpc": cpc,
+ "monthly_paid_equivalent": monthly_value,
+ "annual_paid_equivalent": round(monthly_value * 12, 2),
+ }
+
+
+# ---------------------------------------------------------------------------
+# Briefing Generation
+# ---------------------------------------------------------------------------
+
+CONVERSATION_HOOKS = [
+ "What's your current strategy for [top_keyword]? I noticed some interesting gaps there.",
+ "When you look at your competitive landscape for organic search, what concerns you most?",
+ "If you could rank #1 for one keyword tomorrow, which would move the revenue needle most?",
+ "How much are you currently spending on paid search for terms you could be ranking organically?",
+ "What would it mean for your pipeline if you captured even 20% of the traffic your top competitor gets?",
+ "I pulled some data before our call. Mind if I share what I found about your organic presence vs. [competitor]?",
+ "Your competitor just passed you on [keyword]. Have you noticed the traffic shift?",
+ "What does your content production look like right now? I want to understand where the bottleneck is.",
+]
+
+OBJECTION_RESPONSES = {
+ "price_too_high": {
+ "objection": "That's more than we were expecting to spend.",
+ "response": "I hear you. Let me reframe: your competitor is capturing $X/mo in organic traffic value that you're not. The question isn't whether $Y/mo is expensive; it's whether leaving $X/mo on the table is more expensive. Let me show you the math.",
+ "key_principle": "Redirect from cost to cost-of-inaction",
+ },
+ "need_to_think": {
+ "objection": "We need to think about it / discuss internally.",
+ "response": "Absolutely. To help that internal conversation, I'll send over the competitive analysis we reviewed. One thing worth noting: [competitor] is actively investing in the keywords we discussed. Every month of deliberation is a month they're building a wider moat.",
+ "key_principle": "Create urgency with competitor data, not pressure",
+ },
+ "already_doing_seo": {
+ "objection": "We already have someone doing SEO.",
+ "response": "Great. What are they focused on? The reason I ask is that the data shows [specific gap]. If that's being addressed, fantastic. If not, it might be worth a conversation about where the current strategy is leaving value on the table.",
+ "key_principle": "Don't attack their current vendor; question the results",
+ },
+ "can_do_internally": {
+ "objection": "We think we can handle this in-house.",
+ "response": "In-house is great when you have the bandwidth. The gap we identified represents [X keywords / $Y in traffic value]. To close it, you'd need roughly [estimate] hours/month of specialized work. Hiring for that takes 3-6 months. We can bridge the gap while you build the team, or complement what you have.",
+ "key_principle": "Bridge offer + acknowledge their capability",
+ },
+ "show_me_results": {
+ "objection": "Can you show me results from similar companies?",
+ "response": "Absolutely. We have a client in a similar space who went from ranking for ~Z keywords to over [Z*3] in 8 months. Their organic traffic value went from $A/mo to $B/mo. Happy to connect you with them if that would help.",
+ "key_principle": "Reference customer drop with specific (anonymized) numbers",
+ },
+ "budget_locked": {
+ "objection": "Our budget is already allocated for this quarter.",
+ "response": "Understood. Two thoughts: first, our baseline tier starts at [$X], which might fit within discretionary budget. Second, if we start with a focused engagement on your top 3 keyword gaps, I can show ROI within 60 days that makes the case for a larger Q2 investment. Sometimes the best way to unlock budget is to prove the model.",
+ "key_principle": "Offer a smaller entry point tied to provable ROI",
+ },
+}
+
+
+def generate_briefing(domain: str, competitors: list, industry: str = None, deal_target: int = 50000) -> dict:
+ """Generate a complete pre-call briefing."""
+ # Fetch metrics for all domains
+ prospect_metrics = _fetch_domain_metrics(domain)
+ competitor_metrics = [_fetch_domain_metrics(c) for c in competitors]
+
+ # Build anchor data points
+ anchors = []
+ for comp in competitor_metrics:
+ keyword_gap = comp["total_keywords"] - prospect_metrics["total_keywords"]
+ traffic_gap = comp["monthly_organic_traffic"] - prospect_metrics["monthly_organic_traffic"]
+ if keyword_gap > 0:
+ anchors.append({
+ "type": "keyword_gap",
+ "message": f"You rank for {prospect_metrics['total_keywords']:,} keywords. {comp['domain']} ranks for {comp['total_keywords']:,}. Gap: {keyword_gap:,} keywords.",
+ "severity": "high" if keyword_gap > 5000 else "medium",
+ })
+ if traffic_gap > 0:
+ anchors.append({
+ "type": "traffic_gap",
+ "message": f"{comp['domain']} gets ~{comp['monthly_organic_traffic']:,} organic visits/mo vs. your ~{prospect_metrics['monthly_organic_traffic']:,}. That's {traffic_gap:,} visits you're leaving on the table.",
+ "severity": "high" if traffic_gap > 50000 else "medium",
+ })
+
+ # Build competitive triggers
+ triggers = []
+ for comp in competitor_metrics:
+ for kw in comp["top_keywords"]:
+ # Find matching keyword in prospect
+ for pkw in prospect_metrics["top_keywords"]:
+ if pkw["keyword"].split()[-1] == kw["keyword"].split()[-1]:
+ if kw["position"] < pkw["position"]:
+ triggers.append({
+ "keyword": kw["keyword"],
+ "competitor": comp["domain"],
+ "competitor_position": kw["position"],
+ "prospect_position": pkw["position"],
+ "message": f"{comp['domain']} is #{kw['position']} for '{kw['keyword']}'. You're #{pkw['position']}.",
+ })
+
+ # Build value calculations
+ value_calcs = []
+ for kw in prospect_metrics["top_keywords"]:
+ if kw["position"] > 5:
+ target_pos = min(3, kw["position"])
+ calc = _estimate_traffic_value(kw["volume"], kw["position"], target_pos, kw["cpc"])
+ calc["keyword"] = kw["keyword"]
+ if calc["monthly_paid_equivalent"] > 100:
+ value_calcs.append(calc)
+
+ # Sort value calcs by monthly value
+ value_calcs.sort(key=lambda x: x["monthly_paid_equivalent"], reverse=True)
+
+ # Total value opportunity
+ total_monthly_value = sum(v["monthly_paid_equivalent"] for v in value_calcs)
+ total_annual_value = sum(v["annual_paid_equivalent"] for v in value_calcs)
+
+ # Select conversation hooks (pick 4 most relevant)
+ hooks = random.Random(sum(ord(c) for c in domain)).sample(CONVERSATION_HOOKS, min(4, len(CONVERSATION_HOOKS)))
+ # Personalize hooks
+ if competitor_metrics:
+ hooks = [h.replace("[competitor]", competitors[0]) for h in hooks]
+ if value_calcs:
+ hooks = [h.replace("[top_keyword]", value_calcs[0]["keyword"]) for h in hooks]
+
+ # Build objection pre-empts based on deal size
+ relevant_objections = {}
+ if deal_target >= 50000:
+ relevant_objections["price_too_high"] = OBJECTION_RESPONSES["price_too_high"]
+ relevant_objections["need_to_think"] = OBJECTION_RESPONSES["need_to_think"]
+ if deal_target >= 30000:
+ relevant_objections["can_do_internally"] = OBJECTION_RESPONSES["can_do_internally"]
+ relevant_objections["show_me_results"] = OBJECTION_RESPONSES["show_me_results"]
+ relevant_objections["already_doing_seo"] = OBJECTION_RESPONSES["already_doing_seo"]
+ relevant_objections["budget_locked"] = OBJECTION_RESPONSES["budget_locked"]
+
+ # Fill in dynamic values in objection responses
+ for key, obj in relevant_objections.items():
+ obj = dict(obj) # copy
+ if total_monthly_value > 0:
+ obj["response"] = obj["response"].replace("$X/mo", f"${total_monthly_value:,.0f}/mo")
+ obj["response"] = obj["response"].replace("$Y/mo", f"${deal_target:,}/mo")
+ relevant_objections[key] = obj
+
+ briefing = {
+ "generated_at": datetime.now().isoformat(),
+ "prospect": {
+ "domain": domain,
+ "industry": industry,
+ "deal_target": deal_target,
+ "metrics": prospect_metrics,
+ },
+ "competitors": [{"domain": c, "metrics": m} for c, m in zip(competitors, competitor_metrics)],
+ "anchor_data_points": anchors,
+ "competitive_triggers": triggers,
+ "value_calculations": value_calcs,
+ "total_opportunity": {
+ "monthly_paid_equivalent": round(total_monthly_value, 2),
+ "annual_paid_equivalent": round(total_annual_value, 2),
+ "roi_multiple": round(total_annual_value / (deal_target * 12), 1) if deal_target > 0 else 0,
+ },
+ "conversation_hooks": hooks,
+ "objection_preempts": relevant_objections,
+ }
+
+ return briefing
+
+
+def format_markdown(briefing: dict) -> str:
+ """Format briefing as readable markdown."""
+ lines = []
+ p = briefing["prospect"]
+ lines.append(f"# Pre-Call Briefing: {p['domain']}")
+ lines.append(f"*Generated: {briefing['generated_at']}*")
+ lines.append(f"*Target deal: ${p['deal_target']:,}/mo | Industry: {p.get('industry') or 'Not specified'}*")
+ lines.append("")
+
+ # Prospect snapshot
+ m = p["metrics"]
+ lines.append("## Prospect Snapshot")
+ lines.append(f"- **Domain Authority:** {m['domain_authority']}")
+ lines.append(f"- **Monthly Organic Traffic:** {m['monthly_organic_traffic']:,}")
+ lines.append(f"- **Total Keywords:** {m['total_keywords']:,}")
+ lines.append(f"- **Total Backlinks:** {m['total_backlinks']:,}")
+ lines.append("")
+
+ # Competitor comparison
+ if briefing["competitors"]:
+ lines.append("## Competitor Comparison")
+ lines.append("| Metric | " + p["domain"] + " | " + " | ".join(c["domain"] for c in briefing["competitors"]) + " |")
+ lines.append("|--------|" + "--------|" * (1 + len(briefing["competitors"])))
+ lines.append(f"| DA | {m['domain_authority']} | " + " | ".join(str(c["metrics"]["domain_authority"]) for c in briefing["competitors"]) + " |")
+ lines.append(f"| Traffic | {m['monthly_organic_traffic']:,} | " + " | ".join(f"{c['metrics']['monthly_organic_traffic']:,}" for c in briefing["competitors"]) + " |")
+ lines.append(f"| Keywords | {m['total_keywords']:,} | " + " | ".join(f"{c['metrics']['total_keywords']:,}" for c in briefing["competitors"]) + " |")
+ lines.append("")
+
+ # Anchor data points
+ if briefing["anchor_data_points"]:
+ lines.append("## 🎯 Anchor Data Points")
+ lines.append("*Lead with these. Let the gaps sell the urgency.*")
+ lines.append("")
+ for a in briefing["anchor_data_points"]:
+ icon = "🔴" if a["severity"] == "high" else "🟡"
+ lines.append(f"- {icon} {a['message']}")
+ lines.append("")
+
+ # Competitive triggers
+ if briefing["competitive_triggers"]:
+ lines.append("## ⚡ Competitive Triggers")
+ lines.append("*Use these to activate competitive instinct.*")
+ lines.append("")
+ for t in briefing["competitive_triggers"]:
+ lines.append(f"- **{t['keyword']}**: {t['message']}")
+ lines.append("")
+
+ # Value calculations
+ if briefing["value_calculations"]:
+ lines.append("## 💰 Value Calculations")
+ lines.append("*Make the ROI visual and obvious.*")
+ lines.append("")
+ for v in briefing["value_calculations"]:
+ lines.append(f"### '{v['keyword']}'")
+ lines.append(f"- Current: position #{v['current_position']} → {v['current_monthly_traffic']:,} visits/mo")
+ lines.append(f"- Target: position #{v['target_position']} → {v['projected_monthly_traffic']:,} visits/mo")
+ lines.append(f"- **Additional traffic: +{v['additional_monthly_traffic']:,} visits/mo**")
+ lines.append(f"- **Paid equivalent: ${v['monthly_paid_equivalent']:,.0f}/mo (${v['annual_paid_equivalent']:,.0f}/yr)**")
+ lines.append("")
+
+ opp = briefing["total_opportunity"]
+ lines.append(f"### Total Opportunity")
+ lines.append(f"- Monthly traffic value: **${opp['monthly_paid_equivalent']:,.0f}/mo**")
+ lines.append(f"- Annual traffic value: **${opp['annual_paid_equivalent']:,.0f}/yr**")
+ lines.append(f"- ROI multiple at ${p['deal_target']:,}/mo investment: **{opp['roi_multiple']}x**")
+ lines.append("")
+
+ # Conversation hooks
+ lines.append("## 🎣 Conversation Hooks")
+ lines.append("*Opening questions to surface pain and anchor on value.*")
+ lines.append("")
+ for i, h in enumerate(briefing["conversation_hooks"], 1):
+ lines.append(f"{i}. \"{h}\"")
+ lines.append("")
+
+ # Objection pre-empts
+ lines.append("## 🛡️ Objection Pre-Empts")
+ lines.append("")
+ for key, obj in briefing["objection_preempts"].items():
+ lines.append(f"### \"{obj['objection']}\"")
+ lines.append(f"**Response:** {obj['response']}")
+ lines.append(f"*Principle: {obj['key_principle']}*")
+ lines.append("")
+
+ return "\n".join(lines)
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Value-Based Pricing: Pre-Call Briefing Generator",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog="""
+Examples:
+ python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com,comp2.com"
+ python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com" --industry saas --deal-target 80000
+ python3 value_pricing_briefing.py --domain acme.com --competitors "comp1.com" --format json
+ """,
+ )
+ parser.add_argument("--domain", required=True, help="Prospect's domain (e.g., acme.com)")
+ parser.add_argument("--competitors", required=True, help="Comma-separated competitor domains (e.g., 'comp1.com,comp2.com')")
+ parser.add_argument("--industry", default=None, help="Prospect's industry (e.g., saas, ecommerce, fintech)")
+ parser.add_argument("--deal-target", type=int, default=50000, help="Target monthly deal size in dollars (default: 50000)")
+ parser.add_argument("--format", choices=["markdown", "json", "both"], default="markdown", help="Output format (default: markdown)")
+
+ args = parser.parse_args()
+ competitors = [c.strip() for c in args.competitors.split(",") if c.strip()]
+
+ briefing = generate_briefing(
+ domain=args.domain,
+ competitors=competitors,
+ industry=args.industry,
+ deal_target=args.deal_target,
+ )
+
+ if args.format == "json":
+ print(json.dumps(briefing, indent=2))
+ elif args.format == "both":
+ print(format_markdown(briefing))
+ print("\n---\n## Raw JSON\n")
+ print(json.dumps(briefing, indent=2))
+ else:
+ print(format_markdown(briefing))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/sales-playbook/value_pricing_packager.py b/sales-playbook/value_pricing_packager.py
new file mode 100644
index 0000000..815fcce
--- /dev/null
+++ b/sales-playbook/value_pricing_packager.py
@@ -0,0 +1,391 @@
+#!/usr/bin/env python3
+"""
+Value-Based Pricing: Tiered Package Builder
+
+Input a target deal size and services → auto-generates S/M/L + performance-based
+pricing tiers using value-based pricing principles.
+
+Psychology: Anchor high (Powerhouse), present the real target second (Value),
+create a floor (Baseline), and offer skin-in-the-game (Performance).
+
+Usage:
+ python3 value_pricing_packager.py --target-monthly 80000 --services "seo,cro,content,paid"
+ python3 value_pricing_packager.py --target-monthly 50000 --services "seo,content" --current-spend 10000
+ python3 value_pricing_packager.py --target-monthly 80000 --services "seo,cro,content,paid" --format json
+"""
+
+import argparse
+import json
+import math
+import sys
+from datetime import datetime
+
+# ---------------------------------------------------------------------------
+# Service Deliverable Definitions
+# ---------------------------------------------------------------------------
+# Each service has deliverables scaled by tier multiplier.
+# Format: (deliverable_name, base_quantity, unit, scales_with_tier)
+
+SERVICE_DELIVERABLES = {
+ "seo": {
+ "name": "Search Engine Optimization",
+ "deliverables": [
+ ("Technical SEO audits", 1, "per quarter", False),
+ ("Keyword strategy & mapping", 50, "keywords/mo", True),
+ ("On-page optimization", 15, "pages/mo", True),
+ ("Link building / digital PR", 10, "placements/mo", True),
+ ("Competitive gap analysis", 1, "per month", False),
+ ("Monthly performance reporting", 1, "report/mo", False),
+ ("Strategic SEO roadmap", 1, "per quarter", False),
+ ],
+ "base_cost_pct": 0.30, # Percentage of tier price allocated to this service
+ },
+ "cro": {
+ "name": "Conversion Rate Optimization",
+ "deliverables": [
+ ("CRO audit & heatmap analysis", 1, "per quarter", False),
+ ("A/B test design & execution", 3, "tests/mo", True),
+ ("Landing page optimization", 4, "pages/mo", True),
+ ("Funnel analysis & recommendations", 1, "per month", False),
+ ("User behavior analysis", 1, "per month", False),
+ ("Conversion lift reporting", 1, "report/mo", False),
+ ],
+ "base_cost_pct": 0.20,
+ },
+ "content": {
+ "name": "Content Marketing",
+ "deliverables": [
+ ("Content strategy & editorial calendar", 1, "per month", False),
+ ("Long-form blog posts (2000+ words)", 8, "posts/mo", True),
+ ("Content briefs with keyword targeting", 10, "briefs/mo", True),
+ ("Content refresh & optimization", 5, "posts/mo", True),
+ ("Social content repurposing", 10, "pieces/mo", True),
+ ("Thought leadership pieces", 2, "pieces/mo", True),
+ ],
+ "base_cost_pct": 0.25,
+ },
+ "paid": {
+ "name": "Paid Media Management",
+ "deliverables": [
+ ("Campaign strategy & setup", 1, "per quarter", False),
+ ("Ad creative development", 10, "creatives/mo", True),
+ ("Audience research & targeting", 1, "per month", False),
+ ("Bid management & optimization", 1, "ongoing", False),
+ ("A/B testing (ad copy & creative)", 5, "tests/mo", True),
+ ("Cross-channel attribution reporting", 1, "report/mo", False),
+ ("Budget allocation optimization", 1, "per month", False),
+ ],
+ "base_cost_pct": 0.25,
+ },
+}
+
+# ---------------------------------------------------------------------------
+# Tier Definitions
+# ---------------------------------------------------------------------------
+
+TIER_CONFIGS = {
+ "powerhouse": {
+ "name": "Powerhouse",
+ "subtitle": "Maximum growth, maximum impact",
+ "multiplier_range": (1.30, 1.50),
+ "deliverable_scale": 2.0,
+ "description": "Full-service engagement with senior strategic involvement, dedicated team, and aggressive growth targets. For companies ready to dominate their market.",
+ "extras": [
+ "Dedicated senior strategist (weekly 1:1)",
+ "C-suite quarterly business reviews",
+ "Priority support (4-hour SLA)",
+ "Custom dashboard & real-time reporting",
+ "Competitive intelligence briefings (monthly)",
+ ],
+ "excluded": [],
+ },
+ "value": {
+ "name": "Value",
+ "subtitle": "The sweet spot: high impact, smart investment",
+ "multiplier_range": (1.0, 1.0),
+ "deliverable_scale": 1.0,
+ "description": "Our recommended engagement. Covers all critical growth levers with a proven team and methodology. Where most of our successful clients land.",
+ "extras": [
+ "Senior strategist oversight (bi-weekly)",
+ "Monthly executive summary",
+ "Standard support (24-hour SLA)",
+ ],
+ "excluded": [
+ "Dedicated senior strategist 1:1s (Powerhouse only)",
+ "Real-time custom dashboard (Powerhouse only)",
+ ],
+ },
+ "baseline": {
+ "name": "Baseline",
+ "subtitle": "Foundation for growth",
+ "multiplier_range": (0.40, 0.50),
+ "deliverable_scale": 0.5,
+ "description": "Focused engagement on your highest-impact channels. Ideal for proving the model before scaling, or for companies with some in-house capability.",
+ "extras": [
+ "Monthly strategy call",
+ "Standard reporting",
+ ],
+ "excluded": [
+ "Senior strategist involvement (Value+ only)",
+ "Multi-channel optimization (Value+ only)",
+ "Competitive intelligence (Powerhouse only)",
+ "A/B testing programs (Value+ only)",
+ ],
+ },
+ "performance": {
+ "name": "Performance",
+ "subtitle": "We eat what we kill",
+ "multiplier_range": (0.30, 0.40), # Base is lower
+ "deliverable_scale": 0.75,
+ "description": "Lower base investment + performance bonuses tied to outcomes. We put skin in the game. Aligns incentives so we only win when you win.",
+ "extras": [
+ "Performance bonus triggers tied to KPIs",
+ "Monthly strategy call",
+ "Transparent KPI dashboard",
+ ],
+ "excluded": [
+ "Senior strategist 1:1s (Powerhouse only)",
+ "Guaranteed deliverable volumes (see performance tiers)",
+ ],
+ "bonus_triggers": [
+ {"trigger": "Organic traffic increases 50%+ from baseline", "bonus_pct": 0.15},
+ {"trigger": "Conversion rate improves 25%+ from baseline", "bonus_pct": 0.10},
+ {"trigger": "Revenue attributed to organic exceeds 3x monthly investment", "bonus_pct": 0.20},
+ {"trigger": "Rank #1-3 for 5+ target money keywords", "bonus_pct": 0.10},
+ ],
+ },
+}
+
+
+def _scale_deliverables(service_key: str, scale: float, tier_price: float) -> list:
+ """Scale service deliverables based on tier."""
+ service = SERVICE_DELIVERABLES[service_key]
+ scaled = []
+ for name, base_qty, unit, scales in service["deliverables"]:
+ qty = math.ceil(base_qty * scale) if scales else base_qty
+ scaled.append({"deliverable": name, "quantity": qty, "unit": unit})
+ return scaled
+
+
+def _calculate_roi_projection(monthly_price: float, services: list) -> dict:
+ """Generate ROI projection based on investment level and services."""
+ # Conservative multiplier based on service combination
+ base_multiplier = 3.0
+ if "seo" in services and "cro" in services:
+ base_multiplier += 1.5 # Compounding effect
+ if "content" in services and "seo" in services:
+ base_multiplier += 1.0
+ if len(services) >= 3:
+ base_multiplier += 0.5 # Full-stack bonus
+
+ annual_investment = monthly_price * 12
+ projected_return = annual_investment * base_multiplier
+
+ return {
+ "monthly_investment": monthly_price,
+ "annual_investment": annual_investment,
+ "projected_annual_return": round(projected_return, 0),
+ "roi_multiple": round(base_multiplier, 1),
+ "payback_period_months": round(12 / base_multiplier, 1),
+ "projection_basis": "Based on median outcomes across similar engagements (anonymized). Individual results vary based on market, competition, and execution.",
+ }
+
+
+def generate_packages(target_monthly: int, services: list, current_spend: int = 0) -> dict:
+ """Generate all 4 pricing tiers."""
+ packages = {"generated_at": datetime.now().isoformat(), "target_monthly": target_monthly, "services": services, "current_spend": current_spend, "tiers": {}}
+
+ for tier_key, config in TIER_CONFIGS.items():
+ low, high = config["multiplier_range"]
+ multiplier = (low + high) / 2
+ monthly_price = int(round(target_monthly * multiplier, -2)) # Round to nearest 100
+
+ # Build deliverables per service
+ tier_deliverables = {}
+ for svc in services:
+ if svc in SERVICE_DELIVERABLES:
+ tier_deliverables[svc] = {
+ "service_name": SERVICE_DELIVERABLES[svc]["name"],
+ "deliverables": _scale_deliverables(svc, config["deliverable_scale"], monthly_price),
+ }
+
+ tier = {
+ "name": config["name"],
+ "subtitle": config["subtitle"],
+ "description": config["description"],
+ "monthly_price": monthly_price,
+ "annual_price": monthly_price * 12,
+ "vs_target": f"{multiplier * 100:.0f}%",
+ "deliverables_by_service": tier_deliverables,
+ "included_extras": config["extras"],
+ "not_included": config["excluded"],
+ "roi_projection": _calculate_roi_projection(monthly_price, services),
+ }
+
+ # Add performance bonus info
+ if tier_key == "performance":
+ tier["bonus_structure"] = {
+ "base_monthly": monthly_price,
+ "triggers": config["bonus_triggers"],
+ "max_monthly_with_bonuses": round(monthly_price * 1.55, -2),
+ "note": "Bonuses are additive. If all triggers hit, total monthly = base + sum of bonus percentages applied to base.",
+ }
+
+ # Add context vs current spend
+ if current_spend > 0:
+ tier["vs_current_spend"] = {
+ "current": current_spend,
+ "proposed": monthly_price,
+ "difference": monthly_price - current_spend,
+ "increase_pct": round((monthly_price - current_spend) / current_spend * 100, 0),
+ }
+
+ packages["tiers"][tier_key] = tier
+
+ return packages
+
+
+def format_markdown(packages: dict) -> str:
+ """Format packages as a proposal-ready markdown document."""
+ lines = []
+ lines.append("# Investment Options")
+ lines.append(f"*Prepared: {packages['generated_at'][:10]}*")
+ lines.append(f"*Services: {', '.join(s.upper() for s in packages['services'])}*")
+ lines.append("")
+
+ if packages["current_spend"] > 0:
+ lines.append(f"> Current monthly investment: ${packages['current_spend']:,}")
+ lines.append("")
+
+ # Summary table
+ lines.append("## Package Overview")
+ lines.append("")
+ lines.append("| | Powerhouse | Value ⭐ | Baseline | Performance |")
+ lines.append("|---|---|---|---|---|")
+
+ tiers = packages["tiers"]
+ lines.append(f"| Monthly | ${tiers['powerhouse']['monthly_price']:,} | ${tiers['value']['monthly_price']:,} | ${tiers['baseline']['monthly_price']:,} | ${tiers['performance']['monthly_price']:,} base |")
+ lines.append(f"| Annual | ${tiers['powerhouse']['annual_price']:,} | ${tiers['value']['annual_price']:,} | ${tiers['baseline']['annual_price']:,} | ${tiers['performance']['annual_price']:,}+ |")
+ lines.append(f"| ROI Multiple | {tiers['powerhouse']['roi_projection']['roi_multiple']}x | {tiers['value']['roi_projection']['roi_multiple']}x | {tiers['baseline']['roi_projection']['roi_multiple']}x | {tiers['performance']['roi_projection']['roi_multiple']}x+ |")
+ lines.append("")
+
+ # Detailed tiers
+ for tier_key in ["powerhouse", "value", "baseline", "performance"]:
+ tier = tiers[tier_key]
+ star = " ⭐ Recommended" if tier_key == "value" else ""
+ lines.append(f"---")
+ lines.append(f"## {tier['name']}{star}")
+ lines.append(f"### *{tier['subtitle']}*")
+ lines.append(f"**${tier['monthly_price']:,}/mo** (${tier['annual_price']:,}/yr)")
+ lines.append("")
+ lines.append(tier["description"])
+ lines.append("")
+
+ # Deliverables
+ for svc_key, svc_data in tier["deliverables_by_service"].items():
+ lines.append(f"#### {svc_data['service_name']}")
+ for d in svc_data["deliverables"]:
+ lines.append(f"- {d['deliverable']}: **{d['quantity']} {d['unit']}**")
+ lines.append("")
+
+ # Extras
+ if tier["included_extras"]:
+ lines.append("**Also included:**")
+ for e in tier["included_extras"]:
+ lines.append(f"- ✅ {e}")
+ lines.append("")
+
+ # Not included
+ if tier["not_included"]:
+ lines.append("**Not included in this tier:**")
+ for e in tier["not_included"]:
+ lines.append(f"- ❌ {e}")
+ lines.append("")
+
+ # Performance bonus details
+ if tier_key == "performance" and "bonus_structure" in tier:
+ bs = tier["bonus_structure"]
+ lines.append("**Performance Bonus Triggers:**")
+ for bt in bs["triggers"]:
+ lines.append(f"- 🎯 {bt['trigger']} → +{bt['bonus_pct'] * 100:.0f}% of base")
+ lines.append(f"- Max monthly (all bonuses): **${bs['max_monthly_with_bonuses']:,}**")
+ lines.append("")
+
+ # ROI
+ roi = tier["roi_projection"]
+ lines.append(f"**ROI Projection:**")
+ lines.append(f"- Annual investment: ${roi['annual_investment']:,}")
+ lines.append(f"- Projected annual return: ${roi['projected_annual_return']:,.0f}")
+ lines.append(f"- ROI multiple: {roi['roi_multiple']}x")
+ lines.append(f"- Payback period: {roi['payback_period_months']} months")
+ lines.append(f"- *{roi['projection_basis']}*")
+ lines.append("")
+
+ # Vs current spend
+ if "vs_current_spend" in tier:
+ vs = tier["vs_current_spend"]
+ lines.append(f"**vs. Current Spend:**")
+ direction = "increase" if vs["difference"] > 0 else "decrease"
+ lines.append(f"- Current: ${vs['current']:,}/mo → Proposed: ${vs['proposed']:,}/mo ({vs['increase_pct']:+.0f}% {direction})")
+ lines.append("")
+
+ # Pricing philosophy note
+ lines.append("---")
+ lines.append("## Why These Tiers?")
+ lines.append("")
+ lines.append("We believe pricing should reflect value, not hours. Each tier is designed around outcomes:")
+ lines.append("- **Powerhouse** is for companies ready to make an aggressive move and want senior strategic involvement at every level.")
+ lines.append("- **Value** is where most of our successful clients land. It covers all critical growth levers without over-investing before proving the model.")
+ lines.append("- **Baseline** is a focused starting point. Prove the ROI, then scale.")
+ lines.append("- **Performance** aligns our incentives with yours. We only win when you win.")
+ lines.append("")
+ lines.append("*We recommend starting the conversation with what success looks like for your business, then working backward to the right investment level.*")
+
+ return "\n".join(lines)
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Value-Based Pricing: Tiered Package Builder",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog="""
+Examples:
+ python3 value_pricing_packager.py --target-monthly 80000 --services "seo,cro,content,paid"
+ python3 value_pricing_packager.py --target-monthly 50000 --services "seo,content" --current-spend 10000
+ python3 value_pricing_packager.py --target-monthly 80000 --services "seo,cro,content,paid" --format json
+ """,
+ )
+ parser.add_argument("--target-monthly", type=int, required=True, help="Target monthly deal size in dollars")
+ parser.add_argument("--services", required=True, help="Comma-separated services (seo,cro,content,paid)")
+ parser.add_argument("--current-spend", type=int, default=0, help="Prospect's current monthly marketing spend")
+ parser.add_argument("--format", choices=["markdown", "json", "both"], default="markdown", help="Output format (default: markdown)")
+
+ args = parser.parse_args()
+ services = [s.strip().lower() for s in args.services.split(",") if s.strip()]
+
+ # Validate services
+ valid_services = set(SERVICE_DELIVERABLES.keys())
+ invalid = [s for s in services if s not in valid_services]
+ if invalid:
+ print(f"Error: Unknown services: {', '.join(invalid)}", file=sys.stderr)
+ print(f"Valid services: {', '.join(sorted(valid_services))}", file=sys.stderr)
+ sys.exit(1)
+
+ packages = generate_packages(
+ target_monthly=args.target_monthly,
+ services=services,
+ current_spend=args.current_spend,
+ )
+
+ if args.format == "json":
+ print(json.dumps(packages, indent=2))
+ elif args.format == "both":
+ print(format_markdown(packages))
+ print("\n---\n## Raw JSON\n")
+ print(json.dumps(packages, indent=2))
+ else:
+ print(format_markdown(packages))
+
+
+if __name__ == "__main__":
+ main()