diff --git a/internal/mocks/mocks.go b/internal/mocks/mocks.go
index 514bd7e2b8bd7327aae3faa213408f548230e621..d5ca06a778648f6859f109787f5989eaf074c93b 100644
--- a/internal/mocks/mocks.go
+++ b/internal/mocks/mocks.go
@@ -7,7 +7,7 @@ import (
 	"os"
 	"strconv"
 
-	"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/middlewares"
+	"forge.grandlyon.com/gestion-des-assemblees/elections/pkg/middlewares"
 )
 
 const literralContentType = "Content-Type"
diff --git a/internal/rootmux/rootmux.go b/internal/rootmux/rootmux.go
index 9d09f7088a1a1a2d71a20990b550850be6f8a73a..6bbd0122f54a73f929f87cb5ff93594458d00652 100644
--- a/internal/rootmux/rootmux.go
+++ b/internal/rootmux/rootmux.go
@@ -6,7 +6,7 @@ import (
 
 	"forge.grandlyon.com/gestion-des-assemblees/elections/internal/auth"
 	"forge.grandlyon.com/gestion-des-assemblees/elections/internal/models"
-	"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/middlewares"
+	"forge.grandlyon.com/gestion-des-assemblees/elections/pkg/middlewares"
 
 	"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/common"
 )
@@ -47,6 +47,6 @@ func CreateRootMux(port int, staticDir string) RootMux {
 	mainMux.Handle("/", middlewares.NoCache(http.FileServer(&common.FallBackWrapper{Assets: http.Dir(staticDir)})))
 	// Put it together into the main handler
 	mux := http.NewServeMux()
-	mux.Handle(hostname+"/", middlewares.WebSecurity(mainMux, "*."+hostname+":*", false))
+	mux.Handle(hostname+"/", middlewares.WebSecurity(mainMux, "*."+hostname+":* *.mapbox.com *.grandlyon.com ", false))
 	return RootMux{mux, &m}
 }
