From 352ae4f25676d12e87bf543f108e2afd36d3eb25 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 18 Jul 2026 16:40:09 -0500 Subject: [PATCH] feat(brand): default favicon emblem + Powered By footer badge Ship the Runic Gateway emblem as the baked-in default favicon so an instance renders a tab icon with no BRAND_FAVICON set, and place a left-justified "Powered By" badge in the site footer. - brand.favicon now defaults to /assets/img/favicon.ico (was empty). BRAND_FAVICON still overrides per-instance. - Add favicon.ico + powered-by.svg under client/public/assets/img. - SiteFooter: badge pinned to the left of the centered content column (absolute on >=641px, stacked on mobile); info text stays centered. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01XmHdsbnLzDMAVQkAoTQSBe --- client/public/assets/img/favicon.ico | Bin 0 -> 4286 bytes client/public/assets/img/powered-by.svg | 1 + client/src/components/SiteFooter.jsx | 40 +++++++++++++---------- client/src/styles/theme.css | 41 ++++++++++++++++++++++++ server/src/config/brand.js | 2 +- 5 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 client/public/assets/img/favicon.ico create mode 100644 client/public/assets/img/powered-by.svg diff --git a/client/public/assets/img/favicon.ico b/client/public/assets/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..77b502d5f237bc21fb39c1b64fc1f4d058997ffb GIT binary patch literal 4286 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 \ No newline at end of file diff --git a/client/src/components/SiteFooter.jsx b/client/src/components/SiteFooter.jsx index 526fd8e..a6f7c98 100644 --- a/client/src/components/SiteFooter.jsx +++ b/client/src/components/SiteFooter.jsx @@ -5,31 +5,37 @@ export default function SiteFooter() { const { contactEmail, siteTitle } = useSite() return ( ) diff --git a/client/src/styles/theme.css b/client/src/styles/theme.css index eae23ab..0683b98 100644 --- a/client/src/styles/theme.css +++ b/client/src/styles/theme.css @@ -1009,6 +1009,47 @@ button[disabled] { border-color: #8a4b47; } +/* Site footer: powered-by badge left-justified, info centered. */ +.site-footer-inner { + position: relative; + display: flex; + align-items: center; + justify-content: center; + gap: 16px; + max-width: 1100px; + margin: 0 auto; +} +.site-footer-badge { + height: 56px; + width: auto; + flex: 0 0 auto; + opacity: 0.85; +} +.site-footer-info { + display: flex; + flex-direction: column; + align-items: center; + gap: 6px; + text-align: center; +} +/* Pin the badge to the left while the info column stays visually centered. */ +@media (min-width: 641px) { + .site-footer-badge { + position: absolute; + left: 0; + top: 50%; + transform: translateY(-50%); + } +} +@media (max-width: 640px) { + .site-footer-inner { + flex-direction: column; + } + .site-footer-badge { + height: 44px; + } +} + /* Draft-preview banner on the public renderer. */ .page-preview-banner { border: 1px solid var(--accent); diff --git a/server/src/config/brand.js b/server/src/config/brand.js index 9ee7a28..9b3a0c8 100644 --- a/server/src/config/brand.js +++ b/server/src/config/brand.js @@ -32,7 +32,7 @@ const brand = { accent: process.env.BRAND_ACCENT_COLOR || '#7f99bd', logo: process.env.BRAND_LOGO || '', // empty → no logo image rendered hero: process.env.BRAND_HERO || '/assets/img/hero-moon.png', - favicon: process.env.BRAND_FAVICON || '', // empty → no favicon link injected + favicon: process.env.BRAND_FAVICON || '/assets/img/favicon.ico', // Runic Gateway default emblem } // Discord embeds want an int (0xRRGGBB). Parse the accent hex once; fall back to