This is about the same amount of code than the previous approach, but has the following advantages: * Uses Roda's render plugin, so templates are cached and optimized into compiled methods. The previous approach created 5 separate Tilt::ErubiTemplate objects for every email rendered. The new approach does not create any Tilt::ErubiTemplate objects after the first email. * Uses part instead of render for simpler rendering with locals. * Moves EmailRenderer to separate file, so that reloading works correctly. * Skips the rendering of the email stylesheet, since it does not contain any ERB code. Instead, the file is included without rendering. * Uses fixed locals for the email templates, so providing an invalid local will result in an error. * Removes unnecessary empty `<style>` tag in email layout. The only spec change is adding an email to one of the invoice specs. I'm not sure why this didn't fail before, but the mail library complains if it tries to deliver a email with no recipients.
232 lines
3.9 KiB
HTML
232 lines
3.9 KiB
HTML
<style>
|
|
/* Base */
|
|
|
|
body,
|
|
body *:not(html):not(style):not(br):not(tr):not(code) {
|
|
box-sizing: border-box;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
|
|
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
|
position: relative;
|
|
}
|
|
|
|
body {
|
|
-webkit-text-size-adjust: none;
|
|
background-color: #ffffff;
|
|
color: #718096;
|
|
height: 100%;
|
|
line-height: 1.4;
|
|
margin: 0;
|
|
padding: 0;
|
|
width: 100% !important;
|
|
}
|
|
|
|
p,
|
|
ul,
|
|
ol,
|
|
blockquote {
|
|
line-height: 1.4;
|
|
text-align: left;
|
|
}
|
|
|
|
a {
|
|
color: #3869d4;
|
|
}
|
|
|
|
a img {
|
|
border: none;
|
|
}
|
|
|
|
/* Typography */
|
|
|
|
h1 {
|
|
color: #3d4852;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
margin-top: 0;
|
|
text-align: left;
|
|
}
|
|
|
|
p {
|
|
font-size: 16px;
|
|
line-height: 1.5em;
|
|
margin-top: 0;
|
|
text-align: left;
|
|
}
|
|
|
|
p.sub {
|
|
font-size: 12px;
|
|
}
|
|
|
|
img {
|
|
max-width: 100%;
|
|
}
|
|
|
|
/* Layout */
|
|
|
|
.wrapper {
|
|
-premailer-cellpadding: 0;
|
|
-premailer-cellspacing: 0;
|
|
-premailer-width: 100%;
|
|
background-color: #fef4ea;
|
|
margin: 0;
|
|
padding: 0;
|
|
width: 100%;
|
|
}
|
|
|
|
.content {
|
|
-premailer-cellpadding: 0;
|
|
-premailer-cellspacing: 0;
|
|
-premailer-width: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
width: 100%;
|
|
}
|
|
|
|
/* Header */
|
|
|
|
.header {
|
|
padding: 25px 0;
|
|
text-align: center;
|
|
}
|
|
|
|
.header a {
|
|
color: #3d4852;
|
|
font-size: 19px;
|
|
font-weight: bold;
|
|
text-decoration: none;
|
|
}
|
|
|
|
/* Logo */
|
|
|
|
.logo {
|
|
width: 320px;
|
|
}
|
|
|
|
/* Body */
|
|
|
|
.body {
|
|
-premailer-cellpadding: 0;
|
|
-premailer-cellspacing: 0;
|
|
-premailer-width: 100%;
|
|
background-color: #fef4ea;
|
|
border-bottom: 1px solid #edf2f7;
|
|
border-top: 1px solid #edf2f7;
|
|
margin: 0;
|
|
padding: 0;
|
|
width: 100%;
|
|
}
|
|
|
|
.inner-body {
|
|
-premailer-cellpadding: 0;
|
|
-premailer-cellspacing: 0;
|
|
-premailer-width: 570px;
|
|
background-color: #ffffff;
|
|
border-color: #e8e5ef;
|
|
border-radius: 24px;
|
|
border-width: 1px;
|
|
box-shadow: 0 2px 0 rgba(0, 0, 150, 0.025), 2px 4px 0 rgba(0, 0, 150, 0.015);
|
|
margin: 0 auto;
|
|
padding: 0;
|
|
width: 570px;
|
|
}
|
|
|
|
/* Subcopy */
|
|
|
|
.subcopy {
|
|
border-top: 1px solid #e8e5ef;
|
|
margin-top: 25px;
|
|
padding-top: 25px;
|
|
}
|
|
|
|
.subcopy p {
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* Footer */
|
|
|
|
.footer {
|
|
-premailer-cellpadding: 0;
|
|
-premailer-cellspacing: 0;
|
|
-premailer-width: 570px;
|
|
margin: 0 auto;
|
|
padding: 24px 0;
|
|
text-align: center;
|
|
width: 570px;
|
|
}
|
|
|
|
.footer p {
|
|
color: #b0adc5;
|
|
font-size: 12px;
|
|
text-align: left;
|
|
}
|
|
|
|
.footer a {
|
|
color: #b0adc5;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.footer .icon svg {
|
|
height: 1.5rem;
|
|
width: 1.5rem;
|
|
}
|
|
|
|
.content-cell {
|
|
max-width: 100vw;
|
|
padding: 32px;
|
|
}
|
|
|
|
/* Buttons */
|
|
|
|
.action {
|
|
-premailer-cellpadding: 0;
|
|
-premailer-cellspacing: 0;
|
|
-premailer-width: 100%;
|
|
margin: 30px auto;
|
|
padding: 0;
|
|
text-align: center;
|
|
width: 100%;
|
|
}
|
|
|
|
.button {
|
|
-webkit-text-size-adjust: none;
|
|
border-radius: 4px;
|
|
color: #fff;
|
|
display: inline-block;
|
|
overflow: hidden;
|
|
text-decoration: none;
|
|
text-align: center;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.button-primary {
|
|
background-color: #ea580c;
|
|
border-bottom: 8px solid #ea580c;
|
|
border-left: 18px solid #ea580c;
|
|
border-right: 18px solid #ea580c;
|
|
border-top: 8px solid #ea580c;
|
|
}
|
|
|
|
/* Utilities */
|
|
|
|
.break-all {
|
|
word-break: break-all;
|
|
}
|
|
|
|
@media only screen and (max-width: 600px) {
|
|
.inner-body {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.footer {
|
|
width: 100% !important;
|
|
}
|
|
}
|
|
|
|
@media only screen and (max-width: 500px) {
|
|
.button {
|
|
width: 100% !important;
|
|
}
|
|
}
|
|
</style>
|