fix(style): let the backdrop follow the window's own opacity

Three problems from one screenshot, and the same root cause behind two of them.

The pane painted at full opacity regardless of the window it sat in. BgAlpha
only ever reaches WindowBg, so a draw-list fill ignores it entirely, and a
deliberately translucent settings window came out as a solid block beside a
translucent chat window. The backdrop now reads the alpha out of the resolved
WindowBg colour and carries it through the gradient, the accent wash and the
motes.

The banding is 8-bit quantisation, not a rendering fault: a gentle ramp across a
tall surface crosses so few distinct values that each one covers a visible band.
Halving the range leaves fewer and fainter steps, and the translucency now
underneath them breaks up what remains.

Motes over the chat log drop to 18%. A settings page is read in glances and can
carry motion behind it; a chat log is read line by line, where anything drifting
behind the text competes with it. Intensity is a parameter rather than a second
particle system, so the two surfaces share one implementation.
This commit is contained in:
2026-08-18 18:01:07 +02:00
parent 8ebed6846d
commit 8b96ffb2ec
3 changed files with 32 additions and 13 deletions
+5 -4
View File
@@ -385,10 +385,11 @@ internal sealed class MainWindow : Window, IFocusableChatWindow
{
if (messages.Success)
{
// No accent wash here. It works on a settings pane, where the
// top of the surface is a heading; over a chat log the first
// messages would sit in a tinted band and read as highlighted.
_backdrop.Draw(accentWashHeight: 0f);
// No accent wash, and the motes turned right down. Both work on
// a settings pane, which is read in glances; a chat log is read
// line by line, and anything drifting behind the text competes
// with it. What is left is barely a texture.
_backdrop.Draw(accentWashHeight: 0f, moteIntensity: 0.18f);
if (_activeTab is not null)
_messages.Draw(_activeTab);