<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="using:DodoSSH.Client.Shell.ViewModels"
             xmlns:views="using:DodoSSH.Client.Android.Views"
             x:Class="DodoSSH.Client.Android.Views.HostsScreen"
             x:DataType="vm:VaultViewModel"
             Background="{StaticResource Canvas}">

  <!--
    Design 01 — HOSTS, the phone's home.

    The desktop's sidebar and its right-hand connect column cannot both be on screen at 360dp, so they are
    the same column here: the list fills the screen, and choosing a host raises the connect bar over the
    bottom of it. That is the one structural change from the design, and it is why the bar names the host
    it will connect to — on the desktop the selection is visible beside the button, and here it is not.

    Groups are rows in the same list rather than a nesting container, which is what SidebarRows already
    hands both heads. The desktop shows group headings only when groups exist and so does this, for free.

    ── v2 ────────────────────────────────────────────────────────────────────────────────────────────────
    The rows became cards: rounded, inset from the edge, and filled when chosen rather than marked with a
    strip.

    ── v3 ────────────────────────────────────────────────────────────────────────────────────────────────
    The design's floating + arrives, three versions after it was first asked for. It was refused twice on
    the grounds that it would open an editor this head had not got — hosts were created on the desktop and
    synced down — and that was true until the editors below existed. It opens a sheet rather than a form,
    because "add" on this screen has been two operations since groups existed: a host, or a group to file
    hosts under.

    Both editors are cards in the list's own row, swapped for the list rather than stacked over it, which is
    what SnippetsScreen does and for the reason written there: a form on top of the list hides what it is
    about. There is no dialog and no editor screen anywhere on this head.
  -->

  <!--
    The Panel is what lets the add sheet cover the screen. The + does not need it — it is layered inside the
    list's own Grid row, which is where it has to be so that the connect bar pushes it up rather than being
    covered by it. See the button itself.
  -->
  <Panel>

  <Grid RowDefinitions="Auto,Auto,*,Auto">

    <!-- ============ filter ============ -->
    <!--
      The design's "Search or connect…" well. On the desktop this is Ctrl+K over a palette; on a phone the
      list is already the palette, so it filters in place rather than opening a second surface.
    -->
    <Border Grid.Row="0" Margin="14,10,14,4" Background="{StaticResource Field}"
            BorderBrush="{StaticResource BorderMid}" BorderThickness="1" CornerRadius="11" Height="44">
      <Grid ColumnDefinitions="Auto,*">
        <TextBlock Grid.Column="0" Text="⌕" Foreground="{StaticResource TextFaint}" FontSize="13"
                   Margin="13,0,0,0" VerticalAlignment="Center" />
        <TextBox Grid.Column="1" Text="{Binding HostFilter}" PlaceholderText="Search hosts"
                 Padding="9,0" VerticalContentAlignment="Center"
                 Background="Transparent" BorderThickness="0"
                 Foreground="{StaticResource Text}" FontFamily="{StaticResource MonoFont}" FontSize="12" />
      </Grid>
    </Border>

    <!-- ============ sync + conflicts ============ -->
    <StackPanel Grid.Row="1" Margin="16,4,16,0" Spacing="7">

      <TextBlock Classes="detail" Text="{Binding Status}" TextWrapping="Wrap" />

      <!--
        ◆ The conflict log. The merge is only allowed to pick a winner because this exists, so it is a
        banner the user has to dismiss rather than a screen they might never open.
      -->
      <Border IsVisible="{Binding HasConflicts}" Background="{StaticResource WarnWash}"
              BorderBrush="{StaticResource WarnSoft}" BorderThickness="1" CornerRadius="12" Padding="13,11">
        <StackPanel Spacing="9">
          <ItemsControl ItemsSource="{Binding Conflicts}">
            <ItemsControl.ItemTemplate>
              <DataTemplate x:DataType="vm:ConflictRowViewModel">
                <TextBlock Classes="detail" Foreground="{StaticResource WarnText}" TextWrapping="Wrap"
                           Text="{Binding Summary}" Margin="0,2" />
              </DataTemplate>
            </ItemsControl.ItemTemplate>
          </ItemsControl>
          <Button Classes="secondary" Height="40" Content="DISMISS ALL" FontSize="10"
                  Command="{Binding AcknowledgeAllConflictsCommand}" />
        </StackPanel>
      </Border>

      <Border IsVisible="{Binding HasUnreadableItems}" Background="{StaticResource DangerWash}"
              BorderBrush="{StaticResource DangerSoft}" BorderThickness="1" CornerRadius="12" Padding="13,11">
        <TextBlock Classes="detail" Foreground="{StaticResource DangerText}" TextWrapping="Wrap"
                   Text="{Binding UnreadableSummary}" />
      </Border>
    </StackPanel>

    <!-- ============ the list ============ -->
    <ListBox Grid.Row="2" Margin="0,6,0,0" IsVisible="{Binding !AnEditorIsOpen}"
             ItemsSource="{Binding SidebarRows}"
             SelectedItem="{Binding SelectedSidebarRow}"
             Background="Transparent" BorderThickness="0">

      <ListBox.Styles>
        <!--
          The chosen row is a filled card. The corner radius is on the item rather than on a Border inside
          it so that the fill the theme draws for selection is the rounded one — a radius set inside would
          leave a square highlight behind a rounded row.
        -->
        <Style Selector="ListBoxItem">
          <Setter Property="Padding" Value="0" />
          <Setter Property="MinHeight" Value="0" />
          <Setter Property="Margin" Value="10,1" />
          <Setter Property="CornerRadius" Value="12" />
        </Style>
        <Style Selector="ListBoxItem:selected /template/ ContentPresenter">
          <Setter Property="Background" Value="{StaticResource Active}" />
          <Setter Property="CornerRadius" Value="12" />
        </Style>
      </ListBox.Styles>

      <ListBox.DataTemplates>

        <!--
          A group heading. SidebarGroupHeader, not HostGroupRowViewModel — the latter is a row in the
          groups editor, and the two are deliberately different shapes: this one carries the count *after*
          the filter, which is what a heading over a filtered list has to say.
        -->
        <DataTemplate DataType="vm:SidebarGroupHeader">
          <Grid ColumnDefinitions="Auto,*,Auto,Auto" Margin="8,12,8,5">
            <TextBlock Grid.Column="0" Classes="detail" Text="{Binding Chevron}" VerticalAlignment="Center" />
            <TextBlock Grid.Column="1" Classes="section" Text="{Binding Label}" Margin="7,0,0,0" />
            <TextBlock Grid.Column="2" Classes="detail" Text="{Binding Count}" FontSize="9"
                       VerticalAlignment="Center" />

            <!--
              The phone's only way into a group's editor. The desktop reaches it from a groups panel this
              head does not draw, and a heading's own selection deliberately bounces back to the host — so
              without this a group could be created here and never corrected, which matters more for a group
              than for a host: its defaults are what every host beneath it falls back to.

              Hidden on the ungrouped heading, which has no group behind it to edit.
            -->
            <Button Grid.Column="3" Classes="icon" FontSize="13" Content="✎" Margin="4,0,0,0"
                    IsVisible="{Binding GroupId, Converter={x:Static ObjectConverters.IsNotNull}}"
                    Command="{Binding $parent[views:HostsScreen].((vm:VaultViewModel)DataContext).EditGroupFromHeadingCommand}"
                    CommandParameter="{Binding}" />
          </Grid>
        </DataTemplate>

        <!-- A host. -->
        <DataTemplate DataType="vm:HostRowViewModel">
          <Grid ColumnDefinitions="Auto,*,Auto" MinHeight="56" Margin="14,12">

            <!-- Green means a terminal is open on this host right now. See the .dot style. -->
            <Ellipse Grid.Column="0" Classes="dot" Classes.live="{Binding IsConnected}" Width="8" Height="8"
                     VerticalAlignment="Center" />

            <StackPanel Grid.Column="1" Margin="12,0,0,0" Spacing="3" VerticalAlignment="Center">
              <StackPanel Orientation="Horizontal" Spacing="7">
                <TextBlock Classes="mono" Text="{Binding Label}" FontSize="14" FontWeight="SemiBold"
                           TextTrimming="CharacterEllipsis" />
                <Border Classes="tag outline" IsVisible="{Binding HasVaultBadge}">
                  <TextBlock Text="{Binding VaultBadge}" />
                </Border>
                <Border Classes="tag outline" BorderBrush="{StaticResource WarnSoft}"
                        IsVisible="{Binding Badge, Converter={x:Static StringConverters.IsNotNullOrEmpty}}">
                  <TextBlock Foreground="{StaticResource Warn}" Text="{Binding Badge}" />
                </Border>
              </StackPanel>
              <StackPanel Orientation="Horizontal" Spacing="6">
                <TextBlock Classes="detail" FontSize="10.5" Text="{Binding Address}"
                           TextTrimming="CharacterEllipsis" />
                <TextBlock Classes="detail" FontSize="10.5" Text="·" />
                <TextBlock Classes="detail" FontSize="10.5" Text="{Binding Authentication}" />
              </StackPanel>

              <!--
                The design's tag chips, and the row is where they were always meant to be — what a machine
                *is*, under what it is called and where it answers. Wrapped rather than trimmed: a host
                wearing four tags on a 360dp row takes a second line, which is the honest shape.
              -->
              <ItemsControl ItemsSource="{Binding TagLabels}" IsVisible="{Binding HasTags}"
                            Margin="0,2,0,0">
                <ItemsControl.ItemsPanel>
                  <ItemsPanelTemplate><WrapPanel /></ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                  <DataTemplate x:DataType="x:String">
                    <Border Classes="tag" Margin="0,0,4,3">
                      <TextBlock Text="{Binding}" />
                    </Border>
                  </DataTemplate>
                </ItemsControl.ItemTemplate>
              </ItemsControl>
            </StackPanel>

            <!--
              The design's "live" tag, on exactly the hosts the dot is green for — and in the same green,
              overriding the tag style's accent text. A status word in the accent colour beside a green dot
              meaning the same thing would be one fact drawn in two colours.
            -->
            <Border Grid.Column="2" Classes="tag" IsVisible="{Binding IsConnected}"
                    Background="{StaticResource LiveWash}">
              <TextBlock Text="live" Foreground="{StaticResource Live}" />
            </Border>
            <TextBlock Grid.Column="2" Text="›" Foreground="{StaticResource TextGhost}" FontSize="15"
                       VerticalAlignment="Center" IsVisible="{Binding !IsConnected}" />
          </Grid>
        </DataTemplate>

      </ListBox.DataTemplates>
    </ListBox>

    <!-- ============ the host editor ============ -->
    <!--
      In the list's row and swapped for it, following SnippetsScreen. Every field is the shared view model's
      — the same properties the desktop's sidebar binds — so the two heads cannot drift about what a host
      is or what saving one does.

      ◆ The port and username boxes may be left empty, and empty is not "unset": it means the host takes its
      group's. The watermark on each is what it will actually get, and it follows the group picker below as
      that moves, so the form says what leaving a box blank will do rather than making it a guess. See
      HostInheritance.
    -->
    <Border Grid.Row="2" Classes="card" Margin="12,0" IsVisible="{Binding IsEditing}"
            VerticalAlignment="Top">
      <ScrollViewer MaxHeight="560">
        <StackPanel Spacing="10">
          <TextBlock Classes="label" Text="HOST" />

          <TextBox Classes="field" Text="{Binding EditorLabel}" PlaceholderText="name" />
          <TextBox Classes="field" Text="{Binding EditorHostname}" PlaceholderText="hostname or address" />

          <Grid ColumnDefinitions="*,8,2*">
            <NumericUpDown Grid.Column="0" Value="{Binding EditorPort}" Minimum="1" Maximum="65535"
                           FormatString="0" ShowButtonSpinner="False" MinHeight="44"
                           PlaceholderText="{Binding EditorPortPlaceholder}" />
            <TextBox Grid.Column="2" Classes="field" Text="{Binding EditorUsername}"
                     PlaceholderText="{Binding EditorUsernamePlaceholder}" />
          </Grid>

          <TextBox Classes="field" Text="{Binding EditorNotes}" PlaceholderText="notes" />

          <!--
            One picker for all of them, as on the desktop, which is what makes "a key or a credential, never
            both" impossible to express rather than merely invalid. The qualifier beside each label matters
            for the same reason it does there: a key called deploy and the deploy account's password are the
            ordinary case, and bare labels would offer two identical-looking entries.
          -->
          <TextBlock Classes="label" Text="AUTHENTICATION" Margin="0,4,0,0" />
          <ComboBox ItemsSource="{Binding EditorAuthenticationChoices}"
                    SelectedItem="{Binding EditorSelectedAuthentication}"
                    HorizontalAlignment="Stretch" MinHeight="44">
            <ComboBox.ItemTemplate>
              <DataTemplate x:DataType="vm:AuthenticationChoice">
                <StackPanel Orientation="Horizontal" Spacing="6">
                  <TextBlock Classes="mono" FontSize="12" Text="{Binding Label}" />
                  <TextBlock Classes="detail" FontSize="10" VerticalAlignment="Center"
                             Text="{Binding Qualifier}"
                             IsVisible="{Binding Qualifier, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
                </StackPanel>
              </DataTemplate>
            </ComboBox.ItemTemplate>
          </ComboBox>

          <TextBlock Classes="label" Text="GROUP" Margin="0,4,0,0" />
          <ComboBox ItemsSource="{Binding EditorGroupChoices}"
                    SelectedItem="{Binding EditorSelectedGroup}"
                    HorizontalAlignment="Stretch" MinHeight="44">
            <ComboBox.ItemTemplate>
              <DataTemplate x:DataType="vm:GroupChoice">
                <TextBlock Classes="mono" FontSize="12" Text="{Binding Label}" />
              </DataTemplate>
            </ComboBox.ItemTemplate>
          </ComboBox>

          <!--
            ◆ The tags this host wears. Chips that toggle, matching the chips on the row behind this card —
            a list of names to tick would make the user match an entry to a chip they can see.

            The box under them creates one and puts it on straight away, which is where a tag is usually
            wanted: while tagging a host and finding it does not exist yet. It writes to the keychain
            immediately, unlike every other field here, because a host can only name a tag that has an id —
            so cancelling this editor leaves the tag behind. Renaming and deleting are on the keychain
            screen, with every other item kind.
          -->
          <TextBlock Classes="label" Text="TAGS" Margin="0,4,0,0" />

          <ItemsControl ItemsSource="{Binding EditorTagChoices}" IsVisible="{Binding HasTagChoices}">
            <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate><WrapPanel /></ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
              <DataTemplate x:DataType="vm:TagChoice">
                <Button Classes="chiptoggle" Classes.worn="{Binding IsWorn}" Margin="0,0,6,6"
                        Command="{Binding $parent[ItemsControl].((vm:VaultViewModel)DataContext).ToggleEditorTagCommand}"
                        CommandParameter="{Binding}">
                  <TextBlock Classes="mono" FontSize="11.5" Text="{Binding Label}" />
                </Button>
              </DataTemplate>
            </ItemsControl.ItemTemplate>
          </ItemsControl>

          <Grid ColumnDefinitions="*,8,Auto">
            <TextBox Grid.Column="0" Classes="field" Text="{Binding EditorNewTag}"
                     PlaceholderText="new tag" />
            <Button Grid.Column="2" Classes="secondary" Height="44" Width="72" Content="ADD"
                    Command="{Binding AddEditorTagCommand}" />
          </Grid>

          <!--
            ◆ The one control here that publishes something. Turning it on copies this host's address and
            port into plaintext columns the server can read, which is the single deliberate concession in
            the design — see ADR 0004 — so it says so rather than being a switch labelled "relay".
          -->
          <CheckBox IsChecked="{Binding EditorRelayEnabled}" MinHeight="44">
            <TextBlock Classes="mono" FontSize="11.5" Text="Reach this host through the server relay"
                       TextWrapping="Wrap" />
          </CheckBox>
          <TextBlock Classes="body"
                     Text="The relay dials on your behalf, so this host's address and port are stored on the server in the clear. Everything else about it stays encrypted. A relayed host also needs a port of its own rather than its group's." />

          <Grid ColumnDefinitions="*,8,*">
            <Button Grid.Column="0" Classes="primary" Height="44" Content="SAVE"
                    Command="{Binding SaveHostCommand}" />
            <Button Grid.Column="2" Classes="secondary" Height="44" Content="CANCEL"
                    Command="{Binding CancelEditCommand}" />
          </Grid>
        </StackPanel>
      </ScrollViewer>
    </Border>

    <!-- ============ the group editor ============ -->
    <!--
      The same card in the same row, and a group is now enough of a thing to need one: a name, where it sits
      in the tree, and the three things hosts inside it fall back to. Every one of those may be left empty,
      and empty means the group lends nothing rather than that it has not been filled in.

      The parent picker leaves out this group and everything beneath it, so a cycle cannot be made here. That
      is a courtesy rather than the guarantee — one assembled from two offline re-parents was never offered
      this list, which is why the walk itself stops at a repeat.
    -->
    <Border Grid.Row="2" Classes="card" Margin="12,0" IsVisible="{Binding IsEditingGroup}"
            VerticalAlignment="Top">
      <ScrollViewer MaxHeight="560">
        <StackPanel Spacing="10">
          <TextBlock Classes="label" Text="GROUP" />

          <TextBox Classes="field" Text="{Binding GroupEditorLabel}" PlaceholderText="group name" />

          <TextBlock Classes="label" Text="INSIDE" Margin="0,4,0,0" />
          <ComboBox ItemsSource="{Binding GroupEditorParentChoices}"
                    SelectedItem="{Binding GroupEditorSelectedParent}"
                    HorizontalAlignment="Stretch" MinHeight="44">
            <ComboBox.ItemTemplate>
              <DataTemplate x:DataType="vm:GroupChoice">
                <TextBlock Classes="mono" FontSize="12" Text="{Binding Label}" />
              </DataTemplate>
            </ComboBox.ItemTemplate>
          </ComboBox>

          <TextBlock Classes="label" Text="HOSTS INSIDE FALL BACK TO" Margin="0,6,0,0" />

          <Grid ColumnDefinitions="*,8,2*">
            <NumericUpDown Grid.Column="0" Value="{Binding GroupEditorDefaultPort}" Minimum="1"
                           Maximum="65535" FormatString="0" ShowButtonSpinner="False" MinHeight="44"
                           PlaceholderText="no default" />
            <TextBox Grid.Column="2" Classes="field" Text="{Binding GroupEditorDefaultUsername}"
                     PlaceholderText="no default user" />
          </Grid>

          <ComboBox ItemsSource="{Binding GroupEditorAuthenticationChoices}"
                    SelectedItem="{Binding GroupEditorSelectedAuthentication}"
                    HorizontalAlignment="Stretch" MinHeight="44">
            <ComboBox.ItemTemplate>
              <DataTemplate x:DataType="vm:AuthenticationChoice">
                <StackPanel Orientation="Horizontal" Spacing="6">
                  <TextBlock Classes="mono" FontSize="12" Text="{Binding Label}" />
                  <TextBlock Classes="detail" FontSize="10" VerticalAlignment="Center"
                             Text="{Binding Qualifier}"
                             IsVisible="{Binding Qualifier, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
                </StackPanel>
              </DataTemplate>
            </ComboBox.ItemTemplate>
          </ComboBox>

          <TextBlock Classes="body"
                     Text="A host inside this group uses these wherever it says nothing itself. They are read at connect time rather than copied in, so changing one here changes every host that never overrode it." />

          <Grid ColumnDefinitions="*,8,*">
            <Button Grid.Column="0" Classes="primary" Height="44" Content="SAVE"
                    Command="{Binding SaveGroupCommand}" />
            <Button Grid.Column="2" Classes="secondary" Height="44" Content="CANCEL"
                    Command="{Binding CancelGroupEditCommand}" />
          </Grid>
        </StackPanel>
      </ScrollViewer>
    </Border>

    <!-- ============ connect ============ -->
    <!--
      Raised over the list when a host is chosen, because the desktop's right-hand column has nowhere to go
      at this width. It names the host: the selection that is obvious on a wide window is not obvious here.

      Gone entirely while an editor is up, rather than merely greyed. The editor replaces the list above it,
      so a bar left in place would be a set of buttons about a host that is no longer on screen — and the
      one underneath the host editor would be about the very record being typed into. Disabling it was the
      first attempt and it is worse: a dimmed CONNECT under an open form reads as a screen that has broken
      rather than as one that is busy.
    -->
    <Border Grid.Row="3" IsVisible="{Binding ShowsConnectBar}"
            Background="{StaticResource Chrome}" BorderBrush="{StaticResource Border}"
            BorderThickness="0,1,0,0" Padding="14,12">
      <StackPanel Spacing="10">

        <StackPanel Orientation="Horizontal" Spacing="8">
          <TextBlock Classes="label" Text="CONNECT TO" />
          <TextBlock Classes="mono" FontSize="11" Text="{Binding SelectedHost.Label}" />
        </StackPanel>

        <!--
          Shown only for a host that actually asks for one. A password box beside a key-authenticated host
          is an invitation to type a secret nothing will use.

          The tick below it is the phone's whole answer to storing one, and on this head it is the only one:
          the keychain lists credentials here but has no editor to create one in, so before this a password
          typed on a phone could only ever be typed again. The host editor's picker could then bind it.
        -->
        <TextBox Classes="field secret" IsVisible="{Binding SelectedHostAsksForAPassword}"
                 Text="{Binding ConnectPassword}" PlaceholderText="password">
          <TextBox.KeyBindings>
            <KeyBinding Gesture="Enter" Command="{Binding ConnectCommand}" />
          </TextBox.KeyBindings>
        </TextBox>

        <CheckBox IsChecked="{Binding RemembersConnectPassword}" MinHeight="44"
                  IsVisible="{Binding SelectedHostAsksForAPassword}">
          <TextBlock Classes="mono" FontSize="11.5" TextWrapping="Wrap"
                     Text="Remember this password for this host" />
        </CheckBox>

        <TextBlock Classes="detail" TextWrapping="Wrap" IsVisible="{Binding !SelectedHostAsksForAPassword}"
                   Text="{Binding SelectedHostAuthenticationNote}" />

        <Button Classes="primary" Content="CONNECT" Command="{Binding ConnectCommand}"
                IsEnabled="{Binding !IsBusy}" />

        <!--
          Not asked for by the design, and here because a + that adds hosts with no way to correct one is a
          strange thing to ship. It costs nothing: the editor above serves both, so this is the same panel
          opened on an existing row.
        -->
        <Button Classes="secondary" Height="44" Content="EDIT"
                Command="{Binding EditSelectedHostCommand}" />
      </StackPanel>
    </Border>

    <!-- ============ add ============ -->
    <!--
      ◆ The design's floating +, and the reason every version of this file until now said it could not be
      drawn.

      <b>Grid.Row 2, inside the Grid — not the Panel around it — and the difference is the whole control.</b>
      The plan asked for the outer Panel so the button would not move. A Panel child aligned to the bottom is
      anchored to the bottom of the screen, and the connect bar is a row of that same Grid: the 56px circle
      would then sit squarely over EDIT and the lower edge of CONNECT, and because a Panel hit-tests its
      last-declared child first, tapping the right end of EDIT would raise the add sheet instead. Covering
      CONNECT is the one thing on this screen that must not happen.

      In the list's row it rides up as the connect bar appears, which is what a floating button does on every
      other Android application and what a thumb reaches for. It moves; that is the cost, and it is the
      smaller one.

      Hidden rather than disabled while anything is open over the list. A + that opens an editor on top of an
      open editor is a control with nothing to do, and disabling it would leave a large accented circle on
      screen saying so.
    -->
    <Button Grid.Row="2" Classes="fab" Content="+" Margin="0,0,18,18"
            HorizontalAlignment="Right" VerticalAlignment="Bottom"
            IsVisible="{Binding !AnEditorIsOpen}"
            Command="{Binding OpenAddSheetCommand}" />

  </Grid>

    <!-- ============ the add sheet ============ -->
    <!--
      Follows HostKeySheet, this head's one existing sheet: a scrim, a bottom-aligned panel with the top two
      corners rounded, and a grab handle that is decoration. Two things it does differently, both because it
      is a menu rather than a decision.

      It is dismissible. Tapping the scrim closes it, which HostKeySheet deliberately refuses — answering
      "do you trust this key" by tapping beside it is the swipe-to-dismiss that head was built to avoid.
      "Which kind of thing are you adding" has no wrong answer and no answer at all is one of them.

      And it lives here rather than in PhoneShell. HostKeySheet sits up there because the files screen raises
      it too; nothing but this screen raises this. The cost is that the scrim covers the screen and not the
      64px nav bar underneath, so the four destinations stay lit and tappable — which for a menu is right:
      navigating away is a perfectly good way to decide not to add anything.
    -->
    <Panel IsVisible="{Binding IsAddSheetOpen}">

      <!--
        Declared before the sheet so the sheet draws over it: a Panel stacks its children in declaration
        order. See the .scrim style for why a tap on it must not light anything up.
      -->
      <Button Classes="scrim" Command="{Binding CloseAddSheetCommand}" />

      <Border VerticalAlignment="Bottom" Background="{StaticResource Panel}"
              BorderBrush="{StaticResource BorderMid}" BorderThickness="0,1,0,0"
              CornerRadius="22,22,0,0" Padding="20,18,20,16">
        <StackPanel Spacing="0">

          <Border Width="38" Height="4" CornerRadius="2" Background="{StaticResource BorderMid}"
                  HorizontalAlignment="Center" Margin="0,0,0,16" />

          <TextBlock Classes="title" Text="ADD" FontSize="13" />

          <Button Classes="row" Margin="0,10,0,0" Command="{Binding NewHostCommand}">
            <StackPanel Spacing="3" VerticalAlignment="Center">
              <TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="New host" />
              <TextBlock Classes="detail" FontSize="10.5"
                         Text="A machine to connect to, filed under a group if you want one." />
            </StackPanel>
          </Button>

          <Button Classes="row" Command="{Binding NewGroupCommand}">
            <StackPanel Spacing="3" VerticalAlignment="Center">
              <TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="New group" />
              <TextBlock Classes="detail" FontSize="10.5"
                         Text="A heading for hosts, and the port, user and key they fall back to." />
            </StackPanel>
          </Button>

          <Button Classes="secondary" Content="CANCEL" Margin="0,12,0,0"
                  Command="{Binding CloseAddSheetCommand}" />

        </StackPanel>
      </Border>
    </Panel>

  </Panel>

</UserControl>
