diff --git a/frontend/src/components/layout/RightSidebar.tsx b/frontend/src/components/layout/RightSidebar.tsx
index 8f69b15..a7703d1 100644
--- a/frontend/src/components/layout/RightSidebar.tsx
+++ b/frontend/src/components/layout/RightSidebar.tsx
@@ -249,6 +249,9 @@ export function RightSidebar() {
}
// ── Single-photo: full editor via PhotoInfoPanel ────────────────────
+ // Heap card + header stay pinned at the top; the edit fields and
+ // readonly metadata sections scroll together in a single overflow
+ // region below.
if (selectedPhotos.length === 1) {
const id = activePhotoId ?? selectedPhotos[0]
return (
@@ -259,7 +262,9 @@ export function RightSidebar() {
>
-
+
)
}
diff --git a/frontend/src/components/sidebar/PhotoInfoPanel.tsx b/frontend/src/components/sidebar/PhotoInfoPanel.tsx
index 57d4307..d9f3e74 100644
--- a/frontend/src/components/sidebar/PhotoInfoPanel.tsx
+++ b/frontend/src/components/sidebar/PhotoInfoPanel.tsx
@@ -143,7 +143,7 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
const queryClient = useQueryClient()
const [expandedSections, setExpandedSections] = useState>(
- new Set(['basic', 'camera', 'location', 'tags'])
+ new Set(['metadata', 'basic', 'camera', 'location', 'tags'])
)
const toggleSection = (section: string) => {
const next = new Set(expandedSections)
@@ -380,10 +380,13 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
: 'border-border bg-bg text-text placeholder-text-faint focus:border-primary'
)
+ // Note: no h-full / flex-1 here — the parent (RightSidebar) owns the
+ // scroll container so the edit fields and readonly metadata scroll
+ // together as one block beneath the pinned heap + header.
return (
@@ -542,8 +545,24 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
- {/* Read-only metadata sections */}
-
+ {/* Read-only metadata — collapsed/expanded as one block so the user
+ * can hide everything below the editable form with a single click.
+ * Sub-sections inside stay individually collapsible for finer
+ * control once the outer group is open. */}
+ toggleSection('metadata')}
+ className="border-b border-border"
+ >
+
+ Metadata
+ {expandedSections.has('metadata') ? (
+
+ ) : (
+
+ )}
+
+
)}
-
-
+
+
)
}