Session 35: Design system Phase D — core screens: Grade Result, Slate card, Scan, Terminal, Landing (1839 tests)

VYNDR 2.0 conversion, Phase D (the screens users touch). Frontend-only; zero
backend changes.

- GradeResultCard + ProcessingGrade (the core product moment): intel-surface
  grade hero, signal breakdown, kill conditions, best-book strip, alt ladder;
  sections self-hide when empty.
- lib/gradeAdapter.js maps engine output -> §7 contract and tier-gates content
  (free teaser / analyst kill-conditions / desk alt ladder) so the new card
  doesn't give paid content away.
- Scan result wired to ProcessingGrade->GradeResultCard, preserving scan limits,
  parlay add, reads tracking, and noopener sportsbook deep-links.
- GameCard (Bloomberg best/worst line cells) built + tested.
- Terminal page replaces its stub with a real league-intelligence screen.
- Landing gets the founder-seat ClaimMeter.

Honest scope: live dashboard/Slate swap onto GameCard, scan input -> TerminalInput,
full landing rebuild, and the blurred-paywall polish (Phase G) are deferred to
keep working flows stable.

22 new tests. Backend 1818 -> 1839, 143 suites, zero regressions. Web build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-06-16 00:20:45 -04:00
parent 907c7b17c1
commit 1d83682cdb
13 changed files with 1205 additions and 33 deletions
+24
View File
@@ -197,6 +197,30 @@ The frame every page sits in. Frontend-only.
(terminal/compare/invite/help/about/notifications). Never stub over a route
that already has real content.
## VYNDR 2.0 Core Screens (Session 35 — Phase D)
- **Grade Result Card** = `@/components/vyndr/GradeResultCard` (the product's
core moment) + `ProcessingGrade` (the factor-ignite reveal that precedes it).
Feed them the §7 contract via `lib/gradeAdapter.js` (`mapScanToGradeResult`).
The adapter is CommonJS (unit-testable) and **tier-gates content**: free =
3-signal teaser, no kill conditions, no alt ladder; analyst = full signals +
kill conditions; desk = + alt ladder. Keep that gating — the card itself shows
whatever it's given, so the giveaway-prevention lives in the adapter.
GradeResultCard returns the inferred JS-object type loosely, so cast
`mapScanToGradeResult(...) as GradeResultData` at call sites (the JS adapter
has no TS types).
- **Scan grade flow** (`app/scan/page.tsx`) now renders ProcessingGrade→
GradeResultCard. The existing search/limit/parlay logic, `markReadComplete`
reads tracking, and `noopener noreferrer` sportsbook deep-links were preserved
— don't drop those when iterating.
- **GameCard** = `@/components/vyndr/GameCard` (Bloomberg best/worst line cells:
best = `rgba(0,212,160,.13)` + green left border, worst = subtle red). Built +
tested but NOT yet swapped into the live `dashboard`/`Slate.tsx` — that
data-mapping swap is a pending task; don't assume the dashboard uses it yet.
- **Terminal** (`app/terminal/page.tsx`) is a real page now (server component,
sample intel data) — no longer a RouteStub. Real-data wiring is later.
- **ClaimMeter** = `@/components/vyndr/ClaimMeter` (founder-seat scarcity), on the
landing under the Hero.
## Active Skills
- vyndr-voice (all user-facing output)
- prop-analysis (grading methodology)