v0.20.0
Released June 10, 2026 · All releases
Surface model: chrome, fills, cover layout & engine variants. Completes the surface model — every rune surface gets a consistent chrome, fill, and layout vocabulary — and lands the engine primitive (config variants) that the cover layout depends on.
Changes
- SPEC-090 media-guest interaction posture. A rune in another rune's media slot is a presentational guest by default; interactivity is now an explicit capability —
RuneConfig.interactive, set on the behaviour-driven runes (codegroup,tabs,datatable,form,map,sandbox,juxtapose). When the container is itself an interaction target — acard/bento-cellwith a stretched whole-tilehref— or the guest is acoverbackdrop (SPEC-089), the engine marks the media zonedata-guest-posture="presentational": it goespointer-events: none(so clicks fall through to the link / the overlay owns interaction) and the behaviours layer skips enhancement, so the guest renders its static fallback (the demotedcodegroup/tabstab strip is hidden so panels read as plain stacked content). The demotion is scoped to the media zone only — content-overlay controls (body/footer links & buttons) stay interactive. An interactive guest in a linked tile emits an informative (non-fatal) build warning. A container withouthref(and notcover) hosts interactive guests normally. - SPEC-086 surface chrome. Adds a universal
elevationattribute (self-surfacebox-shadowon the--rf-shadow-*scale), aframespreset registry with theframeattribute and inlineframe-*facets (modelled onbg),RuneConfig.frameTargetrouting (media zone vs self) with a build warning when unresolved, and a shared frame CSS layer (silhouette drop-shadow, displacement/peek, oversize, place, anchor).showcasecollapses into the frame model asframeTarget: 'self'; itsshadow/bleed/offset/aspect/placeattributes are deprecated aliases forframe-*facets (warn for one minor, then removed), with breakout retained. Theoffsetnamed scale is completed (none|sm|md|lg|xl) and its raw-length fallthrough closed. - SPEC-087 surface fills. Adds a tint-tracking inset surface (the
--rf-surface-inset-shiftmix amount + a use-sitecolor-mixrecipe applied to media wells andchart/diagram), andsubstrate— a generated surface pattern with a fixed engine enum (dots|grid|lines|cross|checker|none), inlinesubstrate-size/opacity/fillfacets, a shared always-included gradient recipe stylesheet, andRuneConfig.substrateTargetrouting (defaultself, per-instancesubstrate-targetoverride, build warning when targeting a missing media section). - SPEC-088 bg gradients & scrim. Adds a token-driven
bggradient fill (inlinebg-gradient/bg-from/bg-to/bg-via/bg-gradient-typefacets with semantic token stops, and a structuredBgPresetDefinition.gradientpreset), a structuredscrimlegibility facet (gradient/frost, strength/blur/tone — tone also flips the overlaid foreground), and a constrained flatoverlayvocabulary (dark/light/token + opacity). The raw-stringoverlaypassthrough is deprecated (warns) now thatscrimships, thestyleescape hatch is documented with a stated contract (valid in theme & project config; project merges over theme), and a build-time soft-lint flags raw gradients that the structured facet covers.bg.cssis force-included sincebgis now a universal-attribute feature. - SPEC-089 cover layout. Adds
media-position="cover"as amedia-positionengine variant (SPEC-091): the media well fills the rune interior and content overlays it, with a one-attribute switch fromtop|bottom|start|end. Two rune-declared scopes —full(card: the whole box overlays) andheader(recipe: only the title band overlays, body flows below) — bound the overlay region; there is no overlay primitive in the layout config. Addscontent-place, a 2-axis logical overlay anchor (<block> <inline>, mapping toalign/justify) active only in cover mode (warns otherwise), whoseautodefault — also the behaviour when unset — adapts to the cover region's container-query orientation. Cover turns on a default scrim on the media surface (consuming the SPEC-088 scrim facet), weighted toward the content edge and followingcontent-placeunless an explicitscrim="top|bottom|left|right"pins it;scrim="none"opts out.scrim-type="frost"swaps the gradient for a frosted-glass blur (scrim-blurscale) — in cover mode the scrim renders on the media well, never the self-surface bg layer, masked to the content edge so it never covers the whole image. The overlay foreground followsscrim-tone(a dark scrim yields light text) and is scoped to the overlay ([data-name="content"]in full scope, the cover-band in header scope), so the card's own surface keeps the page palette (light in light mode) while only the text on the media flips. Adds a card intrinsic-height knob (heightnamed scale +aspect) for cover /bg-only cards, and documents cover mode in the card reference. - Bento: a grid-level
elevationnow cascades to cells (joining theframecascade) so{% bento elevation="md" %}lifts each cell rather than the grid box; a cell's ownelevationstill wins. Fixes the bento reference page's frame/elevation example (the images needed an---to land in the media zone).