---
name: "Email newsletter"
repo: https://github.com/varnan-tech/opendirectory
source: https://github.com/varnan-tech/opendirectory/blob/HEAD/skills/email-newsletter/SKILL.md
license: "MIT"
install: "npx skills add varnan-tech/opendirectory --skill email-newsletter"
page: https://100xlab.com/resources/agent-skills/varnan-tech-opendirectory--email-newsletter--18zmrci
---

# Email Newsletter

Draft and design a complete HTML email newsletter from a topic or content brief. Output is paste-ready for Loops, Mailchimp, Beehiiv, Resend, or any standard email platform.

---

**Critical rule:** Table-based HTML with inline styles only. No CSS classes, no flexbox, no grid, no `<style>` blocks. Every element gets `style=""` directly. This is not optional -- email clients strip everything else.

---

## Step 1: Brief Intake

Need three things to start. If all three present in the message: skip to Step 2.

If any missing, ask exactly:

> "To get started, I need three things:
> 1. **Topic** -- what is this newsletter about?
> 2. **Audience** -- who is reading? (role, company size, how they know you)
> 3. **Primary CTA** -- what one action do you want readers to take?"

Wait for all three before continuing.

---

## Step 2: Complete Intake

Ask all questions in one message, grouped by category. User can skip any -- defaults apply.

