diff --git a/.tmp/proof/landing-highlights.png b/.tmp/proof/landing-highlights.png new file mode 100644 index 0000000..71f8d84 Binary files /dev/null and b/.tmp/proof/landing-highlights.png differ diff --git a/packages/app/src/components/landing/LandingPage.test.tsx b/packages/app/src/components/landing/LandingPage.test.tsx index 6381afe..5efd6c8 100644 --- a/packages/app/src/components/landing/LandingPage.test.tsx +++ b/packages/app/src/components/landing/LandingPage.test.tsx @@ -31,6 +31,51 @@ describe('LandingPage', () => { expect(cta).toHaveAttribute('href', '/catalog'); }); + it('renders the four feature highlights', async () => { + await renderInTestApp(); + + expect(screen.getByText('What you can try')).toBeInTheDocument(); + expect(screen.getByText('Software templates')).toBeInTheDocument(); + expect(screen.getByText('Software catalog')).toBeInTheDocument(); + expect(screen.getByText('GitHub integration')).toBeInTheDocument(); + expect(screen.getByText('Answer engine')).toBeInTheDocument(); + expect( + screen.getByText(/Search the catalog and TechDocs in one place/), + ).toBeInTheDocument(); + }); + + it('links each highlight to its live surface', async () => { + await renderInTestApp(); + + expect( + screen.getByRole('link', { name: 'Use a template' }), + ).toHaveAttribute('href', '/self-service'); + expect( + screen.getByRole('link', { name: 'Browse services' }), + ).toHaveAttribute('href', '/catalog'); + expect( + screen.getByRole('link', { name: 'See GitHub integration' }), + ).toHaveAttribute('href', '/showcase'); + expect( + screen.getByRole('link', { name: 'Search catalog and docs' }), + ).toHaveAttribute('href', '/search'); + }); + + it('renders the footer with a second path into the demo', async () => { + await renderInTestApp(); + + expect(screen.getByText('Ready to look around?')).toBeInTheDocument(); + expect( + screen.getByText(/The demo runs as a guest with read-only access/), + ).toBeInTheDocument(); + expect( + screen.getByRole('link', { name: 'Start with the showcase' }), + ).toHaveAttribute('href', '/showcase'); + expect( + screen.getByRole('link', { name: 'Open the catalog' }), + ).toHaveAttribute('href', '/catalog'); + }); + it('shows the portal screenshot with alt text', async () => { await renderInTestApp(); diff --git a/packages/app/src/components/landing/LandingPage.tsx b/packages/app/src/components/landing/LandingPage.tsx index ddaba5a..c1a2138 100644 --- a/packages/app/src/components/landing/LandingPage.tsx +++ b/packages/app/src/components/landing/LandingPage.tsx @@ -32,6 +32,43 @@ const ScreenshotFrame = styled('figure')(({ theme }) => ({ }, })); +const FeatureCard = styled(Box)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1.5), + padding: theme.spacing(3), + borderRadius: theme.spacing(1), + border: `3px solid ${theme.palette.text.primary}`, + backgroundColor: theme.palette.background.paper, +})); + +const highlights = [ + { + title: 'Software templates', + body: 'Start a service, docs site or AI worker from a template that publishes to GitHub and registers itself in the catalog.', + link: '/self-service', + linkLabel: 'Use a template', + }, + { + title: 'Software catalog', + body: 'Every service, API and team in one searchable place, with ownership and lifecycle kept next to the code.', + link: '/catalog', + linkLabel: 'Browse services', + }, + { + title: 'GitHub integration', + body: 'Templates open repositories and pull requests, and the catalog stays in sync with what is actually on GitHub.', + link: '/showcase', + linkLabel: 'See GitHub integration', + }, + { + title: 'Answer engine', + body: 'Search the catalog and TechDocs in one place. The showcase explains how an answer engine can extend this search foundation.', + link: '/search', + linkLabel: 'Search catalog and docs', + }, +]; + export const LandingPage = () => { const theme = useTheme(); @@ -107,6 +144,86 @@ export const LandingPage = () => { The plugin showcase running live in this portal. + + + + What you can try + + + {highlights.map(highlight => ( + + + {highlight.title} + + + {highlight.body} + + + + ))} + + + + + + Ready to look around? + + + The demo runs as a guest with read-only access, so you can open + every page without signing up. + + + + + + );