@city-of-baltimore/bromo-fonts

中文文档
1.4.4发布于 2026/11/09MITES Module近 30 天下载 2739

Font adapter for the Baltimore Design System. Self-hosted base and opt-in script faces, with separate optional Adobe brand delivery.

原始使用文档
文档目录7 节
  1. Why this is not part of Bromo
  2. What it delivers
  3. Optional native-language labels
  4. CSP
  5. Why the brand entry is JavaScript
  6. Licences
  7. On Proxima Nova

@city-of-baltimore/bromo-fonts

The font adapter for the Baltimore Design System. It registers the families named by BROMO_FONT_CONTRACT so every product inherits one delivery mechanism instead of each solving it.

npm install --save-exact @city-of-baltimore/bromo-fonts
// once, near your application entry, before anything renders.
// Pick exactly ONE of these two.
import "@city-of-baltimore/bromo-fonts/brand";        // City brand headings
// import "@city-of-baltimore/bromo-fonts/fonts.css";    // network-free

No @font-face or font URLs belong in application code. Optional native-language labels add only the relevant script entry described below.

Which one? fonts.css requests faces only from the application origin and renders headings in Hanken Grotesk. brand is a superset that adds the City's brand face, Proxima Nova, ahead of it — at the cost of a request to Adobe on every page load. Both are supported; the network-free one is not a degraded mode.

Why this is not part of Bromo

The public @city-of-baltimore/bromo package is MIT and network-free by policy: it declares no @font-face, ships no font binary, and contacts no font host. verify:package-policy and verify:pack-install enforce that mechanically, at zero exceptions.

Bromo owns which families are correct. This adapter owns how they arrive. Keeping them apart is what lets delivery change — a new licence, a new host, self-hosting instead of a CDN — without touching the design system, and what guarantees a licensed binary can never land in an MIT tarball.

What it delivers

RoleFamilyLicenceDeliveryIn which entry
Brand headingsproxima-nova 700/800Adobe web project (delivery-only)Adobe CDNbrand only
Display and headingsHanken Grotesk 700/800SIL OFL-1.1self-hosted, bundled at build timeboth
Body and UINunito Sans 400/700/800SIL OFL-1.1self-hosted, bundled at build timeboth

The two self-hosted families are redistributable, so their files ship inside the @fontsource dependencies and are bundled into your application's own output. This package ships no font binary of its own.

Latin subsets only. The default adapter imports latin and latin-ext, not the full unicode-range set. Cyrillic and Vietnamese are outside that entry; Storybook registers their pinned Nunito faces through its complete upstream stylesheets. Optional script entries are listed below. Applications do not edit fonts.css.

Proxima Nova cannot be bundled: the City holds it under an Adobe Fonts web project, a delivery-only licence that permits rendering from Adobe's CDN and does not grant self-hosting. It is the estate's one documented exception to the self-host rule, and it is bounded — headings only, opt-in, with the self-hosted Hanken Grotesk directly behind it so an Adobe outage costs one tier rather than all of them.

Only h1–h6, the brand lockup, and Alert titles use the heading stack; everything else is the body face.

Optional native-language labels

Typography contract 6 adds these normal weight 700 entries while keeping the base stacks and fonts.css declarations unchanged. They cover current native labels; they do not claim complete translated workflows, arbitrary weights or all regional forms.

Import suffixNamed faceExplicit language attributes
scripts/zh.cssNoto Sans SCzh or zh-Hans (including zh-Hans-*)
scripts/ko.cssNoto Sans KRko and regional subtags
scripts/ar.cssNoto Sans Arabicar and regional subtags
scripts/hi.cssNoto Sans Devanagarihi and regional subtags
// In the existing lazy language-assistance feature, not every application's entry.
import "@city-of-baltimore/bromo-fonts/scripts/ar.css";

<Tag label={<>Arabic · <bdi lang="ar" dir="auto">العربية</bdi></>} />

Keep the existing base font import. The adapter styles explicitly language-tagged text; it neither guesses a language from characters nor rewrites a global font stack. Put lang on the native text only when an English descriptor accompanies it. LanguageAccessPanel also accepts { label, lang, dir? } items, retaining legacy strings and label-based selection/callbacks. Its structured labels use bdi, defaulting to dir="auto". Labels must remain unique.

The bare zh choice is the SC face for today's shared 中文 label. It does not claim Traditional Chinese coverage policy; zh-Hant does not select this entry. Use this 700-only delivery for governed labels, not 400-weight translated body copy. An expanded weight or language requirement needs an explicit contract change.

Each script entry needs its Fontsource family, which the adapter declares as an optional peer at the exact version its CSS was generated from. Install the families for the entries you import, and only those:

