Usage
rows, oldest first, each with a speaker.side of Calltaker or Caller, its text, its timestamp and an optional translation.copy, every visible and accessibility string, typed LocalizedMessage.audioClips, when the call has a recording. Without it the block draws no player and no jump action.highlightTerm and navigationTarget, when the host runs a search or a keyword jump. languages, language and onLanguageChange, when the reader can pick the language.navigationTarget is a controlled request to move to a row, by id, source fragment or timestamp, and to mark text in it for two seconds. Give each request a new requestId; the block applies a target when it changes and never writes it back. onNavigate reports only the reader's own jump from a row to its moment in the audio.
Every row is personal data from a call. The block and its callbacks never log, store or send transcript text. Do not put it in an analytics event, a test id or an error message.
A translated row shows the original first and the translation under it, on both sides. The fields follow the source, which stores them the other way round by side: a caller's text is the original and translation.text its translation; a call-taker's translation.text is the original and text the translation. "Copy original" copies the real original on both sides.
copy.language and copy.audio are optional only in the type. Passing languages without copy.language, or audioClips without copy.audio, warns once in development and draws no language control, or no player and no audio actions. Pass languages with copy.language to draw the language control above the rows: a split button with one single-select menu, "Detect Language" first and then the languages. Detection is the default. The primary button runs it again, the menu picks a language, and onLanguageChange reports the choice (undefined means detection). While detection is in charge the button shows the detected language, or the detect label until there is one. A translated line shows the original first and the translation under it; the host decides which lines carry a translation, and the block shows none of its own.
liveGuidance and composer float as two separate elements under the rows, which scroll behind them and fade out as they do in ChatPanel: the LiveGuidance panel above, the chat input below with its own background. The scroll area ends where they begin, so a followed row is centered in what the reader sees. Once the reader is away from the last line, a round jump-to-latest button floats at the end of the rows; "Scroll to current" floats at their start while the audio plays and following is off. The panel collapses itself; the block only places it. Both are optional, and without them the transcript is read-only.
The block sets no skipInterval or timeDisplayMode default, as the legacy transcript did not. The legacy hosts pass:
Pass locale (a BCP 47 tag) so the audio bar formats and speaks time in the page language; without it AudioPlayer uses the runtime locale.
TimeDisplayMode comes from @prepared911/ui/audio-player.
Axon 911 DS/Blocks/CallTranscript/Composition renders the fixture call with both speakers, a translated line, a keyword highlight, and playhead follow with Scroll to current. Use it to review the block before wiring a host.
The ResizeWhilePlaying interaction story resizes the frame while audio plays and checks that the active row stays in view. The follow hook has a matching unit test.