themes-earthen/email_wrapper.templ
Alex Dunmow 49401f1b41 initial: theme plugin earthen
Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously
an unversioned directory inside ~/src/blockninja-themes/earthen.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 14:11:27 +08:00

155 lines
6.0 KiB
Plaintext

package main
import (
"fmt"
"git.dev.alexdunmow.com/block/core/templates"
)
// earthenEmailTemplate renders the cream/moss email wrapper.
templ earthenEmailTemplate(emailCtx templates.EmailContext, body string) {
<!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>{ emailCtx.SiteSettings.SiteName }</title>
</head>
<body style={ fmt.Sprintf("background-color: %s; margin: 0; padding: 0; font-family: 'Spectral', Georgia, serif; color: %s;", earthenEmailBg(emailCtx), earthenEmailFg(emailCtx)) }>
if emailCtx.PreviewText != "" {
<div style="display: none; max-height: 0; overflow: hidden; mso-hide: all;">
{ emailCtx.PreviewText }
</div>
}
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style={ fmt.Sprintf("background-color: %s;", earthenEmailBg(emailCtx)) }>
<tr>
<td align="center" style="padding: 32px 12px;">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" border="0" style={ fmt.Sprintf("max-width: 600px; background-color: %s; border: 1px solid %s; border-radius: 12px; overflow: hidden;", earthenEmailCard(emailCtx), earthenEmailBorder(emailCtx)) }>
<tr>
<td align="center" style={ fmt.Sprintf("padding: 28px 32px; background-color: %s; color: %s;", earthenEmailPrimary(emailCtx), earthenEmailPrimaryFg(emailCtx)) }>
if emailCtx.SiteSettings.LogoURL != "" {
<img src={ emailCtx.SiteSettings.LogoURL } alt={ emailCtx.SiteSettings.SiteName } style="max-height: 44px; width: auto; display: block;"/>
} else if emailCtx.SiteSettings.SiteName != "" {
<h1 style={ fmt.Sprintf("margin: 0; font-family: 'Fraunces', 'Playfair Display', Georgia, serif; font-size: 26px; font-weight: 600; letter-spacing: -0.01em; color: %s;", earthenEmailPrimaryFg(emailCtx)) }>
{ emailCtx.SiteSettings.SiteName }
</h1>
}
</td>
</tr>
<tr>
<td style={ fmt.Sprintf("padding: 36px 40px; font-size: 16px; line-height: 1.7; color: %s; font-family: 'Spectral', Georgia, serif;", earthenEmailFg(emailCtx)) }>
@templ.Raw(body)
</td>
</tr>
<tr>
<td style={ fmt.Sprintf("padding: 24px 40px; background-color: %s; border-top: 1px solid %s;", earthenEmailMuted(emailCtx), earthenEmailBorder(emailCtx)) }>
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr>
<td align="center">
<p style={ fmt.Sprintf("margin: 0 0 8px; font-family: 'Fraunces', 'Playfair Display', Georgia, serif; font-size: 14px; font-weight: 600; color: %s;", earthenEmailFg(emailCtx)) }>
{ emailCtx.SiteSettings.SiteName }
</p>
<p style={ fmt.Sprintf("margin: 0 0 6px; font-size: 11px; color: %s;", earthenEmailMutedFg(emailCtx)) }>
Registered charity. We respect your inbox.
</p>
if emailCtx.SiteSettings.SiteURL != "" {
<p style={ fmt.Sprintf("margin: 0 0 12px; font-size: 12px; color: %s;", earthenEmailMutedFg(emailCtx)) }>
<a href={ templ.SafeURL(emailCtx.SiteSettings.SiteURL) } style={ fmt.Sprintf("color: %s; text-decoration: none; border-bottom: 1px dotted %s;", earthenEmailPrimary(emailCtx), earthenEmailPrimary(emailCtx)) }>
{ emailCtx.SiteSettings.SiteURL }
</a>
</p>
}
if emailCtx.UnsubscribeURL != "" {
<p style={ fmt.Sprintf("margin: 0; font-size: 11px; color: %s;", earthenEmailMutedFg(emailCtx)) }>
<a href={ templ.SafeURL(emailCtx.UnsubscribeURL) } style={ fmt.Sprintf("color: %s; text-decoration: underline;", earthenEmailMutedFg(emailCtx)) }>
Unsubscribe
</a>
</p>
} else {
<p style={ fmt.Sprintf("margin: 0; font-size: 11px; color: %s;", earthenEmailMutedFg(emailCtx)) }>
<a href="#" style={ fmt.Sprintf("color: %s; text-decoration: underline;", earthenEmailMutedFg(emailCtx)) }>
Unsubscribe
</a>
</p>
}
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
}
// Email colour helpers — fall back to cream/moss defaults when EmailColors are empty.
func earthenEmailBg(emailCtx templates.EmailContext) string {
if emailCtx.Colors.Background != "" {
return emailCtx.Colors.Background
}
return "#F6F1E6"
}
func earthenEmailCard(emailCtx templates.EmailContext) string {
if emailCtx.Colors.Card != "" {
return emailCtx.Colors.Card
}
return "#FCF9F2"
}
func earthenEmailFg(emailCtx templates.EmailContext) string {
if emailCtx.Colors.Foreground != "" {
return emailCtx.Colors.Foreground
}
return "#2D3A28"
}
func earthenEmailPrimary(emailCtx templates.EmailContext) string {
if emailCtx.Colors.Primary != "" {
return emailCtx.Colors.Primary
}
return "#3A5A36"
}
func earthenEmailPrimaryFg(emailCtx templates.EmailContext) string {
if emailCtx.Colors.PrimaryForeground != "" {
return emailCtx.Colors.PrimaryForeground
}
return "#F6F1E6"
}
func earthenEmailBorder(emailCtx templates.EmailContext) string {
if emailCtx.Colors.Border != "" {
return emailCtx.Colors.Border
}
return "#D6D1C2"
}
func earthenEmailMuted(emailCtx templates.EmailContext) string {
if emailCtx.Colors.Muted != "" {
return emailCtx.Colors.Muted
}
return "#EFEBDF"
}
func earthenEmailMutedFg(emailCtx templates.EmailContext) string {
if emailCtx.Colors.MutedForeground != "" {
return emailCtx.Colors.MutedForeground
}
return "#6E7560"
}