# Email Html Qa

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-emailboutique-digital-inc-email-html-qa-skill-email-html-qa-skill`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [EmailBoutique-Digital-Inc](https://agentstack.voostack.com/s/emailboutique-digital-inc)
- **Installs:** 0
- **Category:** [Communication](https://agentstack.voostack.com/c/communication)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [EmailBoutique-Digital-Inc](https://github.com/EmailBoutique-Digital-Inc)
- **Source:** https://github.com/EmailBoutique-Digital-Inc/email-html-qa-skill

## Install

```sh
agentstack add skill-emailboutique-digital-inc-email-html-qa-skill-email-html-qa-skill
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Email HTML QA

A repeatable, opinionated review pass for HTML email, built from real production
experience. Email is not the web: table-based layout, inconsistent CSS support,
and every client renders differently — so QA is about **robust and graceful**,
never pixel-perfect.

## How to run it
1. **If you have the HTML file, run the linter first** — a cheap mechanical pre-check:
   `python scripts/lint_email_html.py path/to/email.html`
   It flags size/clipping, missing `alt`, missing `charset`/`lang`, whether dark
   mode is targeted (the `color-scheme` opt-in), **transparent logos/icons that may
   vanish on a dark background**, layout tables without `role="presentation"`,
   empty/`#` links, **unlinked images** (Gmail-lightbox / lost CTA), missing
   **auto-link suppression** (blue-link risk), missing preheader, and missing
   compliance elements. Fix the boring stuff before spending human attention on craft.
2. **For a sent message, run the header check** — on the raw `.eml` as *received*:
   `python scripts/lint_email_headers.py path/to/message.eml`
   It reports the SPF/DKIM/DMARC results the receiver recorded, checks
   `List-Unsubscribe` + RFC 8058 one-click, and takes a best-effort guess at the
   sending ESP. Run it on a message as received — the pre-send HTML has no auth
   headers yet. It **reports** the recorded results; it does not fix deliverability.
3. **Then work the checklist below**, section by section.
4. **Report findings by severity, most-severe first** — each with *what's wrong,
   where, which client(s) it affects, and the suggested fix.* **Diagnose first;
   do not modify the code unless explicitly asked.**

## The core principle — verify mechanics, not sufficiency
Where a requirement varies by **country, industry, jurisdiction, or ESP** —
compliance wording, the accessibility standard, tracking conventions, the
must-support client list — this QA does **not** rule on legal or regulatory
*sufficiency*. It confirms that whatever was **specified for this project is
present and functional.** Capture the project-specific requirements once, up
front; keep the QA pass generic.

## Severity scale
- **Critical** — breaks for a large share of recipients or destroys the message
  (invisible text in dark mode, Gmail clipping, broken primary CTA).
- **High** — clearly wrong in a common client (Outlook-Mac regression, logo
  invisible on dark, contrast failure).
- **Medium** — noticeable but limited.
- **Low** — polish.

## The checklist

### 1. Dark mode — the highest-risk area
- **First, confirm whether dark mode is targeted at all.** Look for both opt-in
  metas in ``:
  `` and
  ``.
  If they're present, the email declares dark-mode support — verify it renders as
  intended. If they're absent, dark mode is **not** being targeted and clients will
  auto-handle it (often force-inverting) — flag it and decide with the project spec
  whether that's acceptable.
- Test **forced dark mode** explicitly — especially **Gmail**, plus **Outlook-for-Mac**
  and **iOS**. Behaviour varies by client and can't always be targeted.
- Confirm the **logo stays visible on dark** (a dark header + light logo is the
  safest default).
- **Watch transparent logos and social icons.** Dark artwork on a transparent PNG
  can sink into a dark-mode background and disappear. Fix it with a background
  "chip" (a padded light/brand-colour box), a dark-mode image swap, or a light
  logo on a deliberately dark header. The linter flags at-risk logo/icon images
  (transparent, icon-sized, no background behind them), but only a dark-mode proof
  confirms it — a flagged asset usually means going back to design for a variant.
