From eae1b915ca47357cf0d7285d590aa89149c738dc Mon Sep 17 00:00:00 2001 From: Kpa-clawbot Date: Wed, 6 May 2026 21:24:57 -0700 Subject: [PATCH] feat: load Aldrich webfont for #1137 logo SVG (#1138) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds Aldrich webfont so the merged #1137 logo renders in the intended typeface. ## Problem The inline SVG logo merged in #1137 declares `font-family="Aldrich, monospace"` in `public/index.html` and `public/home.js`, but the page never loaded the Aldrich font face. Browsers silently fell back to monospace. ## Fix Self-hosted webfont: - `public/fonts/aldrich-regular.woff2` — Regular 400, ~16KB, downloaded from Google Fonts (latin subset). Self-hosted to avoid third-party CDN dependency, privacy concern, and FOUT delay. - `@font-face` declaration added at the top of `public/style.css` with `font-display: swap`. Aldrich only ships in 400; the SVG `font-weight="700"` on the wordmark synthesizes bold (matches the design intent of #1137). ## TDD - Red commit: E2E test asserting `document.fonts.check('1em Aldrich')` is true and the navbar SVG `` `font-family` contains "Aldrich". Without the font face declaration, both assertions fail on an assertion (not a build error). - Green commit: adds the woff2 + `@font-face` rule, both assertions pass. ## Files - `public/fonts/aldrich-regular.woff2` (new, 16460 bytes) - `public/style.css` — `@font-face` rule - `test-e2e-playwright.js` — new test --------- Co-authored-by: openclaw-bot --- public/fonts/aldrich-regular.woff2 | Bin 0 -> 16460 bytes public/style.css | 11 +++++++++++ scripts/instrument-frontend.sh | 9 +++++++++ test-e2e-playwright.js | 22 ++++++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 public/fonts/aldrich-regular.woff2 diff --git a/public/fonts/aldrich-regular.woff2 b/public/fonts/aldrich-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..c92a531ba0db0a6b6de757349c56f0d309b10134 GIT binary patch literal 16460 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 { + await page.goto(BASE, { waitUntil: 'domcontentloaded' }); + // Explicitly request the font (waits for download). On the broken state + // there is no @font-face for Aldrich, so no FontFace matches and check() + // stays false — the assertion below fails on behavior, not infra. + const aldrichLoaded = await page.evaluate(async () => { + try { await document.fonts.load('1em Aldrich'); } catch (_) {} + await document.fonts.ready; + return document.fonts.check('1em Aldrich'); + }); + assert(aldrichLoaded, 'document.fonts.check("1em Aldrich") returned false — Aldrich is not loaded'); + // Sanity: the inline SVG still declares Aldrich in its font-family. + const fontFamily = await page.evaluate(() => { + const t = document.querySelector('nav svg text, .navbar svg text, header svg text'); + return t ? (t.getAttribute('font-family') || getComputedStyle(t).fontFamily) : null; + }); + assert(fontFamily && /aldrich/i.test(fontFamily), + `Navbar SVG font-family should include Aldrich, got: ${fontFamily}`); + }); + // Test 6: Theme customizer opens (reuses home page from test 1) await test('Theme customizer opens', async () => { // Look for palette/customize button