@seliseblocks/mailcraft 0.2.15 → 0.2.18

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/DOCS.md +70 -67
  3. package/README.md +8 -8
  4. package/README.md.txt +8 -8
  5. package/dist/mailcraft-editor.bundle.js +86 -78
  6. package/dist/mailcraft-editor.bundle.js.map +3 -3
  7. package/examples/templates/activate-your-account.html +1 -1
  8. package/examples/templates/back-in-stock.html +4 -4
  9. package/examples/templates/cart-left-behind.html +3 -3
  10. package/examples/templates/community-giveaway.html +3 -3
  11. package/examples/templates/frontend-futures-invite.html +3 -3
  12. package/examples/templates/give-25-get-25.html +2 -2
  13. package/examples/templates/invoice-paid.html +3 -3
  14. package/examples/templates/meet-nova-launch.html +7 -7
  15. package/examples/templates/mega-weekend-sale.html +1 -1
  16. package/examples/templates/order-confirmed.html +6 -6
  17. package/examples/templates/rate-your-headphones.html +3 -3
  18. package/examples/templates/reset-your-password.html +1 -1
  19. package/examples/templates/thankyou-promo-code.html +3 -3
  20. package/examples/templates/the-sunday-brief.html +4 -4
  21. package/examples/templates/welcome-to-your-workspace.html +4 -4
  22. package/examples/templates/your-password-was-changed.html +2 -2
  23. package/examples/templates/your-signin-code.html +1 -1
  24. package/examples/vanilla.html +63 -63
  25. package/package.json +1 -1
  26. package/src/core/binder.js +10 -0
  27. package/src/core/blocks.js +2 -2
  28. package/src/core/editor-core.js +195 -6
  29. package/src/core/export.js +311 -22
  30. package/src/core/i18n/ar.js +2 -0
  31. package/src/core/i18n/bg.js +2 -0
  32. package/src/core/i18n/bn.js +2 -0
  33. package/src/core/i18n/ca.js +2 -0
  34. package/src/core/i18n/cs.js +2 -0
  35. package/src/core/i18n/da.js +2 -0
  36. package/src/core/i18n/de-CH.js +2 -0
  37. package/src/core/i18n/de.js +2 -0
  38. package/src/core/i18n/dz.js +2 -0
  39. package/src/core/i18n/el.js +2 -0
  40. package/src/core/i18n/en.js +2 -0
  41. package/src/core/i18n/es.js +2 -0
  42. package/src/core/i18n/et.js +2 -0
  43. package/src/core/i18n/fi.js +2 -0
  44. package/src/core/i18n/fr.js +2 -0
  45. package/src/core/i18n/hr.js +2 -0
  46. package/src/core/i18n/hu.js +2 -0
  47. package/src/core/i18n/it.js +2 -0
  48. package/src/core/i18n/lt.js +2 -0
  49. package/src/core/i18n/lv.js +2 -0
  50. package/src/core/i18n/nb.js +2 -0
  51. package/src/core/i18n/nl.js +2 -0
  52. package/src/core/i18n/pl.js +2 -0
  53. package/src/core/i18n/pt.js +2 -0
  54. package/src/core/i18n/ro.js +2 -0
  55. package/src/core/i18n/ru.js +2 -0
  56. package/src/core/i18n/sk.js +2 -0
  57. package/src/core/i18n/sl.js +2 -0
  58. package/src/core/i18n/sv.js +2 -0
  59. package/src/core/i18n/tr.js +2 -0
  60. package/src/core/i18n/uk.js +2 -0
  61. package/src/core/import-html.js +390 -20
  62. package/src/core/layout-style.js +25 -0
  63. package/src/core/sanitize.js +4 -1
  64. package/src/core/theme.js +22 -1
  65. package/src/mailcraft-editor.js +14 -2
  66. package/src/render/block-body.js +129 -17
  67. package/src/render/canvas.js +35 -6
  68. package/src/render/fields.js +19 -0
  69. package/src/render/screenshot.js +40 -5
  70. package/src/render/story.js +46 -18
  71. package/src/render/style.js +1 -1
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Blocks MailCraft live demo</title>
6
+ <title>Blocks MailCraft: live demo</title>
7
7
  <meta name="description" content="A host application embedding the Blocks MailCraft email editor: host-owned theme, locale, brand colour, typography and template gallery." />
8
8
  <link rel="icon" href="../assets/brand/icon.svg" media="(prefers-color-scheme: light)">
9
9
  <link rel="icon" href="../assets/brand/icon-white.svg" media="(prefers-color-scheme: dark)">
@@ -230,7 +230,7 @@
230
230
  <td align="center" style="padding:34px 36px 8px;">
231
231
  <p style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:11px; font-weight:bold; letter-spacing:0.2em; text-transform:uppercase; color:#0065b3;">Account activation</p>
232
232
  <h1 style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:26px; line-height:1.25; color:#10243c;">One last step, {{ first_name }}</h1>
233
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.65; color:#3f5063;">Welcome to {{ company }}. Tap the button below to activate your account &mdash; it takes less than ten seconds.</p>
233
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.65; color:#3f5063;">Welcome to {{ company }}. Tap the button below to activate your account; it takes less than ten seconds.</p>
234
234
  </td>
235
235
  </tr>
236
236
  <tr>
@@ -270,7 +270,7 @@
270
270
  <html>
271
271
  <head>
272
272
  <meta charset="utf-8" />
273
- <title>Back in stock the one you wanted</title>
273
+ <title>Back in stock: the one you wanted</title>
274
274
  </head>
275
275
  <body style="margin:0; padding:0; background-color:#faf7f2;">
276
276
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#faf7f2;">
@@ -281,7 +281,7 @@
281
281
  <td align="center" style="padding:36px 36px 8px;">
282
282
  <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:12px; font-weight:bold; letter-spacing:0.2em; text-transform:uppercase; color:#b85c38;">Back in stock</p>
283
283
  <h1 style="margin:0 0 10px; font-family:Georgia, 'Times New Roman', serif; font-size:28px; line-height:1.25; color:#29241d;">Good news, {{ first_name }}</h1>
284
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.65; color:#5d574c;">The Terracotta Trainer in your size is back &mdash; and your watchlist held your place in line.</p>
284
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.65; color:#5d574c;">The Terracotta Trainer in your size is back, and your watchlist held your place in line.</p>
285
285
  </td>
286
286
  </tr>
287
287
  <tr>
@@ -289,7 +289,7 @@
289
289
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#f6f1e9; ">
290
290
  <tr>
291
291
  <td width="38%" valign="middle" align="center" style="padding:22px 18px;">