- Check **coloured buttons** — confirm button copy doesn't vanish. Never assume a
  blend-mode trick works on a light/coloured fill; judge each button by its own
  fill + text combination.
- Confirm no colour's contrast fails against its **dark-mode-inverted** background.
- Distinguish **fixed-dark** elements (already dark; must render identically —
  gradient-as-solid + blend-mode wrap) from **adaptive** elements (light by
  default; deliberately invert via a dark-mode class). Never mix their techniques.
- Use the companion per-send test grid: [`references/dark-mode-qa-matrix.md`](references/dark-mode-qa-matrix.md)
  — surfaces × clients, with the known high-risk cells to check first.

### 2. Client rendering
- **Outlook (Windows)** — spacing, no-`max-width` elements, background-image gaps.
- **Outlook for Mac** — MSO-conditional regressions; test separately from Windows.
- **Gmail** — `` stripping, coloured buttons, clipping (~102 KB).
- **Apple Mail / iOS** — best support; still confirm the dark-mode behaviour you rely on.
- Render-proof across the client matrix (e.g. Email on Acid / Litmus) and save proofs.

### 3. Responsive / mobile
- Columns stack/flex correctly; no horizontal scroll; adequate tap targets.
- Don't depend unnecessarily on media queries some clients strip.

### 4. Code quality & size
- Lean code; keep well under the ~102 KB Gmail clip threshold.
- Minimal table nesting; no stray markup; no reflexive Outlook ghost tables.
- No inline styles carried in from pasted copy overriding the template.
- Declare ``; confirm curly quotes, dashes, accents and
  emoji render (no mojibake) after copy moves design → code → ESP.

### 5. Accessibility
- **Live text**, not text baked into images.
- **Alt text is intentional, not just present.** Meaningful images get a real,
  descriptive `alt`; **purely decorative images get an empty `alt=""`** (and
  `aria-hidden="true"` where needed) so a screen reader skips them cleanly. The
  failure case is a decorative image with **no `alt` attribute at all** — some
  screen readers then read out the filename. Decide per image: describe it, or
  silence it.
- **Contrast** passes in light **and** dark mode.
- Logical **heading hierarchy**.
- **Semantic mechanics:** layout tables carry `role="presentation"`; a document
  `lang` is set; decorative/spacer cells and images are hidden from assistive tech
  (`aria-hidden` / empty `alt=""`); source order gives a sensible linear reading
  order when columns stack.
- Verify against the **project-specified** accessibility standard — this confirms
  the build honours what was agreed; it does not certify legal conformance.

### 6. Typography
- Correct fonts render (and the fallback stack is sane where webfonts fail);
  **verify in the ESP** — fonts/spacing can be lost design → code → ESP.
- Type scale and spacing match the style guide.

### 7. Images
- Correct export sizes, 2× for retina, lean file sizes.
- All images have alt text; reserve images for hero/lifestyle/product — no
  image-only emails.
- **Link your images — especially large ones.** The eye reaches an image before
  the copy, so an image is effectively a CTA: a hero/product image usually
  deserves the primary link. A large **unlinked** image is also a rendering risk —
  Gmail wraps unlinked images above a certain (undocumented) size in its own
  **lightbox pop-up** and opens them on tap instead of following your CTA.
  Wrapping the image in a real `` both captures the click and prevents the
  lightbox. Safe rule: link it. (Legitimate exceptions — logos, spacers, tiny
  icons — can stay unlinked.)

### 8. Links, CTAs & tracking
- Every link resolves and points where intended; primary CTA works and is visible
  in dark mode.
- Confirm tracking/UTM parameters where the project uses them (convention is
  project-specific).

### 9. Preheader & hidden content
- Preheader text is set, sensible, and not duplicating the subject; hidden/spacer
  content doesn't leak into the visible body or dark mode.

### 10. Personalization & ESP
- Test personalization **with missing fields** — fallbacks are ESP-DB-dependent
  and break silently. Confirm the fallback chain renders gracefully.
- Confirm the build matches the **target ESP's** real constraints.

