Skill: mapbox/mapbox-cartography (version 1.0.0)

--- name: mapbox-cartography description: Expert guidance on map design principles, color theory, visual hierarchy, typography, and cartographic best practices for creating effective and beautiful maps with Mapbox. Use when designing map styles, choosing colors, or making cartographic decisions. --- # Mapbox Cartography Skill This skill provides expert cartographic knowledge to help you design effective, beautiful, and functional maps using Mapbox. ## Core Cartographic Principles ### Visual Hierarchy Maps must guide the viewer's attention to what matters most: - **Most important**: POIs, user location, route highlights - **Secondary**: Major roads, city labels, landmarks - **Tertiary**: Minor streets, administrative boundaries - **Background**: Water, land use, terrain **Implementation:** - Use size, color intensity, and contrast to establish hierarchy - Primary features: high contrast, larger symbols, bold colors - Background features: low contrast, muted colors, smaller text ### Color Theory for Maps **Color Harmony:** - **Analogous colors**: Use colors next to each other on color wheel (blue-green-teal) for cohesive designs - **Complementary colors**: Use opposite colors (blue/orange, red/green) for high contrast emphasis - **Monochromatic**: Single hue with varying saturation/brightness for elegant, minimal designs **Color Psychology:** - **Blue**: Water, trust, calm, professional (default for water bodies) - **Green**: Parks, nature, growth, eco-friendly (vegetation, parks) - **Red/Orange**: Urgent, important, dining (alerts, restaurants) - **Yellow**: Caution, highlight, attention (warnings, selected items) - **Gray**: Neutral, background, roads (infrastructure) **Accessibility:** - Ensure 4.5:1 contrast ratio for text (WCAG AA) - Don't rely solely on color to convey information - Test designs with colorblind simulators - Avoid red/green combinations for critical distinctions **Color Palette Templates:** Light Theme (Day/Professional): ```json { "background": "#f5f5f5", "water": "#a0c8f0", "parks": "#d4e7c5", "roads": "#ffffff", "buildings": "#e0e0e0", "text": "#333333" } ``` Dark Theme (Night Mode): ```json { "background": "#1a1a1a", "water": "#0d47a1", "parks": "#2e7d32", "roads": "#3a3a3a", "buildings": "#2d2d2d", "text": "#ffffff" } ``` > **Road color rule for dark themes:** Roads must use neutral dark gray (`#3a3a3a`), visibly distinct from the background but not colored. Never style roads with amber, blue, or other hues — reserve color for app data layers (routes, markers). Colored base roads and colored data layers will compete visually. Local roads that blend into the background (`#1e1e1e` on `#1a1a1a`) create a "floating labels" problem where street names appear with no visible road beneath them. High Contrast (Accessibility): ```json { "background": "#000000", "water": "#0066ff", "parks": "#00ff00", "roads": "#ffffff", "buildings": "#808080", "text": "#ffffff" } ``` Vintage/Retro: ```json { "background": "#f4e8d0", "water": "#b8d4d4", "parks": "#c8d4a4", "roads": "#d4c4a8", "buildings": "#e4d4c4", "text": "#4a3828" } ``` ### Typography at Map Scale **Font Selection:** - **Sans-serif** (Roboto, Open Sans): Modern, clean, high legibility at small sizes - use for labels - **Serif** (Noto Serif): Traditional, formal - use sparingly for titles or historic maps - **Monospace**: Technical data, coordinates **Text Sizing:** ``` Place labels (cities, POIs): 11-14px Street labels: 9-11px Feature labels (parks): 10-12px Map title: 16-20px Attribution: 8-9px ``` **Label Placement:** - Point labels: Center or slightly offset (avoid overlap with symbol) - Line labels: Follow line curve, repeat for long features - Area labels: Center in polygon, sized appropriately - Prioritize: Major features get labels first, minor features labeled if space allows ### Zoom Level Strategy **Zoom 0-4** (World to Continent): - Major country boundaries - Ocean and sea labels - Capital cities only **Zoom 5-8** (Country to State): - State/province boundaries - Major cities - Major highways - Large water bodies **Zoom 9-11** (Metro Area): - City boundaries - Neighborhoods - All highways and major roads - Parks and landmarks **Zoom 12-15** (Neighborhood): - All streets - Building footprints - POIs (restaurants, shops) - Street names > **Note:** Mapbox's hosted Streets style defaults to showing most POIs around zoom 14. For custom styles, start POIs at zoom 12 — this is the neighborhood scale where density is manageable and users are browsing. Zoom 14 is late; zoom 10 (metro-area scale) is far too early and creates severe icon clutter. **Zoom 16-22** (Street Level): - All detail - House numbers - Parking lots - Fine-grained POIs ## Mapbox-Specific Implementation Guidance ### Style Layer Best Practices **Layer Ordering (bottom to top):** 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 → local streets) 7. Borders (country, state lines) 8. Labels (place names, street names) 9. POI symbols 10. User-generated content (routes, markers) > **Common mistake:** Developers often put their app's route line or active markers _below_ POI symbols, reasoning that "POIs must stay visible." This is backwards — user-generated content (your route, selected location, user position) is the most important layer and must render above everything, including POIs. A route line that covers a POI icon is acceptable; a route obscured by POI icons is not. ### Map Context Considerations **Know Your Audience:** - **General public**: Simplify, use familiar patterns (Google/Apple style) - **Technical users**: Include more detail, technical layers, data precision - **Domain experts**: Show specialized data, use domain-specific symbology **Platform Considerations:** - **Mobile**: Larger touch targets (44x44px minimum), simpler designs, readable at arm's length - **Desktop**: Can include more detail, hover interactions, complex overlays - **Print**: Higher contrast, larger text, consider CMYK color space - **Outdoor/Bright**: Higher contrast, avoid subtle grays **Use Case Optimization:** - **Navigation**: Emphasize roads, clear hierarchy, route visibility - **Data visualization**: Muted base map, let data stand out - **Storytelling**: Guide viewer attention, establish mood with colors - **Location selection**: Show POIs clearly, provide context - **Analysis**: Include relevant layers, maintain clarity at different zooms ## Reference Files For detailed guidance on specific topics, load these references as needed: - `references/scenarios.md` — Common scenario guidance (Restaurant Finder, Real Estate, Data Visualization, Navigation) - `references/performance-testing.md` — Performance optimization, testing checklist, and common mistakes to avoid ## When to Use This Skill Invoke this skill when: - Designing a new map style - Choosing colors for map elements - Making decisions about visual hierarchy - Optimizing for specific use cases - Troubleshooting visibility issues - Ensuring accessibility - Creating themed maps (dark mode, vintage, etc.)

