Skip to main content

Documentation

No results found.
Features Members

Dashboard Branding

Dashboard Branding white-labels the admin chrome — the dashboard sidebar and the login / auth pages — so an install can wear the platform's brand, the client's site brand, or a web designer's agency brand. It controls both the logo and the...

Dashboard Branding white-labels the admin chrome — the dashboard sidebar and the login / auth pages — so an install can wear the platform's brand, the client's site brand, or a web designer's agency brand. It controls both the logo and the chrome colors (sidebar accents, tabs, pills, links, brand buttons), gated behind a paid-member feature toggle.


The three modes

A single radio control on Dashboard → Settings → White Label → Dashboard & Login Branding picks one of three modes (stored as branding.admin_logo_mode). Each mode drives the logo and the chrome colors together — they never diverge.

Mode (branding.admin_logo_mode) Logo Chrome colors
webprocms The shipped platform logo Fixed WebProCMS purple (#495092) + teal accent (#0d9488). Identical in light and dark.
site The client's site logo (the one set on the Branding page) Auto-derived from the site's primary and secondary brand colors. No extra configuration.
designer The agency's own logo (light + dark uploads) The agency's own four swatches: primary light/dark and accent light/dark.

The logo and colors are deliberately one decision: choosing "this site's brand" means the dashboard adopts the client's logo and their colors; choosing the designer brand adopts the agency's logo and their swatches. There is no way to mix (e.g. client logo + agency colors) — that's by design, so the admin always reads as one coherent brand.

Who can do what

  • The mode radio is available to any member (it appears once Features::enabled('dashboard_branding') is true).
  • designer mode can only be selected by a non-super once a designer logo already exists; a Super can select it first to reveal the upload UI.
  • The designer logo uploads and the four color swatches are Super-only — they live inside the same box and only render in designer mode for a Super. This keeps the agency's own brand assets out of reach of the client's day-to-day admins.

Feature gating — paid members only

Dashboard Branding is a registered feature (dashboard_branding in Features::all(), default: true, available: true). It is default-on for paying members and hidden for everyone else:

  • The entire box and its pill-nav entry render only when Features::enabled('dashboard_branding') is true.
  • AdminLogo::mode() resolves to webprocms whenever the feature is disabled, so a non-member install always shows the platform logo and colors regardless of any stored mode.
  • Membership enforcement is layered on top via the Memberships feature gate (Memberships → Settings → Require membership for features, registered by MembershipsServiceProvider), which vetoes every Features entry for non-members. On an install that opts into that gate, toggling membership off instantly reverts the chrome to WebProCMS.

The color model

Chrome colors are emitted by BrandingStyleService::buildDashboard() as CSS variables in the dashboard's inline <style> block. Two token families carry the chrome brand:

  • --color-cms-primary (+ 19 shades) — the dashboard's brand color: links, active tabs, pills, the sidebar active state, brand buttons, and Flux's --color-accent alias.
  • --color-cms-accent (+ 19 shades) — the accent role: stats numbers, pricing checkmarks, feature icons, charts. Never buttons or links.

Each family is resolved per mode by dashboardColorScheme(), which returns explicit light + dark bases. Light bases are written into :root; dark bases into a trailing .dark { } block (the dashboard toggles .dark on <html>).

Why solid fills keep their base in both themes

generateShadeOklch() normalizes lightness per shade — --color-cms-primary-300 is always a light shade regardless of the base. So:

  • Solid fills (bg-cms-primary buttons, active pills) keep the base color in both light and dark mode — a colored button looks the same in both themes, which is correct. In designer mode the dark swatch can shift hue/chroma, but it is never inverted to a light color.
  • Inline links and active-tab text in dark mode use the lightness-normalized shade (dark:text-primary-300 / dark:text-cms-primary-300) so they stay legible on dark backgrounds.

Auto-contrast button text

Brand buttons reference --color-cms-on-primary for their label color through the text-on-cms-primary utility. onPrimaryFor() computes it from the primary base's OKLCH lightness: a base at lightness ≥ 0.62 (a light/yellow primary) gets dark text; anything darker gets light text. This is computed separately for the light and dark primary bases, so an agency only ever picks a button background — the label contrast is automatic and stays readable on any picked color.

Designer mode color swatches

In designer mode a Super sees four color pickers, each an optional 6-digit hex stored as a Setting:

Swatch Setting Fallback when blank
Primary (light mode) agency.cms_primary_light WebProCMS purple
Primary (dark mode) agency.cms_primary_dark the light primary, then WebProCMS purple
Accent (light mode) agency.cms_accent_light WebProCMS teal
Accent (dark mode) agency.cms_accent_dark the light accent, then WebProCMS teal

Leaving a dark swatch blank reuses its light sibling — the common case where an agency only has one brand color and wants it in both themes. Saving the swatches (or switching modes) busts the BrandingStyleService cache so the new chrome appears on the next dashboard load.

Transactional email chrome

Outgoing feature emails (order notices, booking confirmations, membership dunning, activity alerts, review requests, ticket replies, affiliate invites, social-posting notices) all render a shared header. By default it's the site name as text; the branding box's Transactional Email Logo picker swaps in a logo image (capped at 40px tall) across every one of them at once. The shared renderer is EmailChrome::headerHtml() — feature-gated, so turning Dashboard Branding off reverts every email header to the site-name text. The from name was already white-label: it resolves Marketing's from-name setting, then the business name — never "WebProCMS".

(The shop's order emails keep their own richer logo support via branding.logo_url, and Client Billing keeps its business-name header — invoices identify the billing entity.)

The branding box's Help & Support Links repeater (label + URL rows) renders custom links at the bottom of the dashboard sidebar for every user — point clients at your agency's support desk, docs, or contact page instead of leaving them to hunt. Feature-gated like everything else in the box; blank rows are dropped on save.

What lives where

Path Purpose
app/Support/AdminLogo.php Resolves the effective mode and the light / dark / login logo URLs. Gates on Features::enabled('dashboard_branding').
app/Services/BrandingStyleService.php dashboardColorScheme() (per-mode light/dark bases), onPrimaryFor() (auto-contrast), buildDashboard() (emits :root + .dark chrome tokens).
resources/views/pages/dashboard/settings/⚡general.blade.php The "Dashboard & Login Branding" box — mode radio, designer logo uploads, four color swatches, email-logo picker, help-links repeater, and the save handlers.
app/Support/EmailChrome.php Shared transactional-email header (logo or site name) used by every feature module's email wrapper.
resources/css/app.css @theme declarations for --color-cms-accent (+ shades) and --color-cms-on-primary, plus the text-on-cms-primary utility.
resources/views/components/app-logo.blade.php and the three auth layouts Render the resolved logo on the sidebar and login pages.
tests/Feature/AdminLogoTest.php, tests/Feature/BrandingStyleServiceTest.php Mode resolution, feature gating, per-mode light/dark emission, auto-contrast, swatch persistence.

Marketing angle

Run a fleet of client sites — or sell WebProCMS itself — and the admin shouldn't shout someone else's brand. Dashboard Branding lets a paid member white-label the entire dashboard and login experience in one decision: show the client's own logo and colors, or your agency's. Pick a mode and the sidebar, tabs, links, and buttons all retune to match — light and dark mode handled, button-text contrast set automatically, no CSS to write. Hand a client a dashboard that looks like their product, or stamp every build you ship with your agency's mark.

Notes

  • The feature is one toggle on the Features page; flipping it off reverts the chrome to WebProCMS instantly (logo and colors) without deleting any stored mode or swatches.
  • site mode follows the live site brand — change the primary/secondary on the Colors page and the dashboard chrome follows on the next load. No duplicate color entry.
  • --color-cms-accent is provided as a token for stats/charts; it is intentionally wired to neither buttons nor links. Neutral (zinc/Flux) buttons are never brand-colored — only elements already styled with cms-primary retune per mode.
  • The legacy single "Dashboard Primary Color" override was removed when colors became mode-driven; site mode subsumes it (the dashboard follows the site primary) and designer mode supersedes it with explicit light/dark swatches.