Canonical Rebrand — Brand-Surface Map
Authored S406 (2026-06-23) from a 4-angle codebase sweep (app + docs-site + mcp-apps,
65 surfaces). Companion to the docs-site wiring tracker CANONICAL-REBRAND-FOLLOWUP.md
(repo-slug layer, mostly done) — this doc is the visual / product-identity layer that
the brand-direction decision unblocks.
No real users yet (S406, Liam). The MCP server name, plugin download filename, the two mcp-app UI strings, and all cosmetic items can be changed without any risk — there are no saved connectors or live installs to break. The connector-identity caveat noted against the MCP server-name below is therefore moot; treat every string item as a free edit. This means the brand session is gated on one thing only: the visual wordmark/logo decision.
Core architecture finding
Section titled “Core architecture finding”The app brand is config-driven through a single seam:
lib/branding/clients/default.json → loaded by loadBranding() → exported as BRANDING
(lib/client-config.ts:644) → consumed by every app UI / metadata / export surface.
Name-strings are already ~90% rebranded (productName / productShortName /
organisationName = "Canonical"). What remains is only:
- (a) visual assets still showing the old “KH” / “Knowledge Hub” marks, and
- (b) hardcoded strings in surfaces that don’t import
BRANDING(MCP server/apps, docs-site wordmark SVG) — all now zero-risk per the note above.
Legend: [L] logo-asset (redraw image) · [W] wordmark-render (text mark in UI) · [N] name-string (config/metadata text)
⭐ Single highest-leverage item
Section titled “⭐ Single highest-leverage item”lib/branding/clients/default.json — the central brand constant. [N]
One JSON edit ripples to: <title> + favicons (app/layout.tsx), header logo + alt +
sr-only (brand-logo.tsx), mobile drawer (site-header.tsx:168), login h1 + aria
(login/page.tsx), OAuth consent (oauth/consent/page.tsx), DOCX/XLSX/PDF exports, RSS
generator, provenance labels. Already set to “Canonical” for names — but still binds
logoUrl / faviconSvgUrl to the placeholder /favicon.svg and supportEmail to the
old @knowledgehub.dev domain. After editing, run bun run generate:branding to
repopulate lib/branding/client-branding-map.generated.ts.
Runner-up: public/favicon.svg serves triple duty (browser favicon + header logo +
drawer logo via logoUrl=/favicon.svg) and still shows the dark rounded-square “KH”
lockup. Replacing this one asset fixes the most-seen app mark.
App shell / nav
Section titled “App shell / nav”| Surface | Kind | Location | Status |
|---|---|---|---|
BrandLogo component (only logo-drawing component) | [L] | components/shell/brand-logo.tsx:26 | Config-driven, no code change — inherits asset swap |
| Site header (ONLY render site of BrandLogo) | [W] | components/shell/site-header.tsx:99 | Config-driven |
Mobile drawer title (productShortName) | [W] | components/shell/site-header.tsx:168 | Config-driven |
| Home page heading | [W] | app/page.tsx:323 | Config-driven (already reads “Canonical”) |
Note: if the new brand is a wide wordmark rather than a square icon, also update
logoAspectRatio / logoMaxWidthPx (currently 1:1 / 32px) and add a separate
logoUrlDark in default.json (none set today — dark mode falls back to light).
Auth / login
Section titled “Auth / login”| Surface | Kind | Location | Status |
|---|---|---|---|
| Login h1 + aria-label | [W] | app/login/page.tsx:608,614 | Config-driven |
| Login subtitle “Sign in to your knowledge base” | [W] | app/login/page.tsx:619 | HARDCODED — KH-flavoured copy, fix by hand |
localStorage key kh-stay-signed-in | [N] | app/login/page.tsx:57,444 | Non-visible legacy prefix (free cleanup) |
| Login error page | [W] | app/login/error.tsx:26 | Config-driven |
| OAuth consent screen (3rd-party identity) | [W] | app/oauth/consent/page.tsx:86,180 | Config-driven |
Metadata & PWA
Section titled “Metadata & PWA”| Surface | Kind | Location | Status |
|---|---|---|---|
| Root metadata: title / description / icons | [N] | app/layout.tsx:26-40 | Config-driven (cache-busted by commit SHA) |
CLIENT_CONFIG.client_name = 'Knowledge Hub' | [N] | lib/client-config.ts:107 | HARDCODED legacy feature-config (NOT BRANDING) — reconcile to Canonical |
| Generated branding map | [N] | lib/branding/client-branding-map.generated.ts | Build artefact — regenerate, no manual edit |
RSS <generator> tag | [N] | lib/intelligence/rss-generator.ts:67 | Config-driven |
PWA gap (add, not replace): no app/icon.tsx, app/apple-icon.*,
app/opengraph-image.*, apple-touch-icon, or site.webmanifest exist — i.e. there is
currently no apple-touch-icon and no OG/social-share image for the app. The rebrand can
opt to add these.
Favicon & icons
Section titled “Favicon & icons”| Surface | Kind | Location | Status |
|---|---|---|---|
public/favicon.svg (favicon + header logo + drawer) | [L] | public/favicon.svg | PLACEHOLDER — dark square, white “KH”. Triple-duty. Top app asset to redraw |
public/favicon.png (raster fallback, required field) | [L] | public/favicon.png | PLACEHOLDER “KH” raster — re-export from new mark |
| Asset→slot bindings | [N] | lib/branding/clients/default.json:9,13,14 | Repoint logoUrl / logoUrlDark here if splitting wordmark vs icon |
| Surface | Kind | Location | Status |
|---|---|---|---|
supportEmail = support@knowledgehub.dev | [N] | lib/branding/clients/default.json:7 | OLD DOMAIN — surfaces in OAuth consent / settings / error pages. Change to a canonical.* domain |
MCP-app UIs (none import BRANDING — all literal edits, all zero-risk)
Section titled “MCP-app UIs (none import BRANDING — all literal edits, all zero-risk)”| Surface | Kind | Location | Status |
|---|---|---|---|
MCP server handshake name: 'knowledge-hub' | [N] | app/api/mcp/[transport]/route.ts:101 | Machine name shown to Claude.ai/Desktop. Rename to canonical freely — no users → no connector breakage |
| MCP system-prompt persona (“AI assistant for the Knowledge Hub…”) | [N] | lib/mcp/resources.ts:810,939 | HARDCODED AI-facing copy |
| Settings → Connections config snippet (server key + plugin path) | [N] | components/settings/connections-section.tsx:396,403,494 | HARDCODED — must match the MCP server-name decision |
Plugin download filename knowledge-hub-plugin.zip | [N] | app/api/plugin/download/route.ts:30,9 | HARDCODED user-visible download name |
| form-dashboard “View in Knowledge Hub →” + aria | [W] | mcp-apps/form-dashboard/src/app.ts:436,441,444 | HARDCODED — edit source AND rebuild bundle |
| reorient-me welcome copy | [W] | mcp-apps/reorient-me/src/app.ts:205 | HARDCODED — edit source AND rebuild bundle |
| Prebuilt bundle (bakes the two strings above) | [N] | lib/mcp/app-bundles.ts:340 | Must be rebuilt after editing mcp-apps sources |
Note: per-app HTML <title> tags (“Bid Dashboard”, “Coverage Matrix”…) are feature names,
not brand surfaces — no change needed.
Sales / PDF exports (all config-driven — inherit “Canonical”)
Section titled “Sales / PDF exports (all config-driven — inherit “Canonical”)”| Surface | Kind | Location | Status |
|---|---|---|---|
| DOCX bid cover page company name | [W] | lib/procurement/procurement-export-docx.ts:829,335-348 | Config-driven |
DOCX export-types doc-comment (default: "Knowledge Hub") | [N] | lib/procurement/procurement-export-types.ts:58-59 | Stale comment only — cosmetic |
XLSX workbook.creator metadata | [N] | lib/procurement/procurement-export-xlsx.ts:441 | Config-driven |
| Provenance / verification-history PDF (header + footer) | [W] | components/provenance/report-document.tsx:262,278 | Config-driven (closest thing to a branded PDF) |
| AI provenance label | [N] | lib/provenance/item-provenance.ts:83 | Config-driven |
Docs-site (knowledge-hub-docs-site)
Section titled “Docs-site (knowledge-hub-docs-site)”| Surface | Kind | Location | Status |
|---|---|---|---|
| Header wordmark SVG (most visible un-rebranded surface) | [W] | src/assets/kh-wordmark.svg | PLACEHOLDER — literally <text>Knowledge Hub</text>. replacesTitle:true makes it THE header. Redraw as “Canonical”; rename off kh- prefix |
Starlight title:'Canonical' + logo.src + description | [N] | astro.config.mjs:34,37-40 | Title/description already rebranded; logo points at placeholder above |
| Docs favicon | [L] | astro.config.mjs (no favicon: key) | GAP — uses Starlight default; add a Canonical favicon |
editLink GitHub repo slug | [N] | astro.config.mjs:110 | Repoint if docs repo renamed |
Site URL placeholder vercel-default-subdomain… | [N] | astro.config.mjs:~30 | Set real URL |
Package identity (canonical-docs / canonical-internal) | [N] | package.json:2 | Already rebranded — internal only |
| Asset-gap already logged | — | CANONICAL-REBRAND-FOLLOWUP.md:90 | Confirms kh-wordmark.svg replacement is a known item |
Brand-direction session checklist
Section titled “Brand-direction session checklist”The wordmark/logo decision is the only gating dependency. Ordered by what it unblocks:
- Decide the core identity: wordmark-vs-icon lockup, primary mark, light + dark variants, brand-primary colour. (This is the single decision; everything below is execution.)
- Decide the mark shape → determines whether you also update
logoAspectRatio/logoMaxWidthPxand add a separatelogoUrlDarkindefault.json(square icon = swap-only; wide wordmark = config change too). - Produce the app asset set:
public/favicon.svg(redraw),public/favicon.png(re-export). Optionally add the missing apple-icon + opengraph-image + webmanifest. - Produce the docs-site wordmark: replace
src/assets/kh-wordmark.svgand add a docs favicon → wire intoastro.config.mjs. - Edit the central config (
default.json): repointlogoUrl/logoUrlDark/ favicon paths to the new assets, fixsupportEmailto acanonical.*domain, refreshtagline→ thenbun run generate:branding. - String sweep — all zero-risk, do anytime (no users): MCP server
name, system-prompt persona, settings snippet, plugin ZIP filename, the two mcp-app UI strings → rebuild the bundle (lib/mcp/app-bundles.ts); plusclient_nameconstant, stale doc-comments, login subtitle,kh-localStorage/filename prefixes.
Bottom line: the visual decision (step 1) unblocks steps 2–5; step 6 is independent string work that can land in parallel — and, with no users to break, carries no risk.
See also
Section titled “See also”CANONICAL-REBRAND-FOLLOWUP.md(repo root) — the docs-site wiring layer (repo-slug repoint), mostly complete.- Design system:
design/warm-meridian-implementation-spec.md,design/warm-meridian-philosophy.md,design/token-system.md(brand-primary colour lives in the token system). - Claude Design canvas: the
.design-sync/lane (Warm Meridian primitives synced to the Canonical claude.ai/design project) — where the wordmark/typography exploration happens; brief the design agent via.design-sync/conventions.md.