ui(properties): one typography hierarchy, pill switches, and tokens instead of hex
Creator directive 2026-11-01: the properties panels had 14 hand-rolled heading styles, 37 hand-rolled labels, four literal grey hex values, and 14 square checkboxes. - PropertyHeader / PropertySubHeader / PropertyFieldLabel / PropertyHint in Themes/Controls.xaml now carry the whole hierarchy: category bright and 11px, labels and hints dim, size and weight doing the level. Colour groups the panel — bright for what you edit, dim for its labels and help — and no new palette entry was needed; DESIGN.md stays the only colour source. - Every checkbox in the panel is a pill switch (PropertyPillCheck, 32x16 animated thumb). IsChecked semantics unchanged, so no binding moved. - Literal #888/#666/#555 became OnSurfaceVariant / OnSurfaceDisabled. - 13 headings, 2 sub-headers and 31 in-row labels now reference a style instead of repeating colour + size + alignment inline. Controls audited for backing: every Button/Slider/ComboBox/CheckBox/ToggleButton/TextBox in the panel has a Command or Click, a Value binding, an ItemsSource or Selected*, IsChecked, or Text — no dead controls. Release 0 warnings; typography and token tests pass.
This commit is contained in:
+64
-69
@@ -277,7 +277,7 @@
|
||||
</ListBox.ItemTemplate>
|
||||
</Helpers:FocusPreservingListBox>
|
||||
|
||||
<TextBlock Grid.Row="2" Text="No layers yet" Foreground="#555" FontSize="12"
|
||||
<TextBlock Grid.Row="2" Text="No layers yet" Foreground="{StaticResource Brush.OnSurfaceDisabled}" FontSize="12"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
Visibility="{Binding ShowSourcesEmptyHint, Converter={StaticResource BoolToVis}}"/>
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
is not offered in the vertical Chat layout, so that option
|
||||
is not even shown there (CanToggleClipShape). -->
|
||||
<StackPanel Visibility="{Binding IsWebcamSelected, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock Text="Shape" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,4"/>
|
||||
<TextBlock Text="Shape" Style="{StaticResource PropertyHeader}"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="10,0,0,4">
|
||||
<Button Content="{Binding SelectedElement.MirrorButtonText}"
|
||||
Style="{StaticResource YtButtonSecondary}" Padding="10,4"
|
||||
@@ -350,7 +350,7 @@
|
||||
strength slider, on the SAME 0–1 scale and default as the
|
||||
webcam's background blur — one radius curve, shared. -->
|
||||
<StackPanel Visibility="{Binding IsBlurSelected, Converter={StaticResource BoolToVis}}" Margin="0,0,0,8">
|
||||
<TextBlock Text="Blur" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,4"/>
|
||||
<TextBlock Text="Blur" Style="{StaticResource PropertyHeader}"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="10,0,0,6">
|
||||
<ToggleButton Style="{StaticResource SegmentToggle}" Padding="10,4"
|
||||
IsChecked="{Binding SelectedElement.IsRectShape, Mode=TwoWay}">
|
||||
@@ -362,7 +362,7 @@
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<DockPanel Margin="10,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Right" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Margin="8,0,0,0" Width="34">
|
||||
<TextBlock DockPanel.Dock="Right" Style="{StaticResource PropertyFieldLabel}" Margin="8,0,0,0" Width="34">
|
||||
<Run Text="{Binding SelectedElement.BlurAmount, Mode=OneWay, StringFormat={}{0:P0}}"/>
|
||||
</TextBlock>
|
||||
<Slider Minimum="0" Maximum="1" SmallChange="0.05" LargeChange="0.1"
|
||||
@@ -386,23 +386,23 @@
|
||||
above) so the webcam's border/background section stays the
|
||||
one panel bound to SelectedElement.IsWebcam. -->
|
||||
<StackPanel Visibility="{Binding SelectedElement.IsDraggable, Converter={StaticResource BoolToVis}}" Margin="0,0,0,8">
|
||||
<TextBlock Text="Geometry" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,4"/>
|
||||
<TextBlock Text="Geometry" Style="{StaticResource PropertyHeader}"/>
|
||||
<!-- TASK 61: the four fields share ONE fixed width — wide enough
|
||||
for the largest geometry value (1920, plus a typed sign) and
|
||||
no wider, so Y/H no longer stretch to fill the row. -->
|
||||
<DockPanel Margin="10,0,0,4" LastChildFill="False">
|
||||
<TextBlock DockPanel.Dock="Left" Text="X" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="16"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="X" Style="{StaticResource PropertyFieldLabel}" Width="16"/>
|
||||
<TextBox Text="{Binding SelectedElement.X, UpdateSourceTrigger=PropertyChanged, StringFormat=F0}"
|
||||
Style="{StaticResource YtTextBoxCompact}" Width="44"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text=" Y" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="20" Margin="8,0,0,0"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text=" Y" Style="{StaticResource PropertyFieldLabel}" Width="20" Margin="8,0,0,0"/>
|
||||
<TextBox Text="{Binding SelectedElement.Y, UpdateSourceTrigger=PropertyChanged, StringFormat=F0}"
|
||||
Style="{StaticResource YtTextBoxCompact}" Width="44"/>
|
||||
</DockPanel>
|
||||
<DockPanel Margin="10,0,0,4" LastChildFill="False">
|
||||
<TextBlock DockPanel.Dock="Left" Text="W" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="16"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="W" Style="{StaticResource PropertyFieldLabel}" Width="16"/>
|
||||
<TextBox Text="{Binding SelectedElement.Width, UpdateSourceTrigger=PropertyChanged, StringFormat=F0}"
|
||||
Style="{StaticResource YtTextBoxCompact}" Width="44"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text=" H" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="20" Margin="8,0,0,0"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text=" H" Style="{StaticResource PropertyFieldLabel}" Width="20" Margin="8,0,0,0"/>
|
||||
<TextBox Text="{Binding SelectedElement.Height, UpdateSourceTrigger=PropertyChanged, StringFormat=F0}"
|
||||
Style="{StaticResource YtTextBoxCompact}" Width="44"/>
|
||||
</DockPanel>
|
||||
@@ -410,7 +410,7 @@
|
||||
|
||||
<!-- Webcam border config -->
|
||||
<StackPanel Visibility="{Binding SelectedElement.IsWebcam, Converter={StaticResource BoolToVis}}" Margin="0,0,0,8">
|
||||
<TextBlock Text="Border Color" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,2"/>
|
||||
<TextBlock Text="Border Color" Style="{StaticResource PropertyHeader}"/>
|
||||
<!-- TASK 63: the border colour is picked with the app's OWN
|
||||
drop-down (YtComboBox) — the same widget the Display
|
||||
and Font pickers use — not a hand-rolled menu. The hex
|
||||
@@ -429,7 +429,7 @@
|
||||
ToolTip="Border colour" MinWidth="100"
|
||||
Margin="8,0,0,0" VerticalAlignment="Center"/>
|
||||
</DockPanel>
|
||||
<TextBlock Text="Border Thickness" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,2"/>
|
||||
<TextBlock Text="Border Thickness" Style="{StaticResource PropertyHeader}"/>
|
||||
<DockPanel Margin="10,0,0,6">
|
||||
<Button DockPanel.Dock="Right" Style="{StaticResource IconButton}"
|
||||
Width="22" Height="22" Margin="4,0,0,0"
|
||||
@@ -446,17 +446,16 @@
|
||||
<Slider DockPanel.Dock="Left" Width="120" Minimum="0" Maximum="10"
|
||||
Value="{Binding SelectedElement.BorderWidth, Mode=TwoWay}"
|
||||
VerticalAlignment="Center" TickFrequency="1" IsSnapToTickEnabled="True"/>
|
||||
<TextBlock Text="{Binding SelectedElement.BorderWidth}" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11"
|
||||
VerticalAlignment="Center" Margin="8,0,0,0" Width="20"/>
|
||||
<TextBlock Text="{Binding SelectedElement.BorderWidth}" Style="{StaticResource PropertyFieldLabel}" Margin="8,0,0,0" Width="20"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- TASK 51: background effects — two pills acting as radio buttons
|
||||
(one on turns the other off; both off = no effect). TASK 59:
|
||||
the pills are indented under the Background title, and the
|
||||
strength row one level deeper, under Blur. -->
|
||||
<TextBlock Text="Background" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,6"/>
|
||||
<TextBlock Text="Background" Style="{StaticResource PropertyHeader}"/>
|
||||
<DockPanel Margin="10,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Remove" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="84"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Remove" Style="{StaticResource PropertyFieldLabel}" Width="84"/>
|
||||
<ToggleButton x:Name="RemoveBackgroundPill" Style="{StaticResource PillToggle}"
|
||||
IsChecked="{Binding SelectedElement.RemoveBackground, Mode=TwoWay}"
|
||||
AutomationProperties.Name="Remove background"
|
||||
@@ -464,7 +463,7 @@
|
||||
HorizontalAlignment="Left"/>
|
||||
</DockPanel>
|
||||
<DockPanel Margin="10,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Blur" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="84"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Blur" Style="{StaticResource PropertyFieldLabel}" Width="84"/>
|
||||
<ToggleButton x:Name="BlurBackgroundPill" Style="{StaticResource PillToggle}"
|
||||
IsChecked="{Binding SelectedElement.BlurBackground, Mode=TwoWay}"
|
||||
AutomationProperties.Name="Blur background"
|
||||
@@ -473,9 +472,9 @@
|
||||
</DockPanel>
|
||||
<DockPanel Margin="20,0,0,6"
|
||||
Visibility="{Binding SelectedElement.HasBackgroundEffect, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Strength" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="84"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Strength" Style="{StaticResource PropertyFieldLabel}" Width="84"/>
|
||||
<TextBlock DockPanel.Dock="Right" Text="{Binding SelectedElement.BackgroundStrength, StringFormat={}{0:P0}}"
|
||||
Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Margin="8,0,0,0" Width="34"/>
|
||||
Style="{StaticResource PropertyFieldLabel}" Margin="8,0,0,0" Width="34"/>
|
||||
<Slider x:Name="BackgroundStrengthSlider" Minimum="0" Maximum="1"
|
||||
Value="{Binding SelectedElement.BackgroundStrength, Mode=TwoWay}"
|
||||
TickFrequency="0.05" IsSnapToTickEnabled="True" VerticalAlignment="Center"
|
||||
@@ -496,7 +495,7 @@
|
||||
Visibility="{Binding CanUseScoreboard, Converter={StaticResource InverseBoolToVis}}"/>
|
||||
<!-- DEBUG builds only: prove the strip in the preview before a real
|
||||
stream. Absent from Release, not merely hidden by a flag. -->
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Margin="0,0,0,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Margin="0,0,0,4"
|
||||
IsChecked="{Binding ScoreboardSimulate, Mode=TwoWay}"
|
||||
ToolTip="Push sample events so the strip appears in the preview."
|
||||
Visibility="{Binding IsDevelopmentBuild, Converter={StaticResource BoolToVis}}">
|
||||
@@ -504,11 +503,10 @@
|
||||
be mistaken for product. -->
|
||||
<TextBlock Text="Simulate (dev)" Foreground="{StaticResource Brush.Attention}" FontSize="12"/>
|
||||
</CheckBox>
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Margin="0,0,0,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Margin="0,0,0,4"
|
||||
Content="Show the scoreboard" IsChecked="{Binding ScoreboardEnabled, Mode=TwoWay}"
|
||||
ToolTip="Off hides the strip in every scene AND stops the channel polling."/>
|
||||
<TextBlock Text="Edge (socials take the other)" Foreground="{StaticResource Brush.OnSurfaceVariant}"
|
||||
FontSize="11" Margin="10,0,0,2"/>
|
||||
<TextBlock Text="Edge (socials take the other)" Style="{StaticResource PropertySubHeader}"/>
|
||||
<ComboBox Style="{StaticResource YtComboBox}" Height="24" FontSize="11" Margin="10,0,0,6"
|
||||
ItemsSource="{Binding ScoreboardEdgeOptions}"
|
||||
SelectedItem="{Binding ScoreboardEdge, Mode=TwoWay}"/>
|
||||
@@ -523,32 +521,32 @@
|
||||
Value="{Binding ScoreboardScrollSpeed, Mode=TwoWay}" VerticalAlignment="Center"/>
|
||||
</DockPanel>
|
||||
|
||||
<TextBlock Text="Facts" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,4"/>
|
||||
<TextBlock Text="Facts" Style="{StaticResource PropertyHeader}"/>
|
||||
<WrapPanel Margin="10,0,0,0">
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="Subscribers" Margin="0,0,10,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Subscribers" Margin="0,0,10,4"
|
||||
IsChecked="{Binding ScoreboardShowSubscribers, Mode=TwoWay}"/>
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="Watch hours" Margin="0,0,10,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Watch hours" Margin="0,0,10,4"
|
||||
IsChecked="{Binding ScoreboardShowWatchHours, Mode=TwoWay}"/>
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="Super Chats" Margin="0,0,10,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Super Chats" Margin="0,0,10,4"
|
||||
IsChecked="{Binding ScoreboardShowSuperChats, Mode=TwoWay}"/>
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="New members" Margin="0,0,10,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="New members" Margin="0,0,10,4"
|
||||
IsChecked="{Binding ScoreboardShowNewMembers, Mode=TwoWay}"/>
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="Milestones" Margin="0,0,10,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Milestones" Margin="0,0,10,4"
|
||||
IsChecked="{Binding ScoreboardShowMilestones, Mode=TwoWay}"/>
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="Last member" Margin="0,0,10,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Last member" Margin="0,0,10,4"
|
||||
IsChecked="{Binding ScoreboardShowLastMember, Mode=TwoWay}"/>
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="Last Super Chat" Margin="0,0,10,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Last Super Chat" Margin="0,0,10,4"
|
||||
IsChecked="{Binding ScoreboardShowLastSuperChat, Mode=TwoWay}"/>
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="Last gift" Margin="0,0,10,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Last gift" Margin="0,0,10,4"
|
||||
IsChecked="{Binding ScoreboardShowLastGift, Mode=TwoWay}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<TextBlock Text="Text colour" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" Margin="10,6,0,2"/>
|
||||
<TextBlock Text="Text colour" Style="{StaticResource PropertySubHeader}"/>
|
||||
<ComboBox Style="{StaticResource YtComboBox}" Height="24" FontSize="11" Margin="10,0,0,6"
|
||||
ItemsSource="{Binding ScoreboardColorOptions}" DisplayMemberPath="Name"
|
||||
SelectedValuePath="Hex" SelectedValue="{Binding ScoreboardTextColor, Mode=TwoWay}"/>
|
||||
|
||||
<CheckBox Style="{StaticResource YtCheckBox}" Content="Background" Margin="10,0,0,4"
|
||||
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Background" Margin="10,0,0,4"
|
||||
IsChecked="{Binding ScoreboardBackgroundEnabled, Mode=TwoWay}"/>
|
||||
<ComboBox Style="{StaticResource YtComboBox}" Height="24" FontSize="11" Margin="10,0,0,6"
|
||||
ItemsSource="{Binding ScoreboardColorOptions}" DisplayMemberPath="Name"
|
||||
@@ -593,27 +591,26 @@
|
||||
<Slider DockPanel.Dock="Left" Width="120" Minimum="1" Maximum="60"
|
||||
Value="{Binding SelectedElement.TimerMinutes, Mode=TwoWay}"
|
||||
VerticalAlignment="Center" TickFrequency="1" IsSnapToTickEnabled="True"/>
|
||||
<TextBlock Text="{Binding SelectedElement.TimerMinutes}" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11"
|
||||
VerticalAlignment="Center" Margin="8,0,0,0" Width="20"/>
|
||||
<TextBlock Text="{Binding SelectedElement.TimerMinutes}" Style="{StaticResource PropertyFieldLabel}" Margin="8,0,0,0" Width="20"/>
|
||||
</DockPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Web source config -->
|
||||
<StackPanel Visibility="{Binding SelectedElement.IsWebSource, Converter={StaticResource BoolToVis}}" Margin="0,0,0,8">
|
||||
<TextBlock Text="Geometry" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,4"/>
|
||||
<TextBlock Text="Geometry" Style="{StaticResource PropertyHeader}"/>
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="X" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="16"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="X" Style="{StaticResource PropertyFieldLabel}" Width="16"/>
|
||||
<TextBox Text="{Binding SelectedElement.X, UpdateSourceTrigger=PropertyChanged, StringFormat=F0}"
|
||||
Style="{StaticResource YtTextBoxCompact}"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text=" Y" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="20" Margin="8,0,0,0"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text=" Y" Style="{StaticResource PropertyFieldLabel}" Width="20" Margin="8,0,0,0"/>
|
||||
<TextBox Text="{Binding SelectedElement.Y, UpdateSourceTrigger=PropertyChanged, StringFormat=F0}"
|
||||
Style="{StaticResource YtTextBoxCompact}"/>
|
||||
</DockPanel>
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="W" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="16"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="W" Style="{StaticResource PropertyFieldLabel}" Width="16"/>
|
||||
<TextBox Text="{Binding SelectedElement.Width, UpdateSourceTrigger=PropertyChanged, StringFormat=F0}"
|
||||
Style="{StaticResource YtTextBoxCompact}"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text=" H" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="20" Margin="8,0,0,0"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text=" H" Style="{StaticResource PropertyFieldLabel}" Width="20" Margin="8,0,0,0"/>
|
||||
<TextBox Text="{Binding SelectedElement.Height, UpdateSourceTrigger=PropertyChanged, StringFormat=F0}"
|
||||
Style="{StaticResource YtTextBoxCompact}"/>
|
||||
</DockPanel>
|
||||
@@ -639,10 +636,10 @@
|
||||
|
||||
<!-- Chat box config -->
|
||||
<StackPanel Visibility="{Binding SelectedElement.IsChatBox, Converter={StaticResource BoolToVis}}" Margin="0,0,0,8">
|
||||
<TextBlock Text="Chat Overlay" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,6"/>
|
||||
<TextBlock Text="Chat Overlay" Style="{StaticResource PropertyHeader}"/>
|
||||
|
||||
<!-- Border (same controls as the webcam's border) -->
|
||||
<TextBlock Text="Border Color" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,2"/>
|
||||
<TextBlock Text="Border Color" Style="{StaticResource PropertyHeader}"/>
|
||||
<DockPanel Margin="10,0,0,6">
|
||||
<TextBox DockPanel.Dock="Left"
|
||||
Text="{Binding SelectedElement.BorderColor, UpdateSourceTrigger=PropertyChanged}"
|
||||
@@ -656,26 +653,24 @@
|
||||
ToolTip="Border colour" MinWidth="100"
|
||||
Margin="8,0,0,0" VerticalAlignment="Center"/>
|
||||
</DockPanel>
|
||||
<TextBlock Text="Border Thickness" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,2"/>
|
||||
<TextBlock Text="Border Thickness" Style="{StaticResource PropertyHeader}"/>
|
||||
<DockPanel Margin="10,0,0,6">
|
||||
<Slider DockPanel.Dock="Left" Width="120" Minimum="0" Maximum="10"
|
||||
Value="{Binding SelectedElement.BorderWidth, Mode=TwoWay}"
|
||||
VerticalAlignment="Center" TickFrequency="1" IsSnapToTickEnabled="True"/>
|
||||
<TextBlock Text="{Binding SelectedElement.BorderWidth}" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11"
|
||||
VerticalAlignment="Center" Margin="8,0,0,0" Width="20"/>
|
||||
<TextBlock Text="{Binding SelectedElement.BorderWidth}" Style="{StaticResource PropertyFieldLabel}" Margin="8,0,0,0" Width="20"/>
|
||||
</DockPanel>
|
||||
<TextBlock Text="Border Opacity" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,2"/>
|
||||
<TextBlock Text="Border Opacity" Style="{StaticResource PropertyHeader}"/>
|
||||
<DockPanel Margin="10,0,0,8">
|
||||
<Slider DockPanel.Dock="Left" Width="120" Minimum="0" Maximum="1"
|
||||
Value="{Binding SelectedElement.BorderOpacity, Mode=TwoWay}"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding SelectedElement.BorderOpacity, StringFormat={}{0:P0}}" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11"
|
||||
VerticalAlignment="Center" Margin="8,0,0,0" Width="34"/>
|
||||
<TextBlock Text="{Binding SelectedElement.BorderOpacity, StringFormat={}{0:P0}}" Style="{StaticResource PropertyFieldLabel}" Margin="8,0,0,0" Width="34"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- Font Size -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Font Size" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Font Size" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<Slider x:Name="ChatFontSizeSlider" Width="120" Minimum="8" Maximum="72" TickFrequency="2" IsSnapToTickEnabled="True"
|
||||
Value="{Binding SelectedElement.ChatFontSize, Mode=TwoWay}"
|
||||
VerticalAlignment="Center"/>
|
||||
@@ -684,7 +679,7 @@
|
||||
|
||||
<!-- Font Family -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Font" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Font" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<ComboBox SelectedValue="{Binding SelectedElement.ChatFontFamily, Mode=TwoWay}"
|
||||
SelectedValuePath="Content"
|
||||
Style="{StaticResource YtComboBox}"
|
||||
@@ -700,28 +695,28 @@
|
||||
|
||||
<!-- Font Color -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Font Color" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Font Color" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<TextBox Text="{Binding SelectedElement.ChatFontColor, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource YtTextBoxCompact}" Width="80"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- Member Color -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Member" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Member" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<TextBox Text="{Binding SelectedElement.ChatMemberColor, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource YtTextBoxCompact}" Width="80"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- Super Chat Color -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Super Chat" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Super Chat" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<TextBox Text="{Binding SelectedElement.ChatSuperChatColor, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource YtTextBoxCompact}" Width="80"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- Max Messages -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Max Msgs" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Max Msgs" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<Slider x:Name="ChatMaxMsgsSlider" Width="120" Minimum="1" Maximum="20" TickFrequency="1" IsSnapToTickEnabled="True"
|
||||
Value="{Binding SelectedElement.ChatMaxMessages, Mode=TwoWay}"
|
||||
VerticalAlignment="Center"/>
|
||||
@@ -730,14 +725,14 @@
|
||||
|
||||
<!-- Background Color -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Background" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Background" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<TextBox Text="{Binding SelectedElement.ChatBackgroundColor, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource YtTextBoxCompact}" Width="80"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- Background Opacity -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Bg Opacity" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Bg Opacity" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<Slider x:Name="ChatBgOpacitySlider" Width="120" Minimum="0" Maximum="1"
|
||||
Value="{Binding SelectedElement.ChatBackgroundOpacity, Mode=TwoWay}"
|
||||
VerticalAlignment="Center"/>
|
||||
@@ -746,7 +741,7 @@
|
||||
|
||||
<!-- Fade After (seconds) -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Fade After" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="70"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Fade After" Style="{StaticResource PropertyFieldLabel}" Width="70"/>
|
||||
<Slider x:Name="ChatFadeSlider" Width="120" Minimum="0" Maximum="60" TickFrequency="5" IsSnapToTickEnabled="True"
|
||||
Value="{Binding SelectedElement.ChatFadeSeconds, Mode=TwoWay}"
|
||||
VerticalAlignment="Center"/>
|
||||
@@ -754,17 +749,17 @@
|
||||
</DockPanel>
|
||||
|
||||
<!-- Toggles -->
|
||||
<CheckBox Content="Show timestamps" Style="{StaticResource YtCheckBox}" Margin="0,4,0,2"
|
||||
<CheckBox Content="Show timestamps" Style="{StaticResource PropertyPillCheck}" Margin="0,4,0,2"
|
||||
IsChecked="{Binding SelectedElement.ChatShowTimestamps, Mode=TwoWay}"/>
|
||||
<CheckBox Content="Show badges" Style="{StaticResource YtCheckBox}" Margin="0,0,0,2"
|
||||
<CheckBox Content="Show badges" Style="{StaticResource PropertyPillCheck}" Margin="0,0,0,2"
|
||||
IsChecked="{Binding SelectedElement.ChatShowBadges, Mode=TwoWay}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Stream Alerts config -->
|
||||
<StackPanel Visibility="{Binding SelectedElement.IsAlertBox, Converter={StaticResource BoolToVis}}" Margin="0,0,0,8">
|
||||
<TextBlock Text="Stream Alerts" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,0,0,6"/>
|
||||
<TextBlock Text="Stream Alerts" Style="{StaticResource PropertyHeader}"/>
|
||||
<TextBlock Text="The built-in clip plays on every alert (Super Chat, membership…) unless a custom video is picked."
|
||||
Foreground="#888" FontSize="10" TextWrapping="Wrap" Margin="0,0,0,6"/>
|
||||
Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="10" TextWrapping="Wrap" Margin="0,0,0,6"/>
|
||||
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<!-- Test alert (creator ruling 2026-11-01): plays the clip this box
|
||||
@@ -774,7 +769,7 @@
|
||||
Style="{StaticResource YtButtonSecondary}"
|
||||
Padding="8,2" FontSize="11" VerticalAlignment="Center"
|
||||
ToolTip="Play the alert here, exactly as a viewer would trigger it"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Built-in video" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="84"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Built-in video" Style="{StaticResource PropertyFieldLabel}" Width="84"/>
|
||||
<ToggleButton Style="{StaticResource PillToggle}"
|
||||
IsChecked="{Binding SelectedElement.AlertUseDefaultVideo, Mode=TwoWay}"
|
||||
HorizontalAlignment="Left"/>
|
||||
@@ -797,7 +792,7 @@
|
||||
Style="{StaticResource YtTextBoxCompact}" IsReadOnly="True"
|
||||
Foreground="{StaticResource Brush.OnSurfaceVariant}" VerticalAlignment="Center"/>
|
||||
</DockPanel>
|
||||
<CheckBox Content="Loop the sound until the video ends" Style="{StaticResource YtCheckBox}" Margin="0,2,0,6"
|
||||
<CheckBox Content="Loop the sound until the video ends" Style="{StaticResource PropertyPillCheck}" Margin="0,2,0,6"
|
||||
IsChecked="{Binding SelectedElement.AlertAudioLoop, Mode=TwoWay}"
|
||||
IsEnabled="{Binding SelectedElement.HasAlertAudio}"/>
|
||||
|
||||
@@ -819,10 +814,10 @@
|
||||
CommandParameter="{Binding SelectedElement}" Style="{StaticResource YtButtonSecondary}"
|
||||
HorizontalAlignment="Left" Padding="8,2" Margin="0,0,4,0"/>
|
||||
<TextBlock Text="Custom clips are referenced from disk — never stored in the layout."
|
||||
Foreground="#888" FontSize="10" TextWrapping="Wrap" Margin="0,4,0,6"/>
|
||||
Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="10" TextWrapping="Wrap" Margin="0,4,0,6"/>
|
||||
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Message ticker" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="84"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Message ticker" Style="{StaticResource PropertyFieldLabel}" Width="84"/>
|
||||
<ToggleButton Style="{StaticResource PillToggle}"
|
||||
IsChecked="{Binding SelectedElement.AlertShowTicker, Mode=TwoWay}"
|
||||
HorizontalAlignment="Left"/>
|
||||
@@ -832,7 +827,7 @@
|
||||
solid (still). Inline items, not a bound ItemsSource —
|
||||
same shape as the chat Font selector above. -->
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Display" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="84"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Display" Style="{StaticResource PropertyFieldLabel}" Width="84"/>
|
||||
<ComboBox SelectedValue="{Binding SelectedElement.AlertDisplayMethod, Mode=TwoWay}"
|
||||
SelectedValuePath="Tag"
|
||||
Style="{StaticResource YtComboBox}"
|
||||
@@ -844,7 +839,7 @@
|
||||
</DockPanel>
|
||||
|
||||
<DockPanel Margin="0,0,0,4">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Volume" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Width="84"/>
|
||||
<TextBlock DockPanel.Dock="Left" Text="Volume" Style="{StaticResource PropertyFieldLabel}" Width="84"/>
|
||||
<Slider Width="120" Minimum="0" Maximum="1"
|
||||
Value="{Binding SelectedElement.AlertVideoVolume, Mode=TwoWay}"
|
||||
VerticalAlignment="Center"/>
|
||||
@@ -858,7 +853,7 @@
|
||||
<TextBlock Text="Background" Style="{StaticResource SubHeader}"/>
|
||||
<StackPanel Margin="4,0,0,0">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
|
||||
<TextBlock Text="Use default background:" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="Use default background:" Style="{StaticResource PropertyFieldLabel}"/>
|
||||
<ToggleButton Style="{StaticResource PillToggle}"
|
||||
IsChecked="{Binding SelectedElement.UseDefaultBackground, Mode=TwoWay}"
|
||||
Margin="8,0,0,0"/>
|
||||
@@ -900,7 +895,7 @@
|
||||
<TextBlock Text="Chat is inactive" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="13"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,4"/>
|
||||
<TextBlock Text="Chat becomes active once LlamaCasty is connected and streaming on YouTube."
|
||||
Foreground="#666" FontSize="11" TextWrapping="Wrap"
|
||||
Foreground="{StaticResource Brush.OnSurfaceDisabled}" FontSize="11" TextWrapping="Wrap"
|
||||
HorizontalAlignment="Center" TextAlignment="Center" MaxWidth="240"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
@@ -145,6 +145,105 @@
|
||||
<!-- 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). -->
|
||||
<!-- ═══ Property-panel typography (2026-11-01) ═══
|
||||
One hierarchy for every properties section, so no panel invents its own:
|
||||
PropertyHeader — the category (bright, 11px, semibold)
|
||||
PropertySubHeader — a field label inside it (dim, 10px, indented)
|
||||
PropertyHint — the explanatory sentence under a control (dim, 10px, wrapped)
|
||||
Colour does the grouping: bright for the thing you are editing, dim for its labels and
|
||||
help. No new palette entries; these are the existing OnSurface / OnSurfaceVariant tokens. -->
|
||||
<Style x:Key="PropertyHeader" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurface}"/>
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Margin" Value="0,0,0,6"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PropertySubHeader" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurfaceVariant}"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Margin" Value="10,6,0,3"/>
|
||||
</Style>
|
||||
|
||||
<!-- A field label that sits in a row with its control (DockPanel.Dock="Left", fixed Width).
|
||||
Same typography as PropertySubHeader, but vertically centred and marginless so the rows
|
||||
stay on a grid. -->
|
||||
<Style x:Key="PropertyFieldLabel" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurfaceVariant}"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PropertyHint" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurfaceVariant}"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
<Setter Property="Margin" Value="10,0,0,6"/>
|
||||
</Style>
|
||||
|
||||
<!-- Checkboxes are pill switches (creator ruling 2026-11-01): a 14px box in a properties panel
|
||||
reads as a form, and a switch reads as a setting. IsChecked semantics are untouched, so
|
||||
every existing binding still works. -->
|
||||
<Style x:Key="PropertyPillCheck" TargetType="CheckBox">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurface}"/>
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="CheckBox">
|
||||
<Grid Background="Transparent">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="Track" Grid.Column="0" Width="32" Height="16" CornerRadius="8"
|
||||
Background="{StaticResource Brush.SurfaceContainerHighest}"
|
||||
BorderBrush="{StaticResource Brush.Outline}" BorderThickness="1"
|
||||
VerticalAlignment="Center">
|
||||
<Ellipse x:Name="Thumb" Width="10" Height="10" Fill="{StaticResource Brush.OnSurfaceVariant}"
|
||||
HorizontalAlignment="Left" Margin="2,0,0,0">
|
||||
<Ellipse.RenderTransform>
|
||||
<TranslateTransform x:Name="ThumbShift" X="0"/>
|
||||
</Ellipse.RenderTransform>
|
||||
</Ellipse>
|
||||
</Border>
|
||||
<ContentPresenter Grid.Column="1" Margin="8,0,0,0" VerticalAlignment="Center"
|
||||
RecognizesAccessKey="True"/>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="Track" Property="Background" Value="{StaticResource Brush.Tertiary}"/>
|
||||
<Setter TargetName="Track" Property="BorderBrush" Value="{StaticResource Brush.Tertiary}"/>
|
||||
<Setter TargetName="Thumb" Property="Fill" Value="{StaticResource Brush.OnAccent}"/>
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="ThumbShift" Storyboard.TargetProperty="X"
|
||||
To="16" Duration="0:0:0.12"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="ThumbShift" Storyboard.TargetProperty="X"
|
||||
To="0" Duration="0:0:0.12"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurfaceDisabled}"/>
|
||||
<Setter TargetName="Track" Property="Opacity" Value="0.5"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="YtCheckBox" TargetType="CheckBox">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurface}"/>
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
|
||||
@@ -185,3 +185,14 @@ skip (would spam every launch). Still modal by design: SocialsDialog's slot-dele
|
||||
- The image lives in the asset table; the settings table keeps its asset id and file name
|
||||
(`BrandLogoAssetId` / `BrandLogoFileName`). Eye visibility is the layer's ordinary per-scene `IsVisible`.
|
||||
- Default placement: top-left (32,32), 240x120 master px.
|
||||
- **Properties panel typography (2026-11-01):** one hierarchy for every section, defined in
|
||||
`Themes/Controls.xaml` — `PropertyHeader` (category: 11px semibold, `Brush.OnSurface`, the
|
||||
brightest text), `PropertySubHeader` (a field label inside it: 10px semibold, indented 10,
|
||||
`OnSurfaceVariant`), `PropertyFieldLabel` (a label sharing a row with its control: same
|
||||
typography, vertically centred, no margin), `PropertyHint` (the explanatory sentence: 10px,
|
||||
wrapped, dim). Colour carries the grouping — bright for the thing being edited, dim for its
|
||||
labels and help — and no new palette entries were needed. ⛔ No literal hex in the panel: the
|
||||
four `#888`/`#666`/`#555` values that had crept in are now `OnSurfaceVariant` /
|
||||
`OnSurfaceDisabled`. ⛔ **Every checkbox in the properties panel is a pill switch**
|
||||
(`PropertyPillCheck`, 32×16 track with an animated thumb) — a 14px box reads as a form, a switch
|
||||
reads as a setting; `IsChecked` semantics are untouched so all bindings still work.
|
||||
|
||||
Reference in New Issue
Block a user