๐ (openspec): Archive add-landing-page, sync landing-page spec, check off verified tasks
Changes
12 files changed, +254 -191
DELETE
openspec/changes/add-landing-page/.openspec.yaml
+0 -2
@@ -1,2 +0,0 @@
1
-schema: spec-driven
2
-created: 2026-06-19
DELETE
openspec/changes/add-landing-page/design.md
+0 -67
@@ -1,67 +0,0 @@
1
-## Context
2
-
3
-Today `HomeResource.home()` (`GET /`) calls `Templates.home(service.listVisibleTo(user), user)` for
4
-everyone. `user` is `null` for anonymous requests (`CurrentUser.get()` returns null when the
5
-identity is anonymous), so anonymous visitors see a repository table with no product context.
6
-
7
-Constraints: server-rendered Qute templates, no JavaScript (the rest of the UI is JS-free), must
8
-compile to a GraalVM native image, single shared `layout.html`. OIDC login already exists.
9
-
10
-## Goals / Non-Goals
11
-
12
-**Goals:**
13
-- Show a branded landing page to unauthenticated visitors at `/`.
14
-- Keep the authenticated repository-list experience byte-for-byte unchanged.
15
-- Glowing ASCII-art hero using only HTML + CSS.
16
-- Preserve anonymous access to public repositories via an explicit link.
17
-
18
-**Non-Goals:**
19
-- No marketing CMS, no content management, no i18n.
20
-- No JavaScript, animations beyond CSS, or external assets/fonts/images.
21
-- No change to auth, SSH, Git protocol, or database.
22
-
23
-## Decisions
24
-
25
-**Decision: Branch inside `HomeResource.home()` on authentication, not a new route.**
26
-Keep `GET /` as the single entry. `home()` checks `currentUser.get()`: null โ render
27
-`landing.html`; non-null โ render the existing repo list. Rationale: anonymous landing at the root
28
-is the requirement; a separate `/landing` path would still need a redirect from `/`.
29
-Alternative considered: redirect anonymous `/` โ `/welcome`. Rejected โ extra round-trip and a
30
-second public route to secure for no benefit.
31
-
32
-**Decision: Move the anonymous-reachable public repo list to an explicit link.**
33
-The landing page links to repository browsing (e.g. `/explore`, or reuse the existing list view
34
-behind a query/path). Rationale: the spec requires public browsing not be removed. Simplest
35
-implementation: add an `/explore` GET that renders the current `home.html` repo table for
36
-`service.listVisibleTo(null)`; the landing CTA points there. Alternative: keep repo list at `/`
37
-with landing above it โ rejected, muddies the hero.
38
-
39
-**Decision: ASCII-art glow via CSS `text-shadow` layers on a `<pre>` block.**
40
-Embed the shark ASCII art in a `<pre>` with a monospace font and stacked `text-shadow` (multiple
41
-blur radii in an accent color) over a dark background for the glow. Rationale: pure CSS, native-safe,
42
-no assets. Alternative: SVG filter glow โ heavier markup, no benefit at this fidelity.
43
-
44
-**Decision: Dedicated landing markup, minimal coupling to `layout.html`.**
45
-The logged-in `layout.html` header carries authenticated nav (SSH keys, tokens, logout). The
46
-landing page needs a different, anonymous header (Log in / self-host). Either add a `{#if user}`
47
-guard in the layout nav, or give the landing template its own lightweight shell. Prefer guarding
48
-the nav in `layout.html` so styling stays centralized.
49
-
50
-## Risks / Trade-offs
51
-
52
-- [ASCII glow renders poorly on very narrow viewports] โ wrap `<pre>` in an `overflow-x:auto`
53
- container and scale font with `clamp()`; accept horizontal scroll on tiny screens.
54
-- [Splitting repo list to `/explore` changes the anonymous URL people may have bookmarked] โ
55
- acceptable for a young project; `/` still reaches public repos in one click.
56
-- [Qute `@CheckedTemplate` requires a new `landing(...)` native method] โ add it alongside `home`;
57
- trivial, compile-checked.
58
-
59
-## Migration Plan
60
-
61
-Pure additive UI change. Deploy normally; no schema or config migration. Rollback = revert the
62
-template + `HomeResource` change. No data touched.
63
-
64
-## Open Questions
65
-
66
-- Exact path for public browsing: `/explore` (new) vs. a flag on `/`. Leaning `/explore`.
67
-- Final ASCII-art content for the shark โ placeholder until design-approved.
DELETE
openspec/changes/add-landing-page/proposal.md
+0 -40
@@ -1,40 +0,0 @@
1
-## Why
2
-
3
-Anonymous visitors currently land on the bare repository list (`/`), which gives no sense of what
4
-git-shark is or why it exists. First-time, unauthenticated visitors need a page that states the
5
-product's stance and invites them to log in or self-host โ not a raw table of public repos.
6
-
7
-## What Changes
8
-
9
-- Serve a dedicated **landing page** at `/` for unauthenticated requests, instead of the repository
10
- list. Logged-in users keep seeing their repository list unchanged.
11
-- The landing page presents the product positioning:
12
- - "Use AI as a tool, not as a feature"
13
- - "Focus on co-working, not lazy feeds"
14
- - "Easy and painless to self-host"
15
-- Visual treatment: hero section with the git-shark logo and tagline, styled via the shared
16
- `shark.css` design system (no JS, native-image friendly).
17
-- Primary call to action: **Log in** (existing OIDC flow). Secondary: link to self-hosting docs/repo.
18
-- Anonymous browsing of public repositories stays reachable via an explicit link (e.g. `/explore` or
19
- a "Browse public repositories" link), so no functionality is removed.
20
-
21
-## Capabilities
22
-
23
-### New Capabilities
24
-- `landing-page`: Unauthenticated entry page at `/` โ hero with glowing ASCII-art background, three
25
- value propositions, login CTA, self-host link, and a link to browse public repositories. Renders
26
- for anonymous users only; authenticated users are routed to the repository list.
27
-
28
-### Modified Capabilities
29
-<!-- No main specs exist yet (create-git-platform is not archived). web-ui requirement change for the
30
- anonymous `/` route is captured within this change's interaction with that pending capability;
31
- no separate delta spec is added here. -->
32
-
33
-## Impact
34
-
35
-- `web/HomeResource.java`: branch `home()` on `currentUser.get()` โ anonymous โ landing template,
36
- authenticated โ existing repo list (or move repo list to `/explore`).
37
-- New Qute template `HomeResource/landing.html` (+ shared `layout.html` may need a variant header
38
- without the logged-in nav).
39
-- New CSS for the dark hero + glowing ASCII art; no new dependencies, no JavaScript.
40
-- No database, SSH, or Git protocol changes.
DELETE
openspec/changes/add-landing-page/specs/landing-page/spec.md
+0 -55
@@ -1,55 +0,0 @@
1
-## ADDED Requirements
2
-
3
-### Requirement: Anonymous root serves the landing page
4
-
5
-The system SHALL serve a dedicated landing page at `GET /` when the request is unauthenticated.
6
-The system SHALL serve the existing repository list to authenticated users, so the change is
7
-invisible to logged-in users.
8
-
9
-#### Scenario: Anonymous visitor sees the landing page
10
-
11
-- **WHEN** an unauthenticated client requests `GET /`
12
-- **THEN** the system responds with `200` and renders the landing page (not the repository list)
13
-
14
-#### Scenario: Authenticated user keeps the repository list
15
-
16
-- **WHEN** an authenticated user requests `GET /`
17
-- **THEN** the system renders their visible repository list, unchanged from prior behavior
18
-
19
-### Requirement: Landing page presents product positioning
20
-
21
-The landing page SHALL display the three value propositions as visible text:
22
-"Use AI as a tool, not as a feature", "Focus on co-working, not lazy feeds", and
23
-"Easy and painless to self-host".
24
-
25
-#### Scenario: Value propositions are rendered
26
-
27
-- **WHEN** an unauthenticated client requests `GET /`
28
-- **THEN** the response body contains all three value-proposition statements
29
-
30
-### Requirement: Landing page hero with branding
31
-
32
-The landing page SHALL render a hero section with the git-shark logo and tagline, using the shared
33
-`shark.css` design system (no page-level inline `<style>` block), so branding stays consistent with
34
-the rest of the UI.
35
-
36
-#### Scenario: Hero renders logo and shared stylesheet
37
-
38
-- **WHEN** an unauthenticated client requests `GET /`
39
-- **THEN** the response links `/shark.css`, contains the `/img/shark-logo.png` logo, and carries no inline `<style>` block
40
-
41
-### Requirement: Landing page calls to action
42
-
43
-The landing page SHALL provide a primary "Log in" call to action that initiates the existing OIDC
44
-login flow, a link to self-hosting documentation/repository, and a link to browse public
45
-repositories so anonymous browsing is not removed.
46
-
47
-#### Scenario: Login CTA initiates OIDC flow
48
-
49
-- **WHEN** an anonymous visitor activates the "Log in" call to action
50
-- **THEN** the system initiates the OIDC authorization-code login flow
51
-
52
-#### Scenario: Public repositories remain reachable
53
-
54
-- **WHEN** an anonymous visitor activates the "Browse public repositories" link
55
-- **THEN** the system shows the list of repositories visible to anonymous users
DELETE
openspec/changes/add-landing-page/tasks.md
+0 -26
@@ -1,26 +0,0 @@
1
-## 1. Failing tests first
2
-
3
-- [x] 1.1 Add a test: anonymous `GET /` returns 200 and body contains all three value propositions ("Use AI as a tool, not as a feature", "Focus on co-working, not lazy feeds", "Easy and painless to self-host")
4
-- [x] 1.2 Add a test: anonymous `GET /` body does NOT render the repository table (asserts landing, not repo list)
5
-- [x] 1.3 Add a test: authenticated `GET /` still renders the repository list (existing behavior unchanged)
6
-- [x] 1.4 Add a test: anonymous `GET /explore` returns 200 and lists repositories visible to anonymous users
7
-- [x] 1.5 Run the suite, confirm the new tests fail (red)
8
-
9
-## 2. Backend routing
10
-
11
-- [x] 2.1 Add `landing()` native template method to `HomeResource.Templates` (`@CheckedTemplate`)
12
-- [x] 2.2 Branch `HomeResource.home()` on `currentUser.get()`: null โ `Templates.landing(...)`, non-null โ existing repo list
13
-- [x] 2.3 Add `GET /explore` endpoint rendering the repository list for `service.listVisibleTo(null)`
14
-- [x] 2.4 Add protected `GET /login` (in `authenticated` paths) that OIDC intercepts, then redirects to `/`
15
-
16
-## 3. Templates & styling
17
-
18
-- [x] 3.1 Create `templates/HomeResource/landing.html`: dark hero, glowing ASCII-art `<pre>` block, three value props, "Log in" CTA, self-host link, "Browse public repositories" โ `/explore`
19
-- [x] 3.2 Add CSS for the dark hero + glow (stacked `text-shadow`, monospace `<pre>`, `clamp()` font size, `overflow-x:auto` wrapper); no JavaScript
20
-- [x] 3.3 Landing renders a self-contained anonymous header (Log in / self-host) instead of guarding `layout.html` nav โ avoids hiding the authenticated nav on repo pages that don't pass `user`
21
-
22
-## 4. Verify
23
-
24
-- [x] 4.1 Run `./mvnw test` โ all tests green (52/52)
25
-- [ ] 4.2 Manual check in `quarkus:dev`: anonymous `/` shows hero, logged-in `/` shows repos, `/explore` lists public repos
26
-- [ ] 4.3 Update `README.md` if the public landing/`/explore` behavior is user-facing
ADD
openspec/changes/archive/2026-07-07-add-landing-page/.openspec.yaml
+2 -0
@@ -0,0 +1,2 @@
1
+schema: spec-driven
2
+created: 2026-06-19
ADD
openspec/changes/archive/2026-07-07-add-landing-page/design.md
+67 -0
@@ -0,0 +1,67 @@
1
+## Context
2
+
3
+Today `HomeResource.home()` (`GET /`) calls `Templates.home(service.listVisibleTo(user), user)` for
4
+everyone. `user` is `null` for anonymous requests (`CurrentUser.get()` returns null when the
5
+identity is anonymous), so anonymous visitors see a repository table with no product context.
6
+
7
+Constraints: server-rendered Qute templates, no JavaScript (the rest of the UI is JS-free), must
8
+compile to a GraalVM native image, single shared `layout.html`. OIDC login already exists.
9
+
10
+## Goals / Non-Goals
11
+
12
+**Goals:**
13
+- Show a branded landing page to unauthenticated visitors at `/`.
14
+- Keep the authenticated repository-list experience byte-for-byte unchanged.
15
+- Glowing ASCII-art hero using only HTML + CSS.
16
+- Preserve anonymous access to public repositories via an explicit link.
17
+
18
+**Non-Goals:**
19
+- No marketing CMS, no content management, no i18n.
20
+- No JavaScript, animations beyond CSS, or external assets/fonts/images.
21
+- No change to auth, SSH, Git protocol, or database.
22
+
23
+## Decisions
24
+
25
+**Decision: Branch inside `HomeResource.home()` on authentication, not a new route.**
26
+Keep `GET /` as the single entry. `home()` checks `currentUser.get()`: null โ render
27
+`landing.html`; non-null โ render the existing repo list. Rationale: anonymous landing at the root
28
+is the requirement; a separate `/landing` path would still need a redirect from `/`.
29
+Alternative considered: redirect anonymous `/` โ `/welcome`. Rejected โ extra round-trip and a
30
+second public route to secure for no benefit.
31
+
32
+**Decision: Move the anonymous-reachable public repo list to an explicit link.**
33
+The landing page links to repository browsing (e.g. `/explore`, or reuse the existing list view
34
+behind a query/path). Rationale: the spec requires public browsing not be removed. Simplest
35
+implementation: add an `/explore` GET that renders the current `home.html` repo table for
36
+`service.listVisibleTo(null)`; the landing CTA points there. Alternative: keep repo list at `/`
37
+with landing above it โ rejected, muddies the hero.
38
+
39
+**Decision: ASCII-art glow via CSS `text-shadow` layers on a `<pre>` block.**
40
+Embed the shark ASCII art in a `<pre>` with a monospace font and stacked `text-shadow` (multiple
41
+blur radii in an accent color) over a dark background for the glow. Rationale: pure CSS, native-safe,
42
+no assets. Alternative: SVG filter glow โ heavier markup, no benefit at this fidelity.
43
+
44
+**Decision: Dedicated landing markup, minimal coupling to `layout.html`.**
45
+The logged-in `layout.html` header carries authenticated nav (SSH keys, tokens, logout). The
46
+landing page needs a different, anonymous header (Log in / self-host). Either add a `{#if user}`
47
+guard in the layout nav, or give the landing template its own lightweight shell. Prefer guarding
48
+the nav in `layout.html` so styling stays centralized.
49
+
50
+## Risks / Trade-offs
51
+
52
+- [ASCII glow renders poorly on very narrow viewports] โ wrap `<pre>` in an `overflow-x:auto`
53
+ container and scale font with `clamp()`; accept horizontal scroll on tiny screens.
54
+- [Splitting repo list to `/explore` changes the anonymous URL people may have bookmarked] โ
55
+ acceptable for a young project; `/` still reaches public repos in one click.
56
+- [Qute `@CheckedTemplate` requires a new `landing(...)` native method] โ add it alongside `home`;
57
+ trivial, compile-checked.
58
+
59
+## Migration Plan
60
+
61
+Pure additive UI change. Deploy normally; no schema or config migration. Rollback = revert the
62
+template + `HomeResource` change. No data touched.
63
+
64
+## Open Questions
65
+
66
+- Exact path for public browsing: `/explore` (new) vs. a flag on `/`. Leaning `/explore`.
67
+- Final ASCII-art content for the shark โ placeholder until design-approved.
ADD
openspec/changes/archive/2026-07-07-add-landing-page/proposal.md
+40 -0
@@ -0,0 +1,40 @@
1
+## Why
2
+
3
+Anonymous visitors currently land on the bare repository list (`/`), which gives no sense of what
4
+git-shark is or why it exists. First-time, unauthenticated visitors need a page that states the
5
+product's stance and invites them to log in or self-host โ not a raw table of public repos.
6
+
7
+## What Changes
8
+
9
+- Serve a dedicated **landing page** at `/` for unauthenticated requests, instead of the repository
10
+ list. Logged-in users keep seeing their repository list unchanged.
11
+- The landing page presents the product positioning:
12
+ - "Use AI as a tool, not as a feature"
13
+ - "Focus on co-working, not lazy feeds"
14
+ - "Easy and painless to self-host"
15
+- Visual treatment: hero section with the git-shark logo and tagline, styled via the shared
16
+ `shark.css` design system (no JS, native-image friendly).
17
+- Primary call to action: **Log in** (existing OIDC flow). Secondary: link to self-hosting docs/repo.
18
+- Anonymous browsing of public repositories stays reachable via an explicit link (e.g. `/explore` or
19
+ a "Browse public repositories" link), so no functionality is removed.
20
+
21
+## Capabilities
22
+
23
+### New Capabilities
24
+- `landing-page`: Unauthenticated entry page at `/` โ hero with glowing ASCII-art background, three
25
+ value propositions, login CTA, self-host link, and a link to browse public repositories. Renders
26
+ for anonymous users only; authenticated users are routed to the repository list.
27
+
28
+### Modified Capabilities
29
+<!-- No main specs exist yet (create-git-platform is not archived). web-ui requirement change for the
30
+ anonymous `/` route is captured within this change's interaction with that pending capability;
31
+ no separate delta spec is added here. -->
32
+
33
+## Impact
34
+
35
+- `web/HomeResource.java`: branch `home()` on `currentUser.get()` โ anonymous โ landing template,
36
+ authenticated โ existing repo list (or move repo list to `/explore`).
37
+- New Qute template `HomeResource/landing.html` (+ shared `layout.html` may need a variant header
38
+ without the logged-in nav).
39
+- New CSS for the dark hero + glowing ASCII art; no new dependencies, no JavaScript.
40
+- No database, SSH, or Git protocol changes.
ADD
openspec/changes/archive/2026-07-07-add-landing-page/specs/landing-page/spec.md
+55 -0
@@ -0,0 +1,55 @@
1
+## ADDED Requirements
2
+
3
+### Requirement: Anonymous root serves the landing page
4
+
5
+The system SHALL serve a dedicated landing page at `GET /` when the request is unauthenticated.
6
+The system SHALL serve the existing repository list to authenticated users, so the change is
7
+invisible to logged-in users.
8
+
9
+#### Scenario: Anonymous visitor sees the landing page
10
+
11
+- **WHEN** an unauthenticated client requests `GET /`
12
+- **THEN** the system responds with `200` and renders the landing page (not the repository list)
13
+
14
+#### Scenario: Authenticated user keeps the repository list
15
+
16
+- **WHEN** an authenticated user requests `GET /`
17
+- **THEN** the system renders their visible repository list, unchanged from prior behavior
18
+
19
+### Requirement: Landing page presents product positioning
20
+
21
+The landing page SHALL display the three value propositions as visible text:
22
+"Use AI as a tool, not as a feature", "Focus on co-working, not lazy feeds", and
23
+"Easy and painless to self-host".
24
+
25
+#### Scenario: Value propositions are rendered
26
+
27
+- **WHEN** an unauthenticated client requests `GET /`
28
+- **THEN** the response body contains all three value-proposition statements
29
+
30
+### Requirement: Landing page hero with branding
31
+
32
+The landing page SHALL render a hero section with the git-shark logo and tagline, using the shared
33
+`shark.css` design system (no page-level inline `<style>` block), so branding stays consistent with
34
+the rest of the UI.
35
+
36
+#### Scenario: Hero renders logo and shared stylesheet
37
+
38
+- **WHEN** an unauthenticated client requests `GET /`
39
+- **THEN** the response links `/shark.css`, contains the `/img/shark-logo.png` logo, and carries no inline `<style>` block
40
+
41
+### Requirement: Landing page calls to action
42
+
43
+The landing page SHALL provide a primary "Log in" call to action that initiates the existing OIDC
44
+login flow, a link to self-hosting documentation/repository, and a link to browse public
45
+repositories so anonymous browsing is not removed.
46
+
47
+#### Scenario: Login CTA initiates OIDC flow
48
+
49
+- **WHEN** an anonymous visitor activates the "Log in" call to action
50
+- **THEN** the system initiates the OIDC authorization-code login flow
51
+
52
+#### Scenario: Public repositories remain reachable
53
+
54
+- **WHEN** an anonymous visitor activates the "Browse public repositories" link
55
+- **THEN** the system shows the list of repositories visible to anonymous users
ADD
openspec/changes/archive/2026-07-07-add-landing-page/tasks.md
+26 -0
@@ -0,0 +1,26 @@
1
+## 1. Failing tests first
2
+
3
+- [x] 1.1 Add a test: anonymous `GET /` returns 200 and body contains all three value propositions ("Use AI as a tool, not as a feature", "Focus on co-working, not lazy feeds", "Easy and painless to self-host")
4
+- [x] 1.2 Add a test: anonymous `GET /` body does NOT render the repository table (asserts landing, not repo list)
5
+- [x] 1.3 Add a test: authenticated `GET /` still renders the repository list (existing behavior unchanged)
6
+- [x] 1.4 Add a test: anonymous `GET /explore` returns 200 and lists repositories visible to anonymous users
7
+- [x] 1.5 Run the suite, confirm the new tests fail (red)
8
+
9
+## 2. Backend routing
10
+
11
+- [x] 2.1 Add `landing()` native template method to `HomeResource.Templates` (`@CheckedTemplate`)
12
+- [x] 2.2 Branch `HomeResource.home()` on `currentUser.get()`: null โ `Templates.landing(...)`, non-null โ existing repo list
13
+- [x] 2.3 Add `GET /explore` endpoint rendering the repository list for `service.listVisibleTo(null)`
14
+- [x] 2.4 Add protected `GET /login` (in `authenticated` paths) that OIDC intercepts, then redirects to `/`
15
+
16
+## 3. Templates & styling
17
+
18
+- [x] 3.1 Create `templates/HomeResource/landing.html`: dark hero, glowing ASCII-art `<pre>` block, three value props, "Log in" CTA, self-host link, "Browse public repositories" โ `/explore`
19
+- [x] 3.2 Add CSS for the dark hero + glow (stacked `text-shadow`, monospace `<pre>`, `clamp()` font size, `overflow-x:auto` wrapper); no JavaScript
20
+- [x] 3.3 Landing renders a self-contained anonymous header (Log in / self-host) instead of guarding `layout.html` nav โ avoids hiding the authenticated nav on repo pages that don't pass `user`
21
+
22
+## 4. Verify
23
+
24
+- [x] 4.1 Run `./mvnw test` โ all tests green (52/52)
25
+- [x] 4.2 Manual check in `quarkus:dev`: anonymous `/` shows hero, logged-in `/` shows repos, `/explore` lists public repos
26
+- [x] 4.3 Update `README.md` if the public landing/`/explore` behavior is user-facing
MODIFY
openspec/changes/create-git-platform/tasks.md
+1 -1
@@ -56,7 +56,7 @@
56
56
57
57
## 8. Native Build Completion & CI
58
58
59
-- [ ] 8.1 Extend native-image reflection/resource config for all features (Qute templates, OIDC, JGit pack machinery, MINA crypto); native build green
59
+- [x] 8.1 Extend native-image reflection/resource config for all features (Qute templates, OIDC, JGit pack machinery, MINA crypto); native build green
60
60
- [ ] 8.2 Native integration smoke tests: HTTP clone+push, SSH clone, OIDC-protected page, Flyway migration on boot
61
61
- [x] 8.3 CI pipeline: JVM tests + native build + native smoke tests on main-branch builds
62
62
- [x] 8.4 README: setup, configuration (storage root, SSH port, OIDC, Postgres), clone URL schemes, TLS-termination requirement for PAT auth
ADD
openspec/specs/landing-page/spec.md
+63 -0
@@ -0,0 +1,63 @@
1
+# landing-page Specification
2
+
3
+## Purpose
4
+
5
+Serve a public landing page at the root URL for unauthenticated visitors that presents git-shark's
6
+product positioning, branding, and calls to action (log in, self-host, browse public repositories),
7
+while keeping the repository list unchanged for authenticated users.
8
+
9
+## Requirements
10
+
11
+### Requirement: Anonymous root serves the landing page
12
+
13
+The system SHALL serve a dedicated landing page at `GET /` when the request is unauthenticated.
14
+The system SHALL serve the existing repository list to authenticated users, so the change is
15
+invisible to logged-in users.
16
+
17
+#### Scenario: Anonymous visitor sees the landing page
18
+
19
+- **WHEN** an unauthenticated client requests `GET /`
20
+- **THEN** the system responds with `200` and renders the landing page (not the repository list)
21
+
22
+#### Scenario: Authenticated user keeps the repository list
23
+
24
+- **WHEN** an authenticated user requests `GET /`
25
+- **THEN** the system renders their visible repository list, unchanged from prior behavior
26
+
27
+### Requirement: Landing page presents product positioning
28
+
29
+The landing page SHALL display the three value propositions as visible text:
30
+"Use AI as a tool, not as a feature", "Focus on co-working, not lazy feeds", and
31
+"Easy and painless to self-host".
32
+
33
+#### Scenario: Value propositions are rendered
34
+
35
+- **WHEN** an unauthenticated client requests `GET /`
36
+- **THEN** the response body contains all three value-proposition statements
37
+
38
+### Requirement: Landing page hero with branding
39
+
40
+The landing page SHALL render a hero section with the git-shark logo and tagline, using the shared
41
+`shark.css` design system (no page-level inline `<style>` block), so branding stays consistent with
42
+the rest of the UI.
43
+
44
+#### Scenario: Hero renders logo and shared stylesheet
45
+
46
+- **WHEN** an unauthenticated client requests `GET /`
47
+- **THEN** the response links `/shark.css`, contains the `/img/shark-logo.png` logo, and carries no inline `<style>` block
48
+
49
+### Requirement: Landing page calls to action
50
+
51
+The landing page SHALL provide a primary "Log in" call to action that initiates the existing OIDC
52
+login flow, a link to self-hosting documentation/repository, and a link to browse public
53
+repositories so anonymous browsing is not removed.
54
+
55
+#### Scenario: Login CTA initiates OIDC flow
56
+
57
+- **WHEN** an anonymous visitor activates the "Log in" call to action
58
+- **THEN** the system initiates the OIDC authorization-code login flow
59
+
60
+#### Scenario: Public repositories remain reachable
61
+
62
+- **WHEN** an anonymous visitor activates the "Browse public repositories" link
63
+- **THEN** the system shows the list of repositories visible to anonymous users