diff --git a/DECISIONS.md b/DECISIONS.md
index 719e0cb..0617316 100644
--- a/DECISIONS.md
+++ b/DECISIONS.md
@@ -662,3 +662,9 @@ Implementation decisions not spelled out in `memory-bank/implementation-plan.md`
- **The picker runs `validateReposition` per destination**, so the client and server agree on what is possible. Fuel is `tripFuelCost` and time is `tripRealMs` with zero cargo, the same inputs the sim's reposition record uses.
- **The action shows on every idle ship, crewed or not.** An uncrewed ship's options are all disabled with "No pilot assigned", which tells the player what to fix rather than hiding the action.
- **Disabled destinations still show fuel and time**, so the player can see how far off they are.
+
+## Step 10B.9
+
+- **The delivery picker is a dialog with radio buttons and a "Buy for N cr" confirm**, so buying always takes two taps, even with one bay (preselected). The confirm is disabled until a bay is chosen.
+- **"Bay owned" now reads "Your HQ is here"**, and the map panel says "Your HQ is here." or "No HQ here."; the player-facing word for a bay is HQ, while the action keeps "Lease bay" as in the CR.
+- **The success message names the delivery location** ("… is waiting at Moon.") instead of always Earth.
diff --git a/apps/web/src/screens/Locations.tsx b/apps/web/src/screens/Locations.tsx
index 8d5ea8f..5aea0ae 100644
--- a/apps/web/src/screens/Locations.tsx
+++ b/apps/web/src/screens/Locations.tsx
@@ -1,4 +1,5 @@
import { content, type Location } from "@deadhead/content";
+import { Link } from "react-router";
import { useClock } from "../clock/clock";
import { cargoName, formatCredits, formatMillionKm } from "../format";
import { distanceAt } from "../game";
@@ -10,9 +11,13 @@ const TYPE_LABELS: Record = {
"cloud-platform": "Cloud platform",
"belt-station": "Belt station",
};
+/** What a bay is for (CR-002: bays are HQs, not access to contracts). */
+export const HQ_EXPLANATION =
+ "Open an HQ here: hire pilots and take delivery of new ships at this location.";
+
const LANDING_LABELS = { vacuum: "Any ship", atmospheric: "Atmospheric", hardened: "Hardened" };
-/** Every location; details and bay leasing only once discovered (Step 9.9). */
+/** Every location; details, contracts and HQ leasing once discovered (Steps 9.9, 10B.9). */
export function Locations() {
const state = useLoadedPlayer();
const now = useClock((s) => s.now);
@@ -59,18 +64,27 @@ export function Locations() {
+
+ >
)}
);
diff --git a/apps/web/src/screens/MapScreen.tsx b/apps/web/src/screens/MapScreen.tsx
index 9215e81..989c254 100644
--- a/apps/web/src/screens/MapScreen.tsx
+++ b/apps/web/src/screens/MapScreen.tsx
@@ -72,7 +72,7 @@ function Panel({
);
}
-/** A tapped location: details if discovered, and a link to its board if there is a bay. */
+/** A tapped location: details and a link to its contracts once discovered (CR-002). */
function LocationPanel({ locationId, onClose }: { locationId: string; onClose: () => void }) {
const state = useLoadedPlayer();
const now = useClock((s) => s.now);
@@ -95,16 +95,13 @@ function LocationPanel({ locationId, onClose }: { locationId: string; onClose: (
Produces {location.produces.map(cargoName).join(", ") || "nothing"} · demands{" "}
{location.demands.map(cargoName).join(", ") || "nothing"}
- {hasBay ? (
-
- View contract board
-
- ) : (
-
No bay here yet.
- )}
+
+ View contracts
+
+
{hasBay ? "Your HQ is here." : "No HQ here."}
>
) : (
<>
diff --git a/apps/web/src/screens/Market.tsx b/apps/web/src/screens/Market.tsx
index 6cb82d6..6af3185 100644
--- a/apps/web/src/screens/Market.tsx
+++ b/apps/web/src/screens/Market.tsx
@@ -1,19 +1,22 @@
-import { content } from "@deadhead/content";
-import { formatCredits, formatMillionKm } from "../format";
+import { content, type ShipModel } from "@deadhead/content";
+import { useState } from "react";
+import { formatCredits, formatMillionKm, locationName } from "../format";
import { errorMessage, useGameAction, useLoadedPlayer } from "../state/actions";
const LANDING_LABELS = { vacuum: "Vacuum", atmospheric: "Atmospheric", hardened: "Hardened" };
-/** Ship models for sale, delivered to the first bay until Step 10B.9's bay picker (Step 9.8). */
+/** Ship models for sale, delivered to the HQ (bay) the player picks (Steps 9.8, 10B.9). */
export function Market() {
const state = useLoadedPlayer();
const buy = useGameAction("buyShip");
- const bay = state.bays[0];
+ const [buying, setBuying] = useState(null);
return (
Market
-
New ships are delivered to Earth with no pilot.
+
+ New ships are delivered with no pilot to one of your HQs.
+