diff --git a/frontend/editor/src/core/constants/logo.ts b/frontend/editor/src/core/constants/logo.ts index d73f14b4a7..ad958d2502 100644 --- a/frontend/editor/src/core/constants/logo.ts +++ b/frontend/editor/src/core/constants/logo.ts @@ -5,6 +5,27 @@ export const LOGO_FOLDER_BY_VARIANT: Record = { classic: "classic-logo", }; +/** + * Wordmark filenames per variant. The modern wordmark dropped "PDF" from the + * artwork, so it is a different file rather than a same-named copy. + */ +export const WORDMARK_FILES_BY_VARIANT: Record< + LogoVariant, + { black: string; grey: string; white: string } +> = { + modern: { + black: "StirlingLogoBlackText.svg", + // No modern grey artwork exists; muted falls back to the black wordmark. + grey: "StirlingLogoBlackText.svg", + white: "StirlingLogoWhiteText.svg", + }, + classic: { + black: "StirlingPDFLogoBlackText.svg", + grey: "StirlingPDFLogoGreyText.svg", + white: "StirlingPDFLogoWhiteText.svg", + }, +}; + export const ensureLogoVariant = (value?: string | null): LogoVariant => { return value === "classic" ? "classic" : "modern"; }; diff --git a/frontend/editor/src/core/hooks/useLogoAssets.test.ts b/frontend/editor/src/core/hooks/useLogoAssets.test.ts index 3d83fb35f4..4c90760b9d 100644 --- a/frontend/editor/src/core/hooks/useLogoAssets.test.ts +++ b/frontend/editor/src/core/hooks/useLogoAssets.test.ts @@ -1,7 +1,10 @@ import { describe, expect, test } from "vitest"; import * as fs from "fs"; import * as path from "path"; -import { LOGO_FOLDER_BY_VARIANT } from "@app/constants/logo"; +import { + LOGO_FOLDER_BY_VARIANT, + WORDMARK_FILES_BY_VARIANT, +} from "@app/constants/logo"; import type { LogoVariant } from "@app/services/preferencesService"; /** @@ -16,16 +19,15 @@ describe("useLogoAssets - Logo Asset Files", () => { // referencing them by their public-URL path. Validate them at source. const brandDir = path.resolve(__dirname, "../assets/brand"); - // All asset files that useLogoAssets references + // Asset files useLogoAssets references for every variant. const requiredAssets = [ "logo-tooltip.svg", "Firstpage.png", "favicon.ico", "logo192.png", "logo512.png", - "StirlingPDFLogoWhiteText.svg", - "StirlingPDFLogoBlackText.svg", - "StirlingPDFLogoGreyText.svg", + "StirlingPDFLogoNoTextDark.svg", + "StirlingPDFLogoNoTextLight.svg", ]; const logoVariants: LogoVariant[] = ["modern", "classic"]; @@ -45,6 +47,36 @@ describe("useLogoAssets - Logo Asset Files", () => { `Missing asset: ${folder}/${assetName}`, ).toBe(true); }); + + test.each(Object.entries(WORDMARK_FILES_BY_VARIANT[variant]))( + "should have the %s wordmark (%s)", + (_tone, assetName) => { + const assetPath = path.join(folderPath, assetName); + expect( + fs.existsSync(assetPath), + `Missing asset: ${folder}/${assetName}`, + ).toBe(true); + }, + ); + }); + + // Regression guard: modern once shipped byte-identical copies of the classic + // wordmarks, so every rendered the old artwork on the default variant. + describe("modern artwork must not be a copy of classic", () => { + const modernDir = path.join(brandDir, LOGO_FOLDER_BY_VARIANT.modern); + const classicDir = path.join(brandDir, LOGO_FOLDER_BY_VARIANT.classic); + const modernOnly = Object.values(WORDMARK_FILES_BY_VARIANT.modern); + + test.each([...new Set(modernOnly)])("%s differs from classic", (name) => { + const classicTwin = path.join(classicDir, name); + if (!fs.existsSync(classicTwin)) return; + expect( + fs + .readFileSync(path.join(modernDir, name)) + .equals(fs.readFileSync(classicTwin)), + `modern-logo/${name} is byte-identical to classic-logo/${name}`, + ).toBe(false); + }); }); describe("manifest files", () => { diff --git a/frontend/editor/src/core/hooks/useLogoAssets.ts b/frontend/editor/src/core/hooks/useLogoAssets.ts index 8fd0ad4ba5..fd19fd596f 100644 --- a/frontend/editor/src/core/hooks/useLogoAssets.ts +++ b/frontend/editor/src/core/hooks/useLogoAssets.ts @@ -1,6 +1,10 @@ import { useMemo } from "react"; import { BASE_PATH } from "@app/constants/app"; -import { getLogoFolder } from "@app/constants/logo"; +import { + getLogoFolder, + ensureLogoVariant, + WORDMARK_FILES_BY_VARIANT, +} from "@app/constants/logo"; import { useLogoVariant } from "@app/hooks/useLogoVariant"; export function useLogoAssets() { @@ -9,6 +13,8 @@ export function useLogoAssets() { return useMemo(() => { const folder = getLogoFolder(logoVariant); const folderPath = `${BASE_PATH}/${folder}`; + const wordmarkFiles = + WORDMARK_FILES_BY_VARIANT[ensureLogoVariant(logoVariant)]; return { logoVariant, @@ -16,9 +22,9 @@ export function useLogoAssets() { folderPath, getAssetPath: (name: string) => `${folderPath}/${name}`, wordmark: { - black: `${folderPath}/StirlingPDFLogoBlackText.svg`, - grey: `${folderPath}/StirlingPDFLogoGreyText.svg`, - white: `${folderPath}/StirlingPDFLogoWhiteText.svg`, + black: `${folderPath}/${wordmarkFiles.black}`, + grey: `${folderPath}/${wordmarkFiles.grey}`, + white: `${folderPath}/${wordmarkFiles.white}`, }, tooltipLogo: `${folderPath}/logo-tooltip.svg`, firstPage: `${folderPath}/Firstpage.png`,