Files
LlamaCasty/Themes/Controls.xaml
T
gramps 987fddac24 TASK 63: the border-colour picker IS the app's own drop-down
The creator (2026-10-21), on Live -> Layers -> webcam -> Properties:

  "why does the drop down under the web cam properties not show the same style for
   the border color drop down list box?"

  "one of the first things we did was define branding. We established look-and-feel
   standards. And yet you keep ignoring these and I'm wondering why"

WHY IT WAS MISSED - the answer the creator is owed.
The TASK 58 sweep had already walked the whole app for un-themed controls and the
border picker STILL was not themed, because the sweep looked for control TYPES
(ComboBox / CheckBox / TextBox) carrying no theme style - and the border picker was
NONE of those. It was a "..." Button whose Click handler built a ContextMenu of
swatches in code. It was never in the sweep's scope, and PropertiesStyleTests.cs
(a type-based guard) could not see it either. A picker that LOOKS like a drop-down
is invisible to a type-based audit; the guard has to ask "is this the app's widget?".

WHAT CHANGED
- The picker is now the app's YtComboBox - the widget the Display and Font pickers
  wear - bound to the palette (SelectedElement.BorderColorOptions) with its selection
  bound by VALUE (SelectedItem -> BorderColorEntry), because WPF's SelectedValue
  matching is ordinal and the palette mixes #FFFFFF and #e94560.
- The closed box shows the swatch + the colour's NAME; the rows show swatch + hex +
  name (the rows the creator approved in TASK 60). A ComboBox cannot do that with one
  ItemTemplate - WPF copies it into the read-only SelectionBoxItemTemplate - so
  Helpers/ClosedBoxTemplateSelector.cs picks by the ContentPresenter's templated
  parent: the ComboBox for the closed box, the ComboBoxItem for a row. Verified
  against WPF with a throwaway probe, not assumed.
- The swatch is painted by the THEME (Helpers/HexToBrushConverter.cs, registered as
  HexToBrush) - the hand-painted SolidColorBrush(Color.FromRgb(...)) in the old
  click handler was the exact anti-pattern the theme forbids. The swatch also carries
  a 1px #2a3a5e border now, so black and dark swatches are visible on the dark menu
  (the follow-up TASK 60 left open).
- The hex field stays (60px, editable): a colour outside the palette can still be
  typed, and the drop-down then carries that hex as a NAMELESS entry ("no name" is the
  honest answer). The palette's name moved out of TASK 62's TextBlock into the
  drop-down's closed box.
- The hand-built menu, its ContextMenu/MenuItem/SolidColorBrush code and
  WebcamBorderColorPicker_Click are gone.

MODEL: SceneElement.BorderColorName -> BorderColorEntry (the palette entry for the
current hex, with its name; setting it writes the hex back) + BorderColorOptions (the
palette plus the custom entry), both raised when BorderColor changes.
BorderColorPalette gains EntryFor(hex) and OptionsFor(hex); NameOf delegates.

Guards: ytLive.Tests/BorderColorPickerTests.cs (the ONE test for this change - the
model, the panel, and the REAL widget: with the app's theme style and the panel's own
templates the closed box names the colour and the rows show the hex AND the name).
The TASK 60 guard (BorderColorPaletteTests) was updated because the mechanism it
asserted - a code-built menu - no longer exists; it now guards the new wiring (the
drop-down is bound to the palette and neither the panel nor the code-behind carries a
second list of colours).

Full suite: 435/435 passed, 0 warnings.
2026-10-21 23:09:11 -07:00

