diff --git a/lib/exporter/html.ts b/lib/exporter/html.ts
index 24c33e8..cfd0265 100644
--- a/lib/exporter/html.ts
+++ b/lib/exporter/html.ts
@@ -124,7 +124,7 @@ function renderHero(section: { props: { heading: string; subheading?: string; im
${subheading.length > 0 ? `
${escapeHtml(subheading)}
` : ''}
@@ -256,6 +256,7 @@ function buildHead(page: Page) {
+
${escapeHtml(page.seo.title)}
diff --git a/lib/exporter/seoPerf.themeColor.heroDims.test.ts b/lib/exporter/seoPerf.themeColor.heroDims.test.ts
new file mode 100644
index 0000000..3d730cf
--- /dev/null
+++ b/lib/exporter/seoPerf.themeColor.heroDims.test.ts
@@ -0,0 +1,31 @@
+import { describe, it, expect } from 'vitest'
+import { exportPage } from '@/lib/exporter/html'
+import { pageSchema, type Page } from '@/lib/schema/page'
+
+function makePage(): Page {
+ return pageSchema.parse({
+ title: 'SEO/Perf 2',
+ locale: 'en',
+ theme: { primaryColor: '#0ea5e9', fontFamily: 'Inter' },
+ sections: [
+ { type: 'hero', props: { heading: 'Hello', subheading: 'World', imageUrl: 'https://img.example/hero.png' } },
+ ],
+ form: { actionUrl: '', fields: [], spamProtection: { honeypotFieldName: '_hp', minSubmitSeconds: 2 } },
+ seo: { title: 'SEO2', description: 'Desc2' },
+ })
+}
+
+describe('Exporter - theme-color meta and hero image intrinsic size', () => {
+ it('includes theme-color meta using page.theme.primaryColor', () => {
+ const out = exportPage(makePage())
+ const html = out.html
+ expect(html).toMatch(//)
+ })
+
+ it('renders hero image with width/height attributes for CLS reduction', () => {
+ const out = exportPage(makePage())
+ const html = out.html
+ expect(html).toMatch(/
]*\swidth="[0-9]+"/)
+ expect(html).toMatch(/
]*\sheight="[0-9]+"/)
+ })
+})