diff --git a/apps/web/tests/Home.test.tsx b/apps/web/tests/Home.test.tsx
index 8bdf6e2..b63a7da 100644
--- a/apps/web/tests/Home.test.tsx
+++ b/apps/web/tests/Home.test.tsx
@@ -66,4 +66,15 @@ describe('Home', () => {
expect(screen.getByRole('heading', { name: 'Sponsor' })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: 'Start a Project' })).toBeInTheDocument();
});
+
+ it('routes the anonymous "Start a Project" card through login, not the dead GitBook URL', async () => {
+ renderScreen(
+
+
+ ,
+ );
+
+ const card = screen.getByRole('link', { name: /Start a Project/i });
+ expect(card).toHaveAttribute('href', '/login?return=/projects/create');
+ });
});
diff --git a/plans/home-start-project-cta.md b/plans/home-start-project-cta.md
new file mode 100644
index 0000000..2c75819
--- /dev/null
+++ b/plans/home-start-project-cta.md
@@ -0,0 +1,85 @@
+---
+status: done
+depends: []
+specs:
+ - specs/screens/home.md
+issues: []
+pr: 128
+---
+
+# Plan: fix the home "Start a Project" CTA for logged-out visitors
+
+## Scope
+
+Leadership-team feedback (Kat + Travis, #0-leadership-team, June 2026, with
+mobile screenshots) reported the home page's "Start a Project" card landing on
+a dead page — `codeforphilly.gitbook.io/.../first-steps` now returns "Content
+owner not found". The reported "works on laptop, not phone" symptom was really
+**logged-in vs logged-out**, not responsive: the card branches on `person`, and
+the anonymous branch pointed at the legacy GitBook URL.
+
+What ships:
+
+- **Spec fix first.** `specs/screens/home.md` prescribed the GitBook URL for the
+ anonymous case — the spec was wrong, so it leads. Anonymous now routes through
+ `/login?return=/projects/create`, matching the already-correct Volunteer
+ screen convention (`volunteer.md:52`).
+- **Code fix.** `Home.tsx` anonymous branch → `/login?return=/projects/create`;
+ both branches are now in-app routes, so the `target="_blank"`/`rel` props drop
+ away (no more external navigation through react-router ``).
+
+## Implements
+
+- [home.md](../specs/screens/home.md) — Get-involved card table + Authorization
+ table: anonymous "Start a Project" routes through `/login?return=/projects/create`.
+
+## Approach
+
+### 1. Spec change (specops, source of truth first)
+
+`specs/screens/home.md` — Get-involved card link cell and the Authorization
+row both updated so the anonymous case is `/login?return=/projects/create`
+instead of the external GitBook URL.
+
+### 2. SPA: `apps/web/src/screens/Home.tsx`
+
+`to={person ? '/projects/create' : '/login?return=/projects/create'}` and
+remove the now-dead `target`/`rel` conditionals. Mirrors `Volunteer.tsx`.
+
+## Validation
+
+- [x] Spec updated: anonymous "Start a Project" → `/login?return=/projects/create`.
+- [x] `Home.tsx` anonymous branch routes in-app; no external GitBook URL remains.
+- [x] `target="_blank"`/`rel` props removed (both branches internal).
+- [x] Browser test: logged-out home → "Start a Project" → `/login?return=/projects/create`
+ renders the real sign-in page; GitHub link carries `return=%2Fprojects%2Fcreate`.
+- [x] `npm run type-check && npm run lint && npm test` clean (web 74/74, shared 75/75).
+
+## Risks
+
+- Low. One-line behavior change on a well-trodden auth-redirect path already
+ used by the Volunteer screen. `/login` honors `return` already.
+
+## Notes
+
+- The reported "works on laptop, not phone" was a misdiagnosis by the reporters:
+ the card never branched on viewport, only on auth state (`person`). They were
+ signed in on desktop, signed out on mobile. Worth remembering when triaging
+ future "mobile-only" reports against this SPA — check auth state first.
+- The footer's "Start a Project" link (`AppFooter.tsx`) always points at
+ `/projects/create` unconditionally; for an anon user that hits the route's own
+ auth guard rather than the friendly login redirect. Left as-is — out of scope,
+ and the route guard handles it — but noted in case we want footer parity later.
+
+## Follow-ups
+
+Separately surfaced in the same Slack thread, **not** part of this plan's scope
+(distinct features, not deferrals of this work):
+
+- **Issue:** admin can edit but not delete users (project "Danger Zone" has
+ delete; users don't) — parity gap reported by Travis.
+- **Issue:** legacy image fallback — serve old-site images for users/projects
+ (relates to the `codeforphilly-data-snapshot` work, #115).
+
+These are unrelated to the CTA fix and should be filed/triaged on their own; the
+CTA scope here is **None** outstanding.
diff --git a/specs/screens/home.md b/specs/screens/home.md
index 7abde87..68d0e5c 100644
--- a/specs/screens/home.md
+++ b/specs/screens/home.md
@@ -52,7 +52,7 @@ Three side-by-side cards (current site has these; they translate cleanly):
| Card | Heading | Body | Link |
| ---- | ------- | ---- | ---- |
| Sponsor | "Sponsor" | "Sponsor an event" | `/sponsor` |
-| Start a Project | "Start a Project" | "Start or get help on a project" | external GitBook URL from current site, or `/projects/create` for signed-in users |
+| Start a Project | "Start a Project" | "Start or get help on a project" | `/projects/create` for signed-in users, else `/login?return=/projects/create` |
| Volunteer | "Volunteer" | "Join our projects" | `/volunteer` |
### 4. Activity stream
@@ -101,7 +101,7 @@ Three side-by-side cards (current site has these; they translate cleanly):
| ------- | --------- | ---- |
| Hero CTA | "Volunteer" | "Browse Projects" |
| Featured projects | visible | visible |
-| Get involved | visible | visible — "Start a Project" link changes to in-app `/projects/create` form |
+| Get involved | visible — "Start a Project" routes through `/login?return=/projects/create` | visible — "Start a Project" links to the in-app `/projects/create` form |
| Activity stream | visible | visible |
| Help-wanted rail | visible | visible — "Express interest" CTA on each card (deferred polish; v1 just links to project page) |