Context. surface customer · domain atelier · route /atelier/video · auth signed-in · source apps/oshun/web/src/app/atelier/video/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; refreshed 2026-06-28 in apps/oshun/web/e2e/atelier-video-render-queue.spec.ts: route anchors, 12 storyboard panels, render queue, selected shot card, disabled-placeholder Cut action, read-only interaction contract, reduced-motion static state, offline-stable loaded markup, and 390 px no-overflow stack; refreshed 2026-06-30 in apps/oshun/web/e2e/atelier-motion-to-cinematheque.spec.ts for optional motion handoff query context and inbound panel rendering.
Purpose#
Video atelier — "a short film, storyboarded." Five-step workflow: treatment →
twelve-panel storyboard → shot list → render queue → final cut. Server-rendered
by apps/oshun/web/src/app/atelier/video/page.tsx via getAtelierVideo() →
<AtelierVideo data>.
Entry points#
- Atelier index (
/atelier) — third room card - Lilith index (
/lilith) — section VIII card 44 "XII · Cinematheque" - Motion handoff (
/atelier/motion) — "Open in Cinematheque" sends/atelier/video?from=motion&shot=sh-03&take=take-02&voice=foundry-take-03&light=forms-cream-northand renders the inbound motion context panel - Direct URL / bookmark — yes (signed-in)
Layout regions#
AtelierVideo (apps/oshun/web/src/components/lilith/atelier.tsx) renders
inside LWebShell with LCustomerNav active="explore".
The route root exposes data-atelier-video-page with
data-atelier-video-shot-count="12",
data-atelier-video-render-queue-count="3",
data-atelier-video-current-shot="sh 06", and
data-atelier-video-render-progress="64". Its body exposes
data-atelier-video-layout; below 980 px it stacks to one column and the 390 px
Playwright path verifies no horizontal overflow.
- Plate head (
LAPlateHead no="XII"):- kicker: "The atelier · cinematheque"
- title:
A short film, <em>storyboarded</em>. - right chips: "04 : 38 / 06 : 00", "9 of 12 shots", "Rendering · take 02" (accent)
- Three-column body (
230px 1fr 320px):- Left rail (
LAStepRail, current=3): five steps — "Treatment · written", "Storyboard · twelve panels", "Shot list · cameras, lenses", "Render · queue running", "Cut · final edit" - Center:
- Storyboard grid (
data-atelier-video-storyboard): 4×3 desktop grid of 12 16:9 panels with procedural SVG illustrations + per-panel state (renderedfor sh 01–05,rendering · 64%for sh 06,queuedoverlay for sh 07–10,draftedoverlay for sh 11–12); panel sh 06 exposesdata-atelier-video-shot-selected="true"and an accent border - Each panel footer shows
sh NN+ time fromdata.shotTimes+ the title fromdata.shotTitles - Render queue (
data-atelier-video-render-queue): three rows fromdata.renderQueue— sh 06 (rendering, 64%, eta 02:14, accent treatment), sh 07 (queued, eta 04:42), sh 08 (queued, eta 06:18)
- Storyboard grid (
- Right:
- Motion handoff (conditional): when the URL includes the exact motion
handoff query, a compact panel exposes
data-atelier-video-inbound-handoff,data-atelier-video-inbound-source="motion",data-atelier-video-inbound-state="url-context",data-atelier-video-inbound-shot="sh 03",data-atelier-video-inbound-take="take 02",data-atelier-video-inbound-voice="foundry · take 03", anddata-atelier-video-inbound-light="forms · cream-north" - Shot · sh 06 card (accent border): 16:9 SVG render +
T+00:48 · 24fpswatermark +LAProgress value=0.64 eta="02:14" LFieldrows: Camera "Locked, slow tilt up", Lens "35 mm · ƒ2.8", Frame rate "24 fps", Length "00:12", Light "North window, single source", Engine "Lilith Cine · v1.4", Sound "From foundry · 02:14 stem"- "Open in Cut · timeline" button (ghost, full)
- Motion handoff (conditional): when the URL includes the exact motion
handoff query, a compact panel exposes
- Left rail (
States#
- Loading boundary absence — no segment
loading.tsxexists underapps/oshun/web/src/app/atelier/video;getAtelierVideo()currently returns the synchronous fixture through the server component - Populated — fixture provides 12 shot titles/times + 3 render-queue
entries, asserted via
data-atelier-video-shot-count="12"anddata-atelier-video-render-queue-count="3" - Mid-render — sh 06 shows
rendering · 64%pill, selected state, and shot-card progress64 - Queued shots — sh 07/08/09/10 expose
data-atelier-video-shot-state="queued"and queued overlays; queue rows sh 07 and sh 08 expose queued state + eta - Drafted shots — sh 11/12 expose
data-atelier-video-shot-state="drafted"and drafted overlays - Error boundary absence — no route-local
error.tsxexists; failures fall through the inherited app boundary - Offline — after the route is loaded, browser offline mode keeps the static storyboard, render queue, selected shot, and action markup visible
- Reduced motion — progress visual is rendered as a static bar with no animation declared
- Mobile stack — 390 px viewport stacks rail → storyboard/queue → shot card/action with no horizontal overflow
- Inbound motion handoff — exact whitelisted query context renders the
Motion handoff panel; bare
/atelier/videoremains the static Cinematheque route without inbound context
Interactions#
Storyboard panels#
- Each panel (12, sh 01–sh 12) — read-only; tapping sh 10 does not select it, mutate the selected shot card, or navigate
- Highlighted panel (sh 06, accent border) — current selection exposed
by
data-atelier-video-shot-selected="true" - State pills/overlays — read-only; rendering/queued/drafted states are asserted from DOM attributes and visible labels
Render queue rows#
- sh 06 row (rendering, accent) — read-only with progress bar and
data-atelier-video-queue-progress="64" - sh 07 row (queued, eta 04:42)
- sh 08 row (queued, eta 06:18)
Right column#
- Motion handoff panel — read-only URL context from
/atelier/motion, with target shot, source take, inherited voice, and inherited light - Shot card — read-only metadata; SVG preview click does not change the selected shot or navigate
- "Open in Cut · timeline" button (ghost, full) — placeholder
LBtnwitharia-disabled="true",data-placeholder="true", tooltipNo handler wired — placeholder, and no navigation
Data & contracts#
- Reads:
getAtelierVideo()fromapps/oshun/web/src/lib/lilith-data/atelier-depth.ts— returnsAtelierVideoDatawithshotTimes,shotTitles,renderQueue(planned BFF at/atelier/plates/video) - Optional URL context:
from=motion&shot=sh-03&take=take-02&voice=foundry-take-03&light=forms-cream-northmaps toAtelierMotionHandoffDataand renders the inbound panel. Other values are ignored. - Writes: none in current static composition
- Realtime: render queue would update via subscription in production; none in current code
- Caching: server fetch
- Auth/role check: middleware enforces signed-in
Cross-references#
- Atelier index:
atelier.md - Sibling rooms:
atelier-image.md,atelier-audio.md,atelier-forms.md,atelier-motion.md - Upstream — shot sh 06 inherits sound "From foundry · 02:14 stem"
(
atelier-audio.md) - Upstream —
AtelierMotion"Compose · downstream" sends to Cinematheque (sh 03) with URL-scoped motion context - Component source:
apps/oshun/web/src/components/lilith/atelier.tsx(AtelierVideo) - Data:
apps/oshun/web/src/lib/lilith-data/atelier-depth.ts
E2E coverage#
Spec: apps/oshun/web/e2e/atelier-video-render-queue.spec.ts (4 tests)
Coverage depth: deep for the current static/read-only route contract:
fixture-derived storyboard rendering, coherent render queue state, selected shot
metadata, disabled-placeholder Cut action, read-only non-mutation, mobile
no-overflow, reduced-motion static state, and offline-stable loaded markup.
apps/oshun/web/e2e/atelier-motion-to-cinematheque.spec.ts also covers the
motion handoff URL and inbound panel. Remaining gaps are product gaps rather
than test gaps: no route-local loading/error boundaries, no live render-progress
subscription, no storyboard selection/reorder/edit flow, and no Cut timeline
target.
Open questions / known gaps#
- Confirm whether the render queue auto-updates progress or is static — current route is static; progress remains 64% in the loaded DOM
- Document the "Open in Cut · timeline" target — is
/cuta planned route or does it open a modal editor here? - Verify whether storyboard panels support drag-reordering (no affordance shown in code) — current panels are read-only visual cells