diff --git a/apps/planner/app/routes/home.tsx b/apps/planner/app/routes/home.tsx
index de5d4e9..e9177de 100644
--- a/apps/planner/app/routes/home.tsx
+++ b/apps/planner/app/routes/home.tsx
@@ -3,20 +3,87 @@ import type { Route } from "./+types/home";
export function meta(_args: Route.MetaArgs) {
return [
- { title: "trails.cool Planner" },
- { name: "description", content: "Collaborative route planning" },
+ { title: "trails.cool Planner — Collaborative Route Planning" },
+ { name: "description", content: "Plan hiking and cycling routes together in real-time. No account needed." },
];
}
+const features = [
+ { key: "featureCollaborative", icon: "👥" },
+ { key: "featureRouting", icon: "🗺️" },
+ { key: "featureElevation", icon: "⛰️" },
+ { key: "featureExport", icon: "📥" },
+ { key: "featureNoAccount", icon: "🔓" },
+] as const;
+
export default function Home() {
const { t } = useTranslation("planner");
return (
-
-
-
{t("title")}
-
{t("subtitle")}
-
+
+ {/* Hero */}
+
+
+ {/* Features */}
+
+
+ {features.map(({ key, icon }) => (
+
+
{icon}
+
+ {t(`landing.${key}`)}
+
+
+ {t(`landing.${key}Desc`)}
+
+
+ ))}
+
+
+
+ {/* Secondary CTA */}
+
+
+ {/* Footer */}
+
);
}
diff --git a/e2e/planner.test.ts b/e2e/planner.test.ts
index 0d7d67c..67d6c97 100644
--- a/e2e/planner.test.ts
+++ b/e2e/planner.test.ts
@@ -3,8 +3,8 @@ import { test, expect } from "@playwright/test";
test.describe("Planner", () => {
test("loads the home page", async ({ page }) => {
await page.goto("/");
- await expect(page).toHaveTitle("trails.cool Planner");
- await expect(page.getByText("Collaborative route planning")).toBeVisible();
+ await expect(page).toHaveTitle(/trails\.cool Planner/);
+ await expect(page.getByRole("link", { name: "Start Planning" })).toBeVisible();
});
test("can create a session via API", async ({ request }) => {
diff --git a/openspec/changes/planner-landing-page/.openspec.yaml b/openspec/changes/archive/2026-03-25-planner-landing-page/.openspec.yaml
similarity index 100%
rename from openspec/changes/planner-landing-page/.openspec.yaml
rename to openspec/changes/archive/2026-03-25-planner-landing-page/.openspec.yaml
diff --git a/openspec/changes/planner-landing-page/design.md b/openspec/changes/archive/2026-03-25-planner-landing-page/design.md
similarity index 100%
rename from openspec/changes/planner-landing-page/design.md
rename to openspec/changes/archive/2026-03-25-planner-landing-page/design.md
diff --git a/openspec/changes/planner-landing-page/proposal.md b/openspec/changes/archive/2026-03-25-planner-landing-page/proposal.md
similarity index 100%
rename from openspec/changes/planner-landing-page/proposal.md
rename to openspec/changes/archive/2026-03-25-planner-landing-page/proposal.md
diff --git a/openspec/changes/planner-landing-page/specs/planner-session/spec.md b/openspec/changes/archive/2026-03-25-planner-landing-page/specs/planner-session/spec.md
similarity index 100%
rename from openspec/changes/planner-landing-page/specs/planner-session/spec.md
rename to openspec/changes/archive/2026-03-25-planner-landing-page/specs/planner-session/spec.md
diff --git a/openspec/changes/archive/2026-03-25-planner-landing-page/tasks.md b/openspec/changes/archive/2026-03-25-planner-landing-page/tasks.md
new file mode 100644
index 0000000..53095da
--- /dev/null
+++ b/openspec/changes/archive/2026-03-25-planner-landing-page/tasks.md
@@ -0,0 +1,16 @@
+## 1. Landing Page Content
+
+- [x] 1.1 Rewrite Planner home.tsx with hero section: heading, subtitle, "Start Planning" CTA linking to /new
+- [x] 1.2 Add feature highlights section (4-5 cards): collaborative editing, routing profiles, elevation profile, GPX export, no account needed
+- [x] 1.3 Add secondary CTA: "Save your routes on trails.cool" linking to Journal
+- [x] 1.4 Add footer: privacy link, GitHub repo, BRouter/OSM attribution
+
+## 2. i18n
+
+- [x] 2.1 Add all landing page strings to en.ts and de.ts (hero, features, CTAs, footer)
+
+## 3. Verify
+
+- [x] 3.1 Verify landing page renders correctly at planner.trails.cool
+- [x] 3.2 Verify "Start Planning" creates a session and redirects
+- [x] 3.3 Update E2E planner test if home page assertions changed
diff --git a/openspec/changes/planner-landing-page/tasks.md b/openspec/changes/planner-landing-page/tasks.md
deleted file mode 100644
index 0506515..0000000
--- a/openspec/changes/planner-landing-page/tasks.md
+++ /dev/null
@@ -1,16 +0,0 @@
-## 1. Landing Page Content
-
-- [ ] 1.1 Rewrite Planner home.tsx with hero section: heading, subtitle, "Start Planning" CTA linking to /new
-- [ ] 1.2 Add feature highlights section (4-5 cards): collaborative editing, routing profiles, elevation profile, GPX export, no account needed
-- [ ] 1.3 Add secondary CTA: "Save your routes on trails.cool" linking to Journal
-- [ ] 1.4 Add footer: privacy link, GitHub repo, BRouter/OSM attribution
-
-## 2. i18n
-
-- [ ] 2.1 Add all landing page strings to en.ts and de.ts (hero, features, CTAs, footer)
-
-## 3. Verify
-
-- [ ] 3.1 Verify landing page renders correctly at planner.trails.cool
-- [ ] 3.2 Verify "Start Planning" creates a session and redirects
-- [ ] 3.3 Update E2E planner test if home page assertions changed
diff --git a/openspec/specs/planner-session/spec.md b/openspec/specs/planner-session/spec.md
index 9e20ba9..9f86e40 100644
--- a/openspec/specs/planner-session/spec.md
+++ b/openspec/specs/planner-session/spec.md
@@ -73,6 +73,21 @@ The Planner SHALL display presence indicators showing which users are currently
- **WHEN** a user disconnects from the session
- **THEN** their cursor disappears from all other participants' maps within 5 seconds
+### Requirement: Planner home page
+The Planner home page SHALL explain the tool's purpose and provide a one-click way to start planning.
+
+#### Scenario: First-time visitor
+- **WHEN** a user visits planner.trails.cool for the first time
+- **THEN** they see a landing page explaining collaborative route planning, key features, and a prominent "Start Planning" button
+
+#### Scenario: Start a session
+- **WHEN** a user clicks "Start Planning"
+- **THEN** a new anonymous session is created and the user is redirected to the session view
+
+#### Scenario: Journal link
+- **WHEN** a user wants to save routes permanently
+- **THEN** a secondary CTA links to trails.cool for account creation
+
### Requirement: No user data collection
The Planner SHALL NOT collect, store, or track any personal user data. Sessions are anonymous by default.
diff --git a/packages/i18n/src/locales/de.ts b/packages/i18n/src/locales/de.ts
index 9e86754..dea861c 100644
--- a/packages/i18n/src/locales/de.ts
+++ b/packages/i18n/src/locales/de.ts
@@ -39,6 +39,28 @@ export default {
loss: "Höhenmeter abwärts",
profile: "Höhenprofil",
},
+ landing: {
+ startPlanning: "Planung starten",
+ heroDescription: "Plane Wander- und Radrouten gemeinsam in Echtzeit. Kein Konto nötig.",
+ featureCollaborative: "Echtzeit-Zusammenarbeit",
+ featureCollaborativeDesc: "Wegpunkte gemeinsam bearbeiten — Änderungen werden sofort synchronisiert.",
+ featureRouting: "Intelligentes Routing",
+ featureRoutingDesc: "BRouter berechnet optimale Routen für Wandern, Radfahren oder Autofahren mit Höhenprofil.",
+ featureElevation: "Höhenprofil",
+ featureElevationDesc: "Das vollständige Höhenprofil deiner Route mit Auf- und Abstiegsstatistiken.",
+ featureExport: "GPX-Export",
+ featureExportDesc: "Exportiere deine Route als GPX für jedes GPS-Gerät oder jede App.",
+ featureNoAccount: "Kein Konto nötig",
+ featureNoAccountDesc: "Sofort loslegen. Teile einen Link und jeder kann deiner Sitzung beitreten.",
+ saveRoutes: "Routen speichern?",
+ saveRoutesDesc: "Erstelle ein kostenloses Konto auf trails.cool, um Routen zu speichern, Aktivitäten zu verfolgen und mehr.",
+ goToJournal: "Zu trails.cool",
+ footer: {
+ privacy: "Datenschutz",
+ source: "Quellcode",
+ builtWith: "Erstellt mit BRouter und OpenStreetMap",
+ },
+ },
},
journal: {
title: "trails.cool",
diff --git a/packages/i18n/src/locales/en.ts b/packages/i18n/src/locales/en.ts
index c5b3837..3842de0 100644
--- a/packages/i18n/src/locales/en.ts
+++ b/packages/i18n/src/locales/en.ts
@@ -39,6 +39,28 @@ export default {
loss: "Elevation Loss",
profile: "Elevation Profile",
},
+ landing: {
+ startPlanning: "Start Planning",
+ heroDescription: "Plan hiking and cycling routes together in real-time. No account needed.",
+ featureCollaborative: "Real-Time Collaboration",
+ featureCollaborativeDesc: "Edit waypoints together — changes sync instantly across all participants.",
+ featureRouting: "Smart Routing",
+ featureRoutingDesc: "BRouter computes optimal routes for hiking, cycling, or driving with elevation awareness.",
+ featureElevation: "Elevation Profile",
+ featureElevationDesc: "See the full elevation profile of your route with gain and loss statistics.",
+ featureExport: "GPX Export",
+ featureExportDesc: "Export your route as GPX for use in any GPS device or app.",
+ featureNoAccount: "No Account Needed",
+ featureNoAccountDesc: "Start planning immediately. Share a link and anyone can join your session.",
+ saveRoutes: "Want to save your routes?",
+ saveRoutesDesc: "Create a free account on trails.cool to keep your routes, track activities, and more.",
+ goToJournal: "Go to trails.cool",
+ footer: {
+ privacy: "Privacy",
+ source: "Source Code",
+ builtWith: "Built with BRouter and OpenStreetMap",
+ },
+ },
},
journal: {
title: "trails.cool",