feat(street-level): one colour per imagery source

As more sources arrive, each one reads the same everywhere it appears: its
PROVIDERS chip, coverage lines, overview points, image cones and a single
legend swatch. The palette lives in one place, PROVIDER_COLORS in
src/layers/streetLevel/policy.js: Mapillary green (#05cb63), Panoramax
purple, Google Street View blue.

Mapillary drops its age dimming and magenta panoramas: lines and overview
points are Mapillary green, cones are green too and 360° images keep their
ring shape; the 360°/FLAT filter still separates them, and the selected
sequence stays GEV cyan.

The provider contract loses `legend`: `colors.coverage` is the source's one
colour, and the core composes the legend as one swatch per active source
(its name, its colour) followed by Selected. The chip group takes an
optional per-chip colour as a `--chip-color` CSS variable, written only
when it changes; Street Level chips show it as a swatch dot and, while on,
as the chip's border, text and a faint fill.

The feature gate checks the legend has one swatch per source plus Selected
and that the Mapillary chip carries #05cb63.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Opus 5.5 committed 2026-09-29 00:03:00 +01:00
1 parent d5da45eacb
commit 0f2cac2ca2
21 files changed
+188 -99

No files matched your search

+4 -3
View File
@@ -11,7 +11,6 @@ const def = (overrides = {}) => ({
colors: { coverage: '#05cb63' },
credit: { key: 'mapillary', html: 'Mapillary' },
capabilities: { coverage: 'tiles', sequences: true },
legend: [],
externalUrl: (id) => `https://example.test/${id}`,
create: () => ({}),
...overrides,
@@ -44,7 +43,6 @@ test('every required field is checked by name', () => {
'colors',
'credit',
'capabilities',
'legend',
'externalUrl',
'create',
])
@@ -58,7 +56,10 @@ test('every required field is checked by name', () => {
() => validateProviders([def({ credit: { key: 'x' } })]),
/credit/,
);
assert.throws(() => validateProviders([def({ legend: 'no' })]), /legend/);
assert.throws(
() => validateProviders([def({ colors: { pano: '#f0f' } })]),
/coverage colour/,
);
assert.throws(
() => validateProviders([def({ pickPrefix: '' })]),
/pick prefix/,