diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx
index cf16eb1..2730016 100644
--- a/apps/web/app/layout.tsx
+++ b/apps/web/app/layout.tsx
@@ -1,6 +1,7 @@
import type { Metadata } from 'next'
import { Footer, Header } from '@/components/chrome'
import { PitFooter } from '@/components/pit-footer'
+import { AdUnit } from '@/components/ad-unit'
import { SITE } from '@/lib/site'
import './globals.css'
import Script from "next/script";
@@ -87,11 +88,9 @@ export default function RootLayout({ children }: { children: React.ReactNode })
- {/* One CrawlProof unit at the top of the content, never by the footer.
- * No data-format: ad.js picks the size from the container width. */}
-
+ {/* One low-profile CrawlProof unit at the top of the content, never by
+ * the footer, and none on the homepage. */}
+
{children}
diff --git a/apps/web/components/ad-unit.tsx b/apps/web/components/ad-unit.tsx
new file mode 100644
index 0000000..96e14dd
--- /dev/null
+++ b/apps/web/components/ad-unit.tsx
@@ -0,0 +1,30 @@
+'use client'
+
+import { useEffect } from 'react'
+import { usePathname } from 'next/navigation'
+
+const AD_SLOT = '8d21a830-acfe-40ba-9d0d-0078d66ca479'
+
+/**
+ * One CrawlProof unit at the top of the content, never by the footer: the
+ * low-profile text_link line (40px, fluid, its own "Sponsored" mark). The
+ * homepage carries no ad.
+ */
+export function AdUnit() {
+ const pathname = usePathname() ?? '/'
+ if (pathname === '/') return null
+ // Keyed by path: ad.js latches a filled unit, so each navigation gets a fresh one.
+ return
+}
+
+function Unit() {
+ useEffect(() => {
+ // ad.js scans once at load; a unit mounted by client navigation asks again.
+ ;(window as unknown as { crawlproofAds?: { scan?: () => void } }).crawlproofAds?.scan?.()
+ }, [])
+ return (
+
+ )
+}