Commitf8e5fea
feat(landing): replace thin 6-feature homepage with full marketing machine
feat(landing): replace thin 6-feature homepage with full marketing machine New LandingProPage (Stripe/Linear aesthetic): pure white, Inter Tight headlines, single #4353c9 accent, zero cyberpunk. 13 sections covering all 50+ platform surfaces — product breadth grid, developer painkiller table, 4 AI feature deep-dives, security matrix, teams+enterprise, ecosystem cards, comparison table, pricing teaser, and closing CTA. Wires publicStats + all 4 demo-activity feeds (queued, merges, reviews, activity) into the route so the live-now tiles are populated from real data. Tests updated to assert on new copy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 files changed+1474−16f8e5fea681ab422aa0fde3927fd8fccc5752f6ff
4 changed files+1474−16
Modifiedsrc/__tests__/landing-hero.test.ts+7−7View fileUnifiedSplit
@@ -28,13 +28,13 @@ describe("Block L10 — landing hero rewrite", () => {
2828 it("renders the hero headline", async () => {
2929 const res = await app.request(HOME);
3030 const body = await res.text();
31 expect(body).toContain("The git host built for");
31 expect(body).toContain("The platform");
3232 });
3333
3434 it("renders speed-framing copy in hero lede", async () => {
3535 const res = await app.request(HOME);
3636 const body = await res.text();
37 expect(body).toContain("Spec to PR in 90 seconds");
37 expect(body).toContain("under 90 seconds");
3838 });
3939
4040 it("renders primary CTAs in the hero row", async () => {
@@ -56,7 +56,7 @@ describe("Block L10 — landing hero rewrite", () => {
5656 it("renders the 'The git host' eyebrow or headline copy", async () => {
5757 const res = await app.request(HOME);
5858 const body = await res.text();
59 expect(body).toContain("AI-native git host");
59 expect(body).toContain("AI-native git platform");
6060 });
6161
6262 it("injects SEO + Open Graph meta tags", async () => {
@@ -64,19 +64,19 @@ describe("Block L10 — landing hero rewrite", () => {
6464 const body = await res.text();
6565 // <title>
6666 expect(body).toContain(
67 "<title>Gluecron — The AI-native git host</title>"
67 "<title>Gluecron — The AI-native git platform</title>"
6868 );
6969 // <meta name="description">
7070 expect(body).toMatch(
71 /<meta\s+name="description"\s+content="The AI-native git host\. Spec to PR in 90 seconds\./
71 /<meta\s+name="description"\s+content="The git platform that does the work\./
7272 );
7373 // <meta property="og:title">
7474 expect(body).toMatch(
75 /<meta\s+property="og:title"\s+content="Gluecron — The AI-native git host"/
75 /<meta\s+property="og:title"\s+content="Gluecron — The AI-native git platform"/
7676 );
7777 // <meta property="og:description">
7878 expect(body).toMatch(
79 /<meta\s+property="og:description"\s+content="The AI-native git host\./
79 /<meta\s+property="og:description"\s+content="The git platform that does the work\./
8080 );
8181 // <meta property="og:type">
8282 expect(body).toMatch(
Modifiedsrc/__tests__/landing-live-feed.test.ts+1−1View fileUnifiedSplit
@@ -342,7 +342,7 @@ describe("Block M1 — landing route integration", () => {
342342 const res = await app.request("/");
343343 expect(res.status).toBe(200);
344344 const body = await res.text();
345 expect(body).toContain("hero-actions");
345 expect(body).toContain("lp-hero-ctas");
346346 expect(body).toContain('href="/register"');
347347 });
348348});
Modifiedsrc/routes/web.tsx+12−8View fileUnifiedSplit
@@ -64,6 +64,7 @@ import { isAiAvailable } from "../lib/ai-client";
6464import { trackByName } from "../lib/traffic";
6565import { LandingPage, type LandingLiveFeed } from "../views/landing";
6666import { Landing2030Page } from "../views/landing-2030";
67import { LandingProPage } from "../views/landing-pro";
6768import { computePublicStats, type PublicStats } from "../lib/public-stats";
6869import {
6970 listQueuedAiBuildIssues,
@@ -1860,15 +1861,18 @@ web.get("/", async (c) => {
18601861 liveFeed = null;
18611862 }
18621863
1863 // 2030 reboot — the public landing is a self-contained light marketing
1864 // document (its own shell + design system), rendered directly so it never
1865 // inherits the dark app Layout. `publicStats` / `liveFeed` remain computed
1866 // above for the legacy LandingPage and other surfaces; the new page uses the
1867 // headline counters from `stats`.
1868 void publicStats;
1869 void liveFeed;
18701864 void LandingPage;
1871 return c.html("<!DOCTYPE html>" + String(<Landing2030Page stats={stats} />));
1865 void Landing2030Page;
1866 return c.html(
1867 "<!DOCTYPE html>" +
1868 String(
1869 <LandingProPage
1870 stats={stats}
1871 publicStats={publicStats}
1872 liveFeed={liveFeed}
1873 />
1874 )
1875 );
18721876});
18731877
18741878// New repository form
Addedsrc/views/landing-pro.tsx+1454−0View fileUnifiedSplit
Large file (1,455 lines). Load full file