Import suffixInstall
scripts/zh.css@fontsource/[email protected]
scripts/ko.css@fontsource/[email protected]
scripts/ar.css@fontsource/[email protected]
scripts/hi.css@fontsource/[email protected]
npm install --save-exact @fontsource/[email protected]

An application that imports no script entry installs none of them (about 4.8 MB for the adapter and its base faces, against about 133 MB with all four). A missing family fails the build — the bundler cannot resolve the face — rather than painting an OS fallback.

All faces come from exact Fontsource 5.3.0 packages. The generator preserves upstream Unicode ranges, complete script shards and unmodified shaping data; it selects WOFF2 only. It never creates a font from screenshot characters. Only required Unicode shards should download.

The package includes upstream notices in licenses/. Preserve the relevant OFL notices when deploying bundled font assets. The adapter code's MIT license does not replace the fonts' OFL license. See the typography guide for cost estimates and remaining browser/device acceptance; registered faces alone do not prove which face painted a glyph.

CSP

fonts.css and the optional script entries use same-origin assets:

font-src 'self';

Apps on this entry can remove https://use.typekit.net, https://fonts.googleapis.com, and https://fonts.gstatic.com from their style-src and font-src directives entirely.

brand attaches Adobe's stylesheet at runtime rather than importing it, so it needs Adobe reachable for both the stylesheet and the faces:

style-src 'self' https://use.typekit.net;
font-src  'self' https://use.typekit.net https://p.typekit.net;

Nothing else changes — fonts.googleapis.com and fonts.gstatic.com stay out of both.

Why the brand entry is JavaScript

Because a stylesheet cannot stay off the critical rendering path, and that is the only property that matters here.

The optional brand entry attaches Adobe's stylesheet with media="print", then changes it to all on load through addEventListener. This keeps the stylesheet off the initial render-blocking path and preserves a same-origin self-hosted fallback. It does not change Adobe's font descriptor or guarantee that a later swap is imperceptible. The approved heading weights remain 700 and 800; project configuration and licensed delivery stay with the adapter's owner.

Licences

This package is MIT. The fonts it delivers keep their own licence; the self-hosted faces permit the redistribution this adapter performs:

  • Nunito Sans — SIL Open Font License 1.1, via @fontsource/nunito-sans.

  • Hanken Grotesk — SIL Open Font License 1.1, via @fontsource/hanken-grotesk.

  • Noto Sans SC, Noto Sans KR, Noto Sans Arabic and Noto Sans Devanagari — SIL Open Font License 1.1, through the corresponding exact Fontsource packages.

On Proxima Nova

Proxima Nova is delivered only by the separate, deliberate brand opt-in entry. It is never in fonts.css, optional script entries or Bromo's visual baseline environment. Its existing delivery-only Adobe license does not permit vendoring. If the City acquires a self-hosting license, coordinate the typography contract and adapter change and retire the remote exception; do not silently replace the network-free display family.

版本与发布记录

@city-of-baltimore/bromo-fonts 共发布 84 个版本,首次发布于 2026/08/03;过去 12 个月发布了 84 个版本。

版本发布日期距今
1.4.4latest2026/11/09今天
2.0.0-beta.3next2026/11/091 天前
2.0.0-beta.22026/11/081 天前
2.0.0-beta.12026/11/082 天前
1.4.32026/11/054 天前
1.4.22026/10/2317 天前

关于 @city-of-baltimore/bromo-fonts 的常见问题

@city-of-baltimore/bromo-fonts 是什么?

Font adapter for the Baltimore Design System. Self-hosted base and opt-in script faces, with separate optional Adobe brand delivery.

如何安装 @city-of-baltimore/bromo-fonts?

在项目目录运行 npm install @city-of-baltimore/bromo-fonts,或使用 pnpm add / yarn add / bun add。

@city-of-baltimore/bromo-fonts 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/city-of-baltimore__bromo-fonts 是否存在。

@city-of-baltimore/bromo-fonts 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@city-of-baltimore/bromo-fonts 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=26 <27。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@city-of-baltimore/bromo-fonts 可以商用吗?

@city-of-baltimore/bromo-fonts 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@city-of-baltimore/bromo-fonts 的下载量有多少?

根据 npm 官方下载统计,@city-of-baltimore/bromo-fonts 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,739 次,日均约 91 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@city-of-baltimore/bromo-fonts 还在维护吗?

最新版本 1.4.4 发布于 2026/11/09(今天);至今共发布 84 个版本,其中过去 12 个月发布了 84 个;首次发布于 2026/08/03。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。