CSS Variables

Every framework CSS variable is either public contract or private implementation. This page states the contract: which families are public, which are internal, and how the Paint API reads them, themes re-point them, and the Sass source generates them.

#

Who reads, who writes

The public --* variables are where the framework's API surfaces meet. Each surface plays one role and never crosses into another.

The palette behind the variables is defined on Colors . Every variable with its per-mode values is listed on Tokens .

#

Public variables

A variable is public unless its name marks it as internal, and a release keeps every public name in every published bundle. Read public variables with var() in custom CSS or cssVar() in JavaScript, and reference them from theme slots.

The --framework-* channels are public too. They get their own section below because the theme layer and the runtime write them.

/* Custom plugin CSS: reference public variables freely. */
.stat-card {
  padding: var(--gap);
  border-radius: var(--rounded);
}
// JavaScript: read the same contract from the live cascade.
var gap = TRMNLPaint.cssVar("--gap", { el: "my-chart" });
#

Framework channels and slots

The --framework-* families carry resolved paint between the theme layer, the components, and the runtime. They are public names: the minifier renames only the internal families below, so a theme, a plugin stylesheet, or cssVar() can read them in any build.

Themes write these through the slot mixins, where one call fills a whole channel or slot. Setting a single name by hand leaves the rest of its group behind, so plugin markup sets only --framework-icon-src.

#

Internal variables

Six name families are implementation details. The minified bundle (plugins.min.css, the file production serves) renames them to --_tn* names. Do not read or set them; they can change or disappear in any release.

  • --_*: module-private helpers scoped to one component's rules.
  • --framework-internal-*: plumbing that carries resolved values between framework layers.
  • --tile-*: the generated dither tile assets.
  • --bline-{n}: deduplicated border line gradients the border pipeline references.
  • --border-*: the border pipeline, except the theme-contract names below.
  • --tn-*: engine plumbing, except --tn-text-stroke-color, --tn-text-stroke-width and --tn-text-stroke-radius, which the runtime reads.

The development build and the readable plugins.css keep the source names, so you will see them in devtools. Treat them as off-limits anyway.

#

Framework-owned paint variables

The --bg-* and --text-* families keep their names in every build, but the screen-mode engine owns them. They encode device-capability rendering: dither patterns on 1-bit, palette images on limited color, solid colors on full color.

Three border families survive the rename because the theme contract preserves them: the numbered slots --border-1-h-* through --border-7-v-*, the --border-token-* names a shipped theme references, and --border-line-dark / --border-line-light. Everything else under --border-*, including the whole --border-step-* rail, is renamed in released bundles.

Never set them from a plugin or a theme; the theme linter rejects any theme that tries. To consume the resolved paint from JavaScript, go through Paint API instead of reading them raw.