fix(ui): cards on pure black/white, decoupled from bg-anim

Three related fixes after the Phase-4 migration landed:

- `--card-bg` flipped from `#101216` / `#f5f6f8` to pure `#000000` /
  `#ffffff` in base.css. Off-pure greys read as muddy when sitting on a
  pure-black/white page background; pure values keep card surfaces flush
  with the rest of the chrome and let the channel stripe + corner
  bracket carry all the visual differentiation.

- Removed the `[data-bg-anim="on"] .card { background: rgba(...) }`
  block that turned every entity card translucent whenever the WebGL
  background was enabled. Card backgrounds are now stable across the
  toggle — the shader bleeds through `body { background: transparent }`
  only, not through cards. The same card now reads identically with the
  shader on or off.

- WebGL shader base colour (`_bgColor` in bg-anim.ts and bg-shaders.ts)
  was using the legacy mid-grey `#1a1a1a` / `#f5f5f5`. That added a
  constant grey haze under the additive accent glow that didn't exist
  on the surrounding pure-black/white page. Switched to `[0,0,0]` /
  `[1,1,1]` so the shader composes against the same base as the page.

- Reverted two leftovers from the Phase-4 commit where I had migrated
  `.template-card` and `.graph-node-body` away from `var(--card-bg)`
  toward `var(--lux-bg-1, …)`. Those backgrounds now live on
  `var(--card-bg)` again, matching every other migrated card.
