---
name: infinibot-dashboard-worldmap-panel
description: Add a new lazy-loaded Lit mini-panel beside the agent world map on the InfiniBot-fresh dashboard
---
# InfiniBot Dashboard World-Map Panel
## When to use
- Asked to add a mini-panel, widget, or aside (calendar, focus, stats, feed) next to the agent world map on the InfiniBot-fresh main dashboard.
- Extending the dashboard's world-map band with a new custom element.
- Any new dashboard panel that needs to mount a `<custom-element>` and react to navigation.

## How to apply
1. Build the panel as a standalone Lit element in `ui/src/ui/components/<name>-panel.ts`. Take `client: GatewayBrowserClient` and config props. Fetch data via the existing `controllers/*.ts` for that domain (reuse, don't reimplement). Poll on an interval set up in `connectedCallback`; clear it in `disconnectedCallback`.
2. Cover all states: loading (shimmer skeleton), empty, error/unauthenticated CTA, and loaded. Match the `dash-worldmap` aesthetic — dark `#06000f` panel, `#d4af37` gold accents, JetBrains Mono.
3. For cross-view actions, dispatch a bubbling + composed `CustomEvent` (e.g. `dashboard-open-calendar`) rather than calling navigation directly from the component.
4. In `ui/src/ui/views/dashboard.ts`: add an `ensure<Name>PanelLoaded()` lazy-loader mirroring the existing world-viz / focus-panel pattern, mount the element inside `renderWorldMapBand()`, and wrap the band in a `.dash-worldmap__layout` CSS grid (world map `minmax(280px, 7fr)` + aside `minmax(280px, 3fr)`, wrapping below ≤900px).
5. Handle the event on the section and route via `navigate("<tab>")`. Confirm the exact tab slug in `ui/src/ui/navigation.ts` before wiring (calendar = `"schedule"`).
6. Verify: `npx tsc --noEmit -p ui` (ignore pre-existing HEAD errors in untouched code), then `vite build` to write `ui/dist/control-ui` and view on the gateway at `:18789`.

## Rules
- Never start a Vite dev server for the InfiniBot UI — there is no dev server; `:5173` serves KinglyVault. Use `vite build` + the gateway-served bundle at `:18789` to verify.
- Never fetch domain data directly — go through the existing `controllers/*.ts`.
- Always clear poll timers in `disconnectedCallback` to avoid leaks.
- Always confirm the navigation tab slug in `navigation.ts` before wiring an event handler.
- Always mount via a lazy `ensure<Name>PanelLoaded()` loader, matching the world-viz / focus-panel convention — the world-map host is `<agency-world-viz>` in `dashboard.ts`, not `agent-ops/`.