diff --git a/AGENTS.md b/AGENTS.md
index 599e1d2..7058917 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1148,6 +1148,14 @@ session with **no other memory of this project**. So:
say this honestly (2026-09-29). **Still future:** real MLS
(`ts-mls`) instead of group-key crypto, plus Cordn RPC interop. **Lesson: grep
`src` for the feature before building it — this was nearly duplicated.**
+- **Map site-links strip (2026-10-05):** the desktop footer is hidden on the map
+ (full-bleed), so `components/MapFooterStrip.tsx` surfaces the same links
+ (Newsletter/License/Privacy/Collaborators + "not sponsored by OpenSats") as an
+ overlay inside the map container: a **slim full-width bar on desktop** and a
+ **tiny collapsed "Links" chip on mobile** (expands to a compact scrollable row).
+ Dismissible via `useMapFooterHidden` (`skatespots:map-footer-hidden`, same-tab
+ synced), restorable in **Settings → Appearance**. The map's OpenStreetMap
+ attribution moved to `md:bottom-7` so the bar doesn't cover it.
- **Map layout — controls float (2026-09-29):** on mobile the `MapPage` toolbar
is **`absolute` over the map** (`pointer-events-none` wrapper + gradient +
`pointer-events-auto` inner) so the map fills the whole container; `md:static`
diff --git a/src/components/MapFooterStrip.tsx b/src/components/MapFooterStrip.tsx
new file mode 100644
index 0000000..84a7ba5
--- /dev/null
+++ b/src/components/MapFooterStrip.tsx
@@ -0,0 +1,86 @@
+import { useState } from 'react';
+import { Link } from 'react-router-dom';
+import { ChevronUp, X } from 'lucide-react';
+import { useTranslation } from '@/contexts/language';
+import { useMapFooterHidden } from '@/hooks/useMapFooterHidden';
+import { cn } from '@/lib/utils';
+
+/**
+ * The site links that live in the desktop footer — surfaced on the map
+ * (a full-bleed route where the footer is hidden) without stealing map height.
+ *
+ * Desktop: a slim full-width bar. Mobile: a tiny collapsed "Links" chip that
+ * expands to a compact row. Dismissible, and restorable from Settings →
+ * Appearance.
+ */
+export function MapFooterStrip() {
+ const { t } = useTranslation();
+ const [hidden, setHidden] = useMapFooterHidden();
+ const [open, setOpen] = useState(false);
+
+ if (hidden) return null;
+
+ const links = [
+ { to: '/newsletter', label: t('nav.newsletter') },
+ { to: '/license', label: t('chromeUi.license') },
+ { to: '/privacy', label: t('chromeUi.privacy') },
+ { to: '/supporters', label: t('chromeUi.collaborators') },
+ ];
+
+ return (
+
+ {/* Slim, dismissible site-links strip — the desktop footer is hidden
+ on this full-bleed route, so surface the links here instead. */}
+
+
{/* Location permission help dialog */}
{showLocationHelp && (
diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx
index 24cc7b9..2897be2 100644
--- a/src/pages/SettingsPage.tsx
+++ b/src/pages/SettingsPage.tsx
@@ -3,6 +3,7 @@ import { Link, useSearchParams } from 'react-router-dom';
import { EditProfileForm } from '@/components/EditProfileForm';
import { Switch } from '@/components/ui/switch';
import { useSasquatchHidden } from '@/hooks/useSasquatchHidden';
+import { useMapFooterHidden } from '@/hooks/useMapFooterHidden';
import { SkaterDirectoryCard } from '@/components/SkaterDirectoryCard';
import { ProfilePreviewCard } from '@/components/ProfilePreviewCard';
import { RelayListManager } from '@/components/RelayListManager';
@@ -614,6 +615,7 @@ function RelaysScreen({ onBack }: { onBack: () => void }) {
function AppearanceScreen({ onBack }: { onBack: () => void }) {
const { t } = useTranslation();
const [sasquatchHidden, setSasquatchHidden] = useSasquatchHidden();
+ const [mapFooterHidden, setMapFooterHidden] = useMapFooterHidden();
return (