This file is a hands-off memory for the current dm-style.js direction, what is now done, and what should stay intentionally small.
There are two layers:
- page tokens and token application live in page HTML via normal dmax
- the floating editor UI lives in a tiny WC registered with
dmWc(...)
The WC is only a host for controls and markup. The page still owns state. That keeps the rule consistent with the rest of dmax:
- HTML/CSS first
- dmax for dataflow
- imperative JS only for setup/helpers
- load
dmax.js - load
dm-style.js - put one
stylesignal object on the page root - place
<dm-style-panel></dm-style-panel>on the page - call one
pin:
<script>dmStyle.pin(document.getElementById('app'))</script>pin(root, opts?) does the wiring for you:
- subscribes to the style signal
- applies CSS vars to the root
- finds or creates the panel element
- binds the panel open/help signals
Defaults are designed for the common case:
signal: 'style'open: 'stylePanel.open'help: 'oklchHelp'panel: 'dm-style-panel'defs: dmStyle.defs
If your signal lives under a nested path, pass it:
<script>dmStyle.pin(document.getElementById('app'), {
signal: 'mx.style',
open: 'mx.stylePanel.open',
help: 'mx.oklch-help',
panel: 'mx-style-panel',
})</script>If the page already uses CSS vars, that is enough to make the live editor work.
pin is per-root. Call it once per root:
dmStyle.pin(document.getElementById('a'), { signal: 'a.style' })
dmStyle.pin(document.getElementById('b'), { signal: 'b.style' })The page still owns state.
pin just wires the dataflow.
If you want to keep wiring fully declarative, you can still use dmStyle.panel(...) plus an explicit root binding. pin exists for the simpler case.
Example shape:
<div
id="demo"
data-m-si='{"mx":{"oklchHelp":"...","style":{"toneBg":"oklch(...)"}}}'
data-m-ex:.style@mx.style="({ '--tone-bg': val.toneBg })">The important part is:
- one signal object owns the style tokens
- one
data-m-ex:.style@...binding applies them to root CSS vars
#demo {
--tone-bg: oklch(98% .008 250);
--bg: color-mix(in oklab, var(--tone-bg) 96%, white);
background: var(--bg);
}If a token does not visibly change the page, first check that the token is actually consumed by CSS.
dm-style.js does this on top of public dmWc(...).
The WC is intentionally narrow:
- renders controls
- emits normal DOM events through dmax bindings
- does not own a parallel store
- does not try to become a styling framework runtime
Example pattern used now:
<input data-m-ex:.value@mx.style.tone-bg data-m-ex:mx.style.tone-bg@.input>and for color inputs:
<input
type="color"
data-m-ex:.value@mx.style.tone-bg="dmStyle.oklchToHex(val) || '#ffffff'"
data-m-ex:mx.style.tone-bg@.input="dmStyle.hexToOklch(val)">So:
- text input shows OKLCH
- color input shows a familiar picker
- both write the same token
m-ex-cel now proves:
- a page can expose a small live token system with plain dmax
- one tiny shared helper can host the controls cleanly
- OKLCH text and native color pickers can round-trip through the same signal
- root CSS vars can be applied from one signal object
- spacing/radius/line/tone tokens can all flow through the same mechanism
It matches the main dmax rule:
- if you know one thing, you mostly know the rest
The style panel is not a special mini-framework. It is just:
dmStyle.panel(...)/dmWc(...)for packaging UIdata-m-exfor reads/writes- CSS vars for presentation
That is better than introducing a separate styling DSL too early.
Completed in the current small plan:
- generic
dm-style.jshelper exists - generic
dmStyle.panel(...)exists dmStyle.valsToVars(...)removes the repetitive token->CSS-var mappingdmStyle.copy(...)/dmStyle.importVals(...)/dmStyle.promptImport(...)existdmStyle.oklchToHex(...)/dmStyle.hexToOklch(...)existexamples/style-starter.htmlis the smallest starterexamples/m-ex-cel.htmlnow dogfoods the same helper instead of page-specific style plumbing
Still intentionally missing:
- no extra runtime features in
dmax.js - no big styling DSL
- no widget-owned style store
- no pre-themed design system beyond the token defaults
Recommended house token shape is now:
--space-*--radius-*--line-*--size-*--tone-*
Good parts:
- stronger opinionated styling story
- can help users move faster when they want a ready-made design language
Tradeoff:
- can become its own parallel abstraction layer
- can blur where CSS ends and framework magic begins
Dmax direction should stay simpler:
- prefer plain CSS vars and modern CSS features
- keep runtime involvement minimal
- avoid turning styling into a second framework vocabulary
Good parts:
- component packaging pressure-testing
- encourages ergonomic composition
Tradeoff:
- more mechanical framework surface
- can push users away from plain platform-first HTML/CSS
Dmax direction should keep only the high-value parts:
- small declarative packaging
- DOM-native composition
- no large styling runtime contract
Goal:
A customer should be able to style a page with dmax using mostly existing web platform knowledge.
Done.
Done.
Done at the small end only:
- token-object to CSS-var-object helper
- small reusable style-panel package
- import/export helpers
- OKLCH bridge helpers
Still not a full styling subsystem.
- CSS-first, not style-system-first
- normal CSS vars and modern CSS features first
- dmax as dataflow glue, not a parallel styling DSL
- thin WC packaging, not a larger component runtime
- page-owned state, not widget-owned shadow state by default
- a more pre-shaped styling system
- stronger defaults and ready-made design language
- faster drop-in theming
- more packaged reusable interactive pieces
- less manual glue between token state, UI controls, and page application
- stronger pre-baked design defaults
- more packaged component skins
- more opinionated ready-made themes
Those are intentionally out of scope for now.
Do the smallest 20% that gives 80% of the value:
- document one recommended token schema
- provide one tiny style starter
- provide one generic style panel package
- provide one tiny helper layer for export/import and token->CSS-var application
That slice is now complete.
Stop before turning this into a second framework.
Keep style support in this order:
- semantic HTML
- CSS vars and selectors
- dmax signal bindings
- optional WC packaging
- tiny helper JS
- only then consider new runtime features
That keeps dmax small and consistent.