diff --git a/marketing/CAMPAIGN-PLAYBOOK.md b/marketing/CAMPAIGN-PLAYBOOK.md new file mode 100644 index 000000000..7000ac695 --- /dev/null +++ b/marketing/CAMPAIGN-PLAYBOOK.md @@ -0,0 +1,310 @@ +# Marketing Campaign Playbook +## Build a Full Ad Campaign from Publicly Available Information + +A repeatable process for generating complete, client-ready marketing campaign assets — social ads, email, print, and a live deployable showcase — using only public information about the client. + +--- + +## Overview + +**Input**: A client name, website, or brief description +**Output**: A fully deployed marketing campaign showcase with: +- Brand guidelines (derived from research) +- Facebook/Instagram ad mockups (HTML) +- Instagram Stories & Posts (HTML) +- Email campaign (HTML) +- Event poster / print asset (HTML) +- Social media copy (Twitter/X thread, LinkedIn/Facebook copy) +- Optional: Next.js AI-powered generator app (Claude API) +- Deployed to Vercel at a shareable URL + +**Time to complete**: ~2–4 hours (mostly research + asset generation) + +--- + +## Step 1 — Client Research (Public Sources Only) + +Collect all publicly available information. Use `WebSearch` and `WebFetch`. + +### Research Checklist + +``` +[ ] Official website — homepage, about, services/products +[ ] Social media profiles — Instagram, Facebook, LinkedIn, TikTok +[ ] Event pages — Eventbrite, Humanitix, or similar ticketing +[ ] Google Business Profile / reviews +[ ] Press mentions / media coverage +[ ] Competitor landscape (3–5 competitors) +[ ] Target audience signals (who engages, who they speak to) +``` + +### Key Data Points to Extract + +| Field | Where to Find | +|-------|---------------| +| Brand name & tagline | Website homepage | +| Founder / key person | About page, LinkedIn | +| Mission & values | About page | +| Products / services / events | Services/events pages | +| Pricing / tiers | Pricing page or ticketing | +| Colours & fonts | Website CSS / visual inspection | +| Tone of voice | Existing copy | +| Target audience | About page, social bio, ad targeting | +| Social proof (stats, testimonials) | Website, Google reviews | +| Hashtags in use | Instagram posts | +| Key dates / deadlines | Events page | +| Competitors | Search "[niche] + [location]" | + +--- + +## Step 2 — Create Brand Guidelines + +Save as `marketing/[client-slug]/brand-guidelines.md` + +Use the template at `marketing/_template/brand-guidelines-template.md`. + +Sections to fill: +1. **Brand Overview** — who, what, why, founder, website, social handles +2. **Brand Personality** — 5–6 traits with descriptions +3. **Colour Palette** — primary, secondary, accent (hex codes), with usage notes +4. **Typography** — display font, heading font, body font, CTA font +5. **Key Messages** — signature phrases, taglines, mission language, urgency lines +6. **Imagery Style** — photography direction, mood, what to avoid +7. **Do's and Don'ts** — explicit guardrails +8. **Campaign Goal** — specific, measurable (e.g. "sell 200 tickets") + +--- + +## Step 3 — Build Campaign Assets + +### Folder Structure + +``` +marketing/ + [client-slug]/ + brand-guidelines.md ← Step 2 output + index.html ← Campaign showcase hub + vercel.json ← Deployment config + ads/ + facebook-ad-mockups.html ← 3–6 ad variations + social-media/ + instagram-posts.html ← Feed post mockups + instagram-stories.html ← Story mockups (9:16) + facebook-linkedin-ads.md ← Ad copy text + twitter-x-thread.md ← Thread copy + email/ + email-campaign.html ← Full email mockup + print/ + event-poster.html ← A3/A4 poster or flyer + generator/ ← Optional: AI generator app + app/ + package.json + vercel.json +``` + +### Asset Build Order (recommended) + +1. `brand-guidelines.md` — reference for everything else +2. `index.html` — scaffold the hub first (add links as assets are created) +3. `ads/facebook-ad-mockups.html` — highest ROI asset for most clients +4. `social-media/instagram-posts.html` +5. `social-media/instagram-stories.html` +6. `email/email-campaign.html` +7. `print/event-poster.html` +8. Copy decks (`facebook-linkedin-ads.md`, `twitter-x-thread.md`) + +--- + +## Step 4 — Build the Campaign Showcase Hub (index.html) + +The `index.html` is a single-page portal that links to all assets. Include: + +- Hero section with brand name, tagline, campaign goal +- Nav links to each asset section +- Preview thumbnails / iframe previews of each deliverable +- "Open full page" links for each asset +- Brand colour palette and font preview strip +- Download/export notes for the client + +See `marketing/_template/index-template.html` for the scaffold. + +--- + +## Step 5 — (Optional) AI Generator App + +Build a Next.js app that uses the Claude API so the client can generate more content on-demand. + +``` +generator/ + app/ + page.tsx ← UI with form (audience, tone, goal, channels) + api/ + generate/ + route.ts ← Claude API call with brand guidelines as system prompt + package.json + vercel.json + .env.example ← ANTHROPIC_API_KEY placeholder +``` + +**System prompt pattern**: Load `brand-guidelines.md` content as the system prompt so Claude always generates on-brand content. + +**UI inputs**: Channel (Instagram/Facebook/Email/etc.), Tone, Target Audience, Goal, CTA + +See `marketing/_template/generator/` for the full scaffold. + +--- + +## Step 6 — Deploy to Vercel + +### Root-level `vercel.json` (static site — no builds key) + +```json +{ + "rewrites": [ + { "source": "/ads/(.*)", "destination": "/ads/$1" }, + { "source": "/social-media/(.*)", "destination": "/social-media/$1" }, + { "source": "/email/(.*)", "destination": "/email/$1" }, + { "source": "/print/(.*)", "destination": "/print/$1" } + ] +} +``` + +> **Critical**: Do NOT add a `"builds"` key for static HTML projects. This causes Vercel errors. + +### Generator app `vercel.json` (Next.js) + +```json +{ + "framework": "nextjs", + "buildCommand": "npm run build", + "outputDirectory": ".next" +} +``` + +### Deploy commands + +```bash +# Static showcase (from client folder root) +cd marketing/[client-slug] +vercel --prod + +# Generator app (from generator subfolder) +cd marketing/[client-slug]/generator +vercel --prod +``` + +### Environment variables (generator app only) + +Set in Vercel dashboard or via CLI: +```bash +vercel env add ANTHROPIC_API_KEY +``` + +--- + +## Step 7 — Handoff to Client + +Deliver: +1. **Live URL** — the deployed Vercel showcase link +2. **GitHub branch** — all source files in version control +3. **brand-guidelines.md** — editable brand document +4. **Copy decks** (`.md` files) — ready to paste into ad platforms +5. **Generator app URL** — if built, for ongoing content creation + +### Client Instructions Template + +``` +Hi [Client], + +Your campaign assets are ready. Here's everything: + +🌐 Campaign Showcase: [vercel-url] + All your ads, social posts, email, and print assets in one place. + +✍️ Copy Decks (paste-ready): + - Facebook/LinkedIn Ads: [link to .md file] + - Twitter/X Thread: [link to .md file] + +🤖 AI Content Generator (optional): [generator-url] + Enter your ANTHROPIC_API_KEY to generate more on-brand content. + +📁 Source Files: [github-branch-link] + +Brand guidelines are in brand-guidelines.md — update this as your brand evolves. +``` + +--- + +## Replication Checklist (New Client) + +```bash +# 1. Create client folder +cp -r marketing/_template marketing/[new-client-slug] + +# 2. Fill in brand-guidelines.md from research +# 3. Build assets (customise HTML templates with brand colours/copy) +# 4. Update index.html hub +# 5. Deploy +cd marketing/[new-client-slug] +vercel --prod +``` + +--- + +## Quality Checklist Before Delivery + +``` +[ ] All brand colours match guidelines (check hex codes) +[ ] All fonts match guidelines +[ ] No placeholder text ([CLIENT], [DATE], etc.) remaining +[ ] All CTAs link to real URLs (or noted as "replace with X") +[ ] Email renders correctly at 600px width +[ ] Instagram posts are 1:1 ratio (1080×1080) +[ ] Instagram Stories are 9:16 ratio (1080×1920) +[ ] Facebook ads are 1.91:1 ratio (1200×628) for feed +[ ] vercel.json has no "builds" key (for static sites) +[ ] Deployed URL is accessible publicly +[ ] Generator app: ANTHROPIC_API_KEY env var set +``` + +--- + +## Asset Dimensions Reference + +| Format | Dimensions | Ratio | +|--------|-----------|-------| +| Facebook/Instagram Feed Ad | 1200×628px | 1.91:1 | +| Instagram Square Post | 1080×1080px | 1:1 | +| Instagram Story | 1080×1920px | 9:16 | +| Facebook Cover | 1640×624px | — | +| Email Width | 600px | — | +| A4 Print Poster | 210×297mm / 2480×3508px | — | +| Twitter/X Card | 1200×675px | 16:9 | + +--- + +## Time Budget Per Asset + +| Asset | Estimated Time | +|-------|---------------| +| Research + brand guidelines | 30–45 min | +| Facebook ad mockups (3–6 ads) | 30–45 min | +| Instagram posts + stories | 30–45 min | +| Email campaign | 20–30 min | +| Print poster | 20–30 min | +| Copy decks | 15–20 min | +| Showcase hub (index.html) | 20–30 min | +| Generator app | 45–60 min | +| Deployment + QA | 15–20 min | + +--- + +## Examples + +| Client | Niche | Branch | +|--------|-------|--------| +| Thriving Through Menopause | Medical aesthetics symposium | `claude/menopause-symposium-marketing-ojszT` | + +--- + +*Template version: 1.0 — March 2026* diff --git a/marketing/_template/ads/facebook-ad-mockups.html b/marketing/_template/ads/facebook-ad-mockups.html new file mode 100644 index 000000000..21287a0fd --- /dev/null +++ b/marketing/_template/ads/facebook-ad-mockups.html @@ -0,0 +1,108 @@ + + + + + + + [CLIENT NAME] — Facebook Ad Mockups + + + + + + +