diff --git a/main.go b/main.go
index 3520591433848b7e54888af26407ddd9bceca06a..21814b981479b09d827296b57495946aea351065 100644
--- a/main.go
+++ b/main.go
@@ -11,7 +11,7 @@ import (
 	"syscall"
 	"time"
 
-	"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/middlewares"
+	"forge.grandlyon.com/gestion-des-assemblees/elections/pkg/middlewares"
 	"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/tokens"
 
 	"forge.grandlyon.com/gestion-des-assemblees/elections/internal/mocks"
diff --git a/pkg/middlewares/middlewares.go b/pkg/middlewares/middlewares.go
new file mode 100644
index 0000000000000000000000000000000000000000..d7a68e6e42e8f6a73ef27ce9a1bb9762f5fa7d16
--- /dev/null
+++ b/pkg/middlewares/middlewares.go
@@ -0,0 +1,51 @@
+package middlewares
+
+import (
+	"fmt"
+	"net/http"
+	"strconv"
+)
+
+// Cors enables CORS Request on server (for development purposes)
+func Cors(next http.Handler, allowedOrigin string) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		w.Header().Set("Access-Control-Allow-Origin", allowedOrigin)
+		w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, PROPFIND, MKCOL, MOVE, COPY")
+		w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, XSRF-TOKEN, Authorization, Depth, Destination")
+		w.Header().Set("Access-Control-Allow-Credentials", "true")
+		next.ServeHTTP(w, req)
+	})
+}
+
+// WebSecurity adds good practices security headers on http responses
+func WebSecurity(next http.Handler, source string, allowEvalInlineScript bool) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		w.Header().Set("Strict-Transport-Security", "max-age=63072000")
+		var inline string
+		if allowEvalInlineScript {
+			inline = "'unsafe-inline' 'unsafe-eval'"
+		}
+		w.Header().Set("Content-Security-Policy", fmt.Sprintf("default-src %[1]v 'self'; img-src %[1]v 'self' data: blob:; script-src %[1]v 'self' %[2]v; style-src %[1]v 'self' 'unsafe-inline'; frame-src %[1]v; frame-ancestors %[1]v; worker-src blob: ;child-src blob: ;", source, inline))
+		//w.Header().Set("X-Frame-Options", "SAMEORIGIN") // Works fine with chrome but is not obsoleted by frame-src in firefox 72.0.2
+		w.Header().Set("X-XSS-Protection", "1; mode=block")
+		w.Header().Set("Referrer-Policy", "strict-origin")
+		w.Header().Set("X-Content-Type-Options", "nosniff")
+		next.ServeHTTP(w, req)
+	})
+}
+
+// NoCache disable caching
+func NoCache(next http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		w.Header().Set("Cache-Control", "no-store, must-revalidate")
+		next.ServeHTTP(w, req)
+	})
+}
+
+// GetFullHostname returns the full hostname of the server
+func GetFullHostname(hostname string, port int) string {
+	if port == 80 || port == 443 {
+		return "https://" + hostname
+	}
+	return "https://" + hostname + ":" + strconv.Itoa(port)
+}
diff --git a/web/assets/mapbox/vector.json b/web/assets/mapbox/vector.json
new file mode 100644
index 0000000000000000000000000000000000000000..c6a026345b88a4c930fd40017c79ac27664c7938
--- /dev/null
+++ b/web/assets/mapbox/vector.json
@@ -0,0 +1,1106 @@
+{
+  "version": 8,
+  "name": "data",
+  "metadata": {
+    "mapbox:autocomposite": false,
+    "mapbox:type": "template",
+    "maputnik:renderer": "mbgljs",
+    "openmaptiles:version": "3.x",
+    "openmaptiles:mapbox:owner": "openmaptiles",
+    "openmaptiles:mapbox:source:url": "mapbox://openmaptiles.4qljc88t"
+  },
+  "sources": {
+    "openmaptiles": {
+      "type": "vector",
+      "tiles": [
+        "https://openmaptiles.data.grandlyon.com/data/v3/{z}/{x}/{y}.pbf"
+      ],
+      "minzoom": 0,
+      "maxzoom": 22,
+      "attribution": "© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors"
+    }
+  },
+  "sprite": "https://minio.alpha.grandlyon.com/mapbox-assets/mapbox-sprite",
+  "glyphs": "https://minio.alpha.grandlyon.com/mapbox-glyphs/{fontstack}/{range}.pbf",
+  "layers": [
+    {
+      "id": "background",
+      "type": "background",
+      "paint": {
+        "background-color": "#f1f3f8"
+      }
+    },
+    {
+      "id": "landuse-residential",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "landuse",
+      "filter": [
+        "all",
+        ["==", "$type", "Polygon"],
+        ["==", "class", "residential"]
+      ],
+      "layout": {
+        "visibility": "visible"
+      },
+      "paint": {
+        "fill-color": "rgba(237, 238, 234, 1)",
+        "fill-opacity": 0.7
+      }
+    },
+    {
+      "id": "landcover",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "landcover",
+      "filter": ["match", ["get", "class"], ["wood", "grass"], true, false],
+      "paint": {
+        "fill-color": "#C8E8B6"
+      }
+    },
+    {
+      "id": "landcover_grass",
+      "type": "fill",
+      "source": "openmaptiles",
+      "minzoom": 11,
+      "source-layer": "landcover",
+      "filter": ["==", "class", "grass"],
+      "paint": {
+        "fill-pattern": "grass"
+      }
+    },
+    {
+      "id": "landcover_wood",
+      "type": "fill",
+      "minzoom": 11,
+      "source": "openmaptiles",
+      "source-layer": "landcover",
+      "filter": ["match", ["get", "class"], ["wood"], true, false],
+      "paint": {
+        "fill-pattern": "wood"
+      }
+    },
+    {
+      "id": "water",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "water",
+      "filter": ["==", "$type", "Polygon"],
+      "paint": {
+        "fill-color": "#accce9",
+        "fill-outline-color": "hsla(209, 58%, 79%, 0.7)",
+        "fill-pattern": "water",
+        "fill-opacity": 1
+      }
+    },
+    {
+      "id": "landcover-ice-shelf",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "landcover",
+      "filter": ["==", "subclass", "ice_shelf"],
+      "layout": {
+        "visibility": "visible"
+      },
+      "paint": {
+        "fill-color": "hsl(47, 26%, 88%)",
+        "fill-opacity": 0.8
+      }
+    },
+    {
+      "id": "landcover-glacier",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "landcover",
+      "filter": ["==", "subclass", "glacier"],
+      "layout": {
+        "visibility": "visible"
+      },
+      "paint": {
+        "fill-color": "hsl(47, 22%, 94%)",
+        "fill-opacity": {
+          "base": 1,
+          "stops": [
+            [0, 1],
+            [8, 0.5]
+          ]
+        }
+      }
+    },
+    {
+      "id": "landcover_sand",
+      "type": "fill",
+      "metadata": {},
+      "source": "openmaptiles",
+      "source-layer": "landcover",
+      "filter": ["all", ["in", "class", "sand"]],
+      "paint": {
+        "fill-antialias": false,
+        "fill-color": "rgba(232, 214, 38, 1)",
+        "fill-opacity": 0.3
+      }
+    },
+    {
+      "id": "landuse",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "landuse",
+      "minzoom": 15,
+      "filter": [
+        "match",
+        ["get", "class"],
+        ["airport", "hospital", "school"],
+        true,
+        false
+      ],
+      "layout": {},
+      "paint": {
+        "fill-color": [
+          "match",
+          ["get", "class"],
+          ["airport"],
+          "#e0e4f0",
+          ["hospital"],
+          "#e0e4f0",
+          ["school"],
+          "#e0e4f0",
+          "hsla(0, 0%, 0%, 0)"
+        ],
+        "fill-opacity": ["interpolate", ["linear"], ["zoom"], 5, 0, 6, 1],
+        "fill-outline-color": "hsl(0, 0%, 100%)"
+      }
+    },
+    {
+      "id": "landuse_overlay_national_park",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "landcover",
+      "filter": ["==", "class", "national_park"],
+      "paint": {
+        "fill-color": "#E1EBB0",
+        "fill-opacity": {
+          "base": 1,
+          "stops": [
+            [5, 0],
+            [9, 0.75]
+          ]
+        }
+      }
+    },
+    {
+      "id": "park_outline",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "park",
+      "layout": {},
+      "paint": {
+        "line-color": "rgba(159, 183, 118, 0.69)",
+        "line-dasharray": [0.5, 1]
+      }
+    },
+    {
+      "id": "waterway-tunnel",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "waterway",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "tunnel"]
+      ],
+      "paint": {
+        "line-color": "hsl(205, 56%, 73%)",
+        "line-width": {
+          "base": 1.4,
+          "stops": [
+            [8, 1],
+            [20, 2]
+          ]
+        },
+        "line-opacity": 1,
+        "line-gap-width": {
+          "stops": [
+            [12, 0],
+            [20, 6]
+          ]
+        },
+        "line-dasharray": [3, 3]
+      }
+    },
+    {
+      "id": "waterway",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "waterway",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["!in", "brunnel", "tunnel", "bridge"]
+      ],
+      "layout": {
+        "visibility": "none"
+      },
+      "paint": {
+        "line-color": "hsl(205, 56%, 73%)",
+        "line-width": {
+          "base": 1.4,
+          "stops": [
+            [8, 1],
+            [20, 8]
+          ]
+        },
+        "line-opacity": 1
+      }
+    },
+    {
+      "id": "tunnel_railway_transit",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "minzoom": 0,
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "tunnel"],
+        ["==", "class", "transit"]
+      ],
+      "layout": {
+        "line-cap": "butt",
+        "line-join": "miter"
+      },
+      "paint": {
+        "line-color": "rgba(170, 170, 170, 1)",
+        "line-opacity": {
+          "base": 1,
+          "stops": [
+            [11, 0],
+            [16, 1]
+          ]
+        },
+        "line-dasharray": [3, 3]
+      }
+    },
+    {
+      "id": "building",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "building",
+      "minzoom": 15,
+      "layout": {},
+      "paint": {
+        "fill-color": "#e0e4f0",
+        "fill-opacity": ["interpolate", ["linear"], ["zoom"], 13.5, 0, 14, 1],
+        "fill-outline-color": "#f1f3f8"
+      }
+    },
+    {
+      "id": "housenumber",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "housenumber",
+      "minzoom": 17,
+      "filter": ["==", "$type", "Point"],
+      "layout": {
+        "text-field": "{housenumber}",
+        "text-size": 10,
+        "text-font": ["titiliumweb-regular"]
+      },
+      "paint": {
+        "text-color": "rgba(178, 178, 178, 1)"
+      }
+    },
+    {
+      "id": "road_bridge_area",
+      "type": "fill",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "Polygon"],
+        ["in", "brunnel", "bridge"]
+      ],
+      "layout": {},
+      "paint": {
+        "fill-color": "hsl(47, 26%, 88%)",
+        "fill-opacity": 0.5
+      }
+    },
+    {
+      "id": "road_path",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["in", "class", "path", "track"]
+      ],
+      "layout": {
+        "line-cap": "square",
+        "line-join": "bevel",
+        "visibility": "visible"
+      },
+      "paint": {
+        "line-color": "rgba(255, 255, 255, 1)",
+        "line-dasharray": [1, 1],
+        "line-width": {
+          "base": 1.55,
+          "stops": [
+            [4, 0.25],
+            [20, 10]
+          ]
+        }
+      }
+    },
+    {
+      "id": "road_minor",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["in", "class", "minor", "service"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round"
+      },
+      "paint": {
+        "line-color": "hsl(0, 0%, 97%)",
+        "line-width": {
+          "base": 1.55,
+          "stops": [
+            [4, 0.25],
+            [20, 30]
+          ]
+        }
+      }
+    },
+    {
+      "id": "tunnel_minor",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "tunnel"],
+        ["==", "class", "minor_road"]
+      ],
+      "layout": {
+        "line-cap": "butt",
+        "line-join": "miter"
+      },
+      "paint": {
+        "line-color": "rgba(255, 255, 255, 1)",
+        "line-width": {
+          "base": 1.55,
+          "stops": [
+            [4, 0.25],
+            [20, 30]
+          ]
+        },
+        "line-dasharray": [0.36, 0.18]
+      }
+    },
+    {
+      "id": "tunnel_major",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "tunnel"],
+        ["in", "class", "primary", "secondary", "tertiary", "trunk"]
+      ],
+      "layout": {
+        "line-cap": "butt",
+        "line-join": "miter"
+      },
+      "paint": {
+        "line-color": "rgba(255, 255, 255, 1)",
+        "line-width": {
+          "base": 1.4,
+          "stops": [
+            [6, 0.5],
+            [20, 30]
+          ]
+        },
+        "line-dasharray": [0.28, 0.14]
+      }
+    },
+    {
+      "id": "aeroway-area",
+      "type": "fill",
+      "metadata": {
+        "mapbox:group": "1444849345966.4436"
+      },
+      "source": "openmaptiles",
+      "source-layer": "aeroway",
+      "minzoom": 4,
+      "filter": [
+        "all",
+        ["==", "$type", "Polygon"],
+        ["in", "class", "runway", "taxiway"]
+      ],
+      "layout": {
+        "visibility": "visible"
+      },
+      "paint": {
+        "fill-opacity": {
+          "base": 1,
+          "stops": [
+            [13, 0],
+            [14, 1]
+          ]
+        },
+        "fill-color": "rgba(255, 255, 255, 1)"
+      }
+    },
+    {
+      "id": "aeroway-taxiway",
+      "type": "line",
+      "metadata": {
+        "mapbox:group": "1444849345966.4436"
+      },
+      "source": "openmaptiles",
+      "source-layer": "aeroway",
+      "minzoom": 12,
+      "filter": [
+        "all",
+        ["in", "class", "taxiway"],
+        ["==", "$type", "LineString"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round",
+        "visibility": "visible"
+      },
+      "paint": {
+        "line-color": "rgba(255, 255, 255, 1)",
+        "line-width": {
+          "base": 1.5,
+          "stops": [
+            [12, 1],
+            [17, 10]
+          ]
+        },
+        "line-opacity": 1
+      }
+    },
+    {
+      "id": "aeroway-runway",
+      "type": "line",
+      "metadata": {
+        "mapbox:group": "1444849345966.4436"
+      },
+      "source": "openmaptiles",
+      "source-layer": "aeroway",
+      "minzoom": 4,
+      "filter": [
+        "all",
+        ["in", "class", "runway"],
+        ["==", "$type", "LineString"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round",
+        "visibility": "visible"
+      },
+      "paint": {
+        "line-color": "rgba(255, 255, 255, 1)",
+        "line-width": {
+          "base": 1.5,
+          "stops": [
+            [11, 4],
+            [17, 50]
+          ]
+        },
+        "line-opacity": 1
+      }
+    },
+    {
+      "id": "road_trunk_primary",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["in", "class", "trunk", "primary"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round"
+      },
+      "paint": {
+        "line-color": "#fff",
+        "line-width": {
+          "base": 1.4,
+          "stops": [
+            [6, 0.5],
+            [20, 30]
+          ]
+        }
+      }
+    },
+    {
+      "id": "road_secondary_tertiary",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["in", "class", "secondary", "tertiary"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round",
+        "visibility": "visible"
+      },
+      "paint": {
+        "line-color": "#fff",
+        "line-width": {
+          "base": 1.4,
+          "stops": [
+            [6, 0.5],
+            [20, 20]
+          ]
+        }
+      }
+    },
+    {
+      "id": "road_major_motorway",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "class", "motorway"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round"
+      },
+      "paint": {
+        "line-color": "hsl(0, 0%, 100%)",
+        "line-width": {
+          "base": 1.4,
+          "stops": [
+            [8, 1],
+            [16, 10]
+          ]
+        },
+        "line-offset": 0
+      }
+    },
+    {
+      "id": "road_oneway",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "minzoom": 15,
+      "filter": ["all", ["==", "oneway", 1]],
+      "layout": {
+        "symbol-placement": "line",
+        "icon-image": "oneway",
+        "symbol-spacing": 200,
+        "icon-padding": 2,
+        "icon-rotation-alignment": "map",
+        "icon-rotate": 0,
+        "icon-size": {
+          "stops": [
+            [15, 0.5],
+            [19, 1]
+          ]
+        }
+      },
+      "paint": {
+        "icon-opacity": 0.5
+      }
+    },
+    {
+      "id": "road_oneway_opposite",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "minzoom": 15,
+      "filter": ["all", ["==", "oneway", -1]],
+      "layout": {
+        "symbol-placement": "line",
+        "icon-image": "oneway",
+        "symbol-spacing": 200,
+        "icon-padding": 2,
+        "icon-rotation-alignment": "map",
+        "icon-rotate": 180,
+        "icon-size": {
+          "stops": [
+            [15, 0.5],
+            [19, 1]
+          ]
+        }
+      },
+      "paint": {
+        "icon-opacity": 0.5
+      }
+    },
+    {
+      "id": "railway-transit",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "class", "transit"],
+        ["!=", "brunnel", "tunnel"]
+      ],
+      "layout": {
+        "visibility": "none"
+      },
+      "paint": {
+        "line-color": "hsl(34, 12%, 66%)",
+        "line-opacity": {
+          "base": 1,
+          "stops": [
+            [11, 0],
+            [16, 1]
+          ]
+        }
+      }
+    },
+    {
+      "id": "railway",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": ["==", "class", "rail"],
+      "layout": {
+        "visibility": "visible"
+      },
+      "paint": {
+        "line-color": "rgba(203, 203, 203, 1)",
+        "line-opacity": {
+          "base": 1,
+          "stops": [
+            [11, 0],
+            [16, 1]
+          ]
+        }
+      }
+    },
+    {
+      "id": "waterway-bridge-case",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "waterway",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "bridge"]
+      ],
+      "layout": {
+        "line-cap": "butt",
+        "line-join": "miter"
+      },
+      "paint": {
+        "line-color": "#bbbbbb",
+        "line-width": {
+          "base": 1.6,
+          "stops": [
+            [12, 0.5],
+            [20, 10]
+          ]
+        },
+        "line-gap-width": {
+          "base": 1.55,
+          "stops": [
+            [4, 0.25],
+            [20, 30]
+          ]
+        }
+      }
+    },
+    {
+      "id": "waterway-bridge",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "waterway",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "bridge"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round"
+      },
+      "paint": {
+        "line-color": "hsl(205, 56%, 73%)",
+        "line-width": {
+          "base": 1.55,
+          "stops": [
+            [4, 0.25],
+            [20, 30]
+          ]
+        }
+      }
+    },
+    {
+      "id": "bridge_minor case",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "bridge"],
+        ["==", "class", "minor_road"]
+      ],
+      "layout": {
+        "line-cap": "butt",
+        "line-join": "miter"
+      },
+      "paint": {
+        "line-color": "#dedede",
+        "line-width": {
+          "base": 1.6,
+          "stops": [
+            [12, 0.5],
+            [20, 10]
+          ]
+        },
+        "line-gap-width": {
+          "base": 1.55,
+          "stops": [
+            [4, 0.25],
+            [20, 30]
+          ]
+        }
+      }
+    },
+    {
+      "id": "bridge_major case",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "bridge"],
+        ["in", "class", "primary", "secondary", "tertiary", "trunk"]
+      ],
+      "layout": {
+        "line-cap": "butt",
+        "line-join": "miter"
+      },
+      "paint": {
+        "line-color": "#dedede",
+        "line-width": {
+          "base": 1.6,
+          "stops": [
+            [12, 0.5],
+            [20, 10]
+          ]
+        },
+        "line-gap-width": {
+          "base": 1.55,
+          "stops": [
+            [4, 0.25],
+            [20, 30]
+          ]
+        }
+      }
+    },
+    {
+      "id": "bridge_minor",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "bridge"],
+        ["==", "class", "minor_road"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round"
+      },
+      "paint": {
+        "line-color": "#efefef",
+        "line-width": {
+          "base": 1.55,
+          "stops": [
+            [4, 0.25],
+            [20, 30]
+          ]
+        }
+      }
+    },
+    {
+      "id": "bridge_major",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "transportation",
+      "filter": [
+        "all",
+        ["==", "$type", "LineString"],
+        ["==", "brunnel", "bridge"],
+        ["in", "class", "primary", "secondary", "tertiary", "trunk"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round"
+      },
+      "paint": {
+        "line-color": "#fff",
+        "line-width": {
+          "base": 1.4,
+          "stops": [
+            [6, 0.5],
+            [20, 30]
+          ]
+        }
+      }
+    },
+    {
+      "id": "admin_sub",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "boundary",
+      "filter": ["in", "admin_level", 4, 6, 8],
+      "layout": {
+        "visibility": "none"
+      },
+      "paint": {
+        "line-color": "hsla(0, 0%, 60%, 0.5)",
+        "line-dasharray": [2, 1]
+      }
+    },
+    {
+      "id": "admin_country",
+      "type": "line",
+      "source": "openmaptiles",
+      "source-layer": "boundary",
+      "filter": [
+        "all",
+        ["<=", "admin_level", 2],
+        ["==", "$type", "LineString"]
+      ],
+      "layout": {
+        "line-cap": "round",
+        "line-join": "round"
+      },
+      "paint": {
+        "line-color": "hsl(0, 0%, 60%)",
+        "line-width": {
+          "base": 1.3,
+          "stops": [
+            [3, 0.5],
+            [22, 15]
+          ]
+        }
+      }
+    },
+    {
+      "id": "poi_label",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "poi",
+      "minzoom": 14,
+      "filter": ["all", ["==", "$type", "Point"], ["==", "rank", 1]],
+      "layout": {
+        "text-size": 11,
+        "text-font": ["titiliumweb-regular"],
+        "visibility": "visible",
+        "text-offset": [0, 0.5],
+        "icon-size": 1,
+        "text-anchor": "top",
+        "text-field": "{name:latin}\n{name:nonlatin}",
+        "text-max-width": 8
+      },
+      "paint": {
+        "text-color": "#818080",
+        "text-halo-width": 1,
+        "text-halo-color": "rgba(255,255,255,0.75)",
+        "text-halo-blur": 1
+      }
+    },
+    {
+      "id": "airport-label",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "aerodrome_label",
+      "minzoom": 10,
+      "filter": ["all", ["has", "iata"]],
+      "layout": {
+        "text-size": 11,
+        "text-font": ["titiliumweb-regular"],
+        "visibility": "visible",
+        "text-offset": [0, 0.5],
+        "icon-size": 1,
+        "text-anchor": "top",
+        "text-field": "{name:latin}\n{name:nonlatin}",
+        "text-max-width": 8
+      },
+      "paint": {
+        "text-color": "#666",
+        "text-halo-width": 1,
+        "text-halo-color": "rgba(255,255,255,0.75)",
+        "text-halo-blur": 1
+      }
+    },
+    {
+      "id": "road_major_label",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "transportation_name",
+      "filter": ["==", "$type", "LineString"],
+      "layout": {
+        "symbol-placement": "line",
+        "text-field": "{name:latin} {name:nonlatin}",
+        "text-font": ["titiliumweb-regular"],
+        "text-transform": "uppercase",
+        "text-letter-spacing": 0.1,
+        "text-size": {
+          "base": 1.4,
+          "stops": [
+            [10, 8],
+            [20, 14]
+          ]
+        },
+        "text-rotation-alignment": "map"
+      },
+      "paint": {
+        "text-color": "#333744",
+        "text-halo-color": "hsl(0, 0%, 100%)",
+        "text-halo-width": 2
+      }
+    },
+    {
+      "id": "place_label_other",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "place",
+      "minzoom": 8,
+      "filter": [
+        "all",
+        ["==", "$type", "Point"],
+        ["!in", "class", "city", "state", "country", "continent"]
+      ],
+      "layout": {
+        "text-field": "{name:latin}\n{name:nonlatin}",
+        "text-font": ["titiliumweb-regular"],
+        "text-max-width": 6,
+        "text-size": {
+          "stops": [
+            [6, 10],
+            [12, 14]
+          ]
+        },
+        "visibility": "visible",
+        "text-anchor": "center"
+      },
+      "paint": {
+        "text-color": "rgba(129, 128, 128, 1)",
+        "text-halo-color": "hsl(0, 0%, 100%)",
+        "text-halo-blur": 0,
+        "text-halo-width": 2
+      }
+    },
+    {
+      "id": "place_label_city",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "place",
+      "maxzoom": 16,
+      "filter": ["all", ["==", "$type", "Point"], ["==", "class", "city"]],
+      "layout": {
+        "text-field": "{name:latin}\n{name:nonlatin}",
+        "text-font": ["titiliumweb-regular"],
+        "text-max-width": 10,
+        "text-size": {
+          "stops": [
+            [3, 14],
+            [8, 16]
+          ]
+        },
+        "text-justify": "center"
+      },
+      "paint": {
+        "text-color": "rgba(51, 55, 68, 1)",
+        "text-halo-color": "hsla(0, 0%, 100%, 0.75)",
+        "text-halo-blur": 0,
+        "text-halo-width": 2
+      }
+    },
+    {
+      "id": "country_label-other",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "place",
+      "maxzoom": 12,
+      "filter": [
+        "all",
+        ["==", "$type", "Point"],
+        ["==", "class", "country"],
+        ["!has", "iso_a2"]
+      ],
+      "layout": {
+        "text-field": "{name:latin}",
+        "text-font": ["titiliumweb-regular"],
+        "text-max-width": 10,
+        "text-size": {
+          "stops": [
+            [3, 12],
+            [8, 22]
+          ]
+        },
+        "visibility": "visible"
+      },
+      "paint": {
+        "text-color": "hsl(0, 0%, 13%)",
+        "text-halo-color": "rgba(255,255,255,0.75)",
+        "text-halo-width": 2,
+        "text-halo-blur": 0
+      }
+    },
+    {
+      "id": "country_label",
+      "type": "symbol",
+      "source": "openmaptiles",
+      "source-layer": "place",
+      "maxzoom": 12,
+      "filter": [
+        "all",
+        ["==", "$type", "Point"],
+        ["==", "class", "country"],
+        ["has", "iso_a2"]
+      ],
+      "layout": {
+        "text-field": "{name:latin}",
+        "text-font": ["titiliumweb-regular"],
+        "text-max-width": 10,
+        "text-size": {
+          "stops": [
+            [3, 12],
+            [8, 22]
+          ]
+        },
+        "visibility": "visible"
+      },
+      "paint": {
+        "text-color": "hsl(0, 0%, 13%)",
+        "text-halo-color": "rgba(255,255,255,0.75)",
+        "text-halo-width": 2,
+        "text-halo-blur": 0
+      }
+    }
+  ],
+  "id": "klokantech-basic",
+  "owner": ""
+}
diff --git a/web/components/visualization/results-map.js b/web/components/visualization/results-map.js
new file mode 100644
index 0000000000000000000000000000000000000000..87c847bab48f11093e457e79ed60c087000641a6
--- /dev/null
+++ b/web/components/visualization/results-map.js
@@ -0,0 +1,87 @@
+// Imports
+import * as PartyModel from "/services/model/party-model.js";
+import * as AreaModel from "/services/model/area-model.js";
+
+export async function mount(parent) {
+  const mapComponent = new MapComponent(parent);
+  return mapComponent;
+}
+
+class MapComponent {
+  constructor(parent) {
+    this.parent = parent;
+    this.PartyModel = PartyModel.getPartyModel();
+    this.AreaModel = AreaModel.getAreaModel();
+  }
+
+  async displayMapAreas() {
+    console.log("mount area map")
+    await this.initMap("/assets/maps/area.json", this.colorAreas);
+  }
+
+  async displayMapSections() {
+    console.log("mount section map")
+    await this.initMap("/assets/maps/section.json", this.colorSections);
+  }
+
+  async initMap(mapFile, colorationFunction) {
+    // Create datasource
+    const request = new XMLHttpRequest();
+    request.open("GET", mapFile, false);
+    request.send(null);
+    let dataSource = JSON.parse(request.responseText);
+
+      // Add parties and colors to datasource
+      dataSource = await colorationFunction(dataSource);
+
+    document.getElementById("map-component").innerHTML = "";
+    // Create a popup, but don't add it to the map yet.
+    let popup = new mapboxgl.Popup({
+      closeButton: false,
+    });
+
+    const map = new mapboxgl.Map({
+      container: "map-component", // container id
+      style: "/assets/mapbox/vector.json", // stylesheet location
+      center: [4.9, 45.75], // starting position [lng, lat]
+      zoom: 9.7, // starting zoom
+    });
+
+    // map.on("load", function () {
+    //   map.addSource("data-source", {
+    //     type: "geojson",
+    //     data: dataSource,
+    //   });
+
+    //   map.addLayer(
+    //     {
+    //       id: "winners-fills",
+    //       type: "fill",
+    //       source: "data-source",
+    //       layout: {},
+    //       paint: {
+    //         "fill-color": { type: "identity", property: "color" },
+    //         "fill-opacity": 0.5,
+    //         "fill-outline-color": "black",
+    //       },
+    //     },
+    //     "place_label_city"
+    //   );
+
+    //   map.addLayer({
+    //     id: "winners-names",
+    //     type: "symbol",
+    //     source: "data-source",
+    //     filter: ["all"],
+    //     layout: {
+    //       "text-field": "{partyName}",
+    //       "text-font": ["titiliumweb-regular"],
+    //     },
+    //   });
+    // });
+  }
+
+  async colorAreas(dataSource) {}
+
+  async colorSections(dataSource) {}
+}
diff --git a/web/components/visualization/results-zone.js b/web/components/visualization/results-zone.js
index 022bd02f36221f9d6cb6789c48a96c1abd60bb63..05be9f432691ce8b4760ea12ff060ec5713b3f62 100644
--- a/web/components/visualization/results-zone.js
+++ b/web/components/visualization/results-zone.js
@@ -6,6 +6,7 @@ import * as AreaModel from "/services/model/area-model.js";
 import * as Scroller from "/services/common/scroller.js";
 import * as ResultsFlow from "/components/visualization/results-flow.js";
 import * as ResultsDetaileds from "/components/visualization/results-detaileds.js";
