Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/design-system/foundations.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

### Font families

- `--font-ui`: 일반 UI, 제목, 본문, 버튼, 입력. Pretendard/Noto Sans KR/Apple SD Gothic Neo/Malgun Gothic을 포함해 한글 fallback을 보장한다.
- `--font-ui`: 일반 UI, 제목, 본문, 버튼, 입력. 제품 서체를 우선하고, 그 뒤에는 시스템 UI 폰트를 영문도 지원하는 한글 fallback보다 먼저 선언한다. 그래야 한글 fallback이 시스템 UI 폰트의 영문·숫자 글리프까지 대신 표시하지 않는다. 한글은 앞선 서체의 지원 여부에 따라 시스템의 언어별 fallback 또는 뒤에 선언된 한글 글꼴로 표시한다.
- `--font-code`: 모델 ID, URL, 버전, 토큰 수, 로그, 코드. 숫자는 tabular 형태로 정렬한다.

외부 CDN 폰트를 사용하지 않는다. 프록시 관리 화면은 오프라인에서도 열려야 하고, 폰트
Expand Down
4 changes: 2 additions & 2 deletions gui/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@
--radius-round: 50%;
--radius-pill: 999px;

/* typography: product UI first, Korean-safe fallbacks, mono only for machine data */
--font-ui: "OpenAI Sans", "Pretendard Variable", Pretendard, "Noto Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
/* Keep product fonts first, then system UI fonts before Korean fallbacks that also cover Latin. */
--font-ui: "OpenAI Sans", "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", sans-serif;
--font-code: ui-monospace, "SFMono-Regular", "Cascadia Code", "JetBrains Mono", "Noto Sans Mono CJK KR", Menlo, Consolas, monospace;
--font: var(--font-ui);
--mono: var(--font-code);
Expand Down
26 changes: 26 additions & 0 deletions gui/tests/ui-font-fallback.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect, test } from "bun:test";

const css = await Bun.file(new URL("../src/styles.css", import.meta.url)).text();
const fontStack = css.replace(/\/\*[\s\S]*?\*\//g, "")
.match(/--font-ui\s*:\s*([^;]+);/)?.[1];
if (!fontStack) throw new Error("The UI font stack is missing.");
const families = fontStack.split(",").map(family =>
family.trim().replace(/^(["'])(.*)\1$/, "$2"),
);

test("product fonts retain priority in the UI font stack", () => {
expect(families.slice(0, 3)).toEqual(["OpenAI Sans", "Pretendard Variable", "Pretendard"]);
});

// Keep system fonts ahead of Apple SD Gothic Neo, which also covers Latin.
// This guards fallback order; actual glyph selection requires a browser check.
test.each(["-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "system-ui"])(
"%s precedes Apple SD Gothic Neo in the UI font stack",
systemFont => {
const systemIndex = families.indexOf(systemFont);
const koreanIndex = families.indexOf("Apple SD Gothic Neo");
expect(systemIndex).toBeGreaterThanOrEqual(0);
expect(koreanIndex).toBeGreaterThanOrEqual(0);
expect(systemIndex).toBeLessThan(koreanIndex);
},
);
Loading