diff --git a/Controls/LeftPanel.xaml b/Controls/LeftPanel.xaml
index 6e5c1d3..3de42fd 100644
--- a/Controls/LeftPanel.xaml
+++ b/Controls/LeftPanel.xaml
@@ -463,9 +463,13 @@
+ Visibility="{Binding IsDevelopmentBuild, Converter={StaticResource BoolToVis}}">
+
+
+
diff --git a/Controls/PreviewPane.xaml b/Controls/PreviewPane.xaml
index 5399101..60a1e7e 100644
--- a/Controls/PreviewPane.xaml
+++ b/Controls/PreviewPane.xaml
@@ -138,6 +138,11 @@
+
+
+
+
diff --git a/Models/Source.cs b/Models/Source.cs
index 74940fa..0f717e1 100644
--- a/Models/Source.cs
+++ b/Models/Source.cs
@@ -143,9 +143,16 @@ public class Source : SceneElement
public ImageSource? ImageSource => _imageSource;
+ /// Types whose frame is produced at runtime rather than stored as an asset. The
+ /// scoreboard joined this list 2026-10-30 — without it the strip was rendered, published to
+ /// VideoImageSource, and never displayed (the same shape as the invisible-alert defect).
+ private bool IsFrameSource =>
+ Type is SourceType.ChatBox or SourceType.WebSource or SourceType.MediaSource
+ or SourceType.AlertBox or SourceType.Scoreboard;
+
public override ImageSource? DisplaySource => IsLiveCapture
? (VideoImageSource ?? _imageSource)
- : (Type is SourceType.ChatBox or SourceType.WebSource or SourceType.MediaSource or SourceType.AlertBox ? VideoImageSource : _imageSource);
+ : (IsFrameSource ? VideoImageSource : _imageSource);
public override bool IsImageSource => Type == SourceType.Image;
diff --git a/ytLive.Tests/ScoreboardLayerTests.cs b/ytLive.Tests/ScoreboardLayerTests.cs
index 7c2cfd3..b575caf 100644
--- a/ytLive.Tests/ScoreboardLayerTests.cs
+++ b/ytLive.Tests/ScoreboardLayerTests.cs
@@ -25,6 +25,12 @@ public class ScoreboardLayerTests
var resolver = SourceAssert.Text("ViewModels", "MainViewModel.cs");
Assert.Contains("Source { Type: SourceType.Scoreboard } => _scoreboardPresenter?.Frame", resolver);
+ // The PREVIEW must show the strip: its frame is a runtime frame-source and its Image needs
+ // the visibility trigger. Missing either made every property change look inert (2026-10-30).
+ var source = SourceAssert.Text("Models", "Source.cs");
+ Assert.Contains("or SourceType.AlertBox or SourceType.Scoreboard", source);
+ Assert.Contains("IsScoreboard", SourceAssert.Text("Controls", "PreviewPane.xaml"));
+
// Session lifecycle: every start clears the tallies.
var ops = SourceAssert.Text("ViewModels", "MainViewModel.Streaming.Operations.cs");
Assert.Contains("StartScoreboardSession();", ops);
diff --git a/ytLive.Tests/ScoreboardPropertiesTests.cs b/ytLive.Tests/ScoreboardPropertiesTests.cs
index c157a2e..07d124f 100644
--- a/ytLive.Tests/ScoreboardPropertiesTests.cs
+++ b/ytLive.Tests/ScoreboardPropertiesTests.cs
@@ -25,6 +25,10 @@ public class ScoreboardPropertiesTests
Assert.Contains("Sign in to YouTube to use the scoreboard.", block);
Assert.Contains("CanUseScoreboard, Converter={StaticResource InverseBoolToVis}", block);
+ // Dev-only labels are ORANGE, so a development affordance cannot pass for product.
+ Assert.Contains("Simulate (dev)", block);
+ Assert.Contains("Brush.Attention", block);
+
// The master switch sits in the same panel: off hides the strip and stops the polling.
Assert.Contains("ScoreboardEnabled", panel);