Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
201f52b
docs: add solutions landing pages implementation plan
blove Apr 14, 2026
5afbacb
feat(website): add solutions data layer and shared section components
blove Apr 14, 2026
aea1c5d
feat(website): add solution pages, solutions index, and nav/footer links
blove Apr 14, 2026
f5a94b6
fix(website): address code review — remove unused rgb prop, add fade-…
blove Apr 14, 2026
0769d33
docs: add product landing page alignment design spec
blove Apr 14, 2026
5c422eb
docs: add landing page alignment implementation plan
blove Apr 14, 2026
2985649
feat(website): add stack breadcrumb and fix Link usage in AngularHero
blove Apr 14, 2026
3513943
feat(website): add stack breadcrumb and fix Link usage in RenderHero
blove Apr 14, 2026
5435c23
feat(website): add stack breadcrumb and fix Link usage in ChatLanding…
blove Apr 14, 2026
d1c2630
feat(website): upgrade AngularFooterCTA to dark design with pilot pri…
blove Apr 14, 2026
b63b552
feat(website): upgrade RenderFooterCTA to dark design with pilot prim…
blove Apr 14, 2026
9753c58
feat(website): upgrade ChatLandingFooterCTA to dark design with pilot…
blove Apr 14, 2026
3ed85d2
feat(website): refresh WhitePaperGate copy and add mobile breakpoints
blove Apr 14, 2026
e026570
feat(website): add RenderStackSiblings section to /render page
blove Apr 14, 2026
4a2db71
feat(website): add AngularStackSiblings section to /angular page
blove Apr 14, 2026
32d4078
feat(website): add ChatLandingStackSiblings section to /chat page
blove Apr 14, 2026
277b67a
feat(website): add mobile breakpoints to ProblemSolution sections
blove Apr 14, 2026
36812d6
feat(website): add mobile breakpoints to FeaturesGrid sections
blove Apr 14, 2026
5528af6
feat(website): add mobile breakpoints to CodeShowcase sections
blove Apr 14, 2026
cde41ee
feat(website): add mobile breakpoints to Comparison sections
blove Apr 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/website/src/app/angular/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AngularFeaturesGrid } from '../../components/landing/angular/AngularFea
import { AngularCodeShowcase } from '../../components/landing/angular/AngularCodeShowcase';
import { AngularComparison } from '../../components/landing/angular/AngularComparison';
import { AngularWhitePaperGate } from '../../components/landing/angular/AngularWhitePaperGate';
import { AngularStackSiblings } from '../../components/landing/angular/AngularStackSiblings';
import { AngularFooterCTA } from '../../components/landing/angular/AngularFooterCTA';
import { tokens } from '@cacheplane/design-tokens';

Expand All @@ -25,6 +26,7 @@ export default function AngularPage() {
<AngularCodeShowcase />
<AngularComparison />
<AngularWhitePaperGate />
<AngularStackSiblings />
<AngularFooterCTA />
</div>
);
Expand Down
2 changes: 2 additions & 0 deletions apps/website/src/app/chat/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ChatLandingFeaturesGrid } from '../../components/landing/chat-landing/C
import { ChatLandingCodeShowcase } from '../../components/landing/chat-landing/ChatLandingCodeShowcase';
import { ChatLandingComparison } from '../../components/landing/chat-landing/ChatLandingComparison';
import { ChatLandingWhitePaperGate } from '../../components/landing/chat-landing/ChatLandingWhitePaperGate';
import { ChatLandingStackSiblings } from '../../components/landing/chat-landing/ChatLandingStackSiblings';
import { ChatLandingFooterCTA } from '../../components/landing/chat-landing/ChatLandingFooterCTA';
import { tokens } from '@cacheplane/design-tokens';