[CLIENT NAME]

+

Facebook & Instagram Ad Mockups — [Campaign Name]

+ +
+ + +
+
Ad 1 — Awareness
+
+ + [HEADLINE TEXT] +
+
+
[Page Name]
+ +

[Primary text / body copy — 1–3 sentences. Hook, value, CTA.]

+
[Ad headline — short, punchy]
+
[Description line — optional supporting text]
+ Learn More +
+
+ + +
+
Ad 2 — Consideration
+
[HEADLINE TEXT]
+
+
[Page Name]
+

[Primary text]

+
[Headline]
+
[Description]
+ Learn More +
+
+ + +
+
Ad 3 — Conversion
+
[HEADLINE TEXT]
+
+
[Page Name]
+

[Primary text]

+
[Headline]
+
[Description]
+ Get Tickets +
+
+ + +
+
Ad 4 — Social Proof
+
[QUOTE TEXT]
+
+
[Page Name]
+

[Primary text]

+
[Headline]
+
[Description]
+ Register Now +
+
+ + + +
+ + diff --git a/marketing/_template/brand-guidelines-template.md b/marketing/_template/brand-guidelines-template.md new file mode 100644 index 000000000..f109c646a --- /dev/null +++ b/marketing/_template/brand-guidelines-template.md @@ -0,0 +1,154 @@ +# [CLIENT NAME] — Brand Guidelines + +## Brand Overview +**[CLIENT NAME]** is [one-line description of what they do]. + +**[Founder/Key Person]**: [Name] — [credentials/title] + +**[Founder's signature phrase / philosophy]**: *"[Quote if available]"* + +**Website**: [URL] +**Instagram**: [@handle] +**Facebook**: [URL or handle] +**LinkedIn**: [URL or handle] +**Ticket/Booking platform**: [URL if applicable] +**Event/Key date**: [Date if applicable] +**Venue**: [Location if applicable] +**Ticket/Service types**: [List] +**Primary target audience**: [Who they serve] +**Secondary audience**: [Broader audience] + +--- + +## Brand Personality + +| Trait | Description | +|-------|-------------| +| **[Trait 1]** | [What it means in practice] | +| **[Trait 2]** | [What it means in practice] | +| **[Trait 3]** | [What it means in practice] | +| **[Trait 4]** | [What it means in practice] | +| **[Trait 5]** | [What it means in practice] | + +**Brand Voice**: [2–3 sentences describing how the brand sounds. E.g. warm, authoritative, approachable, never X.] + +--- + +## Color Palette + +| Name | Hex | Usage | +|------|-----|-------| +| **[Primary Color]** | `#XXXXXX` | Primary headings, CTAs, strong emphasis | +| **[Secondary Color]** | `#XXXXXX` | Secondary elements, accents, highlights | +| **[Background Color]** | `#XXXXXX` | Backgrounds, cards, breathing space | +| **[Accent Color]** | `#XXXXXX` | Premium accents, borders, icon details | +| **[Supporting Color]** | `#XXXXXX` | Mid-tone, gradients, supporting elements | +| **Text Dark** | `#XXXXXX` | Body text, dark backgrounds | +| **Text Light** | `#XXXXXX` | Page backgrounds, light sections | + +### Gradient Directions +- **Primary Gradient**: `linear-gradient(135deg, #XXXXXX 0%, #XXXXXX 50%, #XXXXXX 100%)` +- **Light Gradient**: `linear-gradient(135deg, #XXXXXX 0%, #XXXXXX 100%)` + +--- + +## Typography + +| Role | Font | Style | +|------|------|-------| +| **Display/Hero** | [Font Name] | Bold, italic for impact | +| **Headings** | [Font Name] | Regular, Semi-bold | +| **Body** | [Font Name] | Regular 400 | +| **Accent/Captions** | [Font Name] | Italic, for quotes | +| **CTA Buttons** | [Font Name] | Bold, uppercase, tracked | + +--- + +## Key Messages + +### Signature Phrase (use as headline/hook) +> **"[Most powerful single piece of copy]"** + +### Official Taglines +> **"[Tagline 1]"** +> **"[Tagline 2]"** + +### Brand Positioning +> **"[What makes them first/best/unique]"** + +### Campaign Taglines +- "[Option 1]" +- "[Option 2]" +- "[Option 3]" +- "[Option 4]" + +### Mission Language +- "[Mission statement fragment]" +- "[Value proposition]" + +--- + +## Products / Services / Ticket Options + +**[Tier 1 / Basic]** +- [Benefit 1] +- [Benefit 2] +- [Benefit 3] +- [Price if known] + +**[Tier 2 / Premium]** (includes everything above, plus) +- [Extra benefit 1] +- [Extra benefit 2] +- [Price if known] + +--- + +## Urgency Messaging (Non-Pushy) +- "[Scarcity line 1]" +- "[Credibility line]" +- "[FOMO line]" +- "[Value line]" + +--- + +## Social Proof +- [Statistic or award] +- [Testimonial or review snippet] +- [Media mention if available] + +--- + +## Imagery Style +- **Photography**: [Describe ideal photography — people, settings, mood] +- **Setting**: [Where photos should be taken / what kind of environment] +- **Avoidance**: [What NOT to show] +- **Mood**: [Feeling the imagery should evoke] + +--- + +## Do's and Don'ts + +### ✅ Do +- [Guideline 1] +- [Guideline 2] +- [Guideline 3] +- [Guideline 4] + +### ❌ Don't +- [Anti-pattern 1] +- [Anti-pattern 2] +- [Anti-pattern 3] +- [Anti-pattern 4] + +--- + +## Social Media Handles & Hashtags +- **Website**: [URL] +- **Instagram**: [@handle] +- **Hashtags**: #[Tag1] #[Tag2] #[Tag3] #[Tag4] #[Tag5] + +--- + +## Campaign Goal +**[Specific, measurable goal]** — e.g. "Sell 200 tickets", "Generate 500 leads", "Drive 1,000 signups" +Strategy: [How you'll get there — one sentence] diff --git a/marketing/_template/generator/.env.example b/marketing/_template/generator/.env.example new file mode 100644 index 000000000..ff7cbeea5 --- /dev/null +++ b/marketing/_template/generator/.env.example @@ -0,0 +1 @@ +ANTHROPIC_API_KEY=your_key_here diff --git a/marketing/_template/generator/app/api/generate/route.ts b/marketing/_template/generator/app/api/generate/route.ts new file mode 100644 index 000000000..9d779e7df --- /dev/null +++ b/marketing/_template/generator/app/api/generate/route.ts @@ -0,0 +1,54 @@ +import Anthropic from "@anthropic-ai/sdk"; +import { NextRequest, NextResponse } from "next/server"; +import fs from "fs"; +import path from "path"; + +const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }); + +// Load brand guidelines as system context +// REPLACE: Update path to point to your client's brand-guidelines.md +function getBrandGuidelines(): string { + try { + const guidelinesPath = path.join(process.cwd(), "..", "brand-guidelines.md"); + return fs.readFileSync(guidelinesPath, "utf-8"); + } catch { + return "Use a professional, warm, and empowering tone."; + } +} + +export async function POST(request: NextRequest) { + const { channel, tone, audience, goal, cta, extraContext } = await request.json(); + + const brandGuidelines = getBrandGuidelines(); + + const systemPrompt = `You are an expert marketing copywriter. You always write on-brand copy based on the following brand guidelines: + +${brandGuidelines} + +Always follow the brand's voice, colour references, messaging hierarchy, and do's/don'ts.`; + + const userPrompt = `Generate marketing copy for the following: + +Channel: ${channel} +Tone: ${tone} +Target Audience: ${audience} +Goal: ${goal} +CTA: ${cta} +${extraContext ? `Additional context: ${extraContext}` : ""} + +Produce complete, ready-to-use copy. Format clearly with labels for each element (e.g. Headline, Body, CTA, Hashtags).`; + + const message = await client.messages.create({ + model: "claude-opus-4-6", + max_tokens: 1024, + system: systemPrompt, + messages: [{ role: "user", content: userPrompt }], + }); + + const content = message.content[0]; + if (content.type !== "text") { + return NextResponse.json({ error: "Unexpected response type" }, { status: 500 }); + } + + return NextResponse.json({ copy: content.text }); +} diff --git a/marketing/_template/generator/app/layout.tsx b/marketing/_template/generator/app/layout.tsx new file mode 100644 index 000000000..bc1b12fda --- /dev/null +++ b/marketing/_template/generator/app/layout.tsx @@ -0,0 +1,15 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + // REPLACE: Update with client name + title: "[CLIENT NAME] — AI Content Generator", + description: "Generate on-brand marketing copy", +}; + +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} diff --git a/marketing/_template/generator/app/page.tsx b/marketing/_template/generator/app/page.tsx new file mode 100644 index 000000000..d88cdca5d --- /dev/null +++ b/marketing/_template/generator/app/page.tsx @@ -0,0 +1,108 @@ +"use client"; +import { useState } from "react"; + +const CHANNELS = ["Instagram Post", "Instagram Story", "Facebook Ad", "LinkedIn Post", "Twitter/X Thread", "Email Campaign", "Print/Flyer"]; +const TONES = ["Warm & Empowering", "Professional & Expert", "Urgent & Action-Oriented", "Playful & Engaging", "Educational & Informative"]; +const GOALS = ["Awareness", "Event Registration", "Lead Generation", "Product Sale", "Community Building", "Brand Authority"]; + +export default function GeneratorPage() { + const [form, setForm] = useState({ + channel: CHANNELS[0], + tone: TONES[0], + audience: "", + goal: GOALS[0], + cta: "", + extraContext: "", + }); + const [output, setOutput] = useState(""); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(""); + + const generate = async () => { + setLoading(true); + setError(""); + setOutput(""); + try { + const res = await fetch("/api/generate", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(form), + }); + const data = await res.json(); + if (data.error) throw new Error(data.error); + setOutput(data.copy); + } catch (e: unknown) { + setError(e instanceof Error ? e.message : "Something went wrong"); + } finally { + setLoading(false); + } + }; + + const field = (label: string, key: keyof typeof form, type: "text" | "textarea" | "select", options?: string[]) => ( +
+ + {type === "select" ? ( + + ) : type === "textarea" ? ( +