| # visualization Specification |
|
|
| ## Purpose |
|
|
| Present the 7-layer progressive translation as an interactive, toy-like |
| experience: a custom WebGL 3D card stack and a 2D parallel-sets view, served by |
| FastAPI (not Gradio, for the "Off-Brand" bonus), with per-layer audio playback. |
|
|
| > Ownership note: the frontend implementation under `static/*` is owned by a |
| > separate coding agent and MUST NOT be edited by others. This spec captures the |
| > intended behavior, not implementation details to change here. |
| |
| ## Requirements |
| |
| ### Requirement: Custom FastAPI-served frontend |
| |
| The visualization SHALL be a fully custom HTML/CSS/JS frontend served directly |
| by FastAPI (no default Gradio UI), to satisfy the "Off-Brand" bonus. |
| |
| #### Scenario: Frontend served from root |
| |
| - **WHEN** a user opens the app root URL |
| - **THEN** the custom frontend is served and static assets are available under |
| `/static` |
| |
| ### Requirement: 3D card stack and 2D parallel-sets views |
| |
| The frontend SHALL provide a WebGL (Three.js, vendored locally) 3D card-stack |
| view and a 2D parallel-sets view of the same seven layers. |
| |
| #### Scenario: Both views available |
| |
| - **WHEN** a translation result is rendered |
| - **THEN** the user can view it as a 3D card stack (original at back, final at |
| front) and as a 2D parallel-sets diagram |
| |
| ### Requirement: Source-to-target gradient colorization |
| |
| Phrase blocks SHALL be colorized along a purple (source) to cyan (target) |
| gradient, and adjacent-layer phrase blocks SHALL be connected by broad elevated |
| translucent ribbons. |
| |
| #### Scenario: Gradient and ribbons |
| |
| - **WHEN** layers and links are rendered |
| - **THEN** blocks are colored from purple (source) to cyan (target) and adjacent |
| layers are joined by translucent ribbons, with reordering shown as crossings |
| |
| ### Requirement: Interactive tracing and playback |
| |
| The frontend SHALL let the user hover to trace a single phrase across all |
| layers, play per-layer audio, play all layers in sequence, and request a random |
| example via a "Surprise me" button. |
| |
| #### Scenario: Hover trace |
| |
| - **WHEN** the user hovers over a phrase block |
| - **THEN** that phrase's path is highlighted across every layer |
| |
| #### Scenario: Audio playback |
| |
| - **WHEN** the user triggers playback on a layer or "play all" |
| - **THEN** the corresponding layer audio is played (one layer, or all in |
| sequence) |
| |
| #### Scenario: Surprise me |
| |
| - **WHEN** the user clicks "Surprise me" |
| - **THEN** a random curated example is loaded and translated |
| |