45bafbc01a
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>
46 lines
1.9 KiB
JavaScript
46 lines
1.9 KiB
JavaScript
/**
|
|
* clvDisplay (DS4 · Billboards — CLV reframe, DESIGN-SPEC Part 3 #16).
|
|
*
|
|
* "Charts that are flat should SAY so." When settled CLV is near-flat (e.g.
|
|
* 73 of 74 reads landed at the close), a 7-bar histogram is one giant bar and
|
|
* six empty stubs — it reads as BROKEN. The record (55-19, 74% hit) is the
|
|
* best data on the site; it must look the MOST premium, never errored.
|
|
*
|
|
* This is the single pure decision: given the server's `clv_distribution`
|
|
* (already n≥20 gated in ledgerService), decide FLAT vs SPREAD. Flat → a
|
|
* confident VOICE line. Spread → the real bars. Pure + CommonJS so the .tsx
|
|
* consumers (ledger, profile) and Jest share one tested rule.
|
|
*/
|
|
|
|
// The flat bucket must hold this share of settled CLV for the histogram to be
|
|
// declared "flat." 73/74 → 0.986; a genuinely dispersed book → well under.
|
|
const FLAT_SHARE_THRESHOLD = 0.6;
|
|
|
|
// VOICE-compliant one-liner. No jargon; states the model's actual claim.
|
|
const CLV_FLAT_LINE = 'CLV flat — we grade the outcome, not the close.';
|
|
|
|
/**
|
|
* @param {Array<{label:string,count:number,side:'beat'|'faded'|'flat'}>|null} dist
|
|
* @returns {{ mode:'flat'|'spread'|'none', total:number, flat:number, flatShare:number }}
|
|
*/
|
|
function clvMode(dist) {
|
|
if (!Array.isArray(dist) || dist.length === 0) {
|
|
return { mode: 'none', total: 0, flat: 0, flatShare: 0 };
|
|
}
|
|
const total = dist.reduce((n, b) => n + (Number(b && b.count) || 0), 0);
|
|
if (total <= 0) return { mode: 'none', total: 0, flat: 0, flatShare: 0 };
|
|
const flat = dist
|
|
.filter((b) => b && b.side === 'flat')
|
|
.reduce((n, b) => n + (Number(b.count) || 0), 0);
|
|
const flatShare = flat / total;
|
|
const mode = flatShare >= FLAT_SHARE_THRESHOLD ? 'flat' : 'spread';
|
|
return { mode, total, flat, flatShare };
|
|
}
|
|
|
|
/** Convenience predicate for the flat branch. */
|
|
function isFlatClv(dist) {
|
|
return clvMode(dist).mode === 'flat';
|
|
}
|
|
|
|
module.exports = { clvMode, isFlatClv, CLV_FLAT_LINE, FLAT_SHARE_THRESHOLD };
|