<Window x:Class="TeamsISO.App.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:TeamsISO.App.ViewModels"
        xmlns:conv="clr-namespace:TeamsISO.App.Converters"
        xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework"
        Title="TeamsISO"
        Icon="/Assets/teamsiso.ico"
        Height="780" Width="1280"
        MinHeight="640" MinWidth="1080"
        Background="{DynamicResource Wd.Canvas}"
        WindowStyle="None"
        ResizeMode="CanResize"
        UseLayoutRounding="True"
        TextOptions.TextFormattingMode="Ideal"
        TextOptions.TextRenderingMode="ClearType">

    <!--
        Chromeless window chrome — removes the standard Windows title bar so we can
        draw our own header that matches the Teams flush look. CaptionHeight=44 makes
        the top 44px of the window act as a drag region. ResizeBorderThickness=6
        keeps edge-resize working. UseAeroCaptionButtons=False disables the OS-drawn
        min/max/close (we draw our own).
    -->
    <shell:WindowChrome.WindowChrome>
        <shell:WindowChrome
            CaptionHeight="44"
            ResizeBorderThickness="6"
            CornerRadius="0"
            GlassFrameThickness="0"
            UseAeroCaptionButtons="False"/>
    </shell:WindowChrome.WindowChrome>

    <Window.Resources>
        <conv:BoolToVisibilityConverter x:Key="BoolToVis"/>
        <conv:BoolToVisibilityConverter x:Key="InvertBool"
                                        TrueValue="Collapsed"
                                        FalseValue="Visible"/>
        <conv:EnumDescriptionConverter x:Key="EnumDesc"/>
        <conv:InitialsConverter x:Key="Initials"/>
        <conv:CountToVisibilityConverter x:Key="CountToVis"/>
    </Window.Resources>

    <!--
        Window-scoped keyboard shortcuts. Bound to view-model commands where
        available; F1 routes to a code-behind handler that opens HelpWindow
        (the help dialog is a host concern, not a VM concern). Window-scoped
        means these only fire when TeamsISO is the foreground window — using
        RegisterHotKey for global shortcuts would be a v2 concern (operators
        rarely want a Stream Deck and a global hotkey for the same action).
    -->
    <Window.InputBindings>
        <KeyBinding Key="F1" Command="{Binding ShowHelpCommand}"/>
        <KeyBinding Key="M" Modifiers="Ctrl" Command="{Binding DropRecordingMarkerCommand}"/>
        <KeyBinding Key="S" Modifiers="Ctrl+Shift" Command="{Binding StopAllIsosCommand}"/>
        <KeyBinding Key="R" Modifiers="Ctrl" Command="{Binding RefreshDiscoveryCommand}"/>
        <!-- NumPad 1-9 toggles ISO for the Nth visible participant (sort + filter aware).
             Top-row digits 1-9 mirror this so laptop operators without a numpad still get them. -->
        <KeyBinding Key="NumPad1" Command="{Binding ToggleByIndexCommand}" CommandParameter="1"/>
        <KeyBinding Key="NumPad2" Command="{Binding ToggleByIndexCommand}" CommandParameter="2"/>
        <KeyBinding Key="NumPad3" Command="{Binding ToggleByIndexCommand}" CommandParameter="3"/>
        <KeyBinding Key="NumPad4" Command="{Binding ToggleByIndexCommand}" CommandParameter="4"/>
        <KeyBinding Key="NumPad5" Command="{Binding ToggleByIndexCommand}" CommandParameter="5"/>
        <KeyBinding Key="NumPad6" Command="{Binding ToggleByIndexCommand}" CommandParameter="6"/>
        <KeyBinding Key="NumPad7" Command="{Binding ToggleByIndexCommand}" CommandParameter="7"/>
        <KeyBinding Key="NumPad8" Command="{Binding ToggleByIndexCommand}" CommandParameter="8"/>
        <KeyBinding Key="NumPad9" Command="{Binding ToggleByIndexCommand}" CommandParameter="9"/>
        <KeyBinding Key="D1" Command="{Binding ToggleByIndexCommand}" CommandParameter="1"/>
        <KeyBinding Key="D2" Command="{Binding ToggleByIndexCommand}" CommandParameter="2"/>
        <KeyBinding Key="D3" Command="{Binding ToggleByIndexCommand}" CommandParameter="3"/>
        <KeyBinding Key="D4" Command="{Binding ToggleByIndexCommand}" CommandParameter="4"/>
        <KeyBinding Key="D5" Command="{Binding ToggleByIndexCommand}" CommandParameter="5"/>
        <KeyBinding Key="D6" Command="{Binding ToggleByIndexCommand}" CommandParameter="6"/>
        <KeyBinding Key="D7" Command="{Binding ToggleByIndexCommand}" CommandParameter="7"/>
        <KeyBinding Key="D8" Command="{Binding ToggleByIndexCommand}" CommandParameter="8"/>
        <KeyBinding Key="D9" Command="{Binding ToggleByIndexCommand}" CommandParameter="9"/>
    </Window.InputBindings>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="72"/>     <!-- Left rail -->
            <ColumnDefinition Width="*"/>      <!-- Main content -->
            <ColumnDefinition Width="380"/>    <!-- Settings panel -->
        </Grid.ColumnDefinitions>

        <!-- ════════════════════════════════════════════════════════════════
             LEFT RAIL (Teams-style nav)
             ════════════════════════════════════════════════════════════════ -->
        <Border Grid.Column="0"
                Background="{DynamicResource Wd.Rail}"
                BorderBrush="{DynamicResource Wd.Border}"
                BorderThickness="0,0,1,0">
            <DockPanel LastChildFill="False">

                <!-- Wild Dragon mark — real logo from wilddragon.net. Clickable: opens About.
                     Lives inside the chromeless title bar's drag region, so we opt into
                     hit-testing so clicks land on the button rather than starting a drag. -->
                <Button DockPanel.Dock="Top"
                        Style="{StaticResource Wd.Button.RailIcon}"
                        Width="48" Height="56"
                        Margin="0,12,0,4"
                        Click="OnAboutClick"
                        shell:WindowChrome.IsHitTestVisibleInChrome="True"
                        ToolTip="About TeamsISO">
                    <StackPanel>
                        <Image Source="/Assets/dragon-mark.png"
                               Width="32" Height="32"
                               HorizontalAlignment="Center"
                               RenderOptions.BitmapScalingMode="HighQuality"/>
                    </StackPanel>
                </Button>

                <TextBlock DockPanel.Dock="Top"
                           Text="Wild Dragon"
                           Style="{StaticResource Wd.Text.Caption}"
                           Foreground="{DynamicResource Wd.Accent.Cyan}"
                           HorizontalAlignment="Center"
                           FontSize="9"
                           Margin="0,0,0,12"/>

                <!-- Divider -->
                <Border DockPanel.Dock="Top"
                        Height="1"
                        Background="{DynamicResource Wd.Border}"
                        Margin="14,0,14,12"/>

                <!-- Nav: Participants (active) -->
                <Button DockPanel.Dock="Top"
                        Style="{StaticResource Wd.Button.RailIcon}"
                        ToolTip="Participants">
                    <Grid>
                        <Border Width="48" Height="48"
                                CornerRadius="8"
                                Background="{DynamicResource Wd.Accent.CyanMuted}"/>
                        <Path Data="M 8,17 C 8,13 12,11 14,11 C 16,11 20,13 20,17 M 14,5 C 16,5 17.5,6.5 17.5,8.5 C 17.5,10.5 16,12 14,12 C 12,12 10.5,10.5 10.5,8.5 C 10.5,6.5 12,5 14,5"
                              Stroke="{DynamicResource Wd.Accent.Cyan}"
                              StrokeThickness="1.6"
                              Fill="Transparent"
                              HorizontalAlignment="Center"
                              VerticalAlignment="Center"
                              Width="28" Height="22"
                              Stretch="Uniform"/>
                    </Grid>
                </Button>

                <!-- Nav: Launch Teams. Click = launch / surface; right-click = stop.
                     The previous "left-click toggles" behavior ambushed operators
                     who'd hidden Teams' windows via the eye toggle next door —
                     they'd hit Launch expecting Teams to come back and instead
                     get a "Close all Teams windows now?" dialog. Now click is
                     always idempotent-progressive (running but hidden → show;
                     not running → launch). Right-click for stop. -->
                <Button DockPanel.Dock="Top"
                        Style="{StaticResource Wd.Button.RailIcon}"
                        Click="OnLaunchTeamsClick"
                        MouseRightButtonUp="OnLaunchTeamsRightClick"
                        ToolTip="Launch Microsoft Teams (or surface its window). Right-click to stop Teams.">
                    <!-- Stylized 'video meeting' camera icon -->
                    <Path Data="M 4,8 L 16,8 L 16,16 L 4,16 Z M 16,11 L 22,8 L 22,16 L 16,13 Z"
                          Stroke="{DynamicResource Wd.Text.Secondary}"
                          StrokeThickness="1.6"
                          Fill="Transparent"
                          StrokeLineJoin="Round"
                          Width="22" Height="20"
                          Stretch="Uniform"/>
                </Button>

                <!-- Nav: Hide / Show Teams windows. Phase E.2 of the embedded-Teams roadmap.
                     Toggles every visible top-level Teams window between SW_HIDE and SW_SHOW
                     so the operator can keep TeamsISO foregrounded without alt-tabbing. -->
                <Button DockPanel.Dock="Top"
                        Style="{StaticResource Wd.Button.RailIcon}"
                        Click="OnToggleTeamsWindowClick"
                        ToolTip="Hide / show Microsoft Teams windows (keeps Teams running but moves it out of the way)">
                    <!-- Eye icon (open / closed handled by the click toggling Teams visibility, not the icon) -->
                    <Path Data="M 1,11 C 5,4 17,4 21,11 C 17,18 5,18 1,11 Z M 11,8 A 3,3 0 1 1 11,14 A 3,3 0 1 1 11,8 Z"
                          Stroke="{DynamicResource Wd.Text.Secondary}"
                          StrokeThickness="1.4"
                          Fill="Transparent"
                          Width="22" Height="22"
                          Stretch="Uniform"/>
                </Button>

                <!-- Nav: Settings (placeholder — opens panel on right; not toggled in this build) -->
                <Button DockPanel.Dock="Top"
                        Style="{StaticResource Wd.Button.RailIcon}"
                        ToolTip="Settings">
                    <Path Data="M 14,4 L 14,7 M 14,21 L 14,24 M 4,14 L 7,14 M 21,14 L 24,14 M 7.5,7.5 L 9.5,9.5 M 18.5,18.5 L 20.5,20.5 M 7.5,20.5 L 9.5,18.5 M 18.5,9.5 L 20.5,7.5 M 14,11 C 15.7,11 17,12.3 17,14 C 17,15.7 15.7,17 14,17 C 12.3,17 11,15.7 11,14 C 11,12.3 12.3,11 14,11"
                          Stroke="{DynamicResource Wd.Text.Secondary}"
                          StrokeThickness="1.5"
                          Fill="Transparent"
                          Width="22" Height="22"
                          Stretch="Uniform"/>
                </Button>

                <!-- Engine status indicator at bottom -->
                <Border DockPanel.Dock="Bottom"
                        Width="40" Height="40"
                        Margin="0,0,0,16"
                        HorizontalAlignment="Center"
                        Background="{DynamicResource Wd.Status.LiveBg}"
                        CornerRadius="20"
                        ToolTip="{Binding StatusText}">
                    <Ellipse Width="10" Height="10"
                             Fill="{DynamicResource Wd.Status.Live}"
                             HorizontalAlignment="Center"
                             VerticalAlignment="Center"/>
                </Border>
            </DockPanel>
        </Border>

        <!-- ════════════════════════════════════════════════════════════════
             MAIN CONTENT
             ════════════════════════════════════════════════════════════════ -->
        <DockPanel Grid.Column="1" LastChildFill="True">

            <!-- Alert banner -->
            <Border DockPanel.Dock="Top"
                    Background="{DynamicResource Wd.Accent.CoralBg}"
                    BorderBrush="{DynamicResource Wd.Accent.Coral}"
                    BorderThickness="0,0,0,1"
                    Padding="24,12"
                    Visibility="{Binding AlertBanner.IsVisible, Converter={StaticResource BoolToVis}}">
                <DockPanel>
                    <Button DockPanel.Dock="Right"
                            Style="{StaticResource Wd.Button.Ghost}"
                            Content="Dismiss"
                            Command="{Binding AlertBanner.DismissCommand}"
                            Margin="12,0,0,0"/>
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                        <Ellipse Width="8" Height="8"
                                 Fill="{DynamicResource Wd.Accent.Coral}"
                                 VerticalAlignment="Center"
                                 Margin="0,0,12,0"/>
                        <TextBlock Text="{Binding AlertBanner.Message}"
                                   Style="{StaticResource Wd.Text.Body}"
                                   FontWeight="SemiBold"
                                   VerticalAlignment="Center"/>
                    </StackPanel>
                </DockPanel>
            </Border>

            <!-- Header strip -->
            <Border DockPanel.Dock="Top"
                    BorderBrush="{DynamicResource Wd.Border}"
                    BorderThickness="0,0,0,1"
                    Padding="32,20">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>

                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                        <TextBlock Text="TeamsISO"
                                   Style="{StaticResource Wd.Text.Title}"
                                   VerticalAlignment="Center"/>
                        <Border Style="{StaticResource Wd.Pill}"
                                Margin="14,0,0,0"
                                VerticalAlignment="Center">
                            <TextBlock Text="by Wild Dragon"
                                       Style="{StaticResource Wd.Text.Mono}"
                                       FontSize="11"
                                       Foreground="{DynamicResource Wd.Accent.Cyan}"/>
                        </Border>
                    </StackPanel>

                    <StackPanel Grid.Column="1"
                                Orientation="Horizontal"
                                VerticalAlignment="Center">
                        <Border Style="{StaticResource Wd.Pill}"
                                Background="{DynamicResource Wd.Status.LiveBg}"
                                VerticalAlignment="Center"
                                Margin="0,0,16,0">
                            <StackPanel Orientation="Horizontal">
                                <Ellipse Width="7" Height="7"
                                         Fill="{DynamicResource Wd.Status.Live}"
                                         VerticalAlignment="Center"/>
                                <TextBlock Text="{Binding StatusText}"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           Margin="8,0,0,0"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Border>

                        <!--
                            Custom window control buttons. WindowChrome.IsHitTestVisibleInChrome
                            tells the chrome that clicks here are real clicks, not drag-region
                            clicks, so the buttons fire instead of starting a window drag.
                        -->
                        <Button x:Name="MinimizeButton"
                                Style="{StaticResource Wd.Button.Caption}"
                                Click="OnMinimize"
                                shell:WindowChrome.IsHitTestVisibleInChrome="True"
                                ToolTip="Minimize">
                            <Path Data="M 0,5 L 10,5"
                                  Stroke="{DynamicResource Wd.Text.Primary}"
                                  StrokeThickness="1.2"
                                  Width="10" Height="10"
                                  Stretch="None"/>
                        </Button>
                        <Button x:Name="MaximizeButton"
                                Style="{StaticResource Wd.Button.Caption}"
                                Click="OnMaximizeRestore"
                                shell:WindowChrome.IsHitTestVisibleInChrome="True"
                                ToolTip="Maximize">
                            <Path x:Name="MaximizeIcon"
                                  Data="M 0,0 L 10,0 L 10,10 L 0,10 Z"
                                  Stroke="{DynamicResource Wd.Text.Primary}"
                                  StrokeThickness="1.2"
                                  Fill="Transparent"
                                  Width="10" Height="10"
                                  Stretch="None"/>
                        </Button>
                        <Button x:Name="CloseButton"
                                Style="{StaticResource Wd.Button.CaptionClose}"
                                Click="OnClose"
                                shell:WindowChrome.IsHitTestVisibleInChrome="True"
                                ToolTip="Close">
                            <Path Data="M 0,0 L 10,10 M 10,0 L 0,10"
                                  Stroke="{DynamicResource Wd.Text.Primary}"
                                  StrokeThickness="1.2"
                                  Width="10" Height="10"
                                  Stretch="None"/>
                        </Button>
                    </StackPanel>
                </Grid>
            </Border>

            <!-- Footer -->
            <Border DockPanel.Dock="Bottom"
                    BorderBrush="{DynamicResource Wd.Border}"
                    BorderThickness="0,1,0,0"
                    Padding="32,10">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="WOOGLIN"
                               Style="{StaticResource Wd.Text.Mono}"
                               Foreground="{DynamicResource Wd.Text.Tertiary}"
                               VerticalAlignment="Center"/>
                    <TextBlock Grid.Column="1"
                               Text="{Binding StatusText}"
                               Style="{StaticResource Wd.Text.Mono}"
                               Foreground="{DynamicResource Wd.Text.Tertiary}"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center"/>

                    <!-- Session timer — green dot + elapsed when at least one ISO is live -->
                    <StackPanel Grid.Column="2"
                                Orientation="Horizontal"
                                VerticalAlignment="Center"
                                Margin="0,0,16,0"
                                Visibility="{Binding IsSessionActive, Converter={StaticResource BoolToVis}}"
                                ToolTip="Elapsed time since the first ISO went live this session.">
                        <Border Width="8" Height="8"
                                CornerRadius="4"
                                Background="{DynamicResource Wd.Status.Live}"
                                VerticalAlignment="Center"
                                Margin="0,0,6,0"/>
                        <TextBlock Text="{Binding SessionElapsed}"
                                   Style="{StaticResource Wd.Text.Mono}"
                                   FontSize="11"
                                   Foreground="{DynamicResource Wd.Status.Live}"
                                   VerticalAlignment="Center"/>
                    </StackPanel>

                    <!-- Recording badge — coral dot + count when recording is on -->
                    <StackPanel Grid.Column="3"
                                Orientation="Horizontal"
                                VerticalAlignment="Center"
                                Margin="0,0,16,0"
                                Visibility="{Binding IsRecording, Converter={StaticResource BoolToVis}}"
                                ToolTip="One or more ISOs are being recorded to disk.">
                        <Border Width="8" Height="8"
                                CornerRadius="4"
                                Background="{DynamicResource Wd.Accent.Coral}"
                                VerticalAlignment="Center"
                                Margin="0,0,6,0"/>
                        <TextBlock Style="{StaticResource Wd.Text.Mono}"
                                   FontSize="11"
                                   Foreground="{DynamicResource Wd.Accent.Coral}"
                                   VerticalAlignment="Center"
                                   Margin="0,0,8,0">
                            <Run Text="REC "/>
                            <Run Text="{Binding ActiveRecordingCount, Mode=OneWay}"/>
                            <Run Text=" · "/>
                            <Run Text="{Binding RecordingElapsed, Mode=OneWay}"/>
                        </TextBlock>
                        <!-- Free disk space on the recording drive. Coral
                             tint kicks in below 10GB; existing DiskSpaceWatcher
                             auto-disables recording at 1GB. -->
                        <TextBlock VerticalAlignment="Center"
                                   ToolTip="Free disk space on the recording drive. Recording auto-disables when free space drops below 1GB.">
                            <TextBlock.Style>
                                <Style TargetType="TextBlock" BasedOn="{StaticResource Wd.Text.Mono}">
                                    <Setter Property="FontSize" Value="11"/>
                                    <Setter Property="Foreground" Value="{DynamicResource Wd.Text.Tertiary}"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsLowDiskSpace}" Value="True">
                                            <Setter Property="Foreground" Value="{DynamicResource Wd.Accent.Coral}"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBlock.Style>
                            <Run Text="· "/>
                            <Run Text="{Binding RecordingFreeSpace, Mode=OneWay}"/>
                            <Run Text=" free"/>
                        </TextBlock>
                    </StackPanel>

                    <!-- Control surface badge — cyan dot + REST/OSC string when active -->
                    <StackPanel Grid.Column="4"
                                Orientation="Horizontal"
                                VerticalAlignment="Center"
                                Margin="0,0,16,0"
                                Visibility="{Binding IsControlSurfaceRunning, Converter={StaticResource BoolToVis}}"
                                ToolTip="External control surface is listening on localhost. See docs/CONTROL-SURFACE.md.">
                        <Border Width="8" Height="8"
                                CornerRadius="4"
                                Background="{DynamicResource Wd.Accent.Cyan}"
                                VerticalAlignment="Center"
                                Margin="0,0,6,0"/>
                        <TextBlock Text="{Binding ControlSurfaceText}"
                                   Style="{StaticResource Wd.Text.Mono}"
                                   FontSize="11"
                                   Foreground="{DynamicResource Wd.Accent.Cyan}"
                                   VerticalAlignment="Center"/>
                    </StackPanel>

                    <TextBlock Grid.Column="5"
                               Text="wilddragon.net · 1.0.0-alpha"
                               Style="{StaticResource Wd.Text.Mono}"
                               Foreground="{DynamicResource Wd.Text.Tertiary}"
                               VerticalAlignment="Center"/>
                </Grid>
            </Border>

            <!-- Body -->
            <Grid Margin="32,28,32,28">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>

                <!--
                    Update-available banner. Hidden by default; shown by the launch-time
                    UpdateChecker if a newer release tag exists on Forgejo. "Get update"
                    opens the releases page; "Dismiss" hides until next launch.
                -->
                <Border Grid.Row="0"
                        Style="{StaticResource Wd.Card}"
                        Padding="14,10"
                        Margin="0,0,0,14"
                        Background="{DynamicResource Wd.Accent.CyanMuted}"
                        BorderBrush="{DynamicResource Wd.Accent.Cyan}"
                        Visibility="{Binding UpdateBanner.IsVisible, Converter={StaticResource BoolToVis}}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <Border Grid.Column="0"
                                Width="8" Height="8"
                                CornerRadius="4"
                                Background="{DynamicResource Wd.Accent.Cyan}"
                                VerticalAlignment="Center"
                                Margin="0,0,12,0"/>
                        <TextBlock Grid.Column="1"
                                   Text="{Binding UpdateBanner.Message}"
                                   Style="{StaticResource Wd.Text.Body}"
                                   FontSize="12"
                                   VerticalAlignment="Center"
                                   Foreground="{DynamicResource Wd.Text.Primary}"/>
                        <Button Grid.Column="2"
                                Style="{StaticResource Wd.Button.Ghost}"
                                Content="Get update"
                                Command="{Binding UpdateBanner.OpenReleasePageCommand}"
                                Padding="14,4"
                                Margin="0,0,8,0"
                                ToolTip="Open the Forgejo releases page in your browser to download the new MSI."/>
                        <Button Grid.Column="3"
                                Style="{StaticResource Wd.Button.Ghost}"
                                Content="Dismiss"
                                Command="{Binding UpdateBanner.DismissCommand}"
                                Padding="14,4"
                                ToolTip="Hide this banner. It'll reappear on next launch if the update is still available."/>
                    </Grid>
                </Border>

                <!--
                    Phase E.3 in-call control bar. Drives Microsoft Teams' UI via
                    UIAutomation so the operator can mute, toggle camera, share, or
                    leave without alt-tabbing to Teams (especially useful when the
                    Teams windows are hidden via the rail toggle). Buttons toast the
                    result; if Teams isn't in a call, the underlying buttons aren't
                    in the automation tree so the toast says so.
                -->
                <Border Grid.Row="1"
                        Style="{StaticResource Wd.Card}"
                        Padding="14,10"
                        Margin="0,0,0,18">
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                        <TextBlock Text="IN-CALL"
                                   Style="{StaticResource Wd.Text.Caption}"
                                   VerticalAlignment="Center"
                                   Margin="0,0,12,0"/>
                        <!-- Teams meeting state pill — populated from a UIA probe
                             at the existing 1Hz stats tick. Visible only when Teams
                             is running. Cyan dot when in a call, gray when Teams is
                             open but idle. So an operator with Teams auto-hidden can
                             see at a glance whether they're in a meeting. -->
                        <Border Style="{StaticResource Wd.Pill}"
                                VerticalAlignment="Center"
                                Margin="0,0,16,0"
                                Padding="10,3"
                                Visibility="{Binding HasTeamsState, Converter={StaticResource BoolToVis}}"
                                ToolTip="Microsoft Teams meeting state (probed via UIAutomation at 1Hz)">
                            <StackPanel Orientation="Horizontal">
                                <Border Width="6" Height="6"
                                        CornerRadius="3"
                                        Margin="0,0,6,0"
                                        VerticalAlignment="Center">
                                    <Border.Style>
                                        <Style TargetType="Border">
                                            <Setter Property="Background" Value="{DynamicResource Wd.Text.Tertiary}"/>
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding IsTeamsInCall}" Value="True">
                                                    <Setter Property="Background" Value="{DynamicResource Wd.Accent.Cyan}"/>
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </Border.Style>
                                </Border>
                                <TextBlock Text="{Binding TeamsMeetingState}"
                                           Style="{StaticResource Wd.Text.Caption}"
                                           FontSize="10"
                                           Foreground="{DynamicResource Wd.Text.Secondary}"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Border>

                        <!-- Local mute / camera-off indicators. Visible only
                             when in-call AND the corresponding state is true.
                             Tells operators using auto-hide "you're muted /
                             camera-off right now" without restoring Teams. -->
                        <Border Style="{StaticResource Wd.Pill}"
                                VerticalAlignment="Center"
                                Margin="0,0,6,0"
                                Padding="8,3"
                                Background="{DynamicResource Wd.Accent.CoralBg}"
                                Visibility="{Binding IsLocalMuted, Converter={StaticResource BoolToVis}}"
                                ToolTip="Your microphone is muted in Teams. Click Mute to unmute.">
                            <TextBlock Text="MUTED"
                                       FontFamily="{StaticResource Wd.Font.Sans}"
                                       FontSize="10"
                                       FontWeight="SemiBold"
                                       Foreground="{DynamicResource Wd.Accent.Coral}"
                                       VerticalAlignment="Center"/>
                        </Border>
                        <Border Style="{StaticResource Wd.Pill}"
                                VerticalAlignment="Center"
                                Margin="0,0,12,0"
                                Padding="8,3"
                                Background="{DynamicResource Wd.Accent.CoralBg}"
                                Visibility="{Binding IsLocalCameraOff, Converter={StaticResource BoolToVis}}"
                                ToolTip="Your camera is off in Teams. Click Camera to turn it on.">
                            <TextBlock Text="CAM OFF"
                                       FontFamily="{StaticResource Wd.Font.Sans}"
                                       FontSize="10"
                                       FontWeight="SemiBold"
                                       Foreground="{DynamicResource Wd.Accent.Coral}"
                                       VerticalAlignment="Center"/>
                        </Border>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding ToggleMuteCommand}"
                                Padding="14,6"
                                Margin="0,0,8,0"
                                ToolTip="Toggle Microsoft Teams microphone mute">
                            <StackPanel Orientation="Horizontal">
                                <Path Data="M 5,2 L 9,2 L 9,8 A 2,2 0 0 1 5,8 Z M 3,8 A 4,4 0 0 0 11,8 M 7,12 L 7,15 M 5,15 L 9,15"
                                      Stroke="{DynamicResource Wd.Text.Primary}"
                                      StrokeThickness="1.4"
                                      Fill="Transparent"
                                      Width="14" Height="16"
                                      Stretch="None"
                                      VerticalAlignment="Center"
                                      Margin="0,0,8,0"/>
                                <TextBlock Text="Mute"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding ToggleCameraCommand}"
                                Padding="14,6"
                                Margin="0,0,8,0"
                                ToolTip="Toggle Microsoft Teams camera">
                            <StackPanel Orientation="Horizontal">
                                <Path Data="M 1,3 L 11,3 L 11,11 L 1,11 Z M 11,5 L 15,3 L 15,11 L 11,9 Z"
                                      Stroke="{DynamicResource Wd.Text.Primary}"
                                      StrokeThickness="1.4"
                                      Fill="Transparent"
                                      Width="16" Height="14"
                                      Stretch="None"
                                      VerticalAlignment="Center"
                                      Margin="0,0,8,0"/>
                                <TextBlock Text="Camera"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding OpenShareTrayCommand}"
                                Padding="14,6"
                                Margin="0,0,8,0"
                                ToolTip="Open the Microsoft Teams share tray">
                            <StackPanel Orientation="Horizontal">
                                <Path Data="M 8,1 L 8,10 M 4,5 L 8,1 L 12,5 M 1,12 L 1,15 L 15,15 L 15,12"
                                      Stroke="{DynamicResource Wd.Text.Primary}"
                                      StrokeThickness="1.4"
                                      Fill="Transparent"
                                      Width="16" Height="16"
                                      Stretch="None"
                                      VerticalAlignment="Center"
                                      Margin="0,0,8,0"/>
                                <TextBlock Text="Share"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding DropRecordingMarkerCommand}"
                                Padding="14,6"
                                Margin="0,0,8,0"
                                ToolTip="Drop a timestamped marker into every active recording. Useful for chaptering in post — 'guest answer starts here', 'highlight clip', etc. Markers land in each recording's manifest.json.">
                            <StackPanel Orientation="Horizontal">
                                <Path Data="M 4,1 L 4,15 M 4,1 L 13,1 L 11,4 L 13,7 L 4,7"
                                      Stroke="{DynamicResource Wd.Text.Primary}"
                                      StrokeThickness="1.4"
                                      Fill="Transparent"
                                      Width="14" Height="16"
                                      Stretch="None"
                                      VerticalAlignment="Center"
                                      Margin="0,0,8,0"/>
                                <TextBlock Text="Marker"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding ShowNotesCommand}"
                                Padding="14,6"
                                Margin="0,0,8,0"
                                ToolTip="Open the show-notes viewer for today. Notes can be appended via the REST or OSC notes endpoint or by typing in this dialog's editor link.">
                            <StackPanel Orientation="Horizontal">
                                <Path Data="M 2,1 L 12,1 L 12,14 L 2,14 Z M 4,4 L 10,4 M 4,7 L 10,7 M 4,10 L 8,10"
                                      Stroke="{DynamicResource Wd.Text.Primary}"
                                      StrokeThickness="1.2"
                                      Fill="Transparent"
                                      Width="14" Height="15"
                                      Stretch="None"
                                      VerticalAlignment="Center"
                                      Margin="0,0,8,0"/>
                                <TextBlock Text="Notes"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding LeaveCallCommand}"
                                Padding="14,6"
                                ToolTip="Leave the Microsoft Teams call">
                            <StackPanel Orientation="Horizontal">
                                <Border Width="8" Height="8"
                                        CornerRadius="4"
                                        Background="{DynamicResource Wd.Accent.Coral}"
                                        VerticalAlignment="Center"
                                        Margin="0,0,8,0"/>
                                <TextBlock Text="Leave"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>

                        <!-- Quick-join: paste a Teams meeting URL, click Join,
                             Teams launches into the meeting via the shell handler.
                             Avoids the open-Teams → Calendar → find meeting → click
                             join dance. Only enabled with non-empty text. -->
                        <Border Width="1"
                                Background="{DynamicResource Wd.Border}"
                                Margin="14,4,12,4"/>
                        <TextBox Text="{Binding JoinMeetingUrl, UpdateSourceTrigger=PropertyChanged}"
                                 Width="240"
                                 VerticalAlignment="Center"
                                 Padding="10,5"
                                 FontSize="11"
                                 ToolTip="Paste a Teams meeting URL (https://teams.microsoft.com/l/meetup-join/... or msteams:/l/meetup-join/...) and click Join. TeamsISO hands it to Teams to launch + join in one step."/>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding JoinMeetingCommand}"
                                Padding="14,6"
                                Margin="6,0,0,0"
                                ToolTip="Hand the pasted meeting URL to Microsoft Teams. With auto-hide on (DISPLAY tab), the Teams window briefly appears then hides automatically.">
                            <StackPanel Orientation="Horizontal">
                                <Path Data="M 8,1 L 8,11 M 4,7 L 8,11 L 12,7 M 1,14 L 15,14"
                                      Stroke="{DynamicResource Wd.Accent.Cyan}"
                                      StrokeThickness="1.5"
                                      Fill="Transparent"
                                      Width="16" Height="15"
                                      Stretch="None"
                                      VerticalAlignment="Center"
                                      Margin="0,0,8,0"/>
                                <TextBlock Text="Join"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                    </StackPanel>
                </Border>

                <!-- Section header -->
                <Grid Grid.Row="2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                        <TextBlock Text="Participants"
                                   Style="{StaticResource Wd.Text.Heading}"
                                   FontSize="18"/>
                        <Border Style="{StaticResource Wd.Pill}"
                                Margin="12,0,0,0"
                                VerticalAlignment="Center">
                            <TextBlock Text="{Binding Participants.Count}"
                                       Style="{StaticResource Wd.Text.Mono}"
                                       FontSize="11"/>
                        </Border>
                    </StackPanel>

                    <!-- Header actions: Refresh discovery, Presets dialog, emergency stop. -->
                    <StackPanel Grid.Column="1"
                                Orientation="Horizontal"
                                VerticalAlignment="Center">
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding EnableAllOnlineCommand}"
                                VerticalAlignment="Center"
                                Margin="0,0,8,0"
                                ToolTip="Enable ISOs for every online participant who isn't already routing. Useful at show-start when everyone has just joined.">
                            <StackPanel Orientation="Horizontal">
                                <Border Width="8" Height="8"
                                        CornerRadius="4"
                                        Background="{DynamicResource Wd.Status.Live}"
                                        VerticalAlignment="Center"
                                        Margin="0,0,8,0"/>
                                <TextBlock Text="Enable all"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding RefreshDiscoveryCommand}"
                                VerticalAlignment="Center"
                                Margin="0,0,8,0"
                                ToolTip="Force NDI discovery to rebuild — useful right after applying a new transcoder topology or after Teams restarts.">
                            <StackPanel Orientation="Horizontal">
                                <Path Data="M 5,1 A 4,4 0 1 1 1.5,5 M 5,1 L 5,3 L 7,3"
                                      Stroke="{DynamicResource Wd.Text.Primary}"
                                      StrokeThickness="1.2"
                                      Width="10" Height="10"
                                      Stretch="None"
                                      VerticalAlignment="Center"
                                      Margin="0,0,8,0"/>
                                <TextBlock Text="Refresh"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding SnapshotAllCommand}"
                                VerticalAlignment="Center"
                                Margin="0,0,8,0"
                                ToolTip="Save a PNG of every enabled participant's current frame. One folder per click under %USERPROFILE%\Pictures\TeamsISO\snapshots-&lt;timestamp&gt;.">
                            <StackPanel Orientation="Horizontal">
                                <Path Data="M 1,3 L 4,3 L 5,1 L 11,1 L 12,3 L 15,3 L 15,13 L 1,13 Z M 8,5 A 3,3 0 1 1 8,11 A 3,3 0 1 1 8,5"
                                      Stroke="{DynamicResource Wd.Text.Primary}"
                                      StrokeThickness="1.2"
                                      Fill="Transparent"
                                      Width="16" Height="14"
                                      Stretch="None"
                                      VerticalAlignment="Center"
                                      Margin="0,0,8,0"/>
                                <TextBlock Text="Snapshot all"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Click="OnPresetsClick"
                                VerticalAlignment="Center"
                                Margin="0,0,8,0"
                                ToolTip="Save or load named ISO assignment snapshots for recurring shows">
                            <StackPanel Orientation="Horizontal">
                                <Border Width="8" Height="8"
                                        CornerRadius="4"
                                        Background="{DynamicResource Wd.Accent.Cyan}"
                                        VerticalAlignment="Center"
                                        Margin="0,0,8,0"/>
                                <TextBlock Text="Presets"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                        <Button Style="{StaticResource Wd.Button.Ghost}"
                                Command="{Binding StopAllIsosCommand}"
                                VerticalAlignment="Center"
                                ToolTip="Disable every running ISO immediately">
                            <StackPanel Orientation="Horizontal">
                                <Border Width="8" Height="8"
                                        CornerRadius="4"
                                        Background="{DynamicResource Wd.Accent.Coral}"
                                        VerticalAlignment="Center"
                                        Margin="0,0,8,0"/>
                                <TextBlock Text="Stop all ISOs"
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="12"
                                           VerticalAlignment="Center"/>
                            </StackPanel>
                        </Button>
                    </StackPanel>
                </Grid>

                <Grid Grid.Row="3" Margin="0,6,0,18">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                               Text="Toggle a participant's ISO to spin up an isolated, normalized NDI output."
                               Style="{StaticResource Wd.Text.Subtle}"
                               Foreground="{DynamicResource Wd.Text.Tertiary}"
                               VerticalAlignment="Center"/>
                    <!-- Live filter input — case-insensitive substring match on display name -->
                    <TextBox Grid.Column="1"
                             Text="{Binding ParticipantFilter, UpdateSourceTrigger=PropertyChanged}"
                             MinWidth="200"
                             Padding="10,6"
                             FontSize="12"
                             VerticalAlignment="Center"
                             ToolTip="Filter the participants list as you type. Case-insensitive substring match against display name."/>
                </Grid>

                <!-- Participants card -->
                <Border Grid.Row="4"
                        Style="{StaticResource Wd.Card}"
                        Padding="0">
                    <Grid>
                        <!-- Empty-state placeholder. Visible when Participants.Count == 0. -->
                        <StackPanel Visibility="{Binding Participants.Count, Converter={StaticResource CountToVis}, ConverterParameter=empty}"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"
                                    MaxWidth="460"
                                    Margin="32,48">
                            <Image Source="/Assets/dragon-mark.png"
                                   Width="64" Height="64"
                                   Opacity="0.45"
                                   HorizontalAlignment="Center"
                                   Margin="0,0,0,20"
                                   RenderOptions.BitmapScalingMode="HighQuality"/>
                            <TextBlock Text="Waiting for Teams"
                                       Style="{StaticResource Wd.Text.Heading}"
                                       FontSize="16"
                                       HorizontalAlignment="Center"/>
                            <TextBlock Style="{StaticResource Wd.Text.Subtle}"
                                       Foreground="{DynamicResource Wd.Text.Tertiary}"
                                       HorizontalAlignment="Center"
                                       TextAlignment="Center"
                                       TextWrapping="Wrap"
                                       Margin="0,8,0,20"
                                       Text="No Teams participants discovered on the network yet. Once Teams broadcasts NDI sources, this list will populate within a few seconds."/>

                            <Border Style="{StaticResource Wd.Card}"
                                    Background="{DynamicResource Wd.SurfaceElevated}"
                                    Padding="16,12">
                                <StackPanel>
                                    <TextBlock Text="QUICK CHECKLIST"
                                               Style="{StaticResource Wd.Text.Caption}"
                                               Margin="0,0,0,8"/>
                                    <TextBlock Style="{StaticResource Wd.Text.Subtle}"
                                               Foreground="{DynamicResource Wd.Text.Secondary}"
                                               TextWrapping="Wrap"
                                               FontSize="12"
                                               Margin="0,0,0,4">
                                        <Run Text="•"/>
                                        <Run Text=" Microsoft Teams is running and a meeting is active"/>
                                    </TextBlock>
                                    <TextBlock Style="{StaticResource Wd.Text.Subtle}"
                                               Foreground="{DynamicResource Wd.Text.Secondary}"
                                               TextWrapping="Wrap"
                                               FontSize="12"
                                               Margin="0,0,0,4">
                                        <Run Text="•"/>
                                        <Run Text=" NDI broadcast is enabled in Teams settings"/>
                                    </TextBlock>
                                    <TextBlock Style="{StaticResource Wd.Text.Subtle}"
                                               Foreground="{DynamicResource Wd.Text.Secondary}"
                                               TextWrapping="Wrap"
                                               FontSize="12"
                                               Margin="0,0,0,4">
                                        <Run Text="•"/>
                                        <Run Text=" Discovery group in Settings matches Teams' broadcast group"/>
                                    </TextBlock>
                                    <TextBlock Style="{StaticResource Wd.Text.Subtle}"
                                               Foreground="{DynamicResource Wd.Text.Secondary}"
                                               TextWrapping="Wrap"
                                               FontSize="12">
                                        <Run Text="•"/>
                                        <Run Text=" Windows Firewall isn't blocking NDI multicast on the active network adapter"/>
                                    </TextBlock>
                                </StackPanel>
                            </Border>
                        </StackPanel>

                        <!-- DataGrid: visible only when Participants.Count > 0. -->
                        <DataGrid ItemsSource="{Binding ParticipantsView}"
                                  Visibility="{Binding Participants.Count, Converter={StaticResource CountToVis}}"
                                  Margin="6,4,6,4">
                        <DataGrid.RowStyle>
                            <Style TargetType="DataGridRow">
                                <Setter Property="ContextMenu">
                                    <Setter.Value>
                                        <ContextMenu>
                                            <MenuItem Header="Toggle ISO" Command="{Binding ToggleIsoCommand}"/>
                                            <MenuItem Header="Restart this ISO"
                                                      Command="{Binding RestartIsoCommand}"
                                                      ToolTip="Disable + re-enable this pipeline only. Useful when a single feed flakes (drops climb, framerate jitters) without affecting other ISOs."/>
                                            <MenuItem Header="Open preview…"
                                                      Command="{Binding OpenPreviewCommand}"
                                                      ToolTip="Pop out a floating live-preview window. Drag to a second monitor for full-screen monitoring."/>
                                            <MenuItem Header="Save current frame…"
                                                      Command="{Binding SaveSnapshotCommand}"
                                                      ToolTip="Save the most recent processed frame as a PNG under %USERPROFILE%\Pictures\TeamsISO. Useful for highlight reels, social posts, or attaching to a bug report."/>
                                            <MenuItem Header="Record this participant"
                                                      IsCheckable="True"
                                                      IsChecked="{Binding RecordToDisk}"/>
                                            <Separator/>
                                            <MenuItem Header="Copy NDI source name"
                                                      Command="{Binding CopySourceNameCommand}"
                                                      ToolTip="{Binding SourceFullName}"/>
                                        </ContextMenu>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </DataGrid.RowStyle>
                        <DataGrid.Columns>
                            <!--
                                Live preview thumbnail. 160×90 (16:9) WriteableBitmap fed
                                from the engine's most recent ProcessedFrame at the 1Hz
                                stats tick. Falls back to the avatar initials when no
                                pipeline is running (Thumbnail is null).
                            -->
                            <DataGridTemplateColumn Header="Preview" Width="120">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
                                            <!-- Placeholder shown when no thumbnail yet -->
                                            <Border Width="100" Height="56"
                                                    Background="{DynamicResource Wd.SurfaceElevated}"
                                                    BorderBrush="{DynamicResource Wd.Border}"
                                                    BorderThickness="1"
                                                    CornerRadius="4"
                                                    Visibility="{Binding HasThumbnail, Converter={StaticResource InvertBool}}">
                                                <TextBlock Text="—"
                                                           Foreground="{DynamicResource Wd.Text.Tertiary}"
                                                           FontFamily="{StaticResource Wd.Font.Mono}"
                                                           FontSize="11"
                                                           HorizontalAlignment="Center"
                                                           VerticalAlignment="Center"/>
                                            </Border>
                                            <!-- Live thumbnail. Stretch=Uniform preserves aspect; clip via Border for rounded corners -->
                                            <Border Width="100" Height="56"
                                                    BorderBrush="{DynamicResource Wd.Border}"
                                                    BorderThickness="1"
                                                    CornerRadius="4"
                                                    ClipToBounds="True"
                                                    Visibility="{Binding HasThumbnail, Converter={StaticResource BoolToVis}}">
                                                <Image Source="{Binding Thumbnail}"
                                                       Stretch="UniformToFill"
                                                       RenderOptions.BitmapScalingMode="LowQuality"/>
                                            </Border>
                                        </Grid>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                            <DataGridTemplateColumn Header="Display Name" Width="2*">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal"
                                                    VerticalAlignment="Center"
                                                    ToolTip="{Binding SourceFullName}">
                                            <Border Style="{StaticResource Wd.Avatar}">
                                                <TextBlock Text="{Binding DisplayName, Converter={StaticResource Initials}}"
                                                           Foreground="{DynamicResource Wd.Accent.Cyan}"
                                                           FontFamily="{StaticResource Wd.Font.Sans}"
                                                           FontWeight="SemiBold"
                                                           FontSize="11"
                                                           HorizontalAlignment="Center"
                                                           VerticalAlignment="Center"/>
                                            </Border>
                                            <TextBlock Text="{Binding DisplayName}"
                                                       Style="{StaticResource Wd.Text.Body}"
                                                       FontWeight="Medium"
                                                       Margin="14,0,0,0"
                                                       VerticalAlignment="Center"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                            <DataGridTemplateColumn Header="Source" Width="*">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <StackPanel VerticalAlignment="Center">
                                            <TextBlock Text="{Binding SourceMachine}"
                                                       Style="{StaticResource Wd.Text.Mono}"/>
                                            <TextBlock Style="{StaticResource Wd.Text.Mono}"
                                                       FontSize="10"
                                                       Foreground="{DynamicResource Wd.Text.Tertiary}">
                                                <Run Text="{Binding IncomingResolution, Mode=OneWay}"/>
                                                <Run Text=" · "/>
                                                <Run Text="{Binding IncomingFps, Mode=OneWay}"/>
                                            </TextBlock>
                                        </StackPanel>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                            <DataGridTemplateColumn Header="Live" Width="140">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <StackPanel VerticalAlignment="Center">
                                            <TextBlock Style="{StaticResource Wd.Text.Mono}"
                                                       FontSize="11">
                                                <Run Text="↓ "/>
                                                <Run Text="{Binding FramesIn, Mode=OneWay}"/>
                                                <Run Text="  ↑ "/>
                                                <Run Text="{Binding FramesOut, Mode=OneWay}"/>
                                            </TextBlock>
                                            <TextBlock Style="{StaticResource Wd.Text.Mono}"
                                                       FontSize="10"
                                                       Foreground="{DynamicResource Wd.Accent.Coral}">
                                                <Run Text="drop "/>
                                                <Run Text="{Binding FramesDropped, Mode=OneWay}"/>
                                            </TextBlock>
                                            <!-- VU bar — width-bound to AudioLevelWidthPercent. The
                                                 outer Border is the 100-pixel-wide track; the inner
                                                 Border is the level fill. When the engine doesn't
                                                 yet feed PeakAudioLevel (current behavior), the bar
                                                 stays at 0 width. ToolTip explains the empty state. -->
                                            <Border Width="100" Height="4"
                                                    HorizontalAlignment="Left"
                                                    Margin="0,4,0,0"
                                                    Background="{DynamicResource Wd.SurfaceElevated}"
                                                    CornerRadius="2"
                                                    ToolTip="Live audio peak. Engine audio capture is a follow-up; the bar will animate once that ships.">
                                                <Border HorizontalAlignment="Left"
                                                        Width="{Binding AudioLevelWidthPercent, Mode=OneWay}"
                                                        Background="{DynamicResource Wd.Status.Live}"
                                                        CornerRadius="2"/>
                                            </Border>
                                        </StackPanel>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                            <DataGridTemplateColumn Header="Output Name" Width="2*">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBox Text="{Binding CustomName, UpdateSourceTrigger=PropertyChanged}"
                                                 Padding="10,7"
                                                 Margin="0,0,12,0"
                                                 VerticalAlignment="Center"
                                                 ToolTip="Override the auto-generated NDI output name (TEAMSISO_xxxxxxxx). Takes effect when ISO is enabled."/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                            <!--
                                Per-participant recording opt-out. When global recording is on,
                                only participants with this checkbox checked get a recorder when
                                their ISO starts. Read at EnableIsoAsync time so toggling on a
                                running pipeline has no effect — operator must disable + re-enable.
                            -->
                            <DataGridTemplateColumn Header="Rec" Width="60">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <CheckBox IsChecked="{Binding RecordToDisk}"
                                                  HorizontalAlignment="Center"
                                                  VerticalAlignment="Center"
                                                  ToolTip="When on, this participant's ISO is recorded to disk while global recording is enabled. Toggle while ISO is OFF — changes don't apply to a running pipeline."/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                            <DataGridTemplateColumn Header="ISO" Width="130">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <Button Command="{Binding ToggleIsoCommand}"
                                                Margin="0,0,12,0"
                                                ToolTip="Toggle this participant's normalized NDI ISO output">
                                            <Button.Style>
                                                <Style TargetType="Button" BasedOn="{StaticResource Wd.Button.IsoToggle}">
                                                    <Setter Property="Content" Value="Enable"/>
                                                    <Setter Property="Foreground" Value="{DynamicResource Wd.Text.Secondary}"/>
                                                    <Style.Triggers>
                                                        <DataTrigger Binding="{Binding IsEnabled}" Value="True">
                                                            <Setter Property="Content" Value="● LIVE"/>
                                                            <Setter Property="Background" Value="{DynamicResource Wd.Accent.CyanMuted}"/>
                                                            <Setter Property="BorderBrush" Value="{DynamicResource Wd.Accent.Cyan}"/>
                                                            <Setter Property="Foreground" Value="{DynamicResource Wd.Accent.Cyan}"/>
                                                        </DataTrigger>
                                                        <!-- Pipeline failed past retry budget — surface the error state in coral. -->
                                                        <DataTrigger Binding="{Binding StateLabel}" Value="ERROR">
                                                            <Setter Property="Content" Value="● ERROR"/>
                                                            <Setter Property="Background" Value="{DynamicResource Wd.Accent.CoralBg}"/>
                                                            <Setter Property="BorderBrush" Value="{DynamicResource Wd.Accent.Coral}"/>
                                                            <Setter Property="Foreground" Value="{DynamicResource Wd.Accent.Coral}"/>
                                                        </DataTrigger>
                                                        <!-- No frames received in slate-threshold window — amber warning. -->
                                                        <DataTrigger Binding="{Binding StateLabel}" Value="NO SIGNAL">
                                                            <Setter Property="Content" Value="● NO SIGNAL"/>
                                                            <Setter Property="Foreground" Value="{DynamicResource Wd.Status.Warn}"/>
                                                            <Setter Property="BorderBrush" Value="{DynamicResource Wd.Status.Warn}"/>
                                                        </DataTrigger>
                                                        <DataTrigger Binding="{Binding IsProcessing}" Value="True">
                                                            <Setter Property="Content" Value="…"/>
                                                            <Setter Property="IsEnabled" Value="False"/>
                                                        </DataTrigger>
                                                    </Style.Triggers>
                                                </Style>
                                            </Button.Style>
                                        </Button>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                    </Grid>
                </Border>

                <!-- Toast overlay: bottom-center, auto-dismissing transient notification.
                     Manual X dismiss for operators running a live show who want
                     to clear visual clutter without waiting the 3s auto-hide. -->
                <Border Grid.Row="2"
                        VerticalAlignment="Bottom"
                        HorizontalAlignment="Center"
                        Margin="0,0,0,16"
                        Background="{DynamicResource Wd.SurfaceElevated}"
                        BorderBrush="{DynamicResource Wd.BorderStrong}"
                        BorderThickness="1"
                        CornerRadius="999"
                        Padding="14,6,8,6"
                        Visibility="{Binding Toast.IsVisible, Converter={StaticResource BoolToVis}}">
                    <StackPanel Orientation="Horizontal">
                        <Ellipse Width="8" Height="8"
                                 Fill="{DynamicResource Wd.Accent.Cyan}"
                                 VerticalAlignment="Center"/>
                        <TextBlock Text="{Binding Toast.Message}"
                                   Style="{StaticResource Wd.Text.Body}"
                                   FontSize="12"
                                   Margin="10,0,12,0"
                                   VerticalAlignment="Center"/>
                        <Button Command="{Binding Toast.DismissCommand}"
                                Width="20" Height="20"
                                Background="Transparent"
                                BorderThickness="0"
                                Cursor="Hand"
                                FocusVisualStyle="{x:Null}"
                                ToolTip="Dismiss this toast">
                            <Button.Template>
                                <ControlTemplate TargetType="Button">
                                    <Border x:Name="Bd"
                                            Background="{TemplateBinding Background}"
                                            CornerRadius="10">
                                        <Path Data="M 0,0 L 8,8 M 8,0 L 0,8"
                                              Stroke="{DynamicResource Wd.Text.Tertiary}"
                                              StrokeThickness="1.2"
                                              Width="8" Height="8"
                                              Stretch="None"
                                              HorizontalAlignment="Center"
                                              VerticalAlignment="Center"/>
                                    </Border>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsMouseOver" Value="True">
                                            <Setter TargetName="Bd" Property="Background" Value="{DynamicResource Wd.Button.HoverBg}"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                    </StackPanel>
                </Border>
            </Grid>
        </DockPanel>

        <!-- ════════════════════════════════════════════════════════════════
             SETTINGS PANEL (right)
             ════════════════════════════════════════════════════════════════ -->
        <Border Grid.Column="2"
                Background="{DynamicResource Wd.Surface}"
                BorderBrush="{DynamicResource Wd.Border}"
                BorderThickness="1,0,0,0">
            <ScrollViewer VerticalScrollBarVisibility="Auto">
                <StackPanel Margin="24,28,24,32">

                    <TextBlock Text="Settings"
                               Style="{StaticResource Wd.Text.Heading}"
                               FontSize="16"
                               Margin="0,0,0,4"/>
                    <TextBlock Text="Per-meeting global processing"
                               Style="{StaticResource Wd.Text.Subtle}"
                               Foreground="{DynamicResource Wd.Text.Tertiary}"
                               Margin="0,0,0,22"/>

                    <!--
                        Settings panel is grouped into three tabs (Output, Network, Display)
                        rather than one long scroll. Apply Changes lives outside the tabs so
                        it commits all three sections at once — the binding paths span groups
                        anyway (framerate + group strings + display toggles all roundtrip
                        through the same Settings.ApplyCommand).
                    -->
                    <TabControl Style="{StaticResource Wd.TabControl}">

                        <!-- ──────────────── Output ──────────────── -->
                        <TabItem Header="OUTPUT" Style="{StaticResource Wd.TabItem}">
                            <StackPanel>
                                <TextBlock Text="Target Framerate"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,0,0,4"/>
                                <ComboBox ItemsSource="{Binding Settings.AvailableFramerates}"
                                          SelectedItem="{Binding Settings.Framerate}"
                                          ToolTip="The framerate every ISO output is normalized to. Click Apply to commit.">
                                    <ComboBox.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding Converter={StaticResource EnumDesc}}"/>
                                        </DataTemplate>
                                    </ComboBox.ItemTemplate>
                                </ComboBox>

                                <TextBlock Text="Target Resolution"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,12,0,4"/>
                                <ComboBox ItemsSource="{Binding Settings.AvailableResolutions}"
                                          SelectedItem="{Binding Settings.Resolution}"
                                          ToolTip="Output resolution. Source frames smaller than this are scaled up; larger frames are scaled down.">
                                    <ComboBox.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding Converter={StaticResource EnumDesc}}"/>
                                        </DataTemplate>
                                    </ComboBox.ItemTemplate>
                                </ComboBox>

                                <TextBlock Text="Aspect Mode"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,12,0,4"/>
                                <ComboBox ItemsSource="{Binding Settings.AvailableAspectModes}"
                                          SelectedItem="{Binding Settings.Aspect}"
                                          ToolTip="How to fit non-matching aspect ratios. Pillarbox = bars on the sides; Letterbox = bars top/bottom; Stretch = distort to fill.">
                                    <ComboBox.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding Converter={StaticResource EnumDesc}}"/>
                                        </DataTemplate>
                                    </ComboBox.ItemTemplate>
                                </ComboBox>

                                <TextBlock Text="Audio Mode"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,12,0,4"/>
                                <ComboBox ItemsSource="{Binding Settings.AvailableAudioModes}"
                                          SelectedItem="{Binding Settings.Audio}"
                                          ToolTip="Audio routing for ISO outputs. Auto = isolated when available, fall back to mixed; Isolated = participant audio only; Mixed = full meeting mix.">
                                    <ComboBox.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding Converter={StaticResource EnumDesc}}"/>
                                        </DataTemplate>
                                    </ComboBox.ItemTemplate>
                                </ComboBox>

                                <Button Style="{StaticResource Wd.Button.Ghost}"
                                        Content="Reset to defaults"
                                        Command="{Binding Settings.ResetOutputDefaultsCommand}"
                                        HorizontalAlignment="Stretch"
                                        Margin="0,16,0,0"
                                        Padding="0,8"
                                        ToolTip="Restore framerate, resolution, aspect and audio to TeamsISO defaults. Doesn't touch NDI groups or display toggles."/>
                            </StackPanel>
                        </TabItem>

                        <!-- ──────────────── Network ──────────────── -->
                        <TabItem Header="NETWORK" Style="{StaticResource Wd.TabItem}">
                            <StackPanel>
                                <TextBlock Text="Discovery group"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,0,0,4"/>
                                <TextBox Text="{Binding Settings.DiscoveryGroups, UpdateSourceTrigger=PropertyChanged}"
                                         ToolTip="Comma-separated NDI group names the engine subscribes to. Empty = Public (default)."/>
                                <TextBlock Text="Receive sources from this group. Empty = Public."
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="11"
                                           Foreground="{DynamicResource Wd.Text.Tertiary}"
                                           Margin="0,4,0,0"/>

                                <TextBlock Text="Output group"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,12,0,4"/>
                                <TextBox Text="{Binding Settings.OutputGroups, UpdateSourceTrigger=PropertyChanged}"
                                         ToolTip="Comma-separated NDI group(s) TeamsISO's normalized ISO outputs broadcast on. Empty = Public."/>
                                <TextBlock Text="Broadcast TeamsISO outputs on this group. Empty = Public."
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="11"
                                           Foreground="{DynamicResource Wd.Text.Tertiary}"
                                           Margin="0,4,0,0"/>

                                <Border Background="{DynamicResource Wd.SurfaceElevated}"
                                        BorderBrush="{DynamicResource Wd.Border}"
                                        BorderThickness="1"
                                        CornerRadius="{StaticResource Radius.M}"
                                        Padding="12,10"
                                        Margin="0,12,0,0">
                                    <TextBlock Style="{StaticResource Wd.Text.Body}"
                                               FontSize="11"
                                               Foreground="{DynamicResource Wd.Text.Secondary}"
                                               TextWrapping="Wrap"
                                               Text="Group changes apply on next launch — running pipelines aren't restarted to avoid orphaning live ISOs."/>
                                </Border>

                                <!-- One-click transcoder topology setup. Writes the system-wide
                                     NDI config so Teams broadcasts on a private group, then sets
                                     the engine to consume from that group and re-emit on Public. -->
                                <Button Style="{StaticResource Wd.Button.Ghost}"
                                        Content="Apply transcoder topology"
                                        Command="{Binding Settings.ApplyTranscoderTopologyCommand}"
                                        HorizontalAlignment="Stretch"
                                        Margin="0,12,0,0"
                                        Padding="0,9"/>
                                <TextBlock Style="{StaticResource Wd.Text.Body}"
                                           FontSize="11"
                                           Foreground="{DynamicResource Wd.Text.Tertiary}"
                                           TextWrapping="Wrap"
                                           Margin="0,4,0,0"
                                           Text="Pins Teams' raw NDI broadcasts to a private 'teamsiso-input' group so they don't pollute the Public network. Restart Teams after applying."/>

                                <TextBlock Text="Output name template"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,16,0,4"/>
                                <TextBox Text="{Binding Settings.OutputNameTemplate, UpdateSourceTrigger=LostFocus}"
                                         FontFamily="{StaticResource Wd.Font.Mono}"
                                         FontSize="11"
                                         ToolTip="Template applied to NDI output names when no per-participant Custom Name is set. Tokens: {name} = display name, {guid} = first-8 of Id, {machine} = PC name, {timestamp} = yyyyMMdd_HHmmss."/>
                                <TextBlock Style="{StaticResource Wd.Text.Body}"
                                           FontSize="11"
                                           Foreground="{DynamicResource Wd.Text.Tertiary}"
                                           TextWrapping="Wrap"
                                           Margin="0,4,0,0"
                                           Text="Tokens: {name}, {guid}, {machine}, {timestamp}. Default: TEAMSISO_{guid}. Use TEAMSISO_{name} for human-readable downstream switcher names."/>
                            </StackPanel>
                        </TabItem>

                        <!-- ──────────────── Display ──────────────── -->
                        <TabItem Header="DISPLAY" Style="{StaticResource Wd.TabItem}">
                            <StackPanel>
                                <CheckBox Content="Hide my self-preview from participants"
                                          IsChecked="{Binding Settings.HideLocalSelf}"
                                          ToolTip="Filters out the '(Local)' source — your own preview that Teams broadcasts on the same machine — so you don't accidentally route it as an ISO."/>

                                <CheckBox Content="Auto-disable ISOs when a participant leaves"
                                          IsChecked="{Binding Settings.AutoDisableOnDeparture}"
                                          ToolTip="When checked, departing participants automatically have their ISO pipelines torn down. Off by default so transient drops don't lose your routing."
                                          Margin="0,10,0,0"/>

                                <CheckBox Content="Auto-apply last preset on launch"
                                          IsChecked="{Binding Settings.AutoApplyLastPreset}"
                                          ToolTip="On launch, automatically re-apply the most recently applied operator preset once participants populate. Useful for recurring shows where the same routing should be restored every session."
                                          Margin="0,10,0,0"/>

                                <TextBlock Text="Sort participants by"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,12,0,4"/>
                                <ComboBox ItemsSource="{Binding Settings.AvailableSortModes}"
                                          SelectedItem="{Binding Settings.ParticipantSort}"
                                          ToolTip="JoinOrder = whatever order Teams emits sources (default). Alphabetical = stable across meetings, good for Stream Deck button assignments. OnlineFirst = online participants float to the top."/>

                                <CheckBox Content="Minimize to system tray"
                                          IsChecked="{Binding Settings.MinimizeToTray}"
                                          Margin="0,12,0,0"
                                          ToolTip="When checked, minimizing the window hides it and shows a tray icon. Useful for long unattended shows. Double-click the tray icon to restore."/>

                                <!-- Phase E.1/E.2 "I only see TeamsISO" pair. With both ticked,
                                     the operator launches TeamsISO and never sees the Teams UI —
                                     Teams runs in the background and all interaction routes
                                     through the IN-CALL bar + participants DataGrid. -->
                                <CheckBox Content="Launch Microsoft Teams on TeamsISO startup"
                                          IsChecked="{Binding Settings.LaunchTeamsOnStartup}"
                                          Margin="0,16,0,0"
                                          ToolTip="When checked, TeamsISO will auto-launch Microsoft Teams in the background each time it starts. Combine with 'Auto-hide Teams windows' for the 'I only see TeamsISO' experience."/>

                                <CheckBox Content="Auto-hide Teams windows when launched"
                                          IsChecked="{Binding Settings.AutoHideTeamsWindows}"
                                          Margin="0,8,0,0"
                                          ToolTip="When checked, Teams' windows are hidden as soon as they materialize after launch. Use the eye-icon button in the rail to restore them when needed. Drives Teams via the IN-CALL bar (mute / camera / share / leave / marker) and the participants DataGrid for ISO routing."/>

                                <CheckBox Content="Auto-record when Teams joins a meeting"
                                          IsChecked="{Binding Settings.AutoRecordOnCall}"
                                          Margin="0,8,0,0"
                                          ToolTip="When checked, recording auto-starts the moment Teams transitions into a call (IN CALL pill goes cyan) and auto-stops when the call ends. Removes the manual Record toggle step from unattended-show workflows."/>

                                <!-- Phase E.4 experimental — SetParent embed. WebView2 in modern
                                     Teams can render weirdly after reparent; if so, untick and
                                     fall back to auto-hide mode. -->
                                <Border Margin="0,12,0,8"
                                        Height="1"
                                        Background="{DynamicResource Wd.Border}"/>
                                <CheckBox Content="Embed Teams window inside TeamsISO (experimental)"
                                          IsChecked="{Binding Settings.EmbedTeamsWindow}"
                                          Margin="0,4,0,0"
                                          ToolTip="EXPERIMENTAL: Reparent Teams' main window into a TeamsISO-owned host so Teams appears INSIDE our window. WebView2 in modern Teams may render glitches or refuse focus after reparent — if so, untick and use auto-hide mode instead. Click 'Open embed window' below after enabling."/>
                                <Button Style="{StaticResource Wd.Button.Ghost}"
                                        Content="Open embed window"
                                        Click="OnOpenEmbedWindowClick"
                                        HorizontalAlignment="Stretch"
                                        Margin="0,8,0,0"
                                        Padding="0,8"
                                        IsEnabled="{Binding Settings.EmbedTeamsWindow}"
                                        ToolTip="Open the embed host window. Teams' main window will be reparented into it on load. Close the window to restore Teams to normal top-level state."/>

                                <Separator Margin="0,16,0,8"/>

                                <CheckBox Content="Record ISOs to disk"
                                          IsChecked="{Binding Settings.RecordIsosToDisk}"
                                          ToolTip="When checked, each newly-enabled ISO writes raw BGRA frames + manifest.json + convert.cmd to its own subdirectory. Run convert.cmd to produce H.264 .mkv via FFmpeg. Recording starts on the next ISO enable; already-running ISOs aren't retroactively captured."/>
                                <TextBlock Text="Output directory"
                                           Style="{StaticResource Wd.Text.Subtle}"
                                           Margin="0,12,0,4"
                                           IsEnabled="{Binding Settings.RecordIsosToDisk}"/>
                                <TextBox Text="{Binding Settings.RecordingDirectory, UpdateSourceTrigger=PropertyChanged}"
                                         IsEnabled="{Binding Settings.RecordIsosToDisk}"
                                         ToolTip="Root directory for recordings. Each participant gets a subdirectory under this path. Default: %USERPROFILE%\Videos\TeamsISO\&lt;date&gt;."/>
                                <TextBlock Text="Recordings live under this path. Each ISO writes raw BGRA + manifest.json. Double-click the convert.cmd inside to produce a final H.264 .mkv."
                                           Style="{StaticResource Wd.Text.Body}"
                                           FontSize="11"
                                           Foreground="{DynamicResource Wd.Text.Tertiary}"
                                           TextWrapping="Wrap"
                                           Margin="0,4,0,0"/>

                                <Separator Margin="0,16,0,8"/>

                                <CheckBox Content="Control surface (Stream Deck / Companion / web)"
                                          IsChecked="{Binding Settings.ControlSurfaceEnabled}"
                                          ToolTip="Start an HTTP server so external controllers (Bitfocus Companion, Stream Deck plugins, Bome MIDI Translator) or a thin-client browser can drive TeamsISO."/>

                                <CheckBox Content="LAN-reachable (allow other machines on your network)"
                                          IsChecked="{Binding Settings.ControlSurfaceLanReachable}"
                                          Margin="20,4,0,0"
                                          ToolTip="When checked, the control surface binds to all interfaces (0.0.0.0) instead of 127.0.0.1, so a phone or laptop on your LAN can drive TeamsISO. First time you turn this on, run this in an Administrator PowerShell once: netsh http add urlacl url=http://+:9755/ user=Everyone"/>

                                <Grid Margin="20,4,0,0">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Column="0"
                                               Text="{Binding Settings.ControlSurfaceUrl}"
                                               Style="{StaticResource Wd.Text.Mono}"
                                               FontSize="11"
                                               Foreground="{DynamicResource Wd.Accent.Cyan}"
                                               VerticalAlignment="Center"
                                               TextTrimming="CharacterEllipsis"/>
                                    <Button Grid.Column="1"
                                            Style="{StaticResource Wd.Button.Ghost}"
                                            Content="Open"
                                            Command="{Binding Settings.OpenControlSurfaceCommand}"
                                            Padding="10,2"
                                            Margin="0,0,4,0"
                                            FontSize="11"
                                            ToolTip="Open this URL in your default browser. Useful for previewing how the control panel looks before pointing a phone or second-monitor at it."/>
                                    <Button Grid.Column="2"
                                            Style="{StaticResource Wd.Button.Ghost}"
                                            Content="Copy"
                                            Command="{Binding Settings.CopyControlSurfaceUrlCommand}"
                                            Padding="10,2"
                                            FontSize="11"
                                            ToolTip="Copy this URL to the clipboard so you can paste it into a phone browser or controller."/>
                                </Grid>
                                <Grid Margin="0,8,0,0">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Column="0"
                                               Text="Port"
                                               Style="{StaticResource Wd.Text.Subtle}"
                                               VerticalAlignment="Center"
                                               Margin="0,0,12,0"/>
                                    <TextBox Grid.Column="1"
                                             Text="{Binding Settings.ControlSurfacePort, UpdateSourceTrigger=LostFocus}"
                                             ToolTip="Listening port for the REST control surface. Default 9755."/>
                                </Grid>
                                <TextBlock Style="{StaticResource Wd.Text.Body}"
                                           FontSize="11"
                                           Foreground="{DynamicResource Wd.Text.Tertiary}"
                                           TextWrapping="Wrap"
                                           Margin="0,4,0,0"
                                           Text="Endpoints: GET /participants, POST /participants/{id}/iso, /presets/{name}/apply, /presets/refresh-discovery, /presets/stop-all, /teams/mute|camera|leave|share|raise-hand, /recording. WebSocket /ws pushes live state. See docs/CONTROL-SURFACE.md."/>

                                <CheckBox Content="OSC bridge (UDP)"
                                          IsChecked="{Binding Settings.OscBridgeEnabled}"
                                          Margin="0,12,0,0"
                                          ToolTip="UDP listener that speaks the same command surface as REST. /teamsiso/iso 'Jane' 1, /teamsiso/preset 'Friday Show', /teamsiso/teams/mute, etc. Bound to 127.0.0.1 only."/>
                                <Grid Margin="0,8,0,0">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Column="0"
                                               Text="OSC port"
                                               Style="{StaticResource Wd.Text.Subtle}"
                                               VerticalAlignment="Center"
                                               Margin="0,0,12,0"/>
                                    <TextBox Grid.Column="1"
                                             Text="{Binding Settings.OscBridgePort, UpdateSourceTrigger=LostFocus}"
                                             ToolTip="UDP port for the OSC bridge. Default 9000 (TouchOSC's default)."/>
                                </Grid>

                                <Separator Margin="0,16,0,8"/>

                                <CheckBox Content="Check for updates on launch"
                                          IsChecked="{Binding Settings.UpdateCheckOnLaunch}"
                                          ToolTip="On startup, ask forge.wilddragon.net whether a newer release exists. Throttled to once per 24h. If newer, a banner appears at the top of the participants area; click 'Get update' to open the releases page in your browser."/>
                            </StackPanel>
                        </TabItem>
                    </TabControl>

                    <!--
                        Apply Changes commits OUTPUT + NETWORK fields together. DISPLAY-tab
                        toggles persist on each click (HideLocalSelf is in-memory only;
                        AutoDisableOnDeparture / AutoApplyLastPreset write through to disk
                        from their setters), so they don't strictly need this button — but
                        keeping it visible from any tab gives the user a single confirm.
                    -->
                    <Button Style="{StaticResource Wd.Button.Primary}"
                            Content="Apply Changes"
                            Command="{Binding Settings.ApplyCommand}"
                            HorizontalAlignment="Stretch"
                            Margin="0,28,0,0"
                            Padding="0,11"
                            ToolTip="Persist all settings to %APPDATA%\TeamsISO\config.json. Group changes apply on next launch."/>
                </StackPanel>
            </ScrollViewer>
        </Border>

    </Grid>
</Window>