### 11. Compliance elements — present & functional
Verify **mechanics**, not legal sufficiency (see the core principle). What each
element must contain — which laws, which address, which language — is the
sender's/their counsel's decision and varies by country and industry.
- **Unsubscribe** link present and **resolves** (not a placeholder/`#`).
- A **sender-identity / physical-address** block present where required.
- The **`list-unsubscribe` header** set where the ESP supports it.
- Any other specified compliance element (consent language, preference centre)
  present and linking correctly.
- Flag anything **missing versus what was specified** — don't assess statutory sufficiency.

### 12. Auto-linking & blue links (phone, date, address)
Some clients **auto-detect phone numbers, dates, and physical addresses** and wrap
them in their own blue links — which can recolour text, change the font, and break
the layout (common in footers). Confirm auto-linking is suppressed and these
elements render as intended. Keep the three overrides **separate** — Gmail strips
chained attribute selectors:
- **Apple Mail / iOS** — override `a[x-apple-data-detectors]` (`color` /
  `text-decoration` / `font-*` all `inherit !important`). Optionally add
  ``.
- **Gmail** — `u + #body a { … inherit !important }`, with `id="body"` on ``.
- **Samsung Mail** — `#MessageViewBody a { … inherit !important }`.
- Then **look at the rendered footer** in each client — suppression CSS is easy to
  add and easy to get stripped, so verify, don't assume.

### 13. Authentication & headers — from a received `.eml`
Runs on a message **as received**, not the pre-send HTML — the authentication
results are stamped by the receiving server. **Read and report; never advise or fix.**
Use `scripts/lint_email_headers.py` (get the raw `.eml` via Gmail's *Show original →
Download*, Apple Mail's *Raw Source*, or Outlook's *View source*).
- **`Authentication-Results`** — report the receiver's recorded **SPF / DKIM / DMARC**
  results and key fields (DKIM `header.i`/selector, SPF mailfrom domain, DMARC
  policy `p=`/`sp=`/`dis=` and `header.from`). Use the **topmost** header (the one
  your receiver added); downstream ones can be forged. `pass` → PASS, `fail` → FAIL,
  anything else (softfail/none/neutral) → WARN.
- **`List-Unsubscribe`** present, and **`List-Unsubscribe-Post: List-Unsubscribe=One-Click`**
  present (RFC 8058 — Gmail/Yahoo bulk-sender one-click).
- **Best-effort ESP identification** from telltale headers / bounce-domain / DKIM
  selector — reported as context, never as a verdict.
This surfaces *what the mailbox provider already determined*; the fixes (record
configuration, warming, spam scoring) belong to the ESP or a deliverability specialist.

## Out of scope — by design
Knowing where the expertise ends is part of doing this well. This QA does **not** cover:
- **Deliverability advice or fixes** — configuring SPF/DKIM/DMARC records, IP/domain
  warming, spam scoring, inbox placement. (We *read and report* the auth results a
  receiver recorded; we don't diagnose or fix them — that's the ESP / deliverability
  provider.)
- **ESP campaign configuration & sending** — audience, segmentation, send time,
  A/B, automation logic.
- **Legal/regulatory certification** — this confirms specified elements are
  present and functional; it does not certify conformance.

If a build touches one of these, note it and route it to the right owner.

## Reporting protocol
Report by severity, most-severe first, each with what's wrong, where, which
client(s) it affects, and the suggested fix. **Diagnose first; fix only on request.**

---
_Maintained by EmailBoutique Digital Inc. · MIT-licensed · rendering/dark-mode
engines change over time — treat client-specific behaviour as time-sensitive and
re-verify._

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [EmailBoutique-Digital-Inc](https://github.com/EmailBoutique-Digital-Inc)
- **Source:** [EmailBoutique-Digital-Inc/email-html-qa-skill](https://github.com/EmailBoutique-Digital-Inc/email-html-qa-skill)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-emailboutique-digital-inc-email-html-qa-skill-email-html-qa-skill
- Seller: https://agentstack.voostack.com/s/emailboutique-digital-inc
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
