From a4456743a6dd05343d41e9a7af9ecdb2f1875812 Mon Sep 17 00:00:00 2001 From: Alex Ivantsov Date: Mon, 20 Jul 2026 13:28:49 -0400 Subject: [PATCH] =?UTF-8?q?fix(ui):=20quote=20multi-word=20font=20families?= =?UTF-8?q?=20=E2=80=94=20unquoted=20"Noto=20Sans=20Symbols=202"=20killed?= =?UTF-8?q?=20the=20whole=20stack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tailwind emits fontFamily entries verbatim into CSS. "Noto Sans Symbols 2" unquoted ends in a bare digit, which is not a valid CSS identifier — making the ENTIRE font-family declaration invalid, silently dropped by Chromium. Consequences since the stack gained that entry: the UI fell back to the browser default font (so JetBrains Mono never showed), and because nothing referenced the emoji family anymore, the bundled emoji font never loaded — emoji rendered blank regardless of font flavor. Families needing quotes now carry them in tailwind.config.js, with a comment explaining the trap. Verified against the real built app under xvfb on a machine with no fonts installed: body computes the JetBrains Mono stack, the latin subset loads, and a screenshot shows JBM glyphs plus full-color emoji in the actual UI. Gate green: lint, typecheck, 121 tests, build. --- CHANGELOG.md | 7 +++++++ tailwind.config.js | 28 ++++++++++++++++------------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4ed6ac..e1871e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,13 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Fixed +- The custom font stacks (and with them the bundled emoji font) never applied: + Tailwind emits font families verbatim, and the unquoted "Noto Sans Symbols 2" + — an identifier ending in a digit — made the whole `font-family` declaration + invalid CSS, which Chromium silently dropped. Families are now quoted; + verified by screenshotting the built app on a system with no fonts installed + (JetBrains Mono + full-color emoji render). + - Emoji and symbols now render on every platform. The app bundles Noto Color Emoji as the **CBDT bitmap** build — the SVG-in-OT flavor some packages ship is unsupported by Chromium (tofu), and the COLRv1 vector build painted diff --git a/tailwind.config.js b/tailwind.config.js index e7cbf4f..053aa0c 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -27,28 +27,32 @@ module.exports = { // terminal aesthetic. Emoji/symbol fallbacks matter on every stack: // platform emoji fonts first (native look on mac/Windows), then the // bundled Noto fonts so rendering is guaranteed with no system fonts. + // NOTE: multi-word family names must carry their own quotes here — + // Tailwind emits these strings verbatim into CSS, and an unquoted name + // ending in a digit ("Noto Sans Symbols 2") is invalid CSS that makes + // Chromium drop the ENTIRE font-family declaration silently. fontFamily: { mono: [ - 'JetBrains Mono', + "'JetBrains Mono'", 'ui-monospace', 'Consolas', 'monospace', - 'Apple Color Emoji', - 'Segoe UI Emoji', - 'Segoe UI Symbol', - 'Noto Color Emoji', - 'Noto Sans Symbols 2' + "'Apple Color Emoji'", + "'Segoe UI Emoji'", + "'Segoe UI Symbol'", + "'Noto Color Emoji'", + "'Noto Sans Symbols 2'" ], sans: [ - 'JetBrains Mono', + "'JetBrains Mono'", 'ui-monospace', 'Consolas', 'monospace', - 'Apple Color Emoji', - 'Segoe UI Emoji', - 'Segoe UI Symbol', - 'Noto Color Emoji', - 'Noto Sans Symbols 2' + "'Apple Color Emoji'", + "'Segoe UI Emoji'", + "'Segoe UI Symbol'", + "'Noto Color Emoji'", + "'Noto Sans Symbols 2'" ] }, keyframes: {