292
- <img src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22340%22%20height%3D%22340%22%20viewBox%3D%220%200%20340%20340%22%3E%20%3Crect%20width%3D%22340%22%20height%3D%22340%22%20fill%3D%22%23b85c38%22%2F%3E%20%3Ccircle%20cx%3D%22264%22%20cy%3D%2272%22%20r%3D%2242%22%20fill%3D%22%23c96f4a%22%2F%3E%20%3Ccircle%20cx%3D%2256%22%20cy%3D%22290%22%20r%3D%2254%22%20fill%3D%22%23a9502e%22%2F%3E%20%3Cellipse%20cx%3D%22172%22%20cy%3D%22252%22%20rx%3D%22120%22%20ry%3D%2213%22%20fill%3D%22%238f4526%22%2F%3E%20%3Cpath%20d%3D%22M52%20222%20Q52%20242%2076%20242%20L268%20242%20Q288%20242%20288%20224%20L288%20216%20Q288%20208%20278%20206%20L62%20206%20Q52%20208%2052%20222%20Z%22%20fill%3D%22%23f3e9dc%22%2F%3E%20%3Cpath%20d%3D%22M62%20208%20Q60%20152%2096%20140%20Q128%20130%20148%20150%20Q170%20172%20210%20178%20L262%20188%20Q286%20194%20286%20208%20Z%22%20fill%3D%22%23e8d9c4%22%2F%3E%20%3Cpath%20d%3D%22M148%20150%20Q170%20172%20210%20178%20L262%20188%20Q286%20194%20286%20208%20L196%20208%20Q170%20198%20156%20174%20Z%22%20fill%3D%22%23caa27f%22%2F%3E%20%3Cpath%20d%3D%22M62%20208%20Q61%20170%2082%20152%20Q68%20172%2070%20208%20Z%22%20fill%3D%22%23d9c3a6%22%2F%3E%20%3Cg%20stroke%3D%22%238f5a3a%22%20stroke-width%3D%226%22%20stroke-linecap%3D%22round%22%3E%20%3Cline%20x1%3D%22112%22%20y1%3D%22152%22%20x2%3D%22140%22%20y2%3D%22166%22%2F%3E%20%3Cline%20x1%3D%22106%22%20y1%3D%22168%22%20x2%3D%22136%22%20y2%3D%22182%22%2F%3E%20%3Cline%20x1%3D%22102%22%20y1%3D%22184%22%20x2%3D%22132%22%20y2%3D%22198%22%2F%3E%20%3C%2Fg%3E%20%3Crect%20x%3D%2258%22%20y%3D%22230%22%20width%3D%22224%22%20height%3D%226%22%20rx%3D%223%22%20fill%3D%22%23d9c3a6%22%2F%3E%20%3C%2Fsvg%3E" width="170" alt="Terracotta Trainer suede and canvas sneaker" style="display:block; width:170px; max-width:100%; height:auto;" />
292
+ <img src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22340%22%20height%3D%22340%22%20viewBox%3D%220%200%20340%20340%22%3E%20%3Crect%20width%3D%22340%22%20height%3D%22340%22%20fill%3D%22%23b85c38%22%2F%3E%20%3Ccircle%20cx%3D%22264%22%20cy%3D%2272%22%20r%3D%2242%22%20fill%3D%22%23c96f4a%22%2F%3E%20%3Ccircle%20cx%3D%2256%22%20cy%3D%22290%22%20r%3D%2254%22%20fill%3D%22%23a9502e%22%2F%3E%20%3Cellipse%20cx%3D%22172%22%20cy%3D%22252%22%20rx%3D%22120%22%20ry%3D%2213%22%20fill%3D%22%238f4526%22%2F%3E%20%3Cpath%20d%3D%22M52%20222%20Q52%20242%2076%20242%20L268%20242%20Q288%20242%20288%20224%20L288%20216%20Q288%20208%20278%20206%20L62%20206%20Q52%20208%2052%20222%20Z%22%20fill%3D%22%23f3e9dc%22%2F%3E%20%3Cpath%20d%3D%22M62%20208%20Q60%20152%2096%20140%20Q128%20130%20148%20150%20Q170%20172%20210%20178%20L262%20188%20Q286%20194%20286%20208%20Z%22%20fill%3D%22%23e8d9c4%22%2F%3E%20%3Cpath%20d%3D%22M148%20150%20Q170%20172%20210%20178%20L262%20188%20Q286%20194%20286%20208%20L196%20208%20Q170%20198%20156%20174%20Z%22%20fill%3D%22%23caa27f%22%2F%3E%20%3Cpath%20d%3D%22M62%20208%20Q61%20170%2082%20152%20Q68%20172%2070%20208%20Z%22%20fill%3D%22%23d9c3a6%22%2F%3E%20%3Cg%20stroke%3D%22%238f5a3a%22%20stroke-width%3D%226%22%20stroke-linecap%3D%22round%22%3E%20%3Cline%20x1%3D%22112%22%20y1%3D%22152%22%20x2%3D%22140%22%20y2%3D%22166%22%2F%3E%20%3Cline%20x1%3D%22106%22%20y1%3D%22168%22%20x2%3D%22136%22%20y2%3D%22182%22%2F%3E%20%3Cline%20x1%3D%22102%22%20y1%3D%22184%22%20x2%3D%22132%22%20y2%3D%22198%22%2F%3E%20%3C%2Fg%3E%20%3Crect%20x%3D%2258%22%20y%3D%22230%22%20width%3D%22224%22%20height%3D%226%22%20rx%3D%223%22%20fill%3D%22%23d9c3a6%22%2F%3E%20%3C%2Fsvg%3E" width="170" alt="Terracotta Trainer, suede and canvas sneaker" style="display:block; width:170px; max-width:100%; height:auto;" />
293
293
  </td>
294
294
  <td width="62%" valign="middle" style="padding:18px 18px 18px 6px;">
295
295
  <h2 style="margin:0 0 6px; font-family:Georgia, serif; font-size:19px; color:#29241d;">Terracotta Trainer</h2>
@@ -303,7 +303,7 @@
303
303
  </tr>
304
304
  <tr>
305
305
  <td align="center" style="padding:20px 36px 8px;">
306
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:13px; color:#8b8271;">Last restock sold out in 4 days &mdash; sizes go first, pairs follow.</p>
306
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:13px; color:#8b8271;">Last restock sold out in 4 days; sizes go first, pairs follow.</p>
307
307
  </td>
308
308
  </tr>
309
309
  <tr>
@@ -347,7 +347,7 @@
347
347
  <tr>
348
348
  <td align="center" style="padding:16px 36px 6px;">
349
349
  <h1 style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:25px; line-height:1.3; color:#241b3a;">Still thinking it over, {{ first_name }}?</h1>
350
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.65; color:#574d70;">Your bag is being held for the next 48 hours &mdash; with a little thank-you for coming back.</p>
350
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.65; color:#574d70;">Your bag is being held for the next 48 hours, with a little thank-you for coming back.</p>
351
351
  </td>
352
352
  </tr>
353
353
  <tr>
@@ -364,7 +364,7 @@
364
364
  </td>
365
365
  </tr>
366
366
  <tr>
367
- <td colspan="2" style="padding:14px 16px; background-color:#faf8fd; border-top:1px solid #e7e3f2; font-family:Arial, Helvetica, sans-serif; font-size:13px; color:#574d70;">Come-back code <strong style="font-family:'Courier New', Courier, monospace; color:#7048b8;">COMEBACK15</strong> applied at checkout &mdash; 15% off this bag.</td>
367
+ <td colspan="2" style="padding:14px 16px; background-color:#faf8fd; border-top:1px solid #e7e3f2; font-family:Arial, Helvetica, sans-serif; font-size:13px; color:#574d70;">Come-back code <strong style="font-family:'Courier New', Courier, monospace; color:#7048b8;">COMEBACK15</strong> applied at checkout: 15% off this bag.</td>
368
368
  </tr>
369
369
  </table>
370
370
  </td>
@@ -372,7 +372,7 @@
372
372
  <tr>
373
373
  <td align="center" style="padding:22px 36px 6px;">
374
374
  <a href="https://example.com/cart" style="display:inline-block; background-color:#7048b8; color:#ffffff; font-family:Arial, Helvetica, sans-serif; font-size:15px; font-weight:bold; text-decoration:none; padding:14px 40px; ">Finish my order</a>
375
- <p style="margin:12px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; color:#9c92b8;">Held until Friday, 18:00 &mdash; after that the bag returns to the shelf.</p>
375
+ <p style="margin:12px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; color:#9c92b8;">Held until Friday, 18:00; after that the bag returns to the shelf.</p>
376
376
  </td>