+import * as ResultsMap from "/components/visualization/results-map.js";
 
 export async function mount(where, parent) {
   const resultZoneComponent = new ResultZoneComponent(parent);
@@ -91,6 +92,7 @@ class ResultZoneComponent {
     `;
     this.ResultsFlow = await ResultsFlow.mount(this);
     this.ResultsDetaileds = await ResultsDetaileds.mount(this);
+    this.ResultsMap = await ResultsMap.mount(this);
     this.scroller = Scroller.scrollInit(
       "news-flow",
       document.getElementById("auto-scroll")
@@ -136,6 +138,9 @@ class ResultZoneComponent {
     let resultHandler = this;
     document.getElementById("map-section").parentElement.className =
       "column is-full";
+    console.log(this.ResultsMap);
+    if (this.parent.zone === "areas") this.ResultsMap.displayMapAreas();
+    else this.ResultsMap.displayMapSections();
     document.getElementById("zoom-map").addEventListener("click", function () {
       resultHandler.unZoom();
     });
@@ -215,6 +220,9 @@ class ResultZoneComponent {
       <i class="fa fa-expand-arrows-alt"></i>
     </span>`;
 
+    if (this.parent.zone === "areas") this.ResultsMap.displayMapAreas();
+    else this.ResultsMap.displayMapSections();
+
     this.handleDom();
   }
 
diff --git a/web/components/visualization/visualization-section.js b/web/components/visualization/visualization-section.js
index 0c3d7fa6c07c9489b32832ee82685886081d7ee4..a58d6db7dce717739dc3f32d397299842e1d6640 100644
--- a/web/components/visualization/visualization-section.js
+++ b/web/components/visualization/visualization-section.js
@@ -104,12 +104,14 @@ class ResultComponent {
       await this.hideGeneralSection();
       document.getElementById("sections").setAttribute("class", "");
       document.getElementById("areas").setAttribute("class", "is-active");
+      this.resultsZone.ResultsMap.displayMapAreas();
     });
     document.getElementById("sections").addEventListener("click", async () => {
       resultHandler.zone = "sections";
       await this.hideGeneralSection();
       document.getElementById("areas").setAttribute("class", "");
       document.getElementById("sections").setAttribute("class", "is-active");
+      this.resultsZone.ResultsMap.displayMapSections();
     });
 
     let radioButtons = document.getElementsByName("filter");