766 lines
40 KiB
XML

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Helpers="clr-namespace:ytLive.Helpers">
<!-- Base button style -->
<Style x:Key="YtButton" TargetType="Button">
<Setter Property="Background" Value="#e94560"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="16,8"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border x:Name="Bd" Background="{TemplateBinding Background}"
CornerRadius="4"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border x:Name="Glow" Background="White" CornerRadius="4" Opacity="0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Glow" Property="Opacity" Value="0.08"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Glow" Property="Opacity" Value="0.16"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.45"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="YtButtonSecondary" TargetType="Button" BasedOn="{StaticResource YtButton}">
<Setter Property="Background" Value="#16213e"/>
</Style>
<Style x:Key="IconButton" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="#d0d0d0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
CornerRadius="3"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#26ffffff"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- Eye icon: open when visible, slashed when hidden (source rows). App scope for
the same LeftPanel reason as EyeButton below. -->
<Style x:Key="EyeIconStyle" TargetType="Path">
<Setter Property="Data" Value="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Data" Value="M12,7c2.76,0 5,2.24 5,5 0,0.65 -0.13,1.26 -0.36,1.83l2.92,2.92c1.51,-1.26 2.7,-2.89 3.43,-4.75 -1.73,-4.39 -6,-7.5 -11,-7.5 -1.4,0 -2.74,0.25 -3.98,0.7l2.16,2.16C10.74,7.13 11.35,7 12,7zM2,4.27l2.28,2.28 0.46,0.46C3.08,8.3 1.78,10.02 1,12c1.73,4.39 6,7.5 11,7.5 1.55,0 3.03,-0.3 4.38,-0.84l0.42,0.42L19.73,22 21,20.73 3.27,3 2,4.27zM7.53,9.8l1.55,1.55c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.66 1.34,3 3,3 0.22,0 0.44,-0.03 0.65,-0.08l1.55,1.55c-0.67,0.33 -1.41,0.53 -2.2,0.53 -2.76,0 -5,-2.24 -5,-5 0,-0.79 0.2,-1.53 0.53,-2.2zM11.84,9.02l3.15,3.15 0.02,-0.16c0,-1.66 -1.34,-3 -3,-3l-0.17,0.01z"/>
</DataTrigger>
</Style.Triggers>
</Style>
<!-- Lives here (app scope), NOT in a window: Controls/LeftPanel.xaml references it
via StaticResource, and a UserControl cannot see window resources at parse
time (startup crash caught 2026-09-01). -->
<Style x:Key="EyeButton" TargetType="Button" BasedOn="{StaticResource IconButton}">
<Setter Property="ToolTip" Value="Hide Layer"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="ToolTip" Value="Show Layer"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="YtTextBox" TargetType="TextBox">
<Setter Property="Background" Value="#0f3460"/>
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="BorderBrush" Value="#2a3a5e"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="8,6"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="CaretBrush" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Bd" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4" Padding="{TemplateBinding Padding}">
<ScrollViewer x:Name="PART_ContentHost" Margin="0"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Bd" Property="BorderBrush" Value="#3d5076"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter TargetName="Bd" Property="BorderBrush" Value="#e94560"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="Opacity" Value="0.45"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Dense variant of YtTextBox for the properties panel (11px labels, tight
padding). Same template + colours as YtTextBox — only the metrics differ,
so the panel keeps its rhythm without hand-painting every field. -->
<Style x:Key="YtTextBoxCompact" TargetType="TextBox" BasedOn="{StaticResource YtTextBox}">
<Setter Property="FontSize" Value="11"/>
<Setter Property="Padding" Value="4,2"/>
<Setter Property="MinHeight" Value="22"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
<!-- Dark check box. The default WPF template is the light system one — it
sticks out of the dark panels, so every check box carries this style
(the guard test in ytLive.Tests/PropertiesStyleTests.cs enforces it). -->
<Style x:Key="YtCheckBox" TargetType="CheckBox">
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="Box" Grid.Column="0" Width="14" Height="14" CornerRadius="3"
Background="#0f3460" BorderBrush="#2a3a5e" BorderThickness="1"
VerticalAlignment="Center">
<Path x:Name="Tick" Data="M2.5,7.2 L5.8,10.5 L11.5,3.8"
Stroke="#ffffff" StrokeThickness="2"
StrokeStartLineCap="Round" StrokeEndLineCap="Round"
Visibility="Collapsed"/>
</Border>
<ContentPresenter Grid.Column="1" Margin="7,0,0,0" VerticalAlignment="Center"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Box" Property="BorderBrush" Value="#3d5076"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter TargetName="Box" Property="BorderBrush" Value="#e94560"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Box" Property="Background" Value="#e94560"/>
<Setter TargetName="Box" Property="BorderBrush" Value="#e94560"/>
<Setter TargetName="Tick" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.45"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="YtComboBox" TargetType="ComboBox">
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="Background" Value="#0f3460"/>
<Setter Property="BorderBrush" Value="#2a3a5e"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="8,6"/>
<Setter Property="MinHeight" Value="30"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ComboBoxItem">
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="Padding" Value="10,7"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border x:Name="Bd" Background="{TemplateBinding Background}"
CornerRadius="3" Margin="0,1" Padding="{TemplateBinding Padding}">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="Bd" Property="Background" Value="#26ffffff"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Bd" Property="Background" Value="#1a3a66"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<Border x:Name="Chrome" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4"/>
<ContentPresenter x:Name="ContentSite" IsHitTestVisible="False"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="Center"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>
<ToggleButton x:Name="ToggleButton" Focusable="False" ClickMode="Press"
Background="Transparent" BorderThickness="0"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Grid Background="Transparent">
<Path x:Name="Chevron" Data="M0,0 L4,4 L8,0" Stroke="#8a93a8"
StrokeThickness="1.5" HorizontalAlignment="Right"
VerticalAlignment="Center" Margin="0,0,10,0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Chevron" Property="Stroke" Value="#c8d0e0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.45"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<Popup x:Name="PART_Popup" Placement="Bottom" AllowsTransparency="True"
PopupAnimation="Fade" StaysOpen="False"
IsOpen="{TemplateBinding IsDropDownOpen}">
<Border Background="#16213e" BorderBrush="#2a3a5e" BorderThickness="1"
CornerRadius="5" Padding="2" Margin="0,4,0,0"
SnapsToDevicePixels="True">
<ScrollViewer MaxHeight="{TemplateBinding MaxDropDownHeight}"
ScrollViewer.CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Chrome" Property="Background" Value="#163a6b"/>
</Trigger>
<Trigger Property="IsDropDownOpen" Value="True">
<Setter TargetName="Chrome" Property="Background" Value="#163a6b"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Chrome" Property="Opacity" Value="0.45"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Thin dark scrollbar -->
<Style x:Key="YtScrollBarPageButton" TargetType="RepeatButton">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid Background="Transparent"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="YtScrollBarThumb" TargetType="Thumb">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Border x:Name="ThumbBd" Background="#2c3c5e" CornerRadius="4" Margin="2"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ThumbBd" Property="Background" Value="#3d5076"/>
</Trigger>
<Trigger Property="IsDragging" Value="True">
<Setter TargetName="ThumbBd" Property="Background" Value="#4a5f8a"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Width" Value="10"/>
<Setter Property="MinWidth" Value="10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<Grid Background="Transparent">
<Track x:Name="PART_Track" IsDirectionReversed="True">
<Track.DecreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageUpCommand}"
Style="{StaticResource YtScrollBarPageButton}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageDownCommand}"
Style="{StaticResource YtScrollBarPageButton}"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource YtScrollBarThumb}"/>
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="10"/>
<Setter Property="MinHeight" Value="10"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- Slider: slim and dimensional — gradient track, beveled fill, gloss-sphere
thumb. The filled side sits on a 5px pill aligned with the track; the
click target stays the full track height. -->
<LinearGradientBrush x:Key="YtSliderTrackBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#0f1b33" Offset="0"/>
<GradientStop Color="#283b60" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="YtSliderFillBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#4fe097" Offset="0"/>
<GradientStop Color="#2dbd7a" Offset="0.5"/>
<GradientStop Color="#1a9e63" Offset="1"/>
</LinearGradientBrush>
<RadialGradientBrush x:Key="YtSliderKnobBrush" Center="0.35,0.3" GradientOrigin="0.35,0.3">
<GradientStop Color="#ffffff" Offset="0"/>
<GradientStop Color="#d7f5e6" Offset="0.22"/>
<GradientStop Color="#3ed588" Offset="0.72"/>
<GradientStop Color="#137a4d" Offset="1"/>
</RadialGradientBrush>
<RadialGradientBrush x:Key="YtSliderKnobHoverBrush" Center="0.35,0.3" GradientOrigin="0.35,0.3">
<GradientStop Color="#ffffff" Offset="0"/>
<GradientStop Color="#e6faef" Offset="0.22"/>
<GradientStop Color="#57e9a1" Offset="0.72"/>
<GradientStop Color="#1b9a63" Offset="1"/>
</RadialGradientBrush>
<Style x:Key="YtSliderTrackButton" TargetType="RepeatButton">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Border Background="{x:Null}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="YtSliderFillButton" TargetType="RepeatButton">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid>
<Border Height="5" VerticalAlignment="Center"
Background="{StaticResource YtSliderFillBrush}"
BorderBrush="#0f7a4e" BorderThickness="1" CornerRadius="2.5"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="YtSliderThumb" TargetType="Thumb">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Grid Width="13" Height="13">
<Ellipse x:Name="Knob" Fill="{StaticResource YtSliderKnobBrush}"
Stroke="#0b1626" StrokeThickness="1">
<Ellipse.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="1" Opacity="0.55"/>
</Ellipse.Effect>
</Ellipse>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Knob" Property="Fill" Value="{StaticResource YtSliderKnobHoverBrush}"/>
</Trigger>
<Trigger Property="IsDragging" Value="True">
<Setter TargetName="Knob" Property="Fill" Value="{StaticResource YtSliderKnobHoverBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Slider">
<Setter Property="Height" Value="20"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="IsMoveToPointEnabled" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Slider">
<Grid VerticalAlignment="Center">
<Border Height="5" CornerRadius="2.5" VerticalAlignment="Center"
Background="{StaticResource YtSliderTrackBrush}"
BorderBrush="#0a1424" BorderThickness="1"/>
<Track x:Name="PART_Track" Height="18">
<Track.DecreaseRepeatButton>
<RepeatButton Command="{x:Static Slider.DecreaseLarge}"
Style="{StaticResource YtSliderFillButton}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static Slider.IncreaseLarge}"
Style="{StaticResource YtSliderTrackButton}"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource YtSliderThumb}"/>
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Dark tooltip -->
<Style TargetType="ToolTip">
<Setter Property="Background" Value="#1a1a2e"/>
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="BorderBrush" Value="#2a3a5e"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="8,6"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4" Padding="{TemplateBinding Padding}">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" TextWrapping="Wrap" MaxWidth="320"
Foreground="#e0e0e0" FontSize="12"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Dark context menu -->
<Style TargetType="ContextMenu">
<Setter Property="Background" Value="#16213e"/>
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="BorderBrush" Value="#2a3a5e"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="5" Padding="{TemplateBinding Padding}">
<Grid IsSharedSizeScope="True">
<ItemsPresenter/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="MenuItem">
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="10,6"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Grid x:Name="Grid" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto"
SharedSizeGroup="MenuItemIconColumnGroup"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="14"/>
</Grid.ColumnDefinitions>
<Border x:Name="Bd" Grid.ColumnSpan="3"
Background="{TemplateBinding Background}"
CornerRadius="3" Margin="0,1"/>
<TextBlock x:Name="CheckGlyph" Grid.Column="0" Text="&#x2713;"
Margin="4,0,6,0" HorizontalAlignment="Center"
VerticalAlignment="Center" Visibility="Collapsed"/>
<ContentPresenter x:Name="Content" Grid.Column="1"
ContentSource="Header"
Margin="{TemplateBinding Padding}"
VerticalAlignment="Center"
HorizontalAlignment="Left"/>
<TextBlock x:Name="Arrow" Grid.Column="2" Text="&#x203A;"
Margin="6,0,0,0" HorizontalAlignment="Center"
VerticalAlignment="Center" Visibility="Collapsed"/>
<Popup x:Name="PART_Popup" Placement="Right"
HorizontalOffset="-1" VerticalOffset="-1"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
Focusable="False">
<Border Background="#16213e" BorderBrush="#2a3a5e"
BorderThickness="1" CornerRadius="5" Padding="3">
<Grid IsSharedSizeScope="True">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</Grid>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="Bd" Property="Background" Value="#26ffffff"/>
</Trigger>
<Trigger Property="IsSubmenuOpen" Value="True">
<Setter TargetName="Bd" Property="Background" Value="#26ffffff"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="CheckGlyph" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.45"/>
</Trigger>
<DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource TemplatedParent}}"
Value="True">
<Setter TargetName="Arrow" Property="Visibility" Value="Visible"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Menu separators render as standalone Separator controls -->
<Style TargetType="Separator">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Separator">
<Border Height="1" Background="#2a3a5e" Margin="8,4"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Dark list item (used by all list boxes) -->
<Style x:Key="YtListBoxItem" TargetType="ListBoxItem">
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="Padding" Value="4,2"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Border x:Name="Accent" Width="3" HorizontalAlignment="Left" CornerRadius="1"
Background="#e94560" Margin="0,2" Opacity="0"
VerticalAlignment="Stretch"/>
<Border x:Name="Bd" Background="{TemplateBinding Background}"
CornerRadius="3" Padding="{TemplateBinding Padding}" Margin="0,1">
<ContentPresenter VerticalAlignment="Center"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Bd" Property="Background" Value="#22ffffff"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Bd" Property="Background" Value="#1a3a66"/>
<Setter TargetName="Accent" Property="Opacity" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="YtLabel" TargetType="TextBlock">
<Setter Property="Foreground" Value="#a0a0b0"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<Style x:Key="SectionHeader" TargetType="TextBlock">
<Setter Property="Foreground" Value="#e0e0e0"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Margin" Value="0,0,0,8"/>
</Style>
<Style x:Key="SubHeader" TargetType="TextBlock">
<Setter Property="Foreground" Value="#a0a0b0"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Margin" Value="4,0,0,4"/>
</Style>
<!-- Top-bar status sign label (REC / ON-AIR): one definition so the two signs can't drift -->
<Style x:Key="StatusSignText" TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding RecTextBrush}"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="8,0,0,0"/>
</Style>
<!-- Sliding pill toggle: ON = green, OFF = red (#ef4444) -->
<Style x:Key="PillToggle" TargetType="ToggleButton">
<Setter Property="Width" Value="36"/>
<Setter Property="Height" Value="18"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" Value="#ef4444"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Border x:Name="Track" Background="{TemplateBinding Background}"
CornerRadius="9" SnapsToDevicePixels="True">
<Ellipse x:Name="Thumb" Width="12" Height="12" Fill="White"
HorizontalAlignment="Left" Margin="3,0,0,0">
<Ellipse.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="1" Opacity="0.35"/>
</Ellipse.Effect>
<Ellipse.RenderTransform>
<TranslateTransform x:Name="ThumbTransform" X="0"/>
</Ellipse.RenderTransform>
</Ellipse>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Track" Property="Background" Value="#22c55e"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ThumbTransform"
Storyboard.TargetProperty="X"
To="18" Duration="0:0:0.15">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ThumbTransform"
Storyboard.TargetProperty="X"
To="0" Duration="0:0:0.15">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Top-bar mode switch segments (top bar redesign): one two-position REC/ON-AIR
switch replaces the old pill pair — one binary decision, one world rendered.
The selected segment fills app-red and its label goes white. -->
<Style x:Key="SegmentToggle" TargetType="ToggleButton">
<Setter Property="Padding" Value="14,5"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="Seg" Background="Transparent" CornerRadius="3"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Seg" Property="Background" Value="#e94560"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SegmentLabel" TargetType="TextBlock">
<Setter Property="Foreground" Value="#a0a0b0"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType=ToggleButton}}"
Value="True">
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
<!-- Value-to-visibility converters, promoted from MainWindow.Window.Resources
so extracted UserControls can resolve them (AGENTS: controls must not
reach into a window's own resources; they share the app-level theme). -->
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
<Helpers:InverseBoolToVisibilityConverter x:Key="InverseBoolToVis"/>
<Helpers:NotNullToVisibilityConverter x:Key="NotNullToVis"/>
<Helpers:NullToVisibilityConverter x:Key="NullToVis"/>
<Helpers:HiddenBoolToVisibilityConverter x:Key="HiddenBoolToVis"/>
<Helpers:EnumToBoolConverter x:Key="EnumToBool"/>
<Helpers:AllTrueToVisibilityConverter x:Key="AllTrueToVis"/>
<Helpers:HexToBrushConverter x:Key="HexToBrush"/>
</ResourceDictionary>