377
377
  </tr>
378
378
  <tr>
@@ -397,7 +397,7 @@
397
397
  <html>
398
398
  <head>
399
399
  <meta charset="utf-8" />
400
- <title>You&rsquo;re in the community giveaway</title>
400
+ <title>You&rsquo;re in: the community giveaway</title>
401
401
  </head>
402
402
  <body style="margin:0; padding:0; background-color:#0c1226;">
403
403
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#0c1226;">
@@ -420,8 +420,8 @@
420
420
  <tr>
421
421
  <td align="center" style="padding:36px 36px 8px;">
422
422
  <p style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:12px; font-weight:bold; letter-spacing:0.22em; text-transform:uppercase; color:#38bdf8;">The community giveaway</p>
423
- <h1 style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:34px; line-height:1.15; color:#ffffff;">One year free &mdash;<br />for you and a friend</h1>
424
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.65; color:#aeb8d8;">We turned five this month. To celebrate, five lucky members win a free year &mdash; and each brings a friend along. Entry takes one click, {{ first_name }}.</p>
423
+ <h1 style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:34px; line-height:1.15; color:#ffffff;">One year free,<br />for you and a friend</h1>
424
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.65; color:#aeb8d8;">We turned five this month. To celebrate, five lucky members win a free year, and each brings a friend along. Entry takes one click, {{ first_name }}.</p>
425
425
  </td>
426
426
  </tr>
427
427
  <tr>
@@ -480,7 +480,7 @@
480
480
  <html>
481
481
  <head>
482
482
  <meta charset="utf-8" />
483
- <title>You&rsquo;re invited Frontend Futures, 24 Sept</title>
483
+ <title>You&rsquo;re invited: Frontend Futures, 24 Sept</title>
484
484
  </head>
485
485
  <body style="margin:0; padding:0; background-color:#0e0c1a;">
486
486
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#0e0c1a;">
@@ -520,12 +520,12 @@
520
520
  </tr>
521
521
  <tr>
522
522
  <td style="padding:26px 44px 6px;">
523
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.7; color:#b3a9d6;">{{ first_name }}, one evening, seven short talks, zero sales pitches &mdash; view transitions, state machines, and what accessibility looks like from the inside. Followed by drinks and argumentative dessert.</p>
523
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.7; color:#b3a9d6;">{{ first_name }}, one evening, seven short talks, zero sales pitches: view transitions, state machines, and what accessibility looks like from the inside. Followed by drinks and argumentative dessert.</p>
524
524
  </td>
525
525
  </tr>
526
526
  <tr>
527
527
  <td align="center" style="padding:24px 36px 8px;">
528
- <a href="https://example.com/events/frontend-futures" style="display:inline-block; background-color:#a48ef0; color:#171332; font-family:Arial, Helvetica, sans-serif; font-size:15px; font-weight:bold; text-decoration:none; padding:14px 44px; ">Reserve a seat &mdash; free</a>
528
+ <a href="https://example.com/events/frontend-futures" style="display:inline-block; background-color:#a48ef0; color:#171332; font-family:Arial, Helvetica, sans-serif; font-size:15px; font-weight:bold; text-decoration:none; padding:14px 44px; ">Reserve a seat (free)</a>
529
529
  <p style="margin:12px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; color:#8f83b8;">The Atrium, 4 Harbour Lane &middot; seats are first come, first served</p>
530
530
  </td>
531
531
  </tr>
@@ -562,7 +562,7 @@
562
562
  <td align="center" style="background-color:#1e7a4f; padding:30px 32px 26px; ">
563
563
  <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:12px; font-weight:bold; letter-spacing:0.22em; text-transform:uppercase; color:#cdeeda;">The {{ company }} referral programme</p>
564
564
  <h1 style="margin:0 0 8px; font-family:Arial, Helvetica, sans-serif; font-size:36px; line-height:1.1; color:#ffffff;">Give $25 &middot; Get $25</h1>
565
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.5; color:#d9efe2;">You both win &mdash; they save on their first order, you get credit when it ships.</p>
565
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.5; color:#d9efe2;">You both win: they save on their first order, you get credit when it ships.</p>
566
566
  </td>
567
567
  </tr>
568
568
  <tr>
@@ -607,7 +607,7 @@
607
607
  </tr>
608
608
  <tr>
609
609
  <td align="center" style="padding:12px 36px 32px;">
610
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:11.5px; line-height:1.6; color:#6f9784;">No cap on rewards &mdash; refer three friends, get $75. Sent to {{ email }}.<br /><a href="{{ unsubscribe_url }}" style="color:#6f9784;">Unsubscribe</a> &middot; <a href="https://example.com/preferences" style="color:#6f9784;">Preferences</a></p>
610
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:11.5px; line-height:1.6; color:#6f9784;">No cap on rewards; refer three friends, get $75. Sent to {{ email }}.<br /><a href="{{ unsubscribe_url }}" style="color:#6f9784;">Unsubscribe</a> &middot; <a href="https://example.com/preferences" style="color:#6f9784;">Preferences</a></p>
611
611
  </td>
612
612
  </tr>
613
613
  </table>
@@ -622,7 +622,7 @@
622
622
  <html>
623
623
  <head>
624
624
  <meta charset="utf-8" />
625
- <title>Invoice paid #INV-2051</title>
625
+ <title>Invoice paid: #INV-2051</title>
626
626
  </head>
627
627
  <body style="margin:0; padding:0; background-color:#f4f6f9;">
628
628
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#f4f6f9;">
@@ -643,7 +643,7 @@
643
643
  <td style="padding:18px 36px 8px;">
644
644
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#e9f7ee; ">
645
645
  <tr>
646
- <td style="padding:14px 18px; font-family:Arial, Helvetica, sans-serif; font-size:14px; font-weight:bold; color:#1e7a3c;">&#10004; &nbsp;Paid in full &mdash; thank you, {{ first_name }}</td>
646
+ <td style="padding:14px 18px; font-family:Arial, Helvetica, sans-serif; font-size:14px; font-weight:bold; color:#1e7a3c;">&#10004; &nbsp;Paid in full. Thank you, {{ first_name }}</td>
647
647
  </tr>
648
648
  </table>
649
649
  </td>
@@ -656,7 +656,7 @@
656
656
  <td align="right" style="padding:12px 18px; border-bottom:1px solid #e2e8f0; font-family:Arial, Helvetica, sans-serif; font-size:11px; font-weight:bold; letter-spacing:0.12em; text-transform:uppercase; color:#8194a7;">Amount</td>
657
657
  </tr>
658
658
  <tr>
659
- <td style="padding:14px 18px; border-bottom:1px solid #e2e8f0; font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#14324f;">Pro plan &mdash; monthly</td>
659
+ <td style="padding:14px 18px; border-bottom:1px solid #e2e8f0; font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#14324f;">Pro plan, monthly</td>
660
660
  <td align="right" style="padding:14px 18px; border-bottom:1px solid #e2e8f0; font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#14324f;">$49.00</td>
661
661
  </tr>
662
662
  <tr>
@@ -701,7 +701,7 @@
701
701
  <html>
702
702
  <head>
703
703
  <meta charset="utf-8" />
704
- <title>Meet Nova our biggest release yet</title>
704
+ <title>Meet Nova: our biggest release yet</title>
705
705
  </head>
706
706
  <body style="margin:0; padding:0; background-color:#0b1020;">
707
707
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#0b1020;">
@@ -712,18 +712,18 @@
712
712
  <td align="center" style="background-color:#0065b3; padding:34px 32px 30px; ">