diff --git a/web/index.html b/web/index.html
index 526f42ee3e88b1ab523602b60f30448fa546cbac..eddde1d663bf645c1ccbada17df42fd8430369a4 100644
--- a/web/index.html
+++ b/web/index.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+
 <html lang="en" class="has-navbar-fixed-top">
   <head>
     <title>Elections</title>
@@ -9,6 +10,11 @@
     <link rel="stylesheet" href="assets/bulma.min.css" />
     <link rel="stylesheet" href="assets/animate.css" />
     <link rel="stylesheet" href="style.css" />
+    <script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
+    <link
+      rel="stylesheet"
+      href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css"
+    />
     <script defer src="assets/fontawesome/brands.min.js"></script>
     <script defer src="assets/fontawesome/solid.min.js"></script>
     <script defer src="assets/fontawesome/fontawesome.min.js"></script>
@@ -16,7 +22,12 @@
   </head>
   <body>
     <!-- Navbar -->
-    <nav id="navbar" class="navbar is-dark is-fixed-top" role="navigation" aria-label="main navigation"></nav>
+    <nav
+      id="navbar"
+      class="navbar is-dark is-fixed-top"
+      role="navigation"
+      aria-label="main navigation"
+    ></nav>
 
     <!-- Main content-->
     <section class="section" id="main" style="margin-bottom: 230px;"></section>
