Skip to content
Merged
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
File renamed without changes.
File renamed without changes.
Binary file added favicon/android-chrome-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added favicon/android-chrome-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added favicon/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added favicon/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added favicon/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added favicon/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions favicon/site.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
55 changes: 54 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,2 +1,55 @@
<!DOCTYPE html>
<meta http-equiv="refresh" content="0;url=maps/index.html">
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Municipality Email Maps</title>
<link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
<link rel="manifest" href="favicon/site.webmanifest">
<link rel="stylesheet" href="css/shared.css">
<style>
body { background: #f0f1f5; min-height: 100vh; }
.landing { max-width: 720px; margin: 0 auto; padding: 40px 20px; }
.landing h2 { font-size: 22px; font-weight: 700; color: #1a1a2e; margin-bottom: 8px; }
.landing p { font-size: 14px; color: #555; line-height: 1.6; margin-bottom: 24px; }
.map-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; }
.map-card {
display: block; background: #fff; border-radius: 8px; padding: 24px;
text-decoration: none; color: #1a1a2e; border: 1px solid #d8dae0;
box-shadow: 0 1px 3px rgba(0,0,0,0.06); transition: box-shadow 0.15s;
}
.map-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.12); }
.map-card h3 { font-size: 17px; font-weight: 600; margin-bottom: 8px; }
.map-card p { font-size: 13px; color: #555; line-height: 1.5; margin: 0; }
.landing-footer { margin-top: 32px; font-size: 12px; color: #999; }
.landing-footer a { color: #2563eb; text-decoration: none; }
.landing-footer a:hover { text-decoration: underline; }
</style>
</head>
<body>
<header id="header">
<div class="header-left">
<h1 class="brand">Municipality Emails</h1>
</div>
</header>
<div class="landing">
<h2>Municipality Email Maps</h2>
<p>Interactive maps showing email infrastructure of ~15,300 municipalities in Germany, Austria, and Switzerland, based on public DNS records and network signals.</p>
<div class="map-list">
<a href="providers.html" class="map-card">
<h3>Email Providers</h3>
<p>Which provider handles each municipality's official email? Classified by jurisdiction: US cloud (Microsoft, Google, AWS), domestic, or foreign.</p>
</a>
<a href="security.html" class="map-card">
<h3>Email Security</h3>
<p>How well are municipality email domains protected against spoofing? Based on SPF and DMARC configuration.</p>
</a>
</div>
<div class="landing-footer">
<p>Open source &amp; open data on <a href="https://github.com/davidhuser/paper-municipality-emails" target="_blank">GitHub</a>.</p>
</div>
</div>
</body>
</html>
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
52 changes: 0 additions & 52 deletions maps/index.html

This file was deleted.

11 changes: 7 additions & 4 deletions maps/providers.html → providers.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
<link rel="preconnect" href="https://d.basemaps.cartocdn.com" crossorigin>
<title>Email Providers of DACH Municipalities</title>
<meta name="description" content="Interactive map showing the email providers of ~15,300 municipalities in Germany, Austria, and Switzerland, based on DNS analysis.">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='2' y='7' width='28' height='18' rx='2' fill='%231a1a2e'/%3E%3Cpath d='M2 9l14 9 14-9' fill='none' stroke='%2316a34a' stroke-width='2'/%3E%3C/svg%3E">
<link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
<link rel="manifest" href="favicon/site.webmanifest">
<link rel="stylesheet" href="css/shared.css">
<link rel="stylesheet" href="css/map.css">
<link rel="preload" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
Expand Down Expand Up @@ -71,7 +74,7 @@ <h3>Open source &amp; open data</h3>
{
label: 'Germany',
topoUrl: 'topo/de-gemeinden.json',
dataUrl: '../output/providers/providers_de.min.json',
dataUrl: 'output/providers/providers_de.min.json',
topoObject: 'VG250_GEM',
featureCodeFn: function(f) { return String(f.id); },
domesticCategory: 'de-based',
Expand All @@ -89,7 +92,7 @@ <h3>Open source &amp; open data</h3>
{
label: 'Austria',
topoUrl: 'topo/at-gemeinden.json',
dataUrl: '../output/providers/providers_at.min.json',
dataUrl: 'output/providers/providers_at.min.json',
topoObject: 'gemeinden',
featureCodeFn: function(f) {
var iso = String(f.id || (f.properties && f.properties.iso) || '');
Expand All @@ -108,7 +111,7 @@ <h3>Open source &amp; open data</h3>
{
label: 'Switzerland',
topoUrl: 'https://unpkg.com/swiss-maps@4.7.0/2026/ch-combined.json',
dataUrl: '../output/providers/providers_ch.min.json',
dataUrl: 'output/providers/providers_ch.min.json',
topoObject: 'municipalities',
featureCodeFn: function(f) { return String(f.id); },
domesticCategory: 'ch-based',
Expand Down
11 changes: 7 additions & 4 deletions maps/security.html → security.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
<link rel="preconnect" href="https://d.basemaps.cartocdn.com" crossorigin>
<title>Email Security of DACH Municipalities</title>
<meta name="description" content="Interactive map showing email security (SPF, DMARC) of ~15,300 municipalities in Germany, Austria, and Switzerland.">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='2' y='7' width='28' height='18' rx='2' fill='%231a1a2e'/%3E%3Cpath d='M2 9l14 9 14-9' fill='none' stroke='%2316a34a' stroke-width='2'/%3E%3C/svg%3E">
<link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
<link rel="manifest" href="favicon/site.webmanifest">
<link rel="stylesheet" href="css/shared.css">
<link rel="stylesheet" href="css/map.css">
<link rel="preload" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
Expand Down Expand Up @@ -71,7 +74,7 @@ <h3>Open source &amp; open data</h3>
{
label: 'Germany',
topoUrl: 'topo/de-gemeinden.json',
dataUrl: '../output/security/security_de.json',
dataUrl: 'output/security/security_de.json',
topoObject: 'VG250_GEM',
featureCodeFn: function(f) { return String(f.id); },
REGION_CODES: {
Expand All @@ -86,7 +89,7 @@ <h3>Open source &amp; open data</h3>
{
label: 'Austria',
topoUrl: 'topo/at-gemeinden.json',
dataUrl: '../output/security/security_at.json',
dataUrl: 'output/security/security_at.json',
topoObject: 'gemeinden',
featureCodeFn: function(f) {
var iso = String(f.id || (f.properties && f.properties.iso) || '');
Expand All @@ -102,7 +105,7 @@ <h3>Open source &amp; open data</h3>
{
label: 'Switzerland',
topoUrl: 'https://unpkg.com/swiss-maps@4.7.0/2026/ch-combined.json',
dataUrl: '../output/security/security_ch.json',
dataUrl: 'output/security/security_ch.json',
topoObject: 'municipalities',
featureCodeFn: function(f) { return String(f.id); },
REGION_CODES: {
Expand Down
File renamed without changes.
File renamed without changes.