713
713
  <p style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:12px; font-weight:bold; letter-spacing:0.22em; text-transform:uppercase; color:#bfdbfe;">New from {{ company }}</p>
714
714
  <h1 style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:38px; line-height:1.1; color:#ffffff;">Meet Nova</h1>
715
- <p style="margin:10px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.5; color:#dbeafe;">Our biggest release yet &mdash; and it&rsquo;s already in your account.</p>
715
+ <p style="margin:10px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.5; color:#dbeafe;">Our biggest release yet, and it&rsquo;s already in your account.</p>
716
716
  </td>
717
717
  </tr>
718
718
  <tr>
719
719
  <td style="padding:0;">
720
- <img src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22600%22%20height%3D%22230%22%20viewBox%3D%220%200%20600%20230%22%3E%20%3Crect%20width%3D%22600%22%20height%3D%22230%22%20fill%3D%22%230b1020%22%2F%3E%20%3Ccircle%20cx%3D%22524%22%20cy%3D%2230%22%20r%3D%2296%22%20fill%3D%22%23111832%22%2F%3E%20%3Ccircle%20cx%3D%2260%22%20cy%3D%22216%22%20r%3D%2280%22%20fill%3D%22%23111832%22%2F%3E%20%3Crect%20x%3D%22150%22%20y%3D%2240%22%20width%3D%22300%22%20height%3D%22172%22%20rx%3D%2212%22%20fill%3D%22%2316203c%22%2F%3E%20%3Cpath%20d%3D%22M150%2052%20Q150%2040%20162%2040%20L438%2040%20Q450%2040%20450%2052%20L450%2072%20L150%2072%20Z%22%20fill%3D%22%231c2848%22%2F%3E%20%3Ccircle%20cx%3D%22172%22%20cy%3D%2256%22%20r%3D%225%22%20fill%3D%22%2358a8e3%22%2F%3E%20%3Ccircle%20cx%3D%22190%22%20cy%3D%2256%22%20r%3D%225%22%20fill%3D%22%233b6ea5%22%2F%3E%20%3Ccircle%20cx%3D%22208%22%20cy%3D%2256%22%20r%3D%225%22%20fill%3D%22%2328497a%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%2290%22%20width%3D%22122%22%20height%3D%2214%22%20rx%3D%227%22%20fill%3D%22%232b3d69%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%22118%22%20width%3D%22264%22%20height%3D%2210%22%20rx%3D%225%22%20fill%3D%22%2322335c%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%22136%22%20width%3D%22236%22%20height%3D%2210%22%20rx%3D%225%22%20fill%3D%22%2322335c%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%22154%22%20width%3D%22250%22%20height%3D%2210%22%20rx%3D%225%22%20fill%3D%22%2322335c%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%22180%22%20width%3D%2298%22%20height%3D%2220%22%20rx%3D%2210%22%20fill%3D%22%2358a8e3%22%2F%3E%20%3Cpath%20d%3D%22M470%2084%20L479%20108%20L502%20117%20L479%20126%20L470%20150%20L461%20126%20L438%20117%20L461%20108%20Z%22%20fill%3D%22%23d9e9f9%22%2F%3E%20%3Cpath%20d%3D%22M502%2056%20L506%2067%20L517%2071%20L506%2075%20L502%2086%20L498%2075%20L487%2071%20L498%2067%20Z%22%20fill%3D%22%2358a8e3%22%2F%3E%20%3C%2Fsvg%3E" width="600" alt="Nova the new workspace" style="display:block; width:100%; max-width:600px; height:auto;" />
720
+ <img src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22600%22%20height%3D%22230%22%20viewBox%3D%220%200%20600%20230%22%3E%20%3Crect%20width%3D%22600%22%20height%3D%22230%22%20fill%3D%22%230b1020%22%2F%3E%20%3Ccircle%20cx%3D%22524%22%20cy%3D%2230%22%20r%3D%2296%22%20fill%3D%22%23111832%22%2F%3E%20%3Ccircle%20cx%3D%2260%22%20cy%3D%22216%22%20r%3D%2280%22%20fill%3D%22%23111832%22%2F%3E%20%3Crect%20x%3D%22150%22%20y%3D%2240%22%20width%3D%22300%22%20height%3D%22172%22%20rx%3D%2212%22%20fill%3D%22%2316203c%22%2F%3E%20%3Cpath%20d%3D%22M150%2052%20Q150%2040%20162%2040%20L438%2040%20Q450%2040%20450%2052%20L450%2072%20L150%2072%20Z%22%20fill%3D%22%231c2848%22%2F%3E%20%3Ccircle%20cx%3D%22172%22%20cy%3D%2256%22%20r%3D%225%22%20fill%3D%22%2358a8e3%22%2F%3E%20%3Ccircle%20cx%3D%22190%22%20cy%3D%2256%22%20r%3D%225%22%20fill%3D%22%233b6ea5%22%2F%3E%20%3Ccircle%20cx%3D%22208%22%20cy%3D%2256%22%20r%3D%225%22%20fill%3D%22%2328497a%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%2290%22%20width%3D%22122%22%20height%3D%2214%22%20rx%3D%227%22%20fill%3D%22%232b3d69%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%22118%22%20width%3D%22264%22%20height%3D%2210%22%20rx%3D%225%22%20fill%3D%22%2322335c%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%22136%22%20width%3D%22236%22%20height%3D%2210%22%20rx%3D%225%22%20fill%3D%22%2322335c%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%22154%22%20width%3D%22250%22%20height%3D%2210%22%20rx%3D%225%22%20fill%3D%22%2322335c%22%2F%3E%20%3Crect%20x%3D%22168%22%20y%3D%22180%22%20width%3D%2298%22%20height%3D%2220%22%20rx%3D%2210%22%20fill%3D%22%2358a8e3%22%2F%3E%20%3Cpath%20d%3D%22M470%2084%20L479%20108%20L502%20117%20L479%20126%20L470%20150%20L461%20126%20L438%20117%20L461%20108%20Z%22%20fill%3D%22%23d9e9f9%22%2F%3E%20%3Cpath%20d%3D%22M502%2056%20L506%2067%20L517%2071%20L506%2075%20L502%2086%20L498%2075%20L487%2071%20L498%2067%20Z%22%20fill%3D%22%2358a8e3%22%2F%3E%20%3C%2Fsvg%3E" width="600" alt="Nova, the new workspace" style="display:block; width:100%; max-width:600px; height:auto;" />
721
721
  </td>
722
722
  </tr>
723
723
  <tr>
724
724
  <td align="center" style="padding:32px 36px 6px;">
725
725
  <h2 style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:21px; line-height:1.3; color:#ffffff;">Everything you asked for, in one update</h2>
726
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.7; color:#aebad6;">Hi {{ first_name }} &mdash; over 4,000 of you shaped this release. Nova rebuilds the parts that slowed you down and adds the three things you asked for most.</p>
726
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.7; color:#aebad6;">Hi {{ first_name }}: over 4,000 of you shaped this release. Nova rebuilds the parts that slowed you down and adds the three things you asked for most.</p>
727
727
  </td>
728
728
  </tr>
729
729
  <tr>
@@ -733,7 +733,7 @@
733
733
  <td width="33%" valign="top" align="center" style="padding:0 8px;">
734
734
  <table role="presentation" cellpadding="0" cellspacing="0" style="background-color:#1c2848; "><tr><td align="center" style="padding:12px 16px; font-family:Arial, Helvetica, sans-serif; font-size:15px; font-weight:bold; color:#58a8e3;">2&times;</td></tr></table>
735
735
  <h3 style="margin:10px 0 6px; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; color:#ffffff;">Faster</h3>
736
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; line-height:1.55; color:#8f9cbd;">A new engine under the hood &mdash; big projects open instantly.</p>
736
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; line-height:1.55; color:#8f9cbd;">A new engine under the hood; big projects open instantly.</p>
737
737
  </td>
738
738
  <td width="34%" valign="top" align="center" style="padding:0 8px;">
739
739
  <table role="presentation" cellpadding="0" cellspacing="0" style="background-color:#1c2848; "><tr><td align="center" style="padding:12px 16px; font-family:Arial, Helvetica, sans-serif; font-size:15px; font-weight:bold; color:#58a8e3;">Smart</td></tr></table>
@@ -743,7 +743,7 @@
743
743
  <td width="33%" valign="top" align="center" style="padding:0 8px;">
744
744
  <table role="presentation" cellpadding="0" cellspacing="0" style="background-color:#1c2848; "><tr><td align="center" style="padding:12px 16px; font-family:Arial, Helvetica, sans-serif; font-size:15px; font-weight:bold; color:#58a8e3;">100%</td></tr></table>
745
745
  <h3 style="margin:10px 0 6px; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; color:#ffffff;">Private</h3>
746
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; line-height:1.55; color:#8f9cbd;">Your data stays yours &mdash; encrypted, never trained on.</p>
746
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; line-height:1.55; color:#8f9cbd;">Your data stays yours: encrypted, never trained on.</p>
747
747
  </td>
748
748
  </tr>
749
749
  </table>
@@ -752,7 +752,7 @@
752
752
  <tr>
753
753
  <td align="center" style="padding:28px 36px 8px;">
754
754
  <a href="https://example.com/nova" style="display:inline-block; background-color:#58a8e3; color:#0b1020; font-family:Arial, Helvetica, sans-serif; font-size:15px; font-weight:bold; text-decoration:none; padding:14px 40px; ">Try Nova today</a>
755
- <p style="margin:12px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; color:#8f9cbd;">Free for every current customer &mdash; nothing to buy, nothing to migrate.</p>
755
+ <p style="margin:12px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; color:#8f9cbd;">Free for every current customer: nothing to buy, nothing to migrate.</p>
756
756
  </td>
757
757
  </tr>
758
758
  <tr>
@@ -777,7 +777,7 @@
777
777
  <html>
778
778
  <head>
779
779
  <meta charset="utf-8" />
780
- <title>MEGA weekend 50% off everything</title>
780
+ <title>MEGA weekend: 50% off everything</title>
781
781
  </head>
782
782
  <body style="margin:0; padding:0; background-color:#ffffff;">
783
783
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#ffffff;">
@@ -846,8 +846,8 @@
846
846
  <tr>
847
847
  <td style="padding:32px 36px 6px;">
848
848
  <p style="margin:0 0 8px; font-family:Arial, Helvetica, sans-serif; font-size:12px; font-weight:bold; letter-spacing:0.16em; text-transform:uppercase; color:#2f9e44;">Order confirmed</p>
849
- <h1 style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:24px; line-height:1.25; color:#1a1a1a;">Thanks, {{ first_name }} &mdash; it&rsquo;s on its way</h1>
850
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.6; color:#4a4a4a;">Order <strong>#48213</strong>, placed today. We&rsquo;ll email tracking as soon as the courier scans it &mdash; usually within one business day.</p>
849
+ <h1 style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:24px; line-height:1.25; color:#1a1a1a;">Thanks, {{ first_name }}: it&rsquo;s on its way</h1>
850
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.6; color:#4a4a4a;">Order <strong>#48213</strong>, placed today. We&rsquo;ll email tracking as soon as the courier scans it, usually within one business day.</p>
851
851
  </td>
852
852
  </tr>
853
853
  <tr>
@@ -857,7 +857,7 @@
857
857
  <td style="padding:14px 18px; border-bottom:1px solid #e6e6e2;">
858
858
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0">
859
859
  <tr>
860
- <td style="font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#1a1a1a;">Field jacket &mdash; olive, M</td>
860
+ <td style="font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#1a1a1a;">Field jacket, olive, M</td>
861
861
  <td align="right" style="font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#1a1a1a;">$148.00</td>
862
862
  </tr>
863
863
  </table>
@@ -867,7 +867,7 @@
867
867
  <td style="padding:14px 18px; border-bottom:1px solid #e6e6e2;">
868
868
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0">
869
869
  <tr>
870
- <td style="font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#1a1a1a;">Merino crew &mdash; charcoal, M</td>
870
+ <td style="font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#1a1a1a;">Merino crew, charcoal, M</td>
871
871
  <td align="right" style="font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#1a1a1a;">$85.00</td>
872
872
  </tr>
873
873
  </table>
@@ -902,8 +902,8 @@
902
902
  </tr>
903
903
  <tr>
904
904
  <td style="padding:10px 36px 30px;">
905
- <p style="margin:0 0 8px; font-family:Arial, Helvetica, sans-serif; font-size:13px; line-height:1.6; color:#4a4a4a;">Need a different size? Exchanges are free for 30 days &mdash; start one from the order page above.</p>
906
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:11.5px; line-height:1.6; color:#9a9a94;">This receipt was sent to {{ email }}. <a href="{{ unsubscribe_url }}" style="color:#9a9a94;">Unsubscribe from marketing</a> &mdash; you will still receive order emails.</p>
905
+ <p style="margin:0 0 8px; font-family:Arial, Helvetica, sans-serif; font-size:13px; line-height:1.6; color:#4a4a4a;">Need a different size? Exchanges are free for 30 days; start one from the order page above.</p>
906
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:11.5px; line-height:1.6; color:#9a9a94;">This receipt was sent to {{ email }}. <a href="{{ unsubscribe_url }}" style="color:#9a9a94;">Unsubscribe from marketing</a>; you will still receive order emails.</p>
907
907
  </td>
908
908
  </tr>
909
909
  </table>
@@ -928,7 +928,7 @@
928
928
  <tr>
929
929
  <td align="center" style="padding:36px 36px 10px;">
930
930
  <p style="margin:0 0 14px; font-family:Arial, Helvetica, sans-serif; font-size:26px; letter-spacing:0.1em; color:#e6b93c;">&#9733; &#9733; &#9733; &#9733; &#9733;</p>
931
- <h1 style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:24px; line-height:1.3; color:#16233a;">Two weeks with your headphones &mdash; how is it going?</h1>
931
+ <h1 style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:24px; line-height:1.3; color:#16233a;">Two weeks with your headphones: how is it going?</h1>
932
932
  <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; line-height:1.65; color:#435d80;">Hi {{ first_name }}, a quick one: your thoughts help the next buyer decide. It takes about a minute, and we&rsquo;d really appreciate it.</p>
933
933
  </td>
934
934
  </tr>
@@ -943,7 +943,7 @@
943
943
  <td align="center" style="padding:0 6px;"><a href="https://example.com/review/1" style="display:block; width:52px; height:52px; background-color:#f6f9fd; border:1px solid #dbe5f2; font-family:Arial, Helvetica, sans-serif; font-size:22px; line-height:52px; text-decoration:none; color:#e6b93c;">&#9733;</a></td>
944
944
  </tr>
945
945
  </table>
946
- <p style="margin:12px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:12px; color:#8194a7;">Tap a star to start &mdash; honest beats polite.</p>
946
+ <p style="margin:12px 0 0; font-family:Arial, Helvetica, sans-serif; font-size:12px; color:#8194a7;">Tap a star to start; honest beats polite.</p>
947
947
  </td>
948
948
  </tr>
949
949
  <tr>
@@ -956,7 +956,7 @@
956
956
  <td valign="middle" width="70%" style="padding:16px 16px 16px 4px;">
957
957
  <h2 style="margin:0 0 4px; font-family:Arial, Helvetica, sans-serif; font-size:15.5px; color:#16233a;">Studio Headphones MK II</h2>
958
958
  <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:13px; color:#435d80;">Order #47190 &middot; delivered 12 August</p>
959
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:13px; line-height:1.55; color:#435d80;">Review in the next 7 days and shipping on your next order is on us &mdash; good or bad.</p>
959
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:13px; line-height:1.55; color:#435d80;">Review in the next 7 days and shipping on your next order is on us, good or bad.</p>
960
960
  </td>
961
961
  </tr>
962
962
  </table>
@@ -1018,7 +1018,7 @@
1018
1018
  <td style="padding:28px 36px 8px;">
1019
1019
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#f4f8fc; ">
1020
1020
  <tr>
1021
- <td style="padding:16px 20px; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; line-height:1.65; color:#5b6d80;">This link works once and expires in 30 minutes. If you didn&rsquo;t ask for a reset, ignore this email &mdash; your current password keeps working.</td>
1021
+ <td style="padding:16px 20px; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; line-height:1.65; color:#5b6d80;">This link works once and expires in 30 minutes. If you didn&rsquo;t ask for a reset, ignore this email; your current password keeps working.</td>
1022
1022
  </tr>
1023
1023
  </table>
1024
1024
  </td>
@@ -1040,7 +1040,7 @@
1040
1040
  <html>
1041
1041
  <head>
1042
1042
  <meta charset="utf-8" />
1043
- <title>A little thank-you 20% off</title>
1043
+ <title>A little thank-you: 20% off</title>
1044
1044
  </head>
1045
1045
  <body style="margin:0; padding:0; background-color:#fdf8f3;">
1046
1046
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#fdf8f3;">
@@ -1051,7 +1051,7 @@
1051
1051
  <td align="center" style="padding:38px 36px 8px;">
1052
1052
  <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:12px; font-weight:bold; letter-spacing:0.2em; text-transform:uppercase; color:#c2762d;">A small thank-you</p>
1053
1053
  <h1 style="margin:0 0 12px; font-family:Georgia, 'Times New Roman', serif; font-size:30px; line-height:1.2; color:#2d2a24;">Here&rsquo;s 20% off, {{ first_name }}</h1>
1054
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.65; color:#5d574c;">It&rsquo;s been a year since you joined us &mdash; and that&rsquo;s worth celebrating. Here&rsquo;s a little something to mark it.</p>
1054
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.65; color:#5d574c;">It&rsquo;s been a year since you joined us, and that&rsquo;s worth celebrating. Here&rsquo;s a little something to mark it.</p>
1055
1055
  </td>
1056
1056
  </tr>
1057
1057
  <tr>
@@ -1082,7 +1082,7 @@
1082
1082
  </td>
1083
1083
  <td width="50%" valign="top" style="padding:0 0 0 10px;">
1084
1084
  <h3 style="margin:0 0 6px; font-family:Arial, Helvetica, sans-serif; font-size:14.5px; color:#2d2a24;">Stack it with sales</h3>
1085
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:13px; line-height:1.55; color:#5d574c;">Already-marked-down pieces count too &mdash; yes, really.</p>
1085
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:13px; line-height:1.55; color:#5d574c;">Already-marked-down pieces count too. Yes, really.</p>
1086
1086
  </td>
1087
1087
  </tr>
1088
1088
  </table>
@@ -1135,16 +1135,16 @@
1135
1135
  <td align="center" style="background-color:#f6f4ee; padding:36px 40px 34px; border-bottom:1px solid #e3e0d8;">
1136
1136
  <p style="margin:0 0 10px; font-family:Georgia, serif; font-size:12px; letter-spacing:0.14em; text-transform:uppercase; color:#a06b2c;">Cover story</p>
1137
1137
  <h2 style="margin:0 0 12px; font-family:Georgia, 'Times New Roman', serif; font-size:28px; line-height:1.25; color:#1c1b18;">Why the best ideas arrive before nine</h2>
1138
- <p style="margin:0 0 18px; font-family:Georgia, serif; font-size:15px; line-height:1.65; color:#3d3a33;">Hello {{ first_name }} &mdash; this week we sat down with three writers who guard their mornings like a vault. What they cut, what they kept, and the one ritual all three share.</p>
1138
+ <p style="margin:0 0 18px; font-family:Georgia, serif; font-size:15px; line-height:1.65; color:#3d3a33;">Hello {{ first_name }}. This week we sat down with three writers who guard their mornings like a vault. What they cut, what they kept, and the one ritual all three share.</p>
1139
1139
  <a href="https://example.com/issue-214" style="display:inline-block; background-color:#1c1b18; color:#f5f2ea; font-family:Georgia, serif; font-size:14px; font-weight:bold; text-decoration:none; padding:12px 26px; ">Read the full story</a>
1140
1140
  </td>
1141
1141
  </tr>
1142
1142
  <tr>
1143
1143
  <td style="padding:26px 32px 4px;">
1144
1144
  <h3 style="margin:0 0 8px; font-family:Georgia, serif; font-size:17px; color:#1c1b18;">Also worth your time</h3>
1145
- <p style="margin:0 0 10px; font-family:Georgia, serif; font-size:14px; line-height:1.6; color:#3d3a33;"><a href="https://example.com/reads/1" style="color:#a06b2c;">The quiet return of the personal website</a> &mdash; a ten-minute read on owning your corner of the internet.</p>
1146
- <p style="margin:0 0 10px; font-family:Georgia, serif; font-size:14px; line-height:1.6; color:#3d3a33;"><a href="https://example.com/reads/2" style="color:#a06b2c;">Notes on a smaller inbox</a> &mdash; what happened when we unsubscribed from everything for a month.</p>
1147
- <p style="margin:0 0 10px; font-family:Georgia, serif; font-size:14px; line-height:1.6; color:#3d3a33;"><a href="https://example.com/reads/3" style="color:#a06b2c;">Interview: the archivist of lost fonts</a> &mdash; rescuing typefaces from forgotten floppy disks.</p>
1145
+ <p style="margin:0 0 10px; font-family:Georgia, serif; font-size:14px; line-height:1.6; color:#3d3a33;"><a href="https://example.com/reads/1" style="color:#a06b2c;">The quiet return of the personal website</a>: a ten-minute read on owning your corner of the internet.</p>
1146
+ <p style="margin:0 0 10px; font-family:Georgia, serif; font-size:14px; line-height:1.6; color:#3d3a33;"><a href="https://example.com/reads/2" style="color:#a06b2c;">Notes on a smaller inbox</a>: what happened when we unsubscribed from everything for a month.</p>
1147
+ <p style="margin:0 0 10px; font-family:Georgia, serif; font-size:14px; line-height:1.6; color:#3d3a33;"><a href="https://example.com/reads/3" style="color:#a06b2c;">Interview: the archivist of lost fonts</a>: rescuing typefaces from forgotten floppy disks.</p>
1148
1148
  </td>
1149
1149
  </tr>
1150
1150
  <tr>
@@ -1195,9 +1195,9 @@
1195
1195
  <tr>
1196
1196
  <td style="padding:26px 36px 4px;">
1197
1197
  <h2 style="margin:0 0 14px; font-family:Arial, Helvetica, sans-serif; font-size:17px; color:#10243c;">Get set up in five minutes</h2>
