Skip to content

Commit 697d0f3

Browse files
bloveclaude
andauthored
feat(website): replace StatsStrip with differentiator-focused PositioningStrip (#155)
* docs(specs): home positioning strip redesign Replace stat-shaped tiles below the hero with four differentiator claims grounded in current competitive research (CopilotKit, Vercel AI SDK 5, assistant-ui). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(plans): home positioning strip implementation plan Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(website): add PositioningStrip component * feat(website): swap StatsStrip for PositioningStrip on home Replace the trust-focused social proof stats section with a differentiation-focused positioning strip that highlights key architectural advantages vs other agent UI frameworks. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(website): pin PositioningStrip to 4-up at >=1024px Previous auto-fit minmax(240px, 1fr) wrapped to 3 columns at 1280px since 4*240+3*16=1008 exceeds the 976px inner width. Use explicit breakpoints: 1-up <640px, 2-up <1024px, 4-up otherwise. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 7db9d1a commit 697d0f3

5 files changed

Lines changed: 545 additions & 50 deletions

File tree

apps/website/src/app/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { HeroTwoCol } from '../components/landing/HeroTwoCol';
2-
import { StatsStrip } from '../components/landing/StatsStrip';
2+
import { PositioningStrip } from '../components/landing/PositioningStrip';
33
import { ProblemSection } from '../components/landing/ProblemSection';
44
import { PilotSolution } from '../components/landing/PilotSolution';
55
import { TheStack } from '../components/landing/TheStack';
@@ -18,8 +18,8 @@ export default async function HomePage() {
1818

1919
{/* 1. Hook — headline, animation, CTA */}
2020
<HeroTwoCol />
21-
{/* 2. Trustquick credibility stats */}
22-
<StatsStrip />
21+
{/* 2. Differentiationpositioning vs other agent UIs */}
22+
<PositioningStrip />
2323
{/* 3. Problem — last-mile gap narrative */}
2424
<ProblemSection />
2525
{/* 4. Solution — pilot-to-prod program */}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
'use client';
2+
import { motion } from 'framer-motion';
3+
import type { ReactNode } from 'react';
4+
import { tokens } from '@ngaf/design-tokens';
5+
6+
interface Card {
7+
eyebrow: string;
8+
headline: string;
9+
body: ReactNode;
10+
}
11+
12+
const CARDS: Card[] = [
13+
{
14+
eyebrow: 'Runtime',
15+
headline: 'One Angular UI. Any agent runtime.',
16+
body: 'Same primitives drive LangGraph, AG-UI, CrewAI, Mastra, Pydantic AI, AWS Strands, and your own backend.',
17+
},
18+
{
19+
eyebrow: 'Streaming',
20+
headline: 'Full-parity LangGraph streaming.',
21+
body: (
22+
<>
23+
<code style={{ fontFamily: 'var(--font-mono)' }}>agent()</code> ships everything React&apos;s{' '}
24+
<code style={{ fontFamily: 'var(--font-mono)' }}>useStream()</code> does — interrupt, subagents, branch and history, tool progress — plus{' '}
25+
<code style={{ fontFamily: 'var(--font-mono)' }}>error()</code>,{' '}
26+
<code style={{ fontFamily: 'var(--font-mono)' }}>status()</code>, and{' '}
27+
<code style={{ fontFamily: 'var(--font-mono)' }}>reload()</code>.
28+
</>
29+
),
30+
},
31+
{
32+
eyebrow: 'Generative UI',
33+
headline: 'Generative UI, built in.',
34+
body: (
35+
<>
36+
Render Vercel <code style={{ fontFamily: 'var(--font-mono)' }}>json-render</code> and Google A2UI specs into Angular components. No second framework to bolt on.
37+
</>
38+
),
39+
},
40+
{
41+
eyebrow: 'License',
42+
headline: 'MIT. Headless primitives, drop-in compositions.',
43+
body: 'No tier gates on Angular. Use the unstyled primitives, or the opinionated chat shell — your call.',
44+
},
45+
];
46+
47+
export function PositioningStrip() {
48+
return (
49+
<section
50+
className="positioning-strip"
51+
aria-labelledby="positioning-heading"
52+
style={{ maxWidth: 1040, margin: '0 auto', padding: '64px 32px' }}
53+
>
54+
<style>{`
55+
.positioning-strip .positioning-grid {
56+
display: grid;
57+
grid-template-columns: 1fr;
58+
gap: 16px;
59+
}
60+
@media (min-width: 640px) {
61+
.positioning-strip .positioning-grid { grid-template-columns: repeat(2, 1fr); }
62+
}
63+
@media (min-width: 1024px) {
64+
.positioning-strip .positioning-grid { grid-template-columns: repeat(4, 1fr); }
65+
}
66+
`}</style>
67+
<h2
68+
id="positioning-heading"
69+
style={{
70+
position: 'absolute',
71+
width: 1,
72+
height: 1,
73+
padding: 0,
74+
margin: -1,
75+
overflow: 'hidden',
76+
clip: 'rect(0,0,0,0)',
77+
whiteSpace: 'nowrap',
78+
border: 0,
79+
}}
80+
>
81+
What makes the Angular Agent Framework different
82+
</h2>
83+
84+
<div className="positioning-grid">
85+
{CARDS.map((card, i) => (
86+
<motion.article
87+
key={card.eyebrow}
88+
initial={{ opacity: 0, y: 20 }}
89+
whileInView={{ opacity: 1, y: 0 }}
90+
viewport={{ once: true }}
91+
transition={{ delay: i * 0.1, duration: 0.4 }}
92+
style={{
93+
padding: '24px 22px',
94+
borderRadius: 18,
95+
background: tokens.glass.bg,
96+
backdropFilter: `blur(${tokens.glass.blur})`,
97+
WebkitBackdropFilter: `blur(${tokens.glass.blur})`,
98+
border: `1px solid ${tokens.glass.border}`,
99+
boxShadow: tokens.glass.shadow,
100+
display: 'flex',
101+
flexDirection: 'column',
102+
gap: 10,
103+
}}
104+
>
105+
<p
106+
style={{
107+
fontFamily: 'var(--font-mono)',
108+
fontSize: '0.7rem',
109+
fontWeight: 700,
110+
textTransform: 'uppercase',
111+
letterSpacing: '0.12em',
112+
color: tokens.colors.accent,
113+
margin: 0,
114+
}}
115+
>
116+
{card.eyebrow}
117+
</p>
118+
<h3
119+
style={{
120+
fontFamily: 'var(--font-garamond)',
121+
fontSize: 'clamp(18px, 1.6vw, 22px)',
122+
fontWeight: 700,
123+
lineHeight: 1.2,
124+
color: tokens.colors.textPrimary,
125+
margin: 0,
126+
}}
127+
>
128+
{card.headline}
129+
</h3>
130+
<p
131+
style={{
132+
fontSize: '0.9rem',
133+
lineHeight: 1.55,
134+
color: tokens.colors.textSecondary,
135+
margin: 0,
136+
}}
137+
>
138+
{card.body}
139+
</p>
140+
</motion.article>
141+
))}
142+
</div>
143+
</section>
144+
);
145+
}

apps/website/src/components/landing/StatsStrip.tsx

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)