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:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user