diff --git a/site/src/components/core/Footer.astro b/site/src/components/core/Footer.astro
new file mode 100644
index 0000000..f8d9269
--- /dev/null
+++ b/site/src/components/core/Footer.astro
@@ -0,0 +1,83 @@
+---
+import { useDict, interpolate } from '@i18n/t';
+import type { Locale } from '@i18n/locales';
+import { pathFor, type PageId } from '@i18n/slugMap';
+import { getProfile } from '@lib/content';
+import LangSwitch from '@components/ui/LangSwitch.astro';
+
+interface Props {
+ locale: Locale;
+ pageId: PageId;
+}
+const { locale, pageId } = Astro.props;
+const d = useDict(locale);
+const p = getProfile(locale);
+const year = new Date().getFullYear();
+
+const nav: { id: PageId; label: string }[] = [
+ { id: 'projects', label: d.nav.projects },
+ { id: 'experience', label: d.nav.experience },
+ { id: 'about', label: d.nav.about },
+ { id: 'contact', label: d.nav.contact },
+];
+---
+
+
diff --git a/site/src/components/core/Header.astro b/site/src/components/core/Header.astro
new file mode 100644
index 0000000..e224a8f
--- /dev/null
+++ b/site/src/components/core/Header.astro
@@ -0,0 +1,119 @@
+---
+import { useDict } from '@i18n/t';
+import type { Locale } from '@i18n/locales';
+import { pathFor, type PageId, PROJECT_PAGE_IDS } from '@i18n/slugMap';
+import LangSwitch from '@components/ui/LangSwitch.astro';
+import ThemeToggle from '@components/ui/ThemeToggle.astro';
+import SplitCvButton from '@components/ui/SplitCvButton.astro';
+import MobileNav from '@components/core/MobileNav.astro';
+
+interface Props {
+ locale: Locale;
+ pageId: PageId;
+}
+const { locale, pageId } = Astro.props;
+const d = useDict(locale);
+
+const navItems: { id: PageId; label: string }[] = [
+ { id: 'projects', label: d.nav.projects },
+ { id: 'experience', label: d.nav.experience },
+ { id: 'about', label: d.nav.about },
+ { id: 'contact', label: d.nav.contact },
+];
+const isCurrent = (id: PageId) =>
+ id === pageId ||
+ (id === 'projects' && (PROJECT_PAGE_IDS as readonly string[]).includes(pageId));
+---
+
+
+ Languages +
+{profile.contactBody}
+ ++ {d.home.earlierRoles} +
+ )} + + {item.emphasis === 'featured' ? ( +{item.summary}
} + {item.highlights && ( ++ {period(item.period.from, item.period.to)} + · + {item.role} + · + {item.employer} +
++ {profile.eyebrow} +
+{profile.heroTagline}
+{profile.heroSummary}
+ +{p.cardTeaser}
++ {d.project.readCaseStudy} + → +
+{p.cardTeaser}
+{tile.stat}
++ {tile.label} +
+{d.home.skillsIntro}
+ ++ {num[i]} — {group.title} +
+{group.context}
+