path: AGENTS.md
content: # Mapbox Cartography Principles

Quick reference for map design, color theory, visual hierarchy, and accessibility.

## Core Cartography Principles

### 1. Visual Hierarchy

**Most Important Rule:** Direct user attention to what matters most.

**Priority levels:**

- **Primary:** Main features (roads, labels for user's task)
- **Secondary:** Supporting context (water, parks)
- **Tertiary:** Background (minor roads, less important labels)

**Tools:**

- Size: Larger = more important
- Color: Brighter/saturated = more important
- Contrast: Higher contrast = more important
- Position: Foreground > Background

### 2. Figure-Ground Relationship

**Make primary features stand out from background:**

```javascript
// ✅ Good contrast between features and background
'background': '#f8f8f8',     // Light gray
'water': '#a8d5ff',          // Distinct blue
'roads': '#ffffff',          // Bright white
'labels': '#333333'          // Dark text
```

### 3. Color Theory

**Color Schemes:**

- **Sequential:** Light → Dark (population density, elevation)
- **Diverging:** Low ← Neutral → High (temperature, sentiment)
- **Categorical:** Distinct colors for categories (never more than 7-8)

**Rules:**

- Limit palette to 5-7 colors maximum
- Use ColorBrewer for data visualization
- Test for colorblindness (deuteranopia most common)
- Avoid red/green combinations

### 4. Label Hierarchy

**Typography sizing:**

```javascript
// Cities by population
'text-size': [
  'interpolate', ['linear'], ['zoom'],
  4, ['match', ['get', 'type'],
    'capital', 16,
    'city', 12,
    'town', 10,
    8
  ]
]
```

**Label placement rules:**

- Cities: Above point
- Roads: Along line
- Areas: Inside polygon
- Avoid label collisions (use `text-allow-overlap: false`)

## Color Best Practices

### Accessible Color Contrast

**WCAG 2.1 Standards:**

- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- Essential graphics: 3:1 contrast ratio

```javascript
// ✅ Good contrast for labels
'text-color': '#333333',     // Dark text
'text-halo-color': '#ffffff', // White halo
'text-halo-width': 2
```

### Colorblind-Safe Palettes

**Avoid:**

- ❌ Red/Green (deuteranopia)
- ❌ Blue/Yellow (tritanopia)
- ❌ Pure color differentiation

**Use:**

- ✅ Pattern/texture in addition to color
- ✅ Labels for categories
- ✅ Size/shape variations
- ✅ Colorblind-safe palettes (ColorBrewer)

## Typography

### Font Selection

**Mapbox fonts:**

- **Roboto**: Clean, modern, web-optimized
- **Open Sans**: Highly legible, good for labels
- **DIN Pro**: Professional, geometric
- **Montserrat**: Elegant headlines

**Rules:**

- Max 2 font families per map
- Use font-weight for hierarchy
- Sans-serif for UI, optional serif for labels

### Label Sizing

**Base sizes:**

```javascript
'text-size': [
  'interpolate', ['linear'], ['zoom'],
  8, 10,    // Small at low zoom
  12, 14,   // Medium at mid zoom
  16, 18    // Large at high zoom
]
```

## Data Visualization

### Choropleth Maps

**For area data (population, income, etc.):**

```javascript
// ✅ Use sequential colors
'fill-color': [
  'step',
  ['get', 'density'],
  '#f7fbff',  // Light
  10, '#deebf7',
  20, '#c6dbef',
  50, '#9ecae1',
  100, '#6baed6',
  200, '#3182bd',
  500, '#08519c'  // Dark
]
```

**Rules:**

- 5-7 data classes maximum
- Equal intervals or quantiles
- Include legend
- Show data source

### Proportional Symbols

**For point data (city size, counts):**

```javascript
// ✅ Scale circle size by value
'circle-radius': [
  'interpolate', ['linear'], ['get', 'population'],
  0, 5,           // Min: 5px
  100000, 15,     // Mid: 15px
  1000000, 30     // Max: 30px
]
```

## Map Styles by Use Case

### Navigation/Wayfinding

- **Emphasize:** Roads, labels, route
- **De-emphasize:** Buildings, terrain
- **Colors:** High contrast, clear hierarchy

### Data Visualization

- **Emphasize:** Data layer, legend
- **De-emphasize:** Base map (grayscale)
- **Colors:** Data-appropriate palette

### Storytelling

- **Emphasize:** Story points, annotations
- **De-emphasize:** Irrelevant features
- **Colors:** Support narrative mood

### Reference Map

- **Balanced:** All features proportionate
- **Clear:** Good labels, readable
- **Colors:** Conventional (blue water, green parks)

## Quick Design Checklist

✅ Clear visual hierarchy (primary features stand out)
✅ Limited color palette (5-7 colors max)
✅ Accessible contrast ratios (4.5:1 for text)
✅ Colorblind-safe colors (avoid red/green alone)
✅ Appropriate label sizes (scales with zoom)
✅ No label collisions (readable at all zooms)
✅ Legend included (for data visualization)
✅ Consistent styling (similar features look similar)
✅ Tested at multiple zoom levels
✅ Mobile-friendly (tap targets, text size)

## Common Mistakes

❌ Too many colors (>7 categories)
❌ Poor contrast (low visibility)
❌ Red/green combinations (colorblind users)
❌ Small text without halos (illegible)
❌ Cluttered labels (overlapping)
❌ Inconsistent styling (confusing)
❌ No legend (data maps unclear)
❌ Ignoring zoom levels (too much/little detail)


path: evals/evals.json
content: {
  "skill_name": "mapbox-cartography",
  "evals": [
    {
      "id": 1,
      "prompt": "I'm building a Mapbox style for a delivery app and need to know the correct layer order. I have these layers: user's active route line, restaurant POI markers, building footprints, road labels, and hillshade terrain. Put them in the correct bottom-to-top render order and explain why.",
      "expected_output": "Should produce the exact order from the skill's 10-step layer hierarchy: hillshade/terrain first, then buildings, then road labels, then POI symbols (restaurants), then user-generated content (active route) on top. Should explain that user content always renders above base data, and labels above geometry.",
      "files": [],
      "expectations": [
        "Places hillshade/terrain below building footprints",
        "Places building footprints below road labels",
        "Places road labels below restaurant POI markers",
        "Places restaurant POI markers below the user's active route line",
        "User route is the topmost layer"
      ]
    },
    {
      "id": 2,
      "prompt": "Our product manager wants restaurant POI icons to appear starting at zoom 10, but a teammate says that's too early and recommends zoom 14. Who is right? And separately — at what zoom level should house numbers first appear?",
      "expected_output": "Should say zoom 10 is too early and zoom 14 is too late — restaurants/POIs belong in the zoom 12-15 range per the cartographic zoom strategy. House numbers should appear at zoom 16+. Should explain the rationale: showing POIs before zoom 12 creates visual clutter at the metro/neighborhood scale.",
      "files": [],
      "expectations": [
        "States that zoom 10 is too early for restaurant POIs",
        "States that zoom 14 is at the late end or acceptable, but zoom 12 is the correct start for POIs",
        "POI recommendation falls in the zoom 12-15 range",
        "States house numbers should appear at zoom 16 or later",
        "Explains the cartographic rationale (clutter, appropriate detail for scale)"
      ]
    },
    {
      "id": 3,
      "prompt": "Give me a complete dark theme color palette for a Mapbox map with exact hex values for: background/land, water, parks/vegetation, roads, buildings, and text labels. This is for a professional nighttime navigation app.",
      "expected_output": "Should provide the skill's dark theme template values (or very close): background #1a1a1a, water dark blue (#0d47a1), parks dark green (#2e7d32), roads dark gray (#3a3a3a), buildings slightly lighter gray (#2d2d2d), text white (#ffffff). Should NOT give generic 'use a dark color' advice without specifics.",
      "files": [],
      "expectations": [
        "Provides a dark near-black background value close to #1a1a1a",
        "Provides a dark blue for water (not light blue — this is a dark theme)",
        "Provides a dark green for parks/vegetation",
        "Roads are a mid-dark gray distinct from the background (not the same color)",
        "Text is white or near-white for readability on dark background",
        "All 6 values given as specific hex codes, not just descriptions"
      ]
    }
  ]
}


path: references/performance-testing.md
content: # Performance, Testing & Common Mistakes

## Performance Optimization

**Style Performance:**

- Minimize layer count (combine similar layers)
- Use expressions instead of multiple layers for variants
- Simplify complex geometries at lower zooms
- Use sprite sheets for repeated icons
- Leverage tileset simplification

**Loading Speed:**

- Preload critical zoom levels
- Use style optimization tools
- Minimize external resource calls
- Compress images in sprite sheets

## Testing Your Design

**Checklist:**

- [ ] View at all relevant zoom levels
- [ ] Test in different lighting conditions
- [ ] Check on actual devices (mobile, desktop)
- [ ] Verify color accessibility (colorblind.org)
- [ ] Review with target users
- [ ] Test with real data density
- [ ] Check label collision/overlap
- [ ] Verify performance on slower devices

## Common Mistakes to Avoid

1. **Too many colors**: Stick to 5-7 main colors maximum
2. **Insufficient contrast**: Text must be readable
3. **Overcrowding**: Not everything needs a label
4. **Ignoring zoom levels**: Show appropriate detail for scale
5. **Poor label hierarchy**: Organize by importance
6. **Inconsistent styling**: Maintain visual consistency
7. **Neglecting performance**: Complex styles slow rendering
8. **Forgetting mobile**: Test on actual devices


path: references/scenarios.md
content: # Common Mapping Scenarios

## Scenario: Restaurant Finder App

**Requirements:**

- Restaurants must be highly visible
- Street context for navigation
- Muted background (food photos overlay)

**Recommendations:**

- Use bold, warm colors for restaurant markers (red, orange)
- Gray out background (low saturation)
- Keep street labels clear but not dominant
- High contrast for selected restaurant
- Mobile-optimized touch targets

## Scenario: Real Estate Map

**Requirements:**

- Property boundaries clearly visible
- Neighborhood context
- Price differentiation

**Recommendations:**

- Use color scale for price ranges (green=affordable, red=expensive)
- Show parks and amenities prominently
- Include school zones if relevant
- Label neighborhoods clearly
- Show transit access

## Scenario: Data Visualization Overlay

**Requirements:**

- Data layer is primary focus
- Base map provides context only
- Multiple data points may cluster

**Recommendations:**

- Monochromatic, low-contrast base map
- Use data-ink ratio principle (minimize non-data elements)
- Base map grayscale or single muted hue
- Remove unnecessary labels
- Consider using light base for dark data, vice versa

## Scenario: Navigation/Routing

**Requirements:**

- Route must be unmissable
- Turn-by-turn clarity
- Current location always visible

**Recommendations:**

- Route in high-contrast color (blue or purple)
- Animate route line or use dashed pattern
- Large, clear turn indicators
- Dim unrelated features
- User location: pulsing blue dot
- Next turn: prominent arrow/icon


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)