DS4 (design): billboards — STREAKS row, grade reveal, CLV reframe, /u profile

P0 billboards (the timeline is customer #1). Pixel-level craft: one bold hero
among muted context, real entities from DS0.

- STREAKS row: rebuilt from a log line into a Bloomberg alert. Streak LENGTH is
  now the mono/tabular HERO (38px, the largest figure in the row); real
  PlayerAvatar identity; muted "built vs [opponents]" lens; ONE severity accent
  (step-up amber / step-down green); grade badge tier-gated (the READ is paid).
- Grade reveal: edge is now sign-colored — negative edge uses var(--miss),
  never green (color contract #3). Fixed in BOTH the confidence strip and the
  MODEL/LINE/EDGE row; that row is now mono + tabular. Letter stays the hero.
- CLV reframe: new pure lib/clvDisplay.js (clvMode flat/spread/none). A near-
  flat distribution (73/74) now renders a confident VOICE line — "CLV flat — we
  grade the outcome, not the close" — instead of a broken-looking histogram;
  bars show only on real spread.
- /u profile: hit% is the bold record hero (56px mono tabular) + beat-close
  secondary; honest CLV-VERIFIED badge (only when closing value is tracked);
  real PlayerAvatar identity on cards; OG image elevated to carry the real
  record at 1200x630 social crop (graceful tagline fallback).

Tests: +23 (tests/unit/ds4Billboards.test.js). Full suite green (2732).
web build exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-12 19:25:57 -04:00
parent 24af247b29
commit 45bafbc01a
7 changed files with 452 additions and 74 deletions
+29 -7
View File
@@ -3,6 +3,7 @@
import { useCallback, useEffect, useState } from 'react';
import { GradePill } from '@/components/GradeCard';
import { useAuth } from '@/contexts/AuthContext';
import { clvMode, CLV_FLAT_LINE } from '@/lib/clvDisplay';
/**
* The Ledger (Session 58, Phase 1) — the truth surface, now backed by the
@@ -191,15 +192,36 @@ function TierCalibration({ agg, minSample }: { agg: ModelAggregate; minSample: n
);
}
/** S6 (A1 board) — compact settled-CLV distribution strip. Bars are DATA
* (mono, tabular): green = beat-the-close side, red = faded side, dim = flat.
* Renders only when the server passed the n≥20 gate (clv_distribution set). */
/** S6 (A1 board) · reframed DS4 — settled-CLV display. The n≥20 gate lives
* in the server (clv_distribution set). DESIGN-SPEC Part 3 #16: a near-flat
* distribution renders as one giant bar + six empty stubs — it reads as
* BROKEN. When CLV is flat we SAY so in one confident VOICE line (the record
* is the best data on the site; it must look the most premium, never errored)
* and show the bars only when there is real spread. */
function ClvDistribution({ agg }: { agg: ModelAggregate }) {
const dist = agg.clv_distribution;
if (!Array.isArray(dist) || dist.length === 0) return null;
const total = dist.reduce((n, b) => n + b.count, 0);
const { mode } = clvMode(dist as Parameters<typeof clvMode>[0]);
if (mode === 'none') return null;
if (mode === 'flat') {
// Flat CLV is a FEATURE, not an error: the model grades outcomes, not the
// close. State it plainly — premium, confident, no broken histogram.
return (
<div style={{ marginTop: 14, paddingTop: 12, borderTop: '1px solid var(--border)' }}>
<div className="mono" style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '0.1em', color: 'var(--text-tertiary)', marginBottom: 6 }}>
CLOSING-LINE VALUE
</div>
<p className="mono" style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-primary)', margin: 0, letterSpacing: '0.01em' }}>
{CLV_FLAT_LINE}
</p>
</div>
);
}
const distArr = dist as ClvBucket[];
const total = distArr.reduce((n, b) => n + b.count, 0);
if (total === 0) return null;
const max = Math.max(...dist.map((b) => b.count));
const max = Math.max(...distArr.map((b) => b.count));
const color = (side: ClvBucket['side']) =>
side === 'beat' ? 'var(--g-a, #00D4A0)' : side === 'faded' ? 'var(--miss, #FF6B6B)' : 'var(--text-tertiary)';
return (
@@ -208,7 +230,7 @@ function ClvDistribution({ agg }: { agg: ModelAggregate }) {
CLV DISTRIBUTION · {total} SETTLED
</div>
<div style={{ display: 'flex', gap: 8, alignItems: 'flex-end', maxWidth: 420 }}>
{dist.map((b) => (
{distArr.map((b) => (
<div key={b.label} title={`${b.label}: ${b.count}`} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, minWidth: 0 }}>
<span className="mono" style={{ fontSize: 10, fontVariantNumeric: 'tabular-nums', color: b.count > 0 ? 'var(--text-secondary)' : 'var(--text-tertiary)' }}>
{b.count}