From b359446038a0a71ab4a389ffdd167b934fbdde84 Mon Sep 17 00:00:00 2001 From: waleed Date: Tue, 30 Jun 2026 19:41:55 -0700 Subject: [PATCH 1/3] improvement(emails): align transactional emails with the platform neutral design system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-skin all ~25 transactional email templates to match the platform/newsletter: - Color tokens in _styles/base.ts now mirror globals.css light mode (#fefefe canvas, #1a1a1a text, #525252/#5c5c5c/#707070 greys, #dedede border) instead of the old lavender + green (#33C482) scheme; accent defaults to neutral #1a1a1a but still honors a whitelabel primaryColor. - Primary CTA now matches the platform's primary Chip (inverse #1a1a1a fill, white text, rounded-lg, text-sm, normal weight); links carry an underline since the neutral color no longer signals a link. - Card uses 8px radius + hairline border; info/code boxes use a subtle token fill. - Logo is the dark, text-only 'sim' wordmark (green icon removed). - Footer: LinkedIn replaces Discord. - Every template routes through the centralized colors tokens — zero hardcoded hex (payment-failed error box tokenized to platform error surface values). --- apps/sim/components/emails/_styles/base.ts | 70 ++++++++++-------- .../billing/credits-exhausted-email.tsx | 2 +- .../billing/free-tier-upgrade-email.tsx | 2 +- .../emails/billing/payment-failed-email.tsx | 4 +- .../emails/components/email-footer.tsx | 9 ++- .../emails/components/email-layout.tsx | 4 +- .../sim/public/brand/color/email/wordmark.png | Bin 2978 -> 15526 bytes 7 files changed, 51 insertions(+), 40 deletions(-) diff --git a/apps/sim/components/emails/_styles/base.ts b/apps/sim/components/emails/_styles/base.ts index 4c0607b4eee..18032761db6 100644 --- a/apps/sim/components/emails/_styles/base.ts +++ b/apps/sim/components/emails/_styles/base.ts @@ -10,30 +10,36 @@ function buildColors() { const brand = getBrandConfig() const isWhitelabeled = brand.isWhitelabeled const accentColor = - isWhitelabeled && brand.theme?.primaryColor ? brand.theme.primaryColor : '#33C482' + isWhitelabeled && brand.theme?.primaryColor ? brand.theme.primaryColor : '#1a1a1a' return { - /** Main canvas background */ - bgOuter: '#F7F9FC', - /** Card/container background - pure white */ + /** Main canvas background — platform `--bg` */ + bgOuter: '#fefefe', + /** Card/container background — platform `--surface-2` */ bgCard: '#ffffff', - /** Primary text color */ - textPrimary: '#2d2d2d', - /** Secondary text color */ - textSecondary: '#404040', - /** Tertiary text color */ + /** Primary text — platform `--text-primary` */ + textPrimary: '#1a1a1a', + /** Secondary text — platform `--text-secondary` */ + textSecondary: '#525252', + /** Tertiary text — platform `--text-tertiary` */ textTertiary: '#5c5c5c', - /** Muted text (footer) */ - textMuted: '#737373', - /** Brand primary color */ + /** Muted text (footer) — platform `--text-muted` */ + textMuted: '#707070', + /** Brand primary — neutral by default, brand color when whitelabeled */ brandPrimary: - isWhitelabeled && brand.theme?.primaryColor ? brand.theme.primaryColor : '#33C482', - /** Brand accent - used for buttons and links */ + isWhitelabeled && brand.theme?.primaryColor ? brand.theme.primaryColor : '#1a1a1a', + /** Accent for buttons and links — neutral by default, brand color when whitelabeled */ brandTertiary: accentColor, - /** Border/divider color */ - divider: '#ededed', - /** Footer background */ - footerBg: '#F7F9FC', + /** Border/divider — platform `--border` */ + divider: '#dedede', + /** Subtle fill for info/code boxes on the white card */ + surfaceSubtle: '#f7f7f7', + /** Error surface fill — platform `--terminal-status-error-bg` */ + errorBg: '#fef2f2', + /** Error surface border — platform `--error-muted` */ + errorBorder: '#fecaca', + /** Footer background — matches the canvas */ + footerBg: '#fefefe', } } @@ -79,12 +85,13 @@ export const baseStyles = { margin: '0 auto', }, - /** Main card container with rounded corners */ + /** Main card container — white surface, chip-radius, hairline border on the near-white canvas */ container: { maxWidth: `${spacing.containerWidth}px`, margin: '0 auto', backgroundColor: colors.bgCard, - borderRadius: '16px', + border: `1px solid ${colors.divider}`, + borderRadius: '8px', overflow: 'hidden', }, @@ -120,26 +127,27 @@ export const baseStyles = { display: 'inline', }, - /** Primary CTA button - matches app tertiary button style */ + /** Primary CTA button - matches the platform's primary Chip (inverse fill, rounded-lg, h-30, text-sm) */ button: { display: 'inline-block', backgroundColor: colors.brandTertiary, color: '#ffffff', - fontWeight: 500, + fontWeight: 400, fontSize: '14px', - padding: '6px 12px', - borderRadius: '5px', + lineHeight: '30px', + padding: '0 12px', + borderRadius: '8px', textDecoration: 'none', textAlign: 'center' as const, margin: '4px 0', fontFamily: typography.fontFamily, }, - /** Link text style */ + /** Link text style - neutral color, so it carries an underline to read as a link */ link: { color: colors.brandTertiary, - fontWeight: 'bold' as const, - textDecoration: 'none', + fontWeight: 400, + textDecoration: 'underline', }, /** Horizontal divider */ @@ -169,8 +177,8 @@ export const baseStyles = { codeContainer: { margin: '12px 0', padding: '12px 16px', - backgroundColor: '#f8f9fa', - borderRadius: '6px', + backgroundColor: colors.surfaceSubtle, + borderRadius: '8px', border: `1px solid ${colors.divider}`, textAlign: 'center' as const, }, @@ -198,9 +206,9 @@ export const baseStyles = { /** Highlighted info box (e.g., "What you get with Pro") */ infoBox: { - backgroundColor: colors.bgOuter, + backgroundColor: colors.surfaceSubtle, padding: '16px 18px', - borderRadius: '6px', + borderRadius: '8px', margin: '16px 0', }, diff --git a/apps/sim/components/emails/billing/credits-exhausted-email.tsx b/apps/sim/components/emails/billing/credits-exhausted-email.tsx index 4108a912624..d505e9e0726 100644 --- a/apps/sim/components/emails/billing/credits-exhausted-email.tsx +++ b/apps/sim/components/emails/billing/credits-exhausted-email.tsx @@ -34,7 +34,7 @@ export function CreditsExhaustedEmail({
- + Discord diff --git a/apps/sim/components/emails/components/email-layout.tsx b/apps/sim/components/emails/components/email-layout.tsx index a60b76c7682..8a5dc29f5e2 100644 --- a/apps/sim/components/emails/components/email-layout.tsx +++ b/apps/sim/components/emails/components/email-layout.tsx @@ -42,8 +42,8 @@ export function EmailLayout({
{brand.name} diff --git a/apps/sim/public/brand/color/email/wordmark.png b/apps/sim/public/brand/color/email/wordmark.png index 639a2ea80fc5fc4df2e27dfc3c8ea32116756433..977814b5655a59b7001a9ec10bd1994024342d68 100644 GIT binary patch literal 15526 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 WhovH{)12Vw25hm8mj7TbCjTEhoP$9C From 578cb5faf091cf1bba39df038b3bcf06eaa895b9 Mon Sep 17 00:00:00 2001 From: waleed Date: Tue, 30 Jun 2026 19:49:18 -0700 Subject: [PATCH 2/3] fix(emails): keep card boundary robust + don't reshape custom logos - Canvas goes to #f8f8f8 (off Andres's newsletter) so the white card reads via contrast in clients that flatten inline borders, not the border alone (Greptile P2). - Logo pins exact 70x34 only for the bundled wordmark; whitelabel brand.logoUrl now constrains by height with auto width so custom logos keep their aspect (Greptile P1). --- apps/sim/components/emails/_styles/base.ts | 6 +++--- apps/sim/components/emails/components/email-layout.tsx | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/sim/components/emails/_styles/base.ts b/apps/sim/components/emails/_styles/base.ts index 18032761db6..adee256223e 100644 --- a/apps/sim/components/emails/_styles/base.ts +++ b/apps/sim/components/emails/_styles/base.ts @@ -13,8 +13,8 @@ function buildColors() { isWhitelabeled && brand.theme?.primaryColor ? brand.theme.primaryColor : '#1a1a1a' return { - /** Main canvas background — platform `--bg` */ - bgOuter: '#fefefe', + /** Main canvas background — a hair off-white so the white card reads via contrast, not the border alone */ + bgOuter: '#f8f8f8', /** Card/container background — platform `--surface-2` */ bgCard: '#ffffff', /** Primary text — platform `--text-primary` */ @@ -39,7 +39,7 @@ function buildColors() { /** Error surface border — platform `--error-muted` */ errorBorder: '#fecaca', /** Footer background — matches the canvas */ - footerBg: '#fefefe', + footerBg: '#f8f8f8', } } diff --git a/apps/sim/components/emails/components/email-layout.tsx b/apps/sim/components/emails/components/email-layout.tsx index 8a5dc29f5e2..8d7fe183c51 100644 --- a/apps/sim/components/emails/components/email-layout.tsx +++ b/apps/sim/components/emails/components/email-layout.tsx @@ -30,6 +30,7 @@ export function EmailLayout({ }: EmailLayoutProps) { const brand = getBrandConfig() const baseUrl = getBaseUrl() + const hasCustomLogo = Boolean(brand.logoUrl) return ( @@ -42,10 +43,10 @@ export function EmailLayout({
{brand.name}
From ac80f3c4f9fd1614bf7444d17d43a668cfc6b88b Mon Sep 17 00:00:00 2001 From: waleed Date: Tue, 30 Jun 2026 19:51:55 -0700 Subject: [PATCH 3/3] improvement(emails): use Season Sans to match the newsletter and platform Register the Season Sans web font (the woff2 shipped with the newsletter, #5302) via react-email's in the layout head, and lead the email font stack with 'Season Sans' (system stack still the fallback for clients that ignore @font-face). --- apps/sim/components/emails/_styles/base.ts | 3 ++- .../components/emails/components/email-layout.tsx | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/sim/components/emails/_styles/base.ts b/apps/sim/components/emails/_styles/base.ts index adee256223e..2ff9fcc74ac 100644 --- a/apps/sim/components/emails/_styles/base.ts +++ b/apps/sim/components/emails/_styles/base.ts @@ -47,7 +47,8 @@ export const colors = buildColors() /** Typography settings */ export const typography = { - fontFamily: "-apple-system, 'SF Pro Display', 'SF Pro Text', 'Helvetica', sans-serif", + fontFamily: + "'Season Sans', -apple-system, 'SF Pro Display', 'SF Pro Text', 'Helvetica', sans-serif", fontSize: { body: '16px', small: '14px', diff --git a/apps/sim/components/emails/components/email-layout.tsx b/apps/sim/components/emails/components/email-layout.tsx index 8d7fe183c51..f28e9a81008 100644 --- a/apps/sim/components/emails/components/email-layout.tsx +++ b/apps/sim/components/emails/components/email-layout.tsx @@ -1,4 +1,4 @@ -import { Body, Container, Head, Html, Img, Preview, Section } from '@react-email/components' +import { Body, Container, Font, Head, Html, Img, Preview, Section } from '@react-email/components' import { baseStyles } from '@/components/emails/_styles' import { EmailFooter } from '@/components/emails/components/email-footer' import { getBaseUrl } from '@/lib/core/utils/urls' @@ -34,7 +34,18 @@ export function EmailLayout({ return ( - + + + {preview} {/* Main card container */}