linXiv frontend (TS/JS)
    Preparing search index...
    interface GraphCanvasProps {
        forces: ForceSettings;
        gutter: number;
        index: GraphIndex;
        match: GraphMatch;
        measureGutter: () => number;
        onAuthorTap: (authorId: number) => void;
        onBackgroundTap: () => void;
        onNodeContextMenu: (e: MouseEvent, node: GraphNodeContext) => void;
        onPaperTap: (id: string, additive: boolean) => void;
        onTagTap: (label: string) => void;
        selectedIds: ReadonlySet<string>;
        theme: ThemeColors;
        view: GraphView;
    }
    Index
    gutter: number

    Canvas pixels covered by the panel column, so a fit frames the visible strip.

    index: GraphIndex
    match: GraphMatch
    measureGutter: () => number

    The same number read straight from the DOM. gutter is React state, and a fit can run in the same task as the ResizeObserver callback that recomputes it — the reveal of this page from display: none is exactly that moment. That setGutter has not committed, so a fit reading the prop sees the hidden column's 0 and frames the whole canvas, leaving the rightmost nodes under the panels for the session. Measure, don't remember.

    onAuthorTap: (authorId: number) => void
    onBackgroundTap: () => void
    onNodeContextMenu: (e: MouseEvent, node: GraphNodeContext) => void
    onPaperTap: (id: string, additive: boolean) => void
    onTagTap: (label: string) => void
    selectedIds: ReadonlySet<string>
    view: GraphView