Skip to content

PROJ-1285 Polish web-next homepage - #325

Merged
AndrewNordstrom merged 2 commits into
mainfrom
dev/PROJ-1285-corgi-v2-homepage-polish
Jul 9, 2026
Merged

AndrewNordstrom merged 2 commits into
mainfrom
dev/PROJ-1285-corgi-v2-homepage-polish

Conversation

@AndrewNordstrom

@AndrewNordstrom AndrewNordstrom commented Jul 9, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Polishes the public web-next homepage toward the v2 design rhythm while preserving reviewer-safe live snapshot data, anonymized receipt copy, static export behavior, and production header/menu behavior.

Changes

  • Reorders / into the v2 rhythm: hero, receipt preview, social proof, feature rows, get-started, proof/changelog, FAQ, CTA, footer.
  • Replaces fake bento/testimonial-style content with truthful Corgi concepts backed by LIVE_METRICS_SNAPSHOT, LIVE_RANK_ONE_EXPLANATION, and LIVE_FEED_POSTS.
  • Makes the hero primary CTA demo-first at /demo and keeps sign-in/account connection secondary.
  • Updates real GitHub/docs/internal links and removes placeholder href="#" residue.
  • Extends the web-next fixture guard for homepage components that now import live snapshot data.
  • Adds an Unreleased changelog note.

Verification

  • cd web-next && npm run lint
  • cd web-next && npx tsc --noEmit
  • cd web-next && npm run build
  • npx vitest tests/web-next-demo-fixtures.test.ts --run
  • npx vitest tests/web-next-landing-ctas-render.test.tsx tests/web-next-score.test.ts --run
  • npx vitest tests/web-next-landing-ctas-render.test.tsx tests/web-next-score.test.ts tests/web-next-demo-fixtures.test.ts tests/web-next-percent.test.ts tests/web-next-homepage-anchors.test.ts --run
  • npm run verify with non-secret dummy test env outside sandbox because local socket tests hit sandbox EPERM

Browser QA

  • Captured post-build screenshots at 1440x1100, 756x762, and 390x844.
  • Verified fresh cache-busted local static export load is nonblank and all three checked viewports report overflowX: 0.
  • Local static server shows expected /api/governance/auth/session 404 because the backend API is not mounted when serving web-next/out directly.

Production Smoke Before Merge

