<?xml version="1.0" encoding="UTF-8" ?>
<Window
    x:Class="LlamaApp.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:LlamaApp.Views"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <!--
        This window is never shown as a normal top-level window. It is styled
        as a Windows 11 flyout (borderless, Mica backdrop, rounded corners) and
        only ever appears anchored to the system-tray icon, dismissing itself
        when it loses focus — mirroring the macOS menu-bar app on Windows.

        The content is a vertical Grid with three sections. Sections 1, 2 take
        their natural height; section 3 stretches to fill the remaining space
        (Row *):
          1. Brand header (logo + llama.app left, action icons right) — Auto, compact
          2. Available (local models, or "No model yet") — Auto, Fluent card
          3. Recommended Models                        — * (stretches), Fluent card
          4. Version footer (app version - llama.cpp version) — Auto, compact
        The two list sections are Fluent cards (4px rounded corners, 1px
        stroke, card fill, z-depth 8 elevation via ThemeShadow), so no divider
        line is needed between them.
        The old footer's Settings/Quit buttons are gone; those actions live as
        icons in the header now. The version caption is re-added as the last
        section.
    -->
    <Window.SystemBackdrop>
        <MicaBackdrop Kind="Base" />
    </Window.SystemBackdrop>

    <!-- Esc dismisses the flyout (the same convention as the chat overlay,
         whose pattern this copies). KeyboardAccelerators live on Control, not
         Window, so the root Grid is wrapped in a UserControl; window-level
         accelerators are processed regardless of which element has focus. -->
    <UserControl>
        <UserControl.KeyboardAccelerators>
            <KeyboardAccelerator Key="Escape" Invoked="EscapeAccelerator_Invoked" />
        </UserControl.KeyboardAccelerators>

    <Grid>
        <Grid.Resources>
            <!-- Local model row: icon + name/params·size + play glyph or progress ring.
                 The row lights up on hover and shows the full (possibly ellipsized)
                 model name as a tooltip. -->
            <DataTemplate x:Key="LocalModelRowTemplate"
                          x:DataType="local:ModelItem">
                <Grid Padding="8,6"
                      ColumnSpacing="10"
                      CornerRadius="{ThemeResource ControlCornerRadius}"
                      Background="Transparent"
                      PointerEntered="Row_PointerEntered"
                      PointerExited="Row_PointerExited"
                      ToolTipService.ToolTip="{x:Bind RowToolTip}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <!-- Logo tile with a "running" status badge pinned to its
                         bottom-right corner. -->
                    <Grid Grid.Column="0" Width="32" Height="32">
                        <Border CornerRadius="{ThemeResource ControlCornerRadius}"
                                Background="{ThemeResource ControlFillColorSecondaryBrush}">
                            <Image Source="{x:Bind Logo, Mode=OneWay}"
                                   Stretch="Uniform"
                                   Margin="4" />
                        </Border>
                        <!-- Running badge: a green dot shown when the server
                             reports this model as loaded (running). Bound to
                             OpenGlyphVisible so it appears in lockstep with the
                             Open/Unload action glyphs. Centered on the logo
                             image's bottom-right corner. The logo image is
                             inset by Margin=4 inside the 32px tile, so its
                             corner sits at (28,28); a 12px dot with a -2 right/
                             bottom margin lands its center exactly there. The
                             stroke matches the tile background on the inside
                             and reads as a thin ring on the outside where the
                             dot sits over the row gap. -->
                        <Ellipse Visibility="{x:Bind OpenGlyphVisible, Mode=OneWay}"
                                 Width="12" Height="12"
                                 Fill="#3FB950"
                                 Stroke="{ThemeResource ControlFillColorSecondaryBrush}"
                                 StrokeThickness="1.5"
                                 HorizontalAlignment="Right"
                                 VerticalAlignment="Bottom"
                                 Margin="0,0,-2,-2"
                                 ToolTipService.ToolTip="Running" />
                    </Grid>

                    <StackPanel Grid.Column="1"
                                VerticalAlignment="Center"
                                Spacing="1">
                        <TextBlock Text="{x:Bind DisplayName}"
                                   FontSize="14"
                                   FontWeight="SemiBold"
                                   TextTrimming="CharacterEllipsis" />
                        <StackPanel Orientation="Horizontal"
                                    Spacing="6"
                                    VerticalAlignment="Center">
                            <!-- Subtitle: "params · size" at rest; while a
                                 download runs, the live detail line instead
                                 ("3.2 GB of 12.1 GB · 45 MB/s · ~4 min left"). -->
                            <TextBlock FontSize="12"
                                       Foreground="{ThemeResource TextFillColorSecondaryBrush}"
                                       VerticalAlignment="Center"
                                       TextTrimming="CharacterEllipsis"
                                       Text="{x:Bind SubtitleText, Mode=OneWay}" />
                            <!-- Vision marker: shown when the server reports
                                 image input (architecture.input_modalities).
                                 A small “view” (eye) glyph, dimmed so it reads
                                 as a capability hint rather than part of the name.
                                 Tiled in the same gray rounded background as
                                 the logo so it reads as a small chip.
                                 The glyph MUST come from the intersection of
                                 Segoe Fluent Icons and Segoe MDL2 Assets:
                                 FontIcon falls back to MDL2 where the Fluent
                                 font is missing/older (Windows 10, older
                                 Windows 11), and there the prettier “glasses”
                                 U+EB25 doesn't exist — it renders as the
                                 crossed-square missing-glyph box. U+E890
                                 (View) exists in both. -->
                            <Border CornerRadius="{ThemeResource ControlCornerRadius}"
                                    Background="{ThemeResource ControlFillColorSecondaryBrush}"
                                    Padding="4,1"
                                    VerticalAlignment="Center"
                                    Visibility="{x:Bind Vision, Mode=OneWay}">
                                <FontIcon Glyph="&#xE890;"
                                          FontSize="10"
                                          Opacity="0.55"
                                          HorizontalAlignment="Center"
                                          VerticalAlignment="Center" />
                            </Border>
                        </StackPanel>
                    </StackPanel>

                    <!-- Action cell: exactly one of play / download ring /
                         load ring / open glyph / failure affordance, driven by
                         the ModelItem load/download state. Mutually exclusive
                         via Visibility. When loaded, the Open and Power/unload
                         glyphs appear side by side. -->
                    <StackPanel Grid.Column="2"
                                Orientation="Horizontal"
                                HorizontalAlignment="Right"
                                VerticalAlignment="Center">
                        <!-- Download failed: warning dot + retry button. Shown
                             instead of the play glyph (PlayGlyphVisible excludes
                             failed rows) so a broken download can't be "loaded".
                             The panel is right-aligned, so the dot and the retry
                             button occupy the same two slots as the delete and
                             play buttons on an available row — both use the same
                             16px glyph metrics as those buttons (and the retry
                             button the same 0.5 opacity) so a row flipping
                             between failed and available doesn't shift or shrink
                             the action cell. -->
                        <FontIcon Visibility="{x:Bind DownloadFailed, Mode=OneWay}"
                                  Glyph="&#xE7BA;"
                                  FontSize="16"
                                  Foreground="#F85149"
                                  VerticalAlignment="Center"
                                  Margin="0,0,2,0"
                                  ToolTipService.ToolTip="Download failed" />
                        <Button Visibility="{x:Bind DownloadFailed, Mode=OneWay}"
                                Click="LocalModelRetryDownload_Click"
                                Tag="{x:Bind}"
                                Padding="6"
                                MinWidth="0" MinHeight="0"
                                Background="Transparent"
                                BorderThickness="0"
                                AutomationProperties.Name="Retry download"
                                ToolTipService.ToolTip="Retry download">
                            <FontIcon Glyph="&#xE72C;"
                                      FontSize="16"
                                      Opacity="0.5" />
                        </Button>

                        <!-- Load failed: warning dot + retry button, mirroring
                             the download-failed pair above (same two slots,
                             same metrics, so a row flipping between failed and
                             available doesn't shift the action cell). Without
                             this a rejected load (OOM, corrupt GGUF, server
                             refusal) was silent: the ring just vanished. -->
                        <FontIcon Visibility="{x:Bind LoadFailed, Mode=OneWay}"
                                  Glyph="&#xE7BA;"
                                  FontSize="16"
                                  Foreground="#F85149"
                                  VerticalAlignment="Center"
                                  Margin="0,0,2,0"
                                  ToolTipService.ToolTip="Couldn't load the model" />
                        <Button Visibility="{x:Bind LoadFailed, Mode=OneWay}"
                                Click="LocalModelRetryLoad_Click"
                                Tag="{x:Bind}"
                                Padding="6"
                                MinWidth="0" MinHeight="0"
                                Background="Transparent"
                                BorderThickness="0"
                                AutomationProperties.Name="Retry load"
                                ToolTipService.ToolTip="Retry load">
                            <FontIcon Glyph="&#xE72C;"
                                      FontSize="16"
                                      Opacity="0.5" />
                        </Button>

                        <!-- Delete button: remove the model from the server's
                             cache (DELETE /models/{name}). Sits to the left of
                             the play glyph; shown only while the model is
                             unloaded (PlayGlyphVisible) so a loaded/loading
                             row isn't accidentally deleted mid-use. Opens a
                             confirmation flyout — deleting re-downloads GBs. -->
                        <Button Visibility="{x:Bind PlayGlyphVisible, Mode=OneWay}"
                                Click="LocalModelDelete_Click"
                                Tag="{x:Bind}"
                                Padding="6"
                                MinWidth="0" MinHeight="0"
                                Background="Transparent"
                                BorderThickness="0"
                                AutomationProperties.Name="Delete model"
                                ToolTipService.ToolTip="Delete model">
                            <Button.Flyout>
                                <Flyout Placement="Bottom">
                                    <StackPanel Spacing="10" MaxWidth="240">
                                        <TextBlock Text="Delete this model?"
                                                   FontSize="13"
                                                   FontWeight="SemiBold" />
                                        <TextBlock Text="The downloaded files are removed from disk. You can download the model again at any time."
                                                   FontSize="12"
                                                   Foreground="{ThemeResource TextFillColorSecondaryBrush}"
                                                   TextWrapping="Wrap" />
                                        <Button Content="Delete"
                                                Click="LocalModelDeleteConfirm_Click"
                                                Foreground="#F85149"
                                                HorizontalAlignment="Right" />
                                    </StackPanel>
                                </Flyout>
                            </Button.Flyout>
                            <FontIcon Glyph="&#xE74D;"
                                      FontSize="16"
                                      Opacity="0.5" />
                        </Button>

                        <!-- Play button: model is unloaded, click to load it. -->
                        <Button Visibility="{x:Bind PlayGlyphVisible, Mode=OneWay}"
                                Click="LocalModelPlay_Click"
                                Tag="{x:Bind}"
                                Padding="6"
                                MinWidth="0" MinHeight="0"
                                Background="Transparent"
                                BorderThickness="0"
                                AutomationProperties.Name="Load model"
                                ToolTipService.ToolTip="Load model">
                            <FontIcon Glyph="&#xE768;"
                                      FontSize="16"
                                      Opacity="0.5" />
                        </Button>

                        <!-- Download progress ring (downloading from the Hub)
                             with a percent caption once the byte count is known
                             — multi-GB downloads need real progress feedback. -->
                        <StackPanel Visibility="{x:Bind ProgressRingVisible, Mode=OneWay}"
                                    VerticalAlignment="Center"
                                    Spacing="2">
                            <ProgressRing Width="20" Height="20"
                                          Value="{x:Bind DownloadProgressPercent, Mode=OneWay}"
                                          Maximum="100"
                                          IsIndeterminate="{x:Bind IsIndeterminateDownload, Mode=OneWay}"
                                          HorizontalAlignment="Center" />
                            <TextBlock Text="{x:Bind DownloadProgressText, Mode=OneWay}"
                                       Visibility="{x:Bind DownloadPercentTextVisible, Mode=OneWay}"
                                       FontSize="10"
                                       Foreground="{ThemeResource TextFillColorSecondaryBrush}"
                                       HorizontalAlignment="Center" />
                        </StackPanel>

                        <!-- Cancel download: stops the in-flight download (the
                             server is asked to abort too; a partial download
                             resumes on the next attempt). Sits at the trailing
                             edge like the other row actions and shares their
                             metrics. Hidden for externally-triggered downloads
                             (WebUI / CLI), which have no cancellation source —
                             CancelDownloadVisible excludes them so the button
                             is never a no-op. The glyph MUST exist in both
                             Segoe Fluent Icons and Segoe MDL2 Assets (see the
                             vision-marker comment above): U+E711 (Cancel) does.
                             The download -> load transition drops this button,
                             shrinking the action cell by one slot; the ring
                             itself keeps its slot, so the row height and the
                             ring position don't move. -->
                        <Button Visibility="{x:Bind CancelDownloadVisible, Mode=OneWay}"
                                Click="LocalModelCancelDownload_Click"
                                Tag="{x:Bind}"
                                Padding="6"
                                MinWidth="0" MinHeight="0"
                                Background="Transparent"
                                BorderThickness="0"
                                VerticalAlignment="Center"
                                AutomationProperties.Name="Cancel download"
                                ToolTipService.ToolTip="Cancel download">
                            <FontIcon Glyph="&#xE711;"
                                      FontSize="16"
                                      Opacity="0.5" />
                        </Button>

                        <!-- Load ring: load request sent. Determinate once the
                             server's status_change SSE events report a progress
                             fraction (with a percent caption, like the download
                             ring); spins indeterminately until the first event
                             — and for externally-triggered loads, which only
                             the poller observes. -->
                        <StackPanel Visibility="{x:Bind LoadingRingVisible, Mode=OneWay}"
                                    VerticalAlignment="Center"
                                    Spacing="2">
                            <ProgressRing Width="20" Height="20"
                                          Value="{x:Bind LoadProgressPercent, Mode=OneWay}"
                                          Maximum="100"
                                          IsIndeterminate="{x:Bind IsIndeterminateLoad, Mode=OneWay}"
                                          HorizontalAlignment="Center" />
                            <TextBlock Text="{x:Bind LoadProgressText, Mode=OneWay}"
                                       Visibility="{x:Bind LoadPercentTextVisible, Mode=OneWay}"
                                       FontSize="10"
                                       Foreground="{ThemeResource TextFillColorSecondaryBrush}"
                                       HorizontalAlignment="Center" />
                        </StackPanel>

                        <!-- Open in new window: model is loaded, click to open
                             the running server's WebUI in the browser. -->
                        <Button Visibility="{x:Bind OpenGlyphVisible, Mode=OneWay}"
                                Click="LocalModelOpen_Click"
                                Tag="{x:Bind}"
                                Padding="6"
                                MinWidth="0" MinHeight="0"
                                Background="Transparent"
                                BorderThickness="0"
                                AutomationProperties.Name="Open WebUI"
                                ToolTipService.ToolTip="Open WebUI">
                            <FontIcon Glyph="&#xE8A7;"
                                      FontSize="16"
                                      Opacity="0.5" />
                        </Button>

                        <!-- Power/unload: model is loaded, click to unload it
                             from the server and free memory. -->
                        <Button Visibility="{x:Bind OpenGlyphVisible, Mode=OneWay}"
                                Click="LocalModelUnload_Click"
                                Tag="{x:Bind}"
                                Padding="6"
                                MinWidth="0" MinHeight="0"
                                Background="Transparent"
                                BorderThickness="0"
                                AutomationProperties.Name="Unload model"
                                ToolTipService.ToolTip="Unload model">
                            <FontIcon Glyph="&#xE7E8;"
                                      FontSize="16"
                                      Opacity="0.5" />
                        </Button>
                    </StackPanel>
                </Grid>
            </DataTemplate>

            <!-- Recommended model row: icon + name/params·license + download glyph.
                 The whole row is a chromeless Button — click, Enter or Space
                 starts a download. A bare Grid (the previous root) isn't
                 focusable and has no invoke pattern, so downloading was
                 impossible by keyboard and invisible to screen readers; the
                 Button gives Tab focus, key invoke, an automation name and a
                 focus visual for free. Its own visual states paint the
                 hover/pressed fill (ButtonBackgroundPointerOver is the same
                 SubtleFillColorSecondaryBrush the Available rows paint
                 manually), so the custom pointer handlers aren't needed here.
                 The tooltip shows the full (possibly ellipsized) model name. -->
            <DataTemplate x:Key="RecommendedModelRowTemplate"
                          x:DataType="local:ModelItem">
                <Button Padding="0"
                        MinWidth="0" MinHeight="0"
                        Background="Transparent"
                        BorderThickness="0"
                        CornerRadius="{ThemeResource ControlCornerRadius}"
                        HorizontalAlignment="Stretch"
                        HorizontalContentAlignment="Stretch"
                        VerticalContentAlignment="Stretch"
                        Click="RecommendedModel_Click"
                        Tag="{x:Bind}"
                        AutomationProperties.Name="{x:Bind DisplayName}"
                        AutomationProperties.HelpText="Download this model"
                        ToolTipService.ToolTip="{x:Bind RowToolTip}">
                <Grid Padding="8,6"
                      ColumnSpacing="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <Border Grid.Column="0"
                            Width="32" Height="32"
                            CornerRadius="{ThemeResource ControlCornerRadius}"
                            Background="{ThemeResource ControlFillColorSecondaryBrush}">
                        <Image Source="{x:Bind Logo, Mode=OneWay}"
                               Stretch="Uniform"
                               Margin="4" />
                    </Border>

                    <StackPanel Grid.Column="1"
                                VerticalAlignment="Center"
                                Spacing="1">
                        <TextBlock Text="{x:Bind DisplayName}"
                                   FontSize="13"
                                   FontWeight="SemiBold"
                                   TextTrimming="CharacterEllipsis" />
                        <StackPanel Orientation="Horizontal" Spacing="4">
                            <!-- params · download size · license — the size is
                                 shown up front so a one-tap row never starts a
                                 multi-GB download the user couldn't foresee. -->
                            <TextBlock FontSize="11"
                                       Foreground="{ThemeResource TextFillColorSecondaryBrush}"
                                       TextTrimming="CharacterEllipsis">
                                <Run Text="{x:Bind Parameters}" />
                                <Run Text=" · " />
                                <Run Text="{x:Bind Size}" />
                                <Run Text=" · " />
                                <Run Text="{x:Bind License}" />
                            </TextBlock>
                            <!-- Vision marker (same as the Available rows —
                                 U+E890 View, which exists in both Segoe Fluent
                                 Icons and Segoe MDL2 Assets; the previous
                                 U+E7B3 was Repair, a wrench). -->
                            <Border CornerRadius="{ThemeResource ControlCornerRadius}"
                                    Background="{ThemeResource ControlFillColorSecondaryBrush}"
                                    Padding="2"
                                    Visibility="{x:Bind Vision, Mode=OneWay}">
                                <FontIcon Glyph="&#xE890;"
                                          FontSize="10"
                                          Opacity="0.55"
                                          VerticalAlignment="Center" />
                            </Border>
                        </StackPanel>
                    </StackPanel>

                    <!-- Right margin clears the ScrollViewer's overlay
                         scrollbar (~12px expanded), which would otherwise
                         cover the glyph when the list scrolls. -->
                    <FontIcon Grid.Column="2"
                              Glyph="&#xE896;"
                              FontSize="16"
                              Opacity="0.5"
                              Margin="0,0,12,0"
                              VerticalAlignment="Center" />
                </Grid>
                </Button>
            </DataTemplate>
        </Grid.Resources>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" /> <!-- Section 1: brand header -->
            <RowDefinition Height="Auto" /> <!-- Divider -->
            <RowDefinition Height="Auto" /> <!-- Section 2: Available (card) -->
            <RowDefinition Height="*" />    <!-- Section 3: Recommended (card, stretches) -->
            <RowDefinition Height="Auto" /> <!-- Divider -->
            <RowDefinition Height="Auto" /> <!-- Section 4: version footer -->
        </Grid.RowDefinitions>

        <!-- ============ Section 1: Brand header (compact) ============
             Logo + "llama.app" left-aligned, action icons right-aligned, both
             at the same 16px horizontal margin as the sections below. The
             settings gear opens Settings; the globe quits the app — replacing
             the old footer's Settings/Quit buttons. -->
        <Grid Grid.Row="0"
              Margin="16,10,16,8"
              ColumnSpacing="8">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <!-- Left: brand logo + wordmark -->
            <StackPanel Grid.Column="0"
                        Orientation="Horizontal"
                        Spacing="6"
                        VerticalAlignment="Center">
                <Image Source="{ThemeResource BrandLogoSource}"
                       Width="20" Height="20"
                       Stretch="Uniform" />
                <StackPanel Orientation="Horizontal"
                            Spacing="1"
                            VerticalAlignment="Center">
                    <TextBlock Text="llama"
                               FontSize="13"
                               FontWeight="SemiBold"
                               Foreground="{ThemeResource TextFillColorPrimaryBrush}"
                               VerticalAlignment="Center" />
                    <TextBlock Text=".app"
                               FontSize="13"
                               FontWeight="SemiBold"
                               Foreground="{StaticResource BrandAccentBrush}"
                               VerticalAlignment="Center" />
                </StackPanel>
            </StackPanel>

            <!-- Right: action icons (replace the old footer buttons). Transparent
                 chrome to match the row icon buttons; the default button visual
                 states still paint a hover/pressed fill. -->
            <StackPanel Grid.Column="1"
                        Orientation="Horizontal"
                        Spacing="2"
                        Margin="0,0,-2,0"
                        VerticalAlignment="Center">
                <!-- HF avatar: shown only when a token is configured and
                     whoami-v2 resolves (see LoadAvatarAsync). Circular picture
                     with a presence dot; click opens the user's hf.co profile. -->
                <Button x:Name="AvatarButton"
                        Click="Avatar_Click"
                        Padding="3"
                        MinWidth="0" MinHeight="0"
                        VerticalAlignment="Center"
                        Background="Transparent"
                        BorderThickness="0"
                        Visibility="Collapsed"
                        AutomationProperties.Name="Open your Hugging Face profile"
                        ToolTipService.ToolTip="Open your Hugging Face profile">
                    <Grid Width="20" Height="20">
                        <PersonPicture x:Name="AvatarPicture"
                                       Width="20" Height="20" />
                        <!-- Presence dot pinned to the bottom-right of the circle -->
                        <Ellipse Width="7" Height="7"
                                 Fill="#3FB950"
                                 Stroke="{ThemeResource SolidBackgroundFillColorBaseBrush}"
                                 StrokeThickness="1"
                                 HorizontalAlignment="Right"
                                 VerticalAlignment="Bottom" />
                    </Grid>
                </Button>
                <Button Click="Settings_Click"
                        Padding="6"
                        MinWidth="0" MinHeight="0"
                        VerticalAlignment="Center"
                        Background="Transparent"
                        BorderThickness="0"
                        AutomationProperties.Name="Settings"
                        ToolTipService.ToolTip="Settings">
                    <FontIcon Glyph="&#xE713;"
                              FontSize="14" />
                </Button>
                <Button Click="Quit_Click"
                        Padding="6"
                        MinWidth="0" MinHeight="0"
                        VerticalAlignment="Center"
                        Background="Transparent"
                        BorderThickness="0"
                        AutomationProperties.Name="Quit"
                        ToolTipService.ToolTip="Quit">
                    <FontIcon Glyph="&#xE7E8;"
                              FontSize="14" />
                </Button>
            </StackPanel>
        </Grid>

        <Rectangle Grid.Row="1"
                   Height="1"
                   Margin="16,0"
                   Fill="{ThemeResource DividerStrokeColorDefaultBrush}" />

        <!-- ============ Section 2: Available (local models) ============
             A Fluent card: 4px rounded corners, 1px stroke, the card fill
             tokens, and z-depth 8 elevation (ThemeShadow). -->
        <Border Grid.Row="2"
                Margin="16,12,16,6"
                Padding="8,10"
                CornerRadius="4"
                BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
                BorderThickness="1"
                Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
                Translation="0,0,8">
            <Border.Shadow>
                <ThemeShadow />
            </Border.Shadow>
            <StackPanel Spacing="8">
                <!-- Section title + link to the running server's API. The link is
                     styled gray/non-bold (not white/bold) to read as a subtle href. -->
                <StackPanel Orientation="Horizontal" Spacing="8"
                            Margin="0,0,-2,0">
                    <TextBlock Text="Available"
                               FontSize="13"
                               FontWeight="SemiBold"
                               Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
                    <Button x:Name="ServerLink"
                            Click="ServerLink_Click"
                            Padding="0"
                            MinWidth="0"
                            MinHeight="0"
                            Opacity="0.55"
                            VerticalAlignment="Center"
                            ToolTipService.ToolTip="Open WebUI">
                        <FontIcon Glyph="&#xE8A7;"
                                  FontSize="14" />
                    </Button>
                </StackPanel>

                <!-- Empty state — shown when there are no local models. The text
                     is set from code (EmptyStatePresentation) and follows the
                     server state: starting/installing progress, an actionable hint
                     once running, an honest failure note when the server is down. -->
                <TextBlock x:Name="NoLocalModelsText"
                           Text="Starting the llama server…"
                           FontSize="13"
                           Foreground="{ThemeResource TextFillColorTertiaryBrush}"
                           HorizontalAlignment="Center"
                           TextAlignment="Center"
                           TextWrapping="Wrap"
                           Margin="0,8,0,8" />

                <!-- Local model rows (run on click). Capped at ~4 rows so the
                     section never pushes the Recommended list off-screen; scrolls
                     internally when there are more local models than that. -->
                <ScrollViewer MaxHeight="184"
                              VerticalScrollBarVisibility="Auto"
                              HorizontalScrollBarVisibility="Hidden"
                              HorizontalScrollMode="Disabled">
                    <ItemsRepeater x:Name="LocalModelsList"
                                   ItemsSource="{x:Bind LocalModels}"
                                   ItemTemplate="{StaticResource LocalModelRowTemplate}">
                        <ItemsRepeater.Layout>
                            <StackLayout Spacing="2" />
                        </ItemsRepeater.Layout>
                    </ItemsRepeater>
                </ScrollViewer>
            </StackPanel>
        </Border>

        <!-- ============ Section 3: Recommended Models (card; stretches, scrolls) ============
             The same Fluent card treatment as the Available section — the card
             stroke + elevation replace the divider line that used to separate
             the two sections. -->
        <Border Grid.Row="3"
                Margin="16,6,16,12"
                Padding="8,10"
                CornerRadius="4"
                BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
                BorderThickness="1"
                Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
                Translation="0,0,8">
            <Border.Shadow>
                <ThemeShadow />
            </Border.Shadow>
            <Grid RowSpacing="8">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" /> <!-- Header (fixed) -->
                    <RowDefinition Height="*" />    <!-- List (fills + scrolls) -->
                </Grid.RowDefinitions>

                <TextBlock Grid.Row="0"
                           Text="Recommended Models"
                           Margin="0,0,-2,0"
                           FontSize="13"
                           FontWeight="SemiBold"
                           Foreground="{ThemeResource TextFillColorSecondaryBrush}" />

                <!-- Scrolls internally when the list outgrows the stretched row. -->
                <ScrollViewer x:Name="RecommendedScroll"
                              Grid.Row="1"
                              Visibility="Collapsed"
                              VerticalScrollBarVisibility="Auto"
                              HorizontalScrollBarVisibility="Hidden"
                              HorizontalScrollMode="Disabled">
                    <ItemsRepeater x:Name="RecommendedModelsList"
                                   ItemsSource="{x:Bind RecommendedModels}"
                                   ItemTemplate="{StaticResource RecommendedModelRowTemplate}">
                        <ItemsRepeater.Layout>
                            <StackLayout Spacing="2" />
                        </ItemsRepeater.Layout>
                    </ItemsRepeater>
                </ScrollViewer>

                <!-- Catalog status: "Loading…" while the remote catalog is being
                     fetched; an error + Retry button if the fetch fails (previously
                     the section just stayed silently blank). -->
                <StackPanel x:Name="RecommendedStatusPanel"
                            Grid.Row="1"
                            VerticalAlignment="Center"
                            Spacing="10">
                    <TextBlock x:Name="RecommendedStatusText"
                               Text="Loading models…"
                               FontSize="12"
                               Foreground="{ThemeResource TextFillColorTertiaryBrush}"
                               HorizontalAlignment="Center"
                               TextAlignment="Center"
                               TextWrapping="Wrap" />
                    <Button x:Name="RetryCatalogButton"
                            Content="Retry"
                            Click="RetryCatalog_Click"
                            HorizontalAlignment="Center"
                            Visibility="Collapsed"
                            FontSize="12"
                            Padding="12,4"
                            MinHeight="0" />
                </StackPanel>
            </Grid>
        </Border>

        <Rectangle Grid.Row="4"
                   Height="1"
                   Margin="16,0"
                   Fill="{ThemeResource DividerStrokeColorDefaultBrush}" />

        <!-- ============ Section 4: Version footer (compact) ============
             A single centered line: a server-status dot (green = running,
             red = crashed, amber = starting, gray = stopped), the app's
             version (no name) and the resolved llama.cpp version separated
             by " - ", and a small relaunch button that appears only when
             the server is down. Bold theme foreground so it reads as a clear
             caption under the Recommended list in either OS theme. -->
        <StackPanel Grid.Row="5"
                    Margin="16,8,16,10"
                    HorizontalAlignment="Center"
                    Orientation="Horizontal"
                    Spacing="6">
            <Ellipse x:Name="ServerStatusDot"
                     Width="8"
                     Height="8"
                     VerticalAlignment="Center"
                     Fill="#8B949E" />
            <TextBlock x:Name="VersionText"
                       FontSize="11"
                       FontWeight="SemiBold"
                       Foreground="{ThemeResource TextFillColorPrimaryBrush}" />
            <Button x:Name="ServerRestartButton"
                    Click="ServerRestart_Click"
                    Padding="4"
                    MinWidth="0"
                    MinHeight="0"
                    Background="Transparent"
                    BorderThickness="0"
                    VerticalAlignment="Center"
                    Visibility="Collapsed"
                    AutomationProperties.Name="Relaunch the llama server"
                    ToolTipService.ToolTip="Relaunch the llama server">
                <FontIcon Glyph="&#xE72C;"
                          FontSize="11"
                          Opacity="0.7" />
            </Button>
        </StackPanel>

    </Grid>
    </UserControl>
</Window>
