@opendirectory.dev/skills 0.1.51 → 0.1.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/registry.json +12 -1
- package/skills/email-newsletter/README.md +98 -0
- package/skills/email-newsletter/SKILL.md +395 -0
- package/skills/email-newsletter/evals/evals.json +35 -0
- package/skills/email-newsletter/references/design-system.md +390 -0
- package/skills/email-newsletter/references/html-email-guide.md +235 -0
- package/skills/email-newsletter/references/platform-compat.md +154 -0
- package/skills/email-newsletter/references/subject-line-formulas.md +207 -0
- package/skills/email-newsletter/templates/dark-newsletter.html +307 -0
- package/skills/email-newsletter/templates/light-newsletter.html +166 -0
- package/skills/meta-ads-skill/README.md +24 -55
- package/skills/meta-ads-skill/meta-ads-skill/SKILL.md +35 -18
- package/skills/meta-ads-skill/meta-ads-skill/references/report_templates.md +4 -3
- package/skills/meta-ads-skill/meta-ads-skill/references/workflows.md +11 -15
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# Email Design System
|
|
2
|
+
|
|
3
|
+
Premium dark-first email design. Every output should look considered and editorial -- not a template dump.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Design Philosophy
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+
Default: dark. Override: `tone=light` for consumer brands, formal industries, or user preference.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Visual Anchor Rule
|
|
16
|
+
|
|
17
|
+
Every email must have ONE element with significantly higher visual weight than everything else. This is the thing that makes the email memorable.
|
|
18
|
+
|
|
19
|
+
**What qualifies as a visual anchor:**
|
|
20
|
+
- CTA callout card (`#D8F90A` full-width rounded card) -- strongest option, highest contrast on dark
|
|
21
|
+
- Stat callout with a striking number in 24px Instrument Serif italic
|
|
22
|
+
- Hero headline in 52px+ Instrument Serif (when the headline IS the story)
|
|
23
|
+
- Step cards section (when the numbered content is the primary value)
|
|
24
|
+
|
|
25
|
+
**What doesn't qualify:** A regular paragraph, a hero with a small button, generic unformatted text.
|
|
26
|
+
|
|
27
|
+
**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.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Color Tokens
|
|
32
|
+
|
|
33
|
+
### Dark (default)
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Outer bg: #050505
|
|
37
|
+
Container bg: #111111
|
|
38
|
+
Header bg: #0A0A0A
|
|
39
|
+
Alt section bg: #161616 (subtle alternation for visual rhythm)
|
|
40
|
+
Elevated card bg: #1A1A1A (stat callout, footer)
|
|
41
|
+
Footer bg: #080808
|
|
42
|
+
|
|
43
|
+
Text primary: #F2F2F2
|
|
44
|
+
Text body: #CCCCCC
|
|
45
|
+
Text muted: #888888
|
|
46
|
+
Text meta: #555555
|
|
47
|
+
|
|
48
|
+
CTA primary bg: #D8F90A (yellow-green — REQUIRES #0A0A0A dark text)
|
|
49
|
+
CTA secondary bg: #FFFFFF (white — #0A0A0A text)
|
|
50
|
+
CTA dark bg: #111111 (inside yellow callout card — #F2F2F2 text)
|
|
51
|
+
|
|
52
|
+
Step badge bg: #D8F90A (numbered card badge)
|
|
53
|
+
Step badge text: #0A0A0A
|
|
54
|
+
|
|
55
|
+
Divider: #2A2A2A
|
|
56
|
+
Card border: #222222
|
|
57
|
+
Brand strip: [BRAND_COLOR] (2px line between header and hero)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Light (fallback when tone=light)
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Outer bg: #F0F0EE
|
|
64
|
+
Container bg: #FFFFFF
|
|
65
|
+
Header bg: #1A1A1A (always dark — anchors the email)
|
|
66
|
+
Alt section bg: #F8F8F6
|
|
67
|
+
Footer bg: #F8F8F6
|
|
68
|
+
|
|
69
|
+
Text primary: #111111
|
|
70
|
+
Text body: #444444
|
|
71
|
+
Text muted: #888888
|
|
72
|
+
|
|
73
|
+
CTA primary bg: #111111 (dark button on white)
|
|
74
|
+
Callout card bg: #111111 (dark card on white email — reversal effect)
|
|
75
|
+
|
|
76
|
+
Divider: #EEEEEE
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Brand Color Rules
|
|
82
|
+
|
|
83
|
+
When `brand_color` is provided:
|
|
84
|
+
- 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
|
|
85
|
+
- Do NOT use it for: body text, large bg sections (unless very dark and intentional)
|
|
86
|
+
|
|
87
|
+
**Luminance check for CTA button text:**
|
|
88
|
+
- Light brand color (luminance > 0.5 — yellows, greens, oranges, light purples): use `#0A0A0A` text
|
|
89
|
+
- Dark brand color (luminance < 0.4 -- navy, forest, dark purple): use `#FFFFFF` text
|
|
90
|
+
|
|
91
|
+
**Brand color on dark email:**
|
|
92
|
+
- If brand color is `#D8F90A` or similar bright/neon: perfect, use directly for CTA + badge
|
|
93
|
+
- 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
|
|
94
|
+
- If brand color is `#856FE6` (purple): works on dark bg, use for strip + stat border + step badges; CTA stays `#D8F90A` for contrast
|
|
95
|
+
|
|
96
|
+
**Substitution in template:**
|
|
97
|
+
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.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Typography
|
|
102
|
+
|
|
103
|
+
### Display (H1, H2)
|
|
104
|
+
|
|
105
|
+
**Font:** Instrument Serif, Georgia fallback
|
|
106
|
+
|
|
107
|
+
```css
|
|
108
|
+
font-family: 'Instrument Serif', Georgia, 'Times New Roman', serif;
|
|
109
|
+
font-weight: 400; /* Instrument Serif is a display weight at 400 */
|
|
110
|
+
letter-spacing: -0.02em;
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**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.
|
|
114
|
+
|
|
115
|
+
**Loading:**
|
|
116
|
+
```html
|
|
117
|
+
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Gmail strips this `<link>` tag. Georgia renders instead. Both look good. Apple Mail, Yahoo, Outlook 365 keep the Google Font.
|
|
121
|
+
|
|
122
|
+
**H1 (hero headline):**
|
|
123
|
+
```
|
|
124
|
+
font-size: 60px (4-5 words — push to poster scale)
|
|
125
|
+
font-size: 56px (6-7 words — editorial authority)
|
|
126
|
+
font-size: 48px (8 words)
|
|
127
|
+
font-size: 32px (mobile fallback via @media)
|
|
128
|
+
line-height: 1.02
|
|
129
|
+
letter-spacing: -0.04em at 60px, -0.03em at 56px, -0.02em at 48px
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Never size a headline down for safety. A bigger headline with tight tracking reads authoritative; a smaller headline reads like a template.
|
|
133
|
+
|
|
134
|
+
**H2 (section headline):**
|
|
135
|
+
```
|
|
136
|
+
font-size: 40px (normal)
|
|
137
|
+
font-size: 52px (CTA callout card -- bigger impact)
|
|
138
|
+
line-height: 1.05
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Body
|
|
142
|
+
|
|
143
|
+
**Font:** Inter, Arial fallback
|
|
144
|
+
|
|
145
|
+
```css
|
|
146
|
+
font-family: Inter, Arial, Helvetica, sans-serif;
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Body text (dark):**
|
|
150
|
+
```
|
|
151
|
+
font-size: 16-17px
|
|
152
|
+
line-height: 1.65-1.7
|
|
153
|
+
color: #CCCCCC
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Bold callouts:**
|
|
157
|
+
```html
|
|
158
|
+
<strong style="color:#F2F2F2;font-weight:600;">Key phrase</strong>
|
|
159
|
+
```
|
|
160
|
+
Use for the opening 3-4 words of each key idea.
|
|
161
|
+
|
|
162
|
+
**Meta / label text:**
|
|
163
|
+
```
|
|
164
|
+
font-size: 11px
|
|
165
|
+
font-weight: 600
|
|
166
|
+
letter-spacing: 0.14-0.22em
|
|
167
|
+
text-transform: uppercase
|
|
168
|
+
color: [BRAND_COLOR] or #555555
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Typography Nuances
|
|
172
|
+
|
|
173
|
+
**Italic variant for editorial emphasis:**
|
|
174
|
+
Instrument Serif has an italic variant (included in the Google Fonts URL). Use `font-style:italic` for:
|
|
175
|
+
- Stat callout quote text -- adds literary weight to a striking number or phrase
|
|
176
|
+
- Hero headline when tone is warm/founder
|
|
177
|
+
- Never on body copy -- italic at 16px is hard to read on dark backgrounds
|
|
178
|
+
|
|
179
|
+
```html
|
|
180
|
+
<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>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Letter-spacing rules:**
|
|
184
|
+
- Very large display (52px+): `-0.03em` (tighter = more editorial authority)
|
|
185
|
+
- Section headlines (38-40px): `-0.02em`
|
|
186
|
+
- Category label (11px uppercase): `0.22em` minimum, up to `0.30em` for wider/premium feel
|
|
187
|
+
- Body Inter: `0` -- never add tracking to body text
|
|
188
|
+
|
|
189
|
+
**Weight contrast rule:**
|
|
190
|
+
`'Instrument Serif' 400` + `Inter 700` (bold callouts) = correct pairing.
|
|
191
|
+
Never use Instrument Serif bold -- it's a display font; 400 is its designed weight.
|
|
192
|
+
Body Inter on dark: color `#CCCCCC` (not `#888888` -- that's muted/meta only).
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Spacing Rhythm
|
|
197
|
+
|
|
198
|
+
| Location | Padding |
|
|
199
|
+
|---|---|
|
|
200
|
+
| Section (standard) | 40px top/bottom, 40px left/right |
|
|
201
|
+
| Hero section | 64px top, 56px bottom, 40px sides |
|
|
202
|
+
| CTA callout card | 52px top/bottom, 40px sides |
|
|
203
|
+
| Footer | 44px top, 52px bottom, 40px sides |
|
|
204
|
+
| Between body paragraphs | 20px margin-bottom |
|
|
205
|
+
| After H2 before content | 24-32px padding |
|
|
206
|
+
| Step card gap | 20px margin-bottom per card |
|
|
207
|
+
| Container max-width | 600px |
|
|
208
|
+
|
|
209
|
+
Mobile (max-width 600px): reduce side padding to 24px via @media.
|
|
210
|
+
|
|
211
|
+
**Valid spacing values (rhythm scale):** 8 / 16 / 20 / 24 / 32 / 40 / 52 / 64px.
|
|
212
|
+
Never use arbitrary values like 18px, 22px, 30px, 45px. They break visual rhythm and signal template output.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Section Patterns
|
|
217
|
+
|
|
218
|
+
### Header
|
|
219
|
+
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.
|
|
220
|
+
|
|
221
|
+
```html
|
|
222
|
+
<tr>
|
|
223
|
+
<td bgcolor="#0A0A0A" style="background-color:#0A0A0A;padding:20px 40px;">
|
|
224
|
+
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
|
225
|
+
<tr>
|
|
226
|
+
<td style="font-family:'Instrument Serif',Georgia,serif;font-size:20px;font-weight:400;color:#F2F2F2;letter-spacing:-0.01em;">[BRAND NAME]</td>
|
|
227
|
+
<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] | [DATE]</td>
|
|
228
|
+
</tr>
|
|
229
|
+
</table>
|
|
230
|
+
</td>
|
|
231
|
+
</tr>
|
|
232
|
+
<tr>
|
|
233
|
+
<td bgcolor="#D8F90A" style="background-color:#D8F90A;height:2px;font-size:1px;line-height:1px;"> </td>
|
|
234
|
+
</tr>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Hero
|
|
238
|
+
52px Instrument Serif headline. Category label above in brand color uppercase. Inter hook paragraph below. Pill CTA button (border-radius:100px).
|
|
239
|
+
|
|
240
|
+
H1 word count → font size:
|
|
241
|
+
- 5 words or fewer: 56px
|
|
242
|
+
- 6-7 words: 52px
|
|
243
|
+
- 8 words: 44px
|
|
244
|
+
|
|
245
|
+
CTA pill button shape (border-radius:100px) is the hero CTA. Rectangular button (border-radius:8px) is used in secondary CTA sections.
|
|
246
|
+
|
|
247
|
+
### Divider
|
|
248
|
+
Centered 96px rule. `#2A2A2A` on dark, `#EEEEEE` on light. Adds visual rhythm between sections.
|
|
249
|
+
|
|
250
|
+
```html
|
|
251
|
+
<tr>
|
|
252
|
+
<td bgcolor="#111111" style="background-color:#111111;padding:40px 40px 0;">
|
|
253
|
+
<table width="96" cellpadding="0" cellspacing="0" border="0" style="margin:0 auto;">
|
|
254
|
+
<tr>
|
|
255
|
+
<td bgcolor="#2A2A2A" style="background-color:#2A2A2A;height:1px;font-size:1px;line-height:1px;"> </td>
|
|
256
|
+
</tr>
|
|
257
|
+
</table>
|
|
258
|
+
</td>
|
|
259
|
+
</tr>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Stat Callout
|
|
263
|
+
`#1A1A1A` elevated card bg. 3px brand color left border. Instrument Serif quote at 24px. Attribution in small Inter.
|
|
264
|
+
|
|
265
|
+
The callout sits on `#111111` outer padding -- the slight elevation (#1A1A1A vs #111111) creates depth without needing a visible border.
|
|
266
|
+
|
|
267
|
+
### Numbered Step Cards
|
|
268
|
+
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`.
|
|
269
|
+
|
|
270
|
+
This pattern replaces bullet lists. It looks significantly better and draws the eye through sequential content.
|
|
271
|
+
|
|
272
|
+
### CTA Callout Card
|
|
273
|
+
The visual anchor. `#D8F90A` background, `border-radius:14px`, generous padding (52px). H2 in Instrument Serif at 40-52px, `color:#1A1A1A`. Dark `#111111` button inside.
|
|
274
|
+
|
|
275
|
+
The yellow card inverts the dark email's color relationship -- it's the one bright element, which makes it unmissable as the primary action.
|
|
276
|
+
|
|
277
|
+
### Footer
|
|
278
|
+
`#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.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Tone Variants
|
|
283
|
+
|
|
284
|
+
### dark (default)
|
|
285
|
+
- Container: `#111111`
|
|
286
|
+
- Hero bg: `#111111`
|
|
287
|
+
- Text: `#F2F2F2` / `#CCCCCC`
|
|
288
|
+
- CTA: `#D8F90A` pill button (dark text)
|
|
289
|
+
- Use for: SaaS, tech, founders, operators, B2B
|
|
290
|
+
|
|
291
|
+
### light (fallback)
|
|
292
|
+
- Container: `#FFFFFF`
|
|
293
|
+
- Header: stays dark `#1A1A1A` (anchors the email)
|
|
294
|
+
- Text: `#111111` / `#444444`
|
|
295
|
+
- CTA: `#111111` rectangular button (white text)
|
|
296
|
+
- Callout card: dark `#111111` card (inverted)
|
|
297
|
+
- Use for: consumer brands, formal B2B, healthcare, finance
|
|
298
|
+
|
|
299
|
+
Trigger light mode: user sets `tone=light` or `tone=formal` or specifies "white background".
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Email Client Behavior
|
|
304
|
+
|
|
305
|
+
| Client | Instrument Serif | Dark bg renders | `@media` |
|
|
306
|
+
|---|---|---|---|
|
|
307
|
+
| Gmail (web) | No -- falls back to Georgia | Yes | Yes |
|
|
308
|
+
| Gmail app (iOS/Android) | No | Yes | Partial |
|
|
309
|
+
| Apple Mail | Yes | Yes | Yes |
|
|
310
|
+
| Outlook 2019+ | Yes (via Google Fonts CDN) | Yes | No |
|
|
311
|
+
| Outlook 2016 | No | May invert colors | No |
|
|
312
|
+
| Yahoo Mail | Yes | Yes | Yes |
|
|
313
|
+
|
|
314
|
+
**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.
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Email Slop Patterns to Avoid
|
|
319
|
+
|
|
320
|
+
These produce generic AI-looking output. Check the self-QA checklist against these before saving.
|
|
321
|
+
|
|
322
|
+
| Pattern | What it signals | Fix |
|
|
323
|
+
|---|---|---|
|
|
324
|
+
| White background + colored button | Safe, corporate, forgettable | Use dark template (default) |
|
|
325
|
+
| Centered hero text on gradient | Stock newsletter look | Left-aligned hero on `#111111` |
|
|
326
|
+
| All-Inter / all-Arial, no display font | No typographic character | Instrument Serif on H1 is non-negotiable |
|
|
327
|
+
| No visual anchor -- every section same weight | Wall of text with branding | Identify and elevate the anchor (CTA card, stat callout, or oversized hero) |
|
|
328
|
+
| Brand color on 4+ elements | Garish / over-branded | Max 3 accent uses: strip, stat border, category label |
|
|
329
|
+
| Bullet lists everywhere | Undesigned content dump | Step cards replace bullets; bold callouts open paragraphs |
|
|
330
|
+
| Generic CTA copy ("Click here", "Learn more") | AI filler | 3-5 word action + benefit ("Save My Seat", "Read the Full Breakdown") |
|
|
331
|
+
| Footer larger than 3 lines | Compliance dump, reader ignores | Brand name + company line + rule + unsubscribe link. That's it. |
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Custom Generation Guide
|
|
336
|
+
|
|
337
|
+
When template doesn't fit Step 2 answers, generate from scratch using these tokens.
|
|
338
|
+
|
|
339
|
+
### Background tokens
|
|
340
|
+
|
|
341
|
+
```
|
|
342
|
+
User says "dark": outer #050505, container #111111, header #0A0A0A, footer #080808
|
|
343
|
+
User says "light": outer #F0F0EE, container #FFFFFF, header #1A1A1A, footer #F8F8F6
|
|
344
|
+
User provides hex: use provided hex for container, darken ~10% for header, lighten ~5% for alt sections
|
|
345
|
+
If hex is dark (<30% luminance): light text #F2F2F2
|
|
346
|
+
If hex is light (>70% luminance): dark text #111111
|
|
347
|
+
If hex is mid: test contrast ratio, pick text accordingly
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Font tokens
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
User says "editorial serif": 'Instrument Serif',Georgia,'Times New Roman',serif (display)
|
|
354
|
+
Inter,Arial,Helvetica,sans-serif (body)
|
|
355
|
+
User says "modern sans": 'DM Sans',Arial,Helvetica,sans-serif (display, load from Google Fonts)
|
|
356
|
+
Inter,Arial,Helvetica,sans-serif (body)
|
|
357
|
+
User says "system fonts": -apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif (both)
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Button style tokens
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
User says "pill": border-radius:100px
|
|
364
|
+
User says "softly rounded": border-radius:10px
|
|
365
|
+
User says "sharp": border-radius:0 (or 2px for sub-pixel rendering)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Accent color tokens
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
User provides accent: use for brand strip, CTA button, step badges, stat border
|
|
372
|
+
text on accent: #0A0A0A if luminance >0.4, #FFFFFF if luminance <0.4
|
|
373
|
+
User says "keep default": #D8F90A with #0A0A0A text
|
|
374
|
+
User says "minimal/none": #FFFFFF CTA on dark, #111111 CTA on light
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## What NOT to Use
|
|
380
|
+
|
|
381
|
+
In inline styles, never:
|
|
382
|
+
- `display:flex` / `display:grid`
|
|
383
|
+
- `position:absolute/relative`
|
|
384
|
+
- `float:`
|
|
385
|
+
- CSS custom properties (`--var`)
|
|
386
|
+
- `min-height:` / `max-height:`
|
|
387
|
+
- `background-image:` (Outlook strips it)
|
|
388
|
+
- `border-radius` on `<table>` elements (use on `<td>` only)
|
|
389
|
+
- `rgba()` colors (use solid hex equivalents)
|
|
390
|
+
- `linear-gradient` (Outlook renders as solid block)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# HTML Email Guide
|
|
2
|
+
|
|
3
|
+
Rules for writing HTML that renders correctly in Gmail, Apple Mail, Outlook, Samsung Mail, and Yahoo Mail.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The One Rule
|
|
8
|
+
|
|
9
|
+
**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.
|
|
10
|
+
|
|
11
|
+
Exception: `@media` queries for mobile responsiveness can go in a `<head>` `<style>` block -- but always include inline fallbacks so the layout works without them.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Layout: Table-Based Only
|
|
16
|
+
|
|
17
|
+
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.
|
|
18
|
+
|
|
19
|
+
### Outer wrapper pattern
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:#F4F4F4;">
|
|
23
|
+
<tr><td align="center" style="padding:24px 16px;">
|
|
24
|
+
|
|
25
|
+
<!-- 600px container -->
|
|
26
|
+
<table width="600" cellpadding="0" cellspacing="0" border="0" style="max-width:600px;width:100%;background-color:#FFFFFF;">
|
|
27
|
+
<!-- sections go here as <tr><td> blocks -->
|
|
28
|
+
</table>
|
|
29
|
+
|
|
30
|
+
</td></tr>
|
|
31
|
+
</table>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Always use both `width="600"` (HTML attribute) and `max-width:600px` (inline style). The attribute handles Outlook; the style handles everything else.
|
|
35
|
+
|
|
36
|
+
### Required table attributes
|
|
37
|
+
|
|
38
|
+
Every `<table>` needs all three:
|
|
39
|
+
```html
|
|
40
|
+
<table cellpadding="0" cellspacing="0" border="0">
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Missing any of these adds default spacing or borders that break layout.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Typography
|
|
48
|
+
|
|
49
|
+
**Font stack (always use system fonts with web-safe fallbacks):**
|
|
50
|
+
|
|
51
|
+
For sans-serif:
|
|
52
|
+
```css
|
|
53
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, Helvetica, sans-serif;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For serif (headlines only):
|
|
57
|
+
```css
|
|
58
|
+
font-family: Georgia, 'Times New Roman', Times, serif;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Web fonts (optional, with caveats):**
|
|
62
|
+
- Declare in `<head>` `<style>` block using `@import` or `<link>`
|
|
63
|
+
- Always include a web-safe fallback -- Gmail strips web font declarations
|
|
64
|
+
- Never rely on a web font being rendered -- design so the fallback looks good
|
|
65
|
+
|
|
66
|
+
**Type scale:**
|
|
67
|
+
- H1 (hero): 28-36px, font-weight 700, line-height 1.2
|
|
68
|
+
- H2 (section headers): 20-24px, font-weight 600, line-height 1.3
|
|
69
|
+
- Body: 15-16px, line-height 1.6-1.7, color #333333 or #444444
|
|
70
|
+
- Small/meta: 12-13px, color #888888
|
|
71
|
+
|
|
72
|
+
**Always set:**
|
|
73
|
+
```css
|
|
74
|
+
font-size: [px];
|
|
75
|
+
line-height: [number];
|
|
76
|
+
color: [hex];
|
|
77
|
+
font-family: [stack];
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
On every text element. Do not rely on inheritance -- email clients do not inherit styles reliably.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Images
|
|
85
|
+
|
|
86
|
+
Every image:
|
|
87
|
+
```html
|
|
88
|
+
<img src="[hosted-url]" alt="[descriptive text]" width="600" border="0" style="display:block;max-width:100%;border:0;">
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Rules:
|
|
92
|
+
- `display:block` removes bottom gap (inline images add ~4px gap below)
|
|
93
|
+
- `border="0"` (HTML attribute) + `border:0` (inline style) -- need both for Outlook
|
|
94
|
+
- Always hosted URL -- base64 images are often blocked by spam filters
|
|
95
|
+
- `max-width:100%` for mobile responsiveness
|
|
96
|
+
- Always fill in `alt` -- many clients block images by default, alt text is what readers see first
|
|
97
|
+
|
|
98
|
+
For full-width hero images:
|
|
99
|
+
```html
|
|
100
|
+
<img src="[url]" alt="" width="600" border="0" style="display:block;max-width:100%;width:100%;height:auto;border:0;">
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## CTA Buttons
|
|
106
|
+
|
|
107
|
+
**Never** use a simple `<a>` tag with `display:block` and background color for buttons. Outlook ignores `display:block` on `<a>` tags.
|
|
108
|
+
|
|
109
|
+
**Always** use the table+td structure:
|
|
110
|
+
|
|
111
|
+
```html
|
|
112
|
+
<table cellpadding="0" cellspacing="0" border="0">
|
|
113
|
+
<tr>
|
|
114
|
+
<td align="center" bgcolor="#1A1A1A" style="background-color:#1A1A1A;border-radius:6px;">
|
|
115
|
+
<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>
|
|
116
|
+
</td>
|
|
117
|
+
</tr>
|
|
118
|
+
</table>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Notes:
|
|
122
|
+
- `bgcolor=` HTML attribute + `background-color:` inline style -- need both for Outlook
|
|
123
|
+
- `border-radius` on `<td>` -- Outlook ignores it on `<a>`
|
|
124
|
+
- `display:inline-block` on `<a>` is fine (it's not a layout block, just expands the click area)
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Colors and Backgrounds
|
|
129
|
+
|
|
130
|
+
Always use both the HTML attribute and inline style for backgrounds:
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<td bgcolor="#FFFFFF" style="background-color:#FFFFFF;">
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Outlook uses `bgcolor` attribute; other clients use the inline style.
|
|
137
|
+
|
|
138
|
+
**Dark backgrounds:**
|
|
139
|
+
Use `bgcolor="#1A1A1A"` (safe dark) or `bgcolor="#000000"`. Avoid pure black text on very dark backgrounds -- use `#FFFFFF` or `#F0F0F0` for text on dark.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Spacing
|
|
144
|
+
|
|
145
|
+
Use `padding` on `<td>` elements, not margins. `margin` on table cells behaves unpredictably across clients.
|
|
146
|
+
|
|
147
|
+
Standard section padding: `padding:40px 32px`
|
|
148
|
+
Content padding (narrower): `padding:24px 32px`
|
|
149
|
+
Header/footer padding: `padding:20px 32px`
|
|
150
|
+
|
|
151
|
+
For vertical spacing between elements, use empty `<tr><td style="height:16px;font-size:1px;line-height:1px;"> </td></tr>` rows in Outlook-heavy sends. For most modern clients, `padding-bottom` on the previous `<td>` is enough.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Mobile Responsiveness
|
|
156
|
+
|
|
157
|
+
Minimal media query approach (add to `<head>` style block):
|
|
158
|
+
|
|
159
|
+
```html
|
|
160
|
+
<style>
|
|
161
|
+
@media only screen and (max-width: 600px) {
|
|
162
|
+
.container { width: 100% !important; max-width: 100% !important; }
|
|
163
|
+
.stack { display: block !important; width: 100% !important; }
|
|
164
|
+
.hide-mobile { display: none !important; }
|
|
165
|
+
h1 { font-size: 26px !important; }
|
|
166
|
+
td { padding-left: 20px !important; padding-right: 20px !important; }
|
|
167
|
+
}
|
|
168
|
+
</style>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Always set inline fallbacks -- treat media queries as an enhancement, not a requirement.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Dark Mode
|
|
176
|
+
|
|
177
|
+
Some clients (Apple Mail, Gmail Android) support dark mode. Add to `<head>` style block:
|
|
178
|
+
|
|
179
|
+
```html
|
|
180
|
+
<style>
|
|
181
|
+
@media (prefers-color-scheme: dark) {
|
|
182
|
+
.dark-bg { background-color: #1A1A1A !important; }
|
|
183
|
+
.dark-text { color: #F0F0F0 !important; }
|
|
184
|
+
}
|
|
185
|
+
</style>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
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.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## What to Avoid
|
|
193
|
+
|
|
194
|
+
Never use in inline styles:
|
|
195
|
+
- `display: flex` / `display: grid` -- not supported in Outlook
|
|
196
|
+
- `position: absolute/relative/fixed` -- breaks table layout
|
|
197
|
+
- `float:` -- unreliable across clients
|
|
198
|
+
- CSS custom properties (`--variable`) -- Outlook does not support
|
|
199
|
+
- `min-height:` / `max-height:` -- Outlook ignores
|
|
200
|
+
- `background-image:` CSS property -- Outlook strips it (use VML instead for complex cases, or avoid background images)
|
|
201
|
+
- `border-radius` on `<table>` -- use on `<td>` only
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Outlook VML (advanced, optional)
|
|
206
|
+
|
|
207
|
+
For solid-color background sections in Outlook, the `bgcolor` attribute is enough. For background images in Outlook specifically, use VML conditionals:
|
|
208
|
+
|
|
209
|
+
```html
|
|
210
|
+
<!--[if gte mso 9]>
|
|
211
|
+
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="width:600px;height:200px;">
|
|
212
|
+
<v:fill type="tile" src="[image-url]" color="#1A1A1A"/>
|
|
213
|
+
<v:textbox inset="0,0,0,0">
|
|
214
|
+
<![endif]-->
|
|
215
|
+
<!-- content here -->
|
|
216
|
+
<!--[if gte mso 9]>
|
|
217
|
+
</v:textbox>
|
|
218
|
+
</v:rect>
|
|
219
|
+
<![endif]-->
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Use this only when background images are critical to the design.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Pre-Send QA Checklist
|
|
227
|
+
|
|
228
|
+
- [ ] All styles inline -- no `<style>` blocks (except optional `<head>` media queries)
|
|
229
|
+
- [ ] All `<table>` have `cellpadding="0" cellspacing="0" border="0"`
|
|
230
|
+
- [ ] Images have `alt`, `border="0"`, `display:block`
|
|
231
|
+
- [ ] CTA button uses table+td with `bgcolor=` attribute
|
|
232
|
+
- [ ] Max-width 600px enforced on container
|
|
233
|
+
- [ ] Footer has unsubscribe link
|
|
234
|
+
- [ ] No `flexbox`, `grid`, `position`, `float`, CSS variables in inline styles
|
|
235
|
+
- [ ] Test in: Gmail web, Gmail app (iOS/Android), Apple Mail, Outlook 2016+
|