import type { ReactNode } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { Link } from 'react-router-dom';
import { SessionRail } from '../sessions/SessionRail';
import { ZipDropOverlay } from '../shared/ZipDropOverlay';
import { useTheme, type ThemeChoice, type ResolvedTheme } from '../../hooks/useTheme';
interface AppShellProps {
children: ReactNode;
}
export function AppShell({ children }: AppShellProps) {
const qc = useQueryClient();
const { choice, resolved, cycle } = useTheme();
return (
kimi vis
debug · local files
{/* min-w-0 lets the main column shrink below its content's intrinsic
width; without it a flex child defaults to min-width:auto and wide
tab content (e.g. the Timeline's flex-wrap rows) blows the layout
out horizontally instead of wrapping. */}
{children}
);
}
function ThemeToggle({
choice,
resolved,
onCycle,
}: {
choice: ThemeChoice;
resolved: ResolvedTheme;
onCycle: () => void;
}) {
const label = choice === 'auto' ? `auto · ${resolved}` : choice;
const title = `Theme: ${label}. Click to cycle (auto → light → dark → auto).`;
return (
);
}
function LogoMark() {
return (
);
}
function RefreshIcon() {
return (
);
}
function SunIcon() {
return (
);
}
function MoonIcon() {
return (
);
}
function AutoIcon() {
return (
);
}