diff --git a/src/web/components/MobileDrawer.tsx b/src/web/components/MobileDrawer.tsx
new file mode 100644
index 0000000..1624f45
--- /dev/null
+++ b/src/web/components/MobileDrawer.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+
+type MobileDrawerProps = {
+ open: boolean;
+ onClose: () => void;
+ children: React.ReactNode;
+};
+
+export default function MobileDrawer({ open, onClose, children }: MobileDrawerProps) {
+ if (!open) return null;
+
+ return (
+
+ );
+}
diff --git a/src/web/components/mobile-drawer.test.tsx b/src/web/components/mobile-drawer.test.tsx
new file mode 100644
index 0000000..1bdfe9b
--- /dev/null
+++ b/src/web/components/mobile-drawer.test.tsx
@@ -0,0 +1,25 @@
+import { describe, expect, it, vi } from 'vitest';
+import { create } from 'react-test-renderer';
+import MobileDrawer from './MobileDrawer.js';
+
+describe('MobileDrawer', () => {
+ it('renders content when open and closes on backdrop click', () => {
+ const onClose = vi.fn();
+ const root = create(
+
+ DrawerContent
+ ,
+ );
+
+ const text = root.root.findAll(() => true)
+ .flatMap((instance) => instance.children)
+ .filter((child): child is string => typeof child === 'string')
+ .join('');
+
+ expect(text).toContain('DrawerContent');
+
+ const backdrop = root.root.find((node) => node.props?.className === 'mobile-drawer-backdrop');
+ backdrop.props.onClick();
+ expect(onClose).toHaveBeenCalledTimes(1);
+ });
+});