@@ -477,6 +477,36 @@ ${footerImport}
477477import { getConfigFile } from '../utils/config';
478478
479479const config = await getConfigFile();
480+
481+ // Font configuration
482+ const fonts = config.branding?.fonts;
483+ const headingFont = fonts?.heading || 'Syne';
484+ const bodyFont = fonts?.body || 'Inter';
485+ const codeFont = fonts?.code || 'Fira Code';
486+
487+ const fontFamilies = [];
488+ if (bodyFont === 'Inter') {
489+ fontFamilies.push('Inter:opsz,wght@14..32,400..700');
490+ } else {
491+ fontFamilies.push(bodyFont.replace(/ /g, '+') + ':wght@400;500;600;700');
492+ }
493+ if (headingFont !== bodyFont) {
494+ fontFamilies.push(headingFont.replace(/ /g, '+') + ':wght@600;700;800');
495+ }
496+ fontFamilies.push(codeFont.replace(/ /g, '+') + ':wght@400;500;600');
497+ const googleFontsUrl = 'https://fonts.googleapis.com/css2?' + fontFamilies.map(f => 'family=' + f).join('&') + '&display=swap';
498+
499+ const fontOverrides = [];
500+ if (bodyFont !== 'Inter') {
501+ fontOverrides.push("--font-sans: '" + bodyFont + "', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif !important;");
502+ }
503+ if (headingFont !== 'Syne') {
504+ fontOverrides.push("--font-heading: '" + headingFont + "', '" + bodyFont + "', system-ui, sans-serif !important;");
505+ }
506+ if (codeFont !== 'Fira Code') {
507+ fontOverrides.push("--font-mono: '" + codeFont + "', 'JetBrains Mono', 'SF Mono', Monaco, Consolas, monospace !important;");
508+ }
509+ const fontOverrideStyle = fontOverrides.length > 0 ? ':root { ' + fontOverrides.join(' ') + ' }' : '';
480510---
481511
482512<!doctype html>
@@ -489,7 +519,8 @@ const config = await getConfigFile();
489519 <link rel="icon" href={config.branding?.favicon || '/favicon.svg'} />
490520 <link rel="preconnect" href="https://fonts.googleapis.com" />
491521 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
492- <link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400..700&family=Fira+Code:wght@400;500;600&display=swap" rel="stylesheet" />
522+ <link href={googleFontsUrl} rel="stylesheet" />
523+ {fontOverrideStyle && <style set:html={fontOverrideStyle} />}
493524 <script is:inline>
494525 const savedTheme = localStorage.getItem('theme');
495526 const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
@@ -837,6 +868,36 @@ ${footerImport}
837868import { getConfigFile } from '../utils/config';
838869
839870const config = await getConfigFile();
871+
872+ // Font configuration
873+ const fonts = config.branding?.fonts;
874+ const headingFont = fonts?.heading || 'Syne';
875+ const bodyFont = fonts?.body || 'Inter';
876+ const codeFont = fonts?.code || 'Fira Code';
877+
878+ const fontFamilies = [];
879+ if (bodyFont === 'Inter') {
880+ fontFamilies.push('Inter:opsz,wght@14..32,400..700');
881+ } else {
882+ fontFamilies.push(bodyFont.replace(/ /g, '+') + ':wght@400;500;600;700');
883+ }
884+ if (headingFont !== bodyFont) {
885+ fontFamilies.push(headingFont.replace(/ /g, '+') + ':wght@600;700;800');
886+ }
887+ fontFamilies.push(codeFont.replace(/ /g, '+') + ':wght@400;500;600');
888+ const googleFontsUrl = 'https://fonts.googleapis.com/css2?' + fontFamilies.map(f => 'family=' + f).join('&') + '&display=swap';
889+
890+ const fontOverrides = [];
891+ if (bodyFont !== 'Inter') {
892+ fontOverrides.push("--font-sans: '" + bodyFont + "', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif !important;");
893+ }
894+ if (headingFont !== 'Syne') {
895+ fontOverrides.push("--font-heading: '" + headingFont + "', '" + bodyFont + "', system-ui, sans-serif !important;");
896+ }
897+ if (codeFont !== 'Fira Code') {
898+ fontOverrides.push("--font-mono: '" + codeFont + "', 'JetBrains Mono', 'SF Mono', Monaco, Consolas, monospace !important;");
899+ }
900+ const fontOverrideStyle = fontOverrides.length > 0 ? ':root { ' + fontOverrides.join(' ') + ' }' : '';
840901---
841902
842903<!doctype html>
@@ -848,7 +909,8 @@ const config = await getConfigFile();
848909 <link rel="icon" href={config.branding?.favicon || '/favicon.svg'} />
849910 <link rel="preconnect" href="https://fonts.googleapis.com" />
850911 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
851- <link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400..700&display=swap" rel="stylesheet" />
912+ <link href={googleFontsUrl} rel="stylesheet" />
913+ {fontOverrideStyle && <style set:html={fontOverrideStyle} />}
852914 <script is:inline>
853915 const savedTheme = localStorage.getItem('theme');
854916 const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
0 commit comments