+
diff --git a/frontend/src/app/recollections/RecollectionMenubar.tsx b/frontend/src/app/recollections/RecollectionMenubar.tsx
index 9a729a8..4ef31e0 100644
--- a/frontend/src/app/recollections/RecollectionMenubar.tsx
+++ b/frontend/src/app/recollections/RecollectionMenubar.tsx
@@ -1,12 +1,11 @@
/**
- * Recollection menubar: Back | title + save status | registered menus (middle) | Logos | Flux.
+ * Recollection menubar: Back | title + save status | registered menus (middle).
*/
import React from 'react'
-import { Link, NavLink, useParams } from 'react-router-dom'
+import { Link, useParams } from 'react-router-dom'
import { usePlatform } from '@/app/kosmos/KosmosContext'
import { ArrowLeft } from 'lucide-react'
-import { FluxIcon, LogosIcon } from '@/lib/icons'
import { useRecollectionMenubar } from './RecollectionMenubarContext'
import { RecollectionEditViewMenus } from './RecollectionEditViewMenus'
@@ -16,7 +15,6 @@ export function RecollectionMenubar() {
const { titleContent } = useRecollectionMenubar()
const recollection = recollectionId ? recollections.find((p) => p.id === recollectionId) : null
- const base = recollectionId ? `/recollections/${recollectionId}` : ''
const defaultTitle = recollection ? (
{recollection.name}
) : null
@@ -36,29 +34,6 @@ export function RecollectionMenubar() {
- {base && (
-
-
- `flex items-center gap-1.5 rounded-sm px-2.5 py-1 text-sm outline-none focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground ${isActive ? 'bg-accent font-medium text-foreground' : 'text-muted-foreground'}`
- }
- >
-
- Logos
-
-
- `flex items-center gap-1.5 rounded-sm px-2.5 py-1 text-sm outline-none focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground ${isActive ? 'bg-accent font-medium text-foreground' : 'text-muted-foreground'}`
- }
- >
-
- Flux
-
-
- )}
)
}
diff --git a/frontend/src/app/recollections/RecollectionViewSwitcher.tsx b/frontend/src/app/recollections/RecollectionViewSwitcher.tsx
new file mode 100644
index 0000000..d5cfc5d
--- /dev/null
+++ b/frontend/src/app/recollections/RecollectionViewSwitcher.tsx
@@ -0,0 +1,88 @@
+/**
+ * Elevator-style view switcher: circular button moves between top (Logos) and bottom (Flux).
+ * Click toggles; shortcut and tooltip on hover.
+ */
+
+import React, { useCallback, useEffect } from 'react'
+import { useLocation, useNavigate, useParams } from 'react-router-dom'
+import { usePlatform } from '@/app/kosmos/KosmosContext'
+import { FluxIcon, LogosIcon } from '@/lib/icons'
+import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
+import { Kbd } from '@/components/ui/kbd'
+
+const VIEW_TOGGLE_KEYS = { key: 'v', shiftKey: true }
+
+function matchKey(ev: KeyboardEvent, want: { key: string; shiftKey: boolean }) {
+ const mod = ev.ctrlKey || ev.metaKey
+ return ev.key.toLowerCase() === want.key && !!mod && ev.shiftKey === want.shiftKey
+}
+
+function shortcutLabel() {
+ if (typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform)) {
+ return '⌘⇧V'
+ }
+ return 'Ctrl+⇧+V'
+}
+
+export function RecollectionViewSwitcher() {
+ const { recollectionId } = useParams<{ recollectionId: string }>()
+ const { pathname } = useLocation()
+ const navigate = useNavigate()
+ const base = recollectionId ? `/recollections/${recollectionId}` : ''
+
+ const isFlux = pathname.endsWith('/flux')
+
+ const toggle = useCallback(() => {
+ if (!base) return
+ navigate(isFlux ? `${base}/logos` : `${base}/flux`)
+ }, [base, isFlux, navigate])
+
+ useEffect(() => {
+ const onKeyDown = (ev: KeyboardEvent) => {
+ if (matchKey(ev, VIEW_TOGGLE_KEYS)) {
+ ev.preventDefault()
+ toggle()
+ }
+ }
+ window.addEventListener('keydown', onKeyDown, true)
+ return () => window.removeEventListener('keydown', onKeyDown, true)
+ }, [toggle])
+
+ if (!base) return null
+
+ const tooltipText = isFlux
+ ? `Switch to Logos`
+ : `Switch to Flux`
+
+ return (
+