Current deployed production routes were checked before this PR merges: /, /demo/, /dashboard/, /vote/, /post/ returned 200 and unknown route returned 404. HTML returned cache-control: no-cache; a _next/static/chunks/*.js asset returned public, max-age=31536000, immutable; /health/ready returned ready. /api/transparency/stats still timed out after 10s and is treated as an existing runtime blocker outside this landing polish.

CodeRabbit Audit

  • Status: exempt
  • Reason: Latest head 76b609c541a1250fc6bf36eff91328842c334e0b has no live current-head CodeRabbit threads and no stale/superseded residue. coderabbit-status reports review_state=APPROVED on review_sha=76b609c541a1250fc6bf36eff91328842c334e0b, threads_open=0, and signal_state=pending / signal_message="Review in progress" while the raw CodeRabbit status context remains pending.
  • Validation: coderabbit-truth-gate --mode threads --head-sha 76b609c541a1250fc6bf36eff91328842c334e0b passed with zero live current-head CodeRabbit threads. resolve-coderabbit-threads --json found no eligible residue and reported all non-CodeRabbit checks green. Local npm run verify passed after the rebase with 109 test files and 990 tests; GitHub backend, frontend, docs, report scripts, quality, CodeQL, Aikido, secret scan, security, Dependabot, Linear, and internal hygiene checks passed on head 76b609c541a1250fc6bf36eff91328842c334e0b.
  • Follow-up: remove the coderabbit:exempt label if CodeRabbit later posts current-head actionable findings before merge; treat any new current-head HIGH/MEDIUM findings as blocking.
  • Expires: 2026-07-10

Checklist

  • Tests added/updated and npm run verify passes locally
  • CHANGELOG.md updated under ## [Unreleased] (per RELEASING.md)
  • Docs updated if behavior, config, or API changed (npm run docs:verify passes) — no docs/API/config change
  • Single-purpose change; no unrelated churn
  • No secrets, internal infrastructure, or private URLs introduced

Refs PROJ-1285

@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The PR refreshes the public web-next homepage with live snapshot content, demo-first CTAs, real navigation links, shared score/percent helpers, and tests that lock down CTA rendering and homepage anchor structure.

Changes

Homepage refresh and navigation

Layer / File(s) Summary
Percent helpers and score formatting
web-next/lib/percent.ts, web-next/lib/score.ts, web-next/components/dashboard-preview.tsx, tests/web-next-percent.test.ts, tests/web-next-score.test.ts
Adds clamped percent and signed-score helpers, uses them in dashboard rendering, and verifies edge cases plus file-level formatting consistency.
Landing shell and demo CTAs
web-next/components/landing-ctas.tsx, web-next/components/hero-section.tsx, web-next/components/get-started-section.tsx, web-next/components/cta-section.tsx, web-next/components/sign-in-dialog.tsx, web-next/app/page.tsx, CHANGELOG.md
Introduces shared demo/sign-in CTAs, rewrites the hero and onboarding copy/layout around the demo path, updates the page composition, and records the homepage refresh in the changelog.
Live snapshot sections and navigation
web-next/components/bento-section.tsx, web-next/components/changelog-section.tsx, web-next/components/social-proof.tsx, web-next/components/footer-section.tsx
Replaces static homepage content and placeholder links with live snapshot-driven sections and real internal/external navigation targets.
Test harness and anchor coverage
vitest.config.ts, tests/web-next-demo-fixtures.test.ts, tests/web-next-homepage-anchors.test.ts, tests/web-next-landing-ctas-render.test.tsx
Expands mock/test wiring and adds assertions for fixture coverage, homepage anchor ownership, and CTA rendering shape.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • PROJ-1550: Matches the reviewer-first homepage, live proof sections, demo CTA flow, and audit/receipt-oriented content in this PR.
  • PROJ-1285: Covers the public landing page and read-only reviewer/demo flow this PR implements.
  • PROJ-1434: Overlaps with the homepage proof/FAQ/product messaging and landing-page component updates.
  • PROJ-1497: Tracks the web-next productization work around landing sections, CTAs, and homepage navigation.
  • PROJ-1431: Aligns with the reviewer-safe demo path and live receipts surfaced here.

Possibly related PRs

Suggested labels: documentation, javascript

Sequence Diagram(s)

sequenceDiagram
  participant Visitor
  participant AppPage as web-next/app/page.tsx
  participant Hero as web-next/components/hero-section.tsx
  participant GetStarted as web-next/components/get-started-section.tsx
  participant LandingCTAs as web-next/components/landing-ctas.tsx
  participant Bento as web-next/components/bento-section.tsx
  participant Changelog as web-next/components/changelog-section.tsx
  participant Footer as web-next/components/footer-section.tsx

  Visitor->>AppPage: Load /
  AppPage->>Hero: Render full-bleed hero
  Hero->>LandingCTAs: Render DemoCTA
  AppPage->>GetStarted: Render reviewer flow
  GetStarted->>LandingCTAs: Render DemoCTA and SignInCTA
  AppPage->>Bento: Render live snapshot features
  AppPage->>Changelog: Render live changelog entries
  AppPage->>Footer: Render real navigation links
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR improves the homepage, but it misses key [PROJ-1285] requirements like read-only /dashboard, /post/:uri deep-links, and the error boundary. Add the unauthenticated /dashboard read-only path, one-click /post/:uri links, governance pulse card, score animation, and app-shell error boundary.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The added components, helpers, tests, and changelog entry all support the homepage refresh; no unrelated code churn stands out.
Title check ✅ Passed Clearly summarizes the homepage polish across layout, content, and CTA updates.
Description check ✅ Passed The description matches the homepage redesign, live snapshot content, link cleanup, fixture updates, and changelog note.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev/PROJ-1285-corgi-v2-homepage-polish
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch dev/PROJ-1285-corgi-v2-homepage-polish

Warning

Review ran into problems

🔥 Problems

These MCP integrations need to be re-authenticated in the Integrations settings: Notion, Linear


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the javascript Pull requests that update javascript code label Jul 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web-next/app/page.tsx`:
- Around line 55-57: The FAQ block is rendering duplicate faq-section IDs
because AnimatedSection forwards the id to its wrapper and FAQSection also sets
the same root id; keep the id on only one element in the
FAQSection/AnimatedSection composition so anchor lookups resolve predictably.
Update the page composition around AnimatedSection and FAQSection to ensure only
one DOM node owns faq-section, and add a regression test covering the FAQ anchor
target/getElementById behavior.

In `@web-next/components/bento-section.tsx`:
- Around line 4-19: `formatPercent` should use the same validation/clamping
behavior as `unitIntervalToPercent` so the VoteWeightsUI bar and label stay
consistent. Update `formatPercent` in `bento-section.tsx` to guard non-finite
values and clamp inputs to the valid 0–1 range before formatting, matching how
`unitIntervalToPercent` handles `item.value`. Keep the formatting logic aligned
for the shared `LIVE_METRICS_SNAPSHOT.weights` values used in `VoteWeightsUI`,
and add a test covering malformed inputs like `NaN` and `1.4` to verify both the
bar width and percent label render consistently.

In `@web-next/components/changelog-section.tsx`:
- Around line 4-31: The changelog badge tags in changelog-section are loosely
coupled, so a future tag typo or new category can break styling at runtime
without a TypeScript error. Tighten the relationship by introducing a shared
literal union or derived tag type for the entries array and use it to type
tagColors and entry.tag so the compiler enforces that every tag has a matching
color mapping and vice versa.

In `@web-next/components/cta-section.tsx`:
- Around line 22-40: The `/demo` and `/sign-in` CTA buttons in this section are
duplicated with identical labels, hrefs, and Tailwind styling, matching the
copies in `hero-section.tsx` and `get-started-section.tsx`. Extract the shared
button markup into reusable components such as `DemoCTA` and `SignInCTA` (or a
small primary/secondary CTA button pair), then replace the inline `Link` +
`Button` blocks here with those shared components so styling and behavior stay
centralized.

In `@web-next/components/dashboard-preview.tsx`:
- Around line 5-11: `clampScoreBarPercent` in `dashboard-preview.tsx` duplicates
the same percent-clamping logic already used by `unitIntervalToPercent` in
`bento-section.tsx`, so extract the shared behavior into a common utility and
have both call it. Create a reusable helper (for example in a shared util
module) that handles the `!Number.isFinite` guard and clamping to 0–100, with an
option to preserve the current `Math.abs` behavior for `clampScoreBarPercent` if
needed. Update both `clampScoreBarPercent` and `unitIntervalToPercent` to use
the shared helper so the implementations stay aligned.

In `@web-next/components/footer-section.tsx`:
- Around line 60-62: The footer Audit log link in footer-section.tsx is pointing
to the dashboard summary instead of the full audit log; update the Link used for
“Audit log” to target the full history route or change the label to match the
dashboard scope. Use the FooterSection component’s Link entry for this item, and
add/update a footer link test to assert the Audit log text and href stay
aligned.

In `@web-next/components/hero-section.tsx`:
- Around line 9-22: The hero background SVG in hero-section.tsx does not cover
the widened 1440px viewBox, leaving a gap on the right. Update the SVG mask
dimensions and the grid generation logic inside the hero background markup so
the masked grid, row loop, and any gradient/end coordinates extend to the full
1440-width canvas. Use the existing SVG background section and its row/column
loop as the place to adjust coverage, then verify the pattern spans the entire
hero at wide desktop sizes.

In `@web-next/components/social-proof.tsx`:
- Around line 13-16: Replace the external GitHub URL usage in the social-proof
link rendering with a plain anchor instead of next/link, following the same
pattern as hero-section.tsx for external destinations. Update the social-proof
component’s link markup so the href to github.com uses an ordinary <a> with the
existing label and external link behavior, and keep the change consistent for
the other mentioned occurrence as well.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2ef0ca08-22da-4fc7-b8a3-d7558759ef38

📥 Commits

Reviewing files that changed from the base of the PR and between 13d99eb and 5cf04b6.

📒 Files selected for processing (12)
  • CHANGELOG.md
  • tests/web-next-demo-fixtures.test.ts
  • web-next/app/page.tsx
  • web-next/components/bento-section.tsx
  • web-next/components/changelog-section.tsx
  • web-next/components/cta-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/footer-section.tsx
  • web-next/components/get-started-section.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/sign-in-dialog.tsx
  • web-next/components/social-proof.tsx

Comment thread web-next/app/page.tsx Outdated
Comment thread web-next/components/bento-section.tsx Outdated
Comment thread web-next/components/changelog-section.tsx Outdated
Comment thread web-next/components/cta-section.tsx
Comment thread web-next/components/dashboard-preview.tsx Outdated
Comment thread web-next/components/footer-section.tsx Outdated
Comment thread web-next/components/hero-section.tsx
Comment thread web-next/components/social-proof.tsx
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai coderabbitai Bot added the documentation Improvements or additions to documentation label Jul 9, 2026
@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1285-corgi-v2-homepage-polish branch from 0b5ea52 to 8b379cf Compare July 9, 2026 04:38
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/web-next-homepage-anchors.test.ts`:
- Around line 13-19: The current test in web-next-homepage-anchors is brittle
because it inspects raw source strings instead of the rendered DOM. Update the
check around Page and FAQSection so it renders the component tree (for example,
via a JSDOM/testing-library test) and asserts that
document.querySelectorAll('`#faq-section`') returns exactly one element, ensuring
the invariant is verified by behavior rather than literal source matching.
- Around line 21-26: The footer audit log test is using two independent
substring checks, so it does not verify that “Audit log” is actually linked to
"/history". Update the test in web-next-homepage-anchors.test.ts to assert the
href and label belong to the same Link in footer-section.tsx, using the existing
footer content fixture and the footer link markup around the Audit log anchor.
This should make the assertion target the specific footer-section.tsx link
rather than any separate occurrence of the text.

In `@tests/web-next-percent.test.ts`:
- Around line 8-23: The percent helper tests in web-next percent helpers are
missing important edge cases and direct coverage of the lowest-level helper.
Update the test file to import and assert clampPercentValue directly, and add
boundary/Infinity cases for unitIntervalToPercentValue and
formatUnitIntervalPercent at 0, 1, Infinity, and -Infinity alongside the
existing NaN/out-of-range checks. Also verify the .5 rounding behavior through
clampPercentValue so the helper chain is covered from the bottom up.

In `@web-next/components/landing-ctas.tsx`:
- Around line 9-22: The landing CTA components currently wrap Button inside
Link, creating nested interactive elements. Update both DemoCTA and SignInCTA in
landing-ctas.tsx to use Button with asChild so the Link becomes the actual
rendered control. Then add a regression test covering both CTA variants to
verify the rendered markup does not include a nested button inside an anchor.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 77c8dbfa-ddf2-4ed7-92ae-0b5071b7c071

📥 Commits

Reviewing files that changed from the base of the PR and between 5cf04b6 and 0b5ea52.

📒 Files selected for processing (13)
  • tests/web-next-homepage-anchors.test.ts
  • tests/web-next-percent.test.ts
  • web-next/app/page.tsx
  • web-next/components/bento-section.tsx
  • web-next/components/changelog-section.tsx
  • web-next/components/cta-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/footer-section.tsx
  • web-next/components/get-started-section.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/landing-ctas.tsx
  • web-next/components/social-proof.tsx
  • web-next/lib/percent.ts

Comment thread tests/web-next-homepage-anchors.test.ts
Comment thread tests/web-next-homepage-anchors.test.ts
Comment thread tests/web-next-percent.test.ts
Comment thread web-next/components/landing-ctas.tsx
@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1285-corgi-v2-homepage-polish branch from 8b379cf to ec56b2a Compare July 9, 2026 04:50
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web-next/components/bento-section.tsx`:
- Around line 5-8: formatScore currently formats NaN/Infinity as a misleading
signed string, so add a non-finite guard to this helper in bento-section.tsx and
make it fail safely like the percent formatters. Update the
ScoreBreakdownUI/MixedFeedUI rendering path to use the guarded formatScore
behavior, and add a test or story that feeds NaN and Infinity through
LIVE_RANK_ONE_EXPLANATION.totalScore to verify the receipt still renders a sane
fallback value instead of "-NaN".

In `@web-next/components/dashboard-preview.tsx`:
- Around line 6-14: The score sign/absolute formatting is duplicated in
DashboardPreview and the existing formatScore helper in BentoSection, so move
this logic into a shared helper next to percent.ts. Add a reusable
formatSignedScore-style function there, then update DashboardPreview and
bento-section.tsx to import it and use it for component values and
totalScorePrefix. Keep the helper as the single source of truth so future
NaN/formatting changes stay consistent across both call sites.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ac9b2405-d2aa-4802-b0f8-a46433114604

📥 Commits

Reviewing files that changed from the base of the PR and between 0b5ea52 and 8b379cf.

📒 Files selected for processing (16)
  • CHANGELOG.md
  • tests/web-next-demo-fixtures.test.ts
  • tests/web-next-homepage-anchors.test.ts
  • tests/web-next-percent.test.ts
  • web-next/app/page.tsx
  • web-next/components/bento-section.tsx
  • web-next/components/changelog-section.tsx
  • web-next/components/cta-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/footer-section.tsx
  • web-next/components/get-started-section.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/landing-ctas.tsx
  • web-next/components/sign-in-dialog.tsx
  • web-next/components/social-proof.tsx
  • web-next/lib/percent.ts

Comment thread web-next/components/bento-section.tsx Outdated
Comment thread web-next/components/dashboard-preview.tsx Outdated
@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1285-corgi-v2-homepage-polish branch from ec56b2a to a067e75 Compare July 9, 2026 04:56
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@AndrewNordstrom AndrewNordstrom added the coderabbit:exempt Temporary CodeRabbit exemption with audit note label Jul 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web-next/components/landing-ctas.tsx`:
- Around line 9-40: Add regression tests for the shared CTA components in
landing-ctas.tsx by covering DemoCTA and SignInCTA rendering through Button
asChild with Link, asserting each produces a single anchor with the correct href
(/demo and /sign-in) and no nested button element. Also verify the className
prop passed into LandingCTAProps is merged with the base styles from cn without
dropping the required layout/classes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e62349c8-8f08-4daa-a246-143d05044e95

📥 Commits

Reviewing files that changed from the base of the PR and between ec56b2a and a067e75.

📒 Files selected for processing (15)
  • tests/web-next-homepage-anchors.test.ts
  • tests/web-next-percent.test.ts
  • tests/web-next-score.test.ts
  • web-next/app/page.tsx
  • web-next/components/bento-section.tsx
  • web-next/components/changelog-section.tsx
  • web-next/components/cta-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/footer-section.tsx
  • web-next/components/get-started-section.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/landing-ctas.tsx
  • web-next/components/social-proof.tsx
  • web-next/lib/percent.ts
  • web-next/lib/score.ts

Comment thread web-next/components/landing-ctas.tsx
@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1285-corgi-v2-homepage-polish branch from a067e75 to 5aa554f Compare July 9, 2026 05:20
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@AndrewNordstrom AndrewNordstrom removed the coderabbit:exempt Temporary CodeRabbit exemption with audit note label Jul 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/web-next-landing-ctas-render.test.tsx`:
- Around line 1-2: The test imports are using hardcoded relative node_modules
paths, which breaks resolution in CI when dependencies are hoisted or deduped.
Update the imports in tests/web-next-landing-ctas-render.test.tsx to use bare
package specifiers for react and react-dom/server so Vitest can resolve them
correctly; locate and replace the imports at the top of the file.
- Around line 34-56: The CTA render tests only cover the happy path, so add an
edge-case around className merging for DemoCTA and SignInCTA. In web-next
landing CTA tests, assert that required base classes from the CTA components
still remain when a conflicting or overriding className is passed, using the
DemoCTA and SignInCTA symbols to locate the render paths. Focus the new coverage
on cn() merge behavior so consumer-supplied classes cannot remove essential
layout/style classes like rounded-full and bg-primary.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 593d47b6-bbf0-4414-a03d-86313114ea25

📥 Commits

Reviewing files that changed from the base of the PR and between a067e75 and 5aa554f.

📒 Files selected for processing (17)
  • tests/web-next-homepage-anchors.test.ts
  • tests/web-next-landing-ctas-render.test.tsx
  • tests/web-next-percent.test.ts
  • tests/web-next-score.test.ts
  • vitest.config.ts
  • web-next/app/page.tsx
  • web-next/components/bento-section.tsx
  • web-next/components/changelog-section.tsx
  • web-next/components/cta-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/footer-section.tsx
  • web-next/components/get-started-section.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/landing-ctas.tsx
  • web-next/components/social-proof.tsx
  • web-next/lib/percent.ts
  • web-next/lib/score.ts

Comment thread tests/web-next-landing-ctas-render.test.tsx Outdated
@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1285-corgi-v2-homepage-polish branch from 5aa554f to c514546 Compare July 9, 2026 05:37
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai coderabbitai Bot removed the documentation Improvements or additions to documentation label Jul 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/web-next-score.test.ts`:
- Around line 14-27: Add an explicit boundary assertion in the web-next score
tests for the zero sign behavior in formatSignedScore, since its branch uses
normalizedValue >= 0. Extend the existing test in tests/web-next-score.test.ts
to verify that formatSignedScore(-0) returns "+0.00" alongside the current
non-finite and rounding cases, so the zero/-0 boundary is covered even if the
implementation of formatSignedScore or normalizeScoreValue changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d28048fe-eb12-4322-8139-f277f66f7b5b

📥 Commits

Reviewing files that changed from the base of the PR and between 5aa554f and c514546.

📒 Files selected for processing (17)
  • tests/web-next-homepage-anchors.test.ts
  • tests/web-next-landing-ctas-render.test.tsx
  • tests/web-next-percent.test.ts
  • tests/web-next-score.test.ts
  • vitest.config.ts
  • web-next/app/page.tsx
  • web-next/components/bento-section.tsx
  • web-next/components/changelog-section.tsx
  • web-next/components/cta-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/footer-section.tsx
  • web-next/components/get-started-section.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/landing-ctas.tsx
  • web-next/components/social-proof.tsx
  • web-next/lib/percent.ts
  • web-next/lib/score.ts

Comment thread tests/web-next-score.test.ts
@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1285-corgi-v2-homepage-polish branch from c514546 to 1a372d8 Compare July 9, 2026 05:45
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@AndrewNordstrom AndrewNordstrom added the coderabbit:exempt Temporary CodeRabbit exemption with audit note label Jul 9, 2026
@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1285-corgi-v2-homepage-polish branch from 1a372d8 to 76b609c Compare July 9, 2026 06:07
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai coderabbitai Bot added the documentation Improvements or additions to documentation label Jul 9, 2026
@AndrewNordstrom
AndrewNordstrom merged commit 5354c21 into main Jul 9, 2026
19 of 20 checks passed
@AndrewNordstrom
AndrewNordstrom deleted the dev/PROJ-1285-corgi-v2-homepage-polish branch July 9, 2026 06:13

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web-next/components/hero-section.tsx (1)

157-161: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Nested <button> inside <a> on secondary CTA — invalid HTML, same issue already fixed for DemoCTA/SignInCTA.

Link href="#features-section" wraps Button variant="ghost", producing a <button> nested inside an <a>. This is invalid HTML and creates ambiguous/duplicate interactive targets for screen readers and keyboard nav (Tab lands on two controls for one action). This exact pattern was already flagged and fixed elsewhere in this PR by switching DemoCTA/SignInCTA to Button asChild; this remaining instance sits in the same CTA row and should get the same treatment.

🔧 Proposed fix
-        <Link href="`#features-section`">
-          <Button variant="ghost" className="text-foreground/70 hover:text-foreground px-5 py-3 rounded-full font-medium text-base">
-            See how ranking works &rarr;
-          </Button>
-        </Link>
+        <Button asChild variant="ghost" className="text-foreground/70 hover:text-foreground px-5 py-3 rounded-full font-medium text-base">
+          <Link href="`#features-section`">
+            See how ranking works &rarr;
+          </Link>
+        </Button>

Consider adding a test case (alongside the existing landing-ctas render tests) asserting this hero CTA row renders no nested <button> inside <a>.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web-next/components/hero-section.tsx` around lines 157 - 161, The secondary
CTA in hero-section still nests a Button inside a Link, creating invalid
anchor/button markup. Update the CTA in the hero section to use the same Button
asChild pattern already applied to DemoCTA and SignInCTA so the link is rendered
without an inner button. Use the Link and Button usage in the hero CTA row to
locate and align this fix, and add a render test in the existing landing-ctas
coverage to ensure this CTA does not produce a nested button inside an anchor.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/web-next-landing-ctas-render.test.tsx`:
- Around line 96-136: Add a test case in web-next landing CTAs coverage that
renders DemoCTA and SignInCTA without passing className, since
LandingCTAProps.className is optional. Use the existing DemoCTA and SignInCTA
symbols from the test file and assert the default markup still includes the
required base classes such as inline-flex, rounded-full, and bg-primary,
confirming cn(baseClasses, undefined) works for the default render path.

In `@web-next/components/bento-section.tsx`:
- Around line 203-210: The receipt CTA in BentoSection points to a /demo hash
that does not exist, so add the matching anchor to the demo receipt/explanation
block in DemoPage and make sure it uses the same rank-based id pattern as
LIVE_RANK_ONE_EXPLANATION.rank. Update the relevant JSX in
web-next/app/demo/page.tsx so the rendered receipt section includes
id="snapshot-rank-${rank}", and add a test that verifies the anchor is present
for the rendered rank.

---

Outside diff comments:
In `@web-next/components/hero-section.tsx`:
- Around line 157-161: The secondary CTA in hero-section still nests a Button
inside a Link, creating invalid anchor/button markup. Update the CTA in the hero
section to use the same Button asChild pattern already applied to DemoCTA and
SignInCTA so the link is rendered without an inner button. Use the Link and
Button usage in the hero CTA row to locate and align this fix, and add a render
test in the existing landing-ctas coverage to ensure this CTA does not produce a
nested button inside an anchor.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 241683ed-6860-437e-bc5f-1732c21fbf0a

📥 Commits

Reviewing files that changed from the base of the PR and between c514546 and 76b609c.

📒 Files selected for processing (20)
  • CHANGELOG.md
  • tests/web-next-demo-fixtures.test.ts
  • tests/web-next-homepage-anchors.test.ts
  • tests/web-next-landing-ctas-render.test.tsx
  • tests/web-next-percent.test.ts
  • tests/web-next-score.test.ts
  • vitest.config.ts
  • web-next/app/page.tsx
  • web-next/components/bento-section.tsx
  • web-next/components/changelog-section.tsx
  • web-next/components/cta-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/footer-section.tsx
  • web-next/components/get-started-section.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/landing-ctas.tsx
  • web-next/components/sign-in-dialog.tsx
  • web-next/components/social-proof.tsx
  • web-next/lib/percent.ts
  • web-next/lib/score.ts

Comment on lines +96 to +136
describe('web-next landing CTAs', () => {
it('renders DemoCTA as one demo anchor without a nested button', () => {
const markup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-class' }));

expect(countMatches(markup, /<a\b/g)).toBe(1);
expect(markup).toContain('href="/demo"');
expect(markup).not.toContain('<button');
expect(markup).toContain('qa-demo-class');
expect(markup).toContain('inline-flex');
expect(markup).toContain('rounded-full');
expect(markup).toContain('bg-primary');
});

it('renders SignInCTA as one sign-in anchor without a nested button', () => {
const markup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-class' }));

expect(countMatches(markup, /<a\b/g)).toBe(1);
expect(markup).toContain('href="/sign-in"');
expect(markup).not.toContain('<button');
expect(markup).toContain('qa-sign-in-class');
expect(markup).toContain('inline-flex');
expect(markup).toContain('rounded-full');
});

it('keeps required base CTA classes when optional className adds layout tokens', () => {
const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-wide sm:px-8' }));
const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-wide sm:px-6' }));

expect(demoMarkup).toContain('qa-demo-wide');
expect(demoMarkup).toContain('sm:px-8');
expect(demoMarkup).toContain('inline-flex');
expect(demoMarkup).toContain('rounded-full');
expect(demoMarkup).toContain('bg-primary');

expect(signInMarkup).toContain('qa-sign-in-wide');
expect(signInMarkup).toContain('sm:px-6');
expect(signInMarkup).toContain('inline-flex');
expect(signInMarkup).toContain('rounded-full');
expect(signInMarkup).toContain('hover:text-foreground');
});
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Missing edge case: default render with no className prop.

All three tests pass a className. LandingCTAProps.className is optional (per landing-ctas.tsx), so add a case rendering DemoCTA/SignInCTA with no className at all to confirm cn(baseClasses, undefined) doesn't throw and still emits the required base classes (bg-primary, rounded-full, inline-flex) — this is the actual default homepage render path and isn't currently covered.

🧪 Suggested test case
   it('keeps required base CTA classes when optional className adds layout tokens', () => {
     ...
   });
+
+  it('renders DemoCTA and SignInCTA with base classes when no className is provided', () => {
+    const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, {}));
+    const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, {}));
+
+    expect(demoMarkup).toContain('inline-flex');
+    expect(demoMarkup).toContain('rounded-full');
+    expect(demoMarkup).toContain('bg-primary');
+    expect(signInMarkup).toContain('inline-flex');
+    expect(signInMarkup).toContain('rounded-full');
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
describe('web-next landing CTAs', () => {
it('renders DemoCTA as one demo anchor without a nested button', () => {
const markup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-class' }));
expect(countMatches(markup, /<a\b/g)).toBe(1);
expect(markup).toContain('href="/demo"');
expect(markup).not.toContain('<button');
expect(markup).toContain('qa-demo-class');
expect(markup).toContain('inline-flex');
expect(markup).toContain('rounded-full');
expect(markup).toContain('bg-primary');
});
it('renders SignInCTA as one sign-in anchor without a nested button', () => {
const markup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-class' }));
expect(countMatches(markup, /<a\b/g)).toBe(1);
expect(markup).toContain('href="/sign-in"');
expect(markup).not.toContain('<button');
expect(markup).toContain('qa-sign-in-class');
expect(markup).toContain('inline-flex');
expect(markup).toContain('rounded-full');
});
it('keeps required base CTA classes when optional className adds layout tokens', () => {
const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-wide sm:px-8' }));
const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-wide sm:px-6' }));
expect(demoMarkup).toContain('qa-demo-wide');
expect(demoMarkup).toContain('sm:px-8');
expect(demoMarkup).toContain('inline-flex');
expect(demoMarkup).toContain('rounded-full');
expect(demoMarkup).toContain('bg-primary');
expect(signInMarkup).toContain('qa-sign-in-wide');
expect(signInMarkup).toContain('sm:px-6');
expect(signInMarkup).toContain('inline-flex');
expect(signInMarkup).toContain('rounded-full');
expect(signInMarkup).toContain('hover:text-foreground');
});
});
describe('web-next landing CTAs', () => {
it('renders DemoCTA as one demo anchor without a nested button', () => {
const markup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-class' }));
expect(countMatches(markup, /<a\b/g)).toBe(1);
expect(markup).toContain('href="/demo"');
expect(markup).not.toContain('<button');
expect(markup).toContain('qa-demo-class');
expect(markup).toContain('inline-flex');
expect(markup).toContain('rounded-full');
expect(markup).toContain('bg-primary');
});
it('renders SignInCTA as one sign-in anchor without a nested button', () => {
const markup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-class' }));
expect(countMatches(markup, /<a\b/g)).toBe(1);
expect(markup).toContain('href="/sign-in"');
expect(markup).not.toContain('<button');
expect(markup).toContain('qa-sign-in-class');
expect(markup).toContain('inline-flex');
expect(markup).toContain('rounded-full');
});
it('keeps required base CTA classes when optional className adds layout tokens', () => {
const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, { className: 'qa-demo-wide sm:px-8' }));
const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, { className: 'qa-sign-in-wide sm:px-6' }));
expect(demoMarkup).toContain('qa-demo-wide');
expect(demoMarkup).toContain('sm:px-8');
expect(demoMarkup).toContain('inline-flex');
expect(demoMarkup).toContain('rounded-full');
expect(demoMarkup).toContain('bg-primary');
expect(signInMarkup).toContain('qa-sign-in-wide');
expect(signInMarkup).toContain('sm:px-6');
expect(signInMarkup).toContain('inline-flex');
expect(signInMarkup).toContain('rounded-full');
expect(signInMarkup).toContain('hover:text-foreground');
});
it('renders DemoCTA and SignInCTA with base classes when no className is provided', () => {
const demoMarkup = renderToStaticMarkup(createElement(DemoCTA, {}));
const signInMarkup = renderToStaticMarkup(createElement(SignInCTA, {}));
expect(demoMarkup).toContain('inline-flex');
expect(demoMarkup).toContain('rounded-full');
expect(demoMarkup).toContain('bg-primary');
expect(signInMarkup).toContain('inline-flex');
expect(signInMarkup).toContain('rounded-full');
});
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/web-next-landing-ctas-render.test.tsx` around lines 96 - 136, Add a
test case in web-next landing CTAs coverage that renders DemoCTA and SignInCTA
without passing className, since LandingCTAProps.className is optional. Use the
existing DemoCTA and SignInCTA symbols from the test file and assert the default
markup still includes the required base classes such as inline-flex,
rounded-full, and bg-primary, confirming cn(baseClasses, undefined) works for
the default render path.

Source: Path instructions

Comment on lines +203 to +210
id: "receipt",
headline: "Every top post keeps an anonymized receipt.",
description:
"The public page can show why a post ranked without leaking raw handles, DIDs, or post URIs. Score components, weights, and totals stay inspectable while the sensitive production content stays redacted.",
cta: "Open the live receipt",
href: `/demo#snapshot-rank-${LIVE_RANK_ONE_EXPLANATION.rank}`,
UI: ScoreBreakdownUI,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Confirm the demo page renders an anchor matching snapshot-rank-<rank>.
rg -n 'snapshot-rank-' web-next/app -g '*.tsx'

Repository: andrewnordstrom-eng/bluesky-community-feed

Length of output: 318


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the demo page and inspect the snapshot-rank anchor usage.
ast-grep outline web-next/app/demo/page.tsx --view expanded || true

echo '--- lines 60-120 ---'
cat -n web-next/app/demo/page.tsx | sed -n '60,120p'

echo '--- search for id/snapshot-rank in demo page ---'
rg -n 'snapshot-rank|id:\s*["'\'']snapshot-rank|id=\{?`?snapshot-rank' web-next/app/demo/page.tsx

Repository: andrewnordstrom-eng/bluesky-community-feed

Length of output: 3709


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- StepFeed / nearby render lines ---'
cat -n web-next/app/demo/page.tsx | sed -n '206,370p'

echo '--- all id assignments in demo page ---'
rg -n 'id\s*=|id:' web-next/app/demo/page.tsx

echo '--- all uses of post.uri / snapshotPostUrl in demo page ---'
rg -n 'post\.uri|snapshotPostUrl|snapshot-rank-' web-next/app/demo/page.tsx

Repository: andrewnordstrom-eng/bluesky-community-feed

Length of output: 10623


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- repo-wide snapshot-rank references ---'
rg -n 'snapshot-rank-' .

echo '--- repo-wide anchor/id patterns for snapshot-rank ---'
rg -n 'id\s*=\s*["'"'"']snapshot-rank-|id:\s*["'"'"']snapshot-rank-' .

Repository: andrewnordstrom-eng/bluesky-community-feed

Length of output: 531


Add the matching /demo anchor for the receipt link. href points to /demo#snapshot-rank-${LIVE_RANK_ONE_EXPLANATION.rank}, but the demo page doesn’t render any element with that id, so the CTA scrolls nowhere. Add id="snapshot-rank-${rank}" to the receipt/explanation block in web-next/app/demo/page.tsx, and add a test that the anchor exists for the rendered rank.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web-next/components/bento-section.tsx` around lines 203 - 210, The receipt
CTA in BentoSection points to a /demo hash that does not exist, so add the
matching anchor to the demo receipt/explanation block in DemoPage and make sure
it uses the same rank-based id pattern as LIVE_RANK_ONE_EXPLANATION.rank. Update
the relevant JSX in web-next/app/demo/page.tsx so the rendered receipt section
includes id="snapshot-rank-${rank}", and add a test that verifies the anchor is
present for the rendered rank.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

coderabbit:exempt Temporary CodeRabbit exemption with audit note documentation Improvements or additions to documentation javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant