themes-editorial/templates/email/editorial.ninjatpl
Alex Dunmow a66113fce0 feat(editorial): Wave A theme lane (WO-TF-017) — personal essayist
Deliver the full Wave A contract for the editorial theme (personal
essayist / independent newsletter persona).

- 49 mandatory builtin overrides in templates/overrides/editorial/,
  re-skinned from the frozen builtins: hairline rules, small-caps labels,
  drop caps, narrow reading measure, oxblood accent. All content fields,
  provider fields, custom tags ({% img %}/{% form %}/{% signup_form %}),
  hx wiring, navbar drawer JS and auth/contact form wiring preserved
  verbatim; legacy button/card field reads reconciled (link/style/label,
  media/text).
- 7 page templates (default, full-width, landing, article, blog-index,
  contact, auth); article is the reading centrepiece with drop-cap opener,
  marginalia rail and a CSS-only reading-progress underline. All set the
  html.dark class and route body font through var(--font-body).
- Block rework: masthead/byline/pullquote/section_label/colophon deleted
  (now overrides of navbar/post-metadata/quote/divider/footer). Persona
  blocks: dropcap_intro, marginalia, reading_list, field_notes.
- 4 presets, all mode "both", book-paper light + sepia-on-charcoal dark.
- Bundled Playfair Display + Source Serif 4 (OFL, latin subset) in
  assets/fonts with license record; fonts.json populated; every
  font-family via var(--font-heading|body|mono, fallback).
- Themed email-safe wrapper (tables, inline styles, literal fonts).
- Master pages + seed demo site (home, about, blog with 3 essays,
  contact with form + data table + row_inserted email-admins workflow,
  login) in essayist voice.
- required_icon_packs=["lucide"]; RECOMMENDED_FONTS/ICONS updated.

Motion tier: CSS-first (progress underline, marginalia fade-in;
prefers-reduced-motion honored). Verified: make + ninja plugin verify +
check-safety all exit 0. Visual quality UNVERIFIED until Wave B.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 11:22:07 +08:00

75 lines
4.2 KiB
Plaintext

<!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="x-apple-disable-message-reformatting">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
<title>{{ site_name }}</title>
<style type="text/css">
body, table, td, p, a, li, blockquote {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
img { -ms-interpolation-mode: bicubic; border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; }
body { margin: 0 !important; padding: 0 !important; width: 100% !important; }
a[x-apple-data-detectors] { color: inherit !important; text-decoration: none !important; }
@media only screen and (max-width: 620px) {
.email-container { width: 100% !important; max-width: 100% !important; }
.content-padding { padding-left: 24px !important; padding-right: 24px !important; }
}
</style>
</head>
<body style="background-color: {{ colors.background|default:"#f2ebda" }}; margin: 0; padding: 0; font-family: 'Source Serif 4', 'Source Serif Pro', Georgia, serif;">
{% if preview_text %}<div style="display: none; max-height: 0; overflow: hidden; mso-hide: all;">{{ preview_text }}</div>{% endif %}
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr>
<td align="center" style="padding: 48px 10px; background-color: {{ colors.background|default:"#f2ebda" }};">
<table role="presentation" class="email-container" width="580" cellspacing="0" cellpadding="0" border="0" style="max-width: 580px; background-color: {{ colors.card|default:"#f7f2e6" }}; border: 1px solid {{ colors.border|default:"#d6cdbc" }};">
<!-- Masthead -->
<tr>
<td align="center" style="padding: 32px 40px 16px 40px;">
{% if logo_url %}<img src="{{ logo_url }}" alt="{{ site_name }}" style="max-height: 48px; width: auto; display: block;">{% elif site_name %}<h1 style="margin: 0; font-family: 'Playfair Display', Georgia, serif; font-style: italic; font-weight: 900; font-size: 34px; color: {{ colors.foreground|default:"#211a14" }}; letter-spacing: -0.02em;">{{ site_name }}</h1>{% endif %}
</td>
</tr>
<!-- Hairline rule -->
<tr>
<td style="padding: 0 40px;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td style="border-top: 1px solid {{ colors.border|default:"#d6cdbc" }}; font-size: 0; line-height: 0; height: 1px;">&nbsp;</td></tr></table>
</td>
</tr>
<!-- Body -->
<tr>
<td class="content-padding" style="padding: 32px 48px 40px 48px; color: {{ colors.foreground|default:"#211a14" }}; font-size: 16px; line-height: 1.7; font-family: 'Source Serif 4', 'Source Serif Pro', Georgia, serif;">{{ body|safe }}</td>
</tr>
<!-- Footer -->
<tr>
<td style="padding: 24px 48px 40px 48px; border-top: 1px solid {{ colors.border|default:"#d6cdbc" }};">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr>
<td align="center" style="font-family: 'Source Serif 4', Georgia, serif; font-size: 12px; color: {{ colors.mutedForeground|default:"#6b6154" }}; text-transform: uppercase; letter-spacing: 0.12em;">
<p style="margin: 0 0 8px;">{{ site_name }}</p>
{% if site_url %}<p style="margin: 0 0 8px;"><a href="{{ site_url }}" style="color: {{ colors.accent|default:"#8a2e28" }}; text-decoration: none; border-bottom: 1px solid {{ colors.accent|default:"#8a2e28" }};">{{ site_url }}</a></p>{% endif %}
{% if unsubscribe_url %}<p style="margin: 12px 0 0; font-size: 11px;"><a href="{{ unsubscribe_url }}" style="color: {{ colors.mutedForeground|default:"#6b6154" }}; text-decoration: underline;">Unsubscribe</a></p>{% endif %}
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>