1198
- <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.6; color:#3f5063;"><strong style="color:#0065b3;">1.</strong> &nbsp;Create your first project &mdash; a name is enough, everything else can change later.</p>
1199
- <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.6; color:#3f5063;"><strong style="color:#0065b3;">2.</strong> &nbsp;Invite your team &mdash; anyone with a {{ company }} email joins without approval.</p>
1200
- <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.6; color:#3f5063;"><strong style="color:#0065b3;">3.</strong> &nbsp;Connect your tools &mdash; two clicks each for calendar, storage and chat.</p>
1198
+ <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.6; color:#3f5063;"><strong style="color:#0065b3;">1.</strong> &nbsp;Create your first project; a name is enough, everything else can change later.</p>
1199
+ <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.6; color:#3f5063;"><strong style="color:#0065b3;">2.</strong> &nbsp;Invite your team: anyone with a {{ company }} email joins without approval.</p>
1200
+ <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.6; color:#3f5063;"><strong style="color:#0065b3;">3.</strong> &nbsp;Connect your tools: two clicks each for calendar, storage and chat.</p>
1201
1201
  </td>
1202
1202
  </tr>
1203
1203
  <tr>
@@ -1212,7 +1212,7 @@
1212
1212
  </tr>
1213
1213
  <tr>
1214
1214
  <td style="padding:12px 36px 32px;">
1215
- <p style="margin:0 0 8px; font-family:Arial, Helvetica, sans-serif; font-size:13px; line-height:1.6; color:#3f5063;">Stuck on anything? Reply to this email &mdash; a real person reads every message, usually within the hour.</p>
1215
+ <p style="margin:0 0 8px; font-family:Arial, Helvetica, sans-serif; font-size:13px; line-height:1.6; color:#3f5063;">Stuck on anything? Reply to this email; a real person reads every message, usually within the hour.</p>
1216
1216
  <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:11.5px; line-height:1.6; color:#8194a7;"><a href="{{ unsubscribe_url }}" style="color:#8194a7;">Unsubscribe</a> &middot; <a href="https://example.com/preferences" style="color:#8194a7;">Notification settings</a></p>
1217
1217
  </td>
1218
1218
  </tr>
@@ -1321,7 +1321,7 @@
1321
1321
  <td align="center" style="padding:34px 36px 8px;">
1322
1322
  <p style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:11px; font-weight:bold; letter-spacing:0.2em; text-transform:uppercase; color:#2f9e44;">Security update</p>
1323
1323
  <h1 style="margin:0 0 12px; font-family:Arial, Helvetica, sans-serif; font-size:26px; line-height:1.25; color:#10243c;">Password updated</h1>
1324
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.65; color:#3f5063;">Hi {{ first_name }}, your {{ company }} password was just changed. Everything went through &mdash; no action is needed.</p>
1324
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:1.65; color:#3f5063;">Hi {{ first_name }}, your {{ company }} password was just changed. Everything went through; no action is needed.</p>
1325
1325
  </td>
1326
1326
  </tr>
1327
1327
  <tr>
@@ -1340,7 +1340,7 @@
1340
1340
  </tr>
1341
1341
  <tr>
1342
1342
  <td style="padding:24px 36px 6px;">
1343
- <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.65; color:#3f5063;"><strong style="color:#10243c;">Wasn&rsquo;t you?</strong> Reset your password right away and reply to this email &mdash; our team will lock the account while we look into it.</p>
1343
+ <p style="margin:0 0 10px; font-family:Arial, Helvetica, sans-serif; font-size:14px; line-height:1.65; color:#3f5063;"><strong style="color:#10243c;">Wasn&rsquo;t you?</strong> Reset your password right away and reply to this email; our team will lock the account while we look into it.</p>
1344
1344
  </td>
1345
1345
  </tr>
1346
1346
  <tr>
@@ -1403,7 +1403,7 @@
1403
1403
  <td style="padding:26px 36px 8px;">
1404
1404
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#151a24; ">
1405
1405
  <tr>
1406
- <td style="padding:16px 20px; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; line-height:1.65; color:#7d8aa5;">Never share this code &mdash; not with support, not with anyone. {{ company }} will never ask for it by phone or email. If you didn&rsquo;t try to sign in, change your password right away.</td>
1406
+ <td style="padding:16px 20px; font-family:Arial, Helvetica, sans-serif; font-size:12.5px; line-height:1.65; color:#7d8aa5;">Never share this code, not with support, not with anyone. {{ company }} will never ask for it by phone or email. If you didn&rsquo;t try to sign in, change your password right away.</td>
1407
1407
  </tr>
1408
1408
  </table>
1409
1409
  </td>
@@ -1535,14 +1535,14 @@
1535
1535
  maxFilesPerDrop: 20,
1536
1536
  };
1537
1537
 
1538
- // A provider is a plain object with four methods two required. The editor
1538
+ // A provider is a plain object with four methods, two required. The editor
1539
1539
  // never fetches anything itself, so this is the whole seam between it and
1540
1540
  // whatever storage you run. Nothing about it is vendor-specific: point the
1541
1541
  // calls below at S3, a DMS, a CDN or your own API and the editor is
1542
1542
  // unchanged.
1543
1543
  //
1544
1544
  // This demo wires a real one. There is no server behind a static page, so
1545
- // the "backend" is IndexedDB in your own browser but everything the editor
1545
+ // the "backend" is IndexedDB in your own browser, but everything the editor
1546
1546
  // is allowed to see about it behaves like a service: round-trip latency,
1547
1547
  // folders and search resolved on the far side, cursor-paged listings,
1548
1548
  // uploads that are still there after a reload, deletes that stay deleted,
@@ -1551,7 +1551,7 @@
1551
1551
  //
1552
1552
  // The editor ships no files of its own: with nothing wired here the library
1553
1553
  // opens empty and stays that way until someone drops something in. Every
1554
- // file in the Assets modal is defined below host content, in host code,
1554
+ // file in the Assets modal is defined below: host content, in host code,
1555
1555
  // exactly where a real integration keeps it.
1556
1556
 
1557
1557
  // ---- the pretend backend ------------------------------------------------
@@ -1574,7 +1574,7 @@
1574
1574
 
1575
1575
  // The demo's own placeholder images, as SVG data URIs so the catalogue
1576
1576
  // needs no binaries next to this file. A real backend hands back durable
