Compiling the Framework

Compile the framework from source with Dart Sass: one entrypoint, one load path, plus a stylesheet per theme. The result is the same plugins.css the release pipeline produces. You only need a source build when a released one is not enough, for modified source or custom device profiles.

#

Toolchain

The framework compiles with Dart Sass; the module system rules out LibSass and node-sass. Releases pin sass-embedded 1.93.3 so published artifacts reproduce byte for byte, and any current Dart Sass produces equivalent CSS.

#

Compiling plugins.css

Create an entrypoint that loads the framework module, then compile it with the framework source on the load path. bin/build in the repository runs exactly this for the released artifacts.

// my-build.scss
@use 'framework';
sass --style=compressed --no-source-map \
  --load-path=trmnl-framework/app/assets/stylesheets \
  my-build.scss plugins.css

To bake your own device profiles into the build, configure the module at the same @use site. See Custom Devices .

The compiled stylesheet embeds every dither tile as data URIs, so it is large on disk. Serve it compressed; the release pipeline ships a .gz next to every artifact for the same reason.

#

Fonts

Every @font-face block in the framework points at a root-relative /fonts/ URL, so a host has to serve those files. Without them the pixel families fall back to the browser default. Nothing errors, the type is simply wrong at every size.

Font URLs resolve against the host that serves the stylesheet, not the page. Link plugins.css from the releases CDN and the fonts load from the same host. Serve your own build and you serve /fonts with it.

#

What the host serves

  • TRMNL12, TRMNL16, and TRMNL21 in Regular and Bold, each as .woff2, .woff, and .ttf (18 files).
  • NicoPups-Regular.ttf, NicoClean-Regular.ttf, and BlockKie.ttf for the Classic bundle (3 files).
  • Inter.ttf and Inter-Italic.ttf, which both bundles use on high-density displays (2 files).

Both bundles download as zips from Releases, each with a README of per-font credits and its license text. Extract the font files into the directory the host serves at /fonts, and keep the credits and license files with your build. Font Family covers which bundle renders what.

The framework release zip holds no fonts. They ship as their own bundles, so a stack assembled from that zip alone renders with no pixel fonts at all.

#

Palette tiles

The compiled stylesheet embeds every dither tile as a data URI, on grayscale screens and color palettes alike. Fonts are the only asset it loads by URL, so a custom stack has no pattern images to serve.

sass --style=compressed --no-source-map \
  --load-path=trmnl-framework/app/assets/stylesheets \
  trmnl-framework/app/assets/stylesheets/framework/themes/black-and-yellow-theme.scss \
  themes/black-and-yellow-theme.css
#

Releases and minification

The repository's release task compiles, minifies, and precompresses (gzip and brotli) every published version reproducibly; those artifacts are what the releases CDN serves. If you don't need a modified build, serve a released version directly and skip the toolchain entirely.

Minifying your own build is optional. If you do, keep custom properties intact: the framework's JavaScript reads public --* variables from the live cascade.