LM widgets were painted with a fixed dark palette: translucent slate fills
plus light text. On the dark palettes those values happened to blend into the
node, but on the Light palette the translucency composited into grey slabs and
light text landed on light surfaces. The prompt textarea was the clearest
case: it used the fixed --color-charcoal-400 scale token, which never flips
with the theme, so it stayed charcoal inside a white node.
Add web/comfyui/lm_theme.css as the single colour layer. Every value aliases the
active ComfyUI palette (--comfy-input-bg, --component-node-*, --comfy-menu-bg,
...) and derives raised/hover/selected surfaces with color-mix, so built-in and
user-imported palettes are covered without per-theme rules. Contexts select the
token family the neighbouring built-in widget uses: lm-widget-root for canvas
DOM widgets, lm-vue-node for the Vue node renderer, lm-popover for menus
appended to <body>. Only status colours, shadows and scrims keep a light/dark
variant. Whole-node containers no longer paint a background, so the node
surface shows through and only inputs, cards and buttons are filled.
lm_styles.css, the canvas widget JS (autocomplete dropdown, tag chips, group
editor) and all Vue SFC styles now consume these tokens; tag category badges
derive their hue from oklch tokens so the tint and text contrast flip with the
theme. Empty states get an explicit 12px size: the canvas DOM overlay inherits
the 16px body size while Vue nodes render at text-xs, which made the
placeholders oversized and heavy in canvas mode.
A regression test rejects new colour literals outside the preview-image
overlays, and the DOM widget guide documents the token map and the
blend-don't-overlay rule. Rebuilt the committed vue-widgets bundle.