← Back to home@jiangking22

dsh-text-color-adaptive

Adaptive text color for DSH: samples the wallpaper and recolors label text so it stays readable over any background.

Stars
0
Language
JavaScript
Created
Oct 22, 2026
Updated
Oct 22, 2026

Introduction

dsh-text-color-adaptive

Recolors DSH label text from the actual brightness of whatever is behind it, so white text on a bright wallpaper stops washing out.

The same paragraph over the bright and the dark part of a wallpaper: fixed white text on the left, adaptive text on the right

Built for the transparent-glass look (a wallpaper plus semi-transparent panels): the shipped dark-theme text color is a fixed near-white, and a live wallpaper keeps moving bright frames underneath it. This plugin measures that backdrop and picks a side — light text or dark text — instead of assuming one.

What it does

Every 0.9 s it samples the wallpaper layer (.we-layer, produced by dsh-plugin-wallpaper-engine) — an <img>, <video>, <canvas>, or a scene iframe reached through its own __wp.capture().

The frame is scaled to 64×36, the text column is averaged into one background color, and that color is blended with the active theme's glass surface to estimate what the glyphs actually sit on. It then picks the side with the higher contrast and pushes the color until it just clears 4.6:1.

It writes five tokens — --dsw-alias-label-primary, -secondary, -tertiary, -caption, -dimmed — plus a text shadow that runs opposite to the text color (dark text gets a light shadow and vice versa) as a safety net.

Switching sides is damped: the new side has to beat the current one by 1.15× on two consecutive samples, so a live wallpaper does not flicker.

When it cannot sample

No wallpaper layer, a frame that is not decoded yet, or a scene iframe that refuses __wp.capture() (cross-origin) — the plugin turns itself off completely (removes html[data-at-adaptive]) and leaves DSH's own colors untouched. It never leaves half an override behind.

Without the wallpaper plugin there is nothing to sample, and DSH's solid background needs no help; the plugin stays dormant.

Tuning

Constants at the top of client.js:

ConstantDefaultMeaning
FLOOR4.6Target contrast for body text (WCAG AA is 4.5:1)
SURFACE_MIX0.45How much of the backdrop is glass surface; raise it if your glass is thicker
TICK_MS900Sampling interval
SWITCH_MARGIN / SWITCH_STABLE1.15 / 2Side-switch margin and stability count

Debug

In the browser console:

__dshAdaptiveText.state
// { active: true, side: 'light', primary: '#fbfcfe', wallpaperLuminance: 0.31 }
__dshAdaptiveText.refresh()   // sample again now
__dshAdaptiveText.dispose()   // restore DSH's own colors

Install

dsh plugin --profile web add dsh-text-color-adaptive

Uninstall

dsh plugin --profile web remove dsh-text-color-adaptive

__dshAdaptiveText.dispose() turns it off for the current page without uninstalling.

License

MIT