Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions skills/mapbox-cartography/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,30 @@ Quick reference for map design, color theory, visual hierarchy, and accessibilit
- Areas: Inside polygon
- Avoid label collisions (use `text-allow-overlap: false`)

### 5. Layer Order

Bottom to top. Anything the user generated sits on top of the basemap, and POI
symbols sit below it — a route or marker the user is actively following must never
be occluded by basemap POIs.

1. Background (solid color or pattern)
2. Landuse (parks, residential, commercial)
3. Water bodies (oceans, lakes, rivers)
4. Terrain/hillshade (if using elevation)
5. Buildings (3D or 2D footprints)
6. Roads (highways to local streets)
7. Borders (country, state lines)
8. Labels (place names, street names)
9. POI symbols
10. User-generated content (routes, markers) — topmost

### 6. Feature Zoom Thresholds

Mapbox's hosted Streets style shows most POIs around zoom 14. For custom styles,
**start POIs at zoom 12** — neighborhood scale, where density is manageable and
users are browsing. Zoom 14 is at the late end but acceptable; zoom 10 is
metro-area scale and far too early, producing severe icon clutter.

## Color Best Practices

### Accessible Color Contrast
Expand Down
63 changes: 58 additions & 5 deletions skills/mapbox-style-patterns/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,21 +233,74 @@ map.addLayer({
});
```

**The base map matters as much as the fill.** Data colors need an uncontested
background, so pair a choropleth with a minimal grayscale base:

- Grayscale palette throughout — never a standard streets or otherwise colorful style
- Gray/desaturated water, **not** blue: blue water competes directly with a red/blue
political choropleth
- Minimal road detail — major roads only at low zoom, or none at all
- Major city labels only for orientation, not the full POI and street label set

### Route Visualization

A route needs **two** layers: a wider casing behind, and a narrower colored line on
top. A single line has no contrast against roads of a similar color, and reads as
just another street.

```javascript
// Casing first (wider, darker) so it renders behind
map.addLayer({
id: 'route-casing',
type: 'line',
source: 'route',
paint: { 'line-color': '#0d47a1', 'line-width': 9 }
});

map.addLayer({
id: 'route',
type: 'line',
source: 'route',
paint: {
'line-color': '#0080ff',
'line-width': 5,
'line-opacity': 0.8
}
paint: { 'line-color': '#0080ff', 'line-width': 5, 'line-opacity': 0.8 }
});
```

### Delivery Zones by Status

Zones carry a status, so the fill must be data-driven. A single static `fill-color`
across all zones throws away the information the user needs.

```javascript
'fill-color': [
'match', ['get', 'status'],
'available', '#4caf50',
'busy', '#ff9800',
'unavailable', '#f44336',
'#9e9e9e' // fallback
]
```

### Pulsing Marker (Active Delivery / Live Location)

Drive a second circle layer beneath the marker with `requestAnimationFrame`,
updating paint properties each frame — there is no built-in pulse.

```javascript
function pulseCustomerMarker() {
const duration = 2000;
const start = performance.now();

function animate(time) {
const phase = ((time - start) % duration) / duration;
map.setPaintProperty('customer-pulse', 'circle-radius', 12 + phase * 12);
map.setPaintProperty('customer-pulse', 'circle-opacity', 0.3 * (1 - phase));
requestAnimationFrame(animate);
}

requestAnimationFrame(animate);
}
```

### 3D Buildings

```javascript
Expand Down
39 changes: 38 additions & 1 deletion skills/mapbox-style-quality/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,41 @@

Quick reference for style validation, accessibility, performance optimization, and testing.

## Validation Tools

These MCP tools do the work described in this guide — reach for them rather than
eyeballing a style or relying on generic web validators.

| Tool | Use it for |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `validate_geojson_tool` | Validate external GeoJSON **before** adding it as a source — catches invalid coordinates, unclosed rings, wrong coordinate order |
| `validate_expression_tool` | Validate expressions as you write them, during development, so type mismatches never reach runtime |
| `check_color_contrast_tool` | Check foreground/background contrast for text layers against WCAG AA (4.5:1 normal, 3:1 large) |
| `compare_styles_tool` | Diff a style against the previous production version to surface unintended changes |
| `optimize_style_tool` | Reduce style size before deploying |

**Pre-deploy order:** validate GeoJSON sources → validate expressions → check label
contrast → compare against the previous production style → optimize → review the
report (`percentReduction`, `changes`) and test before shipping.

**What `optimize_style_tool` does, in order:** removes unused sources left behind by
deleted layers, eliminates duplicate layers with identical paint properties,
simplifies redundant boolean expressions in filters (collapsing `["all", expr]` to
`expr`, dropping tautological conditions), then removes empty layers as a final
cleanup step.

**Automate it.** Catching expression and contrast errors by hand is a losing game —
wire validation into a pre-commit hook and CI so a broken expression cannot reach
production:

```
1. Validate all expressions
2. Check accessibility compliance
3. Run optimization (warn if significant savings)
4. Compare with the production version
5. Generate a quality report
```

## Style Validation Rules

### Required Elements
Expand Down Expand Up @@ -295,11 +330,13 @@ if (!map.getSource('source')) {

**Validation:**

- `validate_geojson_tool`, `validate_expression_tool`, `compare_styles_tool`,
`optimize_style_tool` (see [Validation Tools](#validation-tools))
- Mapbox Style Specification: <https://docs.mapbox.com/mapbox-gl-js/style-spec/>
- JSON Schema validators

**Accessibility:**

- `check_color_contrast_tool` for WCAG AA/AAA checks on label layers
- WebAIM Contrast Checker
- Coblis Color Blindness Simulator
- WAVE Accessibility Evaluation Tool
Expand Down
Loading