# Jeep SA Dealer Finder — Design Spec

**Date:** 2026-04-13  
**Project:** Jeep South Africa Dealer Locator  
**File:** `index.html`

---

## Overview

A single self-contained `index.html` file that functions as an iframe-embedded dealer finder widget for the Jeep South Africa website (`jeep.com/za`). The widget contains only body content — no external header, navigation, or footer — and is styled to match the Jeep brand visual identity so it feels native to the host page.

---

## Data Source

- **Input:** `Jeep_south_Africa_Dealer.csv` (~32 dealers)
- **Strategy:** CSV is parsed at build time and embedded as a JavaScript array directly in `index.html` (Option 1 — single self-contained file, zero runtime dependencies, no CORS issues)
- **Fields used per dealer:**
  - `Dealer Name`
  - `Address`, `City/Prefecture`, `State/Region`
  - `General Phone`
  - `DealerShip Email`
  - `Whatsapp Number`
  - `Latitude`, `Longitude`
  - `Monday` – `Sunday` (operating hours strings, e.g. `"8:00-17:00"` or `"Closed"`)

---

## Layout

**Option A — Left panel + right map** (full viewport height)

```
┌──────────────────────┬───────────────────────────────────┐
│  LEFT PANEL (380px)  │  MAP (flex: 1, full height)       │
│                      │                                   │
│  [Black header bar]  │  Leaflet / OpenStreetMap          │
│  FIND A DEALER  [32] │  Red pin markers                  │
│                      │  Popup on active dealer           │
│  [Search input]      │                                   │
│  [Near Me button]    │                                   │
│  [Province dropdown] │                                   │
│                      │                                   │
│  Showing X dealers   │                                   │
│  ──────────────────  │                                   │
│  Scrollable dealer   │                                   │
│  card list           │                                   │
└──────────────────────┴───────────────────────────────────┘
```

Responsive breakpoint at ≤980px: stacks vertically (panel on top, map below at 50vh).

---

## Visual Design

### Brand Palette
| Token | Value | Usage |
|---|---|---|
| `--black` | `#000000` | Panel header background, "Near Me" button |
| `--red` | `#BA0C2F` | CTAs, active card border, pin markers, city label, count badge |
| `--white` | `#ffffff` | Card backgrounds, text on dark |
| `--border` | `#eeeeee` | Card dividers, input borders |
| `--muted` | `#666666` | Address text, secondary info |

### Typography
- Font stack: `Arial, Helvetica, sans-serif` (matches jeep.com)
- Dealer names: `13px`, `font-weight: 700`, `text-transform: uppercase`, `letter-spacing: 0.5px`
- Section headings: `15px`, `font-weight: 700`, `text-transform: uppercase`, `letter-spacing: 2px`
- Body text: `12–13px`

---

## Left Panel Components

### Header Bar
- Background: `#000`
- Title: "FIND A DEALER" in white uppercase
- Count badge: pill in `#BA0C2F` showing live dealer count (e.g. "32 Dealers")

### Controls
- **Text search input:** full-width, searches across dealer name, city, address, phone
- **"Near Me" button:** triggers `navigator.geolocation`; re-sorts list by distance ascending
- **Province dropdown:** filters list to selected province; options derived from CSV data (All Provinces + unique values)

### Results bar
- Shows "Showing X dealers" text
- "Clear" link resets all filters

### Dealer Cards
Each card displays:
1. **Dealer name** — uppercase bold
2. **City · Province** — small, `#BA0C2F`
3. **Address** — muted
4. **Action buttons:**
   - "Directions" (red filled) → opens `https://www.google.com/maps/dir/?api=1&destination={lat},{lng}` in new tab
   - Phone number (outlined) → `tel:` link
   - "WhatsApp" (green outlined → filled on hover) → `https://wa.me/{number}` link (shown only if WhatsApp number exists in CSV)
5. **"Opening Hours ▼" toggle** — expands/collapses a Mon–Sun table; today's row highlighted in red

**Active state:** card has `border-left: 3px solid #BA0C2F` and light red tint background when its map pin is focused.

---

## Map

- **Library:** Leaflet 1.9.4 (CDN, free)
- **Tiles:** OpenStreetMap (`https://{s}.tile.openstreetmap.org/...`)
- **Markers:** Custom SVG teardrop pin in `#BA0C2F` with white circle centre
- **Active marker:** turns black when selected
- **Interactions:**
  - Clicking a dealer card → map flies to pin + opens popup
  - Clicking a map pin → highlights corresponding card in list + scrolls it into view
- **Initial view:** `fitBounds` on all visible markers; falls back to SA centre `[-28.5, 24.7]` zoom 5 if no markers
- **Popup:** white card with red top border showing dealer name, address, and "Directions" button

---

## Interactions & Behaviour

| Trigger | Result |
|---|---|
| Type in search | Filters list + map markers in real time |
| Select province | Filters list + map markers; stacks with text search |
| Click "Near Me" | Requests geolocation; re-sorts list by distance; map re-fits |
| Click "Clear" | Resets search + province; shows all dealers |
| Click dealer card | Map flies to pin, opens popup, card gets active style |
| Click map pin | Card scrolls into view, gets active style, popup opens |
| Click "Opening Hours" | Inline expand/collapse; today's row highlighted |
| Click "Directions" | New tab → Google Maps directions to dealer |
| Click phone number | `tel:` link |
| Click WhatsApp | New tab → `wa.me/{number}` |

---

## Single-file Build

The final `index.html` contains:
1. All CSS inline in `<style>`
2. Dealer data as `const DEALERS = [...]` JSON array (parsed from CSV)
3. Leaflet CSS loaded from CDN
4. Leaflet JS loaded from CDN
5. All application logic inline in `<script>`

No build tool required. To update dealers: re-run the data-embed step (or manually update the `DEALERS` array).

---

## Out of Scope

- No "Book a Test Drive" CTA (not in CSV data)
- No dealer detail pages
- No inventory search
- No server-side component
- No IE11 support
