From 1f6e05f7ddf3b03c0364dac7c3e068f512369d41 Mon Sep 17 00:00:00 2001 From: Tao Xie Date: Fri, 17 Jul 2026 11:04:50 +0800 Subject: [PATCH 1/3] feat(web): add UI font family preference to appearance settings The web settings exposed color scheme, accent, and font size, but the font family was pinned to the Inter-first stack. Add a Font preference (desktop SettingsDialog + mobile MobileSettingsSheet) with Default (Inter), System (platform UI stack), and Serif (reading-oriented stack) faces. The choice persists in localStorage, mirrors onto , and remaps the --font-ui token, so UI and reading text switch with zero component changes while --font-mono stays put. Both alternate stacks use locally installed fonts only, so nothing extra is downloaded. Documents the new tokens in the design-system view. --- .changeset/web-ui-font-family.md | 5 +++ apps/kimi-web/src/App.vue | 4 ++ .../components/mobile/MobileSettingsSheet.vue | 24 +++++++++++- .../components/settings/SettingsDialog.vue | 16 +++++++- .../src/composables/client/useAppearance.ts | 37 +++++++++++++++++-- .../src/composables/useKimiWebClient.ts | 4 +- apps/kimi-web/src/i18n/locales/en/theme.ts | 4 ++ apps/kimi-web/src/i18n/locales/zh/theme.ts | 4 ++ apps/kimi-web/src/lib/storage.ts | 1 + apps/kimi-web/src/style.css | 25 +++++++++++++ apps/kimi-web/src/views/DesignSystemView.vue | 4 ++ 11 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 .changeset/web-ui-font-family.md diff --git a/.changeset/web-ui-font-family.md b/.changeset/web-ui-font-family.md new file mode 100644 index 0000000000..3315522130 --- /dev/null +++ b/.changeset/web-ui-font-family.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +web: Add a font family preference to Appearance settings (desktop dialog + mobile sheet) with Default (Inter), System, and Serif faces. The choice remaps the `--font-ui` token via ``, so UI and reading text switch fonts while code stays monospace; both alternate stacks use locally installed fonts, so nothing extra is downloaded. diff --git a/apps/kimi-web/src/App.vue b/apps/kimi-web/src/App.vue index 5708bcc9bf..4bcfc4d8aa 100644 --- a/apps/kimi-web/src/App.vue +++ b/apps/kimi-web/src/App.vue @@ -990,6 +990,7 @@ function openPr(url: string): void { :color-scheme="client.colorScheme.value" :accent="client.accent.value" :ui-font-size="client.uiFontSize.value" + :ui-font-family="client.uiFontFamily.value" :auth-ready="client.authReady.value" :account-model="client.defaultModel.value" :notify="client.notifyOnComplete.value" @@ -1006,6 +1007,7 @@ function openPr(url: string): void { @set-color-scheme="client.setColorScheme($event)" @set-accent="client.setAccent($event)" @set-ui-font-size="client.setUiFontSize($event)" + @set-ui-font-family="client.setUiFontFamily($event)" @set-notify="client.setNotifyOnComplete($event)" @set-notify-question="client.setNotifyOnQuestion($event)" @set-notify-approval="client.setNotifyOnApproval($event)" @@ -1108,6 +1110,7 @@ function openPr(url: string): void { :swarm-mode="client.swarmMode.value" :color-scheme="client.colorScheme.value" :ui-font-size="client.uiFontSize.value" + :ui-font-family="client.uiFontFamily.value" :auth-ready="client.authReady.value" :conversation-toc="client.conversationToc.value" :server-version="client.serverVersion.value" @@ -1118,6 +1121,7 @@ function openPr(url: string): void { @set-permission="client.setPermission($event)" @set-color-scheme="client.setColorScheme($event)" @set-ui-font-size="client.setUiFontSize($event)" + @set-ui-font-family="client.setUiFontFamily($event)" @set-conversation-toc="client.setConversationToc($event)" @login="() => { showMobileSettings = false; openLogin(); }" @logout="client.logout" diff --git a/apps/kimi-web/src/components/mobile/MobileSettingsSheet.vue b/apps/kimi-web/src/components/mobile/MobileSettingsSheet.vue index 6e80a74fe1..9d70ab72a4 100644 --- a/apps/kimi-web/src/components/mobile/MobileSettingsSheet.vue +++ b/apps/kimi-web/src/components/mobile/MobileSettingsSheet.vue @@ -10,7 +10,7 @@ import { computed, ref, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import type { ConversationStatus, PermissionMode } from '../../types'; import type { AppModel, AppSession, ThinkingLevel } from '../../api/types'; -import type { ColorScheme } from '../../composables/useKimiWebClient'; +import type { ColorScheme, UiFontFamily } from '../../composables/useKimiWebClient'; import { useKimiWebClient } from '../../composables/useKimiWebClient'; import { commitLevel, @@ -37,6 +37,7 @@ const props = withDefaults( swarmMode?: boolean; colorScheme?: ColorScheme; uiFontSize?: number; + uiFontFamily?: UiFontFamily; authReady?: boolean; conversationToc?: boolean; /** Server version from GET /api/v1/meta, shown as a read-only row. */ @@ -47,6 +48,7 @@ const props = withDefaults( { colorScheme: 'system', uiFontSize: 14, + uiFontFamily: 'default', authReady: false, serverVersion: '', models: () => [], @@ -62,6 +64,7 @@ const emit = defineEmits<{ setPermission: [mode: PermissionMode]; setColorScheme: [colorScheme: ColorScheme]; setUiFontSize: [size: number]; + setUiFontFamily: [font: UiFontFamily]; setConversationToc: [on: boolean]; login: []; logout: []; @@ -71,6 +74,10 @@ function onColorScheme(v: string): void { emit('setColorScheme', v as ColorScheme); } +function onUiFontFamily(v: string): void { + emit('setUiFontFamily', v as UiFontFamily); +} + const PERM_MODES: PermissionMode[] = ['manual', 'auto', 'yolo']; // Identity is the model id — display/model names can collide across providers. @@ -364,6 +371,21 @@ watch( +
+ + {{ t('theme.fontLabel') }} + + +
+