feat(themes): add theme-aware boundary highlight config

Add highlight section to overlay config for all themes with
theme-appropriate colors:
- dark: muted olive-green (#7a9a6b)
- light: forest green (#4a7040)
- clean: Google blue (#1a73e8)
- cyberpunk: electric cyan (#00f0ff)

Update addBoundaryLayer() to read config from
getOverlayConfig(themeId, "highlight") for consistent styling
across all themes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Matt 2026-05-01 18:26:13 +00:00
commit fef10664c8
4 changed files with 1485 additions and 1431 deletions

View file

@ -1247,10 +1247,10 @@ function removeBlmTrails(map) {
} }
/** Add boundary polygon layers with computed accent color (MapLibre rejects CSS vars in paint) */ /** Add boundary polygon layers using theme-aware highlight config */
const BOUNDARY_FILL_LAYER = 'boundary-fill-layer' const BOUNDARY_FILL_LAYER = 'boundary-fill-layer'
function addBoundaryLayer(map) { function addBoundaryLayer(map, themeId) {
if (!map || map.getLayer(BOUNDARY_LAYER)) return if (!map || map.getLayer(BOUNDARY_LAYER)) return
if (!map.getSource(BOUNDARY_SOURCE)) { if (!map.getSource(BOUNDARY_SOURCE)) {
map.addSource(BOUNDARY_SOURCE, { map.addSource(BOUNDARY_SOURCE, {
@ -1258,7 +1258,14 @@ function addBoundaryLayer(map) {
data: { type: "FeatureCollection", features: [] }, data: { type: "FeatureCollection", features: [] },
}) })
} }
const accentColor = getComputedStyle(document.documentElement).getPropertyValue("--accent").trim() || "#7a9a6b" // Get highlight config from theme overlay
const highlight = getOverlayConfig(themeId, "highlight") || {}
const lineColor = highlight.lineColor || "#7a9a6b"
const lineWidth = highlight.lineWidth || 2
const lineDash = highlight.lineDash || [4, 4]
const lineOpacity = highlight.lineOpacity || 0.8
const fillColor = highlight.fillColor || lineColor
const fillOpacity = highlight.fillOpacity || 0.08
// Find first symbol layer to insert boundary layers below labels // Find first symbol layer to insert boundary layers below labels
const layers = map.getStyle().layers const layers = map.getStyle().layers
@ -1276,8 +1283,8 @@ function addBoundaryLayer(map) {
type: "fill", type: "fill",
source: BOUNDARY_SOURCE, source: BOUNDARY_SOURCE,
paint: { paint: {
"fill-color": accentColor, "fill-color": fillColor,
"fill-opacity": 0.05, "fill-opacity": fillOpacity,
}, },
}, firstSymbolId) }, firstSymbolId)
@ -1287,10 +1294,10 @@ function addBoundaryLayer(map) {
type: "line", type: "line",
source: BOUNDARY_SOURCE, source: BOUNDARY_SOURCE,
paint: { paint: {
"line-color": accentColor, "line-color": lineColor,
"line-width": 2, "line-width": lineWidth,
"line-opacity": 0.7, "line-opacity": lineOpacity,
"line-dasharray": [3, 2], "line-dasharray": lineDash,
}, },
}, firstSymbolId) }, firstSymbolId)
} }
@ -1498,7 +1505,14 @@ const MapView = forwardRef(function MapView(_, ref) {
type: "geojson", type: "geojson",
data: { type: "FeatureCollection", features: [] }, data: { type: "FeatureCollection", features: [] },
}) })
const accentColor = getComputedStyle(document.documentElement).getPropertyValue("--accent").trim() || "#7a9a6b" // Get highlight config from theme overlay
const highlight = getOverlayConfig(themeId, "highlight") || {}
const lineColor = highlight.lineColor || "#7a9a6b"
const lineWidth = highlight.lineWidth || 2
const lineDash = highlight.lineDash || [4, 4]
const lineOpacity = highlight.lineOpacity || 0.8
const fillColor = highlight.fillColor || lineColor
const fillOpacity = highlight.fillOpacity || 0.08
map.addLayer({ map.addLayer({
id: MEASURE_LINE_LAYER, id: MEASURE_LINE_LAYER,
type: "line", type: "line",
@ -2124,7 +2138,7 @@ const MapView = forwardRef(function MapView(_, ref) {
// Boundary polygon layer for selected places // Boundary polygon layer for selected places
if (!map.getLayer(BOUNDARY_LAYER)) { if (!map.getLayer(BOUNDARY_LAYER)) {
addBoundaryLayer(map) addBoundaryLayer(map, currentThemeRef.current)
} }
// Apply improved base label styling for readability // Apply improved base label styling for readability
@ -2333,7 +2347,7 @@ const MapView = forwardRef(function MapView(_, ref) {
// Boundary polygon layer // Boundary polygon layer
if (!map.getLayer(BOUNDARY_LAYER)) { if (!map.getLayer(BOUNDARY_LAYER)) {
addBoundaryLayer(map) addBoundaryLayer(map, currentThemeRef.current)
} }
// Apply improved base label styling for readability // Apply improved base label styling for readability

View file

@ -351,6 +351,16 @@ const cleanOverlay = {
labelFont: ['Noto Sans Regular'], labelFont: ['Noto Sans Regular'],
hitWidth: 14, hitWidth: 14,
}, },
// ── Highlight (boundary/selection) ────────────────────────────────────────
highlight: {
lineColor: "#1a73e8", // Google blue for selection
lineWidth: 2,
lineDash: [4, 4],
lineOpacity: 0.7,
fillColor: "#1a73e8",
fillOpacity: 0.06,
},
} }
/** /**

View file

@ -368,6 +368,16 @@ const cyberpunkOverlay = {
// Hit layer // Hit layer
hitWidth: 14, hitWidth: 14,
}, },
// ── Highlight (boundary/selection) ────────────────────────────────────────
highlight: {
lineColor: "#00f0ff", // Electric cyan for selection
lineWidth: 2,
lineDash: [4, 4],
lineOpacity: 0.9,
fillColor: "#00f0ff",
fillOpacity: 0.1,
},
} }
/** /**

View file

@ -288,6 +288,16 @@ const darkOverlay = {
// Hit layer // Hit layer
hitWidth: 14, hitWidth: 14,
}, },
// ── Highlight (boundary/selection) ────────────────────────────────────────
highlight: {
lineColor: "#7a9a6b", // Muted olive-green for dark backgrounds
lineWidth: 2,
lineDash: [4, 4],
lineOpacity: 0.8,
fillColor: "#7a9a6b",
fillOpacity: 0.08,
},
} }
/** /**
@ -450,6 +460,16 @@ const lightOverlay = {
// Hit layer // Hit layer
hitWidth: 14, hitWidth: 14,
}, },
// ── Highlight (boundary/selection) ────────────────────────────────────────
highlight: {
lineColor: "#4a7040", // Forest green for light backgrounds
lineWidth: 2,
lineDash: [4, 4],
lineOpacity: 0.7,
fillColor: "#4a7040",
fillOpacity: 0.06,
},
} }
// ═══════════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════════