---
path: /atelier/audio
surface: customer
domain: atelier
auth: signed-in
source: apps/oshun/web/src/app/atelier/audio/page.tsx
status: walked
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'
---

# Atelier · XI · Foundry of Voices

## Purpose

Audio atelier — "a reading, cast." Five-step workflow: voice cast → prosody-
marked score → four takes → three stems (room/breath/bell) → mix to plate.
Server-rendered by `apps/oshun/web/src/app/atelier/audio/page.tsx` via
`getAtelierAudio()` → `<AtelierAudio data>`.

## Entry points

- **Atelier index** (`/atelier`) — second room card
- **Lilith index** (`/lilith`) — section VIII card 43 "XI · Foundry of Voices"
- **Direct URL / bookmark** — yes (signed-in)

## Layout regions

`AtelierAudio` (`apps/oshun/web/src/components/lilith/atelier.tsx`, line 558)
renders inside `LWebShell` with `LCustomerNav active="explore"`.

- **Plate head** (`LAPlateHead no="XI"`):
  - kicker: "The atelier · the foundry of voices"
  - title: `A reading, <em>cast</em>.`
  - right chips: "SN 22.59", "7 min · 04 takes", "Take 03 · kept" (accent)
- **Three-column body** (`230px 1fr 320px`):
  - **Left rail** (`LAStepRail`, current=3): five steps — "Voice · cast", "Score
    · prosody marked", "Takes · four", "Stems · room, breath, bell", "Mix ·
    plate cut"
  - **Center**:
    - **Score card** (`Score · with breath marks`): three paragraphs with
      timecodes (`00:00`, `00:42`, `02:14`); pause marks `‖` (pause) / `‖‖`
      (long pause) / `(•n)` (breath, n seconds); legend at the bottom
    - **Stems card** (`Stems · three layers`): three rows from `data.stems`
      (each row = label + dB readout + procedural SVG waveform); playhead marker
      at 32%; timecode strip `0:00 / 02:14 · playhead / 07:00`
    - **Action row**: "Re-cast voice", "Re-take §02:14", "Export · stems", "Mix
      · plate cut" (primary)
  - **Right**:
    - **Voice · cast list** from `data.voiceCast` (Sam Harris — kept, Tara Brach
      — alt candidate, J. Goldstein — alt canon, Lilith · house — synthetic
      disclosed); each row has a circular initial, name, attribution, role tag
      (accent for kept)
    - **`LRule`**
    - **Take card · 03** with `LField` rows: Length 07:00, Bell "Tibetan ·
      soft", Pacing "Slow · 124 wpm", Pauses "11 · breath-aligned", Emotion
      "Spacious, even", Synthetic "No · human voice"

## States

- [ ] **Loading** — server component awaits `getAtelierAudio()`; verify
      `loading.tsx`
- [ ] **Populated** — fixture provides 3 stems + 4 voice cast entries
- [ ] **Synthetic voice disclosed** — "Lilith · house" entry visibly marked
      `Synthetic`
- [ ] **Kept take selected** — Take 03 is accent; sample fields shown on right
- [ ] **Error** — verify error boundary
- [ ] **Offline** — static markup; renders offline
- [ ] **Reduced motion** — no animations declared

## Interactions

### Score card

- [ ] **Score paragraphs** — read-only typography with embedded pause glyphs and
      breath markers

### Stems card

- [ ] **Stem rows** (3, from `data.stems`: Voice · S. Harris (accent), Bell ·
      Tibetan, Room · cream)
  - Read-only label + dB readout + procedural waveform SVG
- [ ] **Playhead marker** — visual only; no scrub interaction

### Center actions

- [ ] **"Re-cast voice" button** (ghost) — handler not present in static
      composition
- [ ] **"Re-take §02:14" button** (ghost)
- [ ] **"Export · stems" button** (ghost)
- [ ] **"Mix · plate cut" button** (primary)

### Voice cast list (each row)

- [ ] **Sam Harris row** (accent, "Narrator · kept" + 142 sittings)
- [ ] **Tara Brach row** ("Alt · candidate" + 96 sittings)
- [ ] **J. Goldstein row** ("Alt · canon" + 71 sittings)
- [ ] **Lilith · house row** ("Synthetic" + "Marked · synthetic, disclosed")
- [ ] **Row tap behaviour** — verify whether tap selects a different voice (no
      handler shown)

## Data & contracts

- **Reads**: `getAtelierAudio()` from
  `apps/oshun/web/src/lib/lilith-data/atelier-depth.ts` — returns
  `AtelierAudioData` with `stems` and `voiceCast` (planned BFF at
  `/atelier/plates/audio`)
- **Writes**: none in current static composition
- **Realtime**: none
- **Caching**: server fetch
- **Auth/role check**: middleware enforces signed-in

## Cross-references

- Atelier index: [`atelier.md`](./atelier.md)
- Sibling rooms: [`atelier-image.md`](./atelier-image.md),
  [`atelier-video.md`](./atelier-video.md),
  [`atelier-forms.md`](./atelier-forms.md),
  [`atelier-motion.md`](./atelier-motion.md)
- Downstream — `AtelierMotion`'s "Compose · downstream" panel inherits "voice
  (foundry · take 03)"
- Component source: `apps/oshun/web/src/components/lilith/atelier.tsx`
  (`AtelierAudio`)
- Data: `apps/oshun/web/src/lib/lilith-data/atelier-depth.ts`

## Open questions / known gaps

- [ ] Confirm whether stems card supports playback / scrub interactions or is
      purely visual
- [ ] Verify synthetic-disclosure policy — the Lilith voice row is marked as
      `synthetic, disclosed`; cross-reference with Lilith policy on
      voice-quality and abuse policy
      ([`V1/features.md#lilith-persona-policy`](../../../V1/features.md#lilith-persona-policy))
- [ ] Document where the SN 22.59 chip (top-right) maps to (a Nisaba sutta
      reference?)
