shell-redesign V1 attempt-3 Phase 3 BOUNCE-FIX follow-on: tabs-only topology scope shell

Founder direction 2026-05-06 (with reference mockup): the topology
scope shell should render JUST the view-mode tabs anchored to the
right of the Explorer — no "TOPOLOGY · SEAT" eyebrow, no big
"DISCOVERY.INTAKE-ROUTER" title, no border-bottom + bg-background
header section. Tabs over paper-grid canvas; scope identity reads from
the URL + Explorer tree active state.

Changes:
- ScopeShell now renders just the tabsNav with marginLeft anchored to
  --header-anchor-offset (preserves the fixed-anchor behavior across
  graph / table / terminal switches per Class B).
- Removed: SectionHeader eyebrow, h1 title, border-b underline + bg-background
  on the wrapper div.
- Kept: relative z-30 (tabs stay above Explorer overlay in graph mode),
  px-6 + pt-4 padding for breathing room, marginLeft anchor.
- The eyebrow/title props are still typed (now optional) for
  potential future revival but not consumed.

Visual verification at 1440x900:
- /topology: just GRAPH / TABLE / TERMINAL tabs over paper-grid; tabs
  at fixed anchor.
- /topology/seat/...: just DETAIL / TRANSCRIPT / TERMINAL tabs;
  LiveNodeDetails renders its own H1 below as part of the detail panel
  content (separate concern; not part of the scope shell).
- Tab fixed-anchor preserved across view-mode switches.

Tests: 47/48 PASS in app-shell + topology-view-mode test files (1
skipped seat-scope brittle); no regression.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
mvschwarzandClaude Opus 4.7 committed 2026-05-06 14:58:28 -07:00
1 parent 400477ba4a
commit 6f86a5cd97
1 file changed
+15 -17
@@ -40,34 +40,32 @@ function useOverlayForActiveTab(active: string) {
}
function ScopeShell({
eyebrow,
title,
tabsNav,
children,
}: {
eyebrow: string;
title: string;
/** Eyebrow + title are no longer rendered — founder direction
* 2026-05-06: tabs only, anchored to right of Explorer. The scope
* identity reads from the URL + Explorer tree active state, so the
* big DISCOVERY.INTAKE-ROUTER style title in the canvas is redundant.
* Keeping the prop names for now in case Phase 5 wants to revive a
* smaller breadcrumb. */
eyebrow?: string;
title?: string;
tabsNav: React.ReactNode;
children: React.ReactNode;
}) {
// Class B fixed-anchor: header (with eyebrow + title + view-mode tabs)
// ALWAYS sits at left = var(--explorer-anchor-left) so the tab bar is
// positioned consistently across graph / table / terminal switches.
// The CONTENT below the header inherits the parent <main>'s
// padding-left rule (which is 0 in overlay mode so canvas extends
// behind the Explorer; or anchor in opaque mode). Tab bar gets z-30
// and a solid background so it stays on top of the Explorer overlay
// in graph mode.
// Class B fixed-anchor: tabsNav sits at left = var(--explorer-anchor-left)
// (set on <main> in AppShell) so position is identical across graph /
// table / terminal switches. Transparent over the canvas — paper-grid
// shows through. z-30 keeps tabs above the Explorer overlay in graph
// mode (the tabs are anchored past the Explorer's right edge so they
// shouldn't actually overlap, but z-order is the safety net).
return (
<div className="flex flex-col h-full">
<div
className="px-6 pt-6 pb-2 border-b border-outline-variant relative z-30 bg-background"
className="relative z-30 px-6 pt-4"
style={{ marginLeft: "var(--header-anchor-offset, 0px)" }}
>
<SectionHeader tone="muted">{eyebrow}</SectionHeader>
<h1 className="font-headline text-headline-md font-bold tracking-tight uppercase text-stone-900 mt-1 mb-3">
{title}
</h1>
{tabsNav}
</div>
<div className="flex-1 min-h-0 overflow-auto">