@@ -29,7 +40,12 @@
       <div class="navbar-brand">
         <div class="navbar-item">
           <div class="buttons">
-            <a class="button is-danger" href="https://forge.grandlyon.com/gestion-des-assemblees/elections" target="_blank" rel="noopener noreferrer">
+            <a
+              class="button is-danger"
+              href="https://forge.grandlyon.com/gestion-des-assemblees/elections"
+              target="_blank"
+              rel="noopener noreferrer"
+            >
               <span class="icon">
                 <svg
                   class="svg-inline--fa fa-gitlab fa-w-16"
@@ -45,8 +61,8 @@
                   <path
                     fill="currentColor"
                     d="M105.2 24.9c-3.1-8.9-15.7-8.9-18.9 0L29.8 199.7h132c-.1 0-56.6-174.8-56.6-174.8zM.9 287.7c-2.6 8 .3 16.9 7.1 22l247.9 184-226.2-294zm160.8-88l94.3 294 94.3-294zm349.4 88l-28.8-88-226.3 294 247.9-184c6.9-5.1 9.7-14 7.2-22zM425.7 24.9c-3.1-8.9-15.7-8.9-18.9 0l-56.6 174.8h132z"
-                  ></path></svg
-                >
+                  ></path>
+                </svg>
               </span>
             </a>
           </div>
diff --git a/web/style.css b/web/style.css
index 2a8b9048b43479c80e73b58e3835b2177869c862..449b49759f67645f193e595441a1729b5e8fed26 100644
--- a/web/style.css
+++ b/web/style.css
@@ -211,4 +211,12 @@ select {
 
 .clickable {
   cursor: pointer;
-}
\ No newline at end of file
+}
+
+#map-section {
+  height: 70vh;
+}
+
+#map-component {
+  height: 100%;
+}