diff --git a/.Jules/palette.md b/.Jules/palette.md
index 0a19f42a..c975fe97 100644
--- a/.Jules/palette.md
+++ b/.Jules/palette.md
@@ -26,3 +26,6 @@
## 2026-04-09 - Standardize Modal Accessibility for Cloud Library
**Learning:** The `CloudLibrary` component functioned as a modal visually but lacked standard ARIA modal attributes (`role="dialog"`, `aria-modal="true"`, `aria-labelledby`), causing screen readers to announce it incorrectly or not at all.
**Action:** When implementing custom modals, always include `role="dialog"`, `aria-modal="true"`, an explicit `aria-labelledby` referencing a visually hidden or visible title element, and an `aria-hidden="true"` on the clickable background overlay.
+## 2024-11-20 - Standardize Backdrop Overlay Accessibility
+**Learning:** Components using `fixed inset-0` with a click handler to close a modal will cause screen readers to announce the entire background as a clickable element. This violates accessibility conventions.
+**Action:** When implementing clickable background overlays for custom modals, always separate the clickable backdrop into its own `
` sibling of the dialog element, and explicitly mark it with `aria-hidden="true"`.
diff --git a/src/components/AISongModal.tsx b/src/components/AISongModal.tsx
index 8fa0fdc2..1b5b26fa 100644
--- a/src/components/AISongModal.tsx
+++ b/src/components/AISongModal.tsx
@@ -655,10 +655,17 @@ export function AISongModal({ isOpen, onClose, onImport, onShowToast, audioEngin
e.target === e.currentTarget && handleClose()}
>
+
e.preventDefault()}
@@ -671,7 +678,7 @@ export function AISongModal({ isOpen, onClose, onImport, onShowToast, audioEngin
🤖
-
Import AI Song
+
Import AI Song
Import songs from Claude, Gemini, Jules, Copilot, etc.
diff --git a/src/components/RbsImportModal.tsx b/src/components/RbsImportModal.tsx
index 68cf6789..5a4311fd 100644
--- a/src/components/RbsImportModal.tsx
+++ b/src/components/RbsImportModal.tsx
@@ -384,9 +384,13 @@ export function RbsImportModal({ isOpen, onClose, onImport, onShowToast }: RbsIm
return (
e.target === e.currentTarget && onClose()}
>
-
+
+
{/* Header */}
diff --git a/src/components/VoiceEditor.tsx b/src/components/VoiceEditor.tsx
index d895f194..38c43e23 100644
--- a/src/components/VoiceEditor.tsx
+++ b/src/components/VoiceEditor.tsx
@@ -74,17 +74,19 @@ export const VoiceEditor: React.FC
= ({ onClose }) => {
return (
+
e.stopPropagation()}
>
VOICE DESIGNER (WebGPU)