---
path: /switcher
surface: customer
domain: discovery
auth: signed-in
source: apps/oshun/web/src/app/switcher/page.tsx
status: walked
last_walked:
  '2026-06-28 automated Playwright walk — authenticated direct route, actionable
  room links, active-room state, click navigation, listed keyboard shortcuts
  (Enter, Shift+N sample), Escape return-to-home behavior, route-level axe scan,
  render, expected content, and console/page-errors verified. Evidence:
  apps/oshun/web/e2e/domain-switcher.spec.ts'
---

# Domain switcher

## Purpose

A bookmarkable surface for the desktop ⌘D domain-switch overlay — six rooms, one
keystroke. Lists Tara, Arete, Veritas, Nyx, Nisaba, and Metis with labels,
sub-labels, and keyboard shortcuts.

## Entry points

- **Keyboard shortcut** — `⌘D` chord (handled by the shell; see
  [`shell/06-keyboard-a11y.md`](../../shell/06-keyboard-a11y.md)). The in-shell
  overlay is the primary entry path; this route is the bookmarkable fallback /
  specimen
- **Direct URL / bookmark** — yes; route is canonical
- **Shell nav** — verify domain-switch icon in the shell header opens this page
  or the in-shell overlay

## Layout regions

`page.tsx` renders `<DesktopSwitcher />` from
`@/components/lilith/system-pages`, which now delegates the route behavior to
`apps/oshun/web/src/components/lilith/DesktopSwitcherClient.tsx`. The component
composes Lilith primitives:

- **`LWebShell`** with `<LCustomerNav active="today" />` at the top
- **Background masthead** — large display ("The looker, again.") rendered at 35%
  opacity behind the overlay; non-interactive
- **Centered overlay panel** (`720` px wide, positioned absolutely):
  - **Panel header** — `⌘D` monospace label, "Switch room" italic title, `esc`
    close-hint `LCode`
- **Room navigation** — six anchor rows, one per `SWITCHER_ROOMS` entry, each
  row containing a domain glyph (`LDomainMark`), name, sub-label, and keyboard
  shortcut chip
  - **Active room** — current room (`Tara` in the fixture; `here: true`)
    rendered with paper background and `2px` accent left border

## States

- [x] **Active room indicator** — exactly one row has `data-switcher-current`
      and `aria-current="page"` (today's fixture: Tara, kbd `↵`)
- [x] **Hovered / focused row** — hover and `:focus-visible` apply the paper
      background; focus-visible also applies an inset accent ring
- [x] **Mobile / small viewport** — overlay width is
      `min(720px, calc(100vw - 32px))`; no horizontal overflow at narrow widths
- [ ] **Reduced motion** — _no animations declared._
- [ ] **Anonymous user** — no auth guard in `page.tsx`; relies on shell
      middleware
- [ ] **Standalone PWA** — verify cold-launch lands on this page if a relaunch
      target persisted it (no PWA-specific branch here)

## Interactions

The route now implements the listed room switching behavior directly. The
in-shell overlay remains a separate shell keyboard surface, while `/switcher` is
the bookmarkable fallback/specimen with equivalent room-launch affordances.

- [x] **Room rows** — six anchor rows under `nav[aria-label="Rooms"]`; each
      routes to `/domains/<domain>?origin=switcher`
  - Tara — sub: "sit", kbd: ↵, href `/domains/tara?origin=switcher`, active in
    fixture
  - Arete — sub: "the daily ritual", kbd: ⇧A, href
    `/domains/arete?origin=switcher`
  - Veritas — sub: "what is true", kbd: ⇧V, href
    `/domains/veritas?origin=switcher`
  - Nyx — sub: "the night", kbd: ⇧N, href `/domains/nyx?origin=switcher`
  - Nisaba — sub: "the reading desk", kbd: ⇧S, href
    `/domains/nisaba?origin=switcher`
  - Metis — sub: "the schoolroom", kbd: ⇧M, href
    `/domains/metis?origin=switcher`
- [x] **Keyboard shortcuts**
  - `Enter` routes to the active Tara row
  - `Shift+A`, `Shift+V`, `Shift+N`, `Shift+S`, `Shift+M` route to Arete,
    Veritas, Nyx, Nisaba, and Metis respectively
  - Shortcut handler ignores editable controls and Ctrl/Alt/Meta-modified events
- [x] **`Esc` hint** — `Escape` returns the specimen route to `/`

## Data & contracts

- **Reads**: none — `SWITCHER_ROOMS` is a hard-coded tuple inside
  `DesktopSwitcherClient.tsx`
- **Writes**: _None._
- **Realtime**: _None._
- **Caching**: SSR / static (no `'use client'` on this page)
- **Auth/role check**: shell middleware only

## Cross-references

- Shell: [`shell/01-app-shell.md`](../../shell/01-app-shell.md)
- Keyboard / a11y:
  [`shell/06-keyboard-a11y.md`](../../shell/06-keyboard-a11y.md)
- Sibling routes:
  - [`home.md`](./home.md), [`explore.md`](./explore.md),
    [`activity.md`](./activity.md), [`library.md`](./library.md),
    [`messages.md`](./messages.md), [`search.md`](./search.md)
- Component sources:
  - `apps/oshun/web/src/components/lilith/system-pages.tsx` (`DesktopSwitcher`
    delegates to the client island)
  - `apps/oshun/web/src/components/lilith/DesktopSwitcherClient.tsx`
    (`SWITCHER_ROOMS`, click links, keyboard shortcuts)
- Domain entries:
  - [`../03-tara/tara.md`](../03-tara/tara.md)
  - [`../04-arete/`](../04-arete/), [`../05-veritas/`](../05-veritas/),
    [`../06-nyx/`](../06-nyx/),
    [`../07-nisaba/nisaba.md`](../07-nisaba/nisaba.md),
    [`../08-metis/metis.md`](../08-metis/metis.md)

## Open questions / known gaps

- [x] Room rows are anchor links with domain-specific `href`s and accessible
      link names
- [x] Listed keyboard chords are bound on the route
- [x] `Escape` returns the bookmarkable specimen to Home (`/`)
- [x] This route is documented as the bookmarkable fallback/specimen; the live
      `⌘D` overlay remains the customer shell keyboard surface
