- Live page showHeatMap() now reads meshcore-live-heatmap-opacity from
localStorage and applies it to the canvas element (was hardcoded 0.3)
- Customizer now has two clearly labeled sliders:
🗺️ Nodes Map — controls the static map page heatmap
📡 Live Map — controls the live page heatmap
- Each uses its own localStorage key (meshcore-heatmap-opacity vs
meshcore-live-heatmap-opacity)
- Added E2E tests for live opacity persistence and dual slider existence
- 13/15 E2E tests pass locally (2 fail due to ARM chromium OOM after
heavy live page tests — CI on x64 will handle them)
Closes#119 properly this time.
The previous implementation used L.heatLayer's minOpacity which only
controlled the opacity of the coolest (blue) gradient stops. Now sets
CSS opacity on the canvas element directly, affecting all gradient
colors uniformly. Closes#119 properly.
Customizer now syncs state.home and state.branding to window.SITE_CONFIG
on every change, then dispatches hashchange to trigger page re-render.
Previously only saved to localStorage — home.js reads SITE_CONFIG.
Adds a Theme Presets section at the top of the Theme Colors tab with 8
WCAG AA-verified preset themes:
- Default: Original MeshCore blue (#4a9eff)
- Ocean: Deep blues and teals, professional
- Forest: Greens and earth tones, natural
- Sunset: Warm oranges, ambers, and reds
- Monochrome: Pure grays, no color accent, minimal
- High Contrast: WCAG AAA (7:1), bold colors, accessibility-first
- Midnight: Deep purples and indigos, elegant
- Ember: Dark warm red/orange accents, cyberpunk feel
Each theme has both light and dark variants with all 20 color keys.
High Contrast theme includes custom nodeColors and typeColors for
maximum distinguishability.
Active preset is auto-detected and highlighted. Users can select a
preset then tweak individual colors (becomes Custom).
- Import File button opens file picker for .json theme files
- Merges imported theme into current state, applies live preview
- Also syncs ROLE_COLORS/TYPE_COLORS globals on import
- Moved Copy/Download buttons out of collapsed details
- Raw JSON textarea now editable (was readonly)
- Server reads from theme.json (separate from config.json), hot-loads on every request
- POST /api/config/theme writes theme.json directly — no manual file editing
- GET /api/config/theme now merges: defaults → config.json → theme.json
- Also returns themeDark and typeColors (were missing from API)
- Customizer: replaced 'merge into config.json' instructions with Save/Load Server buttons
- JSON export moved to collapsible details section
- theme.json added to .gitignore (instance-specific)
Added --nav-text and --nav-text-muted CSS variables. All nav
selectors (.top-nav, .nav-brand, .nav-link, .nav-btn, .nav-stats)
use these instead of --text/--text-muted. Nav Text is in Basic
settings. Nav Muted Text in Advanced.
This is separate from page text because nav sits on a dark
background — page text color would be unreadable on the nav.
- Move --status-green/yellow/red from home.css to style.css :root (light+dark)
- Replace hardcoded status colors in style.css (.tl-snr, .health-dot, .byop-err,
.badge-hash-*, .fav-star.on, .spark-fill) with CSS variable references
- Replace hardcoded colors in live.css (VCR mode, stat pills, fdc-link, playhead)
- Replace --primary/--bg-secondary/--text-primary/--text-secondary dead vars with
canonical --accent/--input-bg/--text/--text-muted in style.css, map.js, live.js,
traces.js, packets.js
- Fix nodes.js legend colors to use ROLE_COLORS globals instead of hardcoded hex
- Replace hardcoded hex in home.js (SNR), perf.js (indicators), map.js (accuracy
circles) with CSS variable references via getComputedStyle or var()
- Add --detail-bg to customizer (THEME_CSS_MAP, DEFAULTS, ADVANCED_KEYS, labels)
- Move font/mono out of ADVANCED_KEYS into separate Fonts section in customizer
- Remove debug console.log lines from customize.js
- Bump cache busters in index.html
customize.js loads after roles.js but before app.js triggers
navigate(). Restoring colors in the IIFE body (not DOMContentLoaded)
ensures ROLE_STYLE/ROLE_COLORS/TYPE_COLORS are updated BEFORE
the map or any page creates markers.
Changed nav brand, links, buttons from hardcoded #fff/#cbd5e1 to
var(--text) and var(--text-muted). Setting primary text color
now changes nav text too. Removed unnecessary --nav-text variable.
State now loads: DEFAULTS → server config → localStorage.
Admin saves locally, comes back later, opens customizer —
sees their saved values, export includes everything.
Every color pick, text edit, step change auto-saves (debounced
500ms). No manual save needed. Also fixed syncBadgeColors on
restore and removed stray closing brace.
Textareas use var(--input-bg) and var(--text) instead of white.
Markdown syntax hint shown below each textarea:
**bold** *italic* `code` [text](url) - list
Added miniMarkdown() — simple markdown→HTML (bold, italic, code,
links, lists, line breaks). Home page description/answer fields
render markdown. Customizer uses textareas with markdown hint
for description and answer fields.
Steps/checklist/links were cramming 3+ inputs in one row,
truncating content. Now emoji+title+buttons on row 1,
description on row 2. All content visible.
Badge CSS (.badge-advert etc.) was hardcoded in style.css with
different colors than TYPE_COLORS. Now roles.js generates badge
CSS from TYPE_COLORS on page load via syncBadgeColors(). Customizer
calls syncBadgeColors() after changes. Badges always match the
color pickers and TYPE_COLORS, in both light and dark mode.
Badge classes (.badge-advert etc.) use hardcoded CSS colors.
Now injects a <style> element with color overrides derived from
TYPE_COLORS on every theme preview update.
--content-bg and --card-bg reference --surface-0/--surface-1 via
var() which doesn't live-update when source changes via JS. Now
explicitly sets the derived vars alongside the source.
Color changes dispatch theme-changed event → app.js re-navigates
to current page, rebuilding markers/rows with new colors.
Conflict badges (.hop-ambiguous, .hop-conflict-btn) now use
var(--status-yellow) so they follow the customized status color.
Added global window.TYPE_COLORS in roles.js. Live.js and audio-lab.js
now reference the global. Customizer shows packet type colors with
emoji + descriptions. Changes sync to TYPE_COLORS in real-time.
Saved/restored via localStorage alongside node colors.
Changing node colors in the customizer now updates both ROLE_COLORS
(used for badges, labels) and ROLE_STYLE (used for map markers).
Also fixed localStorage restore to sync both objects.
- Nav bar now uses CSS variables (was hardcoded gradient)
- 19 customizable colors: accent, text, backgrounds, borders,
surfaces, inputs, stripes, hover, selected, status indicators
- Light and dark mode have separate color sets
- Theme tab shows which mode you are editing
- Toggle ☀️/🌙 in nav bar to switch modes and edit the other set
- Export includes both theme and themeDark sections
- localStorage save/restore handles both modes
Export tab now has two sections:
- "My Preferences" — save colors to browser localStorage, auto-applied
on every page load. Personal to you, no server changes.
- "Admin Export" — download config.json for server deployment,
applies to all users.
User theme auto-loads on DOMContentLoaded, overriding CSS variables
and node colors from localStorage.
Click 🎨 in nav to toggle a floating panel. Stays open as you
navigate between pages — tweak colors, check packets, tweak more.
Draggable by header. Close with ✕. Preview persists everywhere.
Each color picker now has a description underneath:
- Accent: 'Active nav tab, buttons, links, selected rows, badges'
- Status Green: 'Healthy nodes, online indicators, good SNR'
- Repeater: 'Infrastructure nodes — map markers, packet path badges'
etc.
Preview was reverting on destroy (page leave). Now CSS variable
overrides stay active until explicit reset, so you can navigate
to packets/map/etc and see your color changes.
New page at #/customize with 5 tabs:
- Branding: site name, tagline, logo/favicon URLs
- Theme Colors: color pickers for all CSS variables with live preview
- Node Colors: per-role color pickers with dot previews
- Home Page: editable hero, steps, checklist, footer links
- Export: JSON diff output, copy/download buttons
Only exports values that differ from defaults. Self-contained CSS.
Mobile responsive, dark mode compatible.