---
path: /atelier/forms
surface: customer
domain: atelier
auth: signed-in
source: apps/oshun/web/src/app/atelier/forms/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 · XIII · Forms

## Purpose

3D atelier — "a form, plotted." Five-step workflow: reference → orthographic
wireframe → material → light → turntable. Server-rendered by
`apps/oshun/web/src/app/atelier/forms/page.tsx` via `getAtelierForms()` →
`<AtelierForms data>`.

## Entry points

- **Atelier index** (`/atelier`) — fourth room card
- **Lilith index** (`/lilith`) — section VIII card 45 "XIII · Forms"
- **Direct URL / bookmark** — yes (signed-in)

## Layout regions

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

- **Plate head** (`LAPlateHead no="XIII"`):
  - kicker: "The atelier · forms"
  - title: `A form, <em>plotted</em>.`
  - right chips: "Stone bench · v3", "Topology · 12.4 k tris", "Light study ·
    cream-north" (accent)
- **Three-column body** (`230px 1fr 320px`):
  - **Left rail** (`LAStepRail`, current=3): five steps — "Reference · plate
    gathered", "Wire · orthographic", "Material · stone, wax", "Light · single
    window", "Turntable · plate kept"
  - **Center**:
    - **Orthographic plate** (`Plate · orthographic study`): grid-paper
      background, three SVG views from `data.views` — TOP (`top · plan`), FRONT
      (`front · elevation`), SIDE (`side · section`); each labelled with
      `120 cm` dimension
    - **Perspective render** (`Perspective · single light`): 16:9 SVG with
      single window and bench rendering; footer reads
      `cam · 38 mm · ƒ4 · 1.4 m h / turntable · 24 frames · 360° / renderer · Lilith Form · v0.9`
    - **Turntable strip** (`Turntable · 24 frames`): 12-cell row of small SVG
      thumbnails (index 4 highlighted)
  - **Right**:
    - **Form · stone bench** card (accent border) with `LField` rows: Topology
      "12.4 k tris", Bounds "120 × 38 × 42 cm", UV "islands · 04 · packed",
      Material "Limestone, weathered", Roughness 0.62, Light "Single window,
      5500 K", Renderer "Lilith Form · v0.9", Seed "0x b3 · locked"
    - **`LRule`**
    - **Reference plates · 4** — 2×2 grid of `r.01 – r.04` thumbnail SVGs
    - **Action stack**: "Bake plate · usd" (primary, full), "Open in Stage ·
      rig" (ghost, full)

## States

- [ ] **Loading** — server component awaits `getAtelierForms()`; verify
      `loading.tsx`
- [ ] **Populated** — fixture provides 3 views (TOP / FRONT / SIDE)
- [ ] **Empty views** — fixture always has three; verify behaviour with empty
      array
- [ ] **Error** — verify error boundary
- [ ] **Offline** — static markup; renders offline
- [ ] **Reduced motion** — turntable is static frames (no rotation)

## Interactions

### Orthographic plate

- [ ] **Top view** (`TOP · top · plan`) — read-only
- [ ] **Front view** (`FRONT · front · elevation`) — read-only
- [ ] **Side view** (`SIDE · side · section`) — read-only with accent horizontal
      line near the top

### Perspective render

- [ ] **Render area** — verify whether tap zooms / pans (no handler in static
      composition)

### Turntable strip

- [ ] **Frame thumbnails** (12 tiles) — read-only; verify whether tapping a
      frame sets the perspective render to that rotation
- [ ] **Selected frame** (index 4) — accent treatment

### Right column

- [ ] **Form metadata fields** — read-only
- [ ] **Reference plate tiles** (4) — verify whether tapping a reference opens
      the source plate
- [ ] **"Bake plate · usd" button** (primary, full)
- [ ] **"Open in Stage · rig" button** (ghost, full)
  - Function: intended hand-off to the Motion atelier; verify whether the static
    composition wires an `href` or `onClick`

## Data & contracts

- **Reads**: `getAtelierForms()` from
  `apps/oshun/web/src/lib/lilith-data/atelier-depth.ts` — returns
  `AtelierFormsData` with `views` (planned BFF at `/atelier/plates/forms`)
- **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-audio.md`](./atelier-audio.md),
  [`atelier-video.md`](./atelier-video.md),
  [`atelier-motion.md`](./atelier-motion.md)
- Downstream — "Open in Stage · rig" routes to
  [`atelier-motion.md`](./atelier-motion.md); `AtelierMotion`'s "Compose ·
  downstream" panel cites "light (forms · cream-north)"
- Component source: `apps/oshun/web/src/components/lilith/atelier.tsx`
  (`AtelierForms`)
- Data: `apps/oshun/web/src/lib/lilith-data/atelier-depth.ts`

## Open questions / known gaps

- [ ] Confirm whether the turntable strip is interactive (rotation control) or
      static frames
- [ ] Document the "Bake plate · usd" target — does it download a USD file, open
      a modal, or hand off to a render queue?
- [ ] Verify that "Open in Stage · rig" navigates to `/atelier/motion` with the
      current form pre-loaded
