Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions apps/website/e2e/website.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ test('landing page renders hero headline', async ({ page }) => {
expect(headline?.toLowerCase()).toContain('angular');
});

test('landing page renders the Yes wall', async ({ page }) => {
test('landing page renders the dark proof band', async ({ page }) => {
await page.goto('/');
await expect(page.locator('#yes-wall-heading')).toBeVisible();
await expect(page.locator('#proof-heading')).toBeVisible();
await expect(page.locator('#proof[data-surface="dark"]')).toBeVisible();
});

test('landing page renders feature blocks (Stream/Render/Ship)', async ({ page }) => {
Expand Down
8 changes: 2 additions & 6 deletions apps/website/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Hero } from '../components/landing/Hero';
import { LogoRibbon } from '../components/landing/LogoRibbon';
import { YesWall } from '../components/landing/YesWall';
import { ProofStrip } from '../components/landing/ProofStrip';
import { FeatureBlock } from '../components/landing/FeatureBlock';
import { StackDiagramSection } from '../components/landing/StackDiagramSection';
import { HomeConceptGrid } from '../components/landing/HomeConceptGrid';
Expand All @@ -9,7 +9,6 @@ import { MediumSwitcher } from '../components/landing/MediumSwitcher';
import { SECTION_MEDIA } from '../lib/section-media';
import { buildPanes } from '../lib/build-panes';
import { PilotBlock } from '../components/landing/PilotBlock';
import { ProofStrip } from '../components/landing/ProofStrip';
import { WhitePaperBlock } from '../components/landing/WhitePaperBlock';
import { HomeFAQ } from '../components/landing/HomeFAQ';
import { FinalCTA } from '../components/landing/FinalCTA';
Expand Down Expand Up @@ -38,7 +37,7 @@ export default async function HomePage() {
<>
<Hero />
<LogoRibbon />
<YesWall />
<ProofStrip />

<StackDiagramSection
id="architecture"
Expand Down Expand Up @@ -108,8 +107,6 @@ export default async function HomePage() {
/>

{/*
The homepage claims human-in-the-loop in the Yes wall, but nothing
before this section showed it.
This is the only section whose heading the approval clip actually
illustrates — the same rule the solutions pages follow.
*/}
Expand All @@ -135,7 +132,6 @@ export default async function HomePage() {

<PilotBlock />
<WhitePaperBlock formPolicy={formPolicy} />
<ProofStrip />
<HomeFAQ />
<RecentArticles />
<FinalCTA variant="dark" />
Expand Down
28 changes: 28 additions & 0 deletions apps/website/src/components/landing/ProofStrip.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,32 @@ describe('ProofStrip', () => {
const badge = screen.getByAltText(/HVTrust grade/i);
expect(badge.getAttribute('src')).toBe('https://hvtracker.net/badge/threadplane.svg');
});

it('renders on the dark contrast band, with a watermark carrying no text', () => {
const { container } = render(<ProofStrip />);

const section = container.querySelector('[data-ui="section"]');
expect(section?.getAttribute('data-surface')).toBe('dark');
expect(section?.getAttribute('id')).toBe('proof');

const mark = container.querySelector('.proof-strip-watermark');
expect(mark?.getAttribute('aria-hidden')).toBe('true');
expect(mark?.getAttribute('data-watermark-text')).toBe('Proof');
expect(mark?.textContent).toBe('');
});

it('keeps the "Reliable to the core" framing on the band', () => {
render(<ProofStrip />);
expect(screen.getByText('Reliable to the core')).toBeTruthy();
const heading = screen.getByRole('heading', { name: 'Audited, scored, published.' });
expect(heading.id).toBe('proof-heading');
});

it('links every number to a human-readable page, never a raw API', () => {
for (const cell of PROOF_CELLS) {
const { hostname, pathname } = new URL(cell.sourceHref);
expect(hostname.startsWith('api.'), cell.sourceHref).toBe(false);
expect(pathname.startsWith('/api/'), cell.sourceHref).toBe(false);
}
});
});
115 changes: 64 additions & 51 deletions apps/website/src/components/landing/ProofStrip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,89 +14,102 @@ interface ProofCell {
}

/**
* Verified 2026-08-27 against live sources (see the homepage design spec,
* Verified 2026-09-04 against live sources (see the homepage design spec,
* "Verification results"). The rank and score drift over time — re-verify on
* touch, and never "round up". The HVTrust grade is deliberately a LIVE badge:
* it sits at 81.2 against an A-band floor of 80 and has flipped grade six
* times in one month; a hardcoded letter would be wrong on some days.
* it sits at 84.3 against an A-band floor of 80 and has flipped grade several
* times in a month; a hardcoded letter would be wrong on some days.
*
* Every href must be a page a human can read. The Scorecard number comes from
* api.securityscorecards.dev, but the LINK goes to the scorecard.dev viewer —
* the API URL renders as raw JSON.
*/
export const PROOF_CELLS: readonly ProofCell[] = [
{
value: '#13',
value: '#8',
suffix: 'of 119',
caption: 'Of all agent frameworks ranked',
sourceLabel: 'hvtracker.net',
sourceHref: 'https://hvtracker.net/categories/agent-frameworks/',
},
{
value: '8.1',
value: '8.2',
suffix: '/10',
caption: 'OpenSSF Scorecard, official API',
sourceLabel: 'securityscorecards.dev',
caption: 'OpenSSF Scorecard, official scan',
sourceLabel: 'scorecard.dev',
sourceHref:
'https://api.securityscorecards.dev/projects/github.com/cacheplane/angular-agent-framework',
'https://scorecard.dev/viewer/?uri=github.com/cacheplane/angular-agent-framework',
},
{
value: null,
caption: 'HVTrust supply-chain grade, live',
sourceLabel: 'hvtracker.net/agents/threadplane',
sourceLabel: 'hvtracker.net/agents',
sourceHref: 'https://hvtracker.net/agents/threadplane/',
},
{
// Revived per the homepage design spec's condition: npm @latest publishes
// ^20 || ^21 || ^22 (verified 2026-08-31). Derived, never hardcoded.
value: `${WEBSITE_SUPPORTED_ANGULAR_MAJORS[0]}–${WEBSITE_SUPPORTED_ANGULAR_MAJORS.at(-1)}`,
caption: 'Angular majors supported, CI-tested',
sourceLabel: 'npmjs.com/@threadplane/langgraph',
sourceLabel: 'npmjs.com',
sourceHref: 'https://www.npmjs.com/package/@threadplane/langgraph',
},
];

export function ProofStrip() {
return (
<Section surface="tinted" tight id="proof" ariaLabelledBy="proof-heading">
<Section surface="dark" id="proof" ariaLabelledBy="proof-heading">
<Container>
<div className="proof-strip-grid">
<SectionHeader
variant="rail"
eyebrow="Reliable to the core"
heading="Audited, scored, published."
headingId="proof-heading"
aside="Not self-reported — every number links to its source."
<div className="proof-strip">
{/* Garamond watermark; the glyph comes from the data attribute so no
* stray text reaches screen readers or getAllByText. */}
<div
className="proof-strip-watermark"
aria-hidden="true"
data-watermark-text="Proof"
/>
<ul className="proof-strip-cells" role="list">
{PROOF_CELLS.map((cell) => (
<li className="proof-strip-cell" key={cell.caption}>
{cell.value ? (
<p className="proof-strip-value">
{cell.value}
{cell.suffix ? (
<span className="proof-strip-suffix"> {cell.suffix}</span>
) : null}
</p>
) : (
<img
className="proof-strip-badge"
src="https://hvtracker.net/badge/threadplane.svg"
alt="HVTrust grade for Threadplane (live badge)"
width={91}
height={20}
loading="lazy"
referrerPolicy="no-referrer"
/>
)}
<p className="proof-strip-caption">{cell.caption}</p>
<a
className="proof-strip-source"
href={cell.sourceHref}
target="_blank"
rel="noopener noreferrer"
>
{cell.sourceLabel}
</a>
</li>
))}
</ul>
<div className="proof-strip-grid">
<SectionHeader
variant="rail"
eyebrow="Reliable to the core"
heading="Audited, scored, published."
headingId="proof-heading"
aside="Not self-reported — every number links to its source."
/>
<ul className="proof-strip-cells" role="list">
{PROOF_CELLS.map((cell) => (
<li className="proof-strip-cell" key={cell.caption}>
{cell.value ? (
<p className="proof-strip-value">
{cell.value}
{cell.suffix ? (
<span className="proof-strip-suffix"> {cell.suffix}</span>
) : null}
</p>
) : (
<img
className="proof-strip-badge"
src="https://hvtracker.net/badge/threadplane.svg"
alt="HVTrust grade for Threadplane (live badge)"
width={91}
height={20}
loading="lazy"
referrerPolicy="no-referrer"
/>
)}
<p className="proof-strip-caption">{cell.caption}</p>
<a
className="proof-strip-source"
href={cell.sourceHref}
target="_blank"
rel="noopener noreferrer"
>
{cell.sourceLabel}
</a>
</li>
))}
</ul>
</div>
</div>
</Container>
</Section>
Expand Down
60 changes: 0 additions & 60 deletions apps/website/src/components/landing/YesWall.spec.tsx

This file was deleted.

Loading
Loading