diff --git a/CHANGELOG.md b/CHANGELOG.md index 52d7818a..ffc83661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). - Dedicated support guide (`SUPPORT.md`) and issue-template contact links for support/security routing ### Changed +- Public `web-next` homepage refreshed around the reviewer-safe live snapshot, anonymized receipt copy, and demo-first CTA path. - README command examples and tooling descriptions updated to match current CLI and MCP behavior - PR template and contributing checklist now enforce changelog and security/audit validation gates - PR template and contributor guide now enforce small, single-purpose PR scope and Linear-linked branch/PR conventions diff --git a/tests/web-next-demo-fixtures.test.ts b/tests/web-next-demo-fixtures.test.ts index 821fe9dd..87e39dbb 100644 --- a/tests/web-next-demo-fixtures.test.ts +++ b/tests/web-next-demo-fixtures.test.ts @@ -23,6 +23,8 @@ const LAB_METRICS_PACKET_FILE = path.join( const UI_FIXTURE_FILES = [ path.join(REPO_ROOT, 'web-next', 'app', 'demo', 'page.tsx'), + path.join(REPO_ROOT, 'web-next', 'components', 'bento-section.tsx'), + path.join(REPO_ROOT, 'web-next', 'components', 'changelog-section.tsx'), path.join(REPO_ROOT, 'web-next', 'components', 'dashboard-preview.tsx'), path.join(REPO_ROOT, 'web-next', 'components', 'hero-section.tsx'), LIVE_METRICS_SNAPSHOT_FILE, diff --git a/tests/web-next-homepage-anchors.test.ts b/tests/web-next-homepage-anchors.test.ts new file mode 100644 index 00000000..5f31bc8e --- /dev/null +++ b/tests/web-next-homepage-anchors.test.ts @@ -0,0 +1,34 @@ +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; + +const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); + +function readRepoFile(relativePath: string): string { + return readFileSync(path.join(REPO_ROOT, relativePath), 'utf8'); +} + +describe('web-next homepage anchors', () => { + it('keeps faq-section owned by a single rendered component root', () => { + const pageContent = readRepoFile('web-next/app/page.tsx'); + const faqContent = readRepoFile('web-next/components/faq-section.tsx'); + + expect(pageContent).not.toContain('id="faq-section"'); + expect((faqContent.match(/id="faq-section"/g) ?? [])).toHaveLength(1); + }); + + it('keeps the footer audit log link pointed at the history route', () => { + const footerContent = readRepoFile('web-next/components/footer-section.tsx'); + + expect(footerContent).toMatch(/]*>\s*Audit log\s*<\/Link>/); + }); + + it('keeps shared landing CTAs rendered through Button asChild', () => { + const ctaContent = readRepoFile('web-next/components/landing-ctas.tsx'); + + expect(ctaContent).not.toMatch(/\s* - - - - + +

- Free · App-password secure · Leave anytime + Snapshot-first · App-password sign-in · No hidden algorithm

diff --git a/web-next/components/dashboard-preview.tsx b/web-next/components/dashboard-preview.tsx index 097baf93..d3a23e7e 100644 --- a/web-next/components/dashboard-preview.tsx +++ b/web-next/components/dashboard-preview.tsx @@ -1,15 +1,17 @@ // Score breakdown card — the "killer feature" UI shown below the hero +import Link from "next/link" import { LIVE_METRICS_SNAPSHOT, LIVE_RANK_ONE_EXPLANATION } from "@/lib/live-metrics-snapshot" +import { absoluteUnitScoreToPercentValue } from "@/lib/percent" +import { formatSignedScore, isNonNegativeScore } from "@/lib/score" export function DashboardPreview() { const signals = LIVE_RANK_ONE_EXPLANATION.components.map((component) => ({ label: component.label, weight: component.weight, - value: `${component.raw_score >= 0 ? "+" : "-"}${Math.abs(component.raw_score).toFixed(2)}`, - bar: Math.round(component.raw_score * 100), - positive: component.weighted >= 0, + value: formatSignedScore(component.raw_score), + bar: absoluteUnitScoreToPercentValue(component.raw_score), + positive: isNonNegativeScore(component.weighted), })) - const totalScorePrefix = LIVE_RANK_ONE_EXPLANATION.totalScore >= 0 ? "+" : "-" return (
@@ -28,7 +30,7 @@ export function DashboardPreview() { {LIVE_RANK_ONE_EXPLANATION.authorLabel} · anonymized live receipt - score: {LIVE_RANK_ONE_EXPLANATION.totalScore.toFixed(2)} + score: {formatSignedScore(LIVE_RANK_ONE_EXPLANATION.totalScore)}

@@ -71,14 +73,14 @@ export function DashboardPreview() {

Total score - {totalScorePrefix}{Math.abs(LIVE_RANK_ONE_EXPLANATION.totalScore).toFixed(2)} + {formatSignedScore(LIVE_RANK_ONE_EXPLANATION.totalScore)}
Epoch #{LIVE_METRICS_SNAPSHOT.epochId} · refreshed {LIVE_METRICS_SNAPSHOT.collectedAtLabel} - +
diff --git a/web-next/components/footer-section.tsx b/web-next/components/footer-section.tsx index 63966303..984b879a 100644 --- a/web-next/components/footer-section.tsx +++ b/web-next/components/footer-section.tsx @@ -1,3 +1,5 @@ +import Link from "next/link" + export function FooterSection() { return (