Context. surface customer · domain nisaba · route /nisaba · auth signed-in · source apps/oshun/web/src/app/nisaba/page.tsx
Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; content re-verified 2026-06-03 against current source
Purpose#
The Nisaba domain hub. A reading desk for the long texts: passage with sections rail, marginalia, cross-references, and links to the deeper Nisaba sub-surfaces (scholar, lexicon, graph, notebook).
Entry points#
- Home domain card grid — see
../02-home-discovery/home.md - Domain switcher —
/switcher(see../02-home-discovery/switcher.md) - Domain back-stack from sibling Nisaba routes —
LSubNav active="desk"keeps the reading desk anchored across/nisaba/* - Library + Explore — sky-and-scripture collection and curated routes link here
- Direct URL / bookmark — yes (auth required via shell middleware)
- Server fetch —
getNisaba()runs on the server before render
Layout regions#
page.tsx is a thin server component: await getNisaba() →
<NisabaRoom data={data} />.
Inside NisabaRoom (rooms.tsx, line 1114), a Lilith room composition. The
desk passage is a Pali / Buddhist text on the five aggregates (anattā /
not-self) — the Greek (Marcus Aurelius) text belongs to the compare and scholar
views, not the desk:
- Web shell top —
LCustomerNav active="library"plus anLSubNavwithdesk | scholar | lexicon | graph | notebooktabs (desk active) - Header / above the fold — passage title (italic muted), citation eyebrow,
language buttons (
data.passage.languages— Pali / English / Both peractiveLanguage) - Sections + Marginalia rail (left, 220 px) —
data.sections.maprows with section number and title (theheresection uses ink color and accent number), then anLRuleand a Marginalia block (data.marginalia.maplabel/count rows) - Main reading column (centre) — passage body (
data.passageBody.map) with a drop-cap first paragraph and an inline "Margin · me" five-aggregates note; below it anLRuleand the prev/next section nav + passage actions (see Interactions) - Cross-references / concept-graph rail (right, 280 px) —
Cross-referenceseyebrow over anLCardwith the concept-graph SVG (data.graphNodes) and aRead alongsidelist of related passages (data.related)
Automation anchors#
This file covers the compact /nisaba reading desk. The search-result
destination is the live domain reader at /domains/nisaba, covered by
../../journeys/nisaba-scholarly-read.md
through data-nisaba-surface, data-nisaba-workspace, and
data-nisaba-reading-* anchors.
- Root:
data-nisaba-desk-pagewith title/citation/active-language and language/section/marginalia/paragraph/graph-node/related counts - Header:
data-nisaba-desk-header,data-nisaba-desk-eyebrow,data-nisaba-desk-heading,data-nisaba-desk-citation-text, and perdata-nisaba-desk-language={language}button witharia-pressedand active-state attributes - Sections + marginalia:
data-nisaba-desk-section-railwith perdata-nisaba-desk-section={number}row, section title/current attributes, anddata-nisaba-desk-marginaliawith per-row label/value cells - Reading:
data-nisaba-desk-reading, perdata-nisaba-desk-paragraph={index}paragraph, inline margin notedata-nisaba-desk-inline-margin-note, and footer action wrappers - Cross-reference rail:
data-nisaba-desk-crossrefs,data-nisaba-desk-graph, per graph-node label/color attributes, anddata-nisaba-desk-relatedwith per-row code/title cells
States#
- Loaded —
getNisaba()resolves before render; no client loading branch in this view - Active language: Pali / English / Both —
data.passage.activeLanguageseeds the selected language button; clicking a language swaps the reading body throughpassageBodies - Active section — exactly one
section.here === true - Cross-domain bridges — verify any links to Tara / Veritas / Metis that the room data surfaces
- Reduced motion — composes static Lilith primitives; no animations observed
- Standalone PWA / Offline — depends on shell + server cache; no Nisaba-specific branch
Interactions#
Top sub-nav#
- The desk (tab) — active; route
/nisaba - Scholar mode (tab) — routes to
/nisaba/scholar(verify wiring inLSubNav) - Lexicon (tab) — routes to
/nisaba/lexicon - Concept graph (tab) — routes to
/nisaba/graph - Notebook (tab) — routes to
/nisaba/notebook
Header language buttons#
- Language button —
Pali,English, andBoth, side-by-sideare real buttons when the live desk provides all three bodies; clicking updates the active-language attribute and reading body. The honest unavailable fallback remains English-only.
Sections rail#
- Section row — navigates to that section anchor; current-section row styled with accent number + ink title
Reading column#
- Footnote / cross-reference link — opens the corresponding lexicon / graph / scholar entry
- Highlighted token — opens lexicon for that word (verify)
Passage footer (below the reading column rule)#
- ‹ I. The setting (
LBtn kind="ghost" href="/nisaba#section-I") — jumps to the previous section anchor - III. On feeling › (
LBtn kind="primary" href="/nisaba#section-III") — jumps to the next section anchor -
NisabaPassageActions(rooms.tsx~1311-1315 →components/lilith/NisabaPassageActions.tsx) — a'use client'row:- Save passage / ✓ Saved — toggles the passage in the local web library
(
toggleOshunWebLibraryItem,domain: 'nisaba') - Read aloud / Pause / Resume — speaks the passage via
window.speechSynthesis; degrades to a "Read-aloud not supported" eyebrow when the API is absent TrustSafetyFlagButton— flags the passage (targetKind="content")
- Save passage / ✓ Saved — toggles the passage in the local web library
(
Data & contracts#
- Reads:
getNisaba()from@/lib/lilith-data/nisaba— fetches the live BFF routeGET /v1/nisaba/roomviabffGet(nisaba.ts~14-19) and returnsNisabaData(passage, sections, languages, activeLanguage, marginalia, graphNodes, related). On an unreachable feed it returns an honestnisabaUnavailable()room (no embedded fixture). - Writes: None from the server view;
NisabaPassageActions(client) writes to the local web library and to the trust/safety flag flow. - Realtime: None.
- Caching: server fetch; SW caches the rendered HTML for offline reload
- Auth/role check: shell middleware
- Route metadata: title "Nisaba · the reading desk", canonical
/nisaba
Cross-references#
- Shell:
shell/01-app-shell.md - Sibling Nisaba routes:
nisaba-compare.md— text, three waysnisaba-daily.md— daily passage (phone shell)nisaba-graph.md— concept graphnisaba-lexicon.md— lexiconnisaba-manuscript.md— Vatic. gr. 1950, f. 24vnisaba-notebook.md— long-form notebooknisaba-plan.md— seven-week study plannisaba-scholar.md— full apparatus
- Component sources:
apps/oshun/web/src/components/lilith/rooms.tsx(NisabaRoomline 1114)apps/oshun/web/src/components/lilith/NisabaPassageActions.tsxapps/oshun/web/src/lib/lilith-data/nisaba.ts
- Feature spec:
V1/features.md#nisaba
Open questions / known gaps#
-
NisabaDatais served live fromGET /v1/nisaba/room; confirm the BFF contract stays in sync with theNisabaDatashape - Confirm whether language and section controls are interactive in V1 —
language buttons swap Pali / English / Both bodies on the live desk;
section rows are links to
/nisaba#section-* - Document the cross-domain bridges Nisaba carries (Tara ritual moments, Veritas grounded evidence, Metis study)
- Confirm shell sub-nav routing —
LSubNavitems carry explicit hrefs for desk, scholar, lexicon, graph, and notebook