diff --git a/__tests__/components/mobile/landscape-guard.test.tsx b/__tests__/components/mobile/landscape-guard.test.tsx
new file mode 100644
index 0000000..ca3a4d1
--- /dev/null
+++ b/__tests__/components/mobile/landscape-guard.test.tsx
@@ -0,0 +1,73 @@
+// @vitest-environment jsdom
+import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
+import { render, screen, act } from '@testing-library/react'
+import { LandscapeGuard } from '@/components/mobile/landscape-guard'
+
+type Listener = (e: MediaQueryListEvent) => void
+
+function mockMatchMedia(initialPortrait: boolean) {
+ let matches = initialPortrait
+ let listener: Listener | null = null
+
+ const mql = {
+ get matches() { return matches },
+ media: '(orientation: portrait)',
+ onchange: null,
+ addEventListener: (_: string, l: Listener) => { listener = l },
+ removeEventListener: () => { listener = null },
+ addListener: () => {},
+ removeListener: () => {},
+ dispatchEvent: () => false,
+ }
+
+ Object.defineProperty(window, 'matchMedia', {
+ writable: true,
+ configurable: true,
+ value: () => mql,
+ })
+
+ return {
+ setPortrait(p: boolean) {
+ matches = p
+ if (listener) listener({ matches: p } as MediaQueryListEvent)
+ },
+ }
+}
+
+describe('LandscapeGuard', () => {
+ beforeEach(() => {})
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ it('renders children always', () => {
+ mockMatchMedia(false)
+ render(kids
)
+ expect(screen.getByText('kids')).toBeTruthy()
+ })
+
+ it('shows overlay in portrait', () => {
+ mockMatchMedia(true)
+ render(kids
)
+ expect(screen.getByRole('alert').textContent).toContain('Draai je telefoon naar landscape')
+ // children blijven in DOM (geen unmount → SSE-streams blijven leven)
+ expect(screen.getByText('kids')).toBeTruthy()
+ })
+
+ it('hides overlay in landscape', () => {
+ mockMatchMedia(false)
+ render(kids
)
+ expect(screen.queryByRole('alert')).toBeNull()
+ })
+
+ it('toggles overlay on orientation change', () => {
+ const ctl = mockMatchMedia(false)
+ render(kids
)
+ expect(screen.queryByRole('alert')).toBeNull()
+ act(() => ctl.setPortrait(true))
+ expect(screen.getByRole('alert')).toBeTruthy()
+ act(() => ctl.setPortrait(false))
+ expect(screen.queryByRole('alert')).toBeNull()
+ })
+})
diff --git a/components/mobile/landscape-guard.tsx b/components/mobile/landscape-guard.tsx
new file mode 100644
index 0000000..339d67d
--- /dev/null
+++ b/components/mobile/landscape-guard.tsx
@@ -0,0 +1,32 @@
+'use client'
+
+import { useEffect, useState } from 'react'
+import { RotateCw } from 'lucide-react'
+
+export function LandscapeGuard({ children }: { children: React.ReactNode }) {
+ const [isPortrait, setIsPortrait] = useState(false)
+
+ useEffect(() => {
+ const mq = window.matchMedia('(orientation: portrait)')
+ const update = () => setIsPortrait(mq.matches)
+ update()
+ mq.addEventListener('change', update)
+ return () => mq.removeEventListener('change', update)
+ }, [])
+
+ return (
+ <>
+ {children}
+ {isPortrait && (
+
+
+
Draai je telefoon naar landscape
+
+ )}
+ >
+ )
+}