Skip to content

Commit b7ce508

Browse files
bloveclaude
andauthored
fix(website): final-review fix batch (#922)
* docs(website): final-review fix batch spec + rulings Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(website): final-review fix batch across all marketing surfaces /ag-ui tells the truth (seven backends, spec-pinned to the grid); the footer tagline loses the last sitewide litany; HomeFAQ joins the rail; /render dedupes its fallback phrasing; FinalCTA's caption and doc comment catch up to the shipped rules; Angular pills derive from the support source; orphaned pricing CSS deleted; a tautological assertion dropped; the pricing kicker unifies on Eyebrow. Rulings recorded in the spec. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 4328c5d commit b7ce508

14 files changed

Lines changed: 73 additions & 96 deletions

File tree

apps/website/src/app/ag-ui/page.spec.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { render, screen } from '@testing-library/react';
22
import { describe, it, expect, vi } from 'vitest';
33
import AgUiPage from './page';
4+
import { BACKENDS } from '../../components/landing/ag-ui/BackendsGrid';
45

56
vi.mock('../../lib/analytics/client', () => ({
67
track: vi.fn(),
@@ -13,6 +14,8 @@ describe('AgUiPage', () => {
1314
it('renders the package kicker, marker sweep, switcher, and dark closer', async () => {
1415
const ui = await AgUiPage();
1516
const { container } = render(ui);
17+
// The H1/subtitle/body say "seven"; this pins the grid to that word.
18+
expect(BACKENDS).toHaveLength(7);
1619
expect(screen.getByText('@threadplane/ag-ui · protocol adapter')).toBeTruthy();
1720
expect(container.querySelector('.marker-highlight')?.textContent).toBe('work the day they ship');
1821
expect(screen.getAllByRole('tablist').length).toBeGreaterThanOrEqual(1);

apps/website/src/app/ag-ui/page.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Link from 'next/link';
2+
import { WEBSITE_SUPPORTED_ANGULAR_MAJORS } from '../../components/pricing/angular-support.mjs';
23
import { Container } from '../../components/ui/Container';
34
import { Section } from '../../components/ui/Section';
45
import { Eyebrow } from '../../components/ui/Eyebrow';
@@ -34,10 +35,10 @@ export default async function AgUiPage() {
3435
<span className="lib-hero-rail-line" aria-hidden="true" />
3536
</div>
3637
<h1 id="ag-ui-hero-heading" className="ag-ui-page-h1">
37-
One adapter. Eight backends.
38+
One adapter. Seven backends.
3839
</h1>
3940
<p className="ag-ui-page-hero-subtitle">
40-
Build the Angular UI once, on the AG-UI protocol — eight runtimes speak it today, and new ones <span className="marker-highlight">work the day they ship</span>. History and checkpoint behavior stays with your backend.
41+
Build the Angular UI once, on the AG-UI protocol — seven runtimes speak it today, and new ones <span className="marker-highlight">work the day they ship</span>. History and checkpoint behavior stays with your backend.
4142
</p>
4243
<div className="ag-ui-page-hero-buttons">
4344
<Button variant="primary" size="lg" href="/docs/ag-ui/getting-started/quickstart">Get started</Button>
@@ -48,7 +49,7 @@ export default async function AgUiPage() {
4849
</p>
4950
<div className="ag-ui-page-hero-pills">
5051
<Pill variant="accent">MIT</Pill>
51-
<Pill variant="angular">Angular 20–22</Pill>
52+
<Pill variant="angular">{`Angular ${WEBSITE_SUPPORTED_ANGULAR_MAJORS[0]}${WEBSITE_SUPPORTED_ANGULAR_MAJORS.at(-1)}`}</Pill>
5253
<Pill variant="neutral">AG-UI protocol</Pill>
5354
</div>
5455
<p className="ag-ui-page-langgraph-note">
@@ -66,7 +67,7 @@ export default async function AgUiPage() {
6667
id="backends"
6768
eyebrow="Runtime choice"
6869
headline="Pick a backend. Keep the UI."
69-
body="The AG-UI protocol decouples your agent runtime from your front-end. @threadplane/ag-ui wraps any AG-UI AbstractAgent into the runtime-neutral Agent contract that @threadplane/chat consumes — so the same Angular components ship against eight different runtimes."
70+
body="The AG-UI protocol decouples your agent runtime from your front-end. @threadplane/ag-ui wraps any AG-UI AbstractAgent into the runtime-neutral Agent contract that @threadplane/chat consumes — so the same Angular components ship against seven different runtimes."
7071
rows={[
7172
{ claim: 'Stream from Python, .NET, or TypeScript', api: 'AG-UI protocol' },
7273
{ claim: 'Tool calls, state deltas, citations — standardized', api: 'protocol events' },

apps/website/src/app/langgraph/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Container } from '../../components/ui/Container';
2+
import { WEBSITE_SUPPORTED_ANGULAR_MAJORS } from '../../components/pricing/angular-support.mjs';
23
import { Section } from '../../components/ui/Section';
34
import { Eyebrow } from '../../components/ui/Eyebrow';
45
import { Button } from '../../components/ui/Button';
@@ -47,7 +48,7 @@ export default async function LangGraphPage() {
4748
</p>
4849
<div className="langgraph-page-hero-pills">
4950
<Pill variant="accent">MIT</Pill>
50-
<Pill variant="angular">Angular 20–22</Pill>
51+
<Pill variant="angular">{`Angular ${WEBSITE_SUPPORTED_ANGULAR_MAJORS[0]}${WEBSITE_SUPPORTED_ANGULAR_MAJORS.at(-1)}`}</Pill>
5152
<Pill variant="neutral">LangGraph + AG-UI</Pill>
5253
</div>
5354
</div>

apps/website/src/app/render/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default async function RenderPage() {
3636
Generative UI without a second framework.
3737
</h1>
3838
<p className="render-page-hero-subtitle">
39-
Server-emitted JSON specs render into Angular <span className="marker-highlight">components you already own</span>. Vercel json-render and Google A2UI both supported. Per-component fallback, readiness gate, no surprises.
39+
Server-emitted JSON specs render into Angular <span className="marker-highlight">components you already own</span>. Vercel json-render and Google A2UI both supported. Unknown specs degrade gracefully — no surprises.
4040
</p>
4141
<div className="render-page-hero-buttons">
4242
<Button variant="primary" size="lg" href="/docs/render/getting-started/introduction">Get started</Button>

apps/website/src/components/landing/FeatureBlock.spec.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ describe('FeatureBlock', () => {
2323
);
2424
expect(screen.getByText('Your design system, not a chat widget')).toBeTruthy();
2525
expect(screen.getByText('@threadplane/render')).toBeTruthy();
26-
expect(container.querySelector('.feature-block-card-row')).toBeNull();
2726
expect(container.querySelectorAll('.feature-block-row')).toHaveLength(2);
2827
expect(container.querySelector('.feature-block-rail')).toBeTruthy();
2928
});

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ interface FinalCTAProps {
1515
/** Optional trailing caption. Defaults to licensing and telemetry line. Pass null to hide. */
1616
caption?: string | null;
1717
/**
18-
* 'dark' renders on the dark band — homepage only, pairing with the Yes
19-
* wall so the inverted treatment appears twice (spec: a lone dark band
20-
* reads as arbitrary). All other pages keep the default tinted surface.
18+
* 'dark' renders on the dark band. Rule (amended 2026-08-31): dark closes
19+
* PRODUCT pages — the homepage (pairing with the Yes wall) and the four
20+
* library pages. Commerce pages keep the default tinted surface.
2121
*/
2222
variant?: 'default' | 'dark';
2323
}
@@ -29,7 +29,7 @@ export function FinalCTA({
2929
subtext = 'Install the framework, read the docs, and have a streaming chat in your app this afternoon.',
3030
primary = null,
3131
secondary = DEFAULT_SECONDARY,
32-
caption = 'All packages are MIT · Production support available · App telemetry off by default',
32+
caption = 'All packages are MIT · Production support available · Installation is inert',
3333
variant = 'default',
3434
}: FinalCTAProps = {}) {
3535
return (

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,12 @@ export function HomeFAQ() {
3939
<Section surface="white" ariaLabelledBy="faq-heading">
4040
<Container>
4141
<div className="home-faq-intro">
42-
<Eyebrow tone="accent" className="home-faq-eyebrow">
43-
Questions
44-
</Eyebrow>
42+
<div className="home-faq-rail">
43+
<Eyebrow tone="accent" className="home-faq-eyebrow">
44+
Questions
45+
</Eyebrow>
46+
<span className="home-faq-rail-line" aria-hidden="true" />
47+
</div>
4548
<h2 id="faq-heading" className="home-faq-heading">
4649
Frequently asked questions.
4750
</h2>

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ export const YES_WALL_GROUPS: readonly YesGroup[] = [
5454
},
5555
];
5656

57+
// NOTE: the SectionHeader aside says "Sixteen questions" in prose — update it
58+
// (and the spec's toBe(16)) together with any row change; the footer count
59+
// derives automatically.
5760
const TOTAL_QUESTIONS = YES_WALL_GROUPS.reduce((n, g) => n + g.rows.length, 0);
5861

5962
export function YesWall() {

apps/website/src/components/landing/ag-ui/BackendsGrid.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ interface Backend {
33
readonly note: string;
44
}
55

6-
const BACKENDS: readonly Backend[] = [
6+
// Three copy sites on /ag-ui say "seven" — the page spec ties this list's
7+
// length to that word. Adding a runtime here fails that test until the copy
8+
// updates. Honest counts only.
9+
export const BACKENDS: readonly Backend[] = [
710
{ name: 'LangGraph', note: 'Python / TS' },
811
{ name: 'CrewAI', note: 'Python' },
912
{ name: 'Mastra', note: 'TypeScript' },

apps/website/src/components/pricing/PricingDetails.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { TIERS, type TierSlug } from '../../../../../pricing/tiers.config';
2+
import { Eyebrow } from '../ui/Eyebrow';
23

34
type ComparisonCells = Record<TierSlug, string>;
45

@@ -70,7 +71,7 @@ export function ArchitectureBoundary() {
7071
<div className="pricing-boundary">
7172
<div className="pricing-section-heading-wrap">
7273
<div className="pricing-section-rail">
73-
<p className="pricing-section-kicker">What you are buying</p>
74+
<Eyebrow tone="accent" className="pricing-section-kicker">What you are buying</Eyebrow>
7475
<span className="pricing-section-rail-line" aria-hidden="true" />
7576
</div>
7677
<h2 id="pricing-value-heading" className="pricing-section-heading">
@@ -121,7 +122,7 @@ export function PricingComparison() {
121122
<div className="pricing-comparison">
122123
<div className="pricing-section-heading-wrap">
123124
<div className="pricing-section-rail">
124-
<p className="pricing-section-kicker">Full comparison</p>
125+
<Eyebrow tone="accent" className="pricing-section-kicker">Full comparison</Eyebrow>
125126
<span className="pricing-section-rail-line" aria-hidden="true" />
126127
</div>
127128
<h2 id="pricing-comparison-heading" className="pricing-section-heading">

0 commit comments

Comments
 (0)