Skip to content

Release Notes - v0.7.0

Release Date: 2026-09-14

Highlights

  • First-Class Discrete Modes - Design systems declare their modes (light, dark, high-contrast, or any custom set) and color tokens carry a generalized mode→value map; the existing lightModeValue/darkModeValue fields keep working as sugar that folds into the map
  • Density Model - Foundations.densities defines named density variants (comfortable, compact, ...) with a spacing scale multiplier and optional per-token spacing overrides
  • Fully additive - documents that don't declare modes or densities are unaffected; generated CSS for those documents is byte-identical to before this release

This closes systemspec-designsystem#9, a proposal UIForge originally filed after implementing both concepts downstream.

What's New

Generalized modes

Declare the modes your system supports at the document root, then give any color a value per mode:

{
  "modes": ["light", "dark", "high-contrast"],
  "foundations": {
    "colors": [
      {
        "id": "surface",
        "value": "#ffffff",
        "modes": {
          "light": "#ffffff",
          "dark": "#111111",
          "high-contrast": "#000000"
        }
      }
    ]
  }
}

lightModeValue/darkModeValue remain valid — they fold into modes via ColorToken.EffectiveModes(), with explicit modes entries taking precedence. ThemeToken gained the equivalent defaults map (EffectiveDefaults()), and themeBindings[].themeMode now accepts any declared mode instead of only light/dark.

A new spec-lint rule, mode-completeness, flags color tokens that use modes but don't cover every declared mode, mode keys that aren't declared, and documents that use per-token modes without declaring modes at all.

Density variants

{
  "foundations": {
    "densities": [
      { "id": "comfortable", "scale": 1.0 },
      { "id": "compact", "scale": 0.75, "spacingOverrides": { "4": "0.65rem" } }
    ]
  }
}

Consume the scale in generated CSS with calc(<base> * var(--density, 1)); spacingOverrides lets a density replace specific spacing tokens outright instead of scaling them.

CSS generation

Mode and density emission is data-driven — no new CLI flags. Presence of modes/per-token mode values or densities in the document is what triggers output:

  • tailwind4 / css-vars: [data-mode="<mode>"] { --color-<id>: <value>; } override blocks; :root { --density: 1; } plus [data-density="<id>"] { --density: <scale>; --spacing-<id>: <override>; } blocks (prefix-aware via Prefix)
  • scss: $color-<id>--<mode>: <value>; and $density-<id>: <scale>; variables
  • mkdocs-material: dark-mode token values are now picked correctly for all colors (previously this format read Value directly, which under-served documents relying on darkModeValue)

Theme bindings, W3C export, and LLM context

  • dss bind resolves token values per-mode across the explicit, semantic, and inherit binding strategies
  • W3C Design Tokens export now carries the full modes map under $extensions["com.plexusone.dss"] (previously only darkModeValue was exported — an asymmetry this release fixes) plus a new density token group
  • dss generate --llm context includes a Modes column on the color token table and a Densities section