Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Feature: PF-95 — Tenant White-Labeling & Theming
Audience: Organization Administrators
Last Updated: 2026-03-24

Overview

Brand Customization allows each organization to apply custom colors, typography, login assets, and favicons to the platform. Changes are scoped to your organization only and do not affect other tenants.

Permissions Required

PermissionRoleDescription
pf.theme.viewStaff, Org AdminView current theme settings
pf.theme.manageOrg AdminCreate, edit, import/export themes
pf.subdomain.manageOrg AdminConfigure subdomain and redirect preferences

Accessing Brand Settings

Navigate to Settings → Branding & Theme. The settings page has four tabs:
  1. Colors — Primary, secondary, accent, background, surface, text, and status colors
  2. Typography — Body and heading font selection
  3. Login & Assets — Login logo, background image, welcome text, favicon
  4. Subdomain — Custom subdomain setup and redirect configuration

Colors

Editing Colors

Each color field accepts hex (#2563eb), RGB (rgb(37, 99, 235)), or HSL (hsl(217, 91%, 53%)) formats.

WCAG Contrast Gates

The platform enforces WCAG 2.1 AA contrast requirements before allowing saves:
Color PairMinimum Ratio
Text on Background4.5:1
Text Muted on Background4.5:1
Text on Surface4.5:1
Primary on Background3:1 (large text / UI components)
If contrast is insufficient, the Save button is disabled and specific failing pairs are shown.

Reset to Defaults

Use the Reset to Defaults button to restore platform default colors. A confirmation dialog appears before resetting.

Typography

Approved Font List

Only the following fonts are permitted (loaded via Google Fonts):
  • system-ui (system default)
  • Inter
  • Source Sans 3
  • Open Sans
  • Lato
  • Roboto
Select separate fonts for body text and headings. Fonts load with font-display: swap to prevent render blocking.

Login & Assets

Upload your organization’s logo for the login page. Recommended: SVG or PNG with transparent background, max 200×80px display area.

Login Background

Optional background image for the login page. Recommended: 1920×1080px minimum, JPEG or WebP for smaller file sizes.

Welcome Text

Custom welcome message displayed on the login page (e.g., “Welcome to Acme Health”).

Favicon

Upload a custom favicon (.ico, .png, or .svg). Recommended: 32×32px or 180×180px for Apple Touch Icon.

Import / Export

Export

Click Export Theme to download a JSON file containing your current theme configuration. The export uses schemaVersion: 1 and omits internal IDs and audit fields.
{
  "schemaVersion": 1,
  "theme": {
    "name": "Acme Brand",
    "colorPrimary": "#2563eb",
    "colorSecondary": "#64748b",
    "fontFamily": "Inter",
    ...
  }
}

Import

Click Import Theme to load a previously exported JSON file. The import dialog (sm:max-w-lg) shows:
  1. A preview of the theme to be applied
  2. Warning for any unknown keys in the file
  3. Confirmation before replacing the active theme
Note: Import replaces the current active theme. The previous theme is retained as an inactive record.

Subdomain Configuration

Setting Up a Subdomain

  1. Enter your desired subdomain label (e.g., acmeacme.yourdomain.com)
  2. The label must:
    • Be 3–63 characters
    • Start and end with a letter or number
    • Contain only lowercase letters, numbers, and hyphens
    • Not be a reserved label

Reserved Labels

The following subdomain labels are not available: www, app, api, admin, mail, smtp, ftp, login, auth, sso, status, help, docs, cdn, assets, static, staging, dev, test, demo, beta, sandbox, internal

Subdomain Verification

After entering a subdomain, a platform administrator must verify it by:
  1. Configuring the subdomain in your hosting provider (Vercel)
  2. Ensuring SSL/TLS is provisioned for the subdomain
  3. Marking the subdomain as Verified in platform settings
Important: Redirects are only enabled after verification to prevent redirect loops to hosts without valid TLS.

Redirect Toggle

Once verified, enable Prefer Subdomain Redirect to activate canonical redirects. When enabled:
ScenarioBehavior
R1: User visits primary host /o/acme/…308 redirect to https://acme.yourdomain.com/o/acme/…
R2: User visits acme.yourdomain.com/o/acme/…No redirect (already correct)
R3: User visits primary host without org pathNo redirect
R4: User visits unknown subdomainNo redirect (platform default)
R5: User visits wrong subdomain for orgNo redirect (deferred)
The redirect preserves the full path and query string. Status code is 308 (Permanent Redirect, preserves method).

Security Notes

  • No anonymous table access: The pf_tenant_themes table is never directly readable by unauthenticated users. Pre-authentication branding is served exclusively through pf_public_login_branding_by_subdomain and pf_public_login_branding_by_slug RPCs, which return a fixed projection of login-safe fields only.
  • Tenant isolation: All theme data is scoped by organization_id with Row-Level Security enforced. Users cannot read or modify themes belonging to other organizations.
  • Single active theme: Only one theme per organization can be active at a time, enforced by a database trigger and partial unique index.
  • Input validation: Color values are validated against safe formats (hex, RGB, HSL). No arbitrary CSS or HTML injection is permitted.
  • Asset uploads: Logo, background, and favicon uploads use existing platform storage patterns with approved file type validation.

Troubleshooting

IssueResolution
Save button disabledCheck WCAG contrast errors displayed below the color pickers
Subdomain rejectedEnsure label meets length (3–63), format, and reserved label requirements
Redirect not workingVerify subdomain is marked as Verified and redirect toggle is enabled
Theme not applyingEnsure the theme is marked as Active; check browser cache
Import failsVerify JSON file has schemaVersion: 1 and valid color formats