V3.2 Overview

Framework 3.2 makes plugins theme-aware. It adds opt-in theme stylesheets, the TRMNLPaint JavaScript paint API, adaptive charts and icons, rebuilt border, outline, and stroke utilities, and Fluid Mashups for arranging views, all on top of the v3 color system. Existing markup keeps working; every 3.2 feature is opt-in.

#

The v3 Color Foundation

3.2 builds on the color system introduced in v3.0: 10 chromatic hues with 14 lightness steps, semantic roles (primary, success, error, warning), a 14-step grayscale, and per-mode CSS custom properties on .screen, so colors follow each device's palette and bit depth with no per-device markup. 3.1 added the TRMNL font bundle as the low-density default. See Colors for the full palette.

#

Independent Text Scale

Text Scale adjusts every framework font size and pixel line height without applying the same factor to interface geometry or text strokes. It composes with Scale, so a dense layout can keep larger text instead of shrinking both together. See Text Scale .

#

Themes

Restyle a whole screen by loading one extra stylesheet and adding screen--theme-<id>. A theme remaps which tokens paint each surface; device-capability rendering is preserved, so a themed screen still dithers on 1-bit and paints solids on full color. 3.2 ships three themes: Black and Yellow, White and Red, and Dark.

  • A theme is a complete color statement: screen--dark-mode has no effect on a themed screen.
  • Author your own theme with the theme-slots mixins and validate it with rake framework:themes:lint.
  • Preview any docs example with a theme via the Style selector in the screen picker.

Full reference: Themes .

#

TRMNLPaint: the JavaScript Paint API

Resolve any framework color, border rail, typography role, or numeric scale from JavaScript. TRMNLPaint reads the live CSS cascade, with device density, scale, bit depth, dark mode, themes, and limited palettes already applied. Token mappings and scale factors are never duplicated in JS.

  • Resolvers: bg(), text(), semantic(), series(), border(), type(), and more.
  • Painters: apply(), applyBorder(), applyType() write resolved paint onto nodes.
  • watch() re-runs your build function whenever the screen's device, scale, mode, dark mode, or theme changes.
  • cssVar() reads any public custom property, the documented extension path for themes.
  • scale() reads the composed scale contract, and px() converts numeric JavaScript dimensions.

Full reference: Paint API .

#

Generated Paint Assets

Dither paint no longer ships as PNG images. Every grayscale and limited-palette tile is generated at build time as an inline ink SVG: the dark pixels are baked into the asset and the light tone rides the background color, so a screen paints with zero image fetches.

  • One tile pipeline: CSS paints from the generated assets, and TRMNLPaint reads the same resolved output back for JavaScript consumers.
  • Dark mode and Raw/Preview recolor by re-pointing tokens at other tiles from the same generated set; the geometry never forks.
  • Regenerate from the color manifest with rake framework:color_tokens; hand-edited pattern assets are gone.
#

Adaptive Charts

Charts historically painted explicit colors and ignored bit depth, dark mode, and themes. The plugin runtime now bundles TRMNLCharts, a Highcharts adapter built on TRMNLPaint. Chart series pull from the screen's chart-series ramp, grid lines use the border system, and plotted text uses framework typography, so charts adapt with the rest of the screen.

  • options() and merge() give you adaptive Highcharts defaults under your own settings.
  • series(i, n) resolves each series fill; applySwatches() paints matching legend markers.
  • watch() rebuilds the chart on device, scale, mode, dark mode, or theme changes.
  • TRMNLPaint.px() scales numeric chart dimensions from the same live CSS contract.

Usage and live examples: Chart . For charting beyond Highcharts, use Paint API directly.

#

Adaptive Icons

Add image--adaptive to a monochrome silhouette icon and the framework repaints it with the screen's icon paint, following the same Raw/Preview, bit-depth, dark-mode, and theme cascade as framework text. One set of icons works everywhere, as long as they are same-origin or CORS-readable. See Image .

#

Rebuilt Borders, Outlines, and Strokes

The Border, Outline, Text Stroke, and Image Stroke utilities were rebuilt on the same token model as the color and pattern system. Each one paints from semantic and theme variables, so dark mode, themes, and bit depth recolor it with no per-mode markup.

#

Fluid Mashups

Fluid Mashups sit alongside the fixed layouts: the mashup--3x3 layout uses mashup-cell placement modifiers for custom three by three tilings, with no inline grid styles. Every cell draws the window frame and a compact title bar at any size, across bit depths, dark mode, and themes. See Mashup .

#

Complete Scale Modifiers

Scale modifiers now compose with each device's native UI density and resize framework gaps, pixel-based utilities, image presets, component geometry, radii, and strokes. The new screen--scale-xxsmall level adds a 66% scale for dense dynamic mashups, and TRMNLPaint.px() converts JavaScript dimensions from the same live CSS contract. See Scale .

#

Under the Hood

  • Smaller stylesheets: utility gate selectors and responsive variants are refactored onto :is() screen scopes, reducing the CSS footprint.
#

Start Here