diff --git a/.badges/frontend-coverage.json b/.badges/frontend-coverage.json index c1a15638..f2f425ed 100644 --- a/.badges/frontend-coverage.json +++ b/.badges/frontend-coverage.json @@ -1 +1 @@ -{"schemaVersion":1,"label":"frontend coverage","message":"35.52%","color":"red"} +{"schemaVersion":1,"label":"frontend coverage","message":"36.25%","color":"red"} diff --git a/config.example.json b/config.example.json index 1a8ed3c8..beccc1d4 100644 --- a/config.example.json +++ b/config.example.json @@ -48,10 +48,10 @@ "_comment": "Marker/badge colors per node role. Used on map, nodes list, and live feed." }, "markerStroke": { - "color": "rgba(255,255,255,0.85)", - "width": 1, + "color": "#fff", + "width": 2, "opacity": 1, - "_comment": "#1488 — outline around each map marker (live + map pages). 'color' accepts any CSS color (hex, rgb, rgba); use rgba() or drop 'opacity' below ~0.5 to soften the outline when hundreds of nodes feel overwhelming. 'width' is the SVG stroke width (0 hides the outline entirely). Operators can override per-browser via the in-app Theme Customizer (Colors tab → Marker Stroke)." + "_comment": "#1488/#1506 — outline around each map marker (live + map pages). Defaults restored to v3.7.2 visual (solid white, 2px). 'color' accepts any CSS color (hex, rgb, rgba); use rgba() or drop 'opacity' below ~0.5 to soften the outline when hundreds of nodes feel overwhelming. 'width' is the SVG stroke width (0 hides the outline entirely). Operators can override per-browser via the in-app Theme Customizer (Colors tab → Marker Stroke)." }, "mapDarkTileProvider": "carto-dark", "_comment_mapDarkTileProvider": "Default dark-mode basemap provider. Allowed: 'carto-dark' (Carto dark_all — default), 'esri-darkgray-labels' (Esri Dark Gray Canvas + reference labels), 'voyager-inverted' (Carto Voyager with CSS invert filter), 'positron-inverted' (Carto Positron with CSS invert filter). Light mode is unaffected. Users can override per-browser via the in-app customizer (persisted to localStorage). #1420.", diff --git a/public/customize-v2.js b/public/customize-v2.js index c09c14d7..27201911 100644 --- a/public/customize-v2.js +++ b/public/customize-v2.js @@ -1309,7 +1309,7 @@ // local override) so the operator sees what's actually painted. var ms = eff.markerStroke || {}; var msColor = typeof ms.color === 'string' && ms.color ? ms.color : '#ffffff'; - var msWidth = ms.width != null && isFinite(ms.width) ? Number(ms.width) : 1; + var msWidth = ms.width != null && isFinite(ms.width) ? Number(ms.width) : 2; var msOpacity = ms.opacity != null && isFinite(ms.opacity) ? Number(ms.opacity) : 1; var msOpacityPct = Math.round(msOpacity * 100); diff --git a/public/style.css b/public/style.css index 1021fdf8..34d67493 100644 --- a/public/style.css +++ b/public/style.css @@ -3724,8 +3724,8 @@ th.sort-active { color: var(--accent, #60a5fa); } * tiles; operators dial these via the customizer (Colors → Marker * Stroke) or via config.json (markerStroke.*). All SVG marker builders * read these vars so changes propagate live without a reload. */ - --mc-marker-stroke-color: rgba(255,255,255,0.85); - --mc-marker-stroke-width: 1; + --mc-marker-stroke-color: #fff; + --mc-marker-stroke-width: 2; --mc-marker-stroke-opacity: 1; /* #1407 — per-role text colors paired with each --mc-role-X bg so diff --git a/test-issue-1488-marker-stroke-vars.js b/test-issue-1488-marker-stroke-vars.js index 087ec140..324a858d 100644 --- a/test-issue-1488-marker-stroke-vars.js +++ b/test-issue-1488-marker-stroke-vars.js @@ -94,6 +94,38 @@ console.log('\n=== #1488 E: customize-v2.js exposes marker stroke controls ===') 'customize-v2.js writes --mc-marker-stroke-opacity'); } +console.log('\n=== #1506 F: server defaults restored to v3.7.2 (solid white, 2px) ==='); +{ + // Locate the :root block in style.css and pull the marker-stroke + // var defaults; assert they match the v3.7.2 visual (solid white, 2px, + // fully opaque). The customizer can dial them down per-operator. + var colorMatch = styleSrc.match(/--mc-marker-stroke-color\s*:\s*([^;]+);/); + var widthMatch = styleSrc.match(/--mc-marker-stroke-width\s*:\s*([^;]+);/); + var opacityMatch = styleSrc.match(/--mc-marker-stroke-opacity\s*:\s*([^;]+);/); + assert(colorMatch && /^(#fff|#ffffff|white|rgb\(\s*255\s*,\s*255\s*,\s*255\s*\))$/i.test(colorMatch[1].trim()), + 'style.css --mc-marker-stroke-color is solid white (got: ' + (colorMatch ? colorMatch[1].trim() : 'MISSING') + ')'); + assert(widthMatch && Number(widthMatch[1].trim()) === 2, + 'style.css --mc-marker-stroke-width is 2 (got: ' + (widthMatch ? widthMatch[1].trim() : 'MISSING') + ')'); + assert(opacityMatch && Number(opacityMatch[1].trim()) === 1, + 'style.css --mc-marker-stroke-opacity is 1 (got: ' + (opacityMatch ? opacityMatch[1].trim() : 'MISSING') + ')'); + + // customize-v2.js fallback defaults (when neither server config nor + // local override provides a value) must match the new server defaults + // so the customizer UI shows what's actually painted. + var fallbackWidth = customizeSrc.match(/ms\.width\s*!=\s*null[^?]*\?\s*Number\(ms\.width\)\s*:\s*(\d+(?:\.\d+)?)/); + assert(fallbackWidth && Number(fallbackWidth[1]) === 2, + 'customize-v2.js msWidth fallback is 2 (got: ' + (fallbackWidth ? fallbackWidth[1] : 'MISSING') + ')'); + + // config.example.json defaults must also match so fresh deploys ship + // the v3.7.2 visual without operator action. + var configSrc = fs.readFileSync(path.join(__dirname, 'config.example.json'), 'utf8'); + var cfg = JSON.parse(configSrc); + assert(cfg.markerStroke && /^(#fff|#ffffff|white|rgb\(\s*255\s*,\s*255\s*,\s*255\s*\))$/i.test(String(cfg.markerStroke.color || '').trim()), + 'config.example.json markerStroke.color is solid white (got: ' + (cfg.markerStroke && cfg.markerStroke.color) + ')'); + assert(cfg.markerStroke && cfg.markerStroke.width === 2, + 'config.example.json markerStroke.width is 2 (got: ' + (cfg.markerStroke && cfg.markerStroke.width) + ')'); +} + console.log('\n--- Summary ---'); console.log(passed + ' passed, ' + failed + ' failed'); process.exit(failed > 0 ? 1 : 0);