This commit is contained in:
2026-04-25 02:42:57 +03:00
parent b43e1cf375
commit dd415e2813
5 changed files with 22 additions and 23 deletions
+7 -17
View File
@@ -101,7 +101,7 @@
[data-theme="dark"] { [data-theme="dark"] {
--bg-color: #000000; --bg-color: #000000;
--bg-secondary: #0a0b0d; --bg-secondary: #0a0b0d;
--card-bg: #101216; --card-bg: #000000;
--text-color: #e0e0e0; --text-color: #e0e0e0;
--text-primary: #e0e0e0; --text-primary: #e0e0e0;
--text-secondary: #999; --text-secondary: #999;
@@ -148,7 +148,7 @@
[data-theme="light"] { [data-theme="light"] {
--bg-color: #ffffff; --bg-color: #ffffff;
--bg-secondary: #fafbfc; --bg-secondary: #fafbfc;
--card-bg: #f5f6f8; --card-bg: #ffffff;
--text-color: #333333; --text-color: #333333;
--text-primary: #333333; --text-primary: #333333;
--text-secondary: #595959; --text-secondary: #595959;
@@ -241,21 +241,11 @@ html.modal-open {
background: transparent; background: transparent;
} }
/* When bg-anim is active, make entity cards slightly translucent /* Card backgrounds are intentionally stable across the dynamic-bg
so the shader bleeds through. Only target cards — NOT modals, toggle — the shader bleeds through the page background only.
pickers, tab bars, headers, or other chrome. */ (Previously a translucent override let the shader show through
[data-bg-anim="on"][data-theme="dark"] .card, cards too, but it made the same card look different depending on
[data-bg-anim="on"][data-theme="dark"] .template-card, whether the user had the WebGL background enabled.) */
[data-bg-anim="on"][data-theme="dark"] .add-device-card,
[data-bg-anim="on"][data-theme="dark"] .dashboard-target {
background: rgba(45, 45, 45, 0.88);
}
[data-bg-anim="on"][data-theme="light"] .card,
[data-bg-anim="on"][data-theme="light"] .template-card,
[data-bg-anim="on"][data-theme="light"] .add-device-card,
[data-bg-anim="on"][data-theme="light"] .dashboard-target {
background: rgba(255, 255, 255, 0.85);
}
/* Blur behind header via pseudo-element — applying backdrop-filter directly /* Blur behind header via pseudo-element — applying backdrop-filter directly
to header would create a containing block and break position:fixed on to header would create a containing block and break position:fixed on
the .tab-bar nested inside it (mobile bottom nav). */ the .tab-bar nested inside it (mobile bottom nav). */
@@ -430,7 +430,7 @@ html:has(#tab-graph.active) {
} }
.graph-node-body { .graph-node-body {
fill: var(--lux-bg-1, var(--card-bg)); fill: var(--card-bg);
stroke: var(--lux-line, var(--border-color)); stroke: var(--lux-line, var(--border-color));
stroke-width: 1; stroke-width: 1;
rx: 6; rx: 6;
+1 -1
View File
@@ -10,7 +10,7 @@
.template-card { .template-card {
--ch: var(--ch-cyan, var(--info-color)); /* default channel — overridden per data-attr below */ --ch: var(--ch-cyan, var(--info-color)); /* default channel — overridden per data-attr below */
background: var(--lux-bg-1, var(--card-bg)); background: var(--card-bg);
border: var(--lux-hairline, 1px) solid var(--lux-line, var(--border-color)); border: var(--lux-hairline, 1px) solid var(--lux-line, var(--border-color));
border-radius: var(--lux-r-md, var(--radius-md)); border-radius: var(--lux-r-md, var(--radius-md));
padding: 18px 20px 16px; padding: 18px 20px 16px;
+7 -2
View File
@@ -114,7 +114,10 @@ let _particleBuf: Float32Array | null = null; // pre-allocated Float32Array for
let _raf: number | null = null; let _raf: number | null = null;
let _startTime = 0; let _startTime = 0;
let _accent = [76 / 255, 175 / 255, 80 / 255]; let _accent = [76 / 255, 175 / 255, 80 / 255];
let _bgColor = [26 / 255, 26 / 255, 26 / 255]; // Base canvas colour — must match `--bg-color` (pure black / white in the
// Lumenworks theme). Using mid-greys here washes the additive glow with a
// constant tint that doesn't exist on the surrounding page background.
let _bgColor = [0, 0, 0];
let _isLight = 0.0; let _isLight = 0.0;
// Particle state (CPU-side, positions in 0..1 UV space) // Particle state (CPU-side, positions in 0..1 UV space)
@@ -262,7 +265,9 @@ export function updateBgAnimAccent(hex: string): void {
} }
export function updateBgAnimTheme(isDark: boolean): void { export function updateBgAnimTheme(isDark: boolean): void {
_bgColor = isDark ? [26 / 255, 26 / 255, 26 / 255] : [245 / 255, 245 / 255, 245 / 255]; // Match the page's `--bg-color` (pure black/white) — see comment on
// the `_bgColor` declaration above.
_bgColor = isDark ? [0, 0, 0] : [1, 1, 1];
_isLight = isDark ? 0.0 : 1.0; _isLight = isDark ? 0.0 : 1.0;
} }
@@ -320,7 +320,10 @@ let _uBg: WebGLUniformLocation | null = null;
let _uLight: WebGLUniformLocation | null = null; let _uLight: WebGLUniformLocation | null = null;
let _accent = [76 / 255, 175 / 255, 80 / 255]; let _accent = [76 / 255, 175 / 255, 80 / 255];
let _bgColor = [26 / 255, 26 / 255, 26 / 255]; // Base canvas colour — must match `--bg-color` (pure black / white in
// the Lumenworks theme). Using mid-greys here washes the additive glow
// with a constant tint that doesn't exist on the surrounding page bg.
let _bgColor = [0, 0, 0];
let _isLight = 0.0; let _isLight = 0.0;
// ─── GL helpers ────────────────────────────────────────────── // ─── GL helpers ──────────────────────────────────────────────
@@ -471,7 +474,8 @@ export function updateShaderAccent(hex: string): void {
/** Update theme brightness (called on theme toggle). */ /** Update theme brightness (called on theme toggle). */
export function updateShaderTheme(isDark: boolean): void { export function updateShaderTheme(isDark: boolean): void {
_bgColor = isDark ? [26 / 255, 26 / 255, 26 / 255] : [245 / 255, 245 / 255, 245 / 255]; // Match the page's `--bg-color` token (pure black/white).
_bgColor = isDark ? [0, 0, 0] : [1, 1, 1];
_isLight = isDark ? 0.0 : 1.0; _isLight = isDark ? 0.0 : 1.0;
} }