diff --git a/README.md b/README.md
index 3cf0049..7f37934 100644
--- a/README.md
+++ b/README.md
@@ -268,11 +268,20 @@ the reasoning behind it. Sign in, unlock, browse hosts, open a shell, and read t
host-key decisions and the counted delete confirmations are there too, and none of them were softened to
fit 360dp.
-Its interface is the **v2 design**: four destinations in a bottom bar — Hosts, Terminal, Keychain and More
-— with snippets, SFTP, S3 buckets, logs and preferences one tap deeper behind the last. Both heads are on
-that design now; the desktop's own v2 is a 190-pixel labelled sidebar in place of the icon rail, a centred
-search box in the titlebar, and session tabs as pills. Its light theme is not built — see
-[`docs/design-import-gaps.md`](docs/design-import-gaps.md) — so the application is dark on both.
+Its interface is the **v2 design**: destinations in a bottom bar, with the rest one tap deeper behind the
+last. The bar is three — **Hosts**, **Connections** and **Settings** — with the keychain, snippets, SFTP,
+S3 buckets, logs and preferences behind Settings. A bottom bar is for the places a session moves between,
+and managing keys is not one of those. Both heads are on that design now; the desktop's own v2 is a
+190-pixel labelled sidebar in place of the icon rail, a centred search box in the titlebar, and session tabs
+as pills, and it keeps its Keychain entry — a rail with nine slots has room. Its light theme is not built —
+see [`docs/design-import-gaps.md`](docs/design-import-gaps.md) — so the application is dark on both.
+
+**Connections is where a connection is made, not only where one is shown.** With nothing open it offers a
+box taking `user@host` or `user@host:port` and a password, and lists the machines most recently connected
+to underneath. That box is the one path in the product to a machine the keychain has never heard of — the
+case somebody has just been handed an address — and nothing typed into it is saved: a machine worth keeping
+belongs on Hosts, where it can carry a key, a group's defaults and a name. Tapping a recent machine goes to
+its host if it has one and back into the box if it does not.
**A connected phone shows one bar and then the terminal.** The header, the session strip and the bottom
bar are collapsed while a shell is up, and a single 35-pixel row replaces them: back on the left, the
diff --git a/docs/android-port.md b/docs/android-port.md
index d9242fe..2adb52d 100644
--- a/docs/android-port.md
+++ b/docs/android-port.md
@@ -493,11 +493,18 @@ go at 360dp:
**Superseded by v2.** A second design — *DodoSSH Android v2* — is what this head now draws, and it took
the "additive rather than structural" claim at its word: snippets, logs, SFTP and S3 are built, over the
- view models that were already shared, behind a MORE hub that holds the five destinations the bottom bar
- has no room for. `ShellScreen` gained `More` and `Buckets`. The palette went blue and the two heads moved
- together, because it is shared. What v2 asked for and did not get is in
+ view models that were already shared, behind a hub that holds the destinations the bottom bar has no room
+ for. `ShellScreen` gained `More` and `Buckets`. The palette went blue and the two heads moved together,
+ because it is shared. What v2 asked for and did not get is in
[`docs/design-import-gaps.md`](design-import-gaps.md) — the short version being that port forwarding is
named as absent rather than drawn, because nothing in the SSH layer forwards anything.
+
+ **The bar has since gone from four entries to three.** The keychain joined the hub, which is now called
+ SETTINGS rather than MORE and wears a gear: a bottom bar is for the places a session moves between, and
+ managing keys is not one of them. `IsMoreSurface` gained `ShellScreen.Vault`, which is the whole of it —
+ the membership test, the tab that lights and the back gesture's first case all read that one property.
+ The desktop keeps its Keychain rail entry, so this is the second thing the two heads arrange
+ deliberately differently, after the hub itself.
8. ~~**The terminal.**~~ **Done** — one `NativeWebView` for every session, as on the desktop and for the
same reason, with the tab strip scrolling horizontally rather than wrapping so that opening a tab never
reflows a terminal while output is arriving.
@@ -516,6 +523,24 @@ go at 360dp:
WebView actually composites above Avalonia content is still the unverified question recorded below, and
collapsing is correct under either answer.
+ **The + also puts the software keyboard away, and that needed the platform.** `TopLevel.InputPane`
+ reports the keyboard and cannot close one — Avalonia's model is that it belongs to whatever has focus, so
+ the supported dismissal is to move focus — and the keyboard over a terminal was raised by the `WebView`'s
+ own text input, by a native view Avalonia's focus manager never owned. Clearing Avalonia's focus does
+ nothing to it. `Platform/SoftKeyboard.cs` asks `InputMethodManager` directly, off the decor view's window
+ token, and every step of it is allowed to be absent. Without it the sheet arrives under a keyboard
+ covering the half of the screen the sheet is on — and worse, laid out into what is left, since the
+ keyboard's inset shortens everything this head draws.
+
+ **With nothing open the surface is a connect screen rather than an empty state**, which is why the bar
+ calls it Connections. It offers a `user@host[:port]` box with a password and the machines most recently
+ connected to, out of the vault's connection log. The connect path in `VaultViewModel` was shaped like
+ `HostRowViewModel` all the way down; it now hangs off a four-field `ConnectionTarget`, so the ladder of
+ refusals, the host-key question, the log entry and the tab's lifecycle are shared rather than copied. The
+ host-key retry replays the attempt that raised the question instead of re-running whichever host was
+ selected — which was correct while a selected host was the only way to connect, and would now dial the
+ wrong machine.
+
All eight are done for the decided scope, and v2 has since gone past it — see the note under step 7.
What is left, in the order it matters:
diff --git a/docs/design-import-gaps.md b/docs/design-import-gaps.md
index 9492bba..25f42fb 100644
--- a/docs/design-import-gaps.md
+++ b/docs/design-import-gaps.md
@@ -6,10 +6,18 @@ the chrome, hosts and terminals, file transfer, the vault, teams, and preference
> ## The second import — v2, phone
>
> A later design in the same project, **DodoSSH Android v2**, is what the phone head now draws: eight
-> screens, a bottom bar of four with the rest behind MORE, and a new palette. It has been imported, and
+> screens, a bottom bar with the rest behind a hub, and a new palette. It has been imported, and
> this section is the same accounting for it. The desktop's own v2 has **not** been imported — only its
> palette, because the palette is shared and the two heads may not disagree about a colour.
>
+> **The bar is three rather than the design's four, and the hub is SETTINGS rather than MORE.** The design
+> puts Hosts, Terminal, Keychain and More along the bottom. The keychain moved behind the hub: a bottom bar
+> is for the places a session moves between, and keys, credentials and tags are managed occasionally and
+> then left alone, which is the shape of everything already behind it. With the keychain on it the hub is no
+> longer "more" of anything — it is where everything that is not connecting to a machine lives — so it takes
+> the name and the glyph that has meant exactly that on a phone since before this application existed.
+> Terminal became **Connections** in the same pass, for a reason below.
+>
> **The palette went from green to blue, and one colour changed meaning rather than value.** Green used to
> be the accent, so `Ellipse.dot.live` filled with `Accent` and "the thing to press" and "a shell is open
> here" were the same colour by construction. v2 makes the accent `#5B8CFF` and keeps a green, `#3DDC97`,
@@ -37,6 +45,7 @@ the chrome, hosts and terminals, file transfer, the vault, teams, and preference
> | A 14px rounded inset around the terminal | Not drawn. The renderer is a native child view composited above everything Avalonia draws, so a rounded frame behind it clips nothing. What the design was after comes from the page's own background, which is the design's `#171A26`. |
> | Instrument Sans / Fira Code | Inter and the system monospace stack, as before and for the same reason — see the note on `MonoFont` in `Palette.axaml`. |
> | A theme toggle (`☀`) in the header, and the desktop v2's light theme | Omitted. There is one theme by decision, and a switch with one position is a control that does nothing. |
+> | TERMINAL's empty state: a sentence saying nothing is open | ◆ **More than the design asked for, which is rare enough on this list to say out loud.** The tab is called **Connections** and with nothing running the screen is where one is made: a box taking `user@host` or `user@host:port` with a password, and the machines most recently connected to underneath it, read from the vault's own connection log. The box is the only path in the product to a machine that is not in the keychain — the design assumes every connection starts from a saved host, and the case it has no answer for is an address somebody was handed five minutes ago. Nothing typed there is saved, and the screen says so. |
>
> ## The desktop's v2
>
diff --git a/docs/manual-checks.md b/docs/manual-checks.md
index f6e0c67..f2d1f5e 100644
--- a/docs/manual-checks.md
+++ b/docs/manual-checks.md
@@ -952,3 +952,54 @@ visibly disabled rather than silently inert.
**Failure means:** they have been folded into the scrolling row — which is the arrangement the connection
line existed to avoid, and the reason it could be removed at all.
+
+### 11.6 The keyboard goes away with the connect menu
+
+With a shell open, tap into the terminal so the software keyboard comes up, then press `+`.
+
+**Pass:** the keyboard drops and the sheet sits on the bottom of the full screen, all four of its rows
+reachable. Repeat on Android 14 or earlier and on 15 or later if you have both — the keyboard shortens this
+head's interface by a different mechanism on each, and a sheet laid out into the strip left above a
+keyboard is the failure this exists to catch.
+
+**Failure means:** `SoftKeyboard.Hide` found no activity, no input-method manager, or the wrong window
+token. Note that Avalonia cannot do this for us — `TopLevel.InputPane` reports the keyboard and cannot close
+one, and the keyboard here belongs to the `WebView`, so clearing Avalonia's focus is not a fallback.
+
+### 11.7 Connections, with nothing open
+
+Close every tab, then press Connections in the bottom bar.
+
+**Pass:** a box reading `user@host or user@host:port`, a password box under it, CONNECT, and — if this
+keychain has ever connected to anything — a RECENT list underneath. The whole thing scrolls with the
+keyboard up, and the password box shows dots with **no suggestion strip** above the keyboard.
+
+Type a machine you can reach and press CONNECT: a tab appears in the bar and the shell opens. Type
+something malformed — no `user@`, or `:70000` — and the refusal appears under the boxes, in the warning
+colour, with no tab and nothing dialled.
+
+**Failure means:** for the suggestion strip, the box lost `Classes="secret"` — see 10.1, and it is the same
+seriousness here, since this password is typed rather than stored and so is typed often.
+
+### 11.8 A recent machine leads to the right place
+
+With at least one keychain host and one machine connected to by hand in the log, open Connections with
+nothing running.
+
+**Pass:** tapping the keychain one lands on HOSTS with that host selected and its connect bar up. Tapping
+the hand-typed one puts its address back in the box on this screen and leaves the password box **empty**.
+Neither one dials anything on its own.
+
+**Failure means:** if the hand-typed one navigates to HOSTS, the log entry is carrying a host id it should
+not have. If the password came back, something is storing it — it never was.
+
+### 11.9 Settings holds the keychain, and back walks out of it
+
+From HOSTS: Settings, then Keychain.
+
+**Pass:** the bottom bar has three entries and the Settings one stays lit while the keychain is showing.
+The keychain draws its own header with a back arrow — the vault name and sync light are not above it. Back,
+by gesture or by the arrow, returns to Settings and not to HOSTS; a second back returns to HOSTS.
+
+**Failure means:** `ShellScreen.Vault` is missing from `IsMoreSurface` or from the back gesture's first
+case, and those two have to move together — the switch mirrors that property by construction.
diff --git a/src/DodoSSH.Client.Android/Platform/SoftKeyboard.cs b/src/DodoSSH.Client.Android/Platform/SoftKeyboard.cs
new file mode 100644
index 0000000..c79782b
--- /dev/null
+++ b/src/DodoSSH.Client.Android/Platform/SoftKeyboard.cs
@@ -0,0 +1,50 @@
+using global::Android.Content;
+using global::Android.Views.InputMethods;
+
+namespace DodoSSH.Client.Android.Platform;
+
+///
+/// Puts the software keyboard away.
+///
+///
+///
+/// There is no Avalonia way to do this, and it is worth knowing why rather than assuming.
+/// TopLevel.InputPane reports the keyboard — its state and the rectangle it occludes, which is what
+/// PhoneShell keeps the interface clear of — and offers nothing that closes it. The framework's model
+/// is that the keyboard belongs to whatever has focus, so the supported way to dismiss one is to move focus
+/// off the text box that raised it.
+///
+///
+/// That model does not reach the case this exists for. The keyboard over a terminal was raised by the
+/// WebView's own text input, inside the page, by a native view Avalonia's focus manager does not own.
+/// Clearing Avalonia's focus leaves it exactly where it is, because Avalonia never had it. So the request
+/// goes to the platform that does own it.
+///
+///
+/// HideSoftInputFromWindow needs a window token, and any attached view's will do — they all belong to
+/// the same window. The decor view is the one guaranteed to exist for as long as the activity does.
+///
+///
+/// Every step is allowed to be absent and none of them is an error: there is no activity while the app is
+/// backgrounded, no input-method manager on a system image without one, and no keyboard up most of the time.
+/// A method whose whole contract is "if a keyboard is showing, stop showing it" has nothing to report when
+/// one is not.
+///
+///
+internal static class SoftKeyboard
+{
+ public static void Hide()
+ {
+ if (PhoneEnvironment.CurrentActivity?.Window?.DecorView is not { } view)
+ {
+ return;
+ }
+
+ if (view.Context?.GetSystemService(Context.InputMethodService) is not InputMethodManager manager)
+ {
+ return;
+ }
+
+ manager.HideSoftInputFromWindow(view.WindowToken, HideSoftInputFlags.None);
+ }
+}
diff --git a/src/DodoSSH.Client.Android/Views/KeychainScreen.axaml b/src/DodoSSH.Client.Android/Views/KeychainScreen.axaml
index b0bf8ba..5342a69 100644
--- a/src/DodoSSH.Client.Android/Views/KeychainScreen.axaml
+++ b/src/DodoSSH.Client.Android/Views/KeychainScreen.axaml
@@ -1,6 +1,7 @@
@@ -26,12 +27,30 @@
Mode=OneWay on the chips is load-bearing: a two-way selection binding moves the chip before the command
beside it has had the chance to refuse, which would leave the row lit for a section the list is not on.
+
+ ── v3 ────────────────────────────────────────────────────────────────────────────────────────────────
+ This screen moved behind SETTINGS, so it draws its own header — the one every hub screen has. It is not
+ a decoration: the shell's header stands down behind the hub, and without a row of its own there would be
+ no back arrow and nothing on screen saying what this list is.
-->
-
+
+
+
+
+
+
+
+
-
@@ -91,7 +110,7 @@
them are still waiting to be pushed — which is the honest version of the design's unconditional
"synced".
-->
-
+
-
@@ -120,7 +139,7 @@
-
+
-
+
+
+
+
+
+