Expand All @@ -25,6 +26,7 @@ export default function ChatPage() {
<ChatLandingCodeShowcase />
<ChatLandingComparison />
<ChatLandingWhitePaperGate />
<ChatLandingStackSiblings />
<ChatLandingFooterCTA />
</div>
);
Expand Down
2 changes: 2 additions & 0 deletions apps/website/src/app/render/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { RenderFeaturesGrid } from '../../components/landing/render/RenderFeatur
import { RenderCodeShowcase } from '../../components/landing/render/RenderCodeShowcase';
import { RenderComparison } from '../../components/landing/render/RenderComparison';
import { RenderWhitePaperGate } from '../../components/landing/render/RenderWhitePaperGate';
import { RenderStackSiblings } from '../../components/landing/render/RenderStackSiblings';
import { RenderFooterCTA } from '../../components/landing/render/RenderFooterCTA';
import { tokens } from '@cacheplane/design-tokens';

Expand All @@ -25,6 +26,7 @@ export default function RenderPage() {
<RenderCodeShowcase />
<RenderComparison />
<RenderWhitePaperGate />
<RenderStackSiblings />
<RenderFooterCTA />
</div>
);
Expand Down
102 changes: 102 additions & 0 deletions apps/website/src/app/solutions/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { notFound } from 'next/navigation';
import { tokens } from '@cacheplane/design-tokens';
import { getSolutionBySlug, getAllSolutionSlugs } from '../../../lib/solutions-data';
import { SolutionHero } from '../../../components/landing/solutions/SolutionHero';
import { SolutionProblem } from '../../../components/landing/solutions/SolutionProblem';
import { SolutionArchitecture } from '../../../components/landing/solutions/SolutionArchitecture';
import { SolutionProofPoints } from '../../../components/landing/solutions/SolutionProofPoints';
import { SolutionFooterCTA } from '../../../components/landing/solutions/SolutionFooterCTA';
import { WhitePaperSection } from '../../../components/landing/WhitePaperSection';

interface PageProps {
params: Promise<{ slug: string }>;
}

export function generateStaticParams() {
return getAllSolutionSlugs().map(slug => ({ slug }));
}

export async function generateMetadata({ params }: PageProps) {
const { slug } = await params;
const solution = getSolutionBySlug(slug);
if (!solution) return {};
return {
title: solution.metaTitle,
description: solution.metaDescription,
};
}

export default async function SolutionPage({ params }: PageProps) {
const { slug } = await params;
const solution = getSolutionBySlug(slug);
if (!solution) notFound();

return (
<div style={{ background: tokens.gradient.bgFlow, position: 'relative', overflow: 'hidden' }}>
{/* Ambient gradient blobs */}
<div
style={{
position: 'absolute',
width: 600,
height: 600,
borderRadius: '50%',
background: `radial-gradient(circle, rgba(${solution.rgb}, 0.12) 0%, transparent 70%)`,
top: -200,
left: -150,
filter: 'blur(80px)',
pointerEvents: 'none',
}}
aria-hidden="true"
/>
<div
style={{
position: 'absolute',
width: 500,
height: 500,
borderRadius: '50%',
background: tokens.gradient.cool,
top: 800,
right: -100,
filter: 'blur(80px)',
pointerEvents: 'none',
}}
aria-hidden="true"
/>
<div
style={{
position: 'absolute',
width: 400,
height: 400,
borderRadius: '50%',
background: `radial-gradient(circle, rgba(${solution.rgb}, 0.08) 0%, transparent 70%)`,
top: 2200,
left: -100,
filter: 'blur(80px)',
pointerEvents: 'none',
}}
aria-hidden="true"
/>

<SolutionHero solution={solution} />
<SolutionProblem
color={solution.color}
painPoints={solution.painPoints}
/>
<SolutionArchitecture
color={solution.color}
intro={solution.architectureIntro}
layers={solution.architectureLayers}
/>
<SolutionProofPoints
color={solution.color}
proofPoints={solution.proofPoints}
/>
<WhitePaperSection />
<SolutionFooterCTA
color={solution.color}
headline={solution.ctaHeadline}
subtext={solution.ctaSubtext}
/>
</div>
);
}
100 changes: 100 additions & 0 deletions apps/website/src/app/solutions/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { tokens } from '@cacheplane/design-tokens';
import { SolutionsGrid } from '../../components/landing/solutions/SolutionsGrid';
import { WhitePaperSection } from '../../components/landing/WhitePaperSection';
import { PilotFooterCTA } from '../../components/landing/PilotFooterCTA';

