From 87f1880083bac8b2e9c0cb1849ea268ea047a55a Mon Sep 17 00:00:00 2001
From: Gigi
Date: Thu, 25 Dec 2025 16:12:26 +0100
Subject: [PATCH 01/28] chore(assets): move world map svg to public/maps
---
public/maps/world.svg | 1037 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 1037 insertions(+)
create mode 100644 public/maps/world.svg
diff --git a/public/maps/world.svg b/public/maps/world.svg
new file mode 100644
index 000000000..612386fcf
--- /dev/null
+++ b/public/maps/world.svg
@@ -0,0 +1,1037 @@
+
+
+
From 5e3ae2c826900841ce2828a6bd7ff74976735627 Mon Sep 17 00:00:00 2001
From: Gigi
Date: Thu, 25 Dec 2025 16:12:36 +0100
Subject: [PATCH 02/28] feat(map): add /map page rendering inline world svg
---
pages/map.tsx | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 pages/map.tsx
diff --git a/pages/map.tsx b/pages/map.tsx
new file mode 100644
index 000000000..02ee79b55
--- /dev/null
+++ b/pages/map.tsx
@@ -0,0 +1,70 @@
+import fs from 'fs'
+import path from 'path'
+import { InferGetStaticPropsType } from 'next'
+import { PageSEO } from '@/components/SEO'
+
+export const getStaticProps = async () => {
+ const svgPath = path.join(process.cwd(), 'public', 'maps', 'world.svg')
+ let svg = fs.readFileSync(svgPath, 'utf8')
+
+ // Strip XML declaration - it doesn't belong in HTML
+ svg = svg.replace(/<\?xml[\s\S]*?\?>\s*/i, '').trim()
+
+ return { props: { svg } }
+}
+
+export default function MapPage({
+ svg,
+}: InferGetStaticPropsType) {
+ return (
+ <>
+
+
+
+
+
+ Grant map
+
+
+ Countries highlighted in orange have received OpenSats grants.
+
+
+
+
+
+
+
+ >
+ )
+}
+
From 136c94fb79f87b10924521594ed7ba8c22022c72 Mon Sep 17 00:00:00 2001
From: Gigi
Date: Thu, 25 Dec 2025 16:13:00 +0100
Subject: [PATCH 03/28] feat(map): highlight grantee countries in OpenSats
orange
---
pages/map.tsx | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/pages/map.tsx b/pages/map.tsx
index 02ee79b55..83e94864a 100644
--- a/pages/map.tsx
+++ b/pages/map.tsx
@@ -3,6 +3,53 @@ import path from 'path'
import { InferGetStaticPropsType } from 'next'
import { PageSEO } from '@/components/SEO'
+const OPENSATS_ORANGE = '#f97316' // tailwind orange-500
+
+// ISO 3166-1 alpha-2 codes that match the SVG's path ids (id="US", id="DE", ...)
+const GRANTEE_COUNTRY_CODES: string[] = [
+ 'US', // USA
+ 'CA', // Canada
+ 'DE', // Germany
+ 'GB', // United Kingdom
+ 'IT', // Italy
+ 'JP', // Japan
+ 'NL', // Netherlands
+ 'CH', // Switzerland
+ 'CN', // China
+ 'BR', // Brazil
+ 'AR', // Argentina
+ 'IE', // Ireland
+ 'HK', // Hong Kong
+ 'GE', // Georgia
+ 'SE', // Sweden
+ 'ES', // Spain
+ 'PT', // Portugal
+ 'NO', // Norway
+ 'GR', // Greece
+ 'AU', // Australia
+ 'IN', // India
+ 'SI', // Slovenia
+ 'KR', // Republic of Korea
+ 'FI', // Finland
+ 'CZ', // Czech Republic
+ 'UG', // Uganda
+ 'BE', // Belgium
+ 'FR', // France
+ 'VN', // Vietnam
+ 'UA', // Ukraine
+ 'TR', // Turkey
+ 'SV', // El Salvador
+ 'NZ', // New Zealand
+ 'HU', // Hungary
+ 'SK', // Slovakia
+ 'NG', // Nigeria
+ 'PA', // Panama
+ 'RO', // Romania
+ 'GT', // Guatemala
+ 'ID', // Indonesia
+ 'AE', // UAE
+]
+
export const getStaticProps = async () => {
const svgPath = path.join(process.cwd(), 'public', 'maps', 'world.svg')
let svg = fs.readFileSync(svgPath, 'utf8')
@@ -16,6 +63,19 @@ export const getStaticProps = async () => {
export default function MapPage({
svg,
}: InferGetStaticPropsType) {
+ // Generate CSS selector for highlighted countries (DRY: one selector string)
+ const highlightSelector = GRANTEE_COUNTRY_CODES.length
+ ? GRANTEE_COUNTRY_CODES.map((c) => `.grant-map svg #${c}`).join(', ')
+ : ''
+
+ const highlightCss = highlightSelector
+ ? `
+ ${highlightSelector} {
+ fill: ${OPENSATS_ORANGE} !important;
+ }
+ `
+ : ''
+
return (
<>
>
)
From c5088f1442b3be05938b48f4656c76507bedb7f6 Mon Sep 17 00:00:00 2001
From: Gigi
Date: Thu, 25 Dec 2025 16:13:12 +0100
Subject: [PATCH 04/28] chore(map): polish a11y and responsiveness
---
pages/map.tsx | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/pages/map.tsx b/pages/map.tsx
index 83e94864a..dfeaa6bf9 100644
--- a/pages/map.tsx
+++ b/pages/map.tsx
@@ -93,7 +93,7 @@ export default function MapPage({
-