fix(map): thinner always-on marker outline — was dominating at zoomed-out levels#1347
Merged
Conversation
added 2 commits
May 24, 2026 04:27
Operator feedback on #1334: always-on white outline at stroke-width=2 dominates the map at zoomed-out levels. Add failing assertion that makeRoleMarkerSVG (and live.js fallback) render shape strokes with stroke-width <= 1, while the highlight ring keeps weight >= 2.
…-out levels Operator feedback on #1334 (the #1293 marker a11y change): the white outline that #1334 baked into every node marker (stroke-width=2) was too heavy and dominated the map at zoomed-out levels — every node read as 'big white blob with a colour core', losing the per-role shape silhouette at the very zoom levels where the shape distinction matters most. Drop the always-on stroke from 2 → 1 across all marker producers (public/roles.js makeRoleMarkerSVG, public/live.js inline fallback, public/map.js makeMarkerIcon switch) and collapse the legacy star 1.5 to 1 for consistency. Shape silhouettes stay distinct on both dark and light tiles (1px is enough contrast on Carto basemaps), the colorblind-friendly point of #1293 is preserved, and the marker no longer dominates the surrounding terrain. The highlight ring used by pulseNodeMarker (selected/active state) is untouched and still pulses at weight 3 → 2 — that's the one place where a heavy outline carries real signal. before: - makeRoleMarkerSVG: stroke-width=2 (1.5 for star) - live.js fallback: stroke-width=2 - map.js makeMarkerIcon: stroke-width=2 (1.5 for star) - highlight ring: weight 3 → 2 (pulse) after: - makeRoleMarkerSVG: stroke-width=1 (all shapes) - live.js fallback: stroke-width=1 - map.js makeMarkerIcon: stroke-width=1 (all shapes) - highlight ring: weight 3 → 2 (pulse) — unchanged Tests: test-marker-outline-weight.js pins the new contract (stroke-width <= 1 for always-on, >= 2 for highlight ring). test-issue-1293-marker-shapes.js still green — shape variation and outline-ring highlight contract preserved.
4 tasks
5 tasks
Kpa-clawbot
pushed a commit
that referenced
this pull request
May 25, 2026
Implements Tufte's structural framing + audit's minimal-patch overrides:
V1 — cluster bubbles (.mc-cluster sm/md/lg):
- Single neutral fill (--mc-cluster-fill), no more --info/--warning/--accent
bucket color.
- Border-style ramp (1.5px solid → 2.5px solid → 2px double) as the
redundant non-color carrier of the count bucket.
- Border color #666 + dark halo box-shadow (audit fix: white border was
1.05:1 vs Carto-light, #666 is 4.83:1 vs light / 3.30:1 vs dark).
- role="img" + aria-label with count + per-role breakdown.
V2 — role pills (.mc-pill, rendered by makeClusterIcon):
- ROLE_LETTERS map (R/C/M/S/O) as primary monochrome carrier.
- Wong (2011) colorblind-safe palette as --mc-role-* CSS vars.
- Dark text #1a1a1a on ALL five pills (audit minimal patch — no per-pill
text-color branching; all 5 pairs pass SC 1.4.3 small-text 4.5:1).
- Font bumped 9px → 10px monospace.
- Per-pill role="img" + aria-label "<N> <role>s".
V3 — multi-byte hash labels (makeRepeaterLabelIcon):
- MB_GLYPHS prefix (✓ confirmed / ? suspected / ✗ unknown) with U+2009
thin-space + hash, as the primary non-color carrier.
- Neutral --mc-mb-fill, 3px colored border-left using the audit's
higher-luminance accent set (#56F0A0 / #FFD966 / #FF8888 — NOT the
Tol "vibrant" set Tufte proposed, which failed 3:1 vs the dark fill).
- role="img" + aria-label "multi-byte <status>, hash <ID>"; the
visible glyph+hash span is aria-hidden="true" so AT does not read
"check mark 3 E" literally.
- MB_COLORS retained as an alias to MB_STATUS_CLASS (semantic flag only,
not a fill color); marker-dot tinting uses the same accent hexes.
Hard rules respected:
- --info / --warning / --accent untouched (constants are --mc-* namespaced).
- No regression to role-shape system (#1293/#1334/#1347) — that lives in
makeMarkerIcon and is unmodified.
- Forced-colors (Windows High Contrast) graceful degradation block added.
Design sources:
- #1356 (comment)
- #1356 (comment)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Operator feedback on #1334
PR #1334 (the #1293 marker a11y change) added a baked-in white outline at
stroke-width=2to every node marker viamakeRoleMarkerSVG. Operator reports it's too heavy and dominates the map at zoomed-out levels — every node reads as a "big white blob with a colour core", which actually drowns out the per-role shape silhouette at the exact zoom levels where the shape distinction matters most.Fix
Drop the always-on stroke from 2 → 1 across all marker producers:
public/roles.jsmakeRoleMarkerSVG(circle / square / triangle / diamond / hexagon)stroke-width="2"stroke-width="1"public/roles.jsmakeRoleMarkerSVG(star branch)stroke-width="1.5"stroke-width="1"public/live.jsaddNodeMarkerinline fallback SVGstroke-width="2"stroke-width="1"public/map.jsmakeMarkerIconswitch (all shapes)stroke-width="2"/"1.5"stroke-width="1"_highlightRing(pulse on selected/active)weight: 3 → 2The highlight ring used by
pulseNodeMarkeris the one place where a heavy outline carries real signal (selected state), so it stays at weight 3 → 2. The always-on shape stroke is now just enough to keep silhouettes distinct on both Carto dark and light basemaps without dominating the surrounding terrain.Constraints preserved
ROLE_COLORS.Tests
New:
test-marker-outline-weight.js(added totest-all.shunit suite)stroke-widthliteral inmakeRoleMarkerSVGis<= 1.live.jsinline fallback SVGstroke-width <= 1._highlightRing(ringHl.setStyle({ weight: N })) keeps at least oneweight >= 2so highlight stays visible.Red commit (
d17cfcc) fails on assertion; green commit (6cfe99b) flips it.Existing
test-issue-1293-marker-shapes.jsstill passes — the shape-variation and outline-ring highlight contracts are intact.