export const metadata = {
title: 'Solutions — Angular Agent Framework',
description: 'See how Angular Agent Framework solves enterprise challenges — compliance, analytics, and customer support.',
};

export default function SolutionsIndexPage() {
return (
<div style={{ background: tokens.gradient.bgFlow, position: 'relative', overflow: 'hidden' }}>
{/* Ambient gradient blobs */}
<div
style={{
position: 'absolute',
width: 600,
height: 600,
borderRadius: '50%',
background: tokens.gradient.warm,
top: -200,
left: -150,
filter: 'blur(80px)',
pointerEvents: 'none',
}}
aria-hidden="true"
/>
<div
style={{
position: 'absolute',
width: 500,
height: 500,
borderRadius: '50%',
background: tokens.gradient.cool,
top: 800,
right: -100,
filter: 'blur(80px)',
pointerEvents: 'none',
}}
aria-hidden="true"
/>

{/* Hero */}
<section style={{ position: 'relative', overflow: 'hidden', padding: '0 2rem' }}>
<div
style={{
maxWidth: '56rem',
margin: '0 auto',
textAlign: 'center',
position: 'relative',
zIndex: 1,
}}
className="py-24 md:py-32"
>
<p
style={{
fontFamily: 'var(--font-mono, "JetBrains Mono", monospace)',
fontSize: 11,
letterSpacing: '0.08em',
color: tokens.colors.accent,
textTransform: 'uppercase',
marginBottom: '1.5rem',
}}
>
Solutions
</p>
<h1
style={{
fontFamily: 'var(--font-garamond, "EB Garamond", Georgia, serif)',
fontSize: 'clamp(36px, 5vw, 56px)',
fontWeight: 700,
lineHeight: 1.1,
color: tokens.colors.textPrimary,
marginBottom: '1.25rem',
}}
>
AI agents built for how enterprises actually work
</h1>
<p
style={{
fontFamily: 'Inter, sans-serif',
fontSize: 18,
color: tokens.colors.textSecondary,
maxWidth: '52ch',
margin: '0 auto',
lineHeight: 1.6,
}}
>
Angular Agent Framework gives your team the streaming, generative UI, and human-in-the-loop patterns that enterprise use cases demand.
</p>
</div>
</section>

<SolutionsGrid />
<WhitePaperSection />
<PilotFooterCTA />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ const SNIPPETS = [

export async function AngularCodeShowcase() {
return (
<section style={{ padding: '80px 32px' }}>
<section className="angular-code" style={{ padding: '80px 32px' }}>
<style>{`@media (max-width: 767px) { .angular-code { padding: 60px 20px !important; } }`}</style>
<div style={{ textAlign: 'center', marginBottom: 48 }}>
<p style={{
fontFamily: 'var(--font-mono,"JetBrains Mono",monospace)',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ const ROWS = [

export function AngularComparison() {
return (
<section style={{ padding: '80px 32px' }}>
<section className="angular-comparison" style={{ padding: '80px 32px' }}>
<style>{`
@media (max-width: 767px) {
.angular-comparison { padding: 60px 20px !important; }
}
`}</style>
<motion.div
initial={{ opacity: 0, y: 16 }}
whileInView={{ opacity: 1, y: 0 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const FEATURES = [

export function AngularFeaturesGrid() {
return (
<section style={{ padding: '80px 32px' }}>
<section className="angular-features" style={{ padding: '80px 32px' }}>
<style>{`@media (max-width: 767px) { .angular-features { padding: 60px 20px !important; } }`}</style>
<motion.div
initial={{ opacity: 0, y: 16 }}
whileInView={{ opacity: 1, y: 0 }}
Expand Down
Loading
Loading