From 6811411881b8595981bfffe218b415d0110b2ad0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 22 Jun 2026 17:03:25 +0000 Subject: [PATCH 1/2] docs: update email layout docs with branding-aware buttons, dark mode, and plan availability - Email layouts page: - Expand branding variables table with dark_primary_color and dark_primary_color_contrast - Add branding-aware buttons section documenting legacy .button and visual editor .block-button behavior - Explain why dark mode requires !important overrides for button styles - Include CSS code snippet for branding-aware button styles - MJML support page: - Add dark mode support section with MJML-specific code snippet - Add branding-aware buttons section with MJML styling code - Client previews page: - Update plan availability from Enterprise-only to all paid plans (Starter+) - Remove Enterprise callout and add Availability section - Document disabled button behavior on free plan Resolves: KNO-13880 Co-authored-by: Sam Seely --- .../integrations/email/client-previews.mdx | 19 +-- content/integrations/email/layouts.mdx | 106 +++++++++++++++- content/integrations/email/mjml.mdx | 120 ++++++++++++++++++ 3 files changed, 226 insertions(+), 19 deletions(-) diff --git a/content/integrations/email/client-previews.mdx b/content/integrations/email/client-previews.mdx index d956b0956..0fc88d6ad 100644 --- a/content/integrations/email/client-previews.mdx +++ b/content/integrations/email/client-previews.mdx @@ -5,25 +5,14 @@ section: Integrations > Email layout: integrations --- - - Email client previews are currently only available on our{" "} - - Enterprise plan - - . - - } -/> - ## Overview Email client previews allow you to test how your email notifications will render across different email clients. This feature is embedded directly in the Knock template editor, using Litmus technology to generate accurate previews without requiring you to leave the editor or send test emails. +## Availability + +Email client previews are available on all paid plans (Starter and above). On the free plan, the client previews button appears in the template editor but is disabled. Hovering over the disabled button displays a tooltip prompting you to upgrade to Starter. + ## Features - Preview emails in popular clients including Gmail, Outlook, and Apple Mail. diff --git a/content/integrations/email/layouts.mdx b/content/integrations/email/layouts.mdx index afb294386..f2e69e213 100644 --- a/content/integrations/email/layouts.mdx +++ b/content/integrations/email/layouts.mdx @@ -105,10 +105,16 @@ Inject account- and environment-level variables into your layout with the `vars. Branding properties set in account settings are available under `vars.branding.*`: -- `vars.branding.logo_url` -- `vars.branding.icon_url` -- `vars.branding.primary_color` -- `vars.branding.primary_color_contrast` +| Variable | Description | +| ------------------------------------------- | ---------------------------------------------------------------------------------- | +| `vars.branding.logo_url` | Your brand logo URL. | +| `vars.branding.icon_url` | Your brand icon URL. | +| `vars.branding.dark_logo_url` | Logo for dark mode (falls back to `logo_url`). | +| `vars.branding.dark_icon_url` | Icon for dark mode (falls back to `icon_url`). | +| `vars.branding.primary_color` | Primary brand color for buttons and accents. Defaults to `#000000`. | +| `vars.branding.primary_color_contrast` | Text color used on primary-colored backgrounds. Defaults to `#FFFFFF`. | +| `vars.branding.dark_primary_color` | Primary color for dark mode (falls back to `primary_color`). | +| `vars.branding.dark_primary_color_contrast` | Contrast color for dark mode (falls back to `primary_color_contrast`). | With [per-tenant branding](/multi-tenancy/per-tenant-branding), Knock resolves these properties against the `tenant_id` on the workflow run, falling back to account-level branding if the tenant has none set. @@ -223,6 +229,98 @@ The ` + + +``` + + + Not every email client supports prefers-color-scheme. Clients + that don't will fall back to your light mode styles, so treat light mode + as the default experience. + + } +/> + +### Branding-aware buttons in MJML layouts + +The Knock default MJML layout wires button styles to your [branding colors](/integrations/email/layouts#using-variables-and-brand-attributes-in-a-custom-layout) so buttons match your brand out of the box. This applies to both the legacy `.button` class and the visual editor's `.block-button` components. + +#### Button behavior in light and dark mode + +- **Solid buttons (`.block-button--solid`).** Background uses `primary_color`, text uses `primary_color_contrast`. In dark mode, these switch to `dark_primary_color` and `dark_primary_color_contrast`. + +- **Outline buttons (`.block-button--outline`).** Transparent background with `primary_color` text and border. In dark mode, these switch to `dark_primary_color`. + +In light mode, per-button colors set in the visual editor take precedence. In dark mode, the layout applies `!important` to override inline styles and ensure readability on dark backgrounds. + +#### Why dark mode uses `!important` overrides + +The visual editor renders button colors as static inline styles that do not change between light and dark mode. Without layout-level overrides, buttons would display their light-mode colors on a dark background, making text unreadable. The layout uses `!important` in dark mode to force branding colors on all buttons. + + + If your MJML layout was created before April 21, 2026, it does not include + branding-aware button styles or dark mode support. Either create a new + layout (which starts from Knock's latest default) or add the styles to + your existing layout. + + } +/> + +Here's the CSS to add branding-aware buttons to a custom MJML layout: + +```mjml title="Branding-aware button styles for MJML" + + /* Legacy button class */ + .button { + background-color: {{ vars.branding.primary_color | default: "#000000" }}; + border-color: {{ vars.branding.primary_color | default: "#000000" }}; + color: {{ vars.branding.primary_color_contrast | default: "#FFFFFF" }}; + } + + /* Visual editor solid buttons */ + .block-button.block-button--solid { + background-color: {{ vars.branding.primary_color | default: "#000000" }}; + border-color: {{ vars.branding.primary_color | default: "#000000" }}; + color: {{ vars.branding.primary_color_contrast | default: "#FFFFFF" }}; + } + + /* Visual editor outline buttons */ + .block-button.block-button--outline { + background-color: transparent; + border-color: {{ vars.branding.primary_color | default: "#000000" }}; + color: {{ vars.branding.primary_color | default: "#000000" }}; + } + + @media (prefers-color-scheme: dark) { + .button { + background-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; + border-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; + color: {{ vars.branding.dark_primary_color_contrast | default: vars.branding.primary_color_contrast | default: "#FFFFFF" }} !important; + } + + .block-button.block-button--solid { + background-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; + border-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; + color: {{ vars.branding.dark_primary_color_contrast | default: vars.branding.primary_color_contrast | default: "#FFFFFF" }} !important; + } + + .block-button.block-button--outline { + background-color: transparent !important; + border-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; + color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; + } + } + +``` + ## MJML templates Email templates can use MJML in two ways: From 215b3a4a9fead0dc80453ed65e0167426d2e2af3 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 22 Jun 2026 17:05:54 +0000 Subject: [PATCH 2/2] style: fix formatting in layouts and mjml docs Co-authored-by: Sam Seely --- content/integrations/email/layouts.mdx | 21 ++++--- content/integrations/email/mjml.mdx | 85 ++++++++++---------------- 2 files changed, 44 insertions(+), 62 deletions(-) diff --git a/content/integrations/email/layouts.mdx b/content/integrations/email/layouts.mdx index f2e69e213..5464ec227 100644 --- a/content/integrations/email/layouts.mdx +++ b/content/integrations/email/layouts.mdx @@ -105,16 +105,16 @@ Inject account- and environment-level variables into your layout with the `vars. Branding properties set in account settings are available under `vars.branding.*`: -| Variable | Description | -| ------------------------------------------- | ---------------------------------------------------------------------------------- | -| `vars.branding.logo_url` | Your brand logo URL. | -| `vars.branding.icon_url` | Your brand icon URL. | -| `vars.branding.dark_logo_url` | Logo for dark mode (falls back to `logo_url`). | -| `vars.branding.dark_icon_url` | Icon for dark mode (falls back to `icon_url`). | -| `vars.branding.primary_color` | Primary brand color for buttons and accents. Defaults to `#000000`. | -| `vars.branding.primary_color_contrast` | Text color used on primary-colored backgrounds. Defaults to `#FFFFFF`. | -| `vars.branding.dark_primary_color` | Primary color for dark mode (falls back to `primary_color`). | -| `vars.branding.dark_primary_color_contrast` | Contrast color for dark mode (falls back to `primary_color_contrast`). | +| Variable | Description | +| ------------------------------------------- | ---------------------------------------------------------------------- | +| `vars.branding.logo_url` | Your brand logo URL. | +| `vars.branding.icon_url` | Your brand icon URL. | +| `vars.branding.dark_logo_url` | Logo for dark mode (falls back to `logo_url`). | +| `vars.branding.dark_icon_url` | Icon for dark mode (falls back to `icon_url`). | +| `vars.branding.primary_color` | Primary brand color for buttons and accents. Defaults to `#000000`. | +| `vars.branding.primary_color_contrast` | Text color used on primary-colored backgrounds. Defaults to `#FFFFFF`. | +| `vars.branding.dark_primary_color` | Primary color for dark mode (falls back to `primary_color`). | +| `vars.branding.dark_primary_color_contrast` | Contrast color for dark mode (falls back to `primary_color_contrast`). | With [per-tenant branding](/multi-tenancy/per-tenant-branding), Knock resolves these properties against the `tenant_id` on the workflow run, falling back to account-level branding if the tenant has none set. @@ -245,6 +245,7 @@ If your templates use the legacy `.button` class, the default layout styles it w Buttons inserted from the visual editor use the `.block-button` class with solid or outline variants: - **Solid buttons (`.block-button--solid`).** + - Light mode: background uses `primary_color`, text uses `primary_color_contrast`. - Dark mode: background uses `dark_primary_color`, text uses `dark_primary_color_contrast`. diff --git a/content/integrations/email/mjml.mdx b/content/integrations/email/mjml.mdx index 4a1313278..9a0a347c3 100644 --- a/content/integrations/email/mjml.mdx +++ b/content/integrations/email/mjml.mdx @@ -46,18 +46,9 @@ The Knock default MJML layout supports dark mode out of the box via the `prefers - :root { - color-scheme: light dark; - supported-color-schemes: light dark; - } - - @media (prefers-color-scheme: dark) { - .email-wrapper, - .email-body { - background-color: #262626 !important; - color: #ffffff !important; - } - } + :root { color-scheme: light dark; supported-color-schemes: light dark; } + @media (prefers-color-scheme: dark) { .email-wrapper, .email-body { + background-color: #262626 !important; color: #ffffff !important; } } @@ -111,46 +102,36 @@ Here's the CSS to add branding-aware buttons to a custom MJML layout: ```mjml title="Branding-aware button styles for MJML" - /* Legacy button class */ - .button { - background-color: {{ vars.branding.primary_color | default: "#000000" }}; - border-color: {{ vars.branding.primary_color | default: "#000000" }}; - color: {{ vars.branding.primary_color_contrast | default: "#FFFFFF" }}; - } - - /* Visual editor solid buttons */ - .block-button.block-button--solid { - background-color: {{ vars.branding.primary_color | default: "#000000" }}; - border-color: {{ vars.branding.primary_color | default: "#000000" }}; - color: {{ vars.branding.primary_color_contrast | default: "#FFFFFF" }}; - } - - /* Visual editor outline buttons */ - .block-button.block-button--outline { - background-color: transparent; - border-color: {{ vars.branding.primary_color | default: "#000000" }}; - color: {{ vars.branding.primary_color | default: "#000000" }}; - } - - @media (prefers-color-scheme: dark) { - .button { - background-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; - border-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; - color: {{ vars.branding.dark_primary_color_contrast | default: vars.branding.primary_color_contrast | default: "#FFFFFF" }} !important; - } - - .block-button.block-button--solid { - background-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; - border-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; - color: {{ vars.branding.dark_primary_color_contrast | default: vars.branding.primary_color_contrast | default: "#FFFFFF" }} !important; - } - - .block-button.block-button--outline { - background-color: transparent !important; - border-color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; - color: {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | default: "#000000" }} !important; - } - } + /* Legacy button class */ .button { background-color: {{ + vars.branding.primary_color | default: "#000000" }}; border-color: {{ + vars.branding.primary_color | default: "#000000" }}; color: {{ + vars.branding.primary_color_contrast | default: "#FFFFFF" }}; } /* Visual + editor solid buttons */ .block-button.block-button--solid { background-color: + {{ vars.branding.primary_color | default: "#000000" }}; border-color: {{ + vars.branding.primary_color | default: "#000000" }}; color: {{ + vars.branding.primary_color_contrast | default: "#FFFFFF" }}; } /* Visual + editor outline buttons */ .block-button.block-button--outline { + background-color: transparent; border-color: {{ vars.branding.primary_color | + default: "#000000" }}; color: {{ vars.branding.primary_color | default: + "#000000" }}; } @media (prefers-color-scheme: dark) { .button { + background-color: {{ vars.branding.dark_primary_color | default: + vars.branding.primary_color | default: "#000000" }} !important; border-color: + {{ vars.branding.dark_primary_color | default: vars.branding.primary_color | + default: "#000000" }} !important; color: {{ + vars.branding.dark_primary_color_contrast | default: + vars.branding.primary_color_contrast | default: "#FFFFFF" }} !important; } + .block-button.block-button--solid { background-color: {{ + vars.branding.dark_primary_color | default: vars.branding.primary_color | + default: "#000000" }} !important; border-color: {{ + vars.branding.dark_primary_color | default: vars.branding.primary_color | + default: "#000000" }} !important; color: {{ + vars.branding.dark_primary_color_contrast | default: + vars.branding.primary_color_contrast | default: "#FFFFFF" }} !important; } + .block-button.block-button--outline { background-color: transparent + !important; border-color: {{ vars.branding.dark_primary_color | default: + vars.branding.primary_color | default: "#000000" }} !important; color: {{ + vars.branding.dark_primary_color | default: vars.branding.primary_color | + default: "#000000" }} !important; } } ```