[feat](trx-frontend-http): add style picker with Nord, Monokai, Contrast themes
Add a style picker dropdown to the tab bar (right of rig picker) with four styles — Original, Nord, Monokai, Contrast — each with full light/dark variants. CSS: define data-style attribute overrides for all CSS custom properties (bg, card-bg, borders, text, accents, jog, audio level, filter, spectrum background) for each of the three new styles × two themes (6 new blocks). JS: introduce CANVAS_PALETTE lookup table covering spectrum/waveform/ waterfall colors for all style×theme combinations. Add currentStyle(), canvasPalette(), setStyle() helpers. Persist selection to localStorage. Replace all isLight ternaries in drawing code with palette lookups: - drawOverviewWaterfall, drawOverviewSignalHistory, waterfallColor signatures changed from isLight flag to pal object - drawSpectrum uses canvasPalette() for grid lines, labels, fill, line - spectrumBgColor() now delegates to canvasPalette().bg Theme toggle also triggers a spectrum redraw so canvas colors update immediately when switching light/dark. Also fix light-theme spectrum rendering broken since canvas drawing used hardcoded dark-only colors (white grid lines invisible on light bg). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -490,6 +490,19 @@ small { color: var(--text-muted); }
|
||||
font-size: 0.78rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.header-style-pick {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.header-style-pick select {
|
||||
height: 2rem;
|
||||
padding: 0.15rem 0.35rem;
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: 6px;
|
||||
background: var(--input-bg);
|
||||
color: var(--text);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.header-logo { height: 4.6em; width: auto; flex-shrink: 0; filter: drop-shadow(0 4px 12px rgba(0,0,0,0.35)); }
|
||||
.subtitle { color: var(--text-muted); font-size: 0.95rem; }
|
||||
.subtitle a { color: var(--accent-green); text-decoration: none; }
|
||||
@@ -887,3 +900,177 @@ button:focus-visible, input:focus-visible, select:focus-visible {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Nord style ───────────────────────────────────────────────────────── */
|
||||
[data-style="nord"] {
|
||||
--bg: #242933;
|
||||
--card-bg: #2e3440;
|
||||
--input-bg: #242933;
|
||||
--border: #3b4252;
|
||||
--border-light: #4c566a;
|
||||
--text: #d8dee9;
|
||||
--text-muted: #8a9ab0;
|
||||
--text-heading: #eceff4;
|
||||
--btn-bg: #3b4252;
|
||||
--btn-border: #5e6f88;
|
||||
--accent-green: #88c0d0;
|
||||
--accent-yellow: #ebcb8b;
|
||||
--accent-red: #bf616a;
|
||||
--jog-hi: #434c5e;
|
||||
--jog-lo: #3b4252;
|
||||
--jog-shadow: rgba(0,0,0,0.40);
|
||||
--jog-inset: rgba(255,255,255,0.06);
|
||||
--audio-level-bg: #2e3440;
|
||||
--audio-level-border: #4c566a;
|
||||
--audio-level-fill-start: #88c0d0;
|
||||
--audio-level-fill-end: #ebcb8b;
|
||||
--filter-bg: #3b4252;
|
||||
--filter-fg: #d8dee9;
|
||||
--filter-border: #5e6f88;
|
||||
--wavelength-fg: #7a8ea8;
|
||||
--spectrum-bg: #1e2530;
|
||||
}
|
||||
[data-style="nord"][data-theme="light"] {
|
||||
--bg: #e5e9f0;
|
||||
--card-bg: #eceff4;
|
||||
--input-bg: #d8dee9;
|
||||
--border: #c5ccd8;
|
||||
--border-light: #a8b2c0;
|
||||
--text: #2e3440;
|
||||
--text-muted: #4c566a;
|
||||
--text-heading: #2e3440;
|
||||
--btn-bg: #d8dee9;
|
||||
--btn-border: #8fa3b8;
|
||||
--accent-green: #5e81ac;
|
||||
--accent-yellow: #c07a22;
|
||||
--accent-red: #bf616a;
|
||||
--jog-hi: #d8dee9;
|
||||
--jog-lo: #c2cbd8;
|
||||
--jog-shadow: rgba(46,52,64,0.18);
|
||||
--jog-inset: rgba(255,255,255,0.70);
|
||||
--audio-level-bg: #d0d6e0;
|
||||
--audio-level-border: #a8b2c0;
|
||||
--audio-level-fill-start: #5e81ac;
|
||||
--audio-level-fill-end: #c07a22;
|
||||
--filter-bg: #d8dee9;
|
||||
--filter-fg: #2e3440;
|
||||
--filter-border: #8fa3b8;
|
||||
--wavelength-fg: #5a6a80;
|
||||
--spectrum-bg: #dde1e9;
|
||||
}
|
||||
|
||||
/* ── Monokai style ────────────────────────────────────────────────────── */
|
||||
[data-style="monokai"] {
|
||||
--bg: #1c1c17;
|
||||
--card-bg: #272822;
|
||||
--input-bg: #1c1c17;
|
||||
--border: #3e3d32;
|
||||
--border-light: #5c5c45;
|
||||
--text: #f8f8f2;
|
||||
--text-muted: #908980;
|
||||
--text-heading: #f8f8f2;
|
||||
--btn-bg: #3e3d32;
|
||||
--btn-border: #75715e;
|
||||
--accent-green: #a6e22e;
|
||||
--accent-yellow: #e6db74;
|
||||
--accent-red: #f92672;
|
||||
--jog-hi: #49483e;
|
||||
--jog-lo: #3e3d32;
|
||||
--jog-shadow: rgba(0,0,0,0.45);
|
||||
--jog-inset: rgba(255,255,255,0.05);
|
||||
--audio-level-bg: #272822;
|
||||
--audio-level-border: #5c5c45;
|
||||
--audio-level-fill-start: #a6e22e;
|
||||
--audio-level-fill-end: #e6db74;
|
||||
--filter-bg: #3e3d32;
|
||||
--filter-fg: #f8f8f2;
|
||||
--filter-border: #75715e;
|
||||
--wavelength-fg: #9c8f78;
|
||||
--spectrum-bg: #181815;
|
||||
}
|
||||
[data-style="monokai"][data-theme="light"] {
|
||||
--bg: #f5f0e4;
|
||||
--card-bg: #fdf9f2;
|
||||
--input-bg: #ede8d8;
|
||||
--border: #d8d0bb;
|
||||
--border-light: #c0b89e;
|
||||
--text: #272822;
|
||||
--text-muted: #6e6a56;
|
||||
--text-heading: #272822;
|
||||
--btn-bg: #ede8d8;
|
||||
--btn-border: #b0a888;
|
||||
--accent-green: #5f8700;
|
||||
--accent-yellow: #9a7200;
|
||||
--accent-red: #c60052;
|
||||
--jog-hi: #ede8d8;
|
||||
--jog-lo: #ddd8c8;
|
||||
--jog-shadow: rgba(39,40,34,0.18);
|
||||
--jog-inset: rgba(255,255,255,0.75);
|
||||
--audio-level-bg: #ede8d8;
|
||||
--audio-level-border: #c0b89e;
|
||||
--audio-level-fill-start: #5f8700;
|
||||
--audio-level-fill-end: #9a7200;
|
||||
--filter-bg: #ede8d8;
|
||||
--filter-fg: #272822;
|
||||
--filter-border: #b0a888;
|
||||
--wavelength-fg: #7a7260;
|
||||
--spectrum-bg: #ede8d8;
|
||||
}
|
||||
|
||||
/* ── Contrast style ───────────────────────────────────────────────────── */
|
||||
[data-style="contrast"] {
|
||||
--bg: #000000;
|
||||
--card-bg: #0a0a0a;
|
||||
--input-bg: #111111;
|
||||
--border: #333333;
|
||||
--border-light: #555555;
|
||||
--text: #ffffff;
|
||||
--text-muted: #bbbbbb;
|
||||
--text-heading: #ffffff;
|
||||
--btn-bg: #1a1a1a;
|
||||
--btn-border: #666666;
|
||||
--accent-green: #00ff88;
|
||||
--accent-yellow: #ffcc00;
|
||||
--accent-red: #ff3344;
|
||||
--jog-hi: #2a2a2a;
|
||||
--jog-lo: #1a1a1a;
|
||||
--jog-shadow: rgba(0,0,0,0.60);
|
||||
--jog-inset: rgba(255,255,255,0.08);
|
||||
--audio-level-bg: #111111;
|
||||
--audio-level-border: #555555;
|
||||
--audio-level-fill-start: #00ff88;
|
||||
--audio-level-fill-end: #ffcc00;
|
||||
--filter-bg: #1a1a1a;
|
||||
--filter-fg: #ffffff;
|
||||
--filter-border: #666666;
|
||||
--wavelength-fg: #aaaaaa;
|
||||
--spectrum-bg: #000000;
|
||||
}
|
||||
[data-style="contrast"][data-theme="light"] {
|
||||
--bg: #ffffff;
|
||||
--card-bg: #f4f4f4;
|
||||
--input-bg: #e8e8e8;
|
||||
--border: #cccccc;
|
||||
--border-light: #999999;
|
||||
--text: #000000;
|
||||
--text-muted: #333333;
|
||||
--text-heading: #000000;
|
||||
--btn-bg: #e0e0e0;
|
||||
--btn-border: #777777;
|
||||
--accent-green: #005cc5;
|
||||
--accent-yellow: #cc5500;
|
||||
--accent-red: #cc0000;
|
||||
--jog-hi: #e0e0e0;
|
||||
--jog-lo: #cccccc;
|
||||
--jog-shadow: rgba(0,0,0,0.25);
|
||||
--jog-inset: rgba(255,255,255,0.80);
|
||||
--audio-level-bg: #e8e8e8;
|
||||
--audio-level-border: #999999;
|
||||
--audio-level-fill-start: #005cc5;
|
||||
--audio-level-fill-end: #cc5500;
|
||||
--filter-bg: #e8e8e8;
|
||||
--filter-fg: #000000;
|
||||
--filter-border: #999999;
|
||||
--wavelength-fg: #444444;
|
||||
--spectrum-bg: #f4f4f4;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user