Fonts
Name your theme's fonts in its tokens, then have the app load them — Astryx never loads a font file.Name the font
A theme names its typefaces in typography: body, heading, and code, each with a family and fallbacks. These set the --font-family-* tokens every component reads. Always give real fallbacks so text stays readable before the font loads, or if it never does. heading inherits family and fallbacks from body when you omit them.
ts// themes/ocean/oceanTheme.tsexport const oceanTheme = defineTheme({name: 'ocean',typography: {body: {family: 'Acme Sans', fallbacks: 'system-ui, sans-serif'},code: {family: 'Acme Mono', fallbacks: 'ui-monospace, monospace'},},// ...your tokens});
The full type scale and font roles are in astryx docs theme.
Load the font in the app
Naming a family does not load it — Astryx never downloads a font file. The app that uses your theme loads the font itself, so your job is to tell your users which families and weights to load, in your theme's docs (astryx docs cli/integrations/building-blocks/themes/document-the-theme). An app loads a font one of two ways:
Linka hosted stylesheet in the app's<head>— for example a Google Fonts<link>covering every weight the UI uses.- Self-host: serve the font files and add an
@font-facefor each weight and style to the app's global CSS.
css/* In the app's global CSS, when self-hosting */@font-face {font-family: 'Acme Sans';src: url('/fonts/acme-sans.woff2') format('woff2');font-weight: 100 900;font-style: normal;font-display: swap;unicode-range: U+0000-00FF, U+0131, U+0152-0153;}
- Load every weight and style the theme uses. Do not let the browser synthesize bold or italic — include the italic face, with the same
unicode-ranges as the roman. - Set a
unicode-rangeper face so the browser downloads only the subsets it needs. - Use
font-display: swapunless a measured need justifies another value. - Serve WOFF2; add another format only when a target browser needs it.
Verify in an app
Before publishing, install the package in a clean app, apply the theme, load the fonts, and open it in a browser. The source and the applied result are not the same thing until you look.
Textrenders in the named families at every weight and style — the italic face resolves, not a synthesized slant.- Every font request succeeds; nothing silently falls back to a system font.
- Color pairs still meet contrast in both light and dark mode.