V3.2 Overview

Framework 3.2 goes open source and adds themes, adaptive charts and icons, a JavaScript paint API, rebuilt borders and strokes, Text Scale, complete Scale modifiers, and Fluid Mashups. 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 hues with 14 lightness steps, semantic roles (primary, success, error, warning), and a 14-step grayscale, listed in full on Colors . Every color adapts to the device's palette and bit depth on its own, with no per-device markup.

#

Themes

Recolor a whole screen by loading one extra stylesheet and adding screen--theme-<id>. The theme picks the colors; each device renders them with the inks it has. 3.2 ships three themes: Black and Yellow, White and Red, and Dark.

  • 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

Read any framework color, border, text style, or size from JavaScript. TRMNLPaint returns what CSS would paint right now, with the device, scale, and theme already applied, so your JavaScript never hardcodes a color.

  • Resolvers read one value each: 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 --* variable, which is how a theme hands values to plugin code.
  • scale() reads the current scale factor, and px() converts pixel numbers with it.

Full reference: Paint API .

#

Generated Paint Assets

Every dither pattern is now generated at build time as an inline SVG instead of shipping as a PNG image, so a screen paints with zero image fetches.

  • CSS and JavaScript share the same generated patterns: TRMNLPaint reads back exactly what CSS paints.
  • Every screen mode, Raw/Preview included, paints from the same generated set, so pattern shapes never change between modes.
#

Adaptive Charts

The runtime now bundles TRMNLCharts, a Highcharts adapter built on TRMNLPaint. Series colors, grid lines, and chart text all come from the framework, so a chart adapts with the rest of the screen instead of carrying its own fixed colors.

  • options() and merge() give you adaptive Highcharts defaults under your own settings.
  • series(i, n) picks each series color; 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 icon and the framework recolors it the way it colors text: it follows the device, Raw/Preview, and the active theme. 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 the same way as the color system and now follow the device and themes on their own.

#

Fluid Mashups

Fluid Mashups sit alongside the fixed layouts: place views on a three by three grid with mashup--3x3 and the mashup-cell modifiers, no inline styles needed. Every cell keeps its frame and a compact title bar at any size, on every device and under themes. See Mashup .

#

Complete Scale Modifiers

Scale modifiers now resize everything: gaps, pixel utilities, image presets, component geometry, radii, and strokes, on top of each device's own density. The new screen--scale-xxsmall level adds a 66% scale for dense mashups, and TRMNLPaint.px() lets JavaScript convert pixel numbers the same way. See Scale .

#

Under the Hood

  • Smaller stylesheets: the responsive and device rules were refactored onto :is() selectors.