diff --git a/src/app.css b/src/app.css index 00a388f74..63815473f 100644 --- a/src/app.css +++ b/src/app.css @@ -1,5 +1,35 @@ @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400&family=LINE+Seed+JP:wght@400;700&family=Oswald:wght@400;500;600;700&display=swap'); +/* Bundled fonts */ +@font-face { + font-family: 'Montserrat'; + src: url('/fonts/Montserrat-VariableFont_wght.ttf') format('truetype'); + font-weight: 100 900; + font-display: swap; +} + +@font-face { + font-family: 'Noto Sans'; + src: url('/fonts/NotoSans-VariableFont_wdth,wght.ttf') format('truetype'); + font-weight: 100 900; + font-display: swap; +} + +@font-face { + font-family: 'Noto Sans'; + src: url('/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf') format('truetype'); + font-weight: 100 900; + font-style: italic; + font-display: swap; +} + +@font-face { + font-family: 'Source Sans 3'; + src: url('/fonts/SourceSans3-VariableFont_wght.ttf') format('truetype'); + font-weight: 200 900; + font-display: swap; +} + :root { /* QBZ Dark Theme Colors */ --bg-primary: #0f0f0f; @@ -71,6 +101,20 @@ --font-mono: 'JetBrains Mono', monospace; } +/* Font overrides */ +[data-font="montserrat"] { + --font-sans: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; +} +[data-font="noto-sans"] { + --font-sans: 'Noto Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; +} +[data-font="source-sans-3"] { + --font-sans: 'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; +} +[data-font="system"] { + --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; +} + /* Light Theme */ [data-theme="light"] { --bg-primary: #ffffff; diff --git a/src/lib/app/bootstrap.ts b/src/lib/app/bootstrap.ts index 0b08f163a..7daa5ef4a 100644 --- a/src/lib/app/bootstrap.ts +++ b/src/lib/app/bootstrap.ts @@ -27,6 +27,16 @@ export function loadSavedTheme(): void { } } +/** + * Load and apply saved font family from localStorage + */ +export function loadSavedFont(): void { + const savedFont = localStorage.getItem('qbz-font-family'); + if (savedFont) { + document.documentElement.setAttribute('data-font', savedFont); + } +} + /** * Apply saved UI zoom level (Tauri webview zoom) */ @@ -124,8 +134,9 @@ export interface BootstrapResult { * @returns Object with cleanup function for onDestroy */ export function bootstrapApp(): BootstrapResult { - // Load theme + // Load theme and font loadSavedTheme(); + loadSavedFont(); void applySavedZoom(); // Load notification preferences diff --git a/src/lib/components/views/SettingsView.svelte b/src/lib/components/views/SettingsView.svelte index 49f3ff8e0..ee4ae151e 100644 --- a/src/lib/components/views/SettingsView.svelte +++ b/src/lib/components/views/SettingsView.svelte @@ -548,6 +548,38 @@ // Available languages (only those with translations) const availableLanguages = ['Auto', 'English', 'Español', 'Français', 'Deutsch']; + // Font family selection + const fontFamilies: Record = { + 'LINE Seed JP': '', // default (no data-font attribute) + 'Montserrat': 'montserrat', + 'Noto Sans': 'noto-sans', + 'Source Sans 3': 'source-sans-3', + 'System': 'system', + }; + + const fontReverseMap: Record = Object.fromEntries( + Object.entries(fontFamilies).map(([name, val]) => [val, name]) + ); + + const fontOptions = Object.keys(fontFamilies); + + let selectedFont = $state('LINE Seed JP'); + + function applyFont(fontValue: string) { + if (fontValue) { + document.documentElement.setAttribute('data-font', fontValue); + } else { + document.documentElement.removeAttribute('data-font'); + } + } + + function handleFontChange(newFont: string) { + selectedFont = newFont; + const fontValue = fontFamilies[newFont] || ''; + applyFont(fontValue); + localStorage.setItem('qbz-font-family', fontValue); + } + // Audio settings let streamingQuality = $state('Hi-Res+'); let outputDevice = $state('System Default'); @@ -887,6 +919,11 @@ theme = themeReverseMap[savedTheme] || 'Dark'; applyTheme(savedTheme); + // Load font + const savedFont = localStorage.getItem('qbz-font-family') || ''; + selectedFont = fontReverseMap[savedFont] || 'LINE Seed JP'; + applyFont(savedFont); + // Load streaming quality preference const savedQuality = getUserItem('qbz-streaming-quality'); if (savedQuality) { @@ -3561,6 +3598,14 @@ onchange={handleLanguageChange} /> +
+ {$t('settings.appearance.fontFamily')} + +
{$t('settings.appearance.uiScale')}