# Subtitle Properties Panel Design **Goal:** Turn the editor's right sidebar into a real subtitle properties panel that edits the selected subtitle's display settings, shows real speaker metadata, and can optionally apply style changes to all subtitles. ## Context The current editor already presents the right side as a properties area, but most of it is still static UI. The `Wife` and `Husband` labels are hard-coded, the text style controls only update a single top-level `textStyles` state object, and the preview overlay always renders with those shared settings instead of reading from the active subtitle. That makes the panel look like a subtitle control surface while behaving more like a mock. The user expectation is that this area should control subtitle presentation for the selected item and optionally propagate those style changes across the full subtitle list. ## Approaches Considered ### Option A: Keep a single global style object Continue storing one `textStyles` object in `EditorScreen` and wire the right panel to that object only. **Pros** - Smallest code change - Minimal test churn **Cons** - Does not match the "current subtitle properties" mental model - Makes "Apply to all subtitles" redundant - Prevents subtitle-level overrides later ### Option B: Store style state per subtitle with optional bulk apply Add a style object to each subtitle, derive the right panel from the active subtitle, and let bulk apply copy style changes to every subtitle. **Pros** - Matches the current UI language and user expectation - Keeps the implementation scoped to the existing editor screen - Leaves room for richer per-speaker or per-preset styling later **Cons** - Requires subtitle normalization when data is loaded - Slightly more state update logic in the editor ### Recommendation Use **Option B**. It gives the right sidebar a truthful interaction model without forcing a much larger style system redesign. ## Architecture ### Data Model Introduce a `SubtitleTextStyle` shape that extends the current style fields with the controls surfaced by the panel: - `fontFamily` - `fontSize` - `color` - `strokeColor` - `strokeWidth` - `alignment` - `isBold` - `isItalic` - `isUnderline` Each `Subtitle` will gain an optional `textStyle` field. When subtitle data is generated or loaded, the editor will normalize every subtitle to ensure a complete style object is present. ### Editor State `EditorScreen` will: 1. Keep a single source of truth in `subtitles` 2. Derive `activeSubtitle` from `activeSubtitleId` 3. Replace the old shared `textStyles` state with helper functions that update: - only the active subtitle - or every subtitle when "Apply to all subtitles" is enabled The checkbox will become real state instead of a static default value. ### Right Sidebar Behavior The properties panel will become data-driven: 1. Speaker badge/label will read from the active subtitle's speaker metadata 2. The text field will show the active subtitle's translated text as contextual reference instead of a hard-coded name 3. Controls will read and write the active subtitle's `textStyle` 4. The panel will show a friendly empty state if no subtitle is selected This keeps the right column focused on subtitle properties without introducing an unrelated metadata editor. ### Preview Behavior The video subtitle overlay will render the style of the subtitle currently visible at the playback position. This means: - editing the selected subtitle updates the preview immediately when that subtitle is active - bulk apply updates every visible subtitle style consistently Stroke rendering will be added via CSS `textShadow` so the preview reflects the new sidebar control. ## Interaction Details ### Size Presets Keep the existing "Normal / Large / Small" control, but wire it to concrete font sizes: - `Small` -> 20 - `Normal` -> 24 - `Large` -> 30 This matches the current UI affordance without adding a freeform number input yet. ### Apply To All When checked, any style change initiated from the right panel copies the changed style keys to all subtitles. It will not overwrite subtitle text, timing, voice, or speaker data. ### Speaker Information The top block will present the active subtitle's speaker identity: - badge uses the first letter of the speaker label - label shows `subtitle.speaker` - secondary read-only field shows the active subtitle text for context This keeps the section meaningful even if there is no separate speaker alias dataset yet. ## Error Handling - If no subtitles are loaded, the right panel stays disabled with helper text - If a subtitle lacks style data, normalization fills defaults before rendering controls - If the active subtitle disappears after regeneration, the editor selects the first subtitle as it already does today ## Testing Strategy ### Component Tests Add tests that verify: - the right panel reflects the active subtitle's speaker and style values - changing a style control updates only the selected subtitle when bulk apply is off - changing a style control updates every subtitle when bulk apply is on - the preview overlay renders the visible subtitle using its style values ### Type Safety Update shared types so exports and preview rendering both receive the richer subtitle style data without unsafe casts. ## Rollout Notes This design intentionally stays inside `EditorScreen` and current data structures. It does not add saved presets, per-speaker style inheritance, or backend persistence, which keeps the work focused on making the existing panel real and trustworthy.