Multi-Page Branding

Independent visual customization for Login, Forgot Password, and Reset Password pages — shared design tokens with per-page overrides, isolated preview, and theme integration.

Multi-Page Branding extends SCRIPE's Login Customizer Studio to support independent visual configurations for all three authentication pages: Login, Forgot Password, and Reset Password. Instead of forcing a single visual identity across all auth flows, Multi-Page Branding allows tenants to present context-appropriate messaging, layouts, and visual treatments for each page. A shared global design provides consistency, while per-page overrides enable targeted differentiation — all managed through the same zero-code studio interface.

Supported Authentication Pages

SCRIPE's authentication system exposes three distinct pages, each serving a different user intent. Multi-Page Branding allows independent customization of all three while maintaining visual consistency through shared design tokens.

PagePurposeKey Messages
LoginPrimary authentication entryFirst impression, strong brand statement
Forgot PasswordPassword recoveryReassuring messaging, trust-building visuals
Reset PasswordNew password creationAction-oriented, minimal distractions

Login Page — The primary authentication entry point. Users enter their credentials (email + password) to access the platform. This page receives the most visual attention as it creates the first impression of the tenant's brand.

Forgot Password Page — The password recovery entry point. Users enter their email to receive a reset link. This page benefits from reassuring messaging ('We'll help you get back in') and softer visual treatments that convey trust and care.

Reset Password Page — The password change confirmation page. Users set a new password using the link from their email. This page benefits from action-oriented messaging ('Create your new password') and clear, focused layouts that minimize distraction.

State Isolation Model

Multi-Page Branding uses a layered state model. The global StudioDraft contains the base configuration for all pages. Each page has an optional override object (pageOverrides.login, pageOverrides.forgotPassword, pageOverrides.resetPassword) that stores only the tokens that differ from the global. This minimizes storage and simplifies diff tracking.

Global Layer (Shared Tokens)

The global layer contains all 50+ design tokens: colors, typography, spacing, overlay, dark mode, and branding panel settings. These tokens apply to ALL auth pages by default. The global layer is always defined — it is never empty.

Page Override Layer (Per-Page Tokens)

Each page's override layer contains ONLY the tokens that differ from the global configuration. For example, if the Forgot Password page has a different headline and subtitle but shares all colors and typography, only panelHeadline and panelSubtitle are stored in the override. Empty fields inherit from the global layer.

Settings Resolution Chain
Global Settings (50+ tokens)
Per-Page Overrides (pages.forgotPassword.*)
Override
Merged Result (global + override)

Runtime Merge Strategy

When the studio switches to a specific page tab, the effective configuration is computed as: effectiveConfig = { ...globalDraft, ...pageOverrides[currentPage] }. This spread-merge ensures that page-specific overrides take precedence while all unspecified tokens fall through to the global values. The merge is performed in the previewTheme() function and in the CSS token emission pipeline.

Studio Integration — Page Tabs

The Customizer Studio sidebar includes a page tab strip (AuthPageTabs component) that allows switching between Login, Forgot Password, and Reset Password. When the active tab changes, the studio loads the corresponding page override (if any) and merges it with the global draft for preview. The preview iframe navigates to the selected auth page route.

AuthPageTabs Component

The AuthPageTabs component renders a horizontal tab bar with 3 tabs (Login, Forgot Password, Reset Password). Each tab displays the page name and an optional 'Customized' badge if per-page overrides exist. Clicking a tab updates the activePage state in the studio, triggers a preview refresh, and loads the page-specific sidebar panel settings.

TabKeyDefault Active
Loginlogin✅ Yes (default)
Forgot PasswordforgotPasswordNo
Reset PasswordresetPasswordNo

Tab Switching Flow

When a user switches tabs: 1. The activePage state is updated to 'login', 'forgotPassword', or 'resetPassword'. 2. The sidebar panels reload with merged values (global + page override). 3. The preview iframe receives an updated postMessage with the merged CSS variables. 4. The iframe URL changes to the corresponding auth route (e.g., /login-preview, /forgot-password-preview, /reset-password-preview). 5. Any changes made in the sidebar are saved to the page override, not the global draft.

Per-Page Editing

When a user modifies a setting while a non-login page is active (e.g., Forgot Password), the change is saved to pageOverrides.forgotPassword — not to the global draft. The studio tracks which page is active and routes edits accordingly. This ensures that changing the forgot-password headline does not affect the login page's headline.

Reset to Global

Each page tab includes a 'Reset to Global' action that removes all per-page overrides for that page, reverting it to the global configuration. This is useful when a tenant wants to undo page-specific customizations and restore visual consistency across all auth pages.

Theme Marketplace Integration

When a marketplace theme includes per-page overrides (pages.forgotPassword, pages.resetPassword), the previewTheme() function in useStudioViewModel.ts automatically imports those overrides into the studio's pageOverrides state. This means applying a theme with per-page branding instantly populates all three auth pages with the theme's intended visual treatment.

Page Override Import

The previewTheme() function checks for the 'pages' key in the theme's ThemeDataJson. If found, it extracts the forgotPassword and resetPassword objects and stores them as pageOverrides. If the theme does not include page overrides, the existing pageOverrides are preserved (or cleared, depending on the apply mode).

Theme Import with Per-Page Merge
Apply Theme (from marketplace)
Merge 50+ global tokens to draft
Check theme.pages for overrides
Merge each page's overrides to draft

Backward Compatibility

Themes without a 'pages' block are fully backward-compatible. The absence of page overrides means all three auth pages use the global design — the same behavior as themes created before the Multi-Page Branding feature. No migration is required for existing themes.

Data Serialization & Persistence

Per-page overrides are stored in the tenant's DraftBrandingJson alongside the global configuration. The JSON structure contains a top-level 'pageOverrides' object with 'login', 'forgotPassword', and 'resetPassword' keys. Each key maps to a flat token object. On publish, the entire structure (global + pageOverrides) is promoted to LiveBrandingJson.

Stored JSON Schema

The DraftBrandingJson stores: { selectedLayout, primaryColor, ...(all global tokens), pageOverrides: { login: { panelHeadline, panelSubtitle, ... }, forgotPassword: { selectedLayout, panelHeadline, overlayColor, ... }, resetPassword: { selectedLayout, panelHeadline, ... } } }. Only non-null override tokens are persisted — empty pages are not stored to save space.

Per-Page Override StructureJSON
{
  "version": "2.0",
  "selectedLayout": "split-right",
  "primaryColor": "#1e40af",
  "fontFamily": "Inter",
  "pageOverrides": {
    "login": {
      "panelHeadline": "Welcome Back",
      "panelSubtitle": "Sign in to continue"
    },
    "forgotPassword": {
      "selectedLayout": "centered",
      "panelHeadline": "Password Recovery",
      "panelSubtitle": "We'll help you get back in",
      "overlayColor": "rgba(30, 64, 175, 0.3)"
    },
    "resetPassword": {
      "panelHeadline": "Create New Password",
      "panelSubtitle": "Choose a strong password"
    }
  }
}

Sandboxed Preview Architecture

Each auth page is previewed in the same sandboxed iframe used by the Login Customizer Studio. When the user switches to a different page tab, the preview URL changes to the corresponding auth route, and new CSS variables (merged from global + page override) are injected via postMessage. The preview supports desktop, tablet, and mobile breakpoints for all three pages.

Preview Isolation

The preview iframe runs in a completely isolated context — separate from the admin panel's authentication state. This prevents the preview from triggering real login/logout actions. The preview pages are purpose-built components that render the auth UI with injected CSS variables but no authentication logic.

Conflict Prevention & Consistency

Multi-Page Branding includes safeguards to prevent visual inconsistency. When the global design changes (e.g., a new font family), all pages that inherit from the global automatically update — only explicitly overridden tokens remain unchanged. The studio displays a 'Customized' badge on page tabs that have overrides, making it clear which pages have independent configurations.

Custom Domain & Subdomain Tenant Matching

When multiple tenants exist, incoming host headers match against custom domains and subdomains to deliver the exact tenant-branded authentication pages.

DNS CNAME Verification & TLS Auto-Provisioning

Custom tenant domains verify CNAME records pointing to the SCRIPE gateway with automated Let's Encrypt TLS certificate provisioning.

Custom Domain Verification Sequence
Admin Enters Custom Domain
Generate Token (scr_ prefix)
Create DNS CNAME & TXT Records
Trigger Verification Request
DnsClient.NET DNS Query (TXT)
Compare TXT Record value with Token
Token Match
Validate CNAME resolved target
Target Valid
Activate Domain & Bind context mappings

Source File Reference

Studio: useStudioViewModel.ts (page state, merge logic, previewTheme())

Components: AuthPageTabs.tsx (tab strip), StylePanel.tsx (sidebar with per-page routing)

Types: StudioDraft.ts (pageOverrides interface), ThemeTypes.ts (page override type definitions)

Backend: LoginThemeSeeder.cs (PageOverrideDesign records, BuildFullThemeJson pages serialization)