+ {/* Hero. The site name lives in the top banner + nav brand, so the
+ h1 carries the product pitch instead to avoid "trails.cool"
+ triplication on a narrow strip. */}
+
{/* Marketing blurbs — flagship only. Self-hosted instances link out
@@ -245,14 +340,18 @@ export default function Home({ loaderData }: Route.ComponentProps) {
{a.name}
diff --git a/openspec/specs/journal-landing/spec.md b/openspec/specs/journal-landing/spec.md
index 9699f71..19b7153 100644
--- a/openspec/specs/journal-landing/spec.md
+++ b/openspec/specs/journal-landing/spec.md
@@ -1,33 +1,40 @@
## Purpose
-The Journal home page (`/`) serves two audiences with one layout: anonymous visitors arriving at the flagship trails.cool instance, and anyone landing on a self-hosted Journal instance. It introduces the product on the flagship, shows a public activity feed on every instance, and avoids asking self-hosters to write their own marketing copy.
+The Journal home page (`/`) serves three audiences with one route: anonymous visitors arriving at the flagship trails.cool instance, anyone landing on a self-hosted Journal instance, and signed-in users returning to *their own* home. It introduces the product to visitors on the flagship, shows a public activity feed on every instance for visitors, and swaps in a personal activity stream for signed-in users so "home" means "your stuff."
## Requirements
-### Requirement: Hero and auth CTAs
-The home page SHALL render a hero section with a product-describing headline, a short tagline, and — for logged-out visitors — Register and Sign In as the primary CTAs. A link to the Planner SHALL be available but visually secondary to auth, because the main conversion goal is account creation.
+### Requirement: Home behavior depends on session
+The `/` route SHALL render one of two distinct layouts based on whether the request carries a valid session. Signed-in users see a personal activity dashboard; signed-out visitors see the marketing + public-feed layout. The two layouts SHALL NOT render simultaneously — a signed-in user does not see the marketing blurbs, auth CTAs, or public instance feed on their home; a signed-out visitor does not see anyone's personal stream.
-#### Scenario: Logged-out visitor sees auth CTAs
+#### Scenario: Signed-in user gets the personal dashboard
+- **WHEN** a request to `/` carries a valid session
+- **THEN** the response is the personal dashboard layout (welcome + New Activity CTA + own activity stream)
+
+#### Scenario: Anonymous visitor gets the visitor home
+- **WHEN** a request to `/` carries no session
+- **THEN** the response is the visitor home layout (hero + auth CTAs + flagship-conditional marketing + public-feed)
+
+### Requirement: Visitor home hero and auth CTAs
+For signed-out visitors, the home page SHALL render a hero section with a product-describing headline, a short tagline, and Register and Sign In as the primary CTAs. A link to the Planner SHALL be available but visually secondary to auth, because the main conversion goal is account creation.
+
+#### Scenario: Auth CTAs are primary
- **WHEN** a visitor without a session loads the home page
- **THEN** Register (primary button) and Sign In (outlined button) appear together, with a smaller "Or try the Planner without an account →" link below them
-#### Scenario: Logged-in user sees welcome instead of CTAs
-- **WHEN** a signed-in user loads the home page
-- **THEN** the auth CTAs are replaced by a welcome line linking to their profile
-
### Requirement: Flagship-only marketing section
-The home page SHALL render a four-card marketing section (Planner / Journal / Federation / Ownership) if and only if the `IS_FLAGSHIP` environment variable is `"true"`. Self-hosted instances SHALL NOT render this block; instead they SHALL show a "Powered by trails.cool — about the project" link that points to `https://trails.cool` so operators don't have to author their own marketing copy.
+The visitor home SHALL render a four-card marketing section (Planner / Journal / Federation / Ownership) if and only if the `IS_FLAGSHIP` environment variable is `"true"`. Self-hosted instances SHALL NOT render this block; instead they SHALL show a "Powered by trails.cool — about the project" link that points to `https://trails.cool` so operators don't have to author their own marketing copy.
#### Scenario: Flagship shows marketing
-- **WHEN** the home page renders with `IS_FLAGSHIP=true`
+- **WHEN** the visitor home renders with `IS_FLAGSHIP=true`
- **THEN** the four marketing cards are shown and the "Powered by" link is suppressed
#### Scenario: Self-host shows the back-link
-- **WHEN** the home page renders with `IS_FLAGSHIP` unset or empty
+- **WHEN** the visitor home renders with `IS_FLAGSHIP` unset or empty
- **THEN** the marketing cards are not rendered and a "Powered by trails.cool — about the project" link appears below the feed
-### Requirement: Public activity feed on home
-The home page SHALL list the most recent public activities on the instance (see `activity-feed` spec, "Instance-wide public activity feed"). Each entry SHALL link to the activity detail page, show a map thumbnail when geometry is available, and display the owner's display name, distance, and start date.
+### Requirement: Public activity feed on visitor home
+The visitor home SHALL list the most recent public activities on the instance (see `activity-feed` spec, "Instance-wide public activity feed"). Each entry SHALL link to the activity detail page, show a map thumbnail when geometry is available, and display the owner's display name, distance, and start date.
#### Scenario: Feed populated
- **WHEN** public activities exist on the instance
@@ -35,4 +42,15 @@ The home page SHALL list the most recent public activities on the instance (see
#### Scenario: Empty feed
- **WHEN** the instance has no public activities
-- **THEN** the home shows an empty-state message instead of the feed list; all other sections (hero, marketing, CTAs) remain unchanged
+- **THEN** the visitor home shows an empty-state message instead of the feed list; all other sections (hero, marketing, CTAs) remain unchanged
+
+### Requirement: Personal dashboard for signed-in users
+For signed-in users, the home page SHALL render a personal activity dashboard: a welcome line linking to the user's profile, a "New Activity" CTA, and a reverse-chronological list of the user's own most recent activities (including `private`, `unlisted`, and `public`). The public instance feed SHALL NOT be rendered on this view; users who want it can browse other users' profiles or the dedicated activities/routes pages.
+
+#### Scenario: Dashboard shows user's own activities
+- **WHEN** a signed-in user loads the home page
+- **THEN** they see their own activities in reverse-chronological order, regardless of visibility, up to 20 entries
+
+#### Scenario: Dashboard empty state
+- **WHEN** a signed-in user has no activities yet
+- **THEN** the dashboard shows an empty-state message pointing to activity creation, while the welcome line and New Activity CTA remain visible
diff --git a/packages/i18n/src/locales/de.ts b/packages/i18n/src/locales/de.ts
index 2540763..1e23c29 100644
--- a/packages/i18n/src/locales/de.ts
+++ b/packages/i18n/src/locales/de.ts
@@ -190,6 +190,7 @@ export default {
heading: "Aktuelle Aktivitäten",
empty: "Noch keine öffentlichen Aktivitäten.",
},
+ dashboardEmpty: "Noch keine Aktivitäten. Erfasse oder importiere deine erste im Aktivitäten-Tab.",
poweredBy: "Powered by trails.cool — über das Projekt",
},
routes: {
diff --git a/packages/i18n/src/locales/en.ts b/packages/i18n/src/locales/en.ts
index 5d6ae44..f9130e3 100644
--- a/packages/i18n/src/locales/en.ts
+++ b/packages/i18n/src/locales/en.ts
@@ -190,6 +190,7 @@ export default {
heading: "Recent activity",
empty: "No public activities yet.",
},
+ dashboardEmpty: "No activities yet. Record or import your first one from the Activities tab.",
poweredBy: "Powered by trails.cool — about the project",
},
routes: {