> "A few questions before I draft -- answer what you know, skip the rest:
>
> **Content**
> 1. **Length** -- brief (300 words, punchy) / standard (500-700) / deep dive (800+ words)?
> 2. **Format** -- editorial article / numbered breakdown / personal story / data report?
> 3. **Issue context** -- one-time send / part of weekly series / monthly digest?
> 4. **CTA URL** -- what's the actual link? (or I'll use a placeholder)
>
> **Brand**
> 5. **Company / brand name** -- for header and footer
> 6. **Tagline** -- one-line description (optional, for footer)
> 7. **City & country** -- for footer (e.g. "San Francisco, US")
> 8. **Primary brand color** -- hex? (e.g. #856FE6)
> 9. **Secondary accent** -- keep default yellow-green (#D8F90A) / use brand color / something else?
>
> **Design**
> 10. **Background** -- dark (editorial/SaaS) / light (clean/corporate) / custom hex?
> 11. **Display font** -- editorial serif (Instrument Serif) / clean modern sans / system fonts only?
> 12. **Button style** -- pill (very rounded) / softly rounded / sharp corners?
> 13. **Visual style** -- editorial / technical+data / warm+founder / bold+campaign?
>
> **Platform & Technical**
> 14. **Platform** -- Loops / Mailchimp / Beehiiv / Resend / other?
> 15. **Tone** -- educational / conversational / bold+direct / formal / playful?
> 16. **Personalization** -- none / first name / first name + company?
> 17. **Subject line** -- have one / want 3 options?
> 18. **Secondary sections** -- sponsor block / product callout / event / quick links / none?
> 19. **Plain-text version** -- yes (recommended) / no?"

**Defaults if skipped:**

| Question | Default |
|---|---|
| Length | standard (500-700 words) |
| Format | editorial article |
| Issue context | one-time send |
| CTA URL | `[CTA_URL]` placeholder |
| Company name | `[YOUR BRAND]` placeholder |
| Tagline | none |
| City & country | `[CITY, COUNTRY]` placeholder |
| Brand color | none (use `#D8F90A` for all accents) |
| Secondary accent | `#D8F90A` (yellow-green default) |
| Background | dark |
| Display font | Instrument Serif (editorial serif) |
| Button style | pill |
| Visual style | editorial |
| Platform | generic |
| Tone | conversational |
| Personalization | none |
| Subject line | generate 3 options |
| Secondary sections | none |
| Plain-text | yes |

---

## Step 2.5: Design Direction (internal -- not shown to user)

From Step 2 answers, determine:
- Visual character (from question 13, or inferred from tone + format if skipped)
- ONE unmissable element -- identify before Step 3
- Template path (see Step 5)

Character defaults if question 13 skipped:
- Educational / formal tone: Editorial
- Metrics-heavy content (stats, benchmarks, reports): Technical/data-forward
- Product launches, events, campaigns: Bold/campaign

Never ask the user for design direction separately -- derive it from their answers.

---

## Step 3: Structure Design

Read `references/html-email-guide.md` for layout rules before choosing sections.

Based on topic + audience + CTA + secondary sections requested, select sections from this library:

| Section | Include when |
|---|---|
| header | Always -- logo placeholder + issue number or date |
| hero | Always -- big headline + 1-2 sentence hook |
| intro | Conversational or educational tone -- short personal note |
| main-content | Primary article or insight (text-heavy) |
| stat-callout | There is a compelling stat, quote, or data point |
| secondary-section | Secondary CTA was requested |
| product-cta | Brand context present and soft product plug fits |
| sponsor-block | Sponsor section was requested |
| quick-links | Curated links section was requested |
| footer | Always -- unsubscribe link + company name |

Output the chosen structure as a numbered list with one-line purpose per section:

```
Proposed structure:
1. Header -- logo + Issue #1 / [date]
2. Hero -- headline + hook paragraph
3. Intro -- short personal framing
4. Main Content -- [topic] breakdown
5. Stat Callout -- key data point from the story
6. CTA -- [cta text]
7. Footer -- unsubscribe + company

Does this structure work, or should I adjust any sections?
```

Wait for confirmation before Step 4.

---

## Step 4: Content Draft

Write copy for each section in sequence. No HTML yet -- clean prose only.

**Rules per section:**
- **Header**: Issue number + date. No copy needed.
- **Hero headline**: 8 words max, outcome-focused, no starting with "I/We/Our"
- **Hero hook**: 1-2 sentences, problem or curiosity gap, pulls reader in
- **Intro**: 2-3 sentences, personal or contextual, not corporate-speak, contractions OK
- **Main content**: 250-400 words, scannable -- use **bold phrases** for key points, short paragraphs (1-3 lines), no walls of text, no bullet overload
- **Stat callout**: One stat or quote, 20 words max, punchy
- **Product CTA**: 2-3 sentences, value-forward, not "Check out our product" -- tell them what changes for them
- **CTA button text**: 3-5 words, action verb + benefit ("Read the full breakdown", "Save my seat", "Get the guide")
- **Footer**: Unsubscribe link placeholder + company name

Read `references/subject-line-formulas.md` then write 3 subject line options (if subject line not provided by user):
- Option A: Curiosity gap formula
- Option B: Direct benefit formula
- Option C: Number/list formula

Do not use em dashes. Do not use: "powerful", "seamless", "game-changing", "leverage", "innovative", "unlock", "transform", "elevate", "cutting-edge", "robust".

---

## Step 5: HTML Generation

Read `references/design-system.md` and `references/html-email-guide.md` before generating HTML.

**Template or custom -- decide based on Step 2 answers:**

**Use `templates/dark-newsletter.html` as base when ALL of:**
- background = dark (or not specified)
- display font = Instrument Serif (or not specified)
- no custom background hex provided

**Use `templates/light-newsletter.html` as base when ALL of:**
- background = light OR tone = formal
- display font = Instrument Serif (or not specified)
- no custom background hex provided

**Generate custom HTML from scratch when ANY of:**
- custom background hex provided (not dark, not white)
- display font = modern sans or system fonts only
- combination of answers produces a design neither template serves

For custom generation: use `references/design-system.md` Custom Generation Guide as the full token spec. Apply user's background/font/button/accent choices throughout.

**Then (for template path):**
1. Select only the sections needed from the template (based on Step 3 structure)
2. Fill in all `[PLACEHOLDER]` values with content from Step 4
3. Apply brand color substitution (see below)
4. Verify all `[UNSUBSCRIBE_URL]` placeholders are still present (platform tuning happens in Step 6)

**Brand color substitution rules:**

If `brand_color` is provided:
- Replace brand strip `bgcolor` (`#D8F90A` in the `height:2px` row) with brand_color
- Replace stat callout left border color with brand_color
- Replace category label color with brand_color
- If brand_color luminance is high (yellows, greens, oranges -- most neons): replace step badge `#D8F90A` with brand_color too
- If brand_color luminance is low (dark navy, forest, charcoal): keep step badges and CTA button as `#D8F90A`, only use brand_color for strip + stat border

If `brand_color` is NOT provided: keep all `#D8F90A` values as-is.

**Content substitution rules (from Step 2 answers):**
- If `company_name` provided: replace all `[YOUR BRAND]` and `[COMPANY NAME]` placeholders
- If `city_country` provided: replace `[CITY, COUNTRY]` placeholder
- If `tagline` provided: add as subtitle line in footer after company name
- If `cta_url` provided: replace all `[CTA_URL]` placeholders with actual URL
- If `personalization = first_name`: add platform-appropriate first name variable to hero greeting -- e.g. `Hey %%first_name%%,` on Beehiiv, `Hey {{first_name}},` on Loops, `Hey *|FNAME|*,` on Mailchimp
- If `personalization = first_name + company`: add both variables where contextually appropriate

**Brand color visual tension check (on dark email):**

Does the brand color visually pop on `#111111`? Test mentally: would it be visible as a 2px strip?
- High-saturation colors (purples, blues, teals, pinks, yellows, oranges, greens): YES -- use for strip + stat border + category label
- Low-saturation / near-neutral (warm greys, beige, off-white): strip only; category label reverts to `#555555`
- Near-black (very dark navy, forest, charcoal below ~`#2A2A2A`): skip brand_color for ALL accent uses, fall back to `#D8F90A` for every element

**Accent discipline rule:** brand_color appears in AT MOST 3 places: brand strip, stat border, category label. Never in body copy, headlines, button backgrounds, or section backgrounds. Over-branding kills the premium feel.

**CTA button text color:**
- On `#D8F90A` button background: always use `#0A0A0A` text (it's a light color)
- On `#111111` button background (inside yellow callout card): always use `#F2F2F2` text
- On brand_color button: use `#0A0A0A` if brand is light, `#FFFFFF` if brand is dark

**Required on every `<td>` with a background color:**
Both the `bgcolor=` HTML attribute AND the inline `background-color:` style. Example:
```html
<td bgcolor="#D8F90A" style="background-color:#D8F90A;">
```
The attribute handles Outlook. The style handles everything else. Never use just one.

**Design excellence (frontend-design principles, email-adapted):**

Email's table constraints don't limit design ambition. Push within them:

- **Typography to its extreme**: 4-5 word headlines = 60px, `-0.04em` tracking. 6-7 word headlines = 56px, `-0.03em`. 8 words = 48px. Never size down for safety -- the headline is a poster, not a label. Instrument Serif italic on stat quotes adds literary weight no other element can match.

- **Density contrast as craft signal**: Hero = maximum open space (64px top). Body paragraphs = tight and dense. CTA callout card = maximum open space again (64px). Open → tight → open is the rhythm that reads as intentional design, not template output.

- **Background depth via section alternation** (all email-safe):
  - Header: `#0A0A0A`
  - Hero: `#111111`
  - Stat callout outer: `#111111`, inner elevated card: `#1A1A1A`
  - Body paragraphs: `#161616` (subtle elevation creates depth without color)
  - Step cards: `#111111` (contrast with body)
  - CTA callout card: `#D8F90A` (the ONLY bright element -- never dilute)
  - Footer: `#080808`

- **Accent scarcity = luxury**: One yellow callout card in a sea of dark reads premium. Yellow appearing in six places reads cheap. The CTA card's power comes entirely from being the single bright element in a dark email.

- **Unforgettable test**: Before saving, state in one sentence what a reader would describe to a colleague 3 hours later. If it's vague ("it was dark and clean") -- the visual anchor isn't strong enough. Make it specific ("the yellow card with the big serif headline").

- **Stat callout as editorial pull quote**: 4px left border (not 3px). 26px italic Instrument Serif on the quote text. 32px inner padding. This is the closest an email gets to a magazine pull quote. Treat it like one.

---

## Step 6: Platform Tuning

Read `references/platform-compat.md` and apply platform-specific adjustments:

| Platform | Action |
|---|---|
| Loops | Replace `[UNSUBSCRIBE_URL]` with `{{unsubscribe_url}}`. Replace `[FIRST_NAME]` refs with `{{first_name}}` |
| Mailchimp | Replace `[UNSUBSCRIBE_URL]` with `*\|UNSUB\|*`. Add `mc:edit="[section-name]"` to editable `<td>` blocks |
| Beehiiv | Replace `[UNSUBSCRIBE_URL]` with `%%unsubscribe_url%%`. Replace `[FIRST_NAME]` with `%%first_name%%` |
| Resend | Replace `[UNSUBSCRIBE_URL]` with `{unsubscribeUrl}`. Note: React Email `.tsx` output available on request |
| Generic/Other | Keep `[UNSUBSCRIBE_URL]` as placeholder with comment: `<!-- Replace with your unsubscribe link -->` |

---

## Step 7: Self-QA

Check the generated HTML before output. Fix every issue found -- do not skip.

**Rendering checks:**
- [ ] All styles inline -- no `<style>` blocks, no `class=` attributes anywhere
- [ ] All `<table>` have `cellpadding="0" cellspacing="0" border="0"`
- [ ] Images (if any) have `alt=""`, `border="0"`, `display:block` in style
- [ ] Max-width 600px enforced on container table
- [ ] CTA button uses `<table>` + `<td>` structure with `bgcolor=` attribute, not just `<a>` with `display:block`
- [ ] No `flexbox`, `grid`, `position:`, `float:`, CSS variables (`--var`), `min-height`, `max-height` in any inline style
- [ ] `border-radius` on `<td>` only -- not on `<table>` or `<a>` (Outlook renders `<td>` radius)
- [ ] Footer has unsubscribe link with platform-correct variable

**Content checks:**
- [ ] Hero headline is 8 words or fewer
- [ ] CTA button text is 3-5 words
- [ ] No em dashes (-- is fine, not --)
- [ ] No banned words: "powerful", "seamless", "game-changing", "leverage", "innovative", "unlock", "transform", "elevate", "cutting-edge", "robust"
- [ ] Plain-text version strips all HTML cleanly (if requested)

**Design quality checks:**
- [ ] ONE unmissable element from Step 2.5 is visually dominant -- not buried between equal-weight sections
- [ ] Typography hierarchy clear: H1 >> H2 >> body -- size contrast at least 2:1 between each level
- [ ] All spacing values from valid rhythm only: 8 / 16 / 20 / 24 / 32 / 40 / 52 / 64px -- no arbitrary values (18px, 22px, 30px, 45px, etc.)
- [ ] Brand color appears in 3 or fewer places -- count instances; if more, remove from lowest-priority element
- [ ] No email slop patterns -- check against the slop list in `references/design-system.md`

If any check fails: fix inline, then re-run the checklist mentally.

---

## Step 8: Subject Line Presentation

If 3 subject line options were generated, present them with a recommendation:

```
**Subject Line Options**

A. [subject] -- [formula used, best for what audience/context]
B. [subject] -- [formula used]
C. [subject] -- [formula used]

Recommendation: [A/B/C] -- [one sentence reason based on audience and tone]
```

If user provided their own subject line, skip this step.

---

## Step 9: Save Files + Present Summary

**Save the HTML to a file first -- do not dump it in the chat.**

```bash
mkdir -p docs/newsletters
```

Write the full HTML to:
`docs/newsletters/[topic-slug]-[YYYY-MM-DD].html`

Where `[topic-slug]` is the topic lowercased with spaces replaced by hyphens (e.g. "AI B2B Sales" → `ai-b2b-sales`).

If a plain-text version was requested, also write it to:
`docs/newsletters/[topic-slug]-[YYYY-MM-DD].txt`

**Then present this summary in the chat (no HTML code fence):**

```
## Newsletter: [topic slug]
Date: [today's date] | Platform: [platform] | Tone: [tone]

Saved to: docs/newsletters/[topic-slug]-[YYYY-MM-DD].html

---

### Subject Lines
A. [subject A] -- [formula]
B. [subject B] -- [formula]
C. [subject C] -- [formula]
Recommended: [letter] -- [one-sentence reason]

---

### Send Checklist
- [ ] Replace [CTA_URL] with your actual link
- [ ] Replace [COMPANY NAME] and [CITY, COUNTRY] in footer
- [ ] Replace [YOUR BRAND] in header with your brand name (or swap in a logo image)
- [ ] Verify unsubscribe variable works in [platform]
- [ ] Send a test email to yourself before launching
```

Do not print the HTML in the chat. The file path tells the user where to find it.

---

## Section Reference

| Section | Purpose |
|---|---|
| header | Logo + issue number or date |
| hero | Big headline + 1-2 sentence hook |
| intro | Short personal note or context |
| main-content | Primary article or insight (text-heavy) |
| image-block | Full-width image + caption |
| stat-callout | Highlighted stat or quote in a box |
| secondary-section | Second story or feature |
| product-cta | Soft product plug or feature highlight |
| sponsor-block | Sponsored content (clearly labeled) |
| quick-links | Curated links section (3-5 items) |
| footer | Unsubscribe link, company info, legal |

## Output Formats (on request)

- **Standard HTML** (default): inline-styled, table-based, works everywhere
- **React Email**: `.tsx` component output -- request explicitly, good for Resend + dev teams
- **Plain text**: stripped fallback always included unless user opts out

---

## Supporting file: evals/evals.json

```json
{
  "skill_name": "email-newsletter",
  "evals": [
    {
      "id": 1,
      "prompt": "Write a newsletter about how AI is changing B2B sales. Audience: VPs of Sales at 100-500 person SaaS companies. CTA: join our upcoming webinar. Tone: direct and confident. Platform: Beehiiv. Brand color: #856FE6.",
      "expected_output": "Topic + audience + CTA present -- skips Step 1. Asks all 19 questions in Step 2 grouped into Content / Brand / Design / Platform categories, since company name, CTA URL, city, display font, button style, personalization, and issue context were not provided. After user answers: reads templates/dark-newsletter.html as base (dark background default, Instrument Serif default, no custom hex). Design direction is derived internally (not stated to user) -- technical+data-forward from the data-heavy content. Hero headline 8 words or fewer in Instrument Serif 56px with Georgia fallback. Brand strip uses #856FE6. Stat callout has border-left:4px solid #856FE6. Step badges stay #D8F90A (purple luminance too low). Category label color #856FE6. Accent discipline: #856FE6 appears in exactly 3 places. CTA pill button uses #D8F90A with #0A0A0A text. If company_name provided in answers: replaces [YOUR BRAND] and [COMPANY NAME]. If cta_url provided: replaces [CTA_URL]. Footer uses %%unsubscribe_url%% (Beehiiv). HTML saved to docs/newsletters/ai-b2b-sales-[date].html. Chat shows only subject lines + send checklist -- no HTML code fence.",
      "files": []
    },
    {
      "id": 2,
      "prompt": "Draft an email newsletter for our summer product launch. Audience: existing customers aged 25-40 who bought last year. CTA: shop the collection. Tone: playful. Platform: Mailchimp.",
      "expected_output": "Topic + audience + CTA present -- skips Step 1. Asks all 19 questions in Step 2 (company name, brand color, CTA URL, city, display font, button style, background, visual style, personalization, etc. not provided). After answers: uses templates/dark-newsletter.html (playful tone = dark, not formal). Design direction internal -- bold+campaign for a product launch. Hero headline energetic, 8 words or fewer, no I/We/Our. CTA pill button in hero uses #D8F90A. Yellow CTA callout card present as visual anchor. If company_name and cta_url provided: replace placeholders. Footer uses *|UNSUB|* (Mailchimp). mc:edit attributes added to editable <td> sections. No em dashes. No banned words. 3 subject lines generated. HTML saved to docs/newsletters/summer-product-launch-[date].html. No HTML in chat.",
      "files": []
    },
    {
      "id": 3,
      "prompt": "Write a newsletter.",
      "expected_output": "Topic, audience, and CTA are all missing. Does NOT open any template or generate any HTML. Asks for all three in Step 1 exactly: 'To get started, I need three things: 1. Topic 2. Audience 3. Primary CTA'. Stops and waits. After user provides all three, proceeds to Step 2 and asks all 19 questions in one message grouped into Content / Brand / Design / Platform categories.",
      "files": []
    },
    {
      "id": 4,
      "prompt": "Write a monthly developer digest newsletter. Topic: notable open source releases this month. Audience: senior engineers and engineering managers. CTA: read the full digest. Platform: Resend. Tone: educational.",
      "expected_output": "Topic + audience + CTA present -- skips Step 1. Asks all 19 questions in Step 2 (company name, brand color, CTA URL, city, background, display font, button style, visual style, personalization, issue context, length not provided). After answers: reads templates/dark-newsletter.html (dark default, Instrument Serif default). Design direction internal -- technical+data-forward for developer digest. Step cards section included for numbered releases. Hero headline uses Instrument Serif 56px with Georgia fallback. If company_name provided: replaces placeholders. Resend unsubscribe variable {unsubscribeUrl} in footer. Note in send checklist that React Email .tsx output available on request for Resend. No HTML in chat -- saved to docs/newsletters/developer-digest-[date].html. 3 subject lines generated.",
      "files": []
    },
    {
      "id": 5,
      "prompt": "Write a formal investor update newsletter. Audience: our seed-round investors. CTA: read the full update. Tone: formal. Platform: Loops. Brand color: #1A3A5C.",
      "expected_output": "Topic + audience + CTA present -- skips Step 1. Asks all 19 questions in Step 2 (company name, CTA URL, city, background, display font, button style, visual style, personalization, length, issue context not provided). After answers: reads templates/light-newsletter.html (formal tone triggers light template). Design direction internal -- editorial for formal investor update. Brand color #1A3A5C is dark (low luminance, near-black) -- used for header strip and stat border only, NOT for step badges or CTA button. CTA button uses #111111 on light template. If company_name provided: replaces [YOUR BRAND] and [COMPANY NAME]. Footer uses {{unsubscribe_url}} (Loops syntax). Hero headline in Instrument Serif 48-56px, Georgia fallback. No step cards (formal tone, investor update doesn't suit numbered cards). Saved to docs/newsletters/investor-update-[date].html.",
      "files": []
    }
  ]
}
```

---

## Supporting file: README.md

# email-newsletter

Draft and design a complete HTML email newsletter from a topic or content brief. Output is paste-ready for Loops, Mailchimp, Beehiiv, Resend, or any standard email platform.

<!-- OPENDIRECTORY_INSTALL_START -->
## Install

### Option A: npx CLI (Recommended)

No global install. Always runs the latest version.

```bash
npx "@opendirectory.dev/skills" install email-newsletter --target claude
```

### Option B: skills.sh

```bash
npx skills add Varnan-Tech/opendirectory --skill email-newsletter
```

Requires Node.js. Add `--global` to install to `~/.claude/skills/` instead of the current project.

### Option C: Claude Desktop App

<video src="https://github.com/user-attachments/assets/cea8b565-2002-4a87-8857-d902bfcfdc1c" controls width="100%"></video>

**Step 1: Download the skill from GitHub**

1. Copy the URL of this specific skill folder from your browser's address bar.
2. Go to [download-directory.github.io](https://download-directory.github.io/).
3. Paste the URL and click **Enter** to download.

**Step 2: Install in Claude**

1. Open your **Claude desktop app**.
2. Go to the sidebar on the left side and click on the **Customize** section.
3. Click on the **Skills** tab, then click on the **+** button to create a new skill.
4. Choose **Upload a skill**, then drag and drop the `.zip` file or extracted folder.

> **Note:** For some skills, the `SKILL.md` file might be located inside a subfolder. Always upload the specific folder that contains the `SKILL.md` file.

### Option D: Claude Code Native

Run these commands inside Claude Code:

```bash
/plugin marketplace add Varnan-Tech/opendirectory
/plugin install opendirectory-gtm-skills@opendirectory-marketplace
```

### Option E: Manus AI

<video src="https://github.com/user-attachments/assets/17cbee2a-9e17-4bd4-ac46-68e0e92ffab4" controls width="100%"></video>

[**Install in Manus AI**](https://manus.im/import-skills?githubUrl=https%3A%2F%2Fgithub.com%2FVarnan-Tech%2Fopendirectory%2Ftree%2Fmain%2Fskills%2Femail-newsletter&utm_source=opendirectory)

Manus AI users can import a skill directly from its OpenDirectory skill page. This is the easiest path when you want Manus to pull the skill from GitHub for you.

1. Open the skill you want from the [opendirectory homepage](https://opendirectory.dev).
2. In the install panel, select the **Manus AI** tab.
3. Click **Install in Manus AI** - this opens Manus with the skill GitHub URL already attached.
4. Confirm the import inside Manus AI.

> If your Manus workspace prefers file uploads, use the **Download** tab instead and upload the downloaded `.skill.zip` file inside Manus.
<!-- OPENDIRECTORY_INSTALL_END -->


## What it does

- Asks the 19 questions that actually determine your newsletter layout
- Writes all sections: hero, intro, main content, stat callout, CTA, footer
- Generates table-based HTML with inline styles -- compatible with every major email client
- Tunes variable syntax per platform (Loops, Mailchimp, Beehiiv, Resend)
- Produces 3 subject line options using proven formulas
- Includes a plain-text fallback for deliverability

## Example

> "Write a newsletter about how AI is changing B2B sales. Audience: VPs of Sales at 100-500 person SaaS companies. CTA: join our upcoming webinar. Tone: direct. Platform: Beehiiv."

Output: full HTML email with hero headline, 3-section body, stat callout, CTA block, and footer -- plus 3 subject line options and a plain-text version, tuned for Beehiiv.

## Supported platforms

| Platform | Notes |
|---|---|
| Loops | `{{unsubscribe_url}}` syntax. Paste into custom HTML editor |
| Mailchimp | `*\|UNSUB\|*` syntax. Use "Code your own" template. Includes `mc:edit` regions |
| Beehiiv | `%%unsubscribe_url%%` syntax. Works with custom HTML block |
| Resend | `{unsubscribeUrl}` syntax. React Email `.tsx` output available on request |
| Generic | `[UNSUBSCRIBE_URL]` placeholder -- replace before sending |

## Output formats

- **Standard HTML** (default): inline-styled, table-based, 600px max-width
- **Plain text**: always included unless you opt out
- **React Email** (on request): `.tsx` component output for Resend / dev teams

## Parameters

| Param | Required | Notes |
|---|---|---|
| topic | Yes | What the newsletter is about |
| audience | Yes | Who is reading |
| cta | Yes | Primary action you want readers to take |
| company_name | No | Brand name for header and footer |
| tagline | No | One-line description for footer |
| city_country | No | Footer location (e.g. "San Francisco, US") |
| cta_url | No | Actual link for CTA button -- placeholder used if omitted |
| brand_color | No | Hex code -- used for strip, stat border, category label |
| background | No | dark / light / custom hex (default: dark) |
| display_font | No | editorial serif / modern sans / system fonts (default: Instrument Serif) |
| button_style | No | pill / softly rounded / sharp (default: pill) |
| visual_style | No | editorial / technical+data / warm+founder / bold+campaign |
| tone | No | educational / conversational / bold+direct / formal / playful |
| platform | No | loops / mailchimp / beehiiv / resend (default: generic) |
| personalization | No | none / first name / first name + company (default: none) |
| length | No | brief (300w) / standard (500-700w) / deep dive (800w+) |
| format | No | editorial article / numbered breakdown / personal story / data report |
| subject_line | No | If omitted, 3 options are suggested |
| secondary_sections | No | sponsor block / product callout / event / quick links |

## No API keys required

Pure AI skill. No external services, no scraping, no dependencies to install.

## Design principles

- Max width 600px (email client standard)
- Inline styles only -- no external CSS, email clients strip it
- Table-based layout for Outlook compatibility
- Georgia serif for hero headlines, Arial/system font for body
- CTA buttons use the table+td VML-compatible structure
- All images include alt text
- Dark mode aware where platform supports it

---

## Supporting file: references/design-system.md

# Email Design System

Premium dark-first email design. Every output should look considered and editorial -- not a template dump.

---

## Design Philosophy

Dark emails signal quality. SaaS founders, VPs, and operators live in dark IDEs, dark Notion, dark Slack. A dark newsletter matches their environment and stands out in an inbox of white-bg blasts. The goal is visual character: strong typographic hierarchy, editorial spacing, a single accent color that does real work.

Default: dark. Override: `tone=light` for consumer brands, formal industries, or user preference.

---

## Visual Anchor Rule

Every email must have ONE element with significantly higher visual weight than everything else. This is the thing that makes the email memorable.

**What qualifies as a visual anchor:**
- CTA callout card (`#D8F90A` full-width rounded card) -- strongest option, highest contrast on dark
- Stat callout with a striking number in 24px Instrument Serif italic
- Hero headline in 52px+ Instrument Serif (when the headline IS the story)
- Step cards section (when the numbered content is the primary value)

**What doesn't qualify:** A regular paragraph, a hero with a small button, generic unformatted text.

**Rule:** If you cannot identify the anchor before generating HTML, the structure is wrong. Add or promote the CTA callout card. An email without a visual anchor is a wall of text with branding.

---

## Color Tokens

### Dark (default)

```
Outer bg:         #050505
Container bg:     #111111
Header bg:        #0A0A0A
Alt section bg:   #161616   (subtle alternation for visual rhythm)
Elevated card bg: #1A1A1A   (stat callout, footer)
Footer bg:        #080808

Text primary:     #F2F2F2
Text body:        #CCCCCC
Text muted:       #888888
Text meta:        #555555

CTA primary bg:   #D8F90A   (yellow-green — REQUIRES #0A0A0A dark text)
CTA secondary bg: #FFFFFF   (white — #0A0A0A text)
CTA dark bg:      #111111   (inside yellow callout card — #F2F2F2 text)

Step badge bg:    #D8F90A   (numbered card badge)
Step badge text:  #0A0A0A

Divider:          #2A2A2A
Card border:      #222222
Brand strip:      [BRAND_COLOR] (2px line between header and hero)
```

### Light (fallback when tone=light)

```
Outer bg:         #F0F0EE
Container bg:     #FFFFFF
Header bg:        #1A1A1A   (always dark — anchors the email)
Alt section bg:   #F8F8F6
Footer bg:        #F8F8F6

Text primary:     #111111
Text body:        #444444
Text muted:       #888888

CTA primary bg:   #111111   (dark button on white)
Callout card bg:  #111111   (dark card on white email — reversal effect)

Divider:          #EEEEEE
```

---

## Brand Color Rules

When `brand_color` is provided:
- Use it for: brand strip (2px line), stat callout left border, category label text, step badge bg (if dark and readable), light-mode CTA button
- Do NOT use it for: body text, large bg sections (unless very dark and intentional)

**Luminance check for CTA button text:**
- Light brand color (luminance > 0.5 — yellows, greens, oranges, light purples): use `#0A0A0A` text
- Dark brand color (luminance < 0.4 -- navy, forest, dark purple): use `#FFFFFF` text

**Brand color on dark email:**
- If brand color is `#D8F90A` or similar bright/neon: perfect, use directly for CTA + badge
- If brand color is dark (e.g. `#1A3A5C`): do NOT use for CTA button -- use `#FFFFFF` CTA instead, use brand_color only for the 2px strip and stat border
- If brand color is `#856FE6` (purple): works on dark bg, use for strip + stat border + step badges; CTA stays `#D8F90A` for contrast

**Substitution in template:**
Replace every instance of `#D8F90A` in the dark template with brand_color IF brand_color is light enough (luminance > 0.4). Otherwise keep `#D8F90A` as CTA color and use brand_color only for accent elements.

---

## Typography

### Display (H1, H2)

**Font:** Instrument Serif, Georgia fallback

```css
font-family: 'Instrument Serif', Georgia, 'Times New Roman', serif;
font-weight: 400;   /* Instrument Serif is a display weight at 400 */
letter-spacing: -0.02em;
```

**Why Instrument Serif:** Elegant editorial serif. Renders beautifully at 40-60px. Georgia fallback is close enough in character -- editorial, serif, strong. The pairing with Inter body creates the same tension as print magazine design.

**Loading:**
```html
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
```

Gmail strips this `<link>` tag. Georgia renders instead. Both look good. Apple Mail, Yahoo, Outlook 365 keep the Google Font.

**H1 (hero headline):**
```
font-size: 60px  (4-5 words — push to poster scale)
font-size: 56px  (6-7 words — editorial authority)
font-size: 48px  (8 words)
font-size: 32px  (mobile fallback via @media)
line-height: 1.02
letter-spacing: -0.04em at 60px, -0.03em at 56px, -0.02em at 48px
```

Never size a headline down for safety. A bigger headline with tight tracking reads authoritative; a smaller headline reads like a template.

**H2 (section headline):**
```
font-size: 40px  (normal)
font-size: 52px  (CTA callout card -- bigger impact)
line-height: 1.05
```

### Body

**Font:** Inter, Arial fallback

```css
font-family: Inter, Arial, Helvetica, sans-serif;
```

**Body text (dark):**
```
font-size: 16-17px
line-height: 1.65-1.7
color: #CCCCCC
```

**Bold callouts:**
```html
<strong style="color:#F2F2F2;font-weight:600;">Key phrase</strong>
```
Use for the opening 3-4 words of each key idea.

**Meta / label text:**
```
font-size: 11px
font-weight: 600
letter-spacing: 0.14-0.22em
text-transform: uppercase
color: [BRAND_COLOR] or #555555
```

### Typography Nuances

**Italic variant for editorial emphasis:**
Instrument Serif has an italic variant (included in the Google Fonts URL). Use `font-style:italic` for:
- Stat callout quote text -- adds literary weight to a striking number or phrase
- Hero headline when tone is warm/founder
- Never on body copy -- italic at 16px is hard to read on dark backgrounds

```html
<p style="font-family:'Instrument Serif',Georgia,'Times New Roman',serif;font-style:italic;font-size:24px;font-weight:400;line-height:1.3;color:#F2F2F2;">"[STAT OR QUOTE]"</p>
```

**Letter-spacing rules:**
- Very large display (52px+): `-0.03em` (tighter = more editorial authority)
- Section headlines (38-40px): `-0.02em`
- Category label (11px uppercase): `0.22em` minimum, up to `0.30em` for wider/premium feel
- Body Inter: `0` -- never add tracking to body text

**Weight contrast rule:**
`'Instrument Serif' 400` + `Inter 700` (bold callouts) = correct pairing.
Never use Instrument Serif bold -- it's a display font; 400 is its designed weight.
Body Inter on dark: color `#CCCCCC` (not `#888888` -- that's muted/meta only).

---

## Spacing Rhythm

| Location | Padding |
|---|---|
| Section (standard) | 40px top/bottom, 40px left/right |
| Hero section | 64px top, 56px bottom, 40px sides |
| CTA callout card | 52px top/bottom, 40px sides |
| Footer | 44px top, 52px bottom, 40px sides |
| Between body paragraphs | 20px margin-bottom |
| After H2 before content | 24-32px padding |
| Step card gap | 20px margin-bottom per card |
| Container max-width | 600px |

Mobile (max-width 600px): reduce side padding to 24px via @media.

**Valid spacing values (rhythm scale):** 8 / 16 / 20 / 24 / 32 / 40 / 52 / 64px.
Never use arbitrary values like 18px, 22px, 30px, 45px. They break visual rhythm and signal template output.

---

## Section Patterns

### Header
Dark `#0A0A0A` bg always. Brand name in Instrument Serif left. Issue + date in small Inter uppercase right. Followed immediately by a 2px brand color strip.

```html
<tr>
  <td bgcolor="#0A0A0A" style="background-color:#0A0A0A;padding:20px 40px;">
    <table width="100%" cellpadding="0" cellspacing="0" border="0">
      <tr>
        <td style="font-family:'Instrument Serif',Georgia,serif;font-size:20px;font-weight:400;color:#F2F2F2;letter-spacing:-0.01em;">[BRAND NAME]</td>
        <td align="right" style="font-family:Inter,Arial,sans-serif;font-size:11px;font-weight:500;color:#555555;letter-spacing:0.14em;text-transform:uppercase;white-space:nowrap;">Issue #[N] &nbsp;|&nbsp; [DATE]</td>
      </tr>
    </table>
  </td>
</tr>
<tr>
  <td bgcolor="#D8F90A" style="background-color:#D8F90A;height:2px;font-size:1px;line-height:1px;">&nbsp;</td>
</tr>
```

### Hero
52px Instrument Serif headline. Category label above in brand color uppercase. Inter hook paragraph below. Pill CTA button (border-radius:100px).

H1 word count → font size:
- 5 words or fewer: 56px
- 6-7 words: 52px
- 8 words: 44px

CTA pill button shape (border-radius:100px) is the hero CTA. Rectangular button (border-radius:8px) is used in secondary CTA sections.

### Divider
Centered 96px rule. `#2A2A2A` on dark, `#EEEEEE` on light. Adds visual rhythm between sections.

```html
<tr>
  <td bgcolor="#111111" style="background-color:#111111;padding:40px 40px 0;">
    <table width="96" cellpadding="0" cellspacing="0" border="0" style="margin:0 auto;">
      <tr>
        <td bgcolor="#2A2A2A" style="background-color:#2A2A2A;height:1px;font-size:1px;line-height:1px;">&nbsp;</td>
      </tr>
    </table>
  </td>
</tr>
```

### Stat Callout
`#1A1A1A` elevated card bg. 3px brand color left border. Instrument Serif quote at 24px. Attribution in small Inter.

The callout sits on `#111111` outer padding -- the slight elevation (#1A1A1A vs #111111) creates depth without needing a visible border.

### Numbered Step Cards
Badge: 28x28 `#D8F90A` square, `border-radius:6px`. Number in 11px Inter bold `#0A0A0A`. Text cell: 16px Inter `#E8E8E8`. Each step is its own `<table>` with `margin-bottom:20px`.

This pattern replaces bullet lists. It looks significantly better and draws the eye through sequential content.

### CTA Callout Card
The visual anchor. `#D8F90A` background, `border-radius:14px`, generous padding (52px). H2 in Instrument Serif at 40-52px, `color:#1A1A1A`. Dark `#111111` button inside.

The yellow card inverts the dark email's color relationship -- it's the one bright element, which makes it unmissable as the primary action.

### Footer
`#080808` bg (slightly different from container `#111111` -- creates visual separation). Brand name in Instrument Serif. Company info in small Inter. 96px divider rule. Unsubscribe links.

---

## Tone Variants

### dark (default)
- Container: `#111111`
- Hero bg: `#111111`
- Text: `#F2F2F2` / `#CCCCCC`
- CTA: `#D8F90A` pill button (dark text)
- Use for: SaaS, tech, founders, operators, B2B

### light (fallback)
- Container: `#FFFFFF`
- Header: stays dark `#1A1A1A` (anchors the email)
- Text: `#111111` / `#444444`
- CTA: `#111111` rectangular button (white text)
- Callout card: dark `#111111` card (inverted)
- Use for: consumer brands, formal B2B, healthcare, finance

Trigger light mode: user sets `tone=light` or `tone=formal` or specifies "white background".

---

## Email Client Behavior

| Client | Instrument Serif | Dark bg renders | `@media` |
|---|---|---|---|
| Gmail (web) | No -- falls back to Georgia | Yes | Yes |
| Gmail app (iOS/Android) | No | Yes | Partial |
| Apple Mail | Yes | Yes | Yes |
| Outlook 2019+ | Yes (via Google Fonts CDN) | Yes | No |
| Outlook 2016 | No | May invert colors | No |
| Yahoo Mail | Yes | Yes | Yes |

**Outlook 2016 dark inversion:** Outlook 2016 may invert dark backgrounds to white. Add `<!--[if mso]>` conditional to force dark bg for Outlook if needed. For modern SaaS audiences, Outlook 2016 represents < 5% of opens -- acceptable tradeoff.

---

## Email Slop Patterns to Avoid

These produce generic AI-looking output. Check the self-QA checklist against these before saving.

| Pattern | What it signals | Fix |
|---|---|---|
| White background + colored button | Safe, corporate, forgettable | Use dark template (default) |
| Centered hero text on gradient | Stock newsletter look | Left-aligned hero on `#111111` |
| All-Inter / all-Arial, no display font | No typographic character | Instrument Serif on H1 is non-negotiable |
| No visual anchor -- every section same weight | Wall of text with branding | Identify and elevate the anchor (CTA card, stat callout, or oversized hero) |
| Brand color on 4+ elements | Garish / over-branded | Max 3 accent uses: strip, stat border, category label |
| Bullet lists everywhere | Undesigned content dump | Step cards replace bullets; bold callouts open paragraphs |
| Generic CTA copy ("Click here", "Learn more") | AI filler | 3-5 word action + benefit ("Save My Seat", "Read the Full Breakdown") |
| Footer larger than 3 lines | Compliance dump, reader ignores | Brand name + company line + rule + unsubscribe link. That's it. |

---

## Custom Generation Guide

When template doesn't fit Step 2 answers, generate from scratch using these tokens.

### Background tokens

```
User says "dark":       outer #050505, container #111111, header #0A0A0A, footer #080808
User says "light":      outer #F0F0EE, container #FFFFFF, header #1A1A1A, footer #F8F8F6
User provides hex:      use provided hex for container, darken ~10% for header, lighten ~5% for alt sections
                        If hex is dark (<30% luminance): light text #F2F2F2
                        If hex is light (>70% luminance): dark text #111111
                        If hex is mid: test contrast ratio, pick text accordingly
```

### Font tokens

```
User says "editorial serif":  'Instrument Serif',Georgia,'Times New Roman',serif (display)
                               Inter,Arial,Helvetica,sans-serif (body)
User says "modern sans":       'DM Sans',Arial,Helvetica,sans-serif (display, load from Google Fonts)
                               Inter,Arial,Helvetica,sans-serif (body)
User says "system fonts":      -apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif (both)
```

### Button style tokens

```
User says "pill":            border-radius:100px
User says "softly rounded":  border-radius:10px
User says "sharp":           border-radius:0 (or 2px for sub-pixel rendering)
```

### Accent color tokens

```
User provides accent:     use for brand strip, CTA button, step badges, stat border
                          text on accent: #0A0A0A if luminance >0.4, #FFFFFF if luminance <0.4
User says "keep default": #D8F90A with #0A0A0A text
User says "minimal/none": #FFFFFF CTA on dark, #111111 CTA on light
```

---

## What NOT to Use

In inline styles, never:
- `display:flex` / `display:grid`
- `position:absolute/relative`
- `float:`
- CSS custom properties (`--var`)
- `min-height:` / `max-height:`
- `background-image:` (Outlook strips it)
- `border-radius` on `<table>` elements (use on `<td>` only)
- `rgba()` colors (use solid hex equivalents)
- `linear-gradient` (Outlook renders as solid block)

---

## Supporting file: references/html-email-guide.md

# HTML Email Guide

Rules for writing HTML that renders correctly in Gmail, Apple Mail, Outlook, Samsung Mail, and Yahoo Mail.

---

## The One Rule

**Inline styles only.** No `<style>` blocks, no `<link>` to external CSS, no CSS classes. Every element that needs styling gets `style=""` directly on the tag. Email clients strip `<style>` blocks (especially Gmail on Android) and ignore class-based rules entirely.

Exception: `@media` queries for mobile responsiveness can go in a `<head>` `<style>` block -- but always include inline fallbacks so the layout works without them.

---

## Layout: Table-Based Only

Use `<table>` for layout. Not `<div>`, not flexbox, not grid. Outlook renders HTML as if it's Microsoft Word, and Word does not understand modern CSS layout.

### Outer wrapper pattern

```html
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:#F4F4F4;">
  <tr><td align="center" style="padding:24px 16px;">

    <!-- 600px container -->
    <table width="600" cellpadding="0" cellspacing="0" border="0" style="max-width:600px;width:100%;background-color:#FFFFFF;">
      <!-- sections go here as <tr><td> blocks -->
    </table>

  </td></tr>
</table>
```

Always use both `width="600"` (HTML attribute) and `max-width:600px` (inline style). The attribute handles Outlook; the style handles everything else.

### Required table attributes

Every `<table>` needs all three:
```html
<table cellpadding="0" cellspacing="0" border="0">
```

Missing any of these adds default spacing or borders that break layout.

---

## Typography

**Font stack (always use system fonts with web-safe fallbacks):**

For sans-serif:
```css
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, Helvetica, sans-serif;
```

For serif (headlines only):
```css
font-family: Georgia, 'Times New Roman', Times, serif;
```

**Web fonts (optional, with caveats):**
- Declare in `<head>` `<style>` block using `@import` or `<link>`
- Always include a web-safe fallback -- Gmail strips web font declarations
- Never rely on a web font being rendered -- design so the fallback looks good

**Type scale:**
- H1 (hero): 28-36px, font-weight 700, line-height 1.2
- H2 (section headers): 20-24px, font-weight 600, line-height 1.3
- Body: 15-16px, line-height 1.6-1.7, color #333333 or #444444
- Small/meta: 12-13px, color #888888

**Always set:**
```css
font-size: [px];
line-height: [number];
color: [hex];
font-family: [stack];
```

On every text element. Do not rely on inheritance -- email clients do not inherit styles reliably.

---

## Images

Every image:
```html
<img src="[hosted-url]" alt="[descriptive text]" width="600" border="0" style="display:block;max-width:100%;border:0;">
```

Rules:
- `display:block` removes bottom gap (inline images add ~4px gap below)
- `border="0"` (HTML attribute) + `border:0` (inline style) -- need both for Outlook
- Always hosted URL -- base64 images are often blocked by spam filters
- `max-width:100%` for mobile responsiveness
- Always fill in `alt` -- many clients block images by default, alt text is what readers see first

For full-width hero images:
```html
<img src="[url]" alt="" width="600" border="0" style="display:block;max-width:100%;width:100%;height:auto;border:0;">
```

---

## CTA Buttons

**Never** use a simple `<a>` tag with `display:block` and background color for buttons. Outlook ignores `display:block` on `<a>` tags.

**Always** use the table+td structure:

```html
<table cellpadding="0" cellspacing="0" border="0">
  <tr>
    <td align="center" bgcolor="#1A1A1A" style="background-color:#1A1A1A;border-radius:6px;">
      <a href="[CTA_URL]" target="_blank" style="display:inline-block;padding:14px 32px;font-family:Arial,Helvetica,sans-serif;font-size:15px;font-weight:600;color:#FFFFFF;text-decoration:none;letter-spacing:0.01em;">Button Text Here</a>
    </td>
  </tr>
</table>
```

Notes:
- `bgcolor=` HTML attribute + `background-color:` inline style -- need both for Outlook
- `border-radius` on `<td>` -- Outlook ignores it on `<a>`
- `display:inline-block` on `<a>` is fine (it's not a layout block, just expands the click area)

---

## Colors and Backgrounds

Always use both the HTML attribute and inline style for backgrounds:

```html
<td bgcolor="#FFFFFF" style="background-color:#FFFFFF;">
```

Outlook uses `bgcolor` attribute; other clients use the inline style.

**Dark backgrounds:**
Use `bgcolor="#1A1A1A"` (safe dark) or `bgcolor="#000000"`. Avoid pure black text on very dark backgrounds -- use `#FFFFFF` or `#F0F0F0` for text on dark.

---

## Spacing

Use `padding` on `<td>` elements, not margins. `margin` on table cells behaves unpredictably across clients.

Standard section padding: `padding:40px 32px`
Content padding (narrower): `padding:24px 32px`
Header/footer padding: `padding:20px 32px`

For vertical spacing between elements, use empty `<tr><td style="height:16px;font-size:1px;line-height:1px;">&nbsp;</td></tr>` rows in Outlook-heavy sends. For most modern clients, `padding-bottom` on the previous `<td>` is enough.

---

## Mobile Responsiveness

Minimal media query approach (add to `<head>` style block):

```html
<style>
  @media only screen and (max-width: 600px) {
    .container { width: 100% !important; max-width: 100% !important; }
    .stack { display: block !important; width: 100% !important; }
    .hide-mobile { display: none !important; }
    h1 { font-size: 26px !important; }
    td { padding-left: 20px !important; padding-right: 20px !important; }
  }
</style>
```

Always set inline fallbacks -- treat media queries as an enhancement, not a requirement.

---

## Dark Mode

Some clients (Apple Mail, Gmail Android) support dark mode. Add to `<head>` style block:

```html
<style>
  @media (prefers-color-scheme: dark) {
    .dark-bg { background-color: #1A1A1A !important; }
    .dark-text { color: #F0F0F0 !important; }
  }
</style>
```

Most clients will ignore this. It is a progressive enhancement. Do not rely on it for readability -- ensure the light mode version is always readable.

---

## What to Avoid

Never use in inline styles:
- `display: flex` / `display: grid` -- not supported in Outlook
- `position: absolute/relative/fixed` -- breaks table layout
- `float:` -- unreliable across clients
- CSS custom properties (`--variable`) -- Outlook does not support
- `min-height:` / `max-height:` -- Outlook ignores
- `background-image:` CSS property -- Outlook strips it (use VML instead for complex cases, or avoid background images)
- `border-radius` on `<table>` -- use on `<td>` only

---

## Outlook VML (advanced, optional)

For solid-color background sections in Outlook, the `bgcolor` attribute is enough. For background images in Outlook specifically, use VML conditionals:

```html
<!--[if gte mso 9]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="width:600px;height:200px;">
  <v:fill type="tile" src="[image-url]" color="#1A1A1A"/>
  <v:textbox inset="0,0,0,0">
<![endif]-->
  <!-- content here -->
<!--[if gte mso 9]>
  </v:textbox>
</v:rect>
<![endif]-->
```

Use this only when background images are critical to the design.

---

## Pre-Send QA Checklist

- [ ] All styles inline -- no `<style>` blocks (except optional `<head>` media queries)
- [ ] All `<table>` have `cellpadding="0" cellspacing="0" border="0"`
- [ ] Images have `alt`, `border="0"`, `display:block`
- [ ] CTA button uses table+td with `bgcolor=` attribute
- [ ] Max-width 600px enforced on container
- [ ] Footer has unsubscribe link
- [ ] No `flexbox`, `grid`, `position`, `float`, CSS variables in inline styles
- [ ] Test in: Gmail web, Gmail app (iOS/Android), Apple Mail, Outlook 2016+

---

## Supporting file: references/platform-compat.md

# Platform Compatibility

Per-platform quirks, variable syntax, and paste instructions.

---

## Loops

**Variable syntax:** Handlebars `{{ }}`

| Placeholder | Loops variable |
|---|---|
| `[UNSUBSCRIBE_URL]` | `{{unsubscribe_url}}` |
| `[FIRST_NAME]` | `{{first_name}}` |
| `[EMAIL]` | `{{email}}` |

**How to use:**
- Open Loops dashboard > New Email > Custom HTML
- Paste the full HTML directly into the custom HTML editor
- Loops supports most standard email HTML including table layouts

**Notes:**
- Loops strips some `<head>` content -- the email still renders correctly
- Test with a preview send before publishing to subscribers

---

## Mailchimp

**Variable syntax:** Merge tags `*| |*`

| Placeholder | Mailchimp merge tag |
|---|---|
| `[UNSUBSCRIBE_URL]` | `*\|UNSUB\|*` |
| `[FIRST_NAME]` | `*\|FNAME\|*` |
| `[EMAIL]` | `*\|EMAIL\|*` |
| `[COMPANY NAME]` | `*\|COMPANY\|*` (if merge field exists) |

**How to use:**
- Create Campaign > Email > Code your own
- Paste HTML into the code editor

**Additional: mc:edit regions**
Mailchimp lets editors modify sections in their visual builder if you add `mc:edit` attributes:

```html
<td mc:edit="main-content" style="padding:24px 32px;">
  <!-- editable content here -->
</td>
```

Add `mc:edit="[section-name]"` to any `<td>` that the Mailchimp team should be able to edit visually. Use descriptive names: `mc:edit="hero"`, `mc:edit="body"`, `mc:edit="footer"`.

**Notes:**
- Inline styles are required -- Mailchimp strips `<style>` blocks in some plans
- Mailchimp has its own image hosting -- you can upload images during setup

---

## Beehiiv

**Variable syntax:** Double percent `%% %%`

| Placeholder | Beehiiv variable |
|---|---|
| `[UNSUBSCRIBE_URL]` | `%%unsubscribe_url%%` |
| `[FIRST_NAME]` | `%%first_name%%` |
| `[EMAIL]` | `%%email%%` |

**How to use:**
- Post > New post > Switch to custom HTML block
- Paste HTML into the HTML block editor
- Table-based layouts are fully supported in Beehiiv

**Notes:**
- Beehiiv wraps your HTML in their outer template -- you do not need to add their header/footer chrome
- Some users paste only the inner content (hero + body + CTA) and let Beehiiv handle the wrapper

---

## Resend

**Variable syntax:** JSX-style curly braces `{ }`

| Placeholder | Resend variable |
|---|---|
| `[UNSUBSCRIBE_URL]` | `{unsubscribeUrl}` |
| `[FIRST_NAME]` | `{firstName}` |

**How to use (Standard HTML):**
- Resend accepts raw HTML via their API: `html: yourHtmlString`
- Or use the Resend dashboard > Broadcasts > Custom HTML

**React Email option:**
Resend supports React Email natively -- if the team is developer-focused, request React Email `.tsx` output instead:
- Each section becomes a React Email component
- Styled with inline styles via the `style=` prop
- Compatible with the `@react-email/components` package

**React Email component structure:**
```tsx
import { Html, Head, Body, Container, Section, Text, Button, Hr } from '@react-email/components';

export default function NewsletterEmail({ firstName = 'there' }: { firstName?: string }) {
  return (
    <Html>
      <Head />
      <Body style={{ backgroundColor: '#F4F4F4', margin: '0', padding: '0' }}>
        <Container style={{ maxWidth: '600px', margin: '0 auto', backgroundColor: '#FFFFFF' }}>
          {/* sections here */}
        </Container>
      </Body>
    </Html>
  );
}
```

Install: `npm install @react-email/components`
Preview: `npx react-email dev`

**Notes:**
- Resend's HTML-to-email rendering is more modern than Outlook -- less table wrestling needed
- Still use inline styles in React Email for maximum compatibility

---

## Generic / Other ESPs

Use these placeholders and instruct the user to replace manually before sending:

| Placeholder | What to replace with |
|---|---|
| `[UNSUBSCRIBE_URL]` | Your ESP's unsubscribe URL or merge tag |
| `[FIRST_NAME]` | Your ESP's first name merge tag |
| `[CTA_URL]` | Actual destination URL |
| `[COMPANY NAME]` | Your company name |
| `[CITY, COUNTRY]` | Your registered address |

Add HTML comment above footer:
```html
<!-- Replace [UNSUBSCRIBE_URL] with your ESP's unsubscribe variable before sending -->
```

---

## Platform Comparison Quick Reference

| Feature | Loops | Mailchimp | Beehiiv | Resend |
|---|---|---|---|---|
| Variable syntax | `{{var}}` | `*\|VAR\|*` | `%%var%%` | `{var}` or JSX |
| Custom HTML | Yes, native | Yes, "Code your own" | Yes, HTML block | Yes, API or dashboard |
| Table layouts | Full support | Full support | Full support | Full support |
| React Email | No | No | No | Yes, native |
| Unsubscribe var | `{{unsubscribe_url}}` | `*\|UNSUB\|*` | `%%unsubscribe_url%%` | `{unsubscribeUrl}` |

---

## Supporting file: references/subject-line-formulas.md

# Subject Line Formulas

10 proven formulas for email subject lines. Each formula is matched to the tone and audience type where it performs best.

---

## The Fundamentals

A subject line does one thing: earn the open. It does not summarize the email. It creates tension, curiosity, or a direct promise that only gets resolved inside.

Rules:
- 40-60 characters ideal (preview cuts off around 60 on mobile)
- No all-caps
- Avoid spam triggers: "FREE", "!", "$$", "urgent", "click now"
- Test the preview text alongside -- first line of email shows in many clients

---

## Formula 1: Curiosity Gap

**Pattern:** "What [audience] gets wrong about [topic]"

Creates an information asymmetry -- the reader assumes they might be making a mistake.

**Examples:**
- "What most founders get wrong about pricing"
- "What 90% of devs miss in code reviews"
- "The B2B sales mistake killing your pipeline"

**Best for:** Educational newsletters, thought leadership, warm audiences

---

## Formula 2: Direct Benefit

**Pattern:** "How to [outcome] in [timeframe or condition]"

No ambiguity. Tells the reader exactly what they get.

**Examples:**
- "How to write a cold email in 10 minutes"
- "How to cut your deploy time by 40%"
- "How to find your first 10 B2B customers"

**Best for:** How-to content, tutorials, conversion-focused newsletters

---

## Formula 3: Number / List

**Pattern:** "[N] [topic] [patterns/lessons/rules/mistakes]"

Numbers create expectation of structure. Readers know they'll get discrete items.

**Examples:**
- "7 pricing patterns from 50 SaaS companies"
- "3 things we learned building in public"
- "5 cold email mistakes killing response rates"

**Best for:** Curated content, research-based newsletters, practical advice

---

## Formula 4: Question

**Pattern:** "Is [common belief] actually true?"

Challenges assumptions. Works best when the reader holds the belief being questioned.

**Examples:**
- "Is product-led growth right for your company?"
- "Are long cold emails actually killing your reply rate?"
- "Is your onboarding flow losing customers?"

**Best for:** Contrarian takes, research-backed content, audiences with strong priors

---

## Formula 5: Insider Access

**Pattern:** "What I/we learned from [credible source/experience]"

Implies firsthand knowledge. The reader gets access to something they could not learn on their own.

**Examples:**
- "What I learned from 200 failed cold emails"
- "What YC founders say about their first 100 customers"
- "What we learned building this in 30 days"

**Best for:** Founder newsletters, experience-based content, personal brand audiences

---

## Formula 6: Specific Stat

**Pattern:** "[Specific number or stat] changed how I think about [topic]"

Specificity signals credibility. Vague stats ("some companies see improvement") are ignored; specific ones stop the scroll.

**Examples:**
- "43% open rate from one subject line change"
- "1 in 3 B2B buyers decides before talking to sales"
- "We cut churn by 28% -- here's how"

**Best for:** Data-driven content, credibility-building, results-focused audiences

**Rule:** Only use if the stat appears in the email and comes from real data. Do not invent.

---

## Formula 7: Contrarian

**Pattern:** "Why [popular opinion] is wrong" or "Stop [common behavior]"

High open rate, high risk. Only use when you can back up the contrarian position in the email.

**Examples:**
- "Why your pricing page is costing you sales"
- "Stop writing product updates nobody reads"
- "The SEO advice that's actually hurting you"

**Best for:** Bold/direct tone, engaged audiences, newsletters where trust is already built

**Warning:** Use sparingly -- works once, then loses potency.

---

## Formula 8: Personal Story Hook

**Pattern:** "I [did thing]. Here's what happened."

Simple, human. Works because it promises a narrative arc.

**Examples:**
- "I sent 500 cold emails. Here's what worked."
- "We pivoted twice in 6 months. Here's what we learned."
- "I hired wrong 3 times. Here's the pattern I missed."

**Best for:** Conversational tone, personal brand, founder/operator audiences

---

## Formula 9: Name Drop

**Pattern:** "How [known company/person] [achieved outcome]"

Borrowed credibility. The reader clicks to learn the method, not just to read about the person.

**Examples:**
- "How Notion grew to 30M users without ads"
- "The Stripe playbook for developer adoption"
- "How Linear built cult loyalty in a crowded market"

**Best for:** GTM, growth, and operator audiences. High CTR on professional topics.

**Rule:** Only use if the content actually covers that company. Do not bait-and-switch.

---

## Formula 10: Urgency / Time-Bound

**Pattern:** "[Event or thing] [ends/starts/closes] [specific time]"

Only use when it is true. Fake urgency destroys trust fast.

**Examples:**
- "Webinar tomorrow: pricing your B2B SaaS"
- "Last chance: early access closes Friday"
- "The window for this is closing"

**Best for:** Event-driven sends, waitlists, limited-time offers

**Rule:** If it is not actually time-limited, do not use this formula.

---

## Picking the Right Formula

| Newsletter type | Top formulas |
|---|---|
| B2B SaaS / GTM | 1, 3, 6, 9 |
| Founder / operator | 5, 8, 1, 7 |
| Consumer / lifestyle | 2, 4, 10, 8 |
| Developer / technical | 3, 6, 2, 4 |
| Educational / media | 1, 3, 4, 6 |
| Product launch | 10, 2, 9 |

---

## Preview Text

The preview text (preheader) shows alongside the subject in most email clients. Treat it as a second subject line.

Pattern: Subject creates curiosity; preview text resolves just enough to confirm the click is worth it.

```html
<!-- Add to <head> -- renders as preview text in most clients -->
<span style="display:none;max-height:0;overflow:hidden;opacity:0;font-size:1px;color:#FAFAFA;">[PREVIEW TEXT HERE]</span>
```

Good preview text:
- Subject: "What most founders get wrong about pricing"
- Preview: "We analyzed 50 SaaS pricing pages -- here's the pattern"

Bad preview text (just repeats subject):
- Subject: "What most founders get wrong about pricing"
- Preview: "Mistakes founders make with their pricing"
