|
78 | 78 | import KeymapDialog from '$lib/components/shared/KeymapDialog.svelte'; |
79 | 79 | import CommandPalette from '$lib/components/shared/CommandPalette.svelte'; |
80 | 80 | import {initKeyboardShortcuts, registerShortcut} from '$lib/utils/keyboard'; |
81 | | - import {hexToRgb} from '$lib/utils/color'; |
| 81 | + import {hexToRgb, isLightRgb} from '$lib/utils/color'; |
82 | 82 | import {buildCommands} from '$lib/commands/commands.svelte'; |
83 | 83 | import type {main} from '../wailsjs/go/models'; |
84 | 84 |
|
|
88 | 88 | let sliderWidget = $state(false); |
89 | 89 | let themesSlider = $state(false); |
90 | 90 |
|
| 91 | + // RGB step between bg-primary and bg-secondary so panels stay |
| 92 | + // visually layered on any theme bg. |
| 93 | + const BG_SECONDARY_SHIFT = 10; |
| 94 | + // CSS tokens layered over bg-primary, paired with their alpha values |
| 95 | + // for light and dark backgrounds. Order: [token, lightAlpha, darkAlpha]. |
| 96 | + const OVERLAY_TOKENS: ReadonlyArray<[string, number, number]> = [ |
| 97 | + ['--color-bg-surface', 0.03, 0.04], |
| 98 | + ['--color-bg-elevated', 0.06, 0.07], |
| 99 | + ['--color-bg-hover', 0.04, 0.05], |
| 100 | + ['--color-border', 0.1, 0.08], |
| 101 | + ['--color-border-focus', 0.2, 0.18], |
| 102 | + ]; |
| 103 | +
|
91 | 104 | // Mirror editor state into Go (debounced) so `aether status` and other IPC |
92 | 105 | // readers reflect live edits without waiting for an Apply. Long enough |
93 | 106 | // to cover slider drags; first sync on mount posts the initial snapshot. |
|
269 | 282 | } |
270 | 283 | if (colors.background) { |
271 | 284 | const bg = hexToRgb(colors.background); |
272 | | - // Luma threshold matches isLightColor() — a light |
273 | | - // omarchy theme needs dark scrim/border overlays, a |
274 | | - // dark theme needs the white-on-dark defaults. |
275 | | - const isLightBg = |
276 | | - (bg.r * 299 + bg.g * 587 + bg.b * 114) / 1000 > 128; |
277 | | - const shift = isLightBg ? -10 : 10; |
| 285 | + const isLightBg = isLightRgb(bg.r, bg.g, bg.b); |
| 286 | + const shift = isLightBg |
| 287 | + ? -BG_SECONDARY_SHIFT |
| 288 | + : BG_SECONDARY_SHIFT; |
278 | 289 | const clamp = (n: number) => |
279 | 290 | Math.max(0, Math.min(255, n)); |
280 | | - const bg2r = clamp(bg.r + shift); |
281 | | - const bg2g = clamp(bg.g + shift); |
282 | | - const bg2b = clamp(bg.b + shift); |
283 | 291 | const overlay = isLightBg ? '0, 0, 0' : '255, 255, 255'; |
284 | 292 | root.style.setProperty( |
285 | 293 | '--color-bg-primary', |
286 | 294 | colors.background |
287 | 295 | ); |
288 | 296 | root.style.setProperty( |
289 | 297 | '--color-bg-secondary', |
290 | | - `rgb(${bg2r}, ${bg2g}, ${bg2b})` |
291 | | - ); |
292 | | - root.style.setProperty( |
293 | | - '--color-bg-surface', |
294 | | - `rgba(${overlay}, ${isLightBg ? 0.03 : 0.04})` |
295 | | - ); |
296 | | - root.style.setProperty( |
297 | | - '--color-bg-elevated', |
298 | | - `rgba(${overlay}, ${isLightBg ? 0.06 : 0.07})` |
299 | | - ); |
300 | | - root.style.setProperty( |
301 | | - '--color-bg-hover', |
302 | | - `rgba(${overlay}, ${isLightBg ? 0.04 : 0.05})` |
303 | | - ); |
304 | | - root.style.setProperty( |
305 | | - '--color-border', |
306 | | - `rgba(${overlay}, ${isLightBg ? 0.1 : 0.08})` |
307 | | - ); |
308 | | - root.style.setProperty( |
309 | | - '--color-border-focus', |
310 | | - `rgba(${overlay}, ${isLightBg ? 0.2 : 0.18})` |
| 298 | + `rgb(${clamp(bg.r + shift)}, ${clamp(bg.g + shift)}, ${clamp(bg.b + shift)})` |
311 | 299 | ); |
| 300 | + for (const [token, lightA, darkA] of OVERLAY_TOKENS) { |
| 301 | + root.style.setProperty( |
| 302 | + token, |
| 303 | + `rgba(${overlay}, ${isLightBg ? lightA : darkA})` |
| 304 | + ); |
| 305 | + } |
312 | 306 | document.body.style.background = colors.background; |
313 | 307 | WindowSetBackgroundColour(bg.r, bg.g, bg.b, 255); |
314 | 308 | } |
|
0 commit comments