1577
- // https URLs instead see the note on `url` at the bottom.
1577
+ // https URLs instead; see the note on `url` at the bottom.
1578
1578
  const ph = (label, w, ht) => 'data:image/svg+xml;utf8,' + encodeURIComponent(
1579
1579
  '<svg xmlns="http://www.w3.org/2000/svg" width="' + w + '" height="' + ht + '">'
1580
1580
  + '<defs><pattern id="p" width="9" height="9" patternTransform="rotate(45)" patternUnits="userSpaceOnUse">'
@@ -1695,7 +1695,7 @@
1695
1695
  folders: async () => { await nap(LATENCY / 2); return FOLDERS.map((f) => ({ id: f.id, name: f.name })); },
1696
1696
 
1697
1697
  // Folder, search and paging are all resolved here, on the far side of the
1698
- // wire which is exactly why the editor stops filtering locally the
1698
+ // wire, which is exactly why the editor stops filtering locally the
1699
1699
  // moment a provider is assigned. A cursor is opaque to it: this one is an
1700
1700
  // offset, a real one is usually a continuation token.
1701
1701
  async list(q) {
@@ -1718,7 +1718,7 @@
1718
1718
 
1719
1719
  // The editor has already validated the file against `storageLimits` and
1720
1720
  // measured it, so `width`/`height` arrive filled in. Uploading from "All
1721
- // files" means no folder was chosen a backend still has to put the
1721
+ // files" means no folder was chosen; a backend still has to put the
1722
1722
  // bytes somewhere, and "Uploads" is this one's answer.
1723
1723
  async upload(file, opts) {
1724
1724
  const url = await readAsDataUrl(file);
@@ -1738,7 +1738,7 @@
1738
1738
  await drop(asset.id);
1739
1739
  },
1740
1740
 
1741
- /** Not part of the contract a console escape hatch for this demo. */
1741
+ /** Not part of the contract: a console escape hatch for this demo. */
1742
1742
  async reset() {
1743
1743
  const rows = await readAll();
1744
1744
  for (let i = 0; i < rows.length; i++) await drop(rows[i].id);
@@ -1749,7 +1749,7 @@
1749
1749
  })();
1750
1750
 
1751
1751
  // The provider itself: four thin methods over whatever the backend is. This
1752
- // is the entire integration no editor internals, no imports, no build step.
1752
+ // is the entire integration: no editor internals, no imports, no build step.
1753
1753
  const demoStorage = {
1754
1754
  folders: () => demoBackend.folders(),
1755
1755
  list: (q) => demoBackend.list(q),
@@ -1760,7 +1760,7 @@
1760
1760
 
1761
1761
  // Handy while poking at the demo: `mailcraftDemo.reset()` empties the
1762
1762
  // library, re-seeds it, and re-lists it. Re-assigning the provider is how a
1763
- // host tells the editor to start over the same call the line above makes.
1763
+ // host tells the editor to start over, the same call the line above makes.
1764
1764
  window.mailcraftDemo = {
1765
1765
  reset: () => demoBackend.reset().then(() => { editor.storageProvider = demoStorage; }),
1766
1766
  };
@@ -1772,12 +1772,12 @@
1772
1772
  // folders: () => myApi.folders(), // optional
1773
1773
  // remove: (asset) => myApi.delete(asset.id), // optional
1774
1774
  //
1775
- // each response mapped onto `{ id, name, url, folder, folderId, w, ht, size }`.
1775
+ // Each response maps onto `{ id, name, url, folder, folderId, w, ht, size }`.
1776
1776
  //
1777
1777
  // The one hard requirement is on `url`: it has to still resolve after the
1778
1778
  // campaign is sent. A URL that expires in an hour produces mail whose images
1779
1779
  // are already broken when it lands. This demo cheats it with data URIs, which
1780
- // no email client will render a real integration returns the durable https
1780
+ // no email client will render; a real integration returns the durable https
1781
1781
  // URL its CDN serves.
1782
1782
  //
1783
1783
  // README.md has the full contract.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seliseblocks/mailcraft",
3
- "version": "0.2.15",
3
+ "version": "0.2.18",
4
4
  "description": "Framework-agnostic drag-and-drop email template editor, packaged as a zero-dependency Web Component.",
5
5
  "license": "MIT",
6
6
  "author": "SELISE Digital Platforms",
@@ -2,6 +2,15 @@
2
2
  export function binder(getProps, set, core) {
3
3
  return {
4
4
  head: (label) => ({ kind: 'head', label }),
5
+ /*
6
+ * A read-only line of prose in the panel, for something the editor knows
7
+ * about the current selection that no control can express -- a `cid:`
8
+ * source that cannot resolve outside a sent message, a placeholder that
9
+ * would ship as a placeholder. It carries no key and writes nothing, so
10
+ * it never enters an undo step; `tone` picks the accent ('warn' is the
11
+ * only one used today, 'info' reads as plain muted text).
12
+ */
13
+ note: (text, tone) => ({ kind: 'note', label: String(text || ''), tone: tone === 'info' ? 'info' : 'warn' }),
5
14
  // `suggestions` (optional array of strings) renders as a datalist on the
6
15
  // input: the user picks one of the host's values or types any other.
7
16
  text: (label, key, ph, suggestions) => ({ kind: 'text', label, value: getProps()[key] ?? '', placeholder: ph || '', suggestions: Array.isArray(suggestions) && suggestions.length ? suggestions : null, onChange: (v) => set(key, v) }),
@@ -126,6 +135,7 @@ export function decorate(list) {
126
135
  const d = Object.assign({}, f, {
127
136
  key: i,
128
137
  isHead: f.kind === 'head', isArea: f.kind === 'area', isBtn: f.kind === 'btn', isSeg: f.kind === 'seg',
138
+ isNote: f.kind === 'note',
129
139
  isRange: f.kind === 'range', isToggle: f.kind === 'toggle', isSocial: f.kind === 'social', isTableGrid: f.kind === 'tablegrid', isRichLinks: f.kind === 'richLinks',
130
140
  isRangeGroup: f.kind === 'rangeGroup', isSlider: f.kind === 'slider',
131
141
  isRow: ['text', 'num', 'color', 'select'].indexOf(f.kind) > -1,
@@ -22,7 +22,7 @@ BLOCKS.push(
22
22
  { type: 'codeblock', code: 'PRE', label: 'Code', hint: 'Preformatted code sample', make: () => ({ code: 'curl -X POST https://api.example.com/v1/sends \\\n -H "Authorization: Bearer $KEY" \\\n -d campaign=mc-4471', bg: '#172033', color: '#e8e9ea', size: 12.5, pad: 14 }) },
23
23
  );
24
24
  BLOCKS.push(
25
- { type: 'box', code: 'BOX', label: 'Section box', hint: 'Styled container with free content', make: () => ({ html: '<strong style="font-size:19px;display:block;margin-bottom:6px">Section title</strong>Drop copy here, or paste markup. The box takes background, padding, border and radius.', bg: '#f8fafc', bgImage: '', border: 1, borderStyle: 'solid', lineColor: '#e2e8f0', topBorder: true, rightBorder: true, bottomBorder: true, leftBorder: true, radius: 12, pad: 22, align: 'left', minH: 0, maxW: 100, shadow: false }) },
25
+ { type: 'box', code: 'BOX', label: 'Section box', hint: 'Styled container with free content', make: () => ({ html: '<strong style="font-size:19px;display:block;margin-bottom:6px">Section title</strong>Drop copy here, or paste markup. The box takes background, padding, border and radius.', bg: '#f8fafc', bgImage: '', bgSize: 'cover', bgPos: 'center', bgRepeat: 'no-repeat', border: 1, borderStyle: 'solid', lineColor: '#e2e8f0', topBorder: true, rightBorder: true, bottomBorder: true, leftBorder: true, radius: 12, pad: 22, align: 'left', minH: 0, maxW: 100, shadow: false }) },
26
26
  { type: 'svg', code: 'SVG', label: 'Inline SVG', hint: 'Paste SVG markup', make: () => ({ code: '<svg viewBox="0 0 120 40" width="120" height="40" fill="none" stroke="#0065b3" stroke-width="1.5"><rect x="0.75" y="0.75" width="118.5" height="38.5"/><path d="M12 28l14-16 12 10 10-8 18 14"/></svg>', align: 'left', width: 100, py: 10 }) },
27
27
  );
28
28
  // Dynamic-content markers. Same contract as merge tags (variables.js): the
@@ -289,7 +289,7 @@ export function normalizeDoc(input) {
289
289
  // rebuilding the column without them silently stripped a card
290
290
  // column's paint on every loadDoc/loadTemplate, before export ever
291
291
  // saw it.
292
- ['bg', 'radius', 'padY', 'padX', 'border', 'borderStyle', 'lineColor'].forEach((k) => {
292
+ ['bg', 'bgImage', 'bgSize', 'bgPos', 'bgRepeat', 'overlay', 'radius', 'padY', 'padX', 'border', 'borderStyle', 'lineColor'].forEach((k) => {
293
293
  if (c[k] !== undefined && c[k] !== '' && c[k] !== 0) col[k] = c[k];
294
294
  });
295
295
  return col;