component · platform-aware chrome

TuxAppSwitcher

Waffle-button trigger + popover grid for hopping between TTI's portals (TTI ↔ my.TTI ↔ TUX docs ↔ Landscape ↔ Atlas ↔ TTI Code). Lives in TuxAppFrame's #right slot on Tauri shells or in TuxSiteNav's utility row on plain-web consumers. Source: Microsoft Fabric "Suite header" absorption. The app list comes from the canonical registry (design/apps.json) via useTuxApps() — never hand-declared.

signed in · registry order

Click the waffle

Tiles render in registry order on every portal — spatial constancy builds the muscle memory. The current app's tile stays a focusable link with aria-current="page" and the "You are here" badge. Desktop apps carry a "Desktop app" affix and point at the launcher, never a raw scheme. Below ~30rem width the grid drops to one column.

const { apps, heading, footerText } = useTuxApps({
  current: "tux",
  signedIn: identity.authenticated,
});

<tux-app-switcher :apps="apps" :heading="heading" :footer-text="footerText" />

anonymous · audience filtering

Signed-out state

Anonymous visitors see only audience: "public" apps, with a footer count pointing at sign-in. Filtering is navigation, not authentication — every destination enforces its own gate.

const { apps, heading, footerText } = useTuxApps({
  current: "tux",
  signedIn: identity.authenticated,
});

<tux-app-switcher :apps="apps" :heading="heading" :footer-text="footerText" />

composition

Place it where it belongs

On TuxAppFrame, drop the switcher in the #right slot alongside user-menu and notifications. On TuxSiteNav, place it in the utility row before TuxIdentity. Single instance per app — not a navigation pattern, an inter-app handoff. The presentation prop is reserved for compact/touch hosts ("sheet